From a14ac2482ece61977da1882ba939dc89bf15c157 Mon Sep 17 00:00:00 2001 From: dtclinch Date: Tue, 6 Aug 2024 17:35:54 +0530 Subject: [PATCH] changes ring renderOrder to 1 --- dist/index.js | 6 +- dist/index.js.map | 2 +- dist/index.umd.cjs | 6 +- dist/index.umd.cjs.map | 2 +- docs/demos/Layouts.story.tsx | 1578 ++++++++++++++++- src/symbols/Ring.tsx | 4 +- src/symbols/nodes/Sphere.tsx | 2 +- ....timestamp-1722941749168-09e3f551cb6e6.mjs | 65 + 8 files changed, 1637 insertions(+), 28 deletions(-) create mode 100644 vite.config.ts.timestamp-1722941749168-09e3f551cb6e6.mjs diff --git a/dist/index.js b/dist/index.js index fa67ff54..4a02042f 100644 --- a/dist/index.js +++ b/dist/index.js @@ -1938,7 +1938,7 @@ const Ring = ({ }); const strokeWidthFraction = strokeWidth / 10; const outerRadius = innerRadius + strokeWidthFraction; - return /* @__PURE__ */ jsx(Billboard, { position: [0, 0, 0], children: /* @__PURE__ */ jsxs(a.mesh, { scale: ringSize, children: [ + return /* @__PURE__ */ jsx(Billboard, { position: [0, 0, 0], children: /* @__PURE__ */ jsxs(a.mesh, { scale: ringSize, renderOrder: 1, children: [ /* @__PURE__ */ jsx( "ringGeometry", { @@ -1952,7 +1952,7 @@ const Ring = ({ attach: "material", color: normalizedColor, transparent: true, - depthTest: true, + depthTest: false, opacity: ringOpacity, side: DoubleSide, fog: true @@ -2008,7 +2008,7 @@ const Sphere = ({ } ) ] }), - (showRing || selected || active) && /* @__PURE__ */ jsx(a.mesh, { position: [0, 0, 1], children: /* @__PURE__ */ jsx( + (showRing || selected || active) && /* @__PURE__ */ jsx(a.mesh, { position: [0, 0, 0], children: /* @__PURE__ */ jsx( Ring, { opacity: 1, diff --git a/dist/index.js.map b/dist/index.js.map index 5de93a5d..f90febae 100644 --- a/dist/index.js.map +++ b/dist/index.js.map @@ -1 +1 @@ -{"version":3,"file":"index.js","sources":["../src/layout/depthUtils.ts","../src/layout/forceUtils.ts","../src/layout/layoutUtils.ts","../src/layout/forceInABox.ts","../src/layout/forceDirected.ts","../src/layout/circular2d.ts","../src/layout/hierarchical.ts","../src/layout/nooverlap.ts","../src/layout/forceatlas2.ts","../src/layout/custom.ts","../src/layout/layoutProvider.ts","../src/layout/recommender.ts","../src/utils/visibility.ts","../src/sizing/pageRank.ts","../src/sizing/centrality.ts","../src/sizing/attribute.ts","../src/sizing/nodeSizeProvider.ts","../src/utils/graph.ts","../src/utils/animation.ts","../src/utils/arrow.ts","../src/utils/position.ts","../src/utils/layout.ts","../src/utils/cluster.ts","../src/utils/useHoverIntent.ts","../src/utils/useDrag.ts","../src/utils/paths.ts","../src/store.ts","../src/collapse/utils.ts","../src/collapse/useCollapse.ts","../src/useGraph.ts","../src/symbols/Label.tsx","../src/symbols/Ring.tsx","../src/symbols/nodes/Sphere.tsx","../src/CameraControls/useCameraControls.ts","../src/CameraControls/CameraControls.tsx","../src/CameraControls/utils.ts","../src/CameraControls/useCenterGraph.ts","../src/symbols/nodes/Icon.tsx","../src/symbols/nodes/SphereWithIcon.tsx","../src/symbols/nodes/Svg.tsx","../src/symbols/nodes/SphereWithSvg.tsx","../src/symbols/Node.tsx","../src/symbols/Arrow.tsx","../src/symbols/Line.tsx","../src/symbols/Edge.tsx","../src/symbols/edges/useEdgeGeometry.ts","../src/symbols/edges/useEdgeEvents.ts","../src/symbols/edges/useEdgeAnimations.ts","../src/symbols/edges/Edge.tsx","../src/symbols/edges/Edges.tsx","../src/symbols/Cluster.tsx","../src/GraphScene.tsx","../src/themes/darkTheme.ts","../src/themes/lightTheme.ts","../src/selection/utils.ts","../src/selection/Lasso.tsx","../src/selection/useSelection.ts","../src/GraphCanvas.tsx","../src/RadialMenu/RadialSlice.tsx","../src/RadialMenu/utils.ts","../src/RadialMenu/RadialMenu.tsx"],"sourcesContent":["import { InternalGraphEdge, InternalGraphNode } from '../types';\r\n\r\nexport interface DepthNode {\r\n data: InternalGraphNode;\r\n ins: DepthNode[];\r\n out: DepthNode[];\r\n depth: number;\r\n}\r\n\r\n/**\r\n * Traverse the graph and get the depth of each node.\r\n */\r\nfunction traverseGraph(nodes: DepthNode[], nodeStack: DepthNode[] = []) {\r\n const currentDepth = nodeStack.length;\r\n\r\n for (const node of nodes) {\r\n const idx = nodeStack.indexOf(node);\r\n if (idx > -1) {\r\n const loop = [...nodeStack.slice(idx), node].map(d => d.data.id);\r\n throw new Error(\r\n `Invalid Graph: Circular node path detected: ${loop.join(' -> ')}.`\r\n );\r\n }\r\n\r\n if (currentDepth > node.depth) {\r\n node.depth = currentDepth;\r\n traverseGraph(node.out, [...nodeStack, node]);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Gets the depth of the graph's nodes. Used in the radial layout.\r\n */\r\nexport function getNodeDepth(\r\n nodes: InternalGraphNode[],\r\n links: InternalGraphEdge[]\r\n) {\r\n let invalid = false;\r\n\r\n const graph: { [key: string]: DepthNode } = nodes.reduce(\r\n (acc, cur) => ({\r\n ...acc,\r\n [cur.id]: {\r\n data: cur,\r\n out: [],\r\n depth: -1,\r\n ins: []\r\n }\r\n }),\r\n {}\r\n );\r\n\r\n try {\r\n for (const link of links) {\r\n const from = link.source;\r\n const to = link.target;\r\n\r\n if (!graph.hasOwnProperty(from)) {\r\n throw new Error(`Missing source Node ${from}`);\r\n }\r\n\r\n if (!graph.hasOwnProperty(to)) {\r\n throw new Error(`Missing target Node ${to}`);\r\n }\r\n\r\n const sourceNode = graph[from];\r\n const targetNode = graph[to];\r\n targetNode.ins.push(sourceNode);\r\n sourceNode.out.push(targetNode);\r\n }\r\n\r\n traverseGraph(Object.values(graph));\r\n } catch (e) {\r\n invalid = true;\r\n }\r\n\r\n const allDepths = Object.keys(graph).map(id => graph[id].depth);\r\n const maxDepth = Math.max(...allDepths);\r\n\r\n return {\r\n invalid,\r\n depths: graph,\r\n maxDepth: maxDepth || 1\r\n };\r\n}\r\n","import { forceRadial as d3ForceRadial } from 'd3-force-3d';\r\nimport { InternalGraphEdge, InternalGraphNode } from 'types';\r\nimport { getNodeDepth } from './depthUtils';\r\n\r\nconst RADIALS: DagMode[] = ['radialin', 'radialout'];\r\n\r\nexport type DagMode =\r\n | 'lr'\r\n | 'rl'\r\n | 'td'\r\n | 'but'\r\n | 'zout'\r\n | 'zin'\r\n | 'radialin'\r\n | 'radialout';\r\n\r\nexport interface ForceRadialInputs {\r\n nodes: InternalGraphNode[];\r\n edges: InternalGraphEdge[];\r\n mode: DagMode;\r\n nodeLevelRatio: number;\r\n}\r\n\r\n/**\r\n * Radial graph layout using D3 Force 3d.\r\n * Inspired by: https://github.com/vasturiano/three-forcegraph/blob/master/src/forcegraph-kapsule.js#L970-L1018\r\n */\r\nexport function forceRadial({\r\n nodes,\r\n edges,\r\n mode = 'lr',\r\n nodeLevelRatio = 2\r\n}: ForceRadialInputs) {\r\n const { depths, maxDepth, invalid } = getNodeDepth(nodes, edges);\r\n\r\n if (invalid) {\r\n return null;\r\n }\r\n\r\n const modeDistance = RADIALS.includes(mode) ? 1 : 5;\r\n const dagLevelDistance =\r\n (nodes.length / maxDepth) * nodeLevelRatio * modeDistance;\r\n\r\n if (mode) {\r\n const getFFn =\r\n (fix: boolean, invert: boolean) => (node: InternalGraphNode) =>\r\n !fix\r\n ? undefined\r\n : (depths[node.id].depth - maxDepth / 2) *\r\n dagLevelDistance *\r\n (invert ? -1 : 1);\r\n\r\n const fxFn = getFFn(['lr', 'rl'].includes(mode), mode === 'rl');\r\n const fyFn = getFFn(['td', 'bu'].includes(mode), mode === 'td');\r\n const fzFn = getFFn(['zin', 'zout'].includes(mode), mode === 'zout');\r\n\r\n nodes.forEach(node => {\r\n node.fx = fxFn(node);\r\n node.fy = fyFn(node);\r\n node.fz = fzFn(node);\r\n });\r\n }\r\n\r\n return RADIALS.includes(mode)\r\n ? d3ForceRadial(node => {\r\n const nodeDepth = depths[node.id];\r\n const depth =\r\n mode === 'radialin' ? maxDepth - nodeDepth.depth : nodeDepth.depth;\r\n return depth * dagLevelDistance;\r\n }).strength(1)\r\n : null;\r\n}\r\n","import Graph from 'graphology';\r\nimport { LayoutStrategy } from './types';\r\nimport { InternalGraphEdge, InternalGraphNode } from '../types';\r\n\r\n/**\r\n * Promise based tick helper.\r\n */\r\nexport function tick(layout: LayoutStrategy) {\r\n return new Promise((resolve, _reject) => {\r\n let stable: boolean | undefined;\r\n\r\n function run() {\r\n if (!stable) {\r\n stable = layout.step();\r\n run();\r\n } else {\r\n resolve(stable);\r\n }\r\n }\r\n\r\n run();\r\n });\r\n}\r\n\r\n/**\r\n * Helper function to turn the graph nodes/edges into an array for\r\n * easier manipulation.\r\n */\r\nexport function buildNodeEdges(graph: Graph) {\r\n const nodes: InternalGraphNode[] = [];\r\n const edges: InternalGraphEdge[] = [];\r\n\r\n graph.forEachNode((id, n: any) => {\r\n nodes.push({\r\n ...n,\r\n id,\r\n // This is for the clustering\r\n radius: n.size || 1\r\n });\r\n });\r\n\r\n graph.forEachEdge((id, l: any) => {\r\n edges.push({ ...l, id });\r\n });\r\n\r\n return { nodes, edges };\r\n}\r\n","import {\r\n forceSimulation,\r\n forceX,\r\n forceY,\r\n forceLink,\r\n forceManyBody,\r\n forceCollide\r\n} from 'd3-force-3d';\r\nimport { treemap, hierarchy } from 'd3-hierarchy';\r\n\r\n/**\r\n * Used for calculating clusterings of nodes.\r\n *\r\n * Modified version of: https://github.com/john-guerra/forceInABox\r\n *\r\n * Changes:\r\n * - Improved d3 import for tree shaking\r\n * - Fixed node lookup for edges using array\r\n * - Updated d3-force to use d3-force-3d\r\n * - Removed template logic\r\n */\r\nexport function forceInABox() {\r\n // d3 style\r\n const constant = (_: any) => () => _;\r\n const index = (d: any) => d.index;\r\n\r\n // Default values\r\n let id = index;\r\n let nodes = [];\r\n let links = []; // needed for the force version\r\n let tree;\r\n let size = [100, 100];\r\n let forceNodeSize = constant(1); // The expected node size used for computing the cluster node\r\n let forceCharge = constant(-1);\r\n let forceLinkDistance = constant(100);\r\n let forceLinkStrength = constant(0.1);\r\n let foci = {};\r\n let linkStrengthIntraCluster = 0.1;\r\n let linkStrengthInterCluster = 0.001;\r\n let templateNodes = [];\r\n let offset = [0, 0];\r\n let templateForce;\r\n let groupBy = d => d.cluster;\r\n let template = 'treemap';\r\n let enableGrouping = true;\r\n let strength = 0.1;\r\n\r\n function force(alpha) {\r\n if (!enableGrouping) {\r\n return force;\r\n }\r\n\r\n if (template === 'force') {\r\n // Do the tick of the template force and get the new focis\r\n templateForce.tick();\r\n getFocisFromTemplate();\r\n }\r\n\r\n for (let i = 0, n = nodes.length, node, k = alpha * strength; i < n; ++i) {\r\n node = nodes[i];\r\n node.vx += (foci[groupBy(node)].x - node.x) * k;\r\n node.vy += (foci[groupBy(node)].y - node.y) * k;\r\n }\r\n }\r\n\r\n function initialize() {\r\n if (!nodes) {\r\n return;\r\n }\r\n\r\n if (template === 'treemap') {\r\n initializeWithTreemap();\r\n } else {\r\n initializeWithForce();\r\n }\r\n }\r\n\r\n force.initialize = function (_) {\r\n nodes = _;\r\n initialize();\r\n };\r\n\r\n function getLinkKey(l) {\r\n let sourceID = groupBy(l.source),\r\n targetID = groupBy(l.target);\r\n\r\n return sourceID <= targetID\r\n ? sourceID + '~' + targetID\r\n : targetID + '~' + sourceID;\r\n }\r\n\r\n function computeClustersNodeCounts(nodes) {\r\n let clustersCounts = new Map(),\r\n tmpCount: any = {};\r\n\r\n nodes.forEach(function (d) {\r\n if (!clustersCounts.has(groupBy(d))) {\r\n clustersCounts.set(groupBy(d), { count: 0, sumforceNodeSize: 0 });\r\n }\r\n });\r\n\r\n nodes.forEach(function (d) {\r\n tmpCount = clustersCounts.get(groupBy(d));\r\n tmpCount.count = tmpCount.count + 1;\r\n tmpCount.sumforceNodeSize =\r\n tmpCount.sumforceNodeSize +\r\n // @ts-ignore\r\n Math.PI * (forceNodeSize(d) * forceNodeSize(d)) * 1.3;\r\n clustersCounts.set(groupBy(d), tmpCount);\r\n });\r\n\r\n return clustersCounts;\r\n }\r\n\r\n //Returns\r\n function computeClustersLinkCounts(links) {\r\n let dClusterLinks = new Map(),\r\n clusterLinks = [];\r\n\r\n links.forEach(function (l) {\r\n let key = getLinkKey(l),\r\n count;\r\n if (dClusterLinks.has(key)) {\r\n count = dClusterLinks.get(key);\r\n } else {\r\n count = 0;\r\n }\r\n count += 1;\r\n dClusterLinks.set(key, count);\r\n });\r\n\r\n dClusterLinks.forEach(function (value, key) {\r\n let source, target;\r\n source = key.split('~')[0];\r\n target = key.split('~')[1];\r\n if (source !== undefined && target !== undefined) {\r\n clusterLinks.push({\r\n source: source,\r\n target: target,\r\n count: value\r\n });\r\n }\r\n });\r\n\r\n return clusterLinks;\r\n }\r\n\r\n //Returns the metagraph of the clusters\r\n function getGroupsGraph() {\r\n let gnodes = [];\r\n let glinks = [];\r\n let dNodes = new Map();\r\n let c;\r\n let i;\r\n let cc;\r\n let clustersCounts;\r\n let clustersLinks;\r\n\r\n clustersCounts = computeClustersNodeCounts(nodes);\r\n clustersLinks = computeClustersLinkCounts(links);\r\n\r\n for (c of clustersCounts.keys()) {\r\n cc = clustersCounts.get(c);\r\n gnodes.push({\r\n id: c,\r\n size: cc.count,\r\n r: Math.sqrt(cc.sumforceNodeSize / Math.PI)\r\n }); // Uses approx meta-node size\r\n dNodes.set(c, i);\r\n }\r\n\r\n clustersLinks.forEach(function (l) {\r\n let source = dNodes.get(l.source),\r\n target = dNodes.get(l.target);\r\n if (source !== undefined && target !== undefined) {\r\n glinks.push({\r\n source: source,\r\n target: target,\r\n count: l.count\r\n });\r\n }\r\n });\r\n\r\n return { nodes: gnodes, links: glinks };\r\n }\r\n\r\n function getGroupsTree() {\r\n let children = [];\r\n let c;\r\n let cc;\r\n let clustersCounts;\r\n\r\n // @ts-ignore\r\n clustersCounts = computeClustersNodeCounts(force.nodes());\r\n\r\n for (c of clustersCounts.keys()) {\r\n cc = clustersCounts.get(c);\r\n children.push({ id: c, size: cc.count });\r\n }\r\n return { id: 'clustersTree', children: children };\r\n }\r\n\r\n function getFocisFromTemplate() {\r\n //compute foci\r\n // @ts-ignore\r\n foci.none = { x: 0, y: 0 };\r\n templateNodes.forEach(function (d) {\r\n if (template === 'treemap') {\r\n foci[d.data.id] = {\r\n x: d.x0 + (d.x1 - d.x0) / 2 - offset[0],\r\n y: d.y0 + (d.y1 - d.y0) / 2 - offset[1]\r\n };\r\n } else {\r\n foci[d.id] = {\r\n x: d.x - offset[0],\r\n y: d.y - offset[1]\r\n };\r\n }\r\n });\r\n return foci;\r\n }\r\n\r\n function initializeWithTreemap() {\r\n // @ts-ignore\r\n let sim = treemap().size(force.size());\r\n\r\n tree = hierarchy(getGroupsTree())\r\n .sum((d: any) => d.radius)\r\n .sort(function (a, b) {\r\n return b.height - a.height || b.value - a.value;\r\n });\r\n\r\n templateNodes = sim(tree).leaves();\r\n getFocisFromTemplate();\r\n }\r\n\r\n function checkLinksAsObjects() {\r\n // Check if links come in the format of indexes instead of objects\r\n let linkCount = 0;\r\n if (nodes.length === 0) return;\r\n\r\n links.forEach(function (link) {\r\n let source, target;\r\n if (!nodes) {\r\n return;\r\n }\r\n\r\n source = link.source;\r\n target = link.target;\r\n\r\n if (typeof link.source !== 'object') {\r\n source = nodes.find(n => n.id === link.source);\r\n }\r\n\r\n if (typeof link.target !== 'object') {\r\n target = nodes.find(n => n.id === link.target);\r\n }\r\n\r\n if (source === undefined || target === undefined) {\r\n throw Error(\r\n 'Error setting links, couldnt find nodes for a link (see it on the console)'\r\n );\r\n }\r\n link.source = source;\r\n link.target = target;\r\n link.index = linkCount++;\r\n });\r\n }\r\n\r\n function initializeWithForce() {\r\n let net;\r\n\r\n if (!nodes || !nodes.length) {\r\n return;\r\n }\r\n\r\n checkLinksAsObjects();\r\n\r\n net = getGroupsGraph();\r\n templateForce = forceSimulation(net.nodes)\r\n .force('x', forceX(size[0] / 2).strength(0.1))\r\n .force('y', forceY(size[1] / 2).strength(0.1))\r\n .force('collide', forceCollide(d => d.r).iterations(4))\r\n .force('charge', forceManyBody().strength(forceCharge))\r\n .force(\r\n 'links',\r\n forceLink(net.nodes.length ? net.links : [])\r\n .distance(forceLinkDistance)\r\n .strength(forceLinkStrength)\r\n );\r\n\r\n templateNodes = templateForce.nodes();\r\n\r\n getFocisFromTemplate();\r\n }\r\n\r\n force.template = function (x) {\r\n if (!arguments.length) {\r\n return template;\r\n }\r\n\r\n template = x;\r\n initialize();\r\n return force;\r\n };\r\n\r\n force.groupBy = function (x) {\r\n if (!arguments.length) {\r\n return groupBy;\r\n }\r\n\r\n if (typeof x === 'string') {\r\n groupBy = function (d) {\r\n return d[x];\r\n };\r\n\r\n return force;\r\n }\r\n\r\n groupBy = x;\r\n\r\n return force;\r\n };\r\n\r\n force.enableGrouping = function (x) {\r\n if (!arguments.length) {\r\n return enableGrouping;\r\n }\r\n\r\n enableGrouping = x;\r\n\r\n return force;\r\n };\r\n\r\n force.strength = function (x) {\r\n if (!arguments.length) {\r\n return strength;\r\n }\r\n\r\n strength = x;\r\n\r\n return force as any;\r\n };\r\n\r\n force.getLinkStrength = function (e) {\r\n if (enableGrouping) {\r\n if (groupBy(e.source) === groupBy(e.target)) {\r\n if (typeof linkStrengthIntraCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthIntraCluster(e);\r\n } else {\r\n return linkStrengthIntraCluster;\r\n }\r\n } else {\r\n if (typeof linkStrengthInterCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthInterCluster(e);\r\n } else {\r\n return linkStrengthInterCluster;\r\n }\r\n }\r\n } else {\r\n // Not grouping return the intracluster\r\n if (typeof linkStrengthIntraCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthIntraCluster(e);\r\n } else {\r\n return linkStrengthIntraCluster;\r\n }\r\n }\r\n };\r\n\r\n force.id = function (_) {\r\n return arguments.length ? ((id = _), force) : id;\r\n };\r\n\r\n force.size = function (_) {\r\n return arguments.length ? ((size = _), force) : size;\r\n };\r\n\r\n force.linkStrengthInterCluster = function (_) {\r\n return arguments.length\r\n ? ((linkStrengthInterCluster = _), force)\r\n : linkStrengthInterCluster;\r\n };\r\n\r\n force.linkStrengthIntraCluster = function (_) {\r\n return arguments.length\r\n ? ((linkStrengthIntraCluster = _), force)\r\n : linkStrengthIntraCluster;\r\n };\r\n\r\n force.nodes = function (_) {\r\n return arguments.length ? ((nodes = _), force) : nodes;\r\n };\r\n\r\n force.links = function (_) {\r\n if (!arguments.length) {\r\n return links;\r\n }\r\n\r\n if (_ === null) {\r\n links = [];\r\n } else {\r\n links = _;\r\n }\r\n\r\n initialize();\r\n\r\n return force;\r\n };\r\n\r\n force.template = function (x) {\r\n if (!arguments.length) {\r\n return template;\r\n }\r\n\r\n template = x;\r\n initialize();\r\n return force;\r\n };\r\n\r\n force.forceNodeSize = function (_) {\r\n return arguments.length\r\n ? ((forceNodeSize = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceNodeSize;\r\n };\r\n\r\n // Legacy support\r\n force.nodeSize = force.forceNodeSize;\r\n\r\n force.forceCharge = function (_) {\r\n return arguments.length\r\n ? ((forceCharge = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceCharge;\r\n };\r\n\r\n force.forceLinkDistance = function (_) {\r\n return arguments.length\r\n ? ((forceLinkDistance = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceLinkDistance;\r\n };\r\n\r\n force.forceLinkStrength = function (_) {\r\n return arguments.length\r\n ? ((forceLinkStrength = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceLinkStrength;\r\n };\r\n\r\n force.offset = function (_) {\r\n return arguments.length\r\n ? ((offset = typeof _ === 'function' ? _ : constant(+_)), force)\r\n : offset;\r\n };\r\n\r\n force.getFocis = getFocisFromTemplate;\r\n\r\n return force;\r\n}\r\n","import {\r\n forceSimulation as d3ForceSimulation,\r\n forceLink as d3ForceLink,\r\n forceCollide,\r\n forceManyBody as d3ForceManyBody,\r\n forceX as d3ForceX,\r\n forceY as d3ForceY,\r\n forceZ as d3ForceZ,\r\n forceCenter as d3ForceCenter\r\n} from 'd3-force-3d';\r\nimport { forceRadial, DagMode } from './forceUtils';\r\nimport { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\nimport { forceInABox } from './forceInABox';\r\nimport { FORCE_LAYOUTS } from './layoutProvider';\r\n\r\nexport interface ForceDirectedLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Center inertia for the layout. Default: 1.\r\n */\r\n centerInertia?: number;\r\n\r\n /**\r\n * Number of dimensions for the layout. 2d or 3d.\r\n */\r\n dimensions?: number;\r\n\r\n /**\r\n * Mode for the dag layout. Only applicable for dag layouts.\r\n */\r\n mode?: DagMode;\r\n\r\n /**\r\n * Distance between links.\r\n */\r\n linkDistance?: number;\r\n\r\n /**\r\n * Strength of the node repulsion.\r\n */\r\n nodeStrength?: number;\r\n\r\n /**\r\n * Strength of the cluster repulsion.\r\n */\r\n clusterStrength?: number;\r\n\r\n /**\r\n * The type of clustering.\r\n */\r\n clusterType?: 'force' | 'treemap';\r\n\r\n /**\r\n * Ratio of the distance between nodes on the same level.\r\n */\r\n nodeLevelRatio?: number;\r\n\r\n /**\r\n * LinkStrength between nodes of different clusters\r\n */\r\n linkStrengthInterCluster?: number | ((d: any) => number);\r\n\r\n /**\r\n * LinkStrength between nodes of the same cluster\r\n */\r\n linkStrengthIntraCluster?: number | ((d: any) => number);\r\n\r\n /**\r\n * Charge between the meta-nodes (Force template only)\r\n */\r\n forceLinkDistance?: number;\r\n\r\n /**\r\n * Used to compute the template force nodes size (Force template only)\r\n */\r\n forceLinkStrength?: number;\r\n\r\n /**\r\n * Used to compute the template force nodes size (Force template only)\r\n */\r\n forceCharge?: number;\r\n\r\n /**\r\n * Used to determine the simulation forceX and forceY values\r\n */\r\n forceLayout: (typeof FORCE_LAYOUTS)[number];\r\n}\r\n\r\nexport function forceDirected({\r\n graph,\r\n nodeLevelRatio = 2,\r\n mode = null,\r\n dimensions = 2,\r\n nodeStrength = -250,\r\n linkDistance = 100,\r\n clusterStrength = 0.5,\r\n linkStrengthInterCluster = 0.01,\r\n linkStrengthIntraCluster = 0.5,\r\n forceLinkDistance = 100,\r\n forceLinkStrength = 0.1,\r\n clusterType = 'force',\r\n forceCharge = -700,\r\n getNodePosition,\r\n drags,\r\n clusterAttribute,\r\n forceLayout\r\n}: ForceDirectedLayoutInputs): LayoutStrategy {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n // Dynamically adjust node strength based on the number of edges\r\n const is2d = dimensions === 2;\r\n const nodeStrengthAdjustment =\r\n is2d && edges.length > 25 ? nodeStrength * 2 : nodeStrength;\r\n\r\n let forceX;\r\n let forceY;\r\n if (forceLayout === 'forceDirected2d') {\r\n forceX = d3ForceX();\r\n forceY = d3ForceY();\r\n } else {\r\n forceX = d3ForceX(600).strength(0.05);\r\n forceY = d3ForceY(600).strength(0.05);\r\n }\r\n\r\n // Create the simulation\r\n const sim = d3ForceSimulation()\r\n .force('center', d3ForceCenter(0, 0))\r\n .force('link', d3ForceLink())\r\n .force('charge', d3ForceManyBody().strength(nodeStrengthAdjustment))\r\n .force('x', forceX)\r\n .force('y', forceY)\r\n .force('z', d3ForceZ())\r\n // Handles nodes not overlapping each other ( most relevant in clustering )\r\n .force(\r\n 'collide',\r\n forceCollide(d => d.radius + 10)\r\n )\r\n .force(\r\n 'dagRadial',\r\n forceRadial({\r\n nodes,\r\n edges,\r\n mode,\r\n nodeLevelRatio\r\n })\r\n )\r\n .stop();\r\n\r\n let groupingForce;\r\n if (clusterAttribute) {\r\n // Dynamically adjust cluster force charge based on the number of nodes\r\n let forceChargeAdjustment = forceCharge;\r\n if (nodes?.length) {\r\n const adjustmentFactor = Math.ceil(nodes.length / 200);\r\n forceChargeAdjustment = forceCharge * adjustmentFactor;\r\n }\r\n\r\n groupingForce = forceInABox()\r\n // Strength to foci\r\n .strength(clusterStrength)\r\n // Either treemap or force\r\n .template(clusterType)\r\n // Node attribute to group\r\n .groupBy(d => d.data[clusterAttribute])\r\n // The graph links. Must be called after setting the grouping attribute\r\n .links(edges)\r\n // Size of the chart\r\n .size([100, 100])\r\n // linkStrength between nodes of different clusters\r\n .linkStrengthInterCluster(linkStrengthInterCluster)\r\n // linkStrength between nodes of the same cluster\r\n .linkStrengthIntraCluster(linkStrengthIntraCluster)\r\n // linkDistance between meta-nodes on the template (Force template only)\r\n .forceLinkDistance(forceLinkDistance)\r\n // linkStrength between meta-nodes of the template (Force template only)\r\n .forceLinkStrength(forceLinkStrength)\r\n // Charge between the meta-nodes (Force template only)\r\n .forceCharge(forceChargeAdjustment)\r\n // Used to compute the template force nodes size (Force template only)\r\n .forceNodeSize(d => d.radius);\r\n }\r\n\r\n // Initialize the simulation\r\n let layout = sim.numDimensions(dimensions).nodes(nodes);\r\n\r\n if (groupingForce) {\r\n layout = layout.force('group', groupingForce);\r\n }\r\n\r\n // Run the force on the links\r\n if (linkDistance) {\r\n let linkForce = layout.force('link');\r\n if (linkForce) {\r\n linkForce\r\n .id(d => d.id)\r\n .links(edges)\r\n // When no mode passed, its a tree layout\r\n // so let's use a larger distance\r\n .distance(linkDistance);\r\n\r\n if (groupingForce) {\r\n linkForce = linkForce.strength(groupingForce?.getLinkStrength ?? 0.1);\r\n }\r\n }\r\n }\r\n\r\n const nodeMap = new Map(nodes.map(n => [n.id, n]));\r\n\r\n return {\r\n step() {\r\n // Run the simulation til we get a stable result\r\n while (sim.alpha() > 0.01) {\r\n sim.tick();\r\n }\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return nodeMap.get(id);\r\n }\r\n };\r\n}\r\n","import circular from 'graphology-layout/circular.js';\r\nimport { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface CircularLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Radius of the circle.\r\n */\r\n radius: 300;\r\n}\r\n\r\nexport function circular2d({\r\n graph,\r\n radius,\r\n drags,\r\n getNodePosition\r\n}: CircularLayoutInputs) {\r\n const layout = circular(graph, {\r\n scale: radius\r\n });\r\n\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return layout?.[id];\r\n }\r\n };\r\n}\r\n","import { InternalGraphEdge, InternalGraphNode } from 'types';\r\nimport { DepthNode, getNodeDepth } from './depthUtils';\r\nimport { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { hierarchy, stratify, tree } from 'd3-hierarchy';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface HierarchicalLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Direction of the layout. Default 'td'.\r\n */\r\n mode?: 'td' | 'lr';\r\n /**\r\n * Factor of distance between nodes. Default 1.\r\n */\r\n nodeSeparation?: number;\r\n /**\r\n * Size of each node. Default [50,50]\r\n */\r\n nodeSize?: [number, number];\r\n}\r\n\r\nconst DIRECTION_MAP = {\r\n td: {\r\n x: 'x',\r\n y: 'y',\r\n factor: -1\r\n },\r\n lr: {\r\n x: 'y',\r\n y: 'x',\r\n factor: 1\r\n }\r\n};\r\n\r\nexport function hierarchical({\r\n graph,\r\n drags,\r\n mode = 'td',\r\n nodeSeparation = 2,\r\n nodeSize = [60, 60],\r\n getNodePosition\r\n}: HierarchicalLayoutInputs): LayoutStrategy {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n // find root node by finding the nodes which have no incoming edges\r\n const parentNodes = nodes.filter(n => !edges.find(e => e.target === n.id));\r\n console.log('parentNodes', parentNodes);\r\n\r\n // if more than 1 root node, then we have multiple trees\r\n // insert a fake root node to connect all root nodes\r\n if (parentNodes.length > 1) {\r\n const fakeRootNode: InternalGraphNode = {\r\n id: 'fakeRoot',\r\n label: '',\r\n fill: '#fff',\r\n activeFill: '#fff',\r\n icon: '',\r\n data: {\r\n id: 'fakeRoot',\r\n loaded: true,\r\n extra: {\r\n id: 'fakeRoot',\r\n properties: {},\r\n labels: []\r\n },\r\n className: '',\r\n style: {\r\n label: ''\r\n }\r\n },\r\n position: {\r\n id: '',\r\n data: {},\r\n links: [],\r\n index: 0,\r\n x: 0,\r\n y: 0,\r\n z: 0,\r\n vx: 0,\r\n vy: 0\r\n }\r\n };\r\n\r\n // add fake root node to nodes\r\n nodes.push(fakeRootNode);\r\n\r\n // add edges from fake root to root nodes\r\n parentNodes.forEach(n => {\r\n edges.push({\r\n id: `fakeRoot-${n.id}`,\r\n source: 'fakeRoot',\r\n target: n.id,\r\n label: '',\r\n backgroundColor: '#fff'\r\n });\r\n });\r\n }\r\n\r\n const { depths } = getNodeDepth(nodes, edges);\r\n const rootNodes = Object.keys(depths).map(d => depths[d]);\r\n\r\n const root = stratify()\r\n .id(d => d.data.id)\r\n .parentId(d => d.ins?.[0]?.data?.id)(rootNodes);\r\n\r\n const treeRoot = tree()\r\n .separation(() => nodeSeparation)\r\n .nodeSize(nodeSize)(hierarchy(root));\r\n\r\n const treeNodes = treeRoot.descendants();\r\n const path = DIRECTION_MAP[mode];\r\n\r\n const mappedNodes = new Map(\r\n nodes.map(n => {\r\n const { x, y } = treeNodes.find((t: any) => t.data.id === n.id);\r\n return [\r\n n.id,\r\n {\r\n ...n,\r\n [path.x]: x * path.factor,\r\n [path.y]: y * path.factor,\r\n z: 0\r\n }\r\n ];\r\n })\r\n );\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return mappedNodes.get(id);\r\n }\r\n };\r\n}\r\n","import noverlapLayout from 'graphology-layout-noverlap';\r\nimport { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface NoOverlapLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Grid size. Default 20.\r\n */\r\n gridSize?: number;\r\n\r\n /**\r\n * Ratio of the layout. Default 10.\r\n */\r\n ratio?: number;\r\n\r\n /**\r\n * Maximum number of iterations. Default 50.\r\n */\r\n maxIterations?: number;\r\n\r\n /**\r\n * Margin between nodes. Default 10.\r\n */\r\n margin?: number;\r\n}\r\n\r\nexport function nooverlap({\r\n graph,\r\n margin,\r\n drags,\r\n getNodePosition,\r\n ratio,\r\n gridSize,\r\n maxIterations\r\n}: NoOverlapLayoutInputs) {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n const layout = noverlapLayout(graph, {\r\n maxIterations,\r\n inputReducer: (_key, attr) => ({\r\n ...attr,\r\n // Have to specify defaults for the engine\r\n x: attr.x || 0,\r\n y: attr.y || 0\r\n }),\r\n settings: {\r\n ratio,\r\n margin,\r\n gridSize\r\n }\r\n });\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return layout?.[id];\r\n }\r\n };\r\n}\r\n","import forceAtlas2Layout from 'graphology-layout-forceatlas2';\r\nimport { LayoutFactoryProps } from './types';\r\nimport random from 'graphology-layout/random.js';\r\n\r\nexport interface ForceAtlas2LayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Should the node’s sizes be taken into account. Default: false.\r\n */\r\n adjustSizes?: boolean;\r\n\r\n /**\r\n * whether to use the Barnes-Hut approximation to compute\r\n * repulsion in O(n*log(n)) rather than default O(n^2),\r\n * n being the number of nodes. Default: false.\r\n */\r\n barnesHutOptimize?: boolean;\r\n\r\n /**\r\n * Barnes-Hut approximation theta parameter. Default: 0.5.\r\n */\r\n barnesHutTheta?: number;\r\n\r\n /**\r\n * Influence of the edge’s weights on the layout. To consider edge weight, don’t\r\n * forget to pass weighted as true. Default: 1.\r\n */\r\n edgeWeightInfluence?: number;\r\n\r\n /**\r\n * Strength of the layout’s gravity. Default: 10.\r\n */\r\n gravity?: number;\r\n\r\n /**\r\n * Whether to use Noack’s LinLog model. Default: false.\r\n */\r\n linLogMode?: boolean;\r\n\r\n /**\r\n * Whether to consider edge weights when calculating repulsion. Default: false.\r\n */\r\n outboundAttractionDistribution?: boolean;\r\n\r\n /**\r\n * Scaling ratio for repulsion. Default: 100.\r\n */\r\n scalingRatio?: number;\r\n\r\n /**\r\n * Speed of the slowdown. Default: 1.\r\n */\r\n slowDown?: number;\r\n\r\n /**\r\n * Whether to use the strong gravity mode. Default: false.\r\n */\r\n strongGravityMode?: boolean;\r\n\r\n /**\r\n * Number of iterations to perform. Default: 50.\r\n */\r\n iterations?: number;\r\n}\r\n\r\nexport function forceAtlas2({\r\n graph,\r\n drags,\r\n iterations,\r\n ...rest\r\n}: ForceAtlas2LayoutInputs) {\r\n // Note: We need to assign a random position to each node\r\n // in order for the force atlas to work.\r\n // Reference: https://graphology.github.io/standard-library/layout-forceatlas2.html#pre-requisites\r\n random.assign(graph);\r\n\r\n const layout = forceAtlas2Layout(graph, {\r\n iterations,\r\n settings: rest\r\n });\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n // If we dragged, we need to use that position\r\n return (drags?.[id]?.position as any) || layout?.[id];\r\n }\r\n };\r\n}\r\n","import { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport function custom({ graph, drags, getNodePosition }: LayoutFactoryProps) {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n return getNodePosition(id, { graph, drags, nodes, edges });\r\n }\r\n };\r\n}\r\n","import { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { forceDirected, ForceDirectedLayoutInputs } from './forceDirected';\r\nimport { circular2d, CircularLayoutInputs } from './circular2d';\r\nimport { hierarchical, HierarchicalLayoutInputs } from './hierarchical';\r\nimport { NoOverlapLayoutInputs, nooverlap } from './nooverlap';\r\nimport { ForceAtlas2LayoutInputs, forceAtlas2 } from './forceatlas2';\r\nimport { custom } from './custom';\r\n\r\nexport type LayoutOverrides = Partial<\r\n | Omit\r\n | CircularLayoutInputs\r\n | HierarchicalLayoutInputs\r\n>;\r\n\r\nexport const FORCE_LAYOUTS = [\r\n 'forceDirected2d',\r\n 'treeTd2d',\r\n 'treeLr2d',\r\n 'radialOut2d',\r\n 'treeTd3d',\r\n 'treeLr3d',\r\n 'radialOut3d',\r\n 'forceDirected3d'\r\n];\r\n\r\nexport function layoutProvider({\r\n type,\r\n ...rest\r\n}: LayoutFactoryProps | LayoutOverrides): LayoutStrategy {\r\n if (FORCE_LAYOUTS.includes(type)) {\r\n const { nodeStrength, linkDistance, nodeLevelRatio } =\r\n rest as ForceDirectedLayoutInputs;\r\n\r\n if (type === 'forceDirected2d') {\r\n return forceDirected({\r\n ...rest,\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeTd2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'td',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeLr2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'lr',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'radialOut2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'radialout',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 100,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeTd3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'td',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 50\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeLr3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'lr',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'radialOut3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'radialout',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 100,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'forceDirected3d') {\r\n return forceDirected({\r\n ...rest,\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n }\r\n } else if (type === 'circular2d') {\r\n const { radius } = rest as CircularLayoutInputs;\r\n return circular2d({\r\n ...rest,\r\n radius: radius || 300\r\n } as CircularLayoutInputs);\r\n } else if (type === 'hierarchicalTd') {\r\n return hierarchical({ ...rest, mode: 'td' } as HierarchicalLayoutInputs);\r\n } else if (type === 'hierarchicalLr') {\r\n return hierarchical({ ...rest, mode: 'lr' } as HierarchicalLayoutInputs);\r\n } else if (type === 'nooverlap') {\r\n const { graph, maxIterations, ratio, margin, gridSize, ...settings } =\r\n rest as NoOverlapLayoutInputs;\r\n\r\n return nooverlap({\r\n type: 'nooverlap',\r\n graph,\r\n margin: margin || 10,\r\n maxIterations: maxIterations || 50,\r\n ratio: ratio || 10,\r\n gridSize: gridSize || 20,\r\n ...settings\r\n });\r\n } else if (type === 'forceatlas2') {\r\n const { graph, iterations, gravity, scalingRatio, ...settings } =\r\n rest as ForceAtlas2LayoutInputs;\r\n\r\n return forceAtlas2({\r\n type: 'forceatlas2',\r\n graph,\r\n ...settings,\r\n scalingRatio: scalingRatio || 100,\r\n gravity: gravity || 10,\r\n iterations: iterations || 50\r\n });\r\n } else if (type === 'custom') {\r\n return custom({\r\n type: 'custom',\r\n ...rest\r\n } as LayoutFactoryProps);\r\n }\r\n\r\n throw new Error(`Layout ${type} not found.`);\r\n}\r\n","import { GraphEdge, GraphNode } from '../types';\r\nimport { getNodeDepth } from './depthUtils';\r\nimport { LayoutTypes } from './types';\r\n\r\n/**\r\n * Given a set of nodes and edges, determine the type of layout that\r\n * is most ideal. This is very beta.\r\n */\r\nexport function recommendLayout(\r\n nodes: GraphNode[],\r\n edges: GraphEdge[]\r\n): LayoutTypes {\r\n const { invalid } = getNodeDepth(nodes as any[], edges as any[]);\r\n const nodeCount = nodes.length;\r\n\r\n if (!invalid) {\r\n // Large tree layouts\r\n if (nodeCount > 100) {\r\n return 'radialOut2d';\r\n } else {\r\n // Smaller tree layouts\r\n return 'treeTd2d';\r\n }\r\n }\r\n\r\n // Circular layouts\r\n return 'forceDirected2d';\r\n}\r\n","import { PerspectiveCamera } from 'three';\r\nimport { EdgeLabelPosition } from '../symbols';\r\n\r\nexport type LabelVisibilityType = 'all' | 'auto' | 'none' | 'nodes' | 'edges';\r\n\r\ninterface CalcLabelVisibilityArgs {\r\n nodeCount: number;\r\n nodePosition?: { x: number; y: number; z: number };\r\n labelType: LabelVisibilityType;\r\n camera?: PerspectiveCamera;\r\n}\r\n\r\nexport function calcLabelVisibility({\r\n nodeCount,\r\n nodePosition,\r\n labelType,\r\n camera\r\n}: CalcLabelVisibilityArgs) {\r\n return (shape: 'node' | 'edge', size: number) => {\r\n if (\r\n camera &&\r\n nodePosition &&\r\n camera?.position?.z / camera?.zoom - nodePosition?.z > 6000\r\n ) {\r\n return false;\r\n }\r\n\r\n if (labelType === 'all') {\r\n return true;\r\n } else if (labelType === 'nodes' && shape === 'node') {\r\n return true;\r\n } else if (labelType === 'edges' && shape === 'edge') {\r\n return true;\r\n } else if (labelType === 'auto' && shape === 'node') {\r\n if (size > 7) {\r\n return true;\r\n } else if (\r\n camera &&\r\n nodePosition &&\r\n camera.position.z / camera.zoom - nodePosition.z < 3000\r\n ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n}\r\n\r\nexport function getLabelOffsetByType(\r\n offset: number,\r\n position: EdgeLabelPosition\r\n): number {\r\n switch (position) {\r\n case 'above':\r\n return offset;\r\n case 'below':\r\n return -offset;\r\n case 'inline':\r\n case 'natural':\r\n default:\r\n return 0;\r\n }\r\n}\r\n","import pagerank from 'graphology-metrics/centrality/pagerank.js';\r\nimport { SizingStrategy, SizingStrategyInputs } from './types';\r\n\r\nexport function pageRankSizing({\r\n graph\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const ranks = pagerank(graph);\r\n\r\n return {\r\n ranks,\r\n getSizeForNode: (nodeID: string) => ranks[nodeID] * 80\r\n };\r\n}\r\n","import { SizingStrategy, SizingStrategyInputs } from './types';\r\nimport { degreeCentrality } from 'graphology-metrics/centrality/degree.js';\r\n\r\nexport function centralitySizing({\r\n graph\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const ranks = degreeCentrality(graph);\r\n\r\n return {\r\n ranks,\r\n getSizeForNode: (nodeID: string) => ranks[nodeID] * 20\r\n };\r\n}\r\n","import { SizingStrategy, SizingStrategyInputs } from './types';\r\n\r\nexport function attributeSizing({\r\n graph,\r\n attribute,\r\n defaultSize\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const map = new Map();\r\n\r\n if (attribute) {\r\n graph.forEachNode((id, node) => {\r\n const size = node.data?.[attribute];\r\n if (isNaN(size)) {\r\n console.warn(`Attribute ${size} is not a number for node ${node.id}`);\r\n }\r\n\r\n map.set(id, size || 0);\r\n });\r\n } else {\r\n console.warn('Attribute sizing configured but no attribute provided');\r\n }\r\n\r\n return {\r\n getSizeForNode: (nodeId: string) => {\r\n if (!attribute || !map) {\r\n return defaultSize;\r\n }\r\n\r\n return map.get(nodeId);\r\n }\r\n };\r\n}\r\n","import { pageRankSizing } from './pageRank';\r\nimport { centralitySizing } from './centrality';\r\nimport { attributeSizing } from './attribute';\r\nimport { SizingStrategyInputs } from './types';\r\nimport { scaleLinear } from 'd3-scale';\r\n\r\nexport type SizingType =\r\n | 'none'\r\n | 'pagerank'\r\n | 'centrality'\r\n | 'attribute'\r\n | 'default';\r\n\r\nexport interface NodeSizeProviderInputs extends SizingStrategyInputs {\r\n /**\r\n * The sizing strategy to use.\r\n */\r\n type: SizingType;\r\n}\r\n\r\nconst providers = {\r\n pagerank: pageRankSizing,\r\n centrality: centralitySizing,\r\n attribute: attributeSizing,\r\n none: ({ defaultSize }: SizingStrategyInputs) => ({\r\n getSizeForNode: (_id: string) => defaultSize\r\n })\r\n};\r\n\r\nexport function nodeSizeProvider({ type, ...rest }: NodeSizeProviderInputs) {\r\n const provider = providers[type]?.(rest);\r\n if (!provider && type !== 'default') {\r\n throw new Error(`Unknown sizing strategy: ${type}`);\r\n }\r\n\r\n const { graph, minSize, maxSize } = rest;\r\n const sizes = new Map();\r\n let min;\r\n let max;\r\n\r\n graph.forEachNode((id, node) => {\r\n let size;\r\n if (type === 'default') {\r\n size = node.size || rest.defaultSize;\r\n } else {\r\n size = provider.getSizeForNode(id);\r\n }\r\n\r\n if (min === undefined || size < min) {\r\n min = size;\r\n }\r\n\r\n if (max === undefined || size > max) {\r\n max = size;\r\n }\r\n\r\n sizes.set(id, size);\r\n });\r\n\r\n // Relatively scale the sizes\r\n if (type !== 'none') {\r\n const scale = scaleLinear()\r\n .domain([min, max])\r\n .rangeRound([minSize, maxSize]);\r\n\r\n for (const [nodeId, size] of sizes) {\r\n sizes.set(nodeId, scale(size));\r\n }\r\n }\r\n\r\n return sizes;\r\n}\r\n","import Graph from 'graphology';\r\nimport { nodeSizeProvider, SizingType } from '../sizing';\r\nimport {\r\n GraphEdge,\r\n GraphNode,\r\n InternalGraphEdge,\r\n InternalGraphNode\r\n} from '../types';\r\nimport { calcLabelVisibility, LabelVisibilityType } from './visibility';\r\nimport { LayoutStrategy } from '../layout';\r\n\r\n/**\r\n * Initialize the graph with the nodes/edges.\r\n */\r\nexport function buildGraph(\r\n graph: Graph,\r\n nodes: GraphNode[],\r\n edges: GraphEdge[]\r\n) {\r\n // TODO: We probably want to make this\r\n // smarter and only add/remove nodes\r\n graph.clear();\r\n\r\n for (const node of nodes) {\r\n try {\r\n graph.addNode(node.id, node);\r\n } catch ({ message }) {\r\n console.error(`[Graph] ${message}`);\r\n }\r\n }\r\n\r\n for (const edge of edges) {\r\n try {\r\n graph.addEdge(edge.source, edge.target, edge);\r\n } catch ({ message }) {\r\n console.error(`[Graph] ${message}`);\r\n }\r\n }\r\n\r\n return graph;\r\n}\r\n\r\ninterface TransformGraphInput {\r\n graph: Graph;\r\n layout: LayoutStrategy;\r\n sizingType?: SizingType;\r\n labelType?: LabelVisibilityType;\r\n sizingAttribute?: string;\r\n minNodeSize?: number;\r\n maxNodeSize?: number;\r\n defaultNodeSize?: number;\r\n}\r\n\r\n/**\r\n * Transform the graph into a format that is easier to work with.\r\n */\r\nexport function transformGraph({\r\n graph,\r\n layout,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n defaultNodeSize,\r\n minNodeSize,\r\n maxNodeSize\r\n}: TransformGraphInput) {\r\n const nodes: InternalGraphNode[] = [];\r\n const edges: InternalGraphEdge[] = [];\r\n const map = new Map();\r\n\r\n const sizes = nodeSizeProvider({\r\n graph,\r\n type: sizingType,\r\n attribute: sizingAttribute,\r\n minSize: minNodeSize,\r\n maxSize: maxNodeSize,\r\n defaultSize: defaultNodeSize\r\n });\r\n\r\n const nodeCount = graph.nodes().length;\r\n const checkVisibility = calcLabelVisibility({ nodeCount, labelType });\r\n\r\n graph.forEachNode((id, node) => {\r\n const position = layout.getNodePosition(id);\r\n const { data, fill, icon, label, size, ...rest } = node;\r\n const nodeSize = sizes.get(node.id);\r\n const labelVisible = checkVisibility('node', nodeSize);\r\n\r\n const nodeLinks = graph.inboundNeighbors(node.id) || [];\r\n const parents = nodeLinks.map(n => graph.getNodeAttributes(n));\r\n\r\n const n: InternalGraphNode = {\r\n ...(node as any),\r\n size: nodeSize,\r\n labelVisible,\r\n label,\r\n icon,\r\n fill,\r\n parents,\r\n data: {\r\n ...rest,\r\n ...(data ?? {})\r\n },\r\n position: {\r\n ...position,\r\n x: position.x || 0,\r\n y: position.y || 0,\r\n z: position.z || 1\r\n }\r\n };\r\n\r\n map.set(node.id, n);\r\n nodes.push(n);\r\n });\r\n\r\n graph.forEachEdge((_id, link) => {\r\n const from = map.get(link.source);\r\n const to = map.get(link.target);\r\n\r\n if (from && to) {\r\n const { data, id, label, size, ...rest } = link;\r\n const labelVisible = checkVisibility('edge', size);\r\n\r\n // TODO: Fix type\r\n edges.push({\r\n ...link,\r\n id,\r\n label,\r\n labelVisible,\r\n size,\r\n data: {\r\n ...rest,\r\n id,\r\n ...(data || {})\r\n }\r\n } as any);\r\n }\r\n });\r\n\r\n return {\r\n nodes,\r\n edges\r\n };\r\n}\r\n","export const animationConfig = {\r\n mass: 10,\r\n tension: 1000,\r\n friction: 300,\r\n // Decreasing precision to improve performance from 0.00001\r\n precision: 0.1\r\n};\r\n","import { Curve, Vector3 } from 'three';\r\n\r\nimport { EdgeArrowPosition } from '../symbols/Arrow';\r\n\r\n// Calculate the correct position for an arrow along a curve,\r\n// as well as the tangent to the curve at that point.\r\nexport function getArrowVectors(\r\n placement: EdgeArrowPosition,\r\n curve: Curve,\r\n arrowLength: number\r\n): [Vector3, Vector3] {\r\n const curveLength = curve.getLength();\r\n const absSize = placement === 'end' ? curveLength : curveLength / 2;\r\n const offset = placement === 'end' ? arrowLength / 2 : 0;\r\n const u = (absSize - offset) / curveLength;\r\n\r\n const position = curve.getPointAt(u);\r\n const rotation = curve.getTangentAt(u);\r\n\r\n return [position, rotation];\r\n}\r\n\r\nexport function getArrowSize(size: number): [number, number] {\r\n return [size + 6, 2 + size / 1.5];\r\n}\r\n","import { Curve, LineCurve3, QuadraticBezierCurve3, Vector3 } from 'three';\r\nimport { InternalGraphNode, InternalVector3 } from '../types';\r\n\r\nconst MULTI_EDGE_OFFSET_FACTOR = 0.7;\r\n\r\n/**\r\n * Get the midpoint given two points.\r\n */\r\nexport function getMidPoint(\r\n from: InternalVector3,\r\n to: InternalVector3,\r\n offset = 0\r\n) {\r\n const fromVector = new Vector3(from.x, from.y || 0, from.z || 0);\r\n const toVector = new Vector3(to.x, to.y || 0, to.z || 0);\r\n const midVector = new Vector3()\r\n .addVectors(fromVector, toVector)\r\n .divideScalar(2);\r\n\r\n return midVector.setLength(midVector.length() + offset);\r\n}\r\n\r\n/**\r\n * Calculate the center for a quadratic bezier curve.\r\n *\r\n * 1) Find the point halfway between the start and end points of the desired curve\r\n * 2) Find the vector pependicular to that point\r\n * 3) Find the point 1/4 the distance between start and end along that vector.\r\n */\r\nexport function getCurvePoints(\r\n from: Vector3,\r\n to: Vector3,\r\n offset = -1\r\n): [Vector3, Vector3, Vector3] {\r\n const fromVector = from.clone();\r\n const toVector = to.clone();\r\n const v = new Vector3().subVectors(toVector, fromVector);\r\n const vlen = v.length();\r\n const vn = v.clone().normalize();\r\n const vv = new Vector3().subVectors(toVector, fromVector).divideScalar(2);\r\n const k = Math.abs(vn.x) % 1;\r\n const b = new Vector3(-vn.y, vn.x - k * vn.z, k * vn.y).normalize();\r\n const vm = new Vector3()\r\n .add(fromVector)\r\n .add(vv)\r\n .add(b.multiplyScalar(vlen / 4).multiplyScalar(offset));\r\n\r\n return [from, vm, to];\r\n}\r\n\r\n/**\r\n * Get the curve given two points.\r\n */\r\nexport function getCurve(\r\n from: Vector3,\r\n fromOffset: number,\r\n to: Vector3,\r\n toOffset: number,\r\n curved: boolean,\r\n curveOffset?: number\r\n): Curve {\r\n const offsetFrom = getPointBetween(from, to, fromOffset);\r\n const offsetTo = getPointBetween(to, from, toOffset);\r\n return curved\r\n ? new QuadraticBezierCurve3(\r\n ...getCurvePoints(offsetFrom, offsetTo, curveOffset)\r\n )\r\n : new LineCurve3(offsetFrom, offsetTo);\r\n}\r\n\r\n/**\r\n * Create a threejs vector for a node.\r\n */\r\nexport function getVector(node: InternalGraphNode): Vector3 {\r\n return new Vector3(node.position.x, node.position.y, node.position.z || 0);\r\n}\r\n\r\n/**\r\n * Get the point between two vectors.\r\n */\r\nfunction getPointBetween(from: Vector3, to: Vector3, offset: number): Vector3 {\r\n const distance = from.distanceTo(to);\r\n return from.clone().add(\r\n to\r\n .clone()\r\n .sub(from)\r\n .multiplyScalar(offset / distance)\r\n );\r\n}\r\n\r\n/**\r\n * Given a node and a new vector set, update the node model.\r\n */\r\nexport function updateNodePosition(node: InternalGraphNode, offset: Vector3) {\r\n return {\r\n ...node,\r\n position: {\r\n ...node.position,\r\n x: node.position.x + offset.x,\r\n y: node.position.y + offset.y,\r\n z: node.position.z + offset.z\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Calculate the curve offset for an edge.\r\n * This is used to offset edges that are parallel to each other (same source and same target).\r\n * This will return a curveOffset of null if the edge is not parallel to any other edges.\r\n */\r\nexport function calculateEdgeCurveOffset({ edge, edges, curved }) {\r\n let updatedCurved = curved;\r\n let curveOffset: number;\r\n\r\n const parallelEdges = edges\r\n .filter(e => e.target === edge.target && e.source === edge.source)\r\n .map(e => e.id);\r\n\r\n if (parallelEdges.length > 1) {\r\n updatedCurved = true;\r\n const edgeIndex = parallelEdges.indexOf(edge.id);\r\n\r\n if (parallelEdges.length === 2) {\r\n curveOffset =\r\n edgeIndex === 0 ? MULTI_EDGE_OFFSET_FACTOR : -MULTI_EDGE_OFFSET_FACTOR;\r\n } else {\r\n curveOffset =\r\n (edgeIndex - Math.floor(parallelEdges.length / 2)) *\r\n MULTI_EDGE_OFFSET_FACTOR;\r\n }\r\n }\r\n\r\n return { curved: updatedCurved, curveOffset };\r\n}\r\n","import { InternalGraphNode } from '../types';\r\n\r\nexport interface CenterPositionVector {\r\n x: number;\r\n y: number;\r\n z: number;\r\n minX: number;\r\n maxX: number;\r\n minY: number;\r\n maxY: number;\r\n minZ: number;\r\n maxZ: number;\r\n height: number;\r\n width: number;\r\n}\r\n\r\n/**\r\n * Given a collection of nodes, get the center point.\r\n */\r\nexport function getLayoutCenter(\r\n nodes: InternalGraphNode[]\r\n): CenterPositionVector {\r\n let minX = Number.POSITIVE_INFINITY;\r\n let maxX = Number.NEGATIVE_INFINITY;\r\n let minY = Number.POSITIVE_INFINITY;\r\n let maxY = Number.NEGATIVE_INFINITY;\r\n let minZ = Number.POSITIVE_INFINITY;\r\n let maxZ = Number.NEGATIVE_INFINITY;\r\n\r\n for (let node of nodes) {\r\n minX = Math.min(minX, node.position.x);\r\n maxX = Math.max(maxX, node.position.x);\r\n minY = Math.min(minY, node.position.y);\r\n maxY = Math.max(maxY, node.position.y);\r\n minZ = Math.min(minZ, node.position.z);\r\n maxZ = Math.max(maxZ, node.position.z);\r\n }\r\n\r\n return {\r\n height: maxY - minY,\r\n width: maxX - minX,\r\n minX,\r\n maxX,\r\n minY,\r\n maxY,\r\n minZ,\r\n maxZ,\r\n x: (maxX + minX) / 2,\r\n y: (maxY + minY) / 2,\r\n z: (maxZ + minZ) / 2\r\n };\r\n}\r\n","import { InternalGraphNode } from '../types';\r\nimport { CenterPositionVector, getLayoutCenter } from './layout';\r\n\r\n/**\r\n * Given nodes and a attribute, find all the cluster groups.\r\n */\r\nexport function buildClusterGroups(\r\n nodes: InternalGraphNode[],\r\n clusterAttribute?: string\r\n) {\r\n if (!clusterAttribute) {\r\n return new Map();\r\n }\r\n\r\n return nodes.reduce((entryMap, e) => {\r\n const val = e.data[clusterAttribute];\r\n if (val) {\r\n entryMap.set(val, [...(entryMap.get(val) || []), e]);\r\n }\r\n return entryMap;\r\n }, new Map());\r\n}\r\n\r\nexport interface CalculateClustersInput {\r\n nodes: InternalGraphNode[];\r\n clusterAttribute?: string;\r\n}\r\n\r\nexport interface ClusterGroup {\r\n nodes: InternalGraphNode[];\r\n position: CenterPositionVector;\r\n label: string;\r\n}\r\n\r\n/**\r\n * Builds the cluster map.\r\n */\r\nexport function calculateClusters({\r\n nodes,\r\n clusterAttribute\r\n}: CalculateClustersInput) {\r\n const result = new Map();\r\n\r\n if (clusterAttribute) {\r\n const groups = buildClusterGroups(nodes, clusterAttribute);\r\n for (const [key, nodes] of groups) {\r\n const position = getLayoutCenter(nodes);\r\n result.set(key, {\r\n label: key,\r\n nodes,\r\n position\r\n });\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","import { useCallback, useRef } from 'react';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface HoverIntentOptions {\r\n interval?: number;\r\n sensitivity?: number;\r\n timeout?: number;\r\n disabled?: boolean;\r\n onPointerOver: (event: ThreeEvent) => void;\r\n onPointerOut: (event: ThreeEvent) => void;\r\n}\r\n\r\nexport interface HoverIntentResult {\r\n pointerOut: (event: ThreeEvent) => void;\r\n pointerOver: (event: ThreeEvent) => void;\r\n}\r\n\r\n/**\r\n * Hover intent identifies if the user actually is\r\n * intending to over by measuring the position of the mouse\r\n * once a pointer enters and determining if in a duration if\r\n * the mouse moved inside a certain threshold and fires the events.\r\n */\r\nexport const useHoverIntent = ({\r\n sensitivity = 7,\r\n interval = 50,\r\n timeout = 0,\r\n disabled,\r\n onPointerOver,\r\n onPointerOut\r\n}: HoverIntentOptions | undefined): HoverIntentResult => {\r\n const mouseOver = useRef(false);\r\n const timer = useRef(null);\r\n const state = useRef(0);\r\n const coords = useRef({\r\n x: null,\r\n y: null,\r\n px: null,\r\n py: null\r\n });\r\n\r\n const onMouseMove = useCallback((event: MouseEvent) => {\r\n coords.current.x = event.clientX;\r\n coords.current.y = event.clientY;\r\n }, []);\r\n\r\n const comparePosition = useCallback(\r\n (event: ThreeEvent) => {\r\n timer.current = clearTimeout(timer.current);\r\n const { px, x, py, y } = coords.current;\r\n\r\n if (Math.abs(px - x) + Math.abs(py - y) < sensitivity) {\r\n state.current = 1;\r\n onPointerOver(event);\r\n } else {\r\n coords.current.px = x;\r\n coords.current.py = y;\r\n timer.current = setTimeout(() => comparePosition(event), interval);\r\n }\r\n },\r\n [interval, onPointerOver, sensitivity]\r\n );\r\n\r\n const cleanup = useCallback(() => {\r\n clearTimeout(timer.current);\r\n if (typeof window !== 'undefined') {\r\n document.removeEventListener('mousemove', onMouseMove, false);\r\n }\r\n }, [onMouseMove]);\r\n\r\n const pointerOver = useCallback(\r\n (event: ThreeEvent) => {\r\n if (!disabled) {\r\n mouseOver.current = true;\r\n cleanup();\r\n\r\n if (state.current !== 1) {\r\n coords.current.px = event.pointer.x;\r\n coords.current.py = event.pointer.y;\r\n\r\n if (typeof window !== 'undefined') {\r\n document.addEventListener('mousemove', onMouseMove, false);\r\n }\r\n\r\n timer.current = setTimeout(() => comparePosition(event), timeout);\r\n }\r\n }\r\n },\r\n [cleanup, comparePosition, disabled, onMouseMove, timeout]\r\n );\r\n\r\n const delay = useCallback(\r\n (event: ThreeEvent) => {\r\n timer.current = clearTimeout(timer.current);\r\n state.current = 0;\r\n onPointerOut(event);\r\n },\r\n [onPointerOut]\r\n );\r\n\r\n const pointerOut = useCallback(\r\n (event: ThreeEvent) => {\r\n mouseOver.current = false;\r\n cleanup();\r\n\r\n if (state.current === 1) {\r\n timer.current = setTimeout(() => delay(event), timeout);\r\n }\r\n },\r\n [cleanup, delay, timeout]\r\n );\r\n\r\n return {\r\n pointerOver,\r\n pointerOut\r\n };\r\n};\r\n","import { useThree } from '@react-three/fiber';\r\nimport { useMemo } from 'react';\r\nimport { useGesture } from 'react-use-gesture';\r\nimport { Vector2, Vector3, Plane } from 'three';\r\nimport { InternalGraphPosition } from '../types';\r\n\r\ninterface DragParams {\r\n draggable: boolean;\r\n position: InternalGraphPosition;\r\n set: (position: Vector3) => void;\r\n onDragStart: () => void;\r\n onDragEnd: () => void;\r\n}\r\n\r\nexport const useDrag = ({\r\n draggable,\r\n set,\r\n position,\r\n onDragStart,\r\n onDragEnd\r\n}: DragParams) => {\r\n const camera = useThree(state => state.camera);\r\n const raycaster = useThree(state => state.raycaster);\r\n const size = useThree(state => state.size);\r\n const gl = useThree(state => state.gl);\r\n\r\n // Reference: https://codesandbox.io/s/react-three-draggable-cxu37\r\n const { mouse2D, mouse3D, offset, normal, plane } = useMemo(\r\n () => ({\r\n // Normalized 2D screen space mouse coords\r\n mouse2D: new Vector2(),\r\n // 3D world space mouse coords\r\n mouse3D: new Vector3(),\r\n // Drag point offset from object origin\r\n offset: new Vector3(),\r\n // Normal of the drag plane\r\n normal: new Vector3(),\r\n // Drag plane\r\n plane: new Plane()\r\n }),\r\n []\r\n );\r\n\r\n const clientRect = useMemo(\r\n () => gl.domElement.getBoundingClientRect(),\r\n [gl.domElement]\r\n );\r\n\r\n return useGesture(\r\n {\r\n onDragStart: ({ event }) => {\r\n // @ts-ignore\r\n const { eventObject, point } = event;\r\n\r\n // Save the offset of click point from object origin\r\n eventObject.getWorldPosition(offset).sub(point);\r\n\r\n // Set initial 3D cursor position (needed for onDrag plane calculation)\r\n mouse3D.copy(point);\r\n\r\n // Run user callback\r\n onDragStart();\r\n },\r\n onDrag: ({ event }) => {\r\n // Compute normalized mouse coordinates (screen space)\r\n const scrollX = window.scrollX || window.pageXOffset;\r\n const scrollY = window.scrollY || window.pageYOffset;\r\n\r\n const nx =\r\n ((event.clientX - (clientRect?.left ?? 0) + scrollX) / size.width) *\r\n 2 -\r\n 1;\r\n const ny =\r\n -((event.clientY - (clientRect?.top ?? 0) + scrollY) / size.height) *\r\n 2 +\r\n 1;\r\n\r\n // Unlike the mouse from useThree, this works offscreen\r\n mouse2D.set(nx, ny);\r\n\r\n // Update raycaster (otherwise it doesn't track offscreen)\r\n raycaster.setFromCamera(mouse2D, camera);\r\n\r\n // The drag plane is normal to the camera view\r\n camera.getWorldDirection(normal).negate();\r\n\r\n // Find the plane that's normal to the camera and contains our drag point\r\n plane.setFromNormalAndCoplanarPoint(normal, mouse3D);\r\n\r\n // Find the point of intersection\r\n raycaster.ray.intersectPlane(plane, mouse3D);\r\n\r\n // Update the object position with the original offset\r\n const updated = new Vector3(position.x, position.y, position.z)\r\n .copy(mouse3D)\r\n .add(offset);\r\n\r\n return set(updated);\r\n },\r\n onDragEnd\r\n },\r\n { drag: { enabled: draggable, threshold: 10 } }\r\n );\r\n};\r\n","import Graph from 'graphology';\r\nimport { bidirectional } from 'graphology-shortest-path';\r\n\r\nexport function findPath(graph: Graph, source: string, target: string) {\r\n return bidirectional(graph, source, target);\r\n}\r\n","import { StoreApi, create } from 'zustand';\r\nimport createContext from 'zustand/context';\r\nimport {\r\n InternalGraphEdge,\r\n InternalGraphNode,\r\n InternalGraphPosition\r\n} from './types';\r\nimport { BufferGeometry, Mesh, Vector3 } from 'three';\r\nimport {\r\n CenterPositionVector,\r\n ClusterGroup,\r\n getLayoutCenter,\r\n getVector,\r\n updateNodePosition\r\n} from './utils';\r\nimport Graph from 'graphology';\r\nimport { Theme } from './themes';\r\n\r\nexport type DragReferences = {\r\n [key: string]: InternalGraphNode;\r\n};\r\n\r\nexport interface GraphState {\r\n nodes: InternalGraphNode[];\r\n edges: InternalGraphEdge[];\r\n graph: Graph;\r\n clusters: Map;\r\n collapsedNodeIds?: string[];\r\n centerPosition?: CenterPositionVector;\r\n actives?: string[];\r\n selections?: string[];\r\n edgeContextMenus?: Set;\r\n setEdgeContextMenus: (edges: Set) => void;\r\n edgeMeshes: Array>;\r\n setEdgeMeshes: (edgeMeshes: Array>) => void;\r\n draggingId?: string | null;\r\n drags?: DragReferences;\r\n panning?: boolean;\r\n theme: Theme;\r\n setTheme: (theme: Theme) => void;\r\n setClusters: (clusters: Map) => void;\r\n setPanning: (panning: boolean) => void;\r\n setDrags: (drags: DragReferences) => void;\r\n setDraggingId: (id: string | null) => void;\r\n setActives: (actives: string[]) => void;\r\n setSelections: (selections: string[]) => void;\r\n setNodes: (nodes: InternalGraphNode[]) => void;\r\n setEdges: (edges: InternalGraphEdge[]) => void;\r\n setNodePosition: (id: string, position: InternalGraphPosition) => void;\r\n setCollapsedNodeIds: (nodeIds: string[]) => void;\r\n canvasRef: HTMLCanvasElement | null;\r\n}\r\n\r\nexport const { Provider, useStore } = createContext>();\r\n\r\nexport const createStore = ({\r\n actives = [],\r\n selections = [],\r\n collapsedNodeIds = [],\r\n theme,\r\n canvasRef = null\r\n}: Partial) =>\r\n create(set => ({\r\n theme: {\r\n ...theme,\r\n edge: {\r\n ...theme.edge,\r\n label: {\r\n ...theme.edge.label,\r\n fontSize: theme.edge.label.fontSize ?? 6\r\n }\r\n }\r\n },\r\n edges: [],\r\n nodes: [],\r\n collapsedNodeIds,\r\n clusters: new Map(),\r\n panning: false,\r\n draggingId: null,\r\n actives,\r\n edgeContextMenus: new Set(),\r\n edgeMeshes: [],\r\n selections,\r\n drags: {},\r\n graph: new Graph({ multi: true }),\r\n setTheme: theme => set(state => ({ ...state, theme })),\r\n setClusters: clusters => set(state => ({ ...state, clusters })),\r\n setEdgeContextMenus: edgeContextMenus =>\r\n set(state => ({\r\n ...state,\r\n edgeContextMenus\r\n })),\r\n setEdgeMeshes: edgeMeshes => set(state => ({ ...state, edgeMeshes })),\r\n setPanning: panning => set(state => ({ ...state, panning })),\r\n setDrags: drags => set(state => ({ ...state, drags })),\r\n setDraggingId: draggingId => set(state => ({ ...state, draggingId })),\r\n setActives: actives => set(state => ({ ...state, actives })),\r\n setSelections: selections => set(state => ({ ...state, selections })),\r\n setNodes: nodes =>\r\n set(state => ({\r\n ...state,\r\n nodes,\r\n centerPosition: getLayoutCenter(nodes)\r\n })),\r\n setEdges: edges => set(state => ({ ...state, edges })),\r\n setNodePosition: (id, position) =>\r\n set(state => {\r\n const node = state.nodes.find(n => n.id === id);\r\n const originalVector = getVector(node);\r\n const newVector = new Vector3(position.x, position.y, position.z);\r\n const offset = newVector.sub(originalVector);\r\n const nodes = [...state.nodes];\r\n\r\n if (state.selections?.includes(id)) {\r\n state.selections?.forEach(id => {\r\n const node = state.nodes.find(n => n.id === id);\r\n // Selections can contain edges:\r\n if (node) {\r\n const nodeIndex = state.nodes.indexOf(node);\r\n nodes[nodeIndex] = updateNodePosition(node, offset);\r\n }\r\n });\r\n } else {\r\n const nodeIndex = state.nodes.indexOf(node);\r\n nodes[nodeIndex] = updateNodePosition(node, offset);\r\n }\r\n\r\n return {\r\n ...state,\r\n drags: {\r\n ...state.drags,\r\n [id]: node\r\n },\r\n nodes\r\n };\r\n }),\r\n setCollapsedNodeIds: (nodeIds = []) =>\r\n set(state => ({ ...state, collapsedNodeIds: nodeIds })),\r\n canvasRef\r\n }));\r\n","import { GraphEdge, GraphNode } from '../types';\r\n\r\ninterface GetHiddenChildrenInput {\r\n nodeId: string;\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n currentHiddenNodes: GraphNode[];\r\n currentHiddenEdges: GraphEdge[];\r\n}\r\n\r\ninterface GetVisibleIdsInput {\r\n collapsedIds: string[];\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n}\r\n\r\ninterface GetExpandPathInput {\r\n nodeId: string;\r\n edges: GraphEdge[];\r\n visibleEdgeIds: string[];\r\n}\r\n\r\n/**\r\n * Get the children of a node id that is hidden.\r\n */\r\nfunction getHiddenChildren({\r\n nodeId,\r\n nodes,\r\n edges,\r\n currentHiddenNodes,\r\n currentHiddenEdges\r\n}: GetHiddenChildrenInput) {\r\n const hiddenNodes: GraphNode[] = [];\r\n const hiddenEdges: GraphEdge[] = [];\r\n const curHiddenNodeIds = currentHiddenNodes.map(n => n.id);\r\n const curHiddenEdgeIds = currentHiddenEdges.map(e => e.id);\r\n\r\n const outboundEdges = edges.filter(l => l.source === nodeId);\r\n const outboundEdgeNodeIds = outboundEdges.map(l => l.target);\r\n\r\n hiddenEdges.push(...outboundEdges);\r\n for (const outboundEdgeNodeId of outboundEdgeNodeIds) {\r\n const incomingEdges = edges.filter(\r\n l => l.target === outboundEdgeNodeId && l.source !== nodeId\r\n );\r\n let hideNode = false;\r\n\r\n // Check to see if any other edge is coming into this node\r\n if (incomingEdges.length === 0) {\r\n hideNode = true;\r\n } else if (\r\n incomingEdges.length > 0 &&\r\n !curHiddenNodeIds.includes(outboundEdgeNodeId)\r\n ) {\r\n // If all inbound links are hidden, hide this node as well\r\n const inboundNodeLinkIds = incomingEdges.map(l => l.id);\r\n if (inboundNodeLinkIds.every(i => curHiddenEdgeIds.includes(i))) {\r\n hideNode = true;\r\n }\r\n }\r\n if (hideNode) {\r\n // Need to hide this node and any children of this node\r\n const node = nodes.find(n => n.id === outboundEdgeNodeId);\r\n if (node) {\r\n hiddenNodes.push(node);\r\n }\r\n const nested = getHiddenChildren({\r\n nodeId: outboundEdgeNodeId,\r\n nodes,\r\n edges,\r\n currentHiddenEdges: hiddenEdges,\r\n currentHiddenNodes: hiddenNodes\r\n });\r\n hiddenEdges.push(...nested.hiddenEdges);\r\n hiddenNodes.push(...nested.hiddenNodes);\r\n }\r\n }\r\n\r\n const uniqueEdges: GraphEdge[] = Object.values(\r\n hiddenEdges.reduce(\r\n (acc, next) => ({\r\n ...acc,\r\n [next.id]: next\r\n }),\r\n {}\r\n )\r\n );\r\n\r\n const uniqueNodes: GraphNode[] = Object.values(\r\n hiddenNodes.reduce(\r\n (acc, next) => ({\r\n ...acc,\r\n [next.id]: next\r\n }),\r\n {}\r\n )\r\n );\r\n\r\n return {\r\n hiddenEdges: uniqueEdges,\r\n hiddenNodes: uniqueNodes\r\n };\r\n}\r\n\r\n/**\r\n * Get the visible nodes and edges given a collapsed set of ids.\r\n */\r\nexport const getVisibleEntities = ({\r\n collapsedIds,\r\n nodes,\r\n edges\r\n}: GetVisibleIdsInput) => {\r\n const curHiddenNodes = [];\r\n const curHiddenEdges = [];\r\n\r\n for (const collapsedId of collapsedIds) {\r\n const { hiddenEdges, hiddenNodes } = getHiddenChildren({\r\n nodeId: collapsedId,\r\n nodes,\r\n edges,\r\n currentHiddenEdges: curHiddenEdges,\r\n currentHiddenNodes: curHiddenNodes\r\n });\r\n\r\n curHiddenNodes.push(...hiddenNodes);\r\n curHiddenEdges.push(...hiddenEdges);\r\n }\r\n\r\n const hiddenNodeIds = curHiddenNodes.map(n => n.id);\r\n const hiddenEdgeIds = curHiddenEdges.map(e => e.id);\r\n const visibleNodes = nodes.filter(n => !hiddenNodeIds.includes(n.id));\r\n const visibleEdges = edges.filter(e => !hiddenEdgeIds.includes(e.id));\r\n\r\n return {\r\n visibleNodes,\r\n visibleEdges\r\n };\r\n};\r\n\r\n/**\r\n * Get the path to expand a node.\r\n */\r\nexport const getExpandPath = ({\r\n nodeId,\r\n edges,\r\n visibleEdgeIds\r\n}: GetExpandPathInput) => {\r\n const parentIds = [];\r\n const inboundEdges = edges.filter(l => l.target === nodeId);\r\n const inboundEdgeIds = inboundEdges.map(e => e.id);\r\n const hasVisibleInboundEdge = inboundEdgeIds.some(id =>\r\n visibleEdgeIds.includes(id)\r\n );\r\n\r\n if (hasVisibleInboundEdge) {\r\n // If there is a visible edge to this node, that means the node is\r\n // visible so no parents need to be expanded\r\n return parentIds;\r\n }\r\n\r\n const inboundEdgeNodeIds = inboundEdges.map(l => l.source);\r\n let addedParent = false;\r\n\r\n for (const inboundNodeId of inboundEdgeNodeIds) {\r\n if (!addedParent) {\r\n // Only want to expand a single path to the node, so if there\r\n // are multiple hidden incoming edges, only expand the first\r\n // to reduce how many nodes are expanded to get to the node\r\n parentIds.push(\r\n ...[\r\n inboundNodeId,\r\n ...getExpandPath({ nodeId: inboundNodeId, edges, visibleEdgeIds })\r\n ]\r\n );\r\n addedParent = true;\r\n }\r\n }\r\n\r\n return parentIds;\r\n};\r\n","import React, { useCallback } from 'react';\r\nimport { GraphEdge, GraphNode } from 'types';\r\nimport { getExpandPath, getVisibleEntities } from './utils';\r\n\r\nexport interface UseCollapseProps {\r\n /**\r\n * Current collapsed node ids.\r\n */\r\n collapsedNodeIds?: string[];\r\n\r\n /**\r\n * Node data.\r\n */\r\n nodes?: GraphNode[];\r\n\r\n /**\r\n * Edge data.\r\n */\r\n edges?: GraphEdge[];\r\n}\r\n\r\nexport interface CollpaseResult {\r\n /**\r\n * Determine if a node is currently collapsed\r\n */\r\n getIsCollapsed: (nodeId: string) => boolean;\r\n\r\n /**\r\n * Return a list of ids required to expand in order to view the provided node\r\n */\r\n getExpandPathIds: (nodeId: string) => string[];\r\n}\r\n\r\nexport const useCollapse = ({\r\n collapsedNodeIds = [],\r\n nodes = [],\r\n edges = []\r\n}: UseCollapseProps): CollpaseResult => {\r\n const getIsCollapsed = useCallback(\r\n (nodeId: string) => {\r\n const { visibleNodes } = getVisibleEntities({\r\n nodes,\r\n edges,\r\n collapsedIds: collapsedNodeIds\r\n });\r\n const visibleNodeIds = visibleNodes.map(n => n.id);\r\n\r\n return !visibleNodeIds.includes(nodeId);\r\n },\r\n [collapsedNodeIds, edges, nodes]\r\n );\r\n\r\n const getExpandPathIds = useCallback(\r\n (nodeId: string) => {\r\n const { visibleEdges } = getVisibleEntities({\r\n nodes,\r\n edges,\r\n collapsedIds: collapsedNodeIds\r\n });\r\n const visibleEdgeIds = visibleEdges.map(e => e.id);\r\n\r\n return getExpandPath({ nodeId, edges, visibleEdgeIds });\r\n },\r\n [collapsedNodeIds, edges, nodes]\r\n );\r\n\r\n return {\r\n getIsCollapsed,\r\n getExpandPathIds\r\n };\r\n};\r\n","import { useRef, useCallback, useEffect, useMemo } from 'react';\r\nimport { useThree } from '@react-three/fiber';\r\nimport { PerspectiveCamera } from 'three';\r\nimport { SizingType } from './sizing';\r\nimport {\r\n LayoutTypes,\r\n layoutProvider,\r\n LayoutStrategy,\r\n LayoutOverrides\r\n} from './layout';\r\nimport { LabelVisibilityType, calcLabelVisibility } from './utils/visibility';\r\nimport { tick } from './layout/layoutUtils';\r\nimport { GraphEdge, GraphNode } from './types';\r\nimport { buildGraph, transformGraph } from './utils/graph';\r\nimport { DragReferences, useStore } from './store';\r\nimport { getVisibleEntities } from './collapse';\r\nimport { calculateClusters } from './utils/cluster';\r\n\r\nexport interface GraphInputs {\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n collapsedNodeIds?: string[];\r\n layoutType?: LayoutTypes;\r\n sizingType?: SizingType;\r\n labelType?: LabelVisibilityType;\r\n sizingAttribute?: string;\r\n selections?: string[];\r\n actives?: string[];\r\n clusterAttribute?: string;\r\n defaultNodeSize?: number;\r\n minNodeSize?: number;\r\n maxNodeSize?: number;\r\n layoutOverrides?: LayoutOverrides;\r\n}\r\n\r\nexport const useGraph = ({\r\n layoutType,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n clusterAttribute,\r\n selections,\r\n nodes,\r\n edges,\r\n actives,\r\n collapsedNodeIds,\r\n defaultNodeSize,\r\n maxNodeSize,\r\n minNodeSize,\r\n layoutOverrides\r\n}: GraphInputs) => {\r\n const graph = useStore(state => state.graph);\r\n const setClusters = useStore(state => state.setClusters);\r\n const stateCollapsedNodeIds = useStore(state => state.collapsedNodeIds);\r\n const setEdges = useStore(state => state.setEdges);\r\n const stateNodes = useStore(state => state.nodes);\r\n const setNodes = useStore(state => state.setNodes);\r\n const setSelections = useStore(state => state.setSelections);\r\n const setActives = useStore(state => state.setActives);\r\n const drags = useStore(state => state.drags);\r\n const setDrags = useStore(state => state.setDrags);\r\n const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\r\n const layoutMounted = useRef(false);\r\n const layout = useRef(null);\r\n const camera = useThree(state => state.camera) as PerspectiveCamera;\r\n\r\n const { visibleEdges, visibleNodes } = useMemo(\r\n () =>\r\n getVisibleEntities({\r\n collapsedIds: stateCollapsedNodeIds,\r\n nodes,\r\n edges\r\n }),\r\n [stateCollapsedNodeIds, nodes, edges]\r\n );\r\n\r\n // Transient updates\r\n const dragRef = useRef(drags);\r\n useEffect(() => {\r\n dragRef.current = drags;\r\n }, [drags]);\r\n\r\n const updateLayout = useCallback(\r\n async (curLayout?: any) => {\r\n // Cache the layout provider\r\n layout.current =\r\n curLayout ||\r\n layoutProvider({\r\n ...layoutOverrides,\r\n type: layoutType,\r\n graph,\r\n drags: dragRef.current,\r\n clusterAttribute\r\n });\r\n\r\n // Run the layout\r\n await tick(layout.current);\r\n\r\n // Transform the graph\r\n const result = transformGraph({\r\n graph,\r\n layout: layout.current,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n maxNodeSize,\r\n minNodeSize,\r\n defaultNodeSize\r\n });\r\n\r\n // Calculate clusters\r\n const clusters = calculateClusters({\r\n nodes: result.nodes,\r\n clusterAttribute\r\n });\r\n\r\n // Set our store outputs\r\n setEdges(result.edges);\r\n setNodes(result.nodes);\r\n setClusters(clusters);\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [\r\n layoutOverrides,\r\n layoutType,\r\n clusterAttribute,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n maxNodeSize,\r\n minNodeSize,\r\n defaultNodeSize,\r\n setEdges,\r\n setNodes,\r\n setClusters\r\n ]\r\n );\r\n\r\n useEffect(() => {\r\n const nodes = stateNodes.map(node => ({\r\n ...node,\r\n labelVisible: calcLabelVisibility({\r\n nodeCount: stateNodes?.length,\r\n labelType,\r\n camera,\r\n nodePosition: node?.position\r\n })('node', node?.size)\r\n }));\r\n\r\n const isVisibilityUpdated = nodes.some(\r\n (node, i) => node.labelVisible !== stateNodes[i].labelVisible\r\n );\r\n\r\n if (isVisibilityUpdated) {\r\n setNodes(nodes);\r\n }\r\n }, [camera, camera.zoom, camera.position.z, setNodes, stateNodes, labelType]);\r\n\r\n useEffect(() => {\r\n // Let's set the store selections so its easier to access\r\n if (layoutMounted.current) {\r\n setSelections(selections);\r\n }\r\n }, [selections, setSelections]);\r\n\r\n useEffect(() => {\r\n // Let's set the store actives so its easier to access\r\n if (layoutMounted.current) {\r\n setActives(actives);\r\n }\r\n }, [actives, setActives]);\r\n\r\n // Create the nggraph graph object\r\n useEffect(() => {\r\n async function update() {\r\n layoutMounted.current = false;\r\n buildGraph(graph, visibleNodes, visibleEdges);\r\n await updateLayout();\r\n layoutMounted.current = true;\r\n }\r\n\r\n update();\r\n // eslint-disable-next-line\r\n }, [visibleNodes, visibleEdges]);\r\n\r\n useEffect(() => {\r\n // Let's set the store collapsedNodeIds so its easier to access\r\n if (layoutMounted.current) {\r\n setCollapsedNodeIds(collapsedNodeIds);\r\n }\r\n }, [collapsedNodeIds, setCollapsedNodeIds]);\r\n\r\n // Update layout on type changes\r\n useEffect(() => {\r\n if (layoutMounted.current) {\r\n // When a update is changed, discard all the previous drag positions\r\n // NOTE: This sets the transient and the state\r\n dragRef.current = {};\r\n setDrags({});\r\n\r\n // Recalculate the layout\r\n updateLayout();\r\n }\r\n }, [layoutType, updateLayout, setDrags]);\r\n\r\n // Update layout on size, label changes\r\n useEffect(() => {\r\n if (layoutMounted.current) {\r\n updateLayout(layout.current);\r\n }\r\n }, [sizingType, sizingAttribute, labelType, updateLayout]);\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { Billboard, RoundedBox, Text } from 'glodrei';\r\nimport { Color, ColorRepresentation, Euler } from 'three';\r\nimport ellipsize from 'ellipsize';\r\nimport { a } from '@react-spring/three';\r\n\r\nconst calculateTextSize = (\r\n text: string,\r\n fontSize: number,\r\n maxWidth: number,\r\n ellipsis: number,\r\n active: boolean\r\n) => {\r\n const shortText = ellipsis && !active ? ellipsize(text, ellipsis) : text;\r\n const lines = [];\r\n let currentLine = '';\r\n const words = shortText.split(' ');\r\n\r\n words.forEach(word => {\r\n const testLine = currentLine ? `${currentLine} ${word}` : word;\r\n const testWidth = testLine.length * fontSize * 1;\r\n\r\n if (testWidth > maxWidth) {\r\n lines.push(currentLine);\r\n currentLine = word;\r\n } else {\r\n currentLine = testLine;\r\n }\r\n });\r\n\r\n if (currentLine) {\r\n lines.push(currentLine);\r\n }\r\n\r\n const width =\r\n Math.min(\r\n maxWidth,\r\n lines.reduce(\r\n (max, line) => Math.max(max, line.length * fontSize * 0.4),\r\n 0\r\n )\r\n ) + 14;\r\n const height = lines.length * fontSize + 6;\r\n\r\n return { width, height, text: lines.join('\\n'), lineCount: lines.length };\r\n};\r\n\r\nexport interface LabelProps {\r\n /**\r\n * Text to render.\r\n */\r\n text: string;\r\n\r\n /**\r\n * Font URL.\r\n * Reference: https://github.com/reaviz/reagraph/issues/23\r\n */\r\n fontUrl?: string;\r\n\r\n /**\r\n * Size of the font.\r\n */\r\n fontSize?: number;\r\n\r\n /**\r\n * Color of the text.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Stroke of the text.\r\n */\r\n stroke?: ColorRepresentation;\r\n\r\n /**\r\n * Opacity for the label.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The lenth of which to start the ellipsis.\r\n */\r\n ellipsis?: number;\r\n\r\n /**\r\n * Whether the label is active ( dragging, hover, focus ).\r\n */\r\n active?: boolean;\r\n\r\n /**\r\n * Rotation of the label.\r\n */\r\n rotation?: Euler | [number, number, number];\r\n\r\n /**\r\n * Maximum width of the label.\r\n */\r\n maxWidth?: number;\r\n\r\n /**\r\n * Background color of the label.\r\n */\r\n backgroundColor?: ColorRepresentation;\r\n\r\n /**\r\n * Border radius of the label.\r\n */\r\n borderRadius?: number;\r\n\r\n /**\r\n * Type of the label.\r\n */\r\n type?: 'node' | 'edge';\r\n\r\n /**\r\n * label visible or not\r\n */\r\n labelVisible?: boolean;\r\n}\r\n\r\nexport const Label: FC = ({\r\n text,\r\n fontSize,\r\n fontUrl,\r\n color,\r\n opacity,\r\n stroke,\r\n active,\r\n rotation,\r\n maxWidth = 100,\r\n ellipsis = 100,\r\n backgroundColor,\r\n borderRadius,\r\n labelVisible = true\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const normalizedBackgroundColor = useMemo(\r\n () => new Color(backgroundColor),\r\n [backgroundColor]\r\n );\r\n const normalizedStroke = useMemo(\r\n () => (stroke ? new Color(stroke) : undefined),\r\n [stroke]\r\n );\r\n\r\n const {\r\n width,\r\n height,\r\n text: processedText,\r\n lineCount\r\n } = useMemo(\r\n () => calculateTextSize(text, fontSize, maxWidth, ellipsis, active),\r\n [text, fontSize, maxWidth, ellipsis, active]\r\n );\r\n\r\n return (\r\n \r\n {backgroundColor ? (\r\n \r\n \r\n \r\n {processedText}\r\n \r\n \r\n \r\n \r\n ) : (\r\n \r\n {processedText}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nLabel.defaultProps = {\r\n opacity: 1,\r\n fontSize: 4,\r\n color: '#2A6475',\r\n ellipsis: 100\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { Color, ColorRepresentation, DoubleSide } from 'three';\r\nimport { animationConfig } from '../utils/animation';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Billboard } from 'glodrei';\r\n\r\nexport interface RingProps {\r\n /**\r\n * The color of the ring.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Whether the ring should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The size of the ring.\r\n */\r\n size?: number;\r\n\r\n /**\r\n * The opacity of the ring.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The stroke width of the ring.\r\n */\r\n strokeWidth?: number;\r\n\r\n /**\r\n * The inner radius of the ring.\r\n * Default value: 4\r\n */\r\n innerRadius?: number;\r\n\r\n /**\r\n * The number of segments in the ring geometry.\r\n * Default value: 25\r\n */\r\n segments?: number;\r\n}\r\n\r\nexport const Ring: FC = ({\r\n color,\r\n size,\r\n opacity,\r\n animated,\r\n strokeWidth,\r\n innerRadius = 2,\r\n segments = 50\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n\r\n const { ringSize, ringOpacity } = useSpring({\r\n from: {\r\n ringOpacity: 0,\r\n ringSize: [0.00001, 0.00001, 0.00001]\r\n },\r\n to: {\r\n ringOpacity: opacity,\r\n ringSize: [size / 2, size / 2, 1]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const strokeWidthFraction = strokeWidth / 10;\r\n const outerRadius = innerRadius + strokeWidthFraction;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nRing.defaultProps = {\r\n color: '#D8E6EA',\r\n size: 1,\r\n opacity: 0.5,\r\n strokeWidth: 5\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { animationConfig } from '../../utils/animation';\r\nimport { Color, DoubleSide } from 'three';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Ring } from '../Ring';\r\nimport { useStore } from '../../store';\r\n\r\nexport const Sphere: FC = ({\r\n color,\r\n id,\r\n size,\r\n active,\r\n selected,\r\n opacity,\r\n animated,\r\n showRing\r\n}) => {\r\n const { scale, nodeOpacity } = useSpring({\r\n from: {\r\n // Note: This prevents incorrect scaling w/ 0\r\n scale: [0.00001, 0.00001, 0.00001],\r\n nodeOpacity: 0\r\n },\r\n to: {\r\n scale: active\r\n ? [size * 1.05, size * 1.05, size * 1.05]\r\n : [size, size, size],\r\n nodeOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const theme = useStore(state => state.theme);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n {(showRing || selected || active) && (\r\n \r\n \r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nSphere.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import CameraControls from 'camera-controls';\r\nimport { createContext, useContext } from 'react';\r\n\r\nexport interface CameraControlsContextProps {\r\n /**\r\n * The camera controls object.\r\n */\r\n controls: CameraControls | null;\r\n\r\n /**\r\n * A function that resets the camera controls.\r\n * If the optional `animated` argument is true, the reset is animated.\r\n */\r\n resetControls: (animated?: boolean) => void;\r\n\r\n /**\r\n * A function that zooms in the camera.\r\n */\r\n zoomIn: () => void;\r\n\r\n /**\r\n * A function that zooms out the camera.\r\n */\r\n zoomOut: () => void;\r\n\r\n /**\r\n * A function that dollies in the camera.\r\n */\r\n dollyIn: (distance?: number) => void;\r\n\r\n /**\r\n * A function that dollies out the camera.\r\n */\r\n dollyOut: (distance?: number) => void;\r\n\r\n /**\r\n * A function that pans the camera to the left.\r\n */\r\n panLeft: () => void;\r\n\r\n /**\r\n * A function that pans the camera to the right.\r\n */\r\n panRight: () => void;\r\n\r\n /**\r\n * A function that pans the camera upwards.\r\n */\r\n panUp: () => void;\r\n\r\n /**\r\n * A function that pans the camera downwards.\r\n */\r\n panDown: () => void;\r\n}\r\n\r\nexport const CameraControlsContext = createContext({\r\n controls: null,\r\n resetControls: () => undefined,\r\n zoomIn: () => undefined,\r\n zoomOut: () => undefined,\r\n dollyIn: () => undefined,\r\n dollyOut: () => undefined,\r\n panLeft: () => undefined,\r\n panRight: () => undefined,\r\n panUp: () => undefined,\r\n panDown: () => undefined\r\n});\r\n\r\nexport const useCameraControls = () => {\r\n const context = useContext(CameraControlsContext);\r\n\r\n if (context === undefined) {\r\n throw new Error(\r\n '`useCameraControls` hook must be used within a `ControlsProvider` component'\r\n );\r\n }\r\n\r\n return context;\r\n};\r\n","import React, {\r\n FC,\r\n useRef,\r\n useEffect,\r\n useCallback,\r\n forwardRef,\r\n Ref,\r\n useImperativeHandle,\r\n useMemo,\r\n ReactNode\r\n} from 'react';\r\nimport { useThree, useFrame, extend } from '@react-three/fiber';\r\nimport {\r\n MOUSE,\r\n Vector2,\r\n Vector3,\r\n Vector4,\r\n Quaternion,\r\n Matrix4,\r\n Spherical,\r\n Box3,\r\n Sphere,\r\n Raycaster,\r\n MathUtils\r\n} from 'three';\r\nimport ThreeCameraControls from 'camera-controls';\r\nimport {\r\n CameraControlsContext,\r\n CameraControlsContextProps\r\n} from './useCameraControls';\r\nimport { useHotkeys } from 'reakeys';\r\nimport * as holdEvent from 'hold-event';\r\nimport { useStore } from '../store';\r\n\r\n// Install the camera controls\r\n// Use a subset for better three shaking\r\nThreeCameraControls.install({\r\n THREE: {\r\n MOUSE: MOUSE,\r\n Vector2: Vector2,\r\n Vector3: Vector3,\r\n Vector4: Vector4,\r\n Quaternion: Quaternion,\r\n Matrix4: Matrix4,\r\n Spherical: Spherical,\r\n Box3: Box3,\r\n Sphere: Sphere,\r\n Raycaster: Raycaster,\r\n MathUtils: {\r\n DEG2RAD: MathUtils?.DEG2RAD,\r\n clamp: MathUtils?.clamp\r\n }\r\n }\r\n});\r\n\r\n// Extend r3f with the new controls\r\nextend({ ThreeCameraControls });\r\n\r\nconst KEY_CODES = {\r\n ARROW_LEFT: 37,\r\n ARROW_UP: 38,\r\n ARROW_RIGHT: 39,\r\n ARROW_DOWN: 40\r\n};\r\n\r\nconst leftKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_LEFT, 100);\r\nconst rightKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_RIGHT, 100);\r\nconst upKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_UP, 100);\r\nconst downKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_DOWN, 100);\r\n\r\nexport type CameraMode = 'pan' | 'rotate' | 'orbit';\r\n\r\nexport interface CameraControlsProps {\r\n /**\r\n * Mode of the camera.\r\n */\r\n mode?: CameraMode;\r\n\r\n /**\r\n * Children symbols.\r\n */\r\n children?: ReactNode;\r\n\r\n /**\r\n * Animate transitions to centering.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the controls are enabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The maximum distance for the camera.\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * The minimum distance for the camera.\r\n */\r\n minDistance?: number;\r\n}\r\n\r\nexport type CameraControlsRef = CameraControlsContextProps;\r\n\r\nexport const CameraControls: FC<\r\n CameraControlsProps & { ref?: Ref }\r\n> = forwardRef(\r\n (\r\n { mode, children, animated, disabled, minDistance, maxDistance },\r\n ref: Ref\r\n ) => {\r\n const cameraRef = useRef(null);\r\n const camera = useThree(state => state.camera);\r\n const gl = useThree(state => state.gl);\r\n const isOrbiting = mode === 'orbit';\r\n const setPanning = useStore(state => state.setPanning);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n useFrame((_state, delta) => {\r\n if (cameraRef.current?.enabled) {\r\n cameraRef.current?.update(delta);\r\n }\r\n\r\n if (isOrbiting) {\r\n cameraRef.current.azimuthAngle += 20 * delta * MathUtils.DEG2RAD;\r\n }\r\n }, -1);\r\n\r\n useEffect(() => () => cameraRef.current?.dispose(), []);\r\n\r\n const zoomIn = useCallback(() => {\r\n cameraRef.current?.zoom(camera.zoom / 2, animated);\r\n }, [animated, camera.zoom]);\r\n\r\n const zoomOut = useCallback(() => {\r\n cameraRef.current?.zoom(-camera.zoom / 2, animated);\r\n }, [animated, camera.zoom]);\r\n\r\n const dollyIn = useCallback(\r\n distance => {\r\n cameraRef.current?.dolly(distance, animated);\r\n },\r\n [animated]\r\n );\r\n\r\n const dollyOut = useCallback(\r\n distance => {\r\n cameraRef.current?.dolly(distance, animated);\r\n },\r\n [animated]\r\n );\r\n\r\n const panRight = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(-0.03 * event.deltaTime, 0, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panLeft = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0.03 * event.deltaTime, 0, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panUp = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0, 0.03 * event.deltaTime, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panDown = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0, -0.03 * event.deltaTime, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const onKeyDown = useCallback(\r\n event => {\r\n if (event.code === 'Space') {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n }\r\n }\r\n },\r\n [mode]\r\n );\r\n\r\n const onKeyUp = useCallback(\r\n event => {\r\n if (event.code === 'Space') {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n }\r\n }\r\n },\r\n [mode]\r\n );\r\n\r\n useEffect(() => {\r\n if (!disabled) {\r\n leftKey.addEventListener('holding', panLeft);\r\n rightKey.addEventListener('holding', panRight);\r\n upKey.addEventListener('holding', panUp);\r\n downKey.addEventListener('holding', panDown);\r\n\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', onKeyDown);\r\n window.addEventListener('keyup', onKeyUp);\r\n }\r\n }\r\n\r\n return () => {\r\n leftKey.removeEventListener('holding', panLeft);\r\n rightKey.removeEventListener('holding', panRight);\r\n upKey.removeEventListener('holding', panUp);\r\n downKey.removeEventListener('holding', panDown);\r\n\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', onKeyDown);\r\n window.removeEventListener('keyup', onKeyUp);\r\n }\r\n };\r\n }, [disabled, onKeyDown, onKeyUp, panDown, panLeft, panRight, panUp]);\r\n\r\n useEffect(() => {\r\n if (disabled) {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\r\n cameraRef.current.mouseButtons.middle = ThreeCameraControls.ACTION.NONE;\r\n cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.NONE;\r\n } else {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.TRUCK;\r\n cameraRef.current.mouseButtons.middle =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.DOLLY;\r\n }\r\n }, [disabled]);\r\n\r\n useEffect(() => {\r\n const onControl = () => setPanning(true);\r\n const onControlEnd = () => setPanning(false);\r\n\r\n const ref = cameraRef.current;\r\n if (ref) {\r\n ref.addEventListener('control', onControl);\r\n ref.addEventListener('controlend', onControlEnd);\r\n }\r\n\r\n return () => {\r\n if (ref) {\r\n ref.removeEventListener('control', onControl);\r\n ref.removeEventListener('controlend', onControlEnd);\r\n }\r\n };\r\n }, [cameraRef, setPanning]);\r\n\r\n useEffect(() => {\r\n // If a node is being dragged, disable the camera controls\r\n if (draggingId) {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\r\n } else {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n }\r\n }\r\n }, [draggingId, mode]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Zoom In',\r\n disabled,\r\n category: 'Graph',\r\n keys: 'command+shift+i',\r\n callback: event => {\r\n event.preventDefault();\r\n zoomIn();\r\n }\r\n },\r\n {\r\n name: 'Zoom Out',\r\n category: 'Graph',\r\n disabled,\r\n keys: 'command+shift+o',\r\n callback: event => {\r\n event.preventDefault();\r\n zoomOut();\r\n }\r\n }\r\n ]);\r\n\r\n const values = useMemo(\r\n () => ({\r\n controls: cameraRef.current,\r\n zoomIn: () => zoomIn(),\r\n zoomOut: () => zoomOut(),\r\n dollyIn: (distance = 1000) => dollyIn(distance),\r\n dollyOut: (distance = -1000) => dollyOut(distance),\r\n panLeft: (deltaTime = 100) => panLeft({ deltaTime }),\r\n panRight: (deltaTime = 100) => panRight({ deltaTime }),\r\n panDown: (deltaTime = 100) => panDown({ deltaTime }),\r\n panUp: (deltaTime = 100) => panUp({ deltaTime }),\r\n resetControls: (animated?: boolean) =>\r\n cameraRef.current?.reset(animated)\r\n }),\r\n // eslint-disable-next-line\r\n [zoomIn, zoomOut, panLeft, panRight, panDown, panUp, cameraRef.current]\r\n );\r\n\r\n useImperativeHandle(ref, () => values);\r\n\r\n return (\r\n \r\n \r\n {children}\r\n \r\n );\r\n }\r\n);\r\n\r\nCameraControls.defaultProps = {\r\n mode: 'rotate',\r\n minDistance: 1000,\r\n maxDistance: 50000\r\n};\r\n","import { PerspectiveCamera } from 'three';\r\nimport { InternalGraphPosition } from '../types';\r\n\r\n/**\r\n * Get the visible height at the z depth.\r\n * Ref: https://discourse.threejs.org/t/functions-to-calculate-the-visible-width-height-at-a-given-z-depth-from-a-perspective-camera/269\r\n */\r\nfunction visibleHeightAtZDepth(depth: number, camera: PerspectiveCamera) {\r\n // compensate for cameras not positioned at z=0\r\n const cameraOffset = camera.position.z;\r\n if (depth < cameraOffset) depth -= cameraOffset;\r\n else depth += cameraOffset;\r\n\r\n // vertical fov in radians\r\n const vFOV = ((camera.fov / camera.zoom) * Math.PI) / 180;\r\n\r\n // Math.abs to ensure the result is always positive\r\n return 2 * Math.tan(vFOV / 2) * Math.abs(depth);\r\n}\r\n\r\n/**\r\n * Get the visible width at the z depth.\r\n */\r\nfunction visibleWidthAtZDepth(depth: number, camera: PerspectiveCamera) {\r\n const height = visibleHeightAtZDepth(depth, camera);\r\n return height * camera.aspect;\r\n}\r\n\r\n/**\r\n * Returns whether the node is in view of the camera.\r\n */\r\nexport function isNodeInView(\r\n camera: PerspectiveCamera,\r\n nodePosition: InternalGraphPosition\r\n): boolean {\r\n const visibleWidth = visibleWidthAtZDepth(1, camera);\r\n const visibleHeight = visibleHeightAtZDepth(1, camera);\r\n\r\n // The boundary coordinates of the area visible to the camera relative to the scene\r\n const visibleArea = {\r\n x0: camera?.position?.x - visibleWidth / 2,\r\n x1: camera?.position?.x + visibleWidth / 2,\r\n y0: camera?.position?.y - visibleHeight / 2,\r\n y1: camera?.position?.y + visibleHeight / 2\r\n };\r\n\r\n return (\r\n nodePosition?.x > visibleArea.x0 &&\r\n nodePosition?.x < visibleArea.x1 &&\r\n nodePosition?.y > visibleArea.y0 &&\r\n nodePosition?.y < visibleArea.y1\r\n );\r\n}\r\n\r\n/**\r\n * Get the closest axis to a given angle.\r\n */\r\nexport function getClosestAxis(angle: number, axes: number[]) {\r\n return axes.reduce((prev, curr) =>\r\n Math.abs(curr - (angle % Math.PI)) < Math.abs(prev - (angle % Math.PI))\r\n ? curr\r\n : prev\r\n );\r\n}\r\n\r\n/**\r\n * Get how far an angle is from the closest 2D axis in radians.\r\n */\r\nexport function getDegreesToClosest2dAxis(\r\n horizontalAngle: number,\r\n verticalAngle: number\r\n) {\r\n const closestHorizontalAxis = getClosestAxis(horizontalAngle, [0, Math.PI]);\r\n const closestVerticalAxis = getClosestAxis(verticalAngle, [\r\n Math.PI / 2,\r\n (3 * Math.PI) / 2\r\n ]);\r\n\r\n return {\r\n horizontalRotation: closestHorizontalAxis - (horizontalAngle % Math.PI),\r\n verticalRotation: closestVerticalAxis - (verticalAngle % Math.PI)\r\n };\r\n}\r\n","import { useThree } from '@react-three/fiber';\r\nimport { useCameraControls } from './useCameraControls';\r\nimport { useCallback, useLayoutEffect, useRef, useState } from 'react';\r\nimport { Vector3, Box3, PerspectiveCamera } from 'three';\r\nimport { useHotkeys } from 'reakeys';\r\nimport { getLayoutCenter } from '../utils/layout';\r\nimport { InternalGraphNode } from '../types';\r\nimport { useStore } from '../store';\r\nimport { isNodeInView, getDegreesToClosest2dAxis } from './utils';\r\nimport { LayoutTypes } from 'layout/types';\r\n\r\nconst PADDING = 50;\r\n\r\nexport interface CenterNodesParams {\r\n animated?: boolean;\r\n centerOnlyIfNodesNotInView?: boolean;\r\n}\r\n\r\nexport interface FitNodesParams {\r\n animated?: boolean;\r\n fitOnlyIfNodesNotInView?: boolean;\r\n}\r\n\r\nexport interface CenterGraphInput {\r\n /**\r\n * Whether the animate the transition or not.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the center graph function is disabled or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The layout type of the graph used to determine rotation logic.\r\n */\r\n layoutType: LayoutTypes;\r\n}\r\n\r\nexport interface CenterGraphOutput {\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodes - An array of `InternalGraphNode` objects to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param animated - A boolean flag that determines whether the centering action should be animated.\r\n *\r\n * @param centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `nodes` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `nodes` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerNodes: (nodes: InternalGraphNode[], opts: CenterNodesParams) => void;\r\n\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `ids` are not currently in view. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerNodesById: (nodeIds: string[], opts?: CenterNodesParams) => void;\r\n\r\n /**\r\n * Fit all the given nodes into view of the camera.\r\n *\r\n * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\r\n * the view will fit to all nodes.\r\n *\r\n * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\r\n * only be fit if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the view will only be fit if one or more of the nodes\r\n * specified by `ids` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the view will be fit regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n fitNodesInViewById: (nodeIds: string[], opts?: FitNodesParams) => void;\r\n\r\n /**\r\n * Whether the graph is centered or not.\r\n */\r\n isCentered?: boolean;\r\n}\r\n\r\nexport const useCenterGraph = ({\r\n animated,\r\n disabled,\r\n layoutType\r\n}: CenterGraphInput): CenterGraphOutput => {\r\n const nodes = useStore(state => state.nodes);\r\n const [isCentered, setIsCentered] = useState(false);\r\n const invalidate = useThree(state => state.invalidate);\r\n const { controls } = useCameraControls();\r\n const camera = useThree(state => state.camera) as PerspectiveCamera;\r\n const mounted = useRef(false);\r\n\r\n const centerNodes = useCallback(\r\n async (nodes, opts?: CenterNodesParams) => {\r\n const animated = opts?.animated !== undefined ? opts?.animated : true;\r\n const centerOnlyIfNodesNotInView =\r\n opts?.centerOnlyIfNodesNotInView !== undefined\r\n ? opts?.centerOnlyIfNodesNotInView\r\n : false;\r\n\r\n if (\r\n !mounted.current ||\r\n !centerOnlyIfNodesNotInView ||\r\n (centerOnlyIfNodesNotInView &&\r\n nodes?.some(node => !isNodeInView(camera, node.position)))\r\n ) {\r\n // Centers the graph based on the central most node\r\n const { x, y, z } = getLayoutCenter(nodes);\r\n\r\n await controls.setTarget(x, y, z, animated);\r\n\r\n if (!isCentered) {\r\n setIsCentered(true);\r\n }\r\n\r\n invalidate();\r\n }\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [invalidate, controls, nodes]\r\n );\r\n\r\n const fitNodesInView = useCallback(\r\n async (\r\n nodes,\r\n opts: FitNodesParams = { animated: true, fitOnlyIfNodesNotInView: false }\r\n ) => {\r\n const { fitOnlyIfNodesNotInView } = opts;\r\n\r\n if (\r\n !fitOnlyIfNodesNotInView ||\r\n (fitOnlyIfNodesNotInView &&\r\n nodes?.some(node => !isNodeInView(camera, node.position)))\r\n ) {\r\n const { minX, maxX, minY, maxY, minZ, maxZ } = getLayoutCenter(nodes);\r\n\r\n if (!layoutType.includes('3d')) {\r\n // fitToBox will auto rotate to the closest axis including the z axis,\r\n // which is not desired for 2D graphs\r\n // So get the rotation to the closest flat axis for 2D graphs\r\n const { horizontalRotation, verticalRotation } =\r\n getDegreesToClosest2dAxis(\r\n controls?.azimuthAngle,\r\n controls?.polarAngle\r\n );\r\n\r\n void controls?.rotate(horizontalRotation, verticalRotation, true);\r\n }\r\n\r\n await controls?.zoomTo(1, opts?.animated);\r\n\r\n await controls?.fitToBox(\r\n new Box3(\r\n new Vector3(minX, minY, minZ),\r\n new Vector3(maxX, maxY, maxZ)\r\n ),\r\n opts?.animated,\r\n {\r\n cover: false,\r\n paddingLeft: PADDING,\r\n paddingRight: PADDING,\r\n paddingBottom: PADDING,\r\n paddingTop: PADDING\r\n }\r\n );\r\n }\r\n },\r\n [camera, controls, layoutType]\r\n );\r\n\r\n const getNodesById = useCallback(\r\n (nodeIds: string[]) => {\r\n let mappedNodes: InternalGraphNode[] | null = null;\r\n\r\n if (nodeIds?.length) {\r\n // Map the node ids to the actual nodes\r\n mappedNodes = nodeIds.reduce((acc, id) => {\r\n const node = nodes.find(n => n.id === id);\r\n if (node) {\r\n acc.push(node);\r\n } else {\r\n throw new Error(\r\n `Attempted to center ${id} but it was not found in the nodes`\r\n );\r\n }\r\n\r\n return acc;\r\n }, []);\r\n }\r\n\r\n return mappedNodes;\r\n },\r\n [nodes]\r\n );\r\n\r\n const centerNodesById = useCallback(\r\n (nodeIds: string[], opts: CenterNodesParams) => {\r\n const mappedNodes = getNodesById(nodeIds);\r\n\r\n centerNodes(mappedNodes || nodes, {\r\n animated,\r\n centerOnlyIfNodesNotInView: opts?.centerOnlyIfNodesNotInView\r\n });\r\n },\r\n [animated, centerNodes, getNodesById, nodes]\r\n );\r\n\r\n const fitNodesInViewById = useCallback(\r\n async (nodeIds: string[], opts: FitNodesParams) => {\r\n const mappedNodes = getNodesById(nodeIds);\r\n\r\n await fitNodesInView(mappedNodes || nodes, { animated, ...opts });\r\n },\r\n [animated, fitNodesInView, getNodesById, nodes]\r\n );\r\n\r\n useLayoutEffect(() => {\r\n async function load() {\r\n // Once we've loaded controls and we have nodes, let's recenter\r\n if (controls && nodes?.length) {\r\n if (!mounted.current) {\r\n // Center the graph once nodes are loaded on mount\r\n await centerNodes(nodes, { animated: false });\r\n await fitNodesInView(nodes, { animated: false });\r\n mounted.current = true;\r\n }\r\n }\r\n }\r\n\r\n load();\r\n }, [controls, centerNodes, nodes, animated, camera, fitNodesInView]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Center',\r\n disabled,\r\n category: 'Graph',\r\n keys: ['command+shift+c'],\r\n callback: () => centerNodes(nodes)\r\n }\r\n ]);\r\n\r\n return { centerNodes, centerNodesById, fitNodesInViewById, isCentered };\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { a, useSpring } from '@react-spring/three';\r\nimport { TextureLoader, LinearFilter, DoubleSide } from 'three';\r\nimport { animationConfig } from '../../utils';\r\nimport { NodeRendererProps } from '../../types';\r\n\r\nexport interface IconProps extends NodeRendererProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n}\r\n\r\nexport const Icon: FC = ({ image, id, size, opacity, animated }) => {\r\n const texture = useMemo(() => new TextureLoader().load(image), [image]);\r\n\r\n const { scale, spriteOpacity } = useSpring({\r\n from: {\r\n scale: [0.00001, 0.00001, 0.00001],\r\n spriteOpacity: 0\r\n },\r\n to: {\r\n scale: [size, size, size],\r\n spriteOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nIcon.defaultProps = {\r\n opacity: 1\r\n};\r\n","import React, { FC } from 'react';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Sphere } from './Sphere';\r\nimport { Icon } from './Icon';\r\n\r\nexport interface SphereWithIconProps extends NodeRendererProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n}\r\n\r\nexport const SphereWithIcon: FC = ({\r\n color,\r\n id,\r\n size,\r\n opacity,\r\n node,\r\n active,\r\n animated,\r\n image,\r\n selected\r\n}) => (\r\n <>\r\n \r\n \r\n \r\n);\r\n\r\nSphereWithIcon.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { a, useSpring } from '@react-spring/three';\r\nimport { animationConfig } from '../../utils';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Billboard, Svg as DreiSvg, SvgProps as DreiSvgProps } from 'glodrei';\r\nimport { Color, DoubleSide } from 'three';\r\n\r\nexport type SvgProps = NodeRendererProps &\r\n Omit & {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n };\r\n\r\nexport const Svg: FC = ({\r\n id,\r\n image,\r\n color,\r\n size,\r\n opacity,\r\n animated,\r\n ...rest\r\n}) => {\r\n const normalizedSize = size / 25;\r\n\r\n const { scale } = useSpring({\r\n from: {\r\n scale: [0.00001, 0.00001, 0.00001]\r\n },\r\n to: {\r\n scale: [normalizedSize, normalizedSize, normalizedSize]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nSvg.defaultProps = {\r\n opacity: 1\r\n};\r\n","import React, { FC } from 'react';\r\nimport { Sphere } from './Sphere';\r\nimport { Svg, SvgProps } from './Svg';\r\nimport { ColorRepresentation } from 'three';\r\n\r\nexport interface SphereWithSvgProps extends SvgProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n\r\n /**\r\n * The color of the svg fill.\r\n */\r\n svgFill?: ColorRepresentation;\r\n}\r\n\r\nexport const SphereWithSvg: FC = ({\r\n color,\r\n id,\r\n size,\r\n opacity,\r\n node,\r\n svgFill,\r\n active,\r\n animated,\r\n image,\r\n selected,\r\n ...rest\r\n}) => (\r\n <>\r\n \r\n \r\n \r\n);\r\n\r\nSphereWithSvg.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import React, {\r\n FC,\r\n ReactNode,\r\n useCallback,\r\n useMemo,\r\n useRef,\r\n useState\r\n} from 'react';\r\nimport { Group } from 'three';\r\nimport { animationConfig } from '../utils';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Sphere } from './nodes/Sphere';\r\nimport { Label } from './Label';\r\nimport {\r\n NodeContextMenuProps,\r\n ContextMenuEvent,\r\n InternalGraphNode,\r\n NodeRenderer,\r\n CollapseProps\r\n} from '../types';\r\nimport { Html, useCursor } from 'glodrei';\r\nimport { useCameraControls } from '../CameraControls';\r\nimport { useStore } from '../store';\r\nimport { useDrag } from '../utils/useDrag';\r\nimport { Icon } from './nodes';\r\nimport { useHoverIntent } from '../utils/useHoverIntent';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface NodeProps {\r\n /**\r\n * The unique identifier for the node.\r\n */\r\n id: string;\r\n\r\n /**\r\n * The parent nodes of the node.\r\n */\r\n parents?: string[];\r\n\r\n /**\r\n * Whether the node is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Whether the node is animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the node is draggable.\r\n */\r\n draggable?: boolean;\r\n\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The function to use to render the node.\r\n */\r\n renderNode?: NodeRenderer;\r\n\r\n /**\r\n * The context menu for the node.\r\n */\r\n contextMenu?: (event: ContextMenuEvent) => ReactNode;\r\n\r\n /**\r\n * The function to call when the pointer is over the node.\r\n */\r\n onPointerOver?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the pointer is out of the node.\r\n */\r\n onPointerOut?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is clicked.\r\n */\r\n onClick?: (\r\n node: InternalGraphNode,\r\n props?: CollapseProps,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is double clicked.\r\n */\r\n onDoubleClick?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is right clicked.\r\n */\r\n onContextMenu?: (\r\n node?: InternalGraphNode,\r\n props?: NodeContextMenuProps\r\n ) => void;\r\n\r\n /**\r\n * Triggered after a node was dragged.\r\n */\r\n onDragged?: (node: InternalGraphNode) => void;\r\n}\r\n\r\nexport const Node: FC = ({\r\n animated,\r\n disabled,\r\n id,\r\n draggable,\r\n labelFontUrl,\r\n contextMenu,\r\n onClick,\r\n onDoubleClick,\r\n onPointerOver,\r\n onDragged,\r\n onPointerOut,\r\n onContextMenu,\r\n renderNode\r\n}) => {\r\n const cameraControls = useCameraControls();\r\n const theme = useStore(state => state.theme);\r\n const node = useStore(state => state.nodes.find(n => n.id === id));\r\n const edges = useStore(state => state.edges);\r\n const draggingId = useStore(state => state.draggingId);\r\n const collapsedNodeIds = useStore(state => state.collapsedNodeIds);\r\n const setDraggingId = useStore(state => state.setDraggingId);\r\n const setNodePosition = useStore(state => state.setNodePosition);\r\n const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\r\n const isCollapsed = useStore(state => state.collapsedNodeIds.includes(id));\r\n const isActive = useStore(state => state.actives?.includes(id));\r\n const isSelected = useStore(state => state.selections?.includes(id));\r\n const hasSelections = useStore(state => state.selections?.length > 0);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const isDragging = draggingId === id;\r\n const {\r\n position,\r\n label,\r\n subLabel,\r\n size: nodeSize = 7,\r\n labelVisible = true\r\n } = node;\r\n\r\n const group = useRef(null);\r\n const [active, setActive] = useState(false);\r\n const [menuVisible, setMenuVisible] = useState(false);\r\n\r\n const shouldHighlight = active || isSelected || isActive;\r\n\r\n const selectionOpacity = hasSelections\r\n ? shouldHighlight\r\n ? theme.node.selectedOpacity\r\n : theme.node.inactiveOpacity\r\n : theme.node.opacity;\r\n\r\n const canCollapse = useMemo(() => {\r\n // If the node has outgoing edges, it can collapse via context menu\r\n const outboundLinks = edges.filter(l => l.source === id);\r\n\r\n return outboundLinks.length > 0 || isCollapsed;\r\n }, [edges, id, isCollapsed]);\r\n\r\n const onCollapse = useCallback(() => {\r\n if (canCollapse) {\r\n if (isCollapsed) {\r\n setCollapsedNodeIds(collapsedNodeIds.filter(p => p !== id));\r\n } else {\r\n setCollapsedNodeIds([...collapsedNodeIds, id]);\r\n }\r\n }\r\n }, [canCollapse, collapsedNodeIds, id, isCollapsed, setCollapsedNodeIds]);\r\n\r\n const [{ nodePosition, labelPosition, subLabelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n nodePosition: center ? [center.x, center.y, 0] : [0, 0, 0],\r\n labelPosition: [0, -(nodeSize + 4), 2],\r\n subLabelPosition: [0, -(nodeSize + 14), 2]\r\n },\r\n to: {\r\n nodePosition: position\r\n ? [\r\n position.x,\r\n position.y,\r\n shouldHighlight ? position.z + 50 : position.z\r\n ]\r\n : [0, 0, 0],\r\n labelPosition: [0, -(nodeSize + 4), 2],\r\n subLabelPosition: [0, -(nodeSize + 14), 2]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [isDragging, position, animated, nodeSize, shouldHighlight]\r\n );\r\n\r\n const bind = useDrag({\r\n draggable,\r\n position,\r\n // @ts-ignore\r\n set: pos => setNodePosition(id, pos),\r\n onDragStart: () => {\r\n setDraggingId(id);\r\n setActive(true);\r\n },\r\n onDragEnd: () => {\r\n setDraggingId(null);\r\n setActive(false);\r\n onDragged?.(node);\r\n }\r\n });\r\n\r\n useCursor(active && !draggingId && onClick !== undefined, 'pointer');\r\n useCursor(\r\n active && draggable && !isDragging && onClick === undefined,\r\n 'grab'\r\n );\r\n useCursor(isDragging, 'grabbing');\r\n\r\n const combinedActiveState = shouldHighlight || isDragging;\r\n const color = combinedActiveState\r\n ? node.activeFill || theme.node.activeFill\r\n : node.fill || theme.node.fill;\r\n\r\n const actualShowRing = node.showRing;\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled: disabled || isDragging,\r\n onPointerOver: (event: ThreeEvent) => {\r\n cameraControls.controls.truckSpeed = 0;\r\n setActive(true);\r\n onPointerOver?.(node, event);\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n cameraControls.controls.truckSpeed = 2.0;\r\n setActive(false);\r\n onPointerOut?.(node, event);\r\n }\r\n });\r\n\r\n const nodeComponent = useMemo(\r\n () =>\r\n renderNode ? (\r\n renderNode({\r\n id,\r\n color,\r\n size: nodeSize,\r\n active: combinedActiveState,\r\n opacity: selectionOpacity,\r\n animated,\r\n selected: isSelected,\r\n node\r\n })\r\n ) : (\r\n <>\r\n {node.icon ? (\r\n \r\n ) : (\r\n \r\n )}\r\n \r\n ),\r\n [\r\n renderNode,\r\n id,\r\n color,\r\n nodeSize,\r\n combinedActiveState,\r\n selectionOpacity,\r\n animated,\r\n isSelected,\r\n node,\r\n actualShowRing\r\n ]\r\n );\r\n\r\n const labelComponent = useMemo(\r\n () =>\r\n label && (\r\n <>\r\n \r\n \r\n \r\n {subLabel && (\r\n \r\n \r\n \r\n )}\r\n \r\n ),\r\n [\r\n active,\r\n isActive,\r\n isDragging,\r\n isSelected,\r\n label,\r\n labelFontUrl,\r\n labelPosition,\r\n labelVisible,\r\n selectionOpacity,\r\n subLabel,\r\n subLabelPosition,\r\n theme.node.label.activeColor,\r\n theme.node.label.color,\r\n theme.node.label.stroke,\r\n theme.node.subLabel?.activeColor,\r\n theme.node.subLabel?.color,\r\n theme.node.subLabel?.stroke,\r\n theme.node.label.fontSize,\r\n theme.node.label.maxWidth,\r\n theme.node.label.ellipsis,\r\n theme.node.label.backgroundColor,\r\n theme.node.label.borderRadius\r\n ]\r\n );\r\n\r\n const menuComponent = useMemo(\r\n () =>\r\n menuVisible &&\r\n contextMenu && (\r\n \r\n {contextMenu({\r\n data: node,\r\n canCollapse,\r\n isCollapsed,\r\n onCollapse,\r\n onClose: () => setMenuVisible(false)\r\n })}\r\n \r\n ),\r\n [menuVisible, contextMenu, node, canCollapse, isCollapsed, onCollapse]\r\n );\r\n\r\n return (\r\n ) => {\r\n if (!disabled && !isDragging) {\r\n onClick?.(\r\n node,\r\n {\r\n canCollapse,\r\n isCollapsed\r\n },\r\n event\r\n );\r\n }\r\n }}\r\n onDoubleClick={(event: ThreeEvent) => {\r\n event.stopPropagation();\r\n if (!disabled && !isDragging) {\r\n onDoubleClick?.(node, event);\r\n }\r\n }}\r\n onContextMenu={() => {\r\n if (!disabled) {\r\n setMenuVisible(true);\r\n onContextMenu?.(node, {\r\n canCollapse,\r\n isCollapsed,\r\n onCollapse\r\n });\r\n }\r\n }}\r\n {...(bind() as any)}\r\n >\r\n {nodeComponent}\r\n {menuComponent}\r\n {labelComponent}\r\n \r\n );\r\n};\r\n\r\nNode.defaultProps = {\r\n draggable: false\r\n};\r\n","import React, { FC, useMemo, useRef, useEffect, useCallback } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Color, ColorRepresentation, Mesh, DoubleSide, Vector3 } from 'three';\r\nimport { animationConfig } from '../utils';\r\nimport { useStore } from '../store';\r\n\r\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\r\n\r\nexport interface ArrowProps {\r\n /**\r\n * Whether the arrow should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The color of the arrow.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * The length of the arrow.\r\n */\r\n length: number;\r\n\r\n /**\r\n * The opacity of the arrow.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The position of the arrow in 3D space.\r\n */\r\n position: Vector3;\r\n\r\n /**\r\n * The rotation of the arrow in 3D space.\r\n */\r\n rotation: Vector3;\r\n\r\n /**\r\n * The size of the arrow.\r\n */\r\n size: number;\r\n\r\n /**\r\n * A function that is called when the arrow is right-clicked.\r\n */\r\n onContextMenu?: () => void;\r\n\r\n /**\r\n * A function that is called when the arrow is selected or deselected.\r\n */\r\n onActive?: (state: boolean) => void;\r\n}\r\n\r\nexport const Arrow: FC = ({\r\n animated,\r\n color,\r\n length,\r\n opacity,\r\n position,\r\n rotation,\r\n size,\r\n onActive,\r\n onContextMenu\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const meshRef = useRef(null);\r\n const draggingId = useStore(state => state.draggingId);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const [{ pos, arrowOpacity }] = useSpring(\r\n () => ({\r\n from: {\r\n pos: center ? [center.x, center.y, center.z] : [0, 0, 0],\r\n arrowOpacity: 0\r\n },\r\n to: {\r\n pos: [position.x, position.y, position.z],\r\n arrowOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [animated, draggingId, opacity, position]\r\n );\r\n\r\n const setQuaternion = useCallback(() => {\r\n const axis = new Vector3(0, 1, 0);\r\n meshRef.current?.quaternion.setFromUnitVectors(axis, rotation);\r\n }, [rotation, meshRef]);\r\n\r\n useEffect(() => setQuaternion(), [setQuaternion]);\r\n\r\n return (\r\n onActive(true)}\r\n onPointerOut={() => onActive(false)}\r\n onPointerDown={event => {\r\n // context menu controls\r\n if (event.nativeEvent.buttons === 2) {\r\n event.stopPropagation();\r\n onContextMenu();\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nArrow.defaultProps = {\r\n size: 1,\r\n opacity: 0.5,\r\n color: '#D8E6EA'\r\n};\r\n","import React, { FC, useEffect, useMemo, useRef } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { animationConfig, getCurve } from '../utils';\r\nimport {\r\n Vector3,\r\n TubeGeometry,\r\n ColorRepresentation,\r\n Color,\r\n Curve\r\n} from 'three';\r\nimport { useStore } from '../store';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface LineProps {\r\n /**\r\n * Whether the line should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The color of the line.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Whether the line should be curved.\r\n */\r\n curved: boolean;\r\n\r\n /**\r\n * The curve of the line in 3D space.\r\n */\r\n curve: Curve;\r\n\r\n /**\r\n * The unique identifier of the line.\r\n */\r\n id: string;\r\n\r\n /**\r\n * The opacity of the line.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The size of the line.\r\n */\r\n size?: number;\r\n\r\n /**\r\n * A function that is called when the line is clicked.\r\n */\r\n onClick?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the line is right-clicked.\r\n */\r\n onContextMenu?: () => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved over the line.\r\n */\r\n onPointerOver?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved out of the line.\r\n */\r\n onPointerOut?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * The offset of the curve.\r\n */\r\n curveOffset?: number;\r\n}\r\n\r\nexport const Line: FC = ({\r\n curveOffset,\r\n animated,\r\n color,\r\n curve,\r\n curved = false,\r\n id,\r\n opacity,\r\n size,\r\n onContextMenu,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const tubeRef = useRef(null);\r\n const draggingId = useStore(state => state.draggingId);\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const center = useStore(state => state.centerPosition);\r\n const mounted = useRef(false);\r\n\r\n // Do opacity seperate from vertices for perf\r\n const { lineOpacity } = useSpring({\r\n from: {\r\n lineOpacity: 0\r\n },\r\n to: {\r\n lineOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n useSpring(() => {\r\n const from = curve.getPoint(0);\r\n const to = curve.getPoint(1);\r\n return {\r\n from: {\r\n // Animate from center first time, then from the actual from point\r\n fromVertices: !mounted.current\r\n ? [center?.x, center?.y, center?.z || 0]\r\n : [to?.x, to?.y, to?.z || 0],\r\n toVertices: [from?.x, from?.y, from?.z || 0]\r\n },\r\n to: {\r\n fromVertices: [from?.x, from?.y, from?.z || 0],\r\n toVertices: [to?.x, to?.y, to?.z || 0]\r\n },\r\n onChange: event => {\r\n const { fromVertices, toVertices } = event.value;\r\n const fromVector = new Vector3(...fromVertices);\r\n const toVector = new Vector3(...toVertices);\r\n\r\n const curve = getCurve(fromVector, 0, toVector, 0, curved, curveOffset);\r\n tubeRef.current.copy(new TubeGeometry(curve, 20, size / 2, 5, false));\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n };\r\n }, [animated, draggingId, curve, size]);\r\n\r\n useEffect(() => {\r\n // Handle mount operation for initial render\r\n mounted.current = true;\r\n }, []);\r\n\r\n return (\r\n {\r\n // context menu controls\r\n if (event.nativeEvent.buttons === 2) {\r\n event.stopPropagation();\r\n onContextMenu();\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nLine.defaultProps = {\r\n color: '#000',\r\n size: 1,\r\n opacity: 1\r\n};\r\n","import React, { FC, useMemo, useState } from 'react';\nimport { useSpring, a } from '@react-spring/three';\nimport { Arrow, EdgeArrowPosition } from './Arrow';\nimport { Label } from './Label';\nimport {\n animationConfig,\n calculateEdgeCurveOffset,\n getArrowSize,\n getArrowVectors,\n getCurve,\n getLabelOffsetByType,\n getMidPoint,\n getVector\n} from '../utils';\nimport { Line } from './Line';\nimport { useStore } from '../store';\nimport { ContextMenuEvent, InternalGraphEdge } from '../types';\nimport { Html, useCursor } from 'glodrei';\nimport { useHoverIntent } from '../utils/useHoverIntent';\nimport { Euler, Vector3 } from 'three';\nimport { ThreeEvent } from '@react-three/fiber';\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 * 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 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) => React.ReactNode;\n\n /**\n * A function that is called when the edge is clicked.\n */\n onClick?: (edge: InternalGraphEdge, event: ThreeEvent) => 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\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\n ) => void;\n}\n\nconst LABEL_PLACEMENT_OFFSET = 3;\n\nexport const Edge: FC = ({\n animated,\n arrowPlacement,\n contextMenu,\n disabled,\n labelPlacement,\n id,\n interpolation,\n labelFontUrl,\n onContextMenu,\n onClick,\n onPointerOver,\n onPointerOut\n}) => {\n const theme = useStore(state => state.theme);\n const draggingId = useStore(state => state.draggingId);\n\n // UI states\n const [active, setActive] = useState(false);\n const [menuVisible, setMenuVisible] = useState(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 labelVisible = false,\n size = 1,\n backgroundColor\n } = edge;\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 // Edge properties\n const labelOffset = (size + theme.edge.label.fontSize) / 2;\n const [arrowLength, arrowSize] = useMemo(() => getArrowSize(size), [size]);\n const { curveOffset, curved } = useMemo(\n () =>\n calculateEdgeCurveOffset({\n edge,\n edges,\n curved: interpolation === 'curved'\n }),\n [edge, edges, interpolation]\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 arrowPlacement,\n curve,\n arrowLength\n );\n\n if (arrowPlacement === '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, arrowPlacement, 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 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 center = useStore(state => state.centerPosition);\n\n const selectionOpacity = hasSelections\n ? isSelected || isActive\n ? theme.edge.selectedOpacity\n : theme.edge.inactiveOpacity\n : theme.edge.opacity;\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 && !draggingId ? undefined : 0\n }\n }),\n [midPoint, animated, draggingId]\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 && !draggingId && onClick !== undefined, 'pointer');\n\n const { pointerOver, pointerOut } = useHoverIntent({\n disabled,\n onPointerOver: (event: ThreeEvent) => {\n setActive(true);\n onPointerOver?.(edge, event);\n },\n onPointerOut: (event: ThreeEvent) => {\n setActive(false);\n onPointerOut?.(edge, event);\n }\n });\n\n const arrowComponent = useMemo(\n () =>\n arrowPlacement !== 'none' && (\n {\n if (!disabled) {\n setMenuVisible(true);\n onContextMenu?.(edge);\n }\n }}\n />\n ),\n [\n active,\n animated,\n arrowLength,\n arrowPlacement,\n arrowPosition,\n arrowRotation,\n arrowSize,\n disabled,\n edge,\n isActive,\n isSelected,\n onContextMenu,\n selectionOpacity,\n theme.arrow.activeFill,\n theme.arrow.fill\n ]\n );\n\n const labelComponent = useMemo(\n () =>\n labelVisible &&\n label && (\n \n \n \n ),\n [\n active,\n isActive,\n isSelected,\n label,\n labelFontUrl,\n labelPosition,\n labelRotation,\n labelVisible,\n selectionOpacity,\n theme.edge.label.activeColor,\n theme.edge.label.color,\n theme.edge.label.fontSize,\n theme.edge.label.maxWidth,\n theme.edge.label.ellipsis,\n theme.edge.label.stroke,\n theme.edge.label.backgroundColor,\n theme.edge.label.borderRadius\n ]\n );\n\n const menuComponent = useMemo(\n () =>\n menuVisible &&\n contextMenu && (\n \n {contextMenu({ data: edge, onClose: () => setMenuVisible(false) })}\n \n ),\n [menuVisible, contextMenu, midPoint, edge]\n );\n\n const lineComponent = useMemo(\n () => (\n {\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 [\n active,\n animated,\n curve,\n curveOffset,\n curved,\n disabled,\n edge,\n id,\n isActive,\n isSelected,\n onClick,\n onContextMenu,\n pointerOut,\n pointerOver,\n selectionOpacity,\n size,\n theme.arrow.activeFill,\n theme.arrow.fill\n ]\n );\n\n return (\n \n {arrowComponent}\n {lineComponent}\n {menuComponent}\n {labelComponent}\n \n );\n};\n\nEdge.defaultProps = {\n labelPlacement: 'inline',\n arrowPlacement: 'end'\n};\n","import { useCallback, useRef } from 'react';\r\nimport {\r\n BoxGeometry,\r\n BufferGeometry,\r\n CylinderGeometry,\r\n Quaternion,\r\n TubeGeometry,\r\n Vector3\r\n} from 'three';\r\nimport { mergeBufferGeometries } from 'three-stdlib';\r\n\r\nimport { GraphState, useStore } from '../../store';\r\nimport { InternalGraphEdge } from '../../types';\r\nimport {\r\n getArrowSize,\r\n getArrowVectors,\r\n getVector,\r\n getCurve\r\n} from '../../utils';\r\nimport { EdgeArrowPosition } from '../Arrow';\r\nimport { EdgeInterpolation } from '../Edge';\r\n\r\nexport type UseEdgeGeometry = {\r\n getGeometries(edges: Array): Array;\r\n getGeometry(\r\n active: Array,\r\n inactive: Array\r\n ): BufferGeometry;\r\n};\r\n\r\nconst NULL_GEOMETRY = new BoxGeometry(0, 0, 0);\r\n\r\nexport function useEdgeGeometry(\r\n arrowPlacement: EdgeArrowPosition,\r\n interpolation: EdgeInterpolation\r\n): UseEdgeGeometry {\r\n // We don't want to rerun everything when the state changes,\r\n // but we do want to use the most recent nodes whenever `getGeometries`\r\n // or `getGeometry` is run, so we store it in a ref:\r\n const stateRef = useRef();\r\n const theme = useStore(state => state.theme);\r\n useStore(state => {\r\n stateRef.current = state;\r\n });\r\n\r\n const geometryCacheRef = useRef(new Map());\r\n\r\n const curved = interpolation === 'curved';\r\n const getGeometries = useCallback(\r\n (edges: Array): Array => {\r\n const geometries: Array = [];\r\n const cache = geometryCacheRef.current;\r\n\r\n const { nodes } = stateRef.current;\r\n\r\n edges.forEach(edge => {\r\n const { target, source, size = 1 } = edge;\r\n\r\n const from = nodes.find(node => node.id === source);\r\n const to = nodes.find(node => node.id === target);\r\n\r\n if (!from || !to) {\r\n return;\r\n }\r\n\r\n // Create hash so geometry can be reused if edge doesn't move:\r\n const hash = `fromX:${from.position.x},fromY:${from.position.y},toX:${to.position.x}},toY:${to.position.y}`;\r\n if (cache.has(hash)) {\r\n const geometry = cache.get(hash);\r\n geometries.push(geometry);\r\n return;\r\n }\r\n\r\n const fromVector = getVector(from);\r\n const fromOffset = from.size + theme.edge.label.fontSize;\r\n const toVector = getVector(to);\r\n const toOffset = to.size + theme.edge.label.fontSize;\r\n let curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n toVector,\r\n toOffset,\r\n curved\r\n );\r\n\r\n let edgeGeometry = new TubeGeometry(curve, 20, size / 2, 5, false);\r\n\r\n if (arrowPlacement === 'none') {\r\n geometries.push(edgeGeometry);\r\n cache.set(hash, edgeGeometry);\r\n return;\r\n }\r\n\r\n const [arrowLength, arrowSize] = getArrowSize(size);\r\n\r\n const [arrowPosition, arrowRotation] = getArrowVectors(\r\n arrowPlacement,\r\n curve,\r\n arrowLength\r\n );\r\n const quaternion = new Quaternion();\r\n quaternion.setFromUnitVectors(new Vector3(0, 1, 0), arrowRotation);\r\n\r\n const arrowGeometry = new CylinderGeometry(\r\n 0,\r\n arrowSize,\r\n arrowLength,\r\n 20,\r\n 1,\r\n true\r\n );\r\n arrowGeometry.applyQuaternion(quaternion);\r\n arrowGeometry.translate(\r\n arrowPosition.x,\r\n arrowPosition.y,\r\n arrowPosition.z\r\n );\r\n\r\n // Move edge so it doesn't stick through the arrow:\r\n if (arrowPlacement && arrowPlacement === 'end') {\r\n const curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n arrowPosition,\r\n 0,\r\n curved\r\n );\r\n edgeGeometry = new TubeGeometry(curve, 20, size / 2, 5, false);\r\n }\r\n\r\n const merged = mergeBufferGeometries([edgeGeometry, arrowGeometry]);\r\n geometries.push(merged);\r\n cache.set(hash, merged);\r\n });\r\n return geometries;\r\n },\r\n [arrowPlacement, curved, theme.edge.label.fontSize]\r\n );\r\n\r\n const getGeometry = useCallback(\r\n (\r\n active: Array,\r\n inactive: Array\r\n ): BufferGeometry => {\r\n const activeGeometries = getGeometries(active);\r\n const inactiveGeometries = getGeometries(inactive);\r\n\r\n return mergeBufferGeometries(\r\n [\r\n inactiveGeometries.length\r\n ? mergeBufferGeometries(inactiveGeometries)\r\n : NULL_GEOMETRY,\r\n activeGeometries.length\r\n ? mergeBufferGeometries(activeGeometries)\r\n : NULL_GEOMETRY\r\n ],\r\n true\r\n );\r\n },\r\n [getGeometries]\r\n );\r\n\r\n return {\r\n getGeometries,\r\n getGeometry\r\n };\r\n}\r\n","import { useCallback, useRef } from 'react';\r\n\r\nimport { useStore } from '../../store';\r\nimport { InternalGraphEdge } from '../../types';\r\n\r\nexport type EdgeEvents = {\r\n onClick?: (edge: InternalGraphEdge) => void;\r\n onContextMenu?: (edge?: InternalGraphEdge) => void;\r\n onPointerOver?: (edge: InternalGraphEdge) => void;\r\n onPointerOut?: (edge: InternalGraphEdge) => void;\r\n};\r\n\r\nexport function useEdgeEvents(\r\n events: EdgeEvents,\r\n contextMenu,\r\n disabled: boolean\r\n) {\r\n const { onClick, onContextMenu, onPointerOut, onPointerOver } = events;\r\n\r\n const edgeContextMenus = useStore(state => state.edgeContextMenus);\r\n const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\r\n\r\n const clickRef = useRef(false);\r\n const handleClick = useCallback(() => {\r\n clickRef.current = true;\r\n }, []);\r\n\r\n const contextMenuEventRef = useRef(false);\r\n const handleContextMenu = useCallback(() => {\r\n contextMenuEventRef.current = true;\r\n }, []);\r\n\r\n const handleIntersections = useCallback(\r\n (\r\n previous: Array,\r\n intersected: Array\r\n ) => {\r\n if (onClick && clickRef.current) {\r\n clickRef.current = false;\r\n if (!disabled) {\r\n intersected.forEach(edge => {\r\n onClick(edge);\r\n });\r\n }\r\n }\r\n\r\n if ((contextMenu || onContextMenu) && contextMenuEventRef.current) {\r\n contextMenuEventRef.current = false;\r\n if (!disabled) {\r\n intersected.forEach(edge => {\r\n if (!edgeContextMenus.has(edge.id)) {\r\n setEdgeContextMenus(new Set([...edgeContextMenus, edge.id]));\r\n onContextMenu?.(edge);\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (onPointerOver) {\r\n const over = intersected.filter(index => !previous.includes(index));\r\n over.forEach(edge => {\r\n onPointerOver(edge);\r\n });\r\n }\r\n\r\n if (onPointerOut) {\r\n const out = previous.filter(index => !intersected.includes(index));\r\n out.forEach(edge => {\r\n onPointerOut(edge);\r\n });\r\n }\r\n },\r\n [\r\n contextMenu,\r\n disabled,\r\n edgeContextMenus,\r\n setEdgeContextMenus,\r\n onClick,\r\n onContextMenu,\r\n onPointerOver,\r\n onPointerOut\r\n ]\r\n );\r\n\r\n return {\r\n handleClick,\r\n handleContextMenu,\r\n handleIntersections\r\n };\r\n}\r\n","import { SpringValue, useSpring } from '@react-spring/three';\r\nimport { useCallback, useEffect, useRef } from 'react';\r\nimport { BufferAttribute, BufferGeometry } from 'three';\r\n\r\nimport { Theme } from '../../themes';\r\nimport { animationConfig } from '../../utils';\r\n\r\nexport function useEdgePositionAnimation(\r\n geometry: BufferGeometry,\r\n animated: boolean\r\n): void {\r\n const geometryRef = useRef(geometry);\r\n\r\n useEffect(() => {\r\n geometryRef.current = geometry;\r\n }, [geometry]);\r\n\r\n const getAnimationPositions = useCallback(() => {\r\n const positions = geometryRef.current.getAttribute('position');\r\n const from = Array.from({\r\n length: positions.array.length\r\n }).fill(0) as Array;\r\n const to = Array.from(positions.array);\r\n return { from, to };\r\n }, []);\r\n\r\n const updateGeometryPosition = useCallback((positions: Array) => {\r\n const buffer = new Float32Array(positions);\r\n const newPosition = new BufferAttribute(buffer, 3, false);\r\n geometryRef.current.setAttribute('position', newPosition);\r\n newPosition.needsUpdate = true;\r\n }, []);\r\n\r\n useSpring(() => {\r\n if (!animated) {\r\n return null;\r\n }\r\n\r\n const animationPositions = getAnimationPositions();\r\n\r\n return {\r\n from: {\r\n positions: animationPositions.from\r\n },\r\n to: {\r\n positions: animationPositions.to\r\n },\r\n onChange: event => {\r\n updateGeometryPosition(event.value.positions);\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n };\r\n }, [animated]);\r\n}\r\n\r\nexport type UseEdgeOpacityAnimations = {\r\n activeOpacity: SpringValue;\r\n inactiveOpacity: SpringValue;\r\n};\r\n\r\nexport function useEdgeOpacityAnimation(\r\n animated: boolean,\r\n hasSelections: boolean,\r\n theme: Theme\r\n): UseEdgeOpacityAnimations {\r\n const [{ activeOpacity, inactiveOpacity }] = useSpring(() => {\r\n return {\r\n from: {\r\n activeOpacity: 0,\r\n inactiveOpacity: 0\r\n },\r\n to: {\r\n activeOpacity: hasSelections\r\n ? theme.edge.selectedOpacity\r\n : theme.edge.opacity,\r\n inactiveOpacity: hasSelections\r\n ? theme.edge.inactiveOpacity\r\n : theme.edge.opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n };\r\n }, [animated, hasSelections, theme]);\r\n\r\n return { activeOpacity, inactiveOpacity };\r\n}\r\n","import React, { FC, useCallback, useMemo } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Html } from 'glodrei';\r\nimport { ColorRepresentation, Euler } from 'three';\r\n\r\nimport { useStore } from '../../store';\r\nimport { Theme } from '../../themes';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../../types';\r\nimport {\r\n animationConfig,\r\n getLabelOffsetByType,\r\n getMidPoint\r\n} from '../../utils';\r\nimport { Label } from '../Label';\r\n\r\n/**\r\n * Label positions relatively edge\r\n *\r\n * below: show label under the edge line\r\n * above: show label above the edge line\r\n * inline: show label along the edge line\r\n * natural: normal text positions\r\n */\r\nexport type EdgeLabelPosition = 'below' | 'above' | 'inline' | 'natural';\r\n\r\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\r\n\r\nexport interface EdgeProps {\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The color of the edge.\r\n */\r\n color: ColorRepresentation;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * The edge object.\r\n */\r\n edge: InternalGraphEdge;\r\n\r\n /**\r\n * The URL of the font for the edge label.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The opacity of the edge.\r\n */\r\n opacity?: number;\r\n}\r\n\r\nexport const Edge: FC = ({\r\n animated,\r\n color,\r\n contextMenu,\r\n edge,\r\n labelFontUrl,\r\n labelPlacement,\r\n opacity\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const { target, source, label, labelVisible = false, size = 1 } = edge;\r\n\r\n const nodes = useStore(store => store.nodes);\r\n const from = nodes.find(node => node.id === source);\r\n const to = nodes.find(node => node.id === target);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n const labelOffset = (size + theme.edge.label.fontSize) / 2;\r\n\r\n const midPoint = useMemo(\r\n () =>\r\n getMidPoint(\r\n from.position,\r\n to.position,\r\n getLabelOffsetByType(labelOffset, labelPlacement)\r\n ),\r\n [from.position, to.position, labelOffset, labelPlacement]\r\n );\r\n\r\n const edgeContextMenus = useStore(state => state.edgeContextMenus);\r\n const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\r\n\r\n const [{ labelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n labelPosition: [0, 0, 0]\r\n },\r\n to: {\r\n labelPosition: [midPoint.x, midPoint.y, midPoint.z]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [midPoint, animated, draggingId]\r\n );\r\n\r\n const removeContextMenu = useCallback(\r\n (edge: InternalGraphEdge) => {\r\n edgeContextMenus.delete(edge.id);\r\n setEdgeContextMenus(new Set(edgeContextMenus.values()));\r\n },\r\n [edgeContextMenus, setEdgeContextMenus]\r\n );\r\n\r\n const labelRotation = useMemo(\r\n () =>\r\n new Euler(\r\n 0,\r\n 0,\r\n labelPlacement === 'natural'\r\n ? 0\r\n : Math.atan(\r\n (to.position.y - from.position.y) /\r\n (to.position.x - from.position.x)\r\n )\r\n ),\r\n [\r\n to.position.x,\r\n to.position.y,\r\n from.position.x,\r\n from.position.y,\r\n labelPlacement\r\n ]\r\n );\r\n\r\n return (\r\n \r\n {labelVisible && label && (\r\n \r\n \r\n \r\n )}\r\n {contextMenu && edgeContextMenus.has(edge.id) && (\r\n \r\n {contextMenu({\r\n data: edge,\r\n onClose: () => removeContextMenu(edge)\r\n })}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nEdge.defaultProps = {\r\n labelPlacement: 'inline'\r\n};\r\n","import React, { FC, useCallback, useEffect, useMemo, useRef } from 'react';\r\nimport { a } from '@react-spring/three';\r\nimport { useFrame } from '@react-three/fiber';\r\nimport { DoubleSide, Mesh, Raycaster, TubeGeometry } from 'three';\r\n\r\nimport { useStore } from '../../store';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../../types';\r\nimport { EdgeArrowPosition } from '../Arrow';\r\nimport { EdgeLabelPosition, EdgeInterpolation } from '../Edge';\r\nimport { useEdgeGeometry } from './useEdgeGeometry';\r\nimport { EdgeEvents, useEdgeEvents } from './useEdgeEvents';\r\nimport {\r\n useEdgePositionAnimation,\r\n useEdgeOpacityAnimation\r\n} from './useEdgeAnimations';\r\nimport { Edge } from './Edge';\r\n\r\nexport type EdgesProps = {\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The placement of the edge arrow.\r\n */\r\n arrowPlacement?: EdgeArrowPosition;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The array of edge objects.\r\n */\r\n edges: Array;\r\n\r\n /**\r\n * The URL of the font for the edge label.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The type of interpolation used to draw the edge.\r\n */\r\n interpolation?: EdgeInterpolation;\r\n} & EdgeEvents;\r\n\r\n/**\r\n * Three.js rendering starts to get slower if you have an individual mesh for each edge\r\n * and a high number of edges.\r\n *\r\n * Instead, we take the edges and split them into their different render states:\r\n *\r\n * * - Active (any edges that are marked as \"selected\" or \"active\" in the state)\r\n * * - Dragging (any edges that are connected to a node that is being dragged)\r\n * * - Intersecting (any edges that are currently intersected by the ray from the mouse position)\r\n * * - Inactive (any edges that aren't active, dragging, or intersected)\r\n *\r\n * We generate the geometry for each edge in each of these groups, and then merge them\r\n * into a single geometry for each group. This merged mesh is rendered as one object\r\n * which gives much better performance. This means that we only need to update geometry\r\n * and positions when edges move between the different states, rather than updating all\r\n * edges whenever any other edge changes.\r\n *\r\n * To get this all working, we have to do a few things outside the @react-three/fiber world,\r\n * specifically:\r\n *\r\n * * manually create edge/arrow geometries (see `useEdgeGeometry`)\r\n * * manually track mouse/edge interactions and fire events (see `useEdgeEvents`)\r\n * * manually update edge/arrow positions during aniamations (see `useEdgeAnimations`)\r\n */\r\nexport const Edges: FC = ({\r\n interpolation = 'linear',\r\n arrowPlacement = 'end',\r\n labelPlacement = 'inline',\r\n animated,\r\n contextMenu,\r\n disabled,\r\n edges,\r\n labelFontUrl,\r\n onClick,\r\n onContextMenu,\r\n onPointerOut,\r\n onPointerOver\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const { getGeometries, getGeometry } = useEdgeGeometry(\r\n arrowPlacement,\r\n interpolation\r\n );\r\n\r\n const draggingId = useStore(state => state.draggingId);\r\n const edgeMeshes = useStore(state => state.edgeMeshes);\r\n const setEdgeMeshes = useStore(state => state.setEdgeMeshes);\r\n const actives = useStore(state => state.actives || []);\r\n const selections = useStore(state => state.selections || []);\r\n\r\n const [active, inactive, draggingActive, draggingInactive] = useMemo(() => {\r\n const active: Array = [];\r\n const inactive: Array = [];\r\n const draggingActive: Array = [];\r\n const draggingInactive: Array = [];\r\n edges.forEach(edge => {\r\n if (draggingId === edge.source || draggingId === edge.target) {\r\n if (selections.includes(edge.id) || actives.includes(edge.id)) {\r\n draggingActive.push(edge);\r\n } else {\r\n draggingInactive.push(edge);\r\n }\r\n return;\r\n }\r\n\r\n if (selections.includes(edge.id) || actives.includes(edge.id)) {\r\n active.push(edge);\r\n } else {\r\n inactive.push(edge);\r\n }\r\n });\r\n return [active, inactive, draggingActive, draggingInactive];\r\n }, [edges, actives, selections, draggingId]);\r\n\r\n const hasSelections = !!selections.length;\r\n\r\n const staticEdgesGeometry = useMemo(\r\n () => getGeometry(active, inactive),\r\n [getGeometry, active, inactive]\r\n );\r\n\r\n const { activeOpacity, inactiveOpacity } = useEdgeOpacityAnimation(\r\n animated,\r\n hasSelections,\r\n theme\r\n );\r\n\r\n useEdgePositionAnimation(staticEdgesGeometry, animated);\r\n\r\n useEffect(() => {\r\n if (draggingId === null) {\r\n const edgeGeometries = getGeometries(edges);\r\n const edgeMeshes = edgeGeometries.map(edge => new Mesh(edge));\r\n setEdgeMeshes(edgeMeshes);\r\n }\r\n }, [getGeometries, setEdgeMeshes, edges, draggingId]);\r\n\r\n const staticEdgesRef = useRef(new Mesh());\r\n const dynamicEdgesRef = useRef(new Mesh());\r\n\r\n const intersect = useCallback(\r\n (raycaster: Raycaster): Array => {\r\n // Handle initial raycaster state:\r\n if (!raycaster.camera) {\r\n return [];\r\n }\r\n const intersections =\r\n raycaster.intersectObjects>(edgeMeshes);\r\n if (!intersections.length) {\r\n return [];\r\n }\r\n return intersections.map(\r\n intersection => edges[edgeMeshes.indexOf(intersection.object)]\r\n );\r\n },\r\n [edgeMeshes, edges]\r\n );\r\n\r\n const { handleClick, handleContextMenu, handleIntersections } = useEdgeEvents(\r\n {\r\n onClick,\r\n onContextMenu,\r\n onPointerOut,\r\n onPointerOver\r\n },\r\n contextMenu,\r\n disabled\r\n );\r\n\r\n const draggingIdRef = useRef(null);\r\n const intersectingRef = useRef>([]);\r\n\r\n useFrame(state => {\r\n staticEdgesRef.current.geometry = staticEdgesGeometry;\r\n\r\n if (disabled) {\r\n return;\r\n }\r\n\r\n const previousDraggingId = draggingIdRef.current;\r\n if (draggingId || (draggingId === null && previousDraggingId !== null)) {\r\n dynamicEdgesRef.current.geometry = getGeometry(\r\n draggingActive,\r\n draggingInactive\r\n );\r\n }\r\n\r\n draggingIdRef.current = draggingId;\r\n if (draggingId) {\r\n return;\r\n }\r\n\r\n const previousIntersecting = intersectingRef.current;\r\n const intersecting = intersect(state.raycaster);\r\n handleIntersections(previousIntersecting, intersecting);\r\n\r\n if (intersecting.join() !== previousIntersecting.join()) {\r\n dynamicEdgesRef.current.geometry = getGeometry(intersecting, []);\r\n }\r\n\r\n intersectingRef.current = intersecting;\r\n });\r\n\r\n return (\r\n \r\n {/* Static edges */}\r\n \r\n \r\n \r\n \r\n {/* Dynamic edges */}\r\n \r\n \r\n \r\n \r\n {edges.map(edge => (\r\n \r\n ))}\r\n \r\n );\r\n};\r\n","import React, { FC, useMemo, useState } from 'react';\r\nimport { ClusterGroup, animationConfig, useHoverIntent } from '../utils';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Color, DoubleSide } from 'three';\r\nimport { useStore } from '../store';\r\nimport { Label } from './Label';\r\nimport { useCursor } from 'glodrei';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport type ClusterEventArgs = Omit;\r\n\r\nexport interface ClusterProps extends ClusterGroup {\r\n /**\r\n * Whether the circle should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The radius of the circle. Default 1.\r\n */\r\n radius?: number;\r\n\r\n /**\r\n * The padding of the circle. Default 20.\r\n */\r\n padding?: number;\r\n\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * Whether the node is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * When the cluster was clicked.\r\n */\r\n onClick?: (cluster: ClusterEventArgs, event: ThreeEvent) => void;\r\n\r\n /**\r\n * When a cluster receives a pointer over event.\r\n */\r\n onPointerOver?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When cluster receives a pointer leave event.\r\n */\r\n onPointerOut?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nexport const Cluster: FC = ({\r\n animated,\r\n position,\r\n padding,\r\n labelFontUrl,\r\n disabled,\r\n radius,\r\n nodes,\r\n label,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const rad = Math.max(position.width, position.height) / 2;\r\n const offset = rad - radius + padding;\r\n const [active, setActive] = useState(false);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const isActive = useStore(state =>\r\n state.actives?.some(id => nodes.some(n => n.id === id))\r\n );\r\n\r\n const isSelected = useStore(state =>\r\n state.selections?.some(id => nodes.some(n => n.id === id))\r\n );\r\n\r\n const hasSelections = useStore(state => state.selections?.length > 0);\r\n\r\n const opacity = hasSelections\r\n ? isSelected || active || isActive\r\n ? theme.cluster?.selectedOpacity\r\n : theme.cluster?.inactiveOpacity\r\n : theme.cluster?.opacity;\r\n\r\n const { circleOpacity, circlePosition, labelPosition } = useSpring({\r\n from: {\r\n circlePosition: [center.x, center.y, -1],\r\n circleOpacity: 0,\r\n labelPosition: [0, -offset, 2]\r\n },\r\n to: {\r\n labelPosition: [0, -offset, 2],\r\n circlePosition: position ? [position.x, position.y, -1] : [0, 0, -1],\r\n circleOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedStroke = useMemo(\r\n () => new Color(theme.cluster?.stroke),\r\n [theme.cluster?.stroke]\r\n );\r\n\r\n const normalizedFill = useMemo(\r\n () => new Color(theme.cluster?.fill),\r\n [theme.cluster?.fill]\r\n );\r\n\r\n useCursor(active && onClick !== undefined, 'pointer');\r\n\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled,\r\n onPointerOver: (event: ThreeEvent) => {\r\n setActive(true);\r\n onPointerOver?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n setActive(false);\r\n onPointerOut?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n }\r\n });\r\n\r\n const cluster = useMemo(\r\n () =>\r\n theme.cluster && (\r\n ) => {\r\n if (!disabled) {\r\n onClick?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {theme.cluster?.label && (\r\n \r\n \r\n \r\n )}\r\n \r\n ),\r\n [\r\n theme.cluster,\r\n circlePosition,\r\n pointerOver,\r\n pointerOut,\r\n offset,\r\n normalizedFill,\r\n circleOpacity,\r\n rad,\r\n padding,\r\n normalizedStroke,\r\n labelPosition,\r\n label,\r\n opacity,\r\n labelFontUrl,\r\n disabled,\r\n onClick,\r\n nodes\r\n ]\r\n );\r\n\r\n return cluster;\r\n};\r\n\r\nCluster.defaultProps = {\r\n radius: 2,\r\n padding: 40\r\n};\r\n","import React, {\r\n FC,\r\n forwardRef,\r\n Fragment,\r\n ReactNode,\r\n Ref,\r\n useImperativeHandle,\r\n useMemo\r\n} from 'react';\r\nimport { useGraph } from './useGraph';\r\nimport { LayoutOverrides, LayoutTypes } from './layout';\r\nimport {\r\n NodeContextMenuProps,\r\n ContextMenuEvent,\r\n GraphEdge,\r\n GraphNode,\r\n InternalGraphEdge,\r\n InternalGraphNode,\r\n NodeRenderer,\r\n CollapseProps\r\n} from './types';\r\nimport { SizingType } from './sizing';\r\nimport {\r\n Cluster,\r\n ClusterEventArgs,\r\n Edge,\r\n EdgeArrowPosition,\r\n EdgeInterpolation,\r\n EdgeLabelPosition,\r\n Edges,\r\n Node\r\n} from './symbols';\r\nimport {\r\n CenterNodesParams,\r\n FitNodesParams,\r\n useCenterGraph\r\n} from './CameraControls';\r\nimport { LabelVisibilityType } from './utils';\r\nimport { useStore } from './store';\r\nimport Graph from 'graphology';\r\nimport { ThreeEvent, useThree } from '@react-three/fiber';\r\n\r\nexport interface GraphSceneProps {\r\n /**\r\n * Type of layout.\r\n */\r\n layoutType?: LayoutTypes;\r\n\r\n /**\r\n * List of ids that are selected.\r\n */\r\n selections?: string[];\r\n\r\n /**\r\n * List of ids that are active.\r\n */\r\n actives?: string[];\r\n\r\n /**\r\n * List of node ids that are collapsed.\r\n */\r\n collapsedNodeIds?: string[];\r\n\r\n /**\r\n * Animate or not the graph positions.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Nodes to pass to the graph.\r\n */\r\n nodes: GraphNode[];\r\n\r\n /**\r\n * Edges to pass to the graph.\r\n */\r\n edges: GraphEdge[];\r\n\r\n /**\r\n * Context menu element.\r\n */\r\n contextMenu?: (event: ContextMenuEvent) => ReactNode;\r\n\r\n /**\r\n * Type of sizing for nodes.\r\n */\r\n sizingType?: SizingType;\r\n\r\n /**\r\n * Type of visibility for labels.\r\n */\r\n labelType?: LabelVisibilityType;\r\n\r\n /**\r\n * Place of visibility for edge labels.\r\n */\r\n edgeLabelPosition?: EdgeLabelPosition;\r\n\r\n /**\r\n * Placement of edge arrows.\r\n */\r\n edgeArrowPosition?: EdgeArrowPosition;\r\n\r\n /**\r\n * Shape of edge.\r\n */\r\n edgeInterpolation?: EdgeInterpolation;\r\n\r\n /**\r\n * Font of label, same as troika-three-text\r\n * The URL of a custom font file to be used. Supported font formats are: * .ttf * .otf * .woff (.woff2 is not supported)\r\n * Default: The Roboto font loaded from Google Fonts CDN\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * Attribute based sizing property.\r\n */\r\n sizingAttribute?: string;\r\n\r\n /**\r\n * The default size to size nodes to. Default is 7.\r\n */\r\n defaultNodeSize?: number;\r\n\r\n /**\r\n * When using sizing attributes, the min size a node can be.\r\n */\r\n minNodeSize?: number;\r\n\r\n /**\r\n * When using sizing attributes, the max size a node can be.\r\n */\r\n maxNodeSize?: number;\r\n\r\n /**\r\n * Attribute used for clustering.\r\n */\r\n clusterAttribute?: string;\r\n\r\n /**\r\n * Disable interactions or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Allow dragging of nodes.\r\n */\r\n draggable?: boolean;\r\n\r\n /**\r\n * Render a custom node\r\n */\r\n renderNode?: NodeRenderer;\r\n\r\n /**\r\n * Advanced overrides for the layout.\r\n */\r\n layoutOverrides?: LayoutOverrides;\r\n\r\n /**\r\n * When a node was clicked.\r\n */\r\n onNodeClick?: (\r\n node: InternalGraphNode,\r\n props?: CollapseProps,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a node was double clicked.\r\n */\r\n onNodeDoubleClick?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a node context menu happened.\r\n */\r\n onNodeContextMenu?: (\r\n node: InternalGraphNode,\r\n props?: NodeContextMenuProps\r\n ) => void;\r\n\r\n /**\r\n * When node got a pointer over.\r\n */\r\n onNodePointerOver?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When node lost pointer over.\r\n */\r\n onNodePointerOut?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * Triggered after a node was dragged.\r\n */\r\n onNodeDragged?: (node: InternalGraphNode) => void;\r\n\r\n /**\r\n * When a edge context menu happened.\r\n */\r\n onEdgeContextMenu?: (edge?: InternalGraphEdge) => void;\r\n\r\n /**\r\n * When an edge was clicked.\r\n */\r\n onEdgeClick?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When edge got a pointer over.\r\n */\r\n onEdgePointerOver?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When edge lost pointer over.\r\n */\r\n onEdgePointerOut?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a cluster was clicked.\r\n */\r\n onClusterClick?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a cluster receives a pointer over event.\r\n */\r\n onClusterPointerOver?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When cluster receives a pointer leave event.\r\n */\r\n onClusterPointerOut?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nexport interface GraphSceneRef {\r\n /**\r\n * Reference to the graph object.\r\n */\r\n graph: Graph;\r\n\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `ids` are not currently in view. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerGraph: (nodeIds?: string[], opts?: CenterNodesParams) => void;\r\n\r\n /**\r\n * Fit all the given nodes into view of the camera.\r\n *\r\n * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\r\n * the view will fit to all nodes.\r\n *\r\n * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\r\n * only be fit if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the view will only be fit if one or more of the nodes\r\n * specified by `ids` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the view will be fit regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n fitNodesInView: (nodeIds?: string[], opts?: FitNodesParams) => void;\r\n\r\n /**\r\n * Calls render scene on the graph. this is useful when you want to manually render the graph\r\n * for things like screenshots.\r\n */\r\n renderScene: () => void;\r\n}\r\n\r\nexport const GraphScene: FC }> =\r\n forwardRef(\r\n (\r\n {\r\n onNodeClick,\r\n onNodeDoubleClick,\r\n onNodeContextMenu,\r\n onEdgeContextMenu,\r\n onEdgeClick,\r\n onEdgePointerOver,\r\n onEdgePointerOut,\r\n onNodePointerOver,\r\n onNodePointerOut,\r\n onClusterClick,\r\n onNodeDragged,\r\n onClusterPointerOver,\r\n onClusterPointerOut,\r\n contextMenu,\r\n animated,\r\n disabled,\r\n draggable,\r\n edgeLabelPosition,\r\n edgeArrowPosition,\r\n edgeInterpolation,\r\n labelFontUrl,\r\n renderNode,\r\n ...rest\r\n },\r\n ref\r\n ) => {\r\n const { layoutType, clusterAttribute } = rest;\r\n\r\n // Get the gl/scene/camera for render shortcuts\r\n const gl = useThree(state => state.gl);\r\n const scene = useThree(state => state.scene);\r\n const camera = useThree(state => state.camera);\r\n\r\n // Mount and build the graph\r\n useGraph(rest);\r\n\r\n if (\r\n clusterAttribute &&\r\n !(layoutType === 'forceDirected2d' || layoutType === 'forceDirected3d')\r\n ) {\r\n throw new Error(\r\n 'Clustering is only supported for the force directed layouts.'\r\n );\r\n }\r\n\r\n // Get the graph and nodes via the store for memo\r\n const graph = useStore(state => state.graph);\r\n const nodes = useStore(state => state.nodes);\r\n const edges = useStore(state => state.edges);\r\n const clusters = useStore(state => [...state.clusters.values()]);\r\n\r\n // Center the graph on the nodes\r\n const { centerNodesById, fitNodesInViewById, isCentered } =\r\n useCenterGraph({\r\n animated,\r\n disabled,\r\n layoutType\r\n });\r\n\r\n // Let's expose some helper methods\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n centerGraph: centerNodesById,\r\n fitNodesInView: fitNodesInViewById,\r\n graph,\r\n renderScene: () => gl.render(scene, camera)\r\n }),\r\n [centerNodesById, fitNodesInViewById, graph, gl, scene, camera]\r\n );\r\n\r\n const nodeComponents = useMemo(\r\n () =>\r\n nodes.map(n => (\r\n \r\n )),\r\n [\r\n animated,\r\n contextMenu,\r\n disabled,\r\n draggable,\r\n labelFontUrl,\r\n nodes,\r\n onNodeClick,\r\n onNodeContextMenu,\r\n onNodeDoubleClick,\r\n onNodeDragged,\r\n onNodePointerOut,\r\n onNodePointerOver,\r\n renderNode\r\n ]\r\n );\r\n\r\n const edgeComponents = useMemo(\r\n () =>\r\n animated ? (\r\n edges.map(e => (\r\n \r\n ))\r\n ) : (\r\n \r\n ),\r\n [\r\n animated,\r\n contextMenu,\r\n disabled,\r\n edgeArrowPosition,\r\n edgeInterpolation,\r\n edgeLabelPosition,\r\n edges,\r\n labelFontUrl,\r\n onEdgeClick,\r\n onEdgeContextMenu,\r\n onEdgePointerOut,\r\n onEdgePointerOver\r\n ]\r\n );\r\n\r\n const clusterComponents = useMemo(\r\n () =>\r\n clusters.map(c => (\r\n \r\n )),\r\n [\r\n animated,\r\n clusters,\r\n disabled,\r\n labelFontUrl,\r\n onClusterClick,\r\n onClusterPointerOut,\r\n onClusterPointerOver\r\n ]\r\n );\r\n\r\n return (\r\n isCentered && (\r\n \r\n {edgeComponents}\r\n {nodeComponents}\r\n {clusterComponents}\r\n \r\n )\r\n );\r\n }\r\n );\r\n\r\nGraphScene.defaultProps = {\r\n edgeInterpolation: 'linear'\r\n};\r\n","import { Theme } from './theme';\r\n\r\nexport const darkTheme: Theme = {\r\n canvas: {\r\n background: '#1E2026'\r\n },\r\n node: {\r\n fill: '#7A8C9E',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n },\r\n subLabel: {\r\n stroke: '#1E2026',\r\n color: '#ACBAC7',\r\n activeColor: '#1DE9AC'\r\n }\r\n },\r\n lasso: {\r\n border: '1px solid #55aaff',\r\n background: 'rgba(75, 160, 255, 0.1)'\r\n },\r\n ring: {\r\n fill: '#54616D',\r\n activeFill: '#1DE9AC'\r\n },\r\n edge: {\r\n fill: '#ffffff',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 4,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n }\r\n },\r\n arrow: {\r\n fill: '#474B56',\r\n activeFill: '#1DE9AC'\r\n },\r\n cluster: {\r\n stroke: '#474B56',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 4,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n }\r\n }\r\n};\r\n","import { Theme } from './theme';\r\n\r\nexport const lightTheme: Theme = {\r\n canvas: {\r\n background: '#fff'\r\n },\r\n node: {\r\n fill: '#7CA0AB',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.2,\r\n label: {\r\n color: '#2A6475',\r\n // stroke: '#fff',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n },\r\n subLabel: {\r\n color: '#ddd',\r\n stroke: 'transparent',\r\n activeColor: '#1DE9AC'\r\n }\r\n },\r\n lasso: {\r\n border: '1px solid #55aaff',\r\n background: 'rgba(75, 160, 255, 0.1)'\r\n },\r\n ring: {\r\n fill: '#D8E6EA',\r\n activeFill: '#1DE9AC'\r\n },\r\n edge: {\r\n fill: '#474B56',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n // stroke: '#fff',\r\n color: '#2A6475',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n }\r\n },\r\n arrow: {\r\n fill: '#D8E6EA',\r\n activeFill: '#1DE9AC'\r\n },\r\n cluster: {\r\n stroke: '#D8E6EA',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n stroke: '#1E2026',\r\n color: '#ACBAC7',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n }\r\n }\r\n};\r\n","import { Theme } from '../themes';\r\nimport Graph from 'graphology';\r\n\r\nexport type PathSelectionTypes = 'direct' | 'out' | 'in' | 'all';\r\n\r\n/**\r\n * Given a graph and a list of node ids, return the adjacent nodes and edges.\r\n *\r\n * TODO: This method could be improved with the introduction of graphology\r\n */\r\nexport function getAdjacents(\r\n graph: Graph,\r\n nodeIds: string | string[],\r\n type: PathSelectionTypes\r\n) {\r\n nodeIds = Array.isArray(nodeIds) ? nodeIds : [nodeIds];\r\n\r\n const nodes: string[] = [];\r\n const edges: string[] = [];\r\n\r\n for (const nodeId of nodeIds) {\r\n const graphLinks = [\r\n ...(graph.inEdgeEntries(nodeId) ?? []),\r\n ...(graph.outEdgeEntries(nodeId) ?? [])\r\n ];\r\n\r\n if (!graphLinks) {\r\n continue;\r\n }\r\n\r\n for (const link of graphLinks) {\r\n const linkId = link.attributes.id;\r\n\r\n if (type === 'in') {\r\n if (link.target === nodeId && !edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n } else if (type === 'out') {\r\n if (link.source === nodeId && !edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n } else {\r\n if (!edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n }\r\n\r\n if (type === 'out' || type === 'all') {\r\n const toId = link.target;\r\n if (!nodes.includes(toId as string)) {\r\n nodes.push(toId as string);\r\n }\r\n }\r\n\r\n if (type === 'in' || type === 'all') {\r\n if (!nodes.includes(link.source)) {\r\n nodes.push(link.source as string);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n nodes,\r\n edges\r\n };\r\n}\r\n\r\n/**\r\n * Set the vectors.\r\n */\r\nexport function prepareRay(event, vec, size) {\r\n const { offsetX, offsetY } = event;\r\n const { width, height } = size;\r\n vec.set((offsetX / width) * 2 - 1, -(offsetY / height) * 2 + 1);\r\n}\r\n\r\n/**\r\n * Create a lasso element.\r\n */\r\nexport function createElement(theme: Theme) {\r\n const element = document.createElement('div');\r\n element.style.pointerEvents = 'none';\r\n element.style.border = theme.lasso.border;\r\n element.style.backgroundColor = theme.lasso.background;\r\n element.style.position = 'fixed';\r\n return element;\r\n}\r\n","import React, {\r\n FC,\r\n PropsWithChildren,\r\n useCallback,\r\n useEffect,\r\n useRef\r\n} from 'react';\r\nimport { useThree } from '@react-three/fiber';\r\nimport { SelectionBox } from 'three-stdlib';\r\nimport { Mesh, Scene, TubeGeometry, Vector2 } from 'three';\r\nimport { useCameraControls } from '../CameraControls';\r\nimport { useStore } from '../store';\r\nimport { createElement, prepareRay } from './utils';\r\n\r\nexport type LassoType = 'none' | 'all' | 'node' | 'edge';\r\n\r\nexport type LassoProps = PropsWithChildren<{\r\n /**\r\n * Whether the lasso tool is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The type of the lasso tool.\r\n */\r\n type?: LassoType;\r\n\r\n /**\r\n * A function that is called when the lasso tool is used to select nodes.\r\n * The function receives an array of the ids of the selected nodes.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * A function that is called when the lasso tool is released, ending the selection.\r\n * The function receives an array of the ids of the selected nodes.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n}>;\r\n\r\nexport const Lasso: FC = ({\r\n children,\r\n type = 'none',\r\n onLasso,\r\n onLassoEnd,\r\n disabled\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const camera = useThree(state => state.camera);\r\n const gl = useThree(state => state.gl);\r\n const setEvents = useThree(state => state.setEvents);\r\n const size = useThree(state => state.size);\r\n const get = useThree(state => state.get);\r\n const scene = useThree(state => state.scene);\r\n\r\n const cameraControls = useCameraControls();\r\n\r\n const actives = useStore(state => state.actives);\r\n const setActives = useStore(state => state.setActives);\r\n const edges = useStore(state => state.edges);\r\n const edgeMeshes = useStore(state => state.edgeMeshes);\r\n\r\n const mountedRef = useRef(false);\r\n const selectionBoxRef = useRef(null);\r\n const edgeMeshSelectionBoxRef = useRef(null);\r\n const elementRef = useRef(createElement(theme));\r\n const vectorsRef = useRef<[Vector2, Vector2, Vector2] | null>(null);\r\n const isDownRef = useRef(false);\r\n const oldRaycasterEnabledRef = useRef(get().events.enabled);\r\n const oldControlsEnabledRef = useRef(\r\n cameraControls.controls?.enabled\r\n );\r\n\r\n useEffect(() => {\r\n if (mountedRef.current) {\r\n onLasso?.(actives);\r\n }\r\n\r\n mountedRef.current = true;\r\n }, [actives, onLasso]);\r\n\r\n const onPointerMove = useCallback(\r\n event => {\r\n if (isDownRef.current) {\r\n const [startPoint, pointTopLeft, pointBottomRight] = vectorsRef.current;\r\n\r\n pointBottomRight.x = Math.max(startPoint.x, event.clientX);\r\n pointBottomRight.y = Math.max(startPoint.y, event.clientY);\r\n pointTopLeft.x = Math.min(startPoint.x, event.clientX);\r\n pointTopLeft.y = Math.min(startPoint.y, event.clientY);\r\n elementRef.current.style.left = `${pointTopLeft.x}px`;\r\n elementRef.current.style.top = `${pointTopLeft.y}px`;\r\n elementRef.current.style.width = `${\r\n pointBottomRight.x - pointTopLeft.x\r\n }px`;\r\n elementRef.current.style.height = `${\r\n pointBottomRight.y - pointTopLeft.y\r\n }px`;\r\n\r\n prepareRay(event, selectionBoxRef.current.endPoint, size);\r\n prepareRay(event, edgeMeshSelectionBoxRef.current.endPoint, size);\r\n\r\n const allSelected = [];\r\n const edgesSelected = edgeMeshSelectionBoxRef.current\r\n .select()\r\n .sort(o => (o as any).uuid)\r\n .map(\r\n edge => edges[edgeMeshes.indexOf(edge as Mesh)].id\r\n );\r\n allSelected.push(...edgesSelected);\r\n\r\n const selected = selectionBoxRef.current\r\n .select()\r\n .sort(o => (o as any).uuid)\r\n .filter(\r\n o =>\r\n o.isMesh &&\r\n o.userData?.id &&\r\n (o.userData?.type === type || type === 'all')\r\n )\r\n .map(o => o.userData.id);\r\n allSelected.push(...selected);\r\n\r\n // Note: This probably isn't the best solution but\r\n // it prevents the render thrashing and causing flickering\r\n requestAnimationFrame(() => {\r\n setActives(allSelected);\r\n });\r\n\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true,\r\n capture: true,\r\n once: true\r\n });\r\n }\r\n },\r\n [edges, edgeMeshes, setActives, size, type]\r\n );\r\n\r\n const onPointerUp = useCallback(() => {\r\n if (isDownRef.current) {\r\n setEvents({ enabled: oldRaycasterEnabledRef.current });\r\n isDownRef.current = false;\r\n elementRef.current.parentElement?.removeChild(elementRef.current);\r\n cameraControls.controls.enabled = oldControlsEnabledRef.current;\r\n onLassoEnd?.(actives);\r\n\r\n document.removeEventListener('pointermove', onPointerMove);\r\n document.removeEventListener('pointerup', onPointerUp);\r\n }\r\n }, [setEvents, cameraControls.controls, onLassoEnd, actives, onPointerMove]);\r\n\r\n const onPointerDown = useCallback(\r\n event => {\r\n if (event.shiftKey) {\r\n // Let's capture the old props to restore them later\r\n oldRaycasterEnabledRef.current = get().events.enabled;\r\n oldControlsEnabledRef.current = cameraControls.controls?.enabled;\r\n\r\n // SelectionBox for all meshes\r\n selectionBoxRef.current = new SelectionBox(camera, scene);\r\n\r\n // SelectionBox for all Edge meshes (since they are combined into one geometry for rendering)\r\n const edgeScene = new Scene();\r\n if (edgeMeshes.length) {\r\n edgeScene.add(...edgeMeshes);\r\n }\r\n edgeMeshSelectionBoxRef.current = new SelectionBox(camera, edgeScene);\r\n\r\n vectorsRef.current = [\r\n // start point\r\n new Vector2(),\r\n // point top left\r\n new Vector2(),\r\n // point bottom right\r\n new Vector2()\r\n ];\r\n\r\n const [startPoint] = vectorsRef.current;\r\n\r\n cameraControls.controls.enabled = false;\r\n setEvents({ enabled: false });\r\n isDownRef.current = true;\r\n gl.domElement.parentElement?.appendChild(elementRef.current);\r\n elementRef.current.style.left = `${event.clientX}px`;\r\n elementRef.current.style.top = `${event.clientY}px`;\r\n elementRef.current.style.width = '0px';\r\n elementRef.current.style.height = '0px';\r\n startPoint.x = event.clientX;\r\n startPoint.y = event.clientY;\r\n\r\n prepareRay(event, selectionBoxRef.current.startPoint, size);\r\n prepareRay(event, edgeMeshSelectionBoxRef.current.startPoint, size);\r\n\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true,\r\n capture: true,\r\n once: true\r\n });\r\n document.addEventListener('pointerup', onPointerUp, { passive: true });\r\n }\r\n },\r\n [\r\n camera,\r\n cameraControls.controls,\r\n edgeMeshes,\r\n get,\r\n gl.domElement.parentElement,\r\n onPointerMove,\r\n onPointerUp,\r\n scene,\r\n setEvents,\r\n size\r\n ]\r\n );\r\n\r\n useEffect(() => {\r\n if (disabled || type === 'none') {\r\n return;\r\n }\r\n\r\n if (typeof window !== 'undefined') {\r\n document.addEventListener('pointerdown', onPointerDown, {\r\n passive: true\r\n });\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true\r\n });\r\n document.addEventListener('pointerup', onPointerUp, { passive: true });\r\n }\r\n\r\n return () => {\r\n if (typeof window !== 'undefined') {\r\n document.removeEventListener('pointerdown', onPointerDown);\r\n document.removeEventListener('pointermove', onPointerMove);\r\n document.removeEventListener('pointerup', onPointerUp);\r\n }\r\n };\r\n }, [type, disabled, onPointerDown, onPointerMove, onPointerUp]);\r\n\r\n return {children};\r\n};\r\n","import React, {\r\n RefObject,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useState\r\n} from 'react';\r\nimport { GraphCanvasRef } from '../GraphCanvas';\r\nimport { useHotkeys } from 'reakeys';\r\nimport { GraphEdge, GraphNode } from '../types';\r\nimport { findPath } from '../utils/paths';\r\nimport { getAdjacents, PathSelectionTypes } from './utils';\r\n\r\nexport type HotkeyTypes = 'selectAll' | 'deselect' | 'delete';\r\n\r\nexport type SelectionTypes = 'single' | 'multi' | 'multiModifier';\r\n\r\nexport interface SelectionProps {\r\n /**\r\n * Required ref for the graph.\r\n */\r\n ref: RefObject;\r\n\r\n /**\r\n * Current selections.\r\n *\r\n * Contains both nodes and edges ids.\r\n */\r\n selections?: string[];\r\n\r\n /**\r\n * Default active selections.\r\n */\r\n actives?: string[];\r\n\r\n /**\r\n * Node datas.\r\n */\r\n nodes?: GraphNode[];\r\n\r\n /**\r\n * Edge datas.\r\n */\r\n edges?: GraphEdge[];\r\n\r\n /**\r\n * Disabled or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Hotkey types\r\n */\r\n hotkeys?: HotkeyTypes[];\r\n\r\n /**\r\n * Whether to focus on select or not.\r\n */\r\n focusOnSelect?: boolean | 'singleOnly';\r\n\r\n /**\r\n * Type of selection.\r\n */\r\n type?: SelectionTypes;\r\n\r\n /**\r\n * Type of selection.\r\n */\r\n pathSelectionType?: PathSelectionTypes;\r\n\r\n /**\r\n * Whether it should active on hover or not.\r\n */\r\n pathHoverType?: PathSelectionTypes;\r\n\r\n /**\r\n * On selection change.\r\n */\r\n onSelection?: (selectionIds: string[]) => void;\r\n}\r\n\r\nexport interface SelectionResult {\r\n /**\r\n * Selections id array (of nodes and edges).\r\n */\r\n selections: string[];\r\n\r\n /**\r\n * The nodes/edges around the selections to highlight.\r\n */\r\n actives: string[];\r\n\r\n /**\r\n * Clear selections method.\r\n */\r\n clearSelections: (value?: string[]) => void;\r\n\r\n /**\r\n * A selection method.\r\n */\r\n addSelection: (value: string) => void;\r\n\r\n /**\r\n * Get the paths between two nodes.\r\n */\r\n selectNodePaths: (source: string, target: string) => void;\r\n\r\n /**\r\n * Remove selection method.\r\n */\r\n removeSelection: (value: string) => void;\r\n\r\n /**\r\n * Toggle existing selection on/off method.\r\n */\r\n toggleSelection: (value: string) => void;\r\n\r\n /**\r\n * Set internal selections.\r\n */\r\n setSelections: (value: string[]) => void;\r\n\r\n /**\r\n * On click event pass through.\r\n */\r\n onNodeClick?: (data: GraphNode) => void;\r\n\r\n /**\r\n * On canvas click event pass through.\r\n */\r\n onCanvasClick?: (event: MouseEvent) => void;\r\n\r\n /**\r\n * When the lasso happened.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the lasso ended.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n\r\n /**\r\n * When node got a pointer over.\r\n */\r\n onNodePointerOver?: (node: GraphNode) => void;\r\n\r\n /**\r\n * When node lost pointer over.\r\n */\r\n onNodePointerOut?: (node: GraphNode) => void;\r\n}\r\n\r\nexport const useSelection = ({\r\n selections = [],\r\n nodes = [],\r\n actives = [],\r\n focusOnSelect = true,\r\n type = 'single',\r\n pathHoverType = 'out',\r\n pathSelectionType = 'direct',\r\n ref,\r\n hotkeys = ['selectAll', 'deselect', 'delete'],\r\n disabled,\r\n onSelection\r\n}: SelectionProps): SelectionResult => {\r\n const [internalHovers, setInternalHovers] = useState([]);\r\n const [internalActives, setInternalActives] = useState(actives);\r\n const [internalSelections, setInternalSelections] =\r\n useState(selections);\r\n const [metaKeyDown, setMetaKeyDown] = useState(false);\r\n const isMulti = type === 'multi' || type === 'multiModifier';\r\n\r\n const addSelection = useCallback(\r\n (items: string | string[]) => {\r\n if (!disabled && items) {\r\n items = Array.isArray(items) ? items : [items];\r\n\r\n const filtered = items.filter(\r\n item => !internalSelections.includes(item)\r\n );\r\n if (filtered.length) {\r\n const next = [...internalSelections, ...filtered];\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n }\r\n },\r\n [disabled, internalSelections, onSelection]\r\n );\r\n\r\n const removeSelection = useCallback(\r\n (items: string | string[]) => {\r\n if (!disabled && items) {\r\n items = Array.isArray(items) ? items : [items];\r\n\r\n const next = internalSelections.filter(i => !items.includes(i));\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n },\r\n [disabled, internalSelections, onSelection]\r\n );\r\n\r\n const clearSelections = useCallback(\r\n (next: string | string[] = []) => {\r\n if (!disabled) {\r\n next = Array.isArray(next) ? next : [next];\r\n setInternalActives([]);\r\n setInternalSelections(next);\r\n onSelection?.(next);\r\n }\r\n },\r\n [disabled, onSelection]\r\n );\r\n\r\n const toggleSelection = useCallback(\r\n (item: string) => {\r\n const has = internalSelections.includes(item);\r\n if (has) {\r\n removeSelection(item);\r\n } else {\r\n if (!isMulti) {\r\n clearSelections(item);\r\n } else {\r\n addSelection(item);\r\n }\r\n }\r\n },\r\n [\r\n addSelection,\r\n clearSelections,\r\n internalSelections,\r\n isMulti,\r\n removeSelection\r\n ]\r\n );\r\n\r\n const onNodeClick = useCallback(\r\n (data: GraphNode) => {\r\n if (isMulti) {\r\n if (type === 'multiModifier') {\r\n if (metaKeyDown) {\r\n addSelection(data.id);\r\n } else {\r\n clearSelections(data.id);\r\n }\r\n } else {\r\n addSelection(data.id);\r\n }\r\n } else {\r\n clearSelections(data.id);\r\n }\r\n\r\n if (\r\n focusOnSelect === true ||\r\n (focusOnSelect === 'singleOnly' && !metaKeyDown)\r\n ) {\r\n if (!ref.current) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n const graph = ref.current.getGraph();\r\n const { nodes: adjacents } = getAdjacents(\r\n graph,\r\n [data.id],\r\n pathSelectionType\r\n );\r\n\r\n ref.current.fitNodesInView([data.id, ...adjacents], {\r\n fitOnlyIfNodesNotInView: true\r\n });\r\n }\r\n },\r\n [\r\n addSelection,\r\n clearSelections,\r\n focusOnSelect,\r\n isMulti,\r\n metaKeyDown,\r\n pathSelectionType,\r\n ref,\r\n type\r\n ]\r\n );\r\n\r\n const selectNodePaths = useCallback(\r\n (source: string, target: string) => {\r\n const graph = ref.current.getGraph();\r\n if (!graph) {\r\n throw new Error('Graph is not initialized');\r\n }\r\n\r\n const path = findPath(graph, source, target);\r\n clearSelections([source, target]);\r\n\r\n const result = [];\r\n for (let i = 0; i < path.length - 1; i++) {\r\n const from = path[i];\r\n const to = path[i + 1];\r\n const edge = graph.getEdgeAttributes(from, to);\r\n if (edge) {\r\n result.push(edge.id);\r\n }\r\n }\r\n\r\n setInternalActives([...path.map(p => p as string), ...result]);\r\n },\r\n [clearSelections, ref]\r\n );\r\n\r\n const onKeyDown = useCallback((event: KeyboardEvent) => {\r\n const element = event.target as any;\r\n const isSafe =\r\n element.tagName !== 'INPUT' &&\r\n element.tagName !== 'SELECT' &&\r\n element.tagName !== 'TEXTAREA' &&\r\n !element.isContentEditable;\r\n\r\n const isMeta = event.metaKey || event.ctrlKey;\r\n\r\n if (isSafe && isMeta) {\r\n event.preventDefault();\r\n setMetaKeyDown(true);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', onKeyDown);\r\n }\r\n\r\n return () => {\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', onKeyDown);\r\n }\r\n };\r\n }, [onKeyDown]);\r\n\r\n const onCanvasClick = useCallback(\r\n (event: MouseEvent) => {\r\n if (\r\n event.button !== 2 &&\r\n (internalSelections.length || internalActives.length)\r\n ) {\r\n clearSelections();\r\n setMetaKeyDown(false);\r\n\r\n // Only re-center if we have a single selection\r\n if (focusOnSelect && internalSelections.length === 1) {\r\n if (!ref.current) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n ref.current.fitNodesInView([], { fitOnlyIfNodesNotInView: true });\r\n }\r\n }\r\n },\r\n [\r\n clearSelections,\r\n focusOnSelect,\r\n internalActives.length,\r\n internalSelections.length,\r\n ref\r\n ]\r\n );\r\n\r\n const onLasso = useCallback((selections: string[]) => {\r\n setInternalActives(selections);\r\n }, []);\r\n\r\n const onLassoEnd = useCallback(\r\n (selections: string[]) => {\r\n clearSelections(selections);\r\n },\r\n [clearSelections]\r\n );\r\n\r\n const onNodePointerOver = useCallback(\r\n (data: GraphNode) => {\r\n if (pathHoverType) {\r\n const graph = ref.current.getGraph();\r\n if (!graph) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n const { nodes, edges } = getAdjacents(graph, [data.id], pathHoverType);\r\n setInternalHovers([...nodes, ...edges]);\r\n }\r\n },\r\n [pathHoverType, ref]\r\n );\r\n\r\n const onNodePointerOut = useCallback(() => {\r\n if (pathHoverType) {\r\n setInternalHovers([]);\r\n }\r\n }, [pathHoverType]);\r\n\r\n useEffect(() => {\r\n if (pathSelectionType !== 'direct' && internalSelections.length > 0) {\r\n const graph = ref.current?.getGraph();\r\n if (graph) {\r\n const { nodes, edges } = getAdjacents(\r\n graph,\r\n internalSelections,\r\n pathSelectionType\r\n );\r\n setInternalActives([...nodes, ...edges]);\r\n }\r\n }\r\n }, [internalSelections, pathSelectionType, ref]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Select All',\r\n keys: 'mod+a',\r\n disabled: !hotkeys.includes('selectAll'),\r\n category: 'Graph',\r\n description: 'Select all nodes and edges',\r\n callback: event => {\r\n event.preventDefault();\r\n\r\n if (!disabled && type !== 'single') {\r\n const next = nodes.map(n => n.id);\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n }\r\n },\r\n {\r\n name: 'Deselect Selections',\r\n category: 'Graph',\r\n disabled: !hotkeys.includes('deselect'),\r\n description: 'Deselect selected nodes and edges',\r\n keys: 'escape',\r\n callback: event => {\r\n if (!disabled) {\r\n event.preventDefault();\r\n onSelection?.([]);\r\n setInternalSelections([]);\r\n }\r\n }\r\n }\r\n ]);\r\n\r\n const joinedActives = useMemo(\r\n () => [...internalActives, ...internalHovers],\r\n [internalActives, internalHovers]\r\n );\r\n\r\n return {\r\n actives: joinedActives,\r\n onNodeClick,\r\n onNodePointerOver,\r\n onNodePointerOut,\r\n onLasso,\r\n onLassoEnd,\r\n selectNodePaths,\r\n onCanvasClick,\r\n selections: internalSelections,\r\n clearSelections,\r\n addSelection,\r\n removeSelection,\r\n toggleSelection,\r\n setSelections: setInternalSelections\r\n };\r\n};\r\n","import React, {\r\n FC,\r\n forwardRef,\r\n ReactNode,\r\n Ref,\r\n Suspense,\r\n useImperativeHandle,\r\n useRef,\r\n useMemo\r\n} from 'react';\r\nimport { Canvas } from '@react-three/fiber';\r\nimport { GraphScene, GraphSceneProps, GraphSceneRef } from './GraphScene';\r\nimport {\r\n CameraMode,\r\n CameraControls,\r\n CameraControlsRef\r\n} from './CameraControls';\r\nimport { Theme, lightTheme } from './themes';\r\nimport { createStore, Provider } from './store';\r\nimport Graph from 'graphology';\r\nimport { Lasso, LassoType } from './selection';\r\nimport ThreeCameraControls from 'camera-controls';\r\nimport css from './GraphCanvas.module.css';\r\n\r\nexport interface GraphCanvasProps extends Omit {\r\n /**\r\n * Theme to use for the graph.\r\n */\r\n theme?: Theme;\r\n\r\n /**\r\n * Type of camera interaction.\r\n */\r\n cameraMode?: CameraMode;\r\n\r\n /**\r\n * The maximum distance for the camera. Default is 50000.\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * The minimum distance for the camera. Default is 1000.\r\n */\r\n minDistance?: number;\r\n\r\n /**\r\n * The type of lasso selection.\r\n */\r\n lassoType?: LassoType;\r\n\r\n /**\r\n * Children to render in the canvas. Useful for things like lights.\r\n */\r\n children?: ReactNode;\r\n\r\n /**\r\n * Ability to extend Cavas gl options. For example { preserveDrawingBuffer: true }\r\n */\r\n glOptions?: Object;\r\n\r\n /**\r\n * When the canvas had a lasso selection.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the canvas had a lasso selection end.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the canvas was clicked but didn't hit a node/edge.\r\n */\r\n onCanvasClick?: (event: MouseEvent) => void;\r\n}\r\n\r\nexport type GraphCanvasRef = Omit &\r\n Omit & {\r\n /**\r\n * Get the graph object.\r\n */\r\n getGraph: () => Graph;\r\n\r\n /**\r\n * Get the camera controls.\r\n */\r\n getControls: () => ThreeCameraControls;\r\n\r\n /**\r\n * Export the canvas as a data URL.\r\n */\r\n exportCanvas: () => string;\r\n };\r\n\r\nconst GL_DEFAULTS = {\r\n alpha: true,\r\n antialias: true\r\n};\r\n\r\n// TODO: Fix type\r\nconst CAMERA_DEFAULTS: any = {\r\n position: [0, 0, 1000],\r\n near: 5,\r\n far: 50000,\r\n fov: 10\r\n};\r\n\r\nexport const GraphCanvas: FC }> =\r\n forwardRef(\r\n (\r\n {\r\n cameraMode,\r\n edges,\r\n children,\r\n nodes,\r\n theme,\r\n minDistance,\r\n maxDistance,\r\n onCanvasClick,\r\n animated,\r\n disabled,\r\n lassoType,\r\n onLasso,\r\n onLassoEnd,\r\n glOptions,\r\n ...rest\r\n },\r\n ref: Ref\r\n ) => {\r\n const rendererRef = useRef(null);\r\n const controlsRef = useRef(null);\r\n const canvasRef = useRef(null);\r\n\r\n useImperativeHandle(ref, () => ({\r\n centerGraph: (nodeIds, opts) =>\r\n rendererRef.current?.centerGraph(nodeIds, opts),\r\n fitNodesInView: (nodeIds, opts) =>\r\n rendererRef.current?.fitNodesInView(nodeIds, opts),\r\n zoomIn: () => controlsRef.current?.zoomIn(),\r\n zoomOut: () => controlsRef.current?.zoomOut(),\r\n dollyIn: distance => controlsRef.current?.dollyIn(distance),\r\n dollyOut: distance => controlsRef.current?.dollyOut(distance),\r\n panLeft: () => controlsRef.current?.panLeft(),\r\n panRight: () => controlsRef.current?.panRight(),\r\n panDown: () => controlsRef.current?.panDown(),\r\n panUp: () => controlsRef.current?.panUp(),\r\n resetControls: (animated?: boolean) =>\r\n controlsRef.current?.resetControls(animated),\r\n getControls: () => controlsRef.current?.controls,\r\n getGraph: () => rendererRef.current?.graph,\r\n exportCanvas: () => {\r\n rendererRef.current.renderScene();\r\n return canvasRef.current.toDataURL();\r\n }\r\n }));\r\n\r\n // Defaults to pass to the store\r\n const { selections, actives, collapsedNodeIds } = rest;\r\n\r\n // It's pretty hard to get good animation performance with large n of edges/nodes\r\n const finalAnimated =\r\n edges.length + nodes.length > 400 ? false : animated;\r\n\r\n const gl = useMemo(() => ({ ...glOptions, ...GL_DEFAULTS }), [glOptions]);\r\n\r\n // NOTE: The legacy/linear/flat flags are for color issues\r\n // Reference: https://github.com/protectwise/troika/discussions/213#discussioncomment-3086666\r\n return (\r\n
\r\n \r\n \r\n createStore({\r\n selections,\r\n actives,\r\n theme,\r\n collapsedNodeIds,\r\n canvasRef: canvasRef.current\r\n })\r\n }\r\n >\r\n {theme.canvas?.background && (\r\n \r\n )}\r\n \r\n {children}\r\n {theme.canvas?.fog && (\r\n \r\n )}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n }\r\n );\r\n\r\nGraphCanvas.defaultProps = {\r\n cameraMode: 'pan',\r\n layoutType: 'forceDirected2d',\r\n sizingType: 'default',\r\n labelType: 'auto',\r\n theme: lightTheme,\r\n animated: true,\r\n defaultNodeSize: 7,\r\n minNodeSize: 5,\r\n maxNodeSize: 15,\r\n lassoType: 'none',\r\n glOptions: {}\r\n};\r\n","import classNames from 'classnames';\r\nimport React, { FC, ReactNode } from 'react';\r\nimport css from './RadialSlice.module.css';\r\n\r\nexport interface MenuItem {\r\n /**\r\n * Label to display on the menu item.\r\n */\r\n label: string;\r\n\r\n /**\r\n * CSS Classname to apply to the slice.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * Optional icon to display on the menu item.\r\n */\r\n icon?: ReactNode;\r\n\r\n /**\r\n * Optional callback to detemine if the menu item is active.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Optional callback to handle when the menu item is clicked.\r\n */\r\n onClick?: (event: React.MouseEvent) => void;\r\n}\r\n\r\ninterface RadialSliceProps extends MenuItem {\r\n /**\r\n * The starting angle of the radial slice, in degrees.\r\n */\r\n startAngle: number;\r\n\r\n /**\r\n * The ending angle of the radial slice, in degrees.\r\n */\r\n endAngle: number;\r\n\r\n /**\r\n * The skew of the radial slice.\r\n */\r\n skew: number;\r\n\r\n /**\r\n * Whether the radial slice is polar (true) or not (false).\r\n */\r\n polar: boolean;\r\n\r\n /**\r\n * The central angle of the radial slice, in degrees.\r\n */\r\n centralAngle: number;\r\n\r\n /**\r\n * The radius of the radial slice.\r\n */\r\n radius: number;\r\n\r\n /**\r\n * The inner radius of the radial slice.\r\n */\r\n innerRadius: number;\r\n}\r\n\r\nexport const RadialSlice: FC = ({\r\n label,\r\n centralAngle,\r\n startAngle,\r\n endAngle,\r\n polar,\r\n radius,\r\n className,\r\n icon,\r\n innerRadius,\r\n skew,\r\n disabled,\r\n onClick\r\n}) => (\r\n 90 ? '100%' : '50%',\r\n height: centralAngle > 90 ? '100%' : '50%',\r\n bottom: centralAngle > 90 ? '50%' : 'initial',\r\n right: centralAngle > 90 ? '50%' : 'initial',\r\n transform: `rotate(${startAngle + endAngle}deg) skew(${skew}deg)`\r\n }}\r\n onClick={event => {\r\n if (!disabled) {\r\n onClick(event);\r\n }\r\n }}\r\n >\r\n \r\n 90 ? '50% + ' : ''\r\n }${radius}px) - ${innerRadius}px) / 2) - 4em)`\r\n }}\r\n >\r\n \r\n {icon}\r\n {label}\r\n \r\n \r\n \r\n \r\n);\r\n","import { MenuItem } from './RadialSlice';\r\n\r\nexport function calculateRadius(items: MenuItem[], startOffsetAngle: number) {\r\n const centralAngle = 360 / items.length || 360;\r\n const polar = centralAngle % 180 === 0;\r\n const deltaAngle = 90 - centralAngle;\r\n const startAngle = polar\r\n ? 45\r\n : startOffsetAngle + deltaAngle + centralAngle / 2;\r\n\r\n return { centralAngle, polar, startAngle, deltaAngle };\r\n}\r\n","import React, { FC, useLayoutEffect, useMemo, useRef } from 'react';\r\nimport { RadialSlice, MenuItem } from './RadialSlice';\r\nimport { calculateRadius } from './utils';\r\nimport css from './RadialMenu.module.css';\r\nimport classNames from 'classnames';\r\n\r\ninterface RadialMenuProps {\r\n /**\r\n * An array of menu items to be displayed in the radial menu.\r\n */\r\n items: MenuItem[];\r\n\r\n /**\r\n * The radius of the radial menu.\r\n */\r\n radius?: number;\r\n\r\n /**\r\n * The inner radius of the radial menu.\r\n */\r\n innerRadius?: number;\r\n\r\n /**\r\n * The starting offset angle for the first menu item.\r\n */\r\n startOffsetAngle?: number;\r\n\r\n /**\r\n * The CSS class name for the radial menu.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * A function that is called when the radial menu is closed.\r\n * The function receives the mouse event that triggered the closure.\r\n */\r\n onClose?: (event: React.MouseEvent) => void;\r\n}\r\n\r\nexport const RadialMenu: FC = ({\r\n items,\r\n radius,\r\n className,\r\n innerRadius,\r\n startOffsetAngle,\r\n onClose\r\n}) => {\r\n const { centralAngle, polar, startAngle, deltaAngle } = useMemo(\r\n () => calculateRadius(items, startOffsetAngle),\r\n [items, startOffsetAngle]\r\n );\r\n const timeout = useRef(null);\r\n\r\n useLayoutEffect(() => {\r\n const timer = timeout.current;\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n if (items.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n clearTimeout(timeout.current)}\r\n onPointerLeave={event => {\r\n clearTimeout(timeout.current);\r\n timeout.current = setTimeout(() => onClose?.(event), 500);\r\n }}\r\n >\r\n {items.map((slice, index) => (\r\n {\r\n slice?.onClick(event);\r\n onClose?.(event);\r\n }}\r\n />\r\n ))}\r\n \r\n );\r\n};\r\n\r\nRadialMenu.defaultProps = {\r\n radius: 175,\r\n innerRadius: 25,\r\n startOffsetAngle: 0\r\n};\r\n"],"names":["d3ForceRadial","tree","nodes","links","a","forceX","forceY","d3ForceX","d3ForceY","d3ForceSimulation","d3ForceCenter","d3ForceLink","d3ForceManyBody","d3ForceZ","_a","_b","n","disabled","theme","actives","selections","id","node","createContext","Sphere","ref","animated","DreiSvg","_c","curve","Edge","arrowPosition","arrowRotation","edge","active","inactive","draggingActive","draggingInactive","edgeMeshes","Fragment","css"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.js","sources":["../src/layout/depthUtils.ts","../src/layout/forceUtils.ts","../src/layout/layoutUtils.ts","../src/layout/forceInABox.ts","../src/layout/forceDirected.ts","../src/layout/circular2d.ts","../src/layout/hierarchical.ts","../src/layout/nooverlap.ts","../src/layout/forceatlas2.ts","../src/layout/custom.ts","../src/layout/layoutProvider.ts","../src/layout/recommender.ts","../src/utils/visibility.ts","../src/sizing/pageRank.ts","../src/sizing/centrality.ts","../src/sizing/attribute.ts","../src/sizing/nodeSizeProvider.ts","../src/utils/graph.ts","../src/utils/animation.ts","../src/utils/arrow.ts","../src/utils/position.ts","../src/utils/layout.ts","../src/utils/cluster.ts","../src/utils/useHoverIntent.ts","../src/utils/useDrag.ts","../src/utils/paths.ts","../src/store.ts","../src/collapse/utils.ts","../src/collapse/useCollapse.ts","../src/useGraph.ts","../src/symbols/Label.tsx","../src/symbols/Ring.tsx","../src/symbols/nodes/Sphere.tsx","../src/CameraControls/useCameraControls.ts","../src/CameraControls/CameraControls.tsx","../src/CameraControls/utils.ts","../src/CameraControls/useCenterGraph.ts","../src/symbols/nodes/Icon.tsx","../src/symbols/nodes/SphereWithIcon.tsx","../src/symbols/nodes/Svg.tsx","../src/symbols/nodes/SphereWithSvg.tsx","../src/symbols/Node.tsx","../src/symbols/Arrow.tsx","../src/symbols/Line.tsx","../src/symbols/Edge.tsx","../src/symbols/edges/useEdgeGeometry.ts","../src/symbols/edges/useEdgeEvents.ts","../src/symbols/edges/useEdgeAnimations.ts","../src/symbols/edges/Edge.tsx","../src/symbols/edges/Edges.tsx","../src/symbols/Cluster.tsx","../src/GraphScene.tsx","../src/themes/darkTheme.ts","../src/themes/lightTheme.ts","../src/selection/utils.ts","../src/selection/Lasso.tsx","../src/selection/useSelection.ts","../src/GraphCanvas.tsx","../src/RadialMenu/RadialSlice.tsx","../src/RadialMenu/utils.ts","../src/RadialMenu/RadialMenu.tsx"],"sourcesContent":["import { InternalGraphEdge, InternalGraphNode } from '../types';\r\n\r\nexport interface DepthNode {\r\n data: InternalGraphNode;\r\n ins: DepthNode[];\r\n out: DepthNode[];\r\n depth: number;\r\n}\r\n\r\n/**\r\n * Traverse the graph and get the depth of each node.\r\n */\r\nfunction traverseGraph(nodes: DepthNode[], nodeStack: DepthNode[] = []) {\r\n const currentDepth = nodeStack.length;\r\n\r\n for (const node of nodes) {\r\n const idx = nodeStack.indexOf(node);\r\n if (idx > -1) {\r\n const loop = [...nodeStack.slice(idx), node].map(d => d.data.id);\r\n throw new Error(\r\n `Invalid Graph: Circular node path detected: ${loop.join(' -> ')}.`\r\n );\r\n }\r\n\r\n if (currentDepth > node.depth) {\r\n node.depth = currentDepth;\r\n traverseGraph(node.out, [...nodeStack, node]);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Gets the depth of the graph's nodes. Used in the radial layout.\r\n */\r\nexport function getNodeDepth(\r\n nodes: InternalGraphNode[],\r\n links: InternalGraphEdge[]\r\n) {\r\n let invalid = false;\r\n\r\n const graph: { [key: string]: DepthNode } = nodes.reduce(\r\n (acc, cur) => ({\r\n ...acc,\r\n [cur.id]: {\r\n data: cur,\r\n out: [],\r\n depth: -1,\r\n ins: []\r\n }\r\n }),\r\n {}\r\n );\r\n\r\n try {\r\n for (const link of links) {\r\n const from = link.source;\r\n const to = link.target;\r\n\r\n if (!graph.hasOwnProperty(from)) {\r\n throw new Error(`Missing source Node ${from}`);\r\n }\r\n\r\n if (!graph.hasOwnProperty(to)) {\r\n throw new Error(`Missing target Node ${to}`);\r\n }\r\n\r\n const sourceNode = graph[from];\r\n const targetNode = graph[to];\r\n targetNode.ins.push(sourceNode);\r\n sourceNode.out.push(targetNode);\r\n }\r\n\r\n traverseGraph(Object.values(graph));\r\n } catch (e) {\r\n invalid = true;\r\n }\r\n\r\n const allDepths = Object.keys(graph).map(id => graph[id].depth);\r\n const maxDepth = Math.max(...allDepths);\r\n\r\n return {\r\n invalid,\r\n depths: graph,\r\n maxDepth: maxDepth || 1\r\n };\r\n}\r\n","import { forceRadial as d3ForceRadial } from 'd3-force-3d';\r\nimport { InternalGraphEdge, InternalGraphNode } from 'types';\r\nimport { getNodeDepth } from './depthUtils';\r\n\r\nconst RADIALS: DagMode[] = ['radialin', 'radialout'];\r\n\r\nexport type DagMode =\r\n | 'lr'\r\n | 'rl'\r\n | 'td'\r\n | 'but'\r\n | 'zout'\r\n | 'zin'\r\n | 'radialin'\r\n | 'radialout';\r\n\r\nexport interface ForceRadialInputs {\r\n nodes: InternalGraphNode[];\r\n edges: InternalGraphEdge[];\r\n mode: DagMode;\r\n nodeLevelRatio: number;\r\n}\r\n\r\n/**\r\n * Radial graph layout using D3 Force 3d.\r\n * Inspired by: https://github.com/vasturiano/three-forcegraph/blob/master/src/forcegraph-kapsule.js#L970-L1018\r\n */\r\nexport function forceRadial({\r\n nodes,\r\n edges,\r\n mode = 'lr',\r\n nodeLevelRatio = 2\r\n}: ForceRadialInputs) {\r\n const { depths, maxDepth, invalid } = getNodeDepth(nodes, edges);\r\n\r\n if (invalid) {\r\n return null;\r\n }\r\n\r\n const modeDistance = RADIALS.includes(mode) ? 1 : 5;\r\n const dagLevelDistance =\r\n (nodes.length / maxDepth) * nodeLevelRatio * modeDistance;\r\n\r\n if (mode) {\r\n const getFFn =\r\n (fix: boolean, invert: boolean) => (node: InternalGraphNode) =>\r\n !fix\r\n ? undefined\r\n : (depths[node.id].depth - maxDepth / 2) *\r\n dagLevelDistance *\r\n (invert ? -1 : 1);\r\n\r\n const fxFn = getFFn(['lr', 'rl'].includes(mode), mode === 'rl');\r\n const fyFn = getFFn(['td', 'bu'].includes(mode), mode === 'td');\r\n const fzFn = getFFn(['zin', 'zout'].includes(mode), mode === 'zout');\r\n\r\n nodes.forEach(node => {\r\n node.fx = fxFn(node);\r\n node.fy = fyFn(node);\r\n node.fz = fzFn(node);\r\n });\r\n }\r\n\r\n return RADIALS.includes(mode)\r\n ? d3ForceRadial(node => {\r\n const nodeDepth = depths[node.id];\r\n const depth =\r\n mode === 'radialin' ? maxDepth - nodeDepth.depth : nodeDepth.depth;\r\n return depth * dagLevelDistance;\r\n }).strength(1)\r\n : null;\r\n}\r\n","import Graph from 'graphology';\r\nimport { LayoutStrategy } from './types';\r\nimport { InternalGraphEdge, InternalGraphNode } from '../types';\r\n\r\n/**\r\n * Promise based tick helper.\r\n */\r\nexport function tick(layout: LayoutStrategy) {\r\n return new Promise((resolve, _reject) => {\r\n let stable: boolean | undefined;\r\n\r\n function run() {\r\n if (!stable) {\r\n stable = layout.step();\r\n run();\r\n } else {\r\n resolve(stable);\r\n }\r\n }\r\n\r\n run();\r\n });\r\n}\r\n\r\n/**\r\n * Helper function to turn the graph nodes/edges into an array for\r\n * easier manipulation.\r\n */\r\nexport function buildNodeEdges(graph: Graph) {\r\n const nodes: InternalGraphNode[] = [];\r\n const edges: InternalGraphEdge[] = [];\r\n\r\n graph.forEachNode((id, n: any) => {\r\n nodes.push({\r\n ...n,\r\n id,\r\n // This is for the clustering\r\n radius: n.size || 1\r\n });\r\n });\r\n\r\n graph.forEachEdge((id, l: any) => {\r\n edges.push({ ...l, id });\r\n });\r\n\r\n return { nodes, edges };\r\n}\r\n","import {\r\n forceSimulation,\r\n forceX,\r\n forceY,\r\n forceLink,\r\n forceManyBody,\r\n forceCollide\r\n} from 'd3-force-3d';\r\nimport { treemap, hierarchy } from 'd3-hierarchy';\r\n\r\n/**\r\n * Used for calculating clusterings of nodes.\r\n *\r\n * Modified version of: https://github.com/john-guerra/forceInABox\r\n *\r\n * Changes:\r\n * - Improved d3 import for tree shaking\r\n * - Fixed node lookup for edges using array\r\n * - Updated d3-force to use d3-force-3d\r\n * - Removed template logic\r\n */\r\nexport function forceInABox() {\r\n // d3 style\r\n const constant = (_: any) => () => _;\r\n const index = (d: any) => d.index;\r\n\r\n // Default values\r\n let id = index;\r\n let nodes = [];\r\n let links = []; // needed for the force version\r\n let tree;\r\n let size = [100, 100];\r\n let forceNodeSize = constant(1); // The expected node size used for computing the cluster node\r\n let forceCharge = constant(-1);\r\n let forceLinkDistance = constant(100);\r\n let forceLinkStrength = constant(0.1);\r\n let foci = {};\r\n let linkStrengthIntraCluster = 0.1;\r\n let linkStrengthInterCluster = 0.001;\r\n let templateNodes = [];\r\n let offset = [0, 0];\r\n let templateForce;\r\n let groupBy = d => d.cluster;\r\n let template = 'treemap';\r\n let enableGrouping = true;\r\n let strength = 0.1;\r\n\r\n function force(alpha) {\r\n if (!enableGrouping) {\r\n return force;\r\n }\r\n\r\n if (template === 'force') {\r\n // Do the tick of the template force and get the new focis\r\n templateForce.tick();\r\n getFocisFromTemplate();\r\n }\r\n\r\n for (let i = 0, n = nodes.length, node, k = alpha * strength; i < n; ++i) {\r\n node = nodes[i];\r\n node.vx += (foci[groupBy(node)].x - node.x) * k;\r\n node.vy += (foci[groupBy(node)].y - node.y) * k;\r\n }\r\n }\r\n\r\n function initialize() {\r\n if (!nodes) {\r\n return;\r\n }\r\n\r\n if (template === 'treemap') {\r\n initializeWithTreemap();\r\n } else {\r\n initializeWithForce();\r\n }\r\n }\r\n\r\n force.initialize = function (_) {\r\n nodes = _;\r\n initialize();\r\n };\r\n\r\n function getLinkKey(l) {\r\n let sourceID = groupBy(l.source),\r\n targetID = groupBy(l.target);\r\n\r\n return sourceID <= targetID\r\n ? sourceID + '~' + targetID\r\n : targetID + '~' + sourceID;\r\n }\r\n\r\n function computeClustersNodeCounts(nodes) {\r\n let clustersCounts = new Map(),\r\n tmpCount: any = {};\r\n\r\n nodes.forEach(function (d) {\r\n if (!clustersCounts.has(groupBy(d))) {\r\n clustersCounts.set(groupBy(d), { count: 0, sumforceNodeSize: 0 });\r\n }\r\n });\r\n\r\n nodes.forEach(function (d) {\r\n tmpCount = clustersCounts.get(groupBy(d));\r\n tmpCount.count = tmpCount.count + 1;\r\n tmpCount.sumforceNodeSize =\r\n tmpCount.sumforceNodeSize +\r\n // @ts-ignore\r\n Math.PI * (forceNodeSize(d) * forceNodeSize(d)) * 1.3;\r\n clustersCounts.set(groupBy(d), tmpCount);\r\n });\r\n\r\n return clustersCounts;\r\n }\r\n\r\n //Returns\r\n function computeClustersLinkCounts(links) {\r\n let dClusterLinks = new Map(),\r\n clusterLinks = [];\r\n\r\n links.forEach(function (l) {\r\n let key = getLinkKey(l),\r\n count;\r\n if (dClusterLinks.has(key)) {\r\n count = dClusterLinks.get(key);\r\n } else {\r\n count = 0;\r\n }\r\n count += 1;\r\n dClusterLinks.set(key, count);\r\n });\r\n\r\n dClusterLinks.forEach(function (value, key) {\r\n let source, target;\r\n source = key.split('~')[0];\r\n target = key.split('~')[1];\r\n if (source !== undefined && target !== undefined) {\r\n clusterLinks.push({\r\n source: source,\r\n target: target,\r\n count: value\r\n });\r\n }\r\n });\r\n\r\n return clusterLinks;\r\n }\r\n\r\n //Returns the metagraph of the clusters\r\n function getGroupsGraph() {\r\n let gnodes = [];\r\n let glinks = [];\r\n let dNodes = new Map();\r\n let c;\r\n let i;\r\n let cc;\r\n let clustersCounts;\r\n let clustersLinks;\r\n\r\n clustersCounts = computeClustersNodeCounts(nodes);\r\n clustersLinks = computeClustersLinkCounts(links);\r\n\r\n for (c of clustersCounts.keys()) {\r\n cc = clustersCounts.get(c);\r\n gnodes.push({\r\n id: c,\r\n size: cc.count,\r\n r: Math.sqrt(cc.sumforceNodeSize / Math.PI)\r\n }); // Uses approx meta-node size\r\n dNodes.set(c, i);\r\n }\r\n\r\n clustersLinks.forEach(function (l) {\r\n let source = dNodes.get(l.source),\r\n target = dNodes.get(l.target);\r\n if (source !== undefined && target !== undefined) {\r\n glinks.push({\r\n source: source,\r\n target: target,\r\n count: l.count\r\n });\r\n }\r\n });\r\n\r\n return { nodes: gnodes, links: glinks };\r\n }\r\n\r\n function getGroupsTree() {\r\n let children = [];\r\n let c;\r\n let cc;\r\n let clustersCounts;\r\n\r\n // @ts-ignore\r\n clustersCounts = computeClustersNodeCounts(force.nodes());\r\n\r\n for (c of clustersCounts.keys()) {\r\n cc = clustersCounts.get(c);\r\n children.push({ id: c, size: cc.count });\r\n }\r\n return { id: 'clustersTree', children: children };\r\n }\r\n\r\n function getFocisFromTemplate() {\r\n //compute foci\r\n // @ts-ignore\r\n foci.none = { x: 0, y: 0 };\r\n templateNodes.forEach(function (d) {\r\n if (template === 'treemap') {\r\n foci[d.data.id] = {\r\n x: d.x0 + (d.x1 - d.x0) / 2 - offset[0],\r\n y: d.y0 + (d.y1 - d.y0) / 2 - offset[1]\r\n };\r\n } else {\r\n foci[d.id] = {\r\n x: d.x - offset[0],\r\n y: d.y - offset[1]\r\n };\r\n }\r\n });\r\n return foci;\r\n }\r\n\r\n function initializeWithTreemap() {\r\n // @ts-ignore\r\n let sim = treemap().size(force.size());\r\n\r\n tree = hierarchy(getGroupsTree())\r\n .sum((d: any) => d.radius)\r\n .sort(function (a, b) {\r\n return b.height - a.height || b.value - a.value;\r\n });\r\n\r\n templateNodes = sim(tree).leaves();\r\n getFocisFromTemplate();\r\n }\r\n\r\n function checkLinksAsObjects() {\r\n // Check if links come in the format of indexes instead of objects\r\n let linkCount = 0;\r\n if (nodes.length === 0) return;\r\n\r\n links.forEach(function (link) {\r\n let source, target;\r\n if (!nodes) {\r\n return;\r\n }\r\n\r\n source = link.source;\r\n target = link.target;\r\n\r\n if (typeof link.source !== 'object') {\r\n source = nodes.find(n => n.id === link.source);\r\n }\r\n\r\n if (typeof link.target !== 'object') {\r\n target = nodes.find(n => n.id === link.target);\r\n }\r\n\r\n if (source === undefined || target === undefined) {\r\n throw Error(\r\n 'Error setting links, couldnt find nodes for a link (see it on the console)'\r\n );\r\n }\r\n link.source = source;\r\n link.target = target;\r\n link.index = linkCount++;\r\n });\r\n }\r\n\r\n function initializeWithForce() {\r\n let net;\r\n\r\n if (!nodes || !nodes.length) {\r\n return;\r\n }\r\n\r\n checkLinksAsObjects();\r\n\r\n net = getGroupsGraph();\r\n templateForce = forceSimulation(net.nodes)\r\n .force('x', forceX(size[0] / 2).strength(0.1))\r\n .force('y', forceY(size[1] / 2).strength(0.1))\r\n .force('collide', forceCollide(d => d.r).iterations(4))\r\n .force('charge', forceManyBody().strength(forceCharge))\r\n .force(\r\n 'links',\r\n forceLink(net.nodes.length ? net.links : [])\r\n .distance(forceLinkDistance)\r\n .strength(forceLinkStrength)\r\n );\r\n\r\n templateNodes = templateForce.nodes();\r\n\r\n getFocisFromTemplate();\r\n }\r\n\r\n force.template = function (x) {\r\n if (!arguments.length) {\r\n return template;\r\n }\r\n\r\n template = x;\r\n initialize();\r\n return force;\r\n };\r\n\r\n force.groupBy = function (x) {\r\n if (!arguments.length) {\r\n return groupBy;\r\n }\r\n\r\n if (typeof x === 'string') {\r\n groupBy = function (d) {\r\n return d[x];\r\n };\r\n\r\n return force;\r\n }\r\n\r\n groupBy = x;\r\n\r\n return force;\r\n };\r\n\r\n force.enableGrouping = function (x) {\r\n if (!arguments.length) {\r\n return enableGrouping;\r\n }\r\n\r\n enableGrouping = x;\r\n\r\n return force;\r\n };\r\n\r\n force.strength = function (x) {\r\n if (!arguments.length) {\r\n return strength;\r\n }\r\n\r\n strength = x;\r\n\r\n return force as any;\r\n };\r\n\r\n force.getLinkStrength = function (e) {\r\n if (enableGrouping) {\r\n if (groupBy(e.source) === groupBy(e.target)) {\r\n if (typeof linkStrengthIntraCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthIntraCluster(e);\r\n } else {\r\n return linkStrengthIntraCluster;\r\n }\r\n } else {\r\n if (typeof linkStrengthInterCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthInterCluster(e);\r\n } else {\r\n return linkStrengthInterCluster;\r\n }\r\n }\r\n } else {\r\n // Not grouping return the intracluster\r\n if (typeof linkStrengthIntraCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthIntraCluster(e);\r\n } else {\r\n return linkStrengthIntraCluster;\r\n }\r\n }\r\n };\r\n\r\n force.id = function (_) {\r\n return arguments.length ? ((id = _), force) : id;\r\n };\r\n\r\n force.size = function (_) {\r\n return arguments.length ? ((size = _), force) : size;\r\n };\r\n\r\n force.linkStrengthInterCluster = function (_) {\r\n return arguments.length\r\n ? ((linkStrengthInterCluster = _), force)\r\n : linkStrengthInterCluster;\r\n };\r\n\r\n force.linkStrengthIntraCluster = function (_) {\r\n return arguments.length\r\n ? ((linkStrengthIntraCluster = _), force)\r\n : linkStrengthIntraCluster;\r\n };\r\n\r\n force.nodes = function (_) {\r\n return arguments.length ? ((nodes = _), force) : nodes;\r\n };\r\n\r\n force.links = function (_) {\r\n if (!arguments.length) {\r\n return links;\r\n }\r\n\r\n if (_ === null) {\r\n links = [];\r\n } else {\r\n links = _;\r\n }\r\n\r\n initialize();\r\n\r\n return force;\r\n };\r\n\r\n force.template = function (x) {\r\n if (!arguments.length) {\r\n return template;\r\n }\r\n\r\n template = x;\r\n initialize();\r\n return force;\r\n };\r\n\r\n force.forceNodeSize = function (_) {\r\n return arguments.length\r\n ? ((forceNodeSize = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceNodeSize;\r\n };\r\n\r\n // Legacy support\r\n force.nodeSize = force.forceNodeSize;\r\n\r\n force.forceCharge = function (_) {\r\n return arguments.length\r\n ? ((forceCharge = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceCharge;\r\n };\r\n\r\n force.forceLinkDistance = function (_) {\r\n return arguments.length\r\n ? ((forceLinkDistance = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceLinkDistance;\r\n };\r\n\r\n force.forceLinkStrength = function (_) {\r\n return arguments.length\r\n ? ((forceLinkStrength = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceLinkStrength;\r\n };\r\n\r\n force.offset = function (_) {\r\n return arguments.length\r\n ? ((offset = typeof _ === 'function' ? _ : constant(+_)), force)\r\n : offset;\r\n };\r\n\r\n force.getFocis = getFocisFromTemplate;\r\n\r\n return force;\r\n}\r\n","import {\r\n forceSimulation as d3ForceSimulation,\r\n forceLink as d3ForceLink,\r\n forceCollide,\r\n forceManyBody as d3ForceManyBody,\r\n forceX as d3ForceX,\r\n forceY as d3ForceY,\r\n forceZ as d3ForceZ,\r\n forceCenter as d3ForceCenter\r\n} from 'd3-force-3d';\r\nimport { forceRadial, DagMode } from './forceUtils';\r\nimport { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\nimport { forceInABox } from './forceInABox';\r\nimport { FORCE_LAYOUTS } from './layoutProvider';\r\n\r\nexport interface ForceDirectedLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Center inertia for the layout. Default: 1.\r\n */\r\n centerInertia?: number;\r\n\r\n /**\r\n * Number of dimensions for the layout. 2d or 3d.\r\n */\r\n dimensions?: number;\r\n\r\n /**\r\n * Mode for the dag layout. Only applicable for dag layouts.\r\n */\r\n mode?: DagMode;\r\n\r\n /**\r\n * Distance between links.\r\n */\r\n linkDistance?: number;\r\n\r\n /**\r\n * Strength of the node repulsion.\r\n */\r\n nodeStrength?: number;\r\n\r\n /**\r\n * Strength of the cluster repulsion.\r\n */\r\n clusterStrength?: number;\r\n\r\n /**\r\n * The type of clustering.\r\n */\r\n clusterType?: 'force' | 'treemap';\r\n\r\n /**\r\n * Ratio of the distance between nodes on the same level.\r\n */\r\n nodeLevelRatio?: number;\r\n\r\n /**\r\n * LinkStrength between nodes of different clusters\r\n */\r\n linkStrengthInterCluster?: number | ((d: any) => number);\r\n\r\n /**\r\n * LinkStrength between nodes of the same cluster\r\n */\r\n linkStrengthIntraCluster?: number | ((d: any) => number);\r\n\r\n /**\r\n * Charge between the meta-nodes (Force template only)\r\n */\r\n forceLinkDistance?: number;\r\n\r\n /**\r\n * Used to compute the template force nodes size (Force template only)\r\n */\r\n forceLinkStrength?: number;\r\n\r\n /**\r\n * Used to compute the template force nodes size (Force template only)\r\n */\r\n forceCharge?: number;\r\n\r\n /**\r\n * Used to determine the simulation forceX and forceY values\r\n */\r\n forceLayout: (typeof FORCE_LAYOUTS)[number];\r\n}\r\n\r\nexport function forceDirected({\r\n graph,\r\n nodeLevelRatio = 2,\r\n mode = null,\r\n dimensions = 2,\r\n nodeStrength = -250,\r\n linkDistance = 100,\r\n clusterStrength = 0.5,\r\n linkStrengthInterCluster = 0.01,\r\n linkStrengthIntraCluster = 0.5,\r\n forceLinkDistance = 100,\r\n forceLinkStrength = 0.1,\r\n clusterType = 'force',\r\n forceCharge = -700,\r\n getNodePosition,\r\n drags,\r\n clusterAttribute,\r\n forceLayout\r\n}: ForceDirectedLayoutInputs): LayoutStrategy {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n // Dynamically adjust node strength based on the number of edges\r\n const is2d = dimensions === 2;\r\n const nodeStrengthAdjustment =\r\n is2d && edges.length > 25 ? nodeStrength * 2 : nodeStrength;\r\n\r\n let forceX;\r\n let forceY;\r\n if (forceLayout === 'forceDirected2d') {\r\n forceX = d3ForceX();\r\n forceY = d3ForceY();\r\n } else {\r\n forceX = d3ForceX(600).strength(0.05);\r\n forceY = d3ForceY(600).strength(0.05);\r\n }\r\n\r\n // Create the simulation\r\n const sim = d3ForceSimulation()\r\n .force('center', d3ForceCenter(0, 0))\r\n .force('link', d3ForceLink())\r\n .force('charge', d3ForceManyBody().strength(nodeStrengthAdjustment))\r\n .force('x', forceX)\r\n .force('y', forceY)\r\n .force('z', d3ForceZ())\r\n // Handles nodes not overlapping each other ( most relevant in clustering )\r\n .force(\r\n 'collide',\r\n forceCollide(d => d.radius + 10)\r\n )\r\n .force(\r\n 'dagRadial',\r\n forceRadial({\r\n nodes,\r\n edges,\r\n mode,\r\n nodeLevelRatio\r\n })\r\n )\r\n .stop();\r\n\r\n let groupingForce;\r\n if (clusterAttribute) {\r\n // Dynamically adjust cluster force charge based on the number of nodes\r\n let forceChargeAdjustment = forceCharge;\r\n if (nodes?.length) {\r\n const adjustmentFactor = Math.ceil(nodes.length / 200);\r\n forceChargeAdjustment = forceCharge * adjustmentFactor;\r\n }\r\n\r\n groupingForce = forceInABox()\r\n // Strength to foci\r\n .strength(clusterStrength)\r\n // Either treemap or force\r\n .template(clusterType)\r\n // Node attribute to group\r\n .groupBy(d => d.data[clusterAttribute])\r\n // The graph links. Must be called after setting the grouping attribute\r\n .links(edges)\r\n // Size of the chart\r\n .size([100, 100])\r\n // linkStrength between nodes of different clusters\r\n .linkStrengthInterCluster(linkStrengthInterCluster)\r\n // linkStrength between nodes of the same cluster\r\n .linkStrengthIntraCluster(linkStrengthIntraCluster)\r\n // linkDistance between meta-nodes on the template (Force template only)\r\n .forceLinkDistance(forceLinkDistance)\r\n // linkStrength between meta-nodes of the template (Force template only)\r\n .forceLinkStrength(forceLinkStrength)\r\n // Charge between the meta-nodes (Force template only)\r\n .forceCharge(forceChargeAdjustment)\r\n // Used to compute the template force nodes size (Force template only)\r\n .forceNodeSize(d => d.radius);\r\n }\r\n\r\n // Initialize the simulation\r\n let layout = sim.numDimensions(dimensions).nodes(nodes);\r\n\r\n if (groupingForce) {\r\n layout = layout.force('group', groupingForce);\r\n }\r\n\r\n // Run the force on the links\r\n if (linkDistance) {\r\n let linkForce = layout.force('link');\r\n if (linkForce) {\r\n linkForce\r\n .id(d => d.id)\r\n .links(edges)\r\n // When no mode passed, its a tree layout\r\n // so let's use a larger distance\r\n .distance(linkDistance);\r\n\r\n if (groupingForce) {\r\n linkForce = linkForce.strength(groupingForce?.getLinkStrength ?? 0.1);\r\n }\r\n }\r\n }\r\n\r\n const nodeMap = new Map(nodes.map(n => [n.id, n]));\r\n\r\n return {\r\n step() {\r\n // Run the simulation til we get a stable result\r\n while (sim.alpha() > 0.01) {\r\n sim.tick();\r\n }\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return nodeMap.get(id);\r\n }\r\n };\r\n}\r\n","import circular from 'graphology-layout/circular.js';\r\nimport { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface CircularLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Radius of the circle.\r\n */\r\n radius: 300;\r\n}\r\n\r\nexport function circular2d({\r\n graph,\r\n radius,\r\n drags,\r\n getNodePosition\r\n}: CircularLayoutInputs) {\r\n const layout = circular(graph, {\r\n scale: radius\r\n });\r\n\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return layout?.[id];\r\n }\r\n };\r\n}\r\n","import { InternalGraphEdge, InternalGraphNode } from 'types';\r\nimport { DepthNode, getNodeDepth } from './depthUtils';\r\nimport { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { hierarchy, stratify, tree } from 'd3-hierarchy';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface HierarchicalLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Direction of the layout. Default 'td'.\r\n */\r\n mode?: 'td' | 'lr';\r\n /**\r\n * Factor of distance between nodes. Default 1.\r\n */\r\n nodeSeparation?: number;\r\n /**\r\n * Size of each node. Default [50,50]\r\n */\r\n nodeSize?: [number, number];\r\n}\r\n\r\nconst DIRECTION_MAP = {\r\n td: {\r\n x: 'x',\r\n y: 'y',\r\n factor: -1\r\n },\r\n lr: {\r\n x: 'y',\r\n y: 'x',\r\n factor: 1\r\n }\r\n};\r\n\r\nexport function hierarchical({\r\n graph,\r\n drags,\r\n mode = 'td',\r\n nodeSeparation = 2,\r\n nodeSize = [60, 60],\r\n getNodePosition\r\n}: HierarchicalLayoutInputs): LayoutStrategy {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n // find root node by finding the nodes which have no incoming edges\r\n const parentNodes = nodes.filter(n => !edges.find(e => e.target === n.id));\r\n console.log('parentNodes', parentNodes);\r\n\r\n // if more than 1 root node, then we have multiple trees\r\n // insert a fake root node to connect all root nodes\r\n if (parentNodes.length > 1) {\r\n const fakeRootNode: InternalGraphNode = {\r\n id: 'fakeRoot',\r\n label: '',\r\n fill: '#fff',\r\n activeFill: '#fff',\r\n icon: '',\r\n data: {\r\n id: 'fakeRoot',\r\n loaded: true,\r\n extra: {\r\n id: 'fakeRoot',\r\n properties: {},\r\n labels: []\r\n },\r\n className: '',\r\n style: {\r\n label: ''\r\n }\r\n },\r\n position: {\r\n id: '',\r\n data: {},\r\n links: [],\r\n index: 0,\r\n x: 0,\r\n y: 0,\r\n z: 0,\r\n vx: 0,\r\n vy: 0\r\n }\r\n };\r\n\r\n // add fake root node to nodes\r\n nodes.push(fakeRootNode);\r\n\r\n // add edges from fake root to root nodes\r\n parentNodes.forEach(n => {\r\n edges.push({\r\n id: `fakeRoot-${n.id}`,\r\n source: 'fakeRoot',\r\n target: n.id,\r\n label: '',\r\n backgroundColor: '#fff'\r\n });\r\n });\r\n }\r\n\r\n const { depths } = getNodeDepth(nodes, edges);\r\n const rootNodes = Object.keys(depths).map(d => depths[d]);\r\n\r\n const root = stratify()\r\n .id(d => d.data.id)\r\n .parentId(d => d.ins?.[0]?.data?.id)(rootNodes);\r\n\r\n const treeRoot = tree()\r\n .separation(() => nodeSeparation)\r\n .nodeSize(nodeSize)(hierarchy(root));\r\n\r\n const treeNodes = treeRoot.descendants();\r\n const path = DIRECTION_MAP[mode];\r\n\r\n const mappedNodes = new Map(\r\n nodes.map(n => {\r\n const { x, y } = treeNodes.find((t: any) => t.data.id === n.id);\r\n return [\r\n n.id,\r\n {\r\n ...n,\r\n [path.x]: x * path.factor,\r\n [path.y]: y * path.factor,\r\n z: 0\r\n }\r\n ];\r\n })\r\n );\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return mappedNodes.get(id);\r\n }\r\n };\r\n}\r\n","import noverlapLayout from 'graphology-layout-noverlap';\r\nimport { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface NoOverlapLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Grid size. Default 20.\r\n */\r\n gridSize?: number;\r\n\r\n /**\r\n * Ratio of the layout. Default 10.\r\n */\r\n ratio?: number;\r\n\r\n /**\r\n * Maximum number of iterations. Default 50.\r\n */\r\n maxIterations?: number;\r\n\r\n /**\r\n * Margin between nodes. Default 10.\r\n */\r\n margin?: number;\r\n}\r\n\r\nexport function nooverlap({\r\n graph,\r\n margin,\r\n drags,\r\n getNodePosition,\r\n ratio,\r\n gridSize,\r\n maxIterations\r\n}: NoOverlapLayoutInputs) {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n const layout = noverlapLayout(graph, {\r\n maxIterations,\r\n inputReducer: (_key, attr) => ({\r\n ...attr,\r\n // Have to specify defaults for the engine\r\n x: attr.x || 0,\r\n y: attr.y || 0\r\n }),\r\n settings: {\r\n ratio,\r\n margin,\r\n gridSize\r\n }\r\n });\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return layout?.[id];\r\n }\r\n };\r\n}\r\n","import forceAtlas2Layout from 'graphology-layout-forceatlas2';\r\nimport { LayoutFactoryProps } from './types';\r\nimport random from 'graphology-layout/random.js';\r\n\r\nexport interface ForceAtlas2LayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Should the node’s sizes be taken into account. Default: false.\r\n */\r\n adjustSizes?: boolean;\r\n\r\n /**\r\n * whether to use the Barnes-Hut approximation to compute\r\n * repulsion in O(n*log(n)) rather than default O(n^2),\r\n * n being the number of nodes. Default: false.\r\n */\r\n barnesHutOptimize?: boolean;\r\n\r\n /**\r\n * Barnes-Hut approximation theta parameter. Default: 0.5.\r\n */\r\n barnesHutTheta?: number;\r\n\r\n /**\r\n * Influence of the edge’s weights on the layout. To consider edge weight, don’t\r\n * forget to pass weighted as true. Default: 1.\r\n */\r\n edgeWeightInfluence?: number;\r\n\r\n /**\r\n * Strength of the layout’s gravity. Default: 10.\r\n */\r\n gravity?: number;\r\n\r\n /**\r\n * Whether to use Noack’s LinLog model. Default: false.\r\n */\r\n linLogMode?: boolean;\r\n\r\n /**\r\n * Whether to consider edge weights when calculating repulsion. Default: false.\r\n */\r\n outboundAttractionDistribution?: boolean;\r\n\r\n /**\r\n * Scaling ratio for repulsion. Default: 100.\r\n */\r\n scalingRatio?: number;\r\n\r\n /**\r\n * Speed of the slowdown. Default: 1.\r\n */\r\n slowDown?: number;\r\n\r\n /**\r\n * Whether to use the strong gravity mode. Default: false.\r\n */\r\n strongGravityMode?: boolean;\r\n\r\n /**\r\n * Number of iterations to perform. Default: 50.\r\n */\r\n iterations?: number;\r\n}\r\n\r\nexport function forceAtlas2({\r\n graph,\r\n drags,\r\n iterations,\r\n ...rest\r\n}: ForceAtlas2LayoutInputs) {\r\n // Note: We need to assign a random position to each node\r\n // in order for the force atlas to work.\r\n // Reference: https://graphology.github.io/standard-library/layout-forceatlas2.html#pre-requisites\r\n random.assign(graph);\r\n\r\n const layout = forceAtlas2Layout(graph, {\r\n iterations,\r\n settings: rest\r\n });\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n // If we dragged, we need to use that position\r\n return (drags?.[id]?.position as any) || layout?.[id];\r\n }\r\n };\r\n}\r\n","import { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport function custom({ graph, drags, getNodePosition }: LayoutFactoryProps) {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n return getNodePosition(id, { graph, drags, nodes, edges });\r\n }\r\n };\r\n}\r\n","import { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { forceDirected, ForceDirectedLayoutInputs } from './forceDirected';\r\nimport { circular2d, CircularLayoutInputs } from './circular2d';\r\nimport { hierarchical, HierarchicalLayoutInputs } from './hierarchical';\r\nimport { NoOverlapLayoutInputs, nooverlap } from './nooverlap';\r\nimport { ForceAtlas2LayoutInputs, forceAtlas2 } from './forceatlas2';\r\nimport { custom } from './custom';\r\n\r\nexport type LayoutOverrides = Partial<\r\n | Omit\r\n | CircularLayoutInputs\r\n | HierarchicalLayoutInputs\r\n>;\r\n\r\nexport const FORCE_LAYOUTS = [\r\n 'forceDirected2d',\r\n 'treeTd2d',\r\n 'treeLr2d',\r\n 'radialOut2d',\r\n 'treeTd3d',\r\n 'treeLr3d',\r\n 'radialOut3d',\r\n 'forceDirected3d'\r\n];\r\n\r\nexport function layoutProvider({\r\n type,\r\n ...rest\r\n}: LayoutFactoryProps | LayoutOverrides): LayoutStrategy {\r\n if (FORCE_LAYOUTS.includes(type)) {\r\n const { nodeStrength, linkDistance, nodeLevelRatio } =\r\n rest as ForceDirectedLayoutInputs;\r\n\r\n if (type === 'forceDirected2d') {\r\n return forceDirected({\r\n ...rest,\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeTd2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'td',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeLr2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'lr',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'radialOut2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'radialout',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 100,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeTd3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'td',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 50\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeLr3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'lr',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'radialOut3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'radialout',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 100,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'forceDirected3d') {\r\n return forceDirected({\r\n ...rest,\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n }\r\n } else if (type === 'circular2d') {\r\n const { radius } = rest as CircularLayoutInputs;\r\n return circular2d({\r\n ...rest,\r\n radius: radius || 300\r\n } as CircularLayoutInputs);\r\n } else if (type === 'hierarchicalTd') {\r\n return hierarchical({ ...rest, mode: 'td' } as HierarchicalLayoutInputs);\r\n } else if (type === 'hierarchicalLr') {\r\n return hierarchical({ ...rest, mode: 'lr' } as HierarchicalLayoutInputs);\r\n } else if (type === 'nooverlap') {\r\n const { graph, maxIterations, ratio, margin, gridSize, ...settings } =\r\n rest as NoOverlapLayoutInputs;\r\n\r\n return nooverlap({\r\n type: 'nooverlap',\r\n graph,\r\n margin: margin || 10,\r\n maxIterations: maxIterations || 50,\r\n ratio: ratio || 10,\r\n gridSize: gridSize || 20,\r\n ...settings\r\n });\r\n } else if (type === 'forceatlas2') {\r\n const { graph, iterations, gravity, scalingRatio, ...settings } =\r\n rest as ForceAtlas2LayoutInputs;\r\n\r\n return forceAtlas2({\r\n type: 'forceatlas2',\r\n graph,\r\n ...settings,\r\n scalingRatio: scalingRatio || 100,\r\n gravity: gravity || 10,\r\n iterations: iterations || 50\r\n });\r\n } else if (type === 'custom') {\r\n return custom({\r\n type: 'custom',\r\n ...rest\r\n } as LayoutFactoryProps);\r\n }\r\n\r\n throw new Error(`Layout ${type} not found.`);\r\n}\r\n","import { GraphEdge, GraphNode } from '../types';\r\nimport { getNodeDepth } from './depthUtils';\r\nimport { LayoutTypes } from './types';\r\n\r\n/**\r\n * Given a set of nodes and edges, determine the type of layout that\r\n * is most ideal. This is very beta.\r\n */\r\nexport function recommendLayout(\r\n nodes: GraphNode[],\r\n edges: GraphEdge[]\r\n): LayoutTypes {\r\n const { invalid } = getNodeDepth(nodes as any[], edges as any[]);\r\n const nodeCount = nodes.length;\r\n\r\n if (!invalid) {\r\n // Large tree layouts\r\n if (nodeCount > 100) {\r\n return 'radialOut2d';\r\n } else {\r\n // Smaller tree layouts\r\n return 'treeTd2d';\r\n }\r\n }\r\n\r\n // Circular layouts\r\n return 'forceDirected2d';\r\n}\r\n","import { PerspectiveCamera } from 'three';\r\nimport { EdgeLabelPosition } from '../symbols';\r\n\r\nexport type LabelVisibilityType = 'all' | 'auto' | 'none' | 'nodes' | 'edges';\r\n\r\ninterface CalcLabelVisibilityArgs {\r\n nodeCount: number;\r\n nodePosition?: { x: number; y: number; z: number };\r\n labelType: LabelVisibilityType;\r\n camera?: PerspectiveCamera;\r\n}\r\n\r\nexport function calcLabelVisibility({\r\n nodeCount,\r\n nodePosition,\r\n labelType,\r\n camera\r\n}: CalcLabelVisibilityArgs) {\r\n return (shape: 'node' | 'edge', size: number) => {\r\n if (\r\n camera &&\r\n nodePosition &&\r\n camera?.position?.z / camera?.zoom - nodePosition?.z > 6000\r\n ) {\r\n return false;\r\n }\r\n\r\n if (labelType === 'all') {\r\n return true;\r\n } else if (labelType === 'nodes' && shape === 'node') {\r\n return true;\r\n } else if (labelType === 'edges' && shape === 'edge') {\r\n return true;\r\n } else if (labelType === 'auto' && shape === 'node') {\r\n if (size > 7) {\r\n return true;\r\n } else if (\r\n camera &&\r\n nodePosition &&\r\n camera.position.z / camera.zoom - nodePosition.z < 3000\r\n ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n}\r\n\r\nexport function getLabelOffsetByType(\r\n offset: number,\r\n position: EdgeLabelPosition\r\n): number {\r\n switch (position) {\r\n case 'above':\r\n return offset;\r\n case 'below':\r\n return -offset;\r\n case 'inline':\r\n case 'natural':\r\n default:\r\n return 0;\r\n }\r\n}\r\n","import pagerank from 'graphology-metrics/centrality/pagerank.js';\r\nimport { SizingStrategy, SizingStrategyInputs } from './types';\r\n\r\nexport function pageRankSizing({\r\n graph\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const ranks = pagerank(graph);\r\n\r\n return {\r\n ranks,\r\n getSizeForNode: (nodeID: string) => ranks[nodeID] * 80\r\n };\r\n}\r\n","import { SizingStrategy, SizingStrategyInputs } from './types';\r\nimport { degreeCentrality } from 'graphology-metrics/centrality/degree.js';\r\n\r\nexport function centralitySizing({\r\n graph\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const ranks = degreeCentrality(graph);\r\n\r\n return {\r\n ranks,\r\n getSizeForNode: (nodeID: string) => ranks[nodeID] * 20\r\n };\r\n}\r\n","import { SizingStrategy, SizingStrategyInputs } from './types';\r\n\r\nexport function attributeSizing({\r\n graph,\r\n attribute,\r\n defaultSize\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const map = new Map();\r\n\r\n if (attribute) {\r\n graph.forEachNode((id, node) => {\r\n const size = node.data?.[attribute];\r\n if (isNaN(size)) {\r\n console.warn(`Attribute ${size} is not a number for node ${node.id}`);\r\n }\r\n\r\n map.set(id, size || 0);\r\n });\r\n } else {\r\n console.warn('Attribute sizing configured but no attribute provided');\r\n }\r\n\r\n return {\r\n getSizeForNode: (nodeId: string) => {\r\n if (!attribute || !map) {\r\n return defaultSize;\r\n }\r\n\r\n return map.get(nodeId);\r\n }\r\n };\r\n}\r\n","import { pageRankSizing } from './pageRank';\r\nimport { centralitySizing } from './centrality';\r\nimport { attributeSizing } from './attribute';\r\nimport { SizingStrategyInputs } from './types';\r\nimport { scaleLinear } from 'd3-scale';\r\n\r\nexport type SizingType =\r\n | 'none'\r\n | 'pagerank'\r\n | 'centrality'\r\n | 'attribute'\r\n | 'default';\r\n\r\nexport interface NodeSizeProviderInputs extends SizingStrategyInputs {\r\n /**\r\n * The sizing strategy to use.\r\n */\r\n type: SizingType;\r\n}\r\n\r\nconst providers = {\r\n pagerank: pageRankSizing,\r\n centrality: centralitySizing,\r\n attribute: attributeSizing,\r\n none: ({ defaultSize }: SizingStrategyInputs) => ({\r\n getSizeForNode: (_id: string) => defaultSize\r\n })\r\n};\r\n\r\nexport function nodeSizeProvider({ type, ...rest }: NodeSizeProviderInputs) {\r\n const provider = providers[type]?.(rest);\r\n if (!provider && type !== 'default') {\r\n throw new Error(`Unknown sizing strategy: ${type}`);\r\n }\r\n\r\n const { graph, minSize, maxSize } = rest;\r\n const sizes = new Map();\r\n let min;\r\n let max;\r\n\r\n graph.forEachNode((id, node) => {\r\n let size;\r\n if (type === 'default') {\r\n size = node.size || rest.defaultSize;\r\n } else {\r\n size = provider.getSizeForNode(id);\r\n }\r\n\r\n if (min === undefined || size < min) {\r\n min = size;\r\n }\r\n\r\n if (max === undefined || size > max) {\r\n max = size;\r\n }\r\n\r\n sizes.set(id, size);\r\n });\r\n\r\n // Relatively scale the sizes\r\n if (type !== 'none') {\r\n const scale = scaleLinear()\r\n .domain([min, max])\r\n .rangeRound([minSize, maxSize]);\r\n\r\n for (const [nodeId, size] of sizes) {\r\n sizes.set(nodeId, scale(size));\r\n }\r\n }\r\n\r\n return sizes;\r\n}\r\n","import Graph from 'graphology';\r\nimport { nodeSizeProvider, SizingType } from '../sizing';\r\nimport {\r\n GraphEdge,\r\n GraphNode,\r\n InternalGraphEdge,\r\n InternalGraphNode\r\n} from '../types';\r\nimport { calcLabelVisibility, LabelVisibilityType } from './visibility';\r\nimport { LayoutStrategy } from '../layout';\r\n\r\n/**\r\n * Initialize the graph with the nodes/edges.\r\n */\r\nexport function buildGraph(\r\n graph: Graph,\r\n nodes: GraphNode[],\r\n edges: GraphEdge[]\r\n) {\r\n // TODO: We probably want to make this\r\n // smarter and only add/remove nodes\r\n graph.clear();\r\n\r\n for (const node of nodes) {\r\n try {\r\n graph.addNode(node.id, node);\r\n } catch ({ message }) {\r\n console.error(`[Graph] ${message}`);\r\n }\r\n }\r\n\r\n for (const edge of edges) {\r\n try {\r\n graph.addEdge(edge.source, edge.target, edge);\r\n } catch ({ message }) {\r\n console.error(`[Graph] ${message}`);\r\n }\r\n }\r\n\r\n return graph;\r\n}\r\n\r\ninterface TransformGraphInput {\r\n graph: Graph;\r\n layout: LayoutStrategy;\r\n sizingType?: SizingType;\r\n labelType?: LabelVisibilityType;\r\n sizingAttribute?: string;\r\n minNodeSize?: number;\r\n maxNodeSize?: number;\r\n defaultNodeSize?: number;\r\n}\r\n\r\n/**\r\n * Transform the graph into a format that is easier to work with.\r\n */\r\nexport function transformGraph({\r\n graph,\r\n layout,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n defaultNodeSize,\r\n minNodeSize,\r\n maxNodeSize\r\n}: TransformGraphInput) {\r\n const nodes: InternalGraphNode[] = [];\r\n const edges: InternalGraphEdge[] = [];\r\n const map = new Map();\r\n\r\n const sizes = nodeSizeProvider({\r\n graph,\r\n type: sizingType,\r\n attribute: sizingAttribute,\r\n minSize: minNodeSize,\r\n maxSize: maxNodeSize,\r\n defaultSize: defaultNodeSize\r\n });\r\n\r\n const nodeCount = graph.nodes().length;\r\n const checkVisibility = calcLabelVisibility({ nodeCount, labelType });\r\n\r\n graph.forEachNode((id, node) => {\r\n const position = layout.getNodePosition(id);\r\n const { data, fill, icon, label, size, ...rest } = node;\r\n const nodeSize = sizes.get(node.id);\r\n const labelVisible = checkVisibility('node', nodeSize);\r\n\r\n const nodeLinks = graph.inboundNeighbors(node.id) || [];\r\n const parents = nodeLinks.map(n => graph.getNodeAttributes(n));\r\n\r\n const n: InternalGraphNode = {\r\n ...(node as any),\r\n size: nodeSize,\r\n labelVisible,\r\n label,\r\n icon,\r\n fill,\r\n parents,\r\n data: {\r\n ...rest,\r\n ...(data ?? {})\r\n },\r\n position: {\r\n ...position,\r\n x: position.x || 0,\r\n y: position.y || 0,\r\n z: position.z || 1\r\n }\r\n };\r\n\r\n map.set(node.id, n);\r\n nodes.push(n);\r\n });\r\n\r\n graph.forEachEdge((_id, link) => {\r\n const from = map.get(link.source);\r\n const to = map.get(link.target);\r\n\r\n if (from && to) {\r\n const { data, id, label, size, ...rest } = link;\r\n const labelVisible = checkVisibility('edge', size);\r\n\r\n // TODO: Fix type\r\n edges.push({\r\n ...link,\r\n id,\r\n label,\r\n labelVisible,\r\n size,\r\n data: {\r\n ...rest,\r\n id,\r\n ...(data || {})\r\n }\r\n } as any);\r\n }\r\n });\r\n\r\n return {\r\n nodes,\r\n edges\r\n };\r\n}\r\n","export const animationConfig = {\r\n mass: 10,\r\n tension: 1000,\r\n friction: 300,\r\n // Decreasing precision to improve performance from 0.00001\r\n precision: 0.1\r\n};\r\n","import { Curve, Vector3 } from 'three';\r\n\r\nimport { EdgeArrowPosition } from '../symbols/Arrow';\r\n\r\n// Calculate the correct position for an arrow along a curve,\r\n// as well as the tangent to the curve at that point.\r\nexport function getArrowVectors(\r\n placement: EdgeArrowPosition,\r\n curve: Curve,\r\n arrowLength: number\r\n): [Vector3, Vector3] {\r\n const curveLength = curve.getLength();\r\n const absSize = placement === 'end' ? curveLength : curveLength / 2;\r\n const offset = placement === 'end' ? arrowLength / 2 : 0;\r\n const u = (absSize - offset) / curveLength;\r\n\r\n const position = curve.getPointAt(u);\r\n const rotation = curve.getTangentAt(u);\r\n\r\n return [position, rotation];\r\n}\r\n\r\nexport function getArrowSize(size: number): [number, number] {\r\n return [size + 6, 2 + size / 1.5];\r\n}\r\n","import { Curve, LineCurve3, QuadraticBezierCurve3, Vector3 } from 'three';\r\nimport { InternalGraphNode, InternalVector3 } from '../types';\r\n\r\nconst MULTI_EDGE_OFFSET_FACTOR = 0.7;\r\n\r\n/**\r\n * Get the midpoint given two points.\r\n */\r\nexport function getMidPoint(\r\n from: InternalVector3,\r\n to: InternalVector3,\r\n offset = 0\r\n) {\r\n const fromVector = new Vector3(from.x, from.y || 0, from.z || 0);\r\n const toVector = new Vector3(to.x, to.y || 0, to.z || 0);\r\n const midVector = new Vector3()\r\n .addVectors(fromVector, toVector)\r\n .divideScalar(2);\r\n\r\n return midVector.setLength(midVector.length() + offset);\r\n}\r\n\r\n/**\r\n * Calculate the center for a quadratic bezier curve.\r\n *\r\n * 1) Find the point halfway between the start and end points of the desired curve\r\n * 2) Find the vector pependicular to that point\r\n * 3) Find the point 1/4 the distance between start and end along that vector.\r\n */\r\nexport function getCurvePoints(\r\n from: Vector3,\r\n to: Vector3,\r\n offset = -1\r\n): [Vector3, Vector3, Vector3] {\r\n const fromVector = from.clone();\r\n const toVector = to.clone();\r\n const v = new Vector3().subVectors(toVector, fromVector);\r\n const vlen = v.length();\r\n const vn = v.clone().normalize();\r\n const vv = new Vector3().subVectors(toVector, fromVector).divideScalar(2);\r\n const k = Math.abs(vn.x) % 1;\r\n const b = new Vector3(-vn.y, vn.x - k * vn.z, k * vn.y).normalize();\r\n const vm = new Vector3()\r\n .add(fromVector)\r\n .add(vv)\r\n .add(b.multiplyScalar(vlen / 4).multiplyScalar(offset));\r\n\r\n return [from, vm, to];\r\n}\r\n\r\n/**\r\n * Get the curve given two points.\r\n */\r\nexport function getCurve(\r\n from: Vector3,\r\n fromOffset: number,\r\n to: Vector3,\r\n toOffset: number,\r\n curved: boolean,\r\n curveOffset?: number\r\n): Curve {\r\n const offsetFrom = getPointBetween(from, to, fromOffset);\r\n const offsetTo = getPointBetween(to, from, toOffset);\r\n return curved\r\n ? new QuadraticBezierCurve3(\r\n ...getCurvePoints(offsetFrom, offsetTo, curveOffset)\r\n )\r\n : new LineCurve3(offsetFrom, offsetTo);\r\n}\r\n\r\n/**\r\n * Create a threejs vector for a node.\r\n */\r\nexport function getVector(node: InternalGraphNode): Vector3 {\r\n return new Vector3(node.position.x, node.position.y, node.position.z || 0);\r\n}\r\n\r\n/**\r\n * Get the point between two vectors.\r\n */\r\nfunction getPointBetween(from: Vector3, to: Vector3, offset: number): Vector3 {\r\n const distance = from.distanceTo(to);\r\n return from.clone().add(\r\n to\r\n .clone()\r\n .sub(from)\r\n .multiplyScalar(offset / distance)\r\n );\r\n}\r\n\r\n/**\r\n * Given a node and a new vector set, update the node model.\r\n */\r\nexport function updateNodePosition(node: InternalGraphNode, offset: Vector3) {\r\n return {\r\n ...node,\r\n position: {\r\n ...node.position,\r\n x: node.position.x + offset.x,\r\n y: node.position.y + offset.y,\r\n z: node.position.z + offset.z\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Calculate the curve offset for an edge.\r\n * This is used to offset edges that are parallel to each other (same source and same target).\r\n * This will return a curveOffset of null if the edge is not parallel to any other edges.\r\n */\r\nexport function calculateEdgeCurveOffset({ edge, edges, curved }) {\r\n let updatedCurved = curved;\r\n let curveOffset: number;\r\n\r\n const parallelEdges = edges\r\n .filter(e => e.target === edge.target && e.source === edge.source)\r\n .map(e => e.id);\r\n\r\n if (parallelEdges.length > 1) {\r\n updatedCurved = true;\r\n const edgeIndex = parallelEdges.indexOf(edge.id);\r\n\r\n if (parallelEdges.length === 2) {\r\n curveOffset =\r\n edgeIndex === 0 ? MULTI_EDGE_OFFSET_FACTOR : -MULTI_EDGE_OFFSET_FACTOR;\r\n } else {\r\n curveOffset =\r\n (edgeIndex - Math.floor(parallelEdges.length / 2)) *\r\n MULTI_EDGE_OFFSET_FACTOR;\r\n }\r\n }\r\n\r\n return { curved: updatedCurved, curveOffset };\r\n}\r\n","import { InternalGraphNode } from '../types';\r\n\r\nexport interface CenterPositionVector {\r\n x: number;\r\n y: number;\r\n z: number;\r\n minX: number;\r\n maxX: number;\r\n minY: number;\r\n maxY: number;\r\n minZ: number;\r\n maxZ: number;\r\n height: number;\r\n width: number;\r\n}\r\n\r\n/**\r\n * Given a collection of nodes, get the center point.\r\n */\r\nexport function getLayoutCenter(\r\n nodes: InternalGraphNode[]\r\n): CenterPositionVector {\r\n let minX = Number.POSITIVE_INFINITY;\r\n let maxX = Number.NEGATIVE_INFINITY;\r\n let minY = Number.POSITIVE_INFINITY;\r\n let maxY = Number.NEGATIVE_INFINITY;\r\n let minZ = Number.POSITIVE_INFINITY;\r\n let maxZ = Number.NEGATIVE_INFINITY;\r\n\r\n for (let node of nodes) {\r\n minX = Math.min(minX, node.position.x);\r\n maxX = Math.max(maxX, node.position.x);\r\n minY = Math.min(minY, node.position.y);\r\n maxY = Math.max(maxY, node.position.y);\r\n minZ = Math.min(minZ, node.position.z);\r\n maxZ = Math.max(maxZ, node.position.z);\r\n }\r\n\r\n return {\r\n height: maxY - minY,\r\n width: maxX - minX,\r\n minX,\r\n maxX,\r\n minY,\r\n maxY,\r\n minZ,\r\n maxZ,\r\n x: (maxX + minX) / 2,\r\n y: (maxY + minY) / 2,\r\n z: (maxZ + minZ) / 2\r\n };\r\n}\r\n","import { InternalGraphNode } from '../types';\r\nimport { CenterPositionVector, getLayoutCenter } from './layout';\r\n\r\n/**\r\n * Given nodes and a attribute, find all the cluster groups.\r\n */\r\nexport function buildClusterGroups(\r\n nodes: InternalGraphNode[],\r\n clusterAttribute?: string\r\n) {\r\n if (!clusterAttribute) {\r\n return new Map();\r\n }\r\n\r\n return nodes.reduce((entryMap, e) => {\r\n const val = e.data[clusterAttribute];\r\n if (val) {\r\n entryMap.set(val, [...(entryMap.get(val) || []), e]);\r\n }\r\n return entryMap;\r\n }, new Map());\r\n}\r\n\r\nexport interface CalculateClustersInput {\r\n nodes: InternalGraphNode[];\r\n clusterAttribute?: string;\r\n}\r\n\r\nexport interface ClusterGroup {\r\n nodes: InternalGraphNode[];\r\n position: CenterPositionVector;\r\n label: string;\r\n}\r\n\r\n/**\r\n * Builds the cluster map.\r\n */\r\nexport function calculateClusters({\r\n nodes,\r\n clusterAttribute\r\n}: CalculateClustersInput) {\r\n const result = new Map();\r\n\r\n if (clusterAttribute) {\r\n const groups = buildClusterGroups(nodes, clusterAttribute);\r\n for (const [key, nodes] of groups) {\r\n const position = getLayoutCenter(nodes);\r\n result.set(key, {\r\n label: key,\r\n nodes,\r\n position\r\n });\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","import { useCallback, useRef } from 'react';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface HoverIntentOptions {\r\n interval?: number;\r\n sensitivity?: number;\r\n timeout?: number;\r\n disabled?: boolean;\r\n onPointerOver: (event: ThreeEvent) => void;\r\n onPointerOut: (event: ThreeEvent) => void;\r\n}\r\n\r\nexport interface HoverIntentResult {\r\n pointerOut: (event: ThreeEvent) => void;\r\n pointerOver: (event: ThreeEvent) => void;\r\n}\r\n\r\n/**\r\n * Hover intent identifies if the user actually is\r\n * intending to over by measuring the position of the mouse\r\n * once a pointer enters and determining if in a duration if\r\n * the mouse moved inside a certain threshold and fires the events.\r\n */\r\nexport const useHoverIntent = ({\r\n sensitivity = 7,\r\n interval = 50,\r\n timeout = 0,\r\n disabled,\r\n onPointerOver,\r\n onPointerOut\r\n}: HoverIntentOptions | undefined): HoverIntentResult => {\r\n const mouseOver = useRef(false);\r\n const timer = useRef(null);\r\n const state = useRef(0);\r\n const coords = useRef({\r\n x: null,\r\n y: null,\r\n px: null,\r\n py: null\r\n });\r\n\r\n const onMouseMove = useCallback((event: MouseEvent) => {\r\n coords.current.x = event.clientX;\r\n coords.current.y = event.clientY;\r\n }, []);\r\n\r\n const comparePosition = useCallback(\r\n (event: ThreeEvent) => {\r\n timer.current = clearTimeout(timer.current);\r\n const { px, x, py, y } = coords.current;\r\n\r\n if (Math.abs(px - x) + Math.abs(py - y) < sensitivity) {\r\n state.current = 1;\r\n onPointerOver(event);\r\n } else {\r\n coords.current.px = x;\r\n coords.current.py = y;\r\n timer.current = setTimeout(() => comparePosition(event), interval);\r\n }\r\n },\r\n [interval, onPointerOver, sensitivity]\r\n );\r\n\r\n const cleanup = useCallback(() => {\r\n clearTimeout(timer.current);\r\n if (typeof window !== 'undefined') {\r\n document.removeEventListener('mousemove', onMouseMove, false);\r\n }\r\n }, [onMouseMove]);\r\n\r\n const pointerOver = useCallback(\r\n (event: ThreeEvent) => {\r\n if (!disabled) {\r\n mouseOver.current = true;\r\n cleanup();\r\n\r\n if (state.current !== 1) {\r\n coords.current.px = event.pointer.x;\r\n coords.current.py = event.pointer.y;\r\n\r\n if (typeof window !== 'undefined') {\r\n document.addEventListener('mousemove', onMouseMove, false);\r\n }\r\n\r\n timer.current = setTimeout(() => comparePosition(event), timeout);\r\n }\r\n }\r\n },\r\n [cleanup, comparePosition, disabled, onMouseMove, timeout]\r\n );\r\n\r\n const delay = useCallback(\r\n (event: ThreeEvent) => {\r\n timer.current = clearTimeout(timer.current);\r\n state.current = 0;\r\n onPointerOut(event);\r\n },\r\n [onPointerOut]\r\n );\r\n\r\n const pointerOut = useCallback(\r\n (event: ThreeEvent) => {\r\n mouseOver.current = false;\r\n cleanup();\r\n\r\n if (state.current === 1) {\r\n timer.current = setTimeout(() => delay(event), timeout);\r\n }\r\n },\r\n [cleanup, delay, timeout]\r\n );\r\n\r\n return {\r\n pointerOver,\r\n pointerOut\r\n };\r\n};\r\n","import { useThree } from '@react-three/fiber';\r\nimport { useMemo } from 'react';\r\nimport { useGesture } from 'react-use-gesture';\r\nimport { Vector2, Vector3, Plane } from 'three';\r\nimport { InternalGraphPosition } from '../types';\r\n\r\ninterface DragParams {\r\n draggable: boolean;\r\n position: InternalGraphPosition;\r\n set: (position: Vector3) => void;\r\n onDragStart: () => void;\r\n onDragEnd: () => void;\r\n}\r\n\r\nexport const useDrag = ({\r\n draggable,\r\n set,\r\n position,\r\n onDragStart,\r\n onDragEnd\r\n}: DragParams) => {\r\n const camera = useThree(state => state.camera);\r\n const raycaster = useThree(state => state.raycaster);\r\n const size = useThree(state => state.size);\r\n const gl = useThree(state => state.gl);\r\n\r\n // Reference: https://codesandbox.io/s/react-three-draggable-cxu37\r\n const { mouse2D, mouse3D, offset, normal, plane } = useMemo(\r\n () => ({\r\n // Normalized 2D screen space mouse coords\r\n mouse2D: new Vector2(),\r\n // 3D world space mouse coords\r\n mouse3D: new Vector3(),\r\n // Drag point offset from object origin\r\n offset: new Vector3(),\r\n // Normal of the drag plane\r\n normal: new Vector3(),\r\n // Drag plane\r\n plane: new Plane()\r\n }),\r\n []\r\n );\r\n\r\n const clientRect = useMemo(\r\n () => gl.domElement.getBoundingClientRect(),\r\n [gl.domElement]\r\n );\r\n\r\n return useGesture(\r\n {\r\n onDragStart: ({ event }) => {\r\n // @ts-ignore\r\n const { eventObject, point } = event;\r\n\r\n // Save the offset of click point from object origin\r\n eventObject.getWorldPosition(offset).sub(point);\r\n\r\n // Set initial 3D cursor position (needed for onDrag plane calculation)\r\n mouse3D.copy(point);\r\n\r\n // Run user callback\r\n onDragStart();\r\n },\r\n onDrag: ({ event }) => {\r\n // Compute normalized mouse coordinates (screen space)\r\n const scrollX = window.scrollX || window.pageXOffset;\r\n const scrollY = window.scrollY || window.pageYOffset;\r\n\r\n const nx =\r\n ((event.clientX - (clientRect?.left ?? 0) + scrollX) / size.width) *\r\n 2 -\r\n 1;\r\n const ny =\r\n -((event.clientY - (clientRect?.top ?? 0) + scrollY) / size.height) *\r\n 2 +\r\n 1;\r\n\r\n // Unlike the mouse from useThree, this works offscreen\r\n mouse2D.set(nx, ny);\r\n\r\n // Update raycaster (otherwise it doesn't track offscreen)\r\n raycaster.setFromCamera(mouse2D, camera);\r\n\r\n // The drag plane is normal to the camera view\r\n camera.getWorldDirection(normal).negate();\r\n\r\n // Find the plane that's normal to the camera and contains our drag point\r\n plane.setFromNormalAndCoplanarPoint(normal, mouse3D);\r\n\r\n // Find the point of intersection\r\n raycaster.ray.intersectPlane(plane, mouse3D);\r\n\r\n // Update the object position with the original offset\r\n const updated = new Vector3(position.x, position.y, position.z)\r\n .copy(mouse3D)\r\n .add(offset);\r\n\r\n return set(updated);\r\n },\r\n onDragEnd\r\n },\r\n { drag: { enabled: draggable, threshold: 10 } }\r\n );\r\n};\r\n","import Graph from 'graphology';\r\nimport { bidirectional } from 'graphology-shortest-path';\r\n\r\nexport function findPath(graph: Graph, source: string, target: string) {\r\n return bidirectional(graph, source, target);\r\n}\r\n","import { StoreApi, create } from 'zustand';\r\nimport createContext from 'zustand/context';\r\nimport {\r\n InternalGraphEdge,\r\n InternalGraphNode,\r\n InternalGraphPosition\r\n} from './types';\r\nimport { BufferGeometry, Mesh, Vector3 } from 'three';\r\nimport {\r\n CenterPositionVector,\r\n ClusterGroup,\r\n getLayoutCenter,\r\n getVector,\r\n updateNodePosition\r\n} from './utils';\r\nimport Graph from 'graphology';\r\nimport { Theme } from './themes';\r\n\r\nexport type DragReferences = {\r\n [key: string]: InternalGraphNode;\r\n};\r\n\r\nexport interface GraphState {\r\n nodes: InternalGraphNode[];\r\n edges: InternalGraphEdge[];\r\n graph: Graph;\r\n clusters: Map;\r\n collapsedNodeIds?: string[];\r\n centerPosition?: CenterPositionVector;\r\n actives?: string[];\r\n selections?: string[];\r\n edgeContextMenus?: Set;\r\n setEdgeContextMenus: (edges: Set) => void;\r\n edgeMeshes: Array>;\r\n setEdgeMeshes: (edgeMeshes: Array>) => void;\r\n draggingId?: string | null;\r\n drags?: DragReferences;\r\n panning?: boolean;\r\n theme: Theme;\r\n setTheme: (theme: Theme) => void;\r\n setClusters: (clusters: Map) => void;\r\n setPanning: (panning: boolean) => void;\r\n setDrags: (drags: DragReferences) => void;\r\n setDraggingId: (id: string | null) => void;\r\n setActives: (actives: string[]) => void;\r\n setSelections: (selections: string[]) => void;\r\n setNodes: (nodes: InternalGraphNode[]) => void;\r\n setEdges: (edges: InternalGraphEdge[]) => void;\r\n setNodePosition: (id: string, position: InternalGraphPosition) => void;\r\n setCollapsedNodeIds: (nodeIds: string[]) => void;\r\n canvasRef: HTMLCanvasElement | null;\r\n}\r\n\r\nexport const { Provider, useStore } = createContext>();\r\n\r\nexport const createStore = ({\r\n actives = [],\r\n selections = [],\r\n collapsedNodeIds = [],\r\n theme,\r\n canvasRef = null\r\n}: Partial) =>\r\n create(set => ({\r\n theme: {\r\n ...theme,\r\n edge: {\r\n ...theme.edge,\r\n label: {\r\n ...theme.edge.label,\r\n fontSize: theme.edge.label.fontSize ?? 6\r\n }\r\n }\r\n },\r\n edges: [],\r\n nodes: [],\r\n collapsedNodeIds,\r\n clusters: new Map(),\r\n panning: false,\r\n draggingId: null,\r\n actives,\r\n edgeContextMenus: new Set(),\r\n edgeMeshes: [],\r\n selections,\r\n drags: {},\r\n graph: new Graph({ multi: true }),\r\n setTheme: theme => set(state => ({ ...state, theme })),\r\n setClusters: clusters => set(state => ({ ...state, clusters })),\r\n setEdgeContextMenus: edgeContextMenus =>\r\n set(state => ({\r\n ...state,\r\n edgeContextMenus\r\n })),\r\n setEdgeMeshes: edgeMeshes => set(state => ({ ...state, edgeMeshes })),\r\n setPanning: panning => set(state => ({ ...state, panning })),\r\n setDrags: drags => set(state => ({ ...state, drags })),\r\n setDraggingId: draggingId => set(state => ({ ...state, draggingId })),\r\n setActives: actives => set(state => ({ ...state, actives })),\r\n setSelections: selections => set(state => ({ ...state, selections })),\r\n setNodes: nodes =>\r\n set(state => ({\r\n ...state,\r\n nodes,\r\n centerPosition: getLayoutCenter(nodes)\r\n })),\r\n setEdges: edges => set(state => ({ ...state, edges })),\r\n setNodePosition: (id, position) =>\r\n set(state => {\r\n const node = state.nodes.find(n => n.id === id);\r\n const originalVector = getVector(node);\r\n const newVector = new Vector3(position.x, position.y, position.z);\r\n const offset = newVector.sub(originalVector);\r\n const nodes = [...state.nodes];\r\n\r\n if (state.selections?.includes(id)) {\r\n state.selections?.forEach(id => {\r\n const node = state.nodes.find(n => n.id === id);\r\n // Selections can contain edges:\r\n if (node) {\r\n const nodeIndex = state.nodes.indexOf(node);\r\n nodes[nodeIndex] = updateNodePosition(node, offset);\r\n }\r\n });\r\n } else {\r\n const nodeIndex = state.nodes.indexOf(node);\r\n nodes[nodeIndex] = updateNodePosition(node, offset);\r\n }\r\n\r\n return {\r\n ...state,\r\n drags: {\r\n ...state.drags,\r\n [id]: node\r\n },\r\n nodes\r\n };\r\n }),\r\n setCollapsedNodeIds: (nodeIds = []) =>\r\n set(state => ({ ...state, collapsedNodeIds: nodeIds })),\r\n canvasRef\r\n }));\r\n","import { GraphEdge, GraphNode } from '../types';\r\n\r\ninterface GetHiddenChildrenInput {\r\n nodeId: string;\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n currentHiddenNodes: GraphNode[];\r\n currentHiddenEdges: GraphEdge[];\r\n}\r\n\r\ninterface GetVisibleIdsInput {\r\n collapsedIds: string[];\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n}\r\n\r\ninterface GetExpandPathInput {\r\n nodeId: string;\r\n edges: GraphEdge[];\r\n visibleEdgeIds: string[];\r\n}\r\n\r\n/**\r\n * Get the children of a node id that is hidden.\r\n */\r\nfunction getHiddenChildren({\r\n nodeId,\r\n nodes,\r\n edges,\r\n currentHiddenNodes,\r\n currentHiddenEdges\r\n}: GetHiddenChildrenInput) {\r\n const hiddenNodes: GraphNode[] = [];\r\n const hiddenEdges: GraphEdge[] = [];\r\n const curHiddenNodeIds = currentHiddenNodes.map(n => n.id);\r\n const curHiddenEdgeIds = currentHiddenEdges.map(e => e.id);\r\n\r\n const outboundEdges = edges.filter(l => l.source === nodeId);\r\n const outboundEdgeNodeIds = outboundEdges.map(l => l.target);\r\n\r\n hiddenEdges.push(...outboundEdges);\r\n for (const outboundEdgeNodeId of outboundEdgeNodeIds) {\r\n const incomingEdges = edges.filter(\r\n l => l.target === outboundEdgeNodeId && l.source !== nodeId\r\n );\r\n let hideNode = false;\r\n\r\n // Check to see if any other edge is coming into this node\r\n if (incomingEdges.length === 0) {\r\n hideNode = true;\r\n } else if (\r\n incomingEdges.length > 0 &&\r\n !curHiddenNodeIds.includes(outboundEdgeNodeId)\r\n ) {\r\n // If all inbound links are hidden, hide this node as well\r\n const inboundNodeLinkIds = incomingEdges.map(l => l.id);\r\n if (inboundNodeLinkIds.every(i => curHiddenEdgeIds.includes(i))) {\r\n hideNode = true;\r\n }\r\n }\r\n if (hideNode) {\r\n // Need to hide this node and any children of this node\r\n const node = nodes.find(n => n.id === outboundEdgeNodeId);\r\n if (node) {\r\n hiddenNodes.push(node);\r\n }\r\n const nested = getHiddenChildren({\r\n nodeId: outboundEdgeNodeId,\r\n nodes,\r\n edges,\r\n currentHiddenEdges: hiddenEdges,\r\n currentHiddenNodes: hiddenNodes\r\n });\r\n hiddenEdges.push(...nested.hiddenEdges);\r\n hiddenNodes.push(...nested.hiddenNodes);\r\n }\r\n }\r\n\r\n const uniqueEdges: GraphEdge[] = Object.values(\r\n hiddenEdges.reduce(\r\n (acc, next) => ({\r\n ...acc,\r\n [next.id]: next\r\n }),\r\n {}\r\n )\r\n );\r\n\r\n const uniqueNodes: GraphNode[] = Object.values(\r\n hiddenNodes.reduce(\r\n (acc, next) => ({\r\n ...acc,\r\n [next.id]: next\r\n }),\r\n {}\r\n )\r\n );\r\n\r\n return {\r\n hiddenEdges: uniqueEdges,\r\n hiddenNodes: uniqueNodes\r\n };\r\n}\r\n\r\n/**\r\n * Get the visible nodes and edges given a collapsed set of ids.\r\n */\r\nexport const getVisibleEntities = ({\r\n collapsedIds,\r\n nodes,\r\n edges\r\n}: GetVisibleIdsInput) => {\r\n const curHiddenNodes = [];\r\n const curHiddenEdges = [];\r\n\r\n for (const collapsedId of collapsedIds) {\r\n const { hiddenEdges, hiddenNodes } = getHiddenChildren({\r\n nodeId: collapsedId,\r\n nodes,\r\n edges,\r\n currentHiddenEdges: curHiddenEdges,\r\n currentHiddenNodes: curHiddenNodes\r\n });\r\n\r\n curHiddenNodes.push(...hiddenNodes);\r\n curHiddenEdges.push(...hiddenEdges);\r\n }\r\n\r\n const hiddenNodeIds = curHiddenNodes.map(n => n.id);\r\n const hiddenEdgeIds = curHiddenEdges.map(e => e.id);\r\n const visibleNodes = nodes.filter(n => !hiddenNodeIds.includes(n.id));\r\n const visibleEdges = edges.filter(e => !hiddenEdgeIds.includes(e.id));\r\n\r\n return {\r\n visibleNodes,\r\n visibleEdges\r\n };\r\n};\r\n\r\n/**\r\n * Get the path to expand a node.\r\n */\r\nexport const getExpandPath = ({\r\n nodeId,\r\n edges,\r\n visibleEdgeIds\r\n}: GetExpandPathInput) => {\r\n const parentIds = [];\r\n const inboundEdges = edges.filter(l => l.target === nodeId);\r\n const inboundEdgeIds = inboundEdges.map(e => e.id);\r\n const hasVisibleInboundEdge = inboundEdgeIds.some(id =>\r\n visibleEdgeIds.includes(id)\r\n );\r\n\r\n if (hasVisibleInboundEdge) {\r\n // If there is a visible edge to this node, that means the node is\r\n // visible so no parents need to be expanded\r\n return parentIds;\r\n }\r\n\r\n const inboundEdgeNodeIds = inboundEdges.map(l => l.source);\r\n let addedParent = false;\r\n\r\n for (const inboundNodeId of inboundEdgeNodeIds) {\r\n if (!addedParent) {\r\n // Only want to expand a single path to the node, so if there\r\n // are multiple hidden incoming edges, only expand the first\r\n // to reduce how many nodes are expanded to get to the node\r\n parentIds.push(\r\n ...[\r\n inboundNodeId,\r\n ...getExpandPath({ nodeId: inboundNodeId, edges, visibleEdgeIds })\r\n ]\r\n );\r\n addedParent = true;\r\n }\r\n }\r\n\r\n return parentIds;\r\n};\r\n","import React, { useCallback } from 'react';\r\nimport { GraphEdge, GraphNode } from 'types';\r\nimport { getExpandPath, getVisibleEntities } from './utils';\r\n\r\nexport interface UseCollapseProps {\r\n /**\r\n * Current collapsed node ids.\r\n */\r\n collapsedNodeIds?: string[];\r\n\r\n /**\r\n * Node data.\r\n */\r\n nodes?: GraphNode[];\r\n\r\n /**\r\n * Edge data.\r\n */\r\n edges?: GraphEdge[];\r\n}\r\n\r\nexport interface CollpaseResult {\r\n /**\r\n * Determine if a node is currently collapsed\r\n */\r\n getIsCollapsed: (nodeId: string) => boolean;\r\n\r\n /**\r\n * Return a list of ids required to expand in order to view the provided node\r\n */\r\n getExpandPathIds: (nodeId: string) => string[];\r\n}\r\n\r\nexport const useCollapse = ({\r\n collapsedNodeIds = [],\r\n nodes = [],\r\n edges = []\r\n}: UseCollapseProps): CollpaseResult => {\r\n const getIsCollapsed = useCallback(\r\n (nodeId: string) => {\r\n const { visibleNodes } = getVisibleEntities({\r\n nodes,\r\n edges,\r\n collapsedIds: collapsedNodeIds\r\n });\r\n const visibleNodeIds = visibleNodes.map(n => n.id);\r\n\r\n return !visibleNodeIds.includes(nodeId);\r\n },\r\n [collapsedNodeIds, edges, nodes]\r\n );\r\n\r\n const getExpandPathIds = useCallback(\r\n (nodeId: string) => {\r\n const { visibleEdges } = getVisibleEntities({\r\n nodes,\r\n edges,\r\n collapsedIds: collapsedNodeIds\r\n });\r\n const visibleEdgeIds = visibleEdges.map(e => e.id);\r\n\r\n return getExpandPath({ nodeId, edges, visibleEdgeIds });\r\n },\r\n [collapsedNodeIds, edges, nodes]\r\n );\r\n\r\n return {\r\n getIsCollapsed,\r\n getExpandPathIds\r\n };\r\n};\r\n","import { useRef, useCallback, useEffect, useMemo } from 'react';\r\nimport { useThree } from '@react-three/fiber';\r\nimport { PerspectiveCamera } from 'three';\r\nimport { SizingType } from './sizing';\r\nimport {\r\n LayoutTypes,\r\n layoutProvider,\r\n LayoutStrategy,\r\n LayoutOverrides\r\n} from './layout';\r\nimport { LabelVisibilityType, calcLabelVisibility } from './utils/visibility';\r\nimport { tick } from './layout/layoutUtils';\r\nimport { GraphEdge, GraphNode } from './types';\r\nimport { buildGraph, transformGraph } from './utils/graph';\r\nimport { DragReferences, useStore } from './store';\r\nimport { getVisibleEntities } from './collapse';\r\nimport { calculateClusters } from './utils/cluster';\r\n\r\nexport interface GraphInputs {\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n collapsedNodeIds?: string[];\r\n layoutType?: LayoutTypes;\r\n sizingType?: SizingType;\r\n labelType?: LabelVisibilityType;\r\n sizingAttribute?: string;\r\n selections?: string[];\r\n actives?: string[];\r\n clusterAttribute?: string;\r\n defaultNodeSize?: number;\r\n minNodeSize?: number;\r\n maxNodeSize?: number;\r\n layoutOverrides?: LayoutOverrides;\r\n}\r\n\r\nexport const useGraph = ({\r\n layoutType,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n clusterAttribute,\r\n selections,\r\n nodes,\r\n edges,\r\n actives,\r\n collapsedNodeIds,\r\n defaultNodeSize,\r\n maxNodeSize,\r\n minNodeSize,\r\n layoutOverrides\r\n}: GraphInputs) => {\r\n const graph = useStore(state => state.graph);\r\n const setClusters = useStore(state => state.setClusters);\r\n const stateCollapsedNodeIds = useStore(state => state.collapsedNodeIds);\r\n const setEdges = useStore(state => state.setEdges);\r\n const stateNodes = useStore(state => state.nodes);\r\n const setNodes = useStore(state => state.setNodes);\r\n const setSelections = useStore(state => state.setSelections);\r\n const setActives = useStore(state => state.setActives);\r\n const drags = useStore(state => state.drags);\r\n const setDrags = useStore(state => state.setDrags);\r\n const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\r\n const layoutMounted = useRef(false);\r\n const layout = useRef(null);\r\n const camera = useThree(state => state.camera) as PerspectiveCamera;\r\n\r\n const { visibleEdges, visibleNodes } = useMemo(\r\n () =>\r\n getVisibleEntities({\r\n collapsedIds: stateCollapsedNodeIds,\r\n nodes,\r\n edges\r\n }),\r\n [stateCollapsedNodeIds, nodes, edges]\r\n );\r\n\r\n // Transient updates\r\n const dragRef = useRef(drags);\r\n useEffect(() => {\r\n dragRef.current = drags;\r\n }, [drags]);\r\n\r\n const updateLayout = useCallback(\r\n async (curLayout?: any) => {\r\n // Cache the layout provider\r\n layout.current =\r\n curLayout ||\r\n layoutProvider({\r\n ...layoutOverrides,\r\n type: layoutType,\r\n graph,\r\n drags: dragRef.current,\r\n clusterAttribute\r\n });\r\n\r\n // Run the layout\r\n await tick(layout.current);\r\n\r\n // Transform the graph\r\n const result = transformGraph({\r\n graph,\r\n layout: layout.current,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n maxNodeSize,\r\n minNodeSize,\r\n defaultNodeSize\r\n });\r\n\r\n // Calculate clusters\r\n const clusters = calculateClusters({\r\n nodes: result.nodes,\r\n clusterAttribute\r\n });\r\n\r\n // Set our store outputs\r\n setEdges(result.edges);\r\n setNodes(result.nodes);\r\n setClusters(clusters);\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [\r\n layoutOverrides,\r\n layoutType,\r\n clusterAttribute,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n maxNodeSize,\r\n minNodeSize,\r\n defaultNodeSize,\r\n setEdges,\r\n setNodes,\r\n setClusters\r\n ]\r\n );\r\n\r\n useEffect(() => {\r\n const nodes = stateNodes.map(node => ({\r\n ...node,\r\n labelVisible: calcLabelVisibility({\r\n nodeCount: stateNodes?.length,\r\n labelType,\r\n camera,\r\n nodePosition: node?.position\r\n })('node', node?.size)\r\n }));\r\n\r\n const isVisibilityUpdated = nodes.some(\r\n (node, i) => node.labelVisible !== stateNodes[i].labelVisible\r\n );\r\n\r\n if (isVisibilityUpdated) {\r\n setNodes(nodes);\r\n }\r\n }, [camera, camera.zoom, camera.position.z, setNodes, stateNodes, labelType]);\r\n\r\n useEffect(() => {\r\n // Let's set the store selections so its easier to access\r\n if (layoutMounted.current) {\r\n setSelections(selections);\r\n }\r\n }, [selections, setSelections]);\r\n\r\n useEffect(() => {\r\n // Let's set the store actives so its easier to access\r\n if (layoutMounted.current) {\r\n setActives(actives);\r\n }\r\n }, [actives, setActives]);\r\n\r\n // Create the nggraph graph object\r\n useEffect(() => {\r\n async function update() {\r\n layoutMounted.current = false;\r\n buildGraph(graph, visibleNodes, visibleEdges);\r\n await updateLayout();\r\n layoutMounted.current = true;\r\n }\r\n\r\n update();\r\n // eslint-disable-next-line\r\n }, [visibleNodes, visibleEdges]);\r\n\r\n useEffect(() => {\r\n // Let's set the store collapsedNodeIds so its easier to access\r\n if (layoutMounted.current) {\r\n setCollapsedNodeIds(collapsedNodeIds);\r\n }\r\n }, [collapsedNodeIds, setCollapsedNodeIds]);\r\n\r\n // Update layout on type changes\r\n useEffect(() => {\r\n if (layoutMounted.current) {\r\n // When a update is changed, discard all the previous drag positions\r\n // NOTE: This sets the transient and the state\r\n dragRef.current = {};\r\n setDrags({});\r\n\r\n // Recalculate the layout\r\n updateLayout();\r\n }\r\n }, [layoutType, updateLayout, setDrags]);\r\n\r\n // Update layout on size, label changes\r\n useEffect(() => {\r\n if (layoutMounted.current) {\r\n updateLayout(layout.current);\r\n }\r\n }, [sizingType, sizingAttribute, labelType, updateLayout]);\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { Billboard, RoundedBox, Text } from 'glodrei';\r\nimport { Color, ColorRepresentation, Euler } from 'three';\r\nimport ellipsize from 'ellipsize';\r\nimport { a } from '@react-spring/three';\r\n\r\nconst calculateTextSize = (\r\n text: string,\r\n fontSize: number,\r\n maxWidth: number,\r\n ellipsis: number,\r\n active: boolean\r\n) => {\r\n const shortText = ellipsis && !active ? ellipsize(text, ellipsis) : text;\r\n const lines = [];\r\n let currentLine = '';\r\n const words = shortText.split(' ');\r\n\r\n words.forEach(word => {\r\n const testLine = currentLine ? `${currentLine} ${word}` : word;\r\n const testWidth = testLine.length * fontSize * 1;\r\n\r\n if (testWidth > maxWidth) {\r\n lines.push(currentLine);\r\n currentLine = word;\r\n } else {\r\n currentLine = testLine;\r\n }\r\n });\r\n\r\n if (currentLine) {\r\n lines.push(currentLine);\r\n }\r\n\r\n const width =\r\n Math.min(\r\n maxWidth,\r\n lines.reduce(\r\n (max, line) => Math.max(max, line.length * fontSize * 0.4),\r\n 0\r\n )\r\n ) + 14;\r\n const height = lines.length * fontSize + 6;\r\n\r\n return { width, height, text: lines.join('\\n'), lineCount: lines.length };\r\n};\r\n\r\nexport interface LabelProps {\r\n /**\r\n * Text to render.\r\n */\r\n text: string;\r\n\r\n /**\r\n * Font URL.\r\n * Reference: https://github.com/reaviz/reagraph/issues/23\r\n */\r\n fontUrl?: string;\r\n\r\n /**\r\n * Size of the font.\r\n */\r\n fontSize?: number;\r\n\r\n /**\r\n * Color of the text.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Stroke of the text.\r\n */\r\n stroke?: ColorRepresentation;\r\n\r\n /**\r\n * Opacity for the label.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The lenth of which to start the ellipsis.\r\n */\r\n ellipsis?: number;\r\n\r\n /**\r\n * Whether the label is active ( dragging, hover, focus ).\r\n */\r\n active?: boolean;\r\n\r\n /**\r\n * Rotation of the label.\r\n */\r\n rotation?: Euler | [number, number, number];\r\n\r\n /**\r\n * Maximum width of the label.\r\n */\r\n maxWidth?: number;\r\n\r\n /**\r\n * Background color of the label.\r\n */\r\n backgroundColor?: ColorRepresentation;\r\n\r\n /**\r\n * Border radius of the label.\r\n */\r\n borderRadius?: number;\r\n\r\n /**\r\n * Type of the label.\r\n */\r\n type?: 'node' | 'edge';\r\n\r\n /**\r\n * label visible or not\r\n */\r\n labelVisible?: boolean;\r\n}\r\n\r\nexport const Label: FC = ({\r\n text,\r\n fontSize,\r\n fontUrl,\r\n color,\r\n opacity,\r\n stroke,\r\n active,\r\n rotation,\r\n maxWidth = 100,\r\n ellipsis = 100,\r\n backgroundColor,\r\n borderRadius,\r\n labelVisible = true\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const normalizedBackgroundColor = useMemo(\r\n () => new Color(backgroundColor),\r\n [backgroundColor]\r\n );\r\n const normalizedStroke = useMemo(\r\n () => (stroke ? new Color(stroke) : undefined),\r\n [stroke]\r\n );\r\n\r\n const {\r\n width,\r\n height,\r\n text: processedText,\r\n lineCount\r\n } = useMemo(\r\n () => calculateTextSize(text, fontSize, maxWidth, ellipsis, active),\r\n [text, fontSize, maxWidth, ellipsis, active]\r\n );\r\n\r\n return (\r\n \r\n {backgroundColor ? (\r\n \r\n \r\n \r\n {processedText}\r\n \r\n \r\n \r\n \r\n ) : (\r\n \r\n {processedText}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nLabel.defaultProps = {\r\n opacity: 1,\r\n fontSize: 4,\r\n color: '#2A6475',\r\n ellipsis: 100\r\n};\r\n","import React, { FC, useMemo } from 'react';\nimport { Color, ColorRepresentation, DoubleSide } from 'three';\nimport { animationConfig } from '../utils/animation';\nimport { useSpring, a } from '@react-spring/three';\nimport { Billboard } from 'glodrei';\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 = ({\n color,\n size,\n opacity,\n animated,\n strokeWidth,\n innerRadius = 2,\n segments = 50\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 \n \n \n \n \n \n );\n};\n\nRing.defaultProps = {\n color: '#D8E6EA',\n size: 1,\n opacity: 0.5,\n strokeWidth: 5\n};\n","import React, { FC, useMemo } from 'react';\nimport { useSpring, a } from '@react-spring/three';\nimport { animationConfig } from '../../utils/animation';\nimport { Color, DoubleSide } from 'three';\nimport { NodeRendererProps } from '../../types';\nimport { Ring } from '../Ring';\nimport { useStore } from '../../store';\n\nexport const Sphere: FC = ({\n color,\n id,\n size,\n active,\n selected,\n opacity,\n animated,\n showRing\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: active\n ? [size * 1.05, size * 1.05, size * 1.05]\n : [size, size, size],\n nodeOpacity: opacity\n },\n config: {\n ...animationConfig,\n duration: animated ? undefined : 0\n }\n });\n\n const normalizedColor = useMemo(() => new Color(color), [color]);\n const theme = useStore(state => state.theme);\n\n return (\n <>\n \n \n \n \n {(showRing || selected || active) && (\n \n \n \n )}\n \n );\n};\n\nSphere.defaultProps = {\n opacity: 1,\n active: false\n};\n","import CameraControls from 'camera-controls';\r\nimport { createContext, useContext } from 'react';\r\n\r\nexport interface CameraControlsContextProps {\r\n /**\r\n * The camera controls object.\r\n */\r\n controls: CameraControls | null;\r\n\r\n /**\r\n * A function that resets the camera controls.\r\n * If the optional `animated` argument is true, the reset is animated.\r\n */\r\n resetControls: (animated?: boolean) => void;\r\n\r\n /**\r\n * A function that zooms in the camera.\r\n */\r\n zoomIn: () => void;\r\n\r\n /**\r\n * A function that zooms out the camera.\r\n */\r\n zoomOut: () => void;\r\n\r\n /**\r\n * A function that dollies in the camera.\r\n */\r\n dollyIn: (distance?: number) => void;\r\n\r\n /**\r\n * A function that dollies out the camera.\r\n */\r\n dollyOut: (distance?: number) => void;\r\n\r\n /**\r\n * A function that pans the camera to the left.\r\n */\r\n panLeft: () => void;\r\n\r\n /**\r\n * A function that pans the camera to the right.\r\n */\r\n panRight: () => void;\r\n\r\n /**\r\n * A function that pans the camera upwards.\r\n */\r\n panUp: () => void;\r\n\r\n /**\r\n * A function that pans the camera downwards.\r\n */\r\n panDown: () => void;\r\n}\r\n\r\nexport const CameraControlsContext = createContext({\r\n controls: null,\r\n resetControls: () => undefined,\r\n zoomIn: () => undefined,\r\n zoomOut: () => undefined,\r\n dollyIn: () => undefined,\r\n dollyOut: () => undefined,\r\n panLeft: () => undefined,\r\n panRight: () => undefined,\r\n panUp: () => undefined,\r\n panDown: () => undefined\r\n});\r\n\r\nexport const useCameraControls = () => {\r\n const context = useContext(CameraControlsContext);\r\n\r\n if (context === undefined) {\r\n throw new Error(\r\n '`useCameraControls` hook must be used within a `ControlsProvider` component'\r\n );\r\n }\r\n\r\n return context;\r\n};\r\n","import React, {\r\n FC,\r\n useRef,\r\n useEffect,\r\n useCallback,\r\n forwardRef,\r\n Ref,\r\n useImperativeHandle,\r\n useMemo,\r\n ReactNode\r\n} from 'react';\r\nimport { useThree, useFrame, extend } from '@react-three/fiber';\r\nimport {\r\n MOUSE,\r\n Vector2,\r\n Vector3,\r\n Vector4,\r\n Quaternion,\r\n Matrix4,\r\n Spherical,\r\n Box3,\r\n Sphere,\r\n Raycaster,\r\n MathUtils\r\n} from 'three';\r\nimport ThreeCameraControls from 'camera-controls';\r\nimport {\r\n CameraControlsContext,\r\n CameraControlsContextProps\r\n} from './useCameraControls';\r\nimport { useHotkeys } from 'reakeys';\r\nimport * as holdEvent from 'hold-event';\r\nimport { useStore } from '../store';\r\n\r\n// Install the camera controls\r\n// Use a subset for better three shaking\r\nThreeCameraControls.install({\r\n THREE: {\r\n MOUSE: MOUSE,\r\n Vector2: Vector2,\r\n Vector3: Vector3,\r\n Vector4: Vector4,\r\n Quaternion: Quaternion,\r\n Matrix4: Matrix4,\r\n Spherical: Spherical,\r\n Box3: Box3,\r\n Sphere: Sphere,\r\n Raycaster: Raycaster,\r\n MathUtils: {\r\n DEG2RAD: MathUtils?.DEG2RAD,\r\n clamp: MathUtils?.clamp\r\n }\r\n }\r\n});\r\n\r\n// Extend r3f with the new controls\r\nextend({ ThreeCameraControls });\r\n\r\nconst KEY_CODES = {\r\n ARROW_LEFT: 37,\r\n ARROW_UP: 38,\r\n ARROW_RIGHT: 39,\r\n ARROW_DOWN: 40\r\n};\r\n\r\nconst leftKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_LEFT, 100);\r\nconst rightKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_RIGHT, 100);\r\nconst upKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_UP, 100);\r\nconst downKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_DOWN, 100);\r\n\r\nexport type CameraMode = 'pan' | 'rotate' | 'orbit';\r\n\r\nexport interface CameraControlsProps {\r\n /**\r\n * Mode of the camera.\r\n */\r\n mode?: CameraMode;\r\n\r\n /**\r\n * Children symbols.\r\n */\r\n children?: ReactNode;\r\n\r\n /**\r\n * Animate transitions to centering.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the controls are enabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The maximum distance for the camera.\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * The minimum distance for the camera.\r\n */\r\n minDistance?: number;\r\n}\r\n\r\nexport type CameraControlsRef = CameraControlsContextProps;\r\n\r\nexport const CameraControls: FC<\r\n CameraControlsProps & { ref?: Ref }\r\n> = forwardRef(\r\n (\r\n { mode, children, animated, disabled, minDistance, maxDistance },\r\n ref: Ref\r\n ) => {\r\n const cameraRef = useRef(null);\r\n const camera = useThree(state => state.camera);\r\n const gl = useThree(state => state.gl);\r\n const isOrbiting = mode === 'orbit';\r\n const setPanning = useStore(state => state.setPanning);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n useFrame((_state, delta) => {\r\n if (cameraRef.current?.enabled) {\r\n cameraRef.current?.update(delta);\r\n }\r\n\r\n if (isOrbiting) {\r\n cameraRef.current.azimuthAngle += 20 * delta * MathUtils.DEG2RAD;\r\n }\r\n }, -1);\r\n\r\n useEffect(() => () => cameraRef.current?.dispose(), []);\r\n\r\n const zoomIn = useCallback(() => {\r\n cameraRef.current?.zoom(camera.zoom / 2, animated);\r\n }, [animated, camera.zoom]);\r\n\r\n const zoomOut = useCallback(() => {\r\n cameraRef.current?.zoom(-camera.zoom / 2, animated);\r\n }, [animated, camera.zoom]);\r\n\r\n const dollyIn = useCallback(\r\n distance => {\r\n cameraRef.current?.dolly(distance, animated);\r\n },\r\n [animated]\r\n );\r\n\r\n const dollyOut = useCallback(\r\n distance => {\r\n cameraRef.current?.dolly(distance, animated);\r\n },\r\n [animated]\r\n );\r\n\r\n const panRight = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(-0.03 * event.deltaTime, 0, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panLeft = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0.03 * event.deltaTime, 0, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panUp = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0, 0.03 * event.deltaTime, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panDown = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0, -0.03 * event.deltaTime, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const onKeyDown = useCallback(\r\n event => {\r\n if (event.code === 'Space') {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n }\r\n }\r\n },\r\n [mode]\r\n );\r\n\r\n const onKeyUp = useCallback(\r\n event => {\r\n if (event.code === 'Space') {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n }\r\n }\r\n },\r\n [mode]\r\n );\r\n\r\n useEffect(() => {\r\n if (!disabled) {\r\n leftKey.addEventListener('holding', panLeft);\r\n rightKey.addEventListener('holding', panRight);\r\n upKey.addEventListener('holding', panUp);\r\n downKey.addEventListener('holding', panDown);\r\n\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', onKeyDown);\r\n window.addEventListener('keyup', onKeyUp);\r\n }\r\n }\r\n\r\n return () => {\r\n leftKey.removeEventListener('holding', panLeft);\r\n rightKey.removeEventListener('holding', panRight);\r\n upKey.removeEventListener('holding', panUp);\r\n downKey.removeEventListener('holding', panDown);\r\n\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', onKeyDown);\r\n window.removeEventListener('keyup', onKeyUp);\r\n }\r\n };\r\n }, [disabled, onKeyDown, onKeyUp, panDown, panLeft, panRight, panUp]);\r\n\r\n useEffect(() => {\r\n if (disabled) {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\r\n cameraRef.current.mouseButtons.middle = ThreeCameraControls.ACTION.NONE;\r\n cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.NONE;\r\n } else {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.TRUCK;\r\n cameraRef.current.mouseButtons.middle =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.DOLLY;\r\n }\r\n }, [disabled]);\r\n\r\n useEffect(() => {\r\n const onControl = () => setPanning(true);\r\n const onControlEnd = () => setPanning(false);\r\n\r\n const ref = cameraRef.current;\r\n if (ref) {\r\n ref.addEventListener('control', onControl);\r\n ref.addEventListener('controlend', onControlEnd);\r\n }\r\n\r\n return () => {\r\n if (ref) {\r\n ref.removeEventListener('control', onControl);\r\n ref.removeEventListener('controlend', onControlEnd);\r\n }\r\n };\r\n }, [cameraRef, setPanning]);\r\n\r\n useEffect(() => {\r\n // If a node is being dragged, disable the camera controls\r\n if (draggingId) {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\r\n } else {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n }\r\n }\r\n }, [draggingId, mode]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Zoom In',\r\n disabled,\r\n category: 'Graph',\r\n keys: 'command+shift+i',\r\n callback: event => {\r\n event.preventDefault();\r\n zoomIn();\r\n }\r\n },\r\n {\r\n name: 'Zoom Out',\r\n category: 'Graph',\r\n disabled,\r\n keys: 'command+shift+o',\r\n callback: event => {\r\n event.preventDefault();\r\n zoomOut();\r\n }\r\n }\r\n ]);\r\n\r\n const values = useMemo(\r\n () => ({\r\n controls: cameraRef.current,\r\n zoomIn: () => zoomIn(),\r\n zoomOut: () => zoomOut(),\r\n dollyIn: (distance = 1000) => dollyIn(distance),\r\n dollyOut: (distance = -1000) => dollyOut(distance),\r\n panLeft: (deltaTime = 100) => panLeft({ deltaTime }),\r\n panRight: (deltaTime = 100) => panRight({ deltaTime }),\r\n panDown: (deltaTime = 100) => panDown({ deltaTime }),\r\n panUp: (deltaTime = 100) => panUp({ deltaTime }),\r\n resetControls: (animated?: boolean) =>\r\n cameraRef.current?.reset(animated)\r\n }),\r\n // eslint-disable-next-line\r\n [zoomIn, zoomOut, panLeft, panRight, panDown, panUp, cameraRef.current]\r\n );\r\n\r\n useImperativeHandle(ref, () => values);\r\n\r\n return (\r\n \r\n \r\n {children}\r\n \r\n );\r\n }\r\n);\r\n\r\nCameraControls.defaultProps = {\r\n mode: 'rotate',\r\n minDistance: 1000,\r\n maxDistance: 50000\r\n};\r\n","import { PerspectiveCamera } from 'three';\r\nimport { InternalGraphPosition } from '../types';\r\n\r\n/**\r\n * Get the visible height at the z depth.\r\n * Ref: https://discourse.threejs.org/t/functions-to-calculate-the-visible-width-height-at-a-given-z-depth-from-a-perspective-camera/269\r\n */\r\nfunction visibleHeightAtZDepth(depth: number, camera: PerspectiveCamera) {\r\n // compensate for cameras not positioned at z=0\r\n const cameraOffset = camera.position.z;\r\n if (depth < cameraOffset) depth -= cameraOffset;\r\n else depth += cameraOffset;\r\n\r\n // vertical fov in radians\r\n const vFOV = ((camera.fov / camera.zoom) * Math.PI) / 180;\r\n\r\n // Math.abs to ensure the result is always positive\r\n return 2 * Math.tan(vFOV / 2) * Math.abs(depth);\r\n}\r\n\r\n/**\r\n * Get the visible width at the z depth.\r\n */\r\nfunction visibleWidthAtZDepth(depth: number, camera: PerspectiveCamera) {\r\n const height = visibleHeightAtZDepth(depth, camera);\r\n return height * camera.aspect;\r\n}\r\n\r\n/**\r\n * Returns whether the node is in view of the camera.\r\n */\r\nexport function isNodeInView(\r\n camera: PerspectiveCamera,\r\n nodePosition: InternalGraphPosition\r\n): boolean {\r\n const visibleWidth = visibleWidthAtZDepth(1, camera);\r\n const visibleHeight = visibleHeightAtZDepth(1, camera);\r\n\r\n // The boundary coordinates of the area visible to the camera relative to the scene\r\n const visibleArea = {\r\n x0: camera?.position?.x - visibleWidth / 2,\r\n x1: camera?.position?.x + visibleWidth / 2,\r\n y0: camera?.position?.y - visibleHeight / 2,\r\n y1: camera?.position?.y + visibleHeight / 2\r\n };\r\n\r\n return (\r\n nodePosition?.x > visibleArea.x0 &&\r\n nodePosition?.x < visibleArea.x1 &&\r\n nodePosition?.y > visibleArea.y0 &&\r\n nodePosition?.y < visibleArea.y1\r\n );\r\n}\r\n\r\n/**\r\n * Get the closest axis to a given angle.\r\n */\r\nexport function getClosestAxis(angle: number, axes: number[]) {\r\n return axes.reduce((prev, curr) =>\r\n Math.abs(curr - (angle % Math.PI)) < Math.abs(prev - (angle % Math.PI))\r\n ? curr\r\n : prev\r\n );\r\n}\r\n\r\n/**\r\n * Get how far an angle is from the closest 2D axis in radians.\r\n */\r\nexport function getDegreesToClosest2dAxis(\r\n horizontalAngle: number,\r\n verticalAngle: number\r\n) {\r\n const closestHorizontalAxis = getClosestAxis(horizontalAngle, [0, Math.PI]);\r\n const closestVerticalAxis = getClosestAxis(verticalAngle, [\r\n Math.PI / 2,\r\n (3 * Math.PI) / 2\r\n ]);\r\n\r\n return {\r\n horizontalRotation: closestHorizontalAxis - (horizontalAngle % Math.PI),\r\n verticalRotation: closestVerticalAxis - (verticalAngle % Math.PI)\r\n };\r\n}\r\n","import { useThree } from '@react-three/fiber';\r\nimport { useCameraControls } from './useCameraControls';\r\nimport { useCallback, useLayoutEffect, useRef, useState } from 'react';\r\nimport { Vector3, Box3, PerspectiveCamera } from 'three';\r\nimport { useHotkeys } from 'reakeys';\r\nimport { getLayoutCenter } from '../utils/layout';\r\nimport { InternalGraphNode } from '../types';\r\nimport { useStore } from '../store';\r\nimport { isNodeInView, getDegreesToClosest2dAxis } from './utils';\r\nimport { LayoutTypes } from 'layout/types';\r\n\r\nconst PADDING = 50;\r\n\r\nexport interface CenterNodesParams {\r\n animated?: boolean;\r\n centerOnlyIfNodesNotInView?: boolean;\r\n}\r\n\r\nexport interface FitNodesParams {\r\n animated?: boolean;\r\n fitOnlyIfNodesNotInView?: boolean;\r\n}\r\n\r\nexport interface CenterGraphInput {\r\n /**\r\n * Whether the animate the transition or not.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the center graph function is disabled or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The layout type of the graph used to determine rotation logic.\r\n */\r\n layoutType: LayoutTypes;\r\n}\r\n\r\nexport interface CenterGraphOutput {\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodes - An array of `InternalGraphNode` objects to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param animated - A boolean flag that determines whether the centering action should be animated.\r\n *\r\n * @param centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `nodes` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `nodes` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerNodes: (nodes: InternalGraphNode[], opts: CenterNodesParams) => void;\r\n\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `ids` are not currently in view. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerNodesById: (nodeIds: string[], opts?: CenterNodesParams) => void;\r\n\r\n /**\r\n * Fit all the given nodes into view of the camera.\r\n *\r\n * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\r\n * the view will fit to all nodes.\r\n *\r\n * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\r\n * only be fit if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the view will only be fit if one or more of the nodes\r\n * specified by `ids` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the view will be fit regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n fitNodesInViewById: (nodeIds: string[], opts?: FitNodesParams) => void;\r\n\r\n /**\r\n * Whether the graph is centered or not.\r\n */\r\n isCentered?: boolean;\r\n}\r\n\r\nexport const useCenterGraph = ({\r\n animated,\r\n disabled,\r\n layoutType\r\n}: CenterGraphInput): CenterGraphOutput => {\r\n const nodes = useStore(state => state.nodes);\r\n const [isCentered, setIsCentered] = useState(false);\r\n const invalidate = useThree(state => state.invalidate);\r\n const { controls } = useCameraControls();\r\n const camera = useThree(state => state.camera) as PerspectiveCamera;\r\n const mounted = useRef(false);\r\n\r\n const centerNodes = useCallback(\r\n async (nodes, opts?: CenterNodesParams) => {\r\n const animated = opts?.animated !== undefined ? opts?.animated : true;\r\n const centerOnlyIfNodesNotInView =\r\n opts?.centerOnlyIfNodesNotInView !== undefined\r\n ? opts?.centerOnlyIfNodesNotInView\r\n : false;\r\n\r\n if (\r\n !mounted.current ||\r\n !centerOnlyIfNodesNotInView ||\r\n (centerOnlyIfNodesNotInView &&\r\n nodes?.some(node => !isNodeInView(camera, node.position)))\r\n ) {\r\n // Centers the graph based on the central most node\r\n const { x, y, z } = getLayoutCenter(nodes);\r\n\r\n await controls.setTarget(x, y, z, animated);\r\n\r\n if (!isCentered) {\r\n setIsCentered(true);\r\n }\r\n\r\n invalidate();\r\n }\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [invalidate, controls, nodes]\r\n );\r\n\r\n const fitNodesInView = useCallback(\r\n async (\r\n nodes,\r\n opts: FitNodesParams = { animated: true, fitOnlyIfNodesNotInView: false }\r\n ) => {\r\n const { fitOnlyIfNodesNotInView } = opts;\r\n\r\n if (\r\n !fitOnlyIfNodesNotInView ||\r\n (fitOnlyIfNodesNotInView &&\r\n nodes?.some(node => !isNodeInView(camera, node.position)))\r\n ) {\r\n const { minX, maxX, minY, maxY, minZ, maxZ } = getLayoutCenter(nodes);\r\n\r\n if (!layoutType.includes('3d')) {\r\n // fitToBox will auto rotate to the closest axis including the z axis,\r\n // which is not desired for 2D graphs\r\n // So get the rotation to the closest flat axis for 2D graphs\r\n const { horizontalRotation, verticalRotation } =\r\n getDegreesToClosest2dAxis(\r\n controls?.azimuthAngle,\r\n controls?.polarAngle\r\n );\r\n\r\n void controls?.rotate(horizontalRotation, verticalRotation, true);\r\n }\r\n\r\n await controls?.zoomTo(1, opts?.animated);\r\n\r\n await controls?.fitToBox(\r\n new Box3(\r\n new Vector3(minX, minY, minZ),\r\n new Vector3(maxX, maxY, maxZ)\r\n ),\r\n opts?.animated,\r\n {\r\n cover: false,\r\n paddingLeft: PADDING,\r\n paddingRight: PADDING,\r\n paddingBottom: PADDING,\r\n paddingTop: PADDING\r\n }\r\n );\r\n }\r\n },\r\n [camera, controls, layoutType]\r\n );\r\n\r\n const getNodesById = useCallback(\r\n (nodeIds: string[]) => {\r\n let mappedNodes: InternalGraphNode[] | null = null;\r\n\r\n if (nodeIds?.length) {\r\n // Map the node ids to the actual nodes\r\n mappedNodes = nodeIds.reduce((acc, id) => {\r\n const node = nodes.find(n => n.id === id);\r\n if (node) {\r\n acc.push(node);\r\n } else {\r\n throw new Error(\r\n `Attempted to center ${id} but it was not found in the nodes`\r\n );\r\n }\r\n\r\n return acc;\r\n }, []);\r\n }\r\n\r\n return mappedNodes;\r\n },\r\n [nodes]\r\n );\r\n\r\n const centerNodesById = useCallback(\r\n (nodeIds: string[], opts: CenterNodesParams) => {\r\n const mappedNodes = getNodesById(nodeIds);\r\n\r\n centerNodes(mappedNodes || nodes, {\r\n animated,\r\n centerOnlyIfNodesNotInView: opts?.centerOnlyIfNodesNotInView\r\n });\r\n },\r\n [animated, centerNodes, getNodesById, nodes]\r\n );\r\n\r\n const fitNodesInViewById = useCallback(\r\n async (nodeIds: string[], opts: FitNodesParams) => {\r\n const mappedNodes = getNodesById(nodeIds);\r\n\r\n await fitNodesInView(mappedNodes || nodes, { animated, ...opts });\r\n },\r\n [animated, fitNodesInView, getNodesById, nodes]\r\n );\r\n\r\n useLayoutEffect(() => {\r\n async function load() {\r\n // Once we've loaded controls and we have nodes, let's recenter\r\n if (controls && nodes?.length) {\r\n if (!mounted.current) {\r\n // Center the graph once nodes are loaded on mount\r\n await centerNodes(nodes, { animated: false });\r\n await fitNodesInView(nodes, { animated: false });\r\n mounted.current = true;\r\n }\r\n }\r\n }\r\n\r\n load();\r\n }, [controls, centerNodes, nodes, animated, camera, fitNodesInView]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Center',\r\n disabled,\r\n category: 'Graph',\r\n keys: ['command+shift+c'],\r\n callback: () => centerNodes(nodes)\r\n }\r\n ]);\r\n\r\n return { centerNodes, centerNodesById, fitNodesInViewById, isCentered };\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { a, useSpring } from '@react-spring/three';\r\nimport { TextureLoader, LinearFilter, DoubleSide } from 'three';\r\nimport { animationConfig } from '../../utils';\r\nimport { NodeRendererProps } from '../../types';\r\n\r\nexport interface IconProps extends NodeRendererProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n}\r\n\r\nexport const Icon: FC = ({ image, id, size, opacity, animated }) => {\r\n const texture = useMemo(() => new TextureLoader().load(image), [image]);\r\n\r\n const { scale, spriteOpacity } = useSpring({\r\n from: {\r\n scale: [0.00001, 0.00001, 0.00001],\r\n spriteOpacity: 0\r\n },\r\n to: {\r\n scale: [size, size, size],\r\n spriteOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nIcon.defaultProps = {\r\n opacity: 1\r\n};\r\n","import React, { FC } from 'react';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Sphere } from './Sphere';\r\nimport { Icon } from './Icon';\r\n\r\nexport interface SphereWithIconProps extends NodeRendererProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n}\r\n\r\nexport const SphereWithIcon: FC = ({\r\n color,\r\n id,\r\n size,\r\n opacity,\r\n node,\r\n active,\r\n animated,\r\n image,\r\n selected\r\n}) => (\r\n <>\r\n \r\n \r\n \r\n);\r\n\r\nSphereWithIcon.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { a, useSpring } from '@react-spring/three';\r\nimport { animationConfig } from '../../utils';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Billboard, Svg as DreiSvg, SvgProps as DreiSvgProps } from 'glodrei';\r\nimport { Color, DoubleSide } from 'three';\r\n\r\nexport type SvgProps = NodeRendererProps &\r\n Omit & {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n };\r\n\r\nexport const Svg: FC = ({\r\n id,\r\n image,\r\n color,\r\n size,\r\n opacity,\r\n animated,\r\n ...rest\r\n}) => {\r\n const normalizedSize = size / 25;\r\n\r\n const { scale } = useSpring({\r\n from: {\r\n scale: [0.00001, 0.00001, 0.00001]\r\n },\r\n to: {\r\n scale: [normalizedSize, normalizedSize, normalizedSize]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nSvg.defaultProps = {\r\n opacity: 1\r\n};\r\n","import React, { FC } from 'react';\r\nimport { Sphere } from './Sphere';\r\nimport { Svg, SvgProps } from './Svg';\r\nimport { ColorRepresentation } from 'three';\r\n\r\nexport interface SphereWithSvgProps extends SvgProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n\r\n /**\r\n * The color of the svg fill.\r\n */\r\n svgFill?: ColorRepresentation;\r\n}\r\n\r\nexport const SphereWithSvg: FC = ({\r\n color,\r\n id,\r\n size,\r\n opacity,\r\n node,\r\n svgFill,\r\n active,\r\n animated,\r\n image,\r\n selected,\r\n ...rest\r\n}) => (\r\n <>\r\n \r\n \r\n \r\n);\r\n\r\nSphereWithSvg.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import React, {\r\n FC,\r\n ReactNode,\r\n useCallback,\r\n useMemo,\r\n useRef,\r\n useState\r\n} from 'react';\r\nimport { Group } from 'three';\r\nimport { animationConfig } from '../utils';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Sphere } from './nodes/Sphere';\r\nimport { Label } from './Label';\r\nimport {\r\n NodeContextMenuProps,\r\n ContextMenuEvent,\r\n InternalGraphNode,\r\n NodeRenderer,\r\n CollapseProps\r\n} from '../types';\r\nimport { Html, useCursor } from 'glodrei';\r\nimport { useCameraControls } from '../CameraControls';\r\nimport { useStore } from '../store';\r\nimport { useDrag } from '../utils/useDrag';\r\nimport { Icon } from './nodes';\r\nimport { useHoverIntent } from '../utils/useHoverIntent';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface NodeProps {\r\n /**\r\n * The unique identifier for the node.\r\n */\r\n id: string;\r\n\r\n /**\r\n * The parent nodes of the node.\r\n */\r\n parents?: string[];\r\n\r\n /**\r\n * Whether the node is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Whether the node is animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the node is draggable.\r\n */\r\n draggable?: boolean;\r\n\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The function to use to render the node.\r\n */\r\n renderNode?: NodeRenderer;\r\n\r\n /**\r\n * The context menu for the node.\r\n */\r\n contextMenu?: (event: ContextMenuEvent) => ReactNode;\r\n\r\n /**\r\n * The function to call when the pointer is over the node.\r\n */\r\n onPointerOver?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the pointer is out of the node.\r\n */\r\n onPointerOut?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is clicked.\r\n */\r\n onClick?: (\r\n node: InternalGraphNode,\r\n props?: CollapseProps,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is double clicked.\r\n */\r\n onDoubleClick?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is right clicked.\r\n */\r\n onContextMenu?: (\r\n node?: InternalGraphNode,\r\n props?: NodeContextMenuProps\r\n ) => void;\r\n\r\n /**\r\n * Triggered after a node was dragged.\r\n */\r\n onDragged?: (node: InternalGraphNode) => void;\r\n}\r\n\r\nexport const Node: FC = ({\r\n animated,\r\n disabled,\r\n id,\r\n draggable,\r\n labelFontUrl,\r\n contextMenu,\r\n onClick,\r\n onDoubleClick,\r\n onPointerOver,\r\n onDragged,\r\n onPointerOut,\r\n onContextMenu,\r\n renderNode\r\n}) => {\r\n const cameraControls = useCameraControls();\r\n const theme = useStore(state => state.theme);\r\n const node = useStore(state => state.nodes.find(n => n.id === id));\r\n const edges = useStore(state => state.edges);\r\n const draggingId = useStore(state => state.draggingId);\r\n const collapsedNodeIds = useStore(state => state.collapsedNodeIds);\r\n const setDraggingId = useStore(state => state.setDraggingId);\r\n const setNodePosition = useStore(state => state.setNodePosition);\r\n const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\r\n const isCollapsed = useStore(state => state.collapsedNodeIds.includes(id));\r\n const isActive = useStore(state => state.actives?.includes(id));\r\n const isSelected = useStore(state => state.selections?.includes(id));\r\n const hasSelections = useStore(state => state.selections?.length > 0);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const isDragging = draggingId === id;\r\n const {\r\n position,\r\n label,\r\n subLabel,\r\n size: nodeSize = 7,\r\n labelVisible = true\r\n } = node;\r\n\r\n const group = useRef(null);\r\n const [active, setActive] = useState(false);\r\n const [menuVisible, setMenuVisible] = useState(false);\r\n\r\n const shouldHighlight = active || isSelected || isActive;\r\n\r\n const selectionOpacity = hasSelections\r\n ? shouldHighlight\r\n ? theme.node.selectedOpacity\r\n : theme.node.inactiveOpacity\r\n : theme.node.opacity;\r\n\r\n const canCollapse = useMemo(() => {\r\n // If the node has outgoing edges, it can collapse via context menu\r\n const outboundLinks = edges.filter(l => l.source === id);\r\n\r\n return outboundLinks.length > 0 || isCollapsed;\r\n }, [edges, id, isCollapsed]);\r\n\r\n const onCollapse = useCallback(() => {\r\n if (canCollapse) {\r\n if (isCollapsed) {\r\n setCollapsedNodeIds(collapsedNodeIds.filter(p => p !== id));\r\n } else {\r\n setCollapsedNodeIds([...collapsedNodeIds, id]);\r\n }\r\n }\r\n }, [canCollapse, collapsedNodeIds, id, isCollapsed, setCollapsedNodeIds]);\r\n\r\n const [{ nodePosition, labelPosition, subLabelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n nodePosition: center ? [center.x, center.y, 0] : [0, 0, 0],\r\n labelPosition: [0, -(nodeSize + 4), 2],\r\n subLabelPosition: [0, -(nodeSize + 14), 2]\r\n },\r\n to: {\r\n nodePosition: position\r\n ? [\r\n position.x,\r\n position.y,\r\n shouldHighlight ? position.z + 50 : position.z\r\n ]\r\n : [0, 0, 0],\r\n labelPosition: [0, -(nodeSize + 4), 2],\r\n subLabelPosition: [0, -(nodeSize + 14), 2]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [isDragging, position, animated, nodeSize, shouldHighlight]\r\n );\r\n\r\n const bind = useDrag({\r\n draggable,\r\n position,\r\n // @ts-ignore\r\n set: pos => setNodePosition(id, pos),\r\n onDragStart: () => {\r\n setDraggingId(id);\r\n setActive(true);\r\n },\r\n onDragEnd: () => {\r\n setDraggingId(null);\r\n setActive(false);\r\n onDragged?.(node);\r\n }\r\n });\r\n\r\n useCursor(active && !draggingId && onClick !== undefined, 'pointer');\r\n useCursor(\r\n active && draggable && !isDragging && onClick === undefined,\r\n 'grab'\r\n );\r\n useCursor(isDragging, 'grabbing');\r\n\r\n const combinedActiveState = shouldHighlight || isDragging;\r\n const color = combinedActiveState\r\n ? node.activeFill || theme.node.activeFill\r\n : node.fill || theme.node.fill;\r\n\r\n const actualShowRing = node.showRing;\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled: disabled || isDragging,\r\n onPointerOver: (event: ThreeEvent) => {\r\n cameraControls.controls.truckSpeed = 0;\r\n setActive(true);\r\n onPointerOver?.(node, event);\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n cameraControls.controls.truckSpeed = 2.0;\r\n setActive(false);\r\n onPointerOut?.(node, event);\r\n }\r\n });\r\n\r\n const nodeComponent = useMemo(\r\n () =>\r\n renderNode ? (\r\n renderNode({\r\n id,\r\n color,\r\n size: nodeSize,\r\n active: combinedActiveState,\r\n opacity: selectionOpacity,\r\n animated,\r\n selected: isSelected,\r\n node\r\n })\r\n ) : (\r\n <>\r\n {node.icon ? (\r\n \r\n ) : (\r\n \r\n )}\r\n \r\n ),\r\n [\r\n renderNode,\r\n id,\r\n color,\r\n nodeSize,\r\n combinedActiveState,\r\n selectionOpacity,\r\n animated,\r\n isSelected,\r\n node,\r\n actualShowRing\r\n ]\r\n );\r\n\r\n const labelComponent = useMemo(\r\n () =>\r\n label && (\r\n <>\r\n \r\n \r\n \r\n {subLabel && (\r\n \r\n \r\n \r\n )}\r\n \r\n ),\r\n [\r\n active,\r\n isActive,\r\n isDragging,\r\n isSelected,\r\n label,\r\n labelFontUrl,\r\n labelPosition,\r\n labelVisible,\r\n selectionOpacity,\r\n subLabel,\r\n subLabelPosition,\r\n theme.node.label.activeColor,\r\n theme.node.label.color,\r\n theme.node.label.stroke,\r\n theme.node.subLabel?.activeColor,\r\n theme.node.subLabel?.color,\r\n theme.node.subLabel?.stroke,\r\n theme.node.label.fontSize,\r\n theme.node.label.maxWidth,\r\n theme.node.label.ellipsis,\r\n theme.node.label.backgroundColor,\r\n theme.node.label.borderRadius\r\n ]\r\n );\r\n\r\n const menuComponent = useMemo(\r\n () =>\r\n menuVisible &&\r\n contextMenu && (\r\n \r\n {contextMenu({\r\n data: node,\r\n canCollapse,\r\n isCollapsed,\r\n onCollapse,\r\n onClose: () => setMenuVisible(false)\r\n })}\r\n \r\n ),\r\n [menuVisible, contextMenu, node, canCollapse, isCollapsed, onCollapse]\r\n );\r\n\r\n return (\r\n ) => {\r\n if (!disabled && !isDragging) {\r\n onClick?.(\r\n node,\r\n {\r\n canCollapse,\r\n isCollapsed\r\n },\r\n event\r\n );\r\n }\r\n }}\r\n onDoubleClick={(event: ThreeEvent) => {\r\n event.stopPropagation();\r\n if (!disabled && !isDragging) {\r\n onDoubleClick?.(node, event);\r\n }\r\n }}\r\n onContextMenu={() => {\r\n if (!disabled) {\r\n setMenuVisible(true);\r\n onContextMenu?.(node, {\r\n canCollapse,\r\n isCollapsed,\r\n onCollapse\r\n });\r\n }\r\n }}\r\n {...(bind() as any)}\r\n >\r\n {nodeComponent}\r\n {menuComponent}\r\n {labelComponent}\r\n \r\n );\r\n};\r\n\r\nNode.defaultProps = {\r\n draggable: false\r\n};\r\n","import React, { FC, useMemo, useRef, useEffect, useCallback } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Color, ColorRepresentation, Mesh, DoubleSide, Vector3 } from 'three';\r\nimport { animationConfig } from '../utils';\r\nimport { useStore } from '../store';\r\n\r\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\r\n\r\nexport interface ArrowProps {\r\n /**\r\n * Whether the arrow should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The color of the arrow.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * The length of the arrow.\r\n */\r\n length: number;\r\n\r\n /**\r\n * The opacity of the arrow.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The position of the arrow in 3D space.\r\n */\r\n position: Vector3;\r\n\r\n /**\r\n * The rotation of the arrow in 3D space.\r\n */\r\n rotation: Vector3;\r\n\r\n /**\r\n * The size of the arrow.\r\n */\r\n size: number;\r\n\r\n /**\r\n * A function that is called when the arrow is right-clicked.\r\n */\r\n onContextMenu?: () => void;\r\n\r\n /**\r\n * A function that is called when the arrow is selected or deselected.\r\n */\r\n onActive?: (state: boolean) => void;\r\n}\r\n\r\nexport const Arrow: FC = ({\r\n animated,\r\n color,\r\n length,\r\n opacity,\r\n position,\r\n rotation,\r\n size,\r\n onActive,\r\n onContextMenu\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const meshRef = useRef(null);\r\n const draggingId = useStore(state => state.draggingId);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const [{ pos, arrowOpacity }] = useSpring(\r\n () => ({\r\n from: {\r\n pos: center ? [center.x, center.y, center.z] : [0, 0, 0],\r\n arrowOpacity: 0\r\n },\r\n to: {\r\n pos: [position.x, position.y, position.z],\r\n arrowOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [animated, draggingId, opacity, position]\r\n );\r\n\r\n const setQuaternion = useCallback(() => {\r\n const axis = new Vector3(0, 1, 0);\r\n meshRef.current?.quaternion.setFromUnitVectors(axis, rotation);\r\n }, [rotation, meshRef]);\r\n\r\n useEffect(() => setQuaternion(), [setQuaternion]);\r\n\r\n return (\r\n onActive(true)}\r\n onPointerOut={() => onActive(false)}\r\n onPointerDown={event => {\r\n // context menu controls\r\n if (event.nativeEvent.buttons === 2) {\r\n event.stopPropagation();\r\n onContextMenu();\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nArrow.defaultProps = {\r\n size: 1,\r\n opacity: 0.5,\r\n color: '#D8E6EA'\r\n};\r\n","import React, { FC, useEffect, useMemo, useRef } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { animationConfig, getCurve } from '../utils';\r\nimport {\r\n Vector3,\r\n TubeGeometry,\r\n ColorRepresentation,\r\n Color,\r\n Curve\r\n} from 'three';\r\nimport { useStore } from '../store';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface LineProps {\r\n /**\r\n * Whether the line should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The color of the line.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Whether the line should be curved.\r\n */\r\n curved: boolean;\r\n\r\n /**\r\n * The curve of the line in 3D space.\r\n */\r\n curve: Curve;\r\n\r\n /**\r\n * The unique identifier of the line.\r\n */\r\n id: string;\r\n\r\n /**\r\n * The opacity of the line.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The size of the line.\r\n */\r\n size?: number;\r\n\r\n /**\r\n * A function that is called when the line is clicked.\r\n */\r\n onClick?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the line is right-clicked.\r\n */\r\n onContextMenu?: () => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved over the line.\r\n */\r\n onPointerOver?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved out of the line.\r\n */\r\n onPointerOut?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * The offset of the curve.\r\n */\r\n curveOffset?: number;\r\n}\r\n\r\nexport const Line: FC = ({\r\n curveOffset,\r\n animated,\r\n color,\r\n curve,\r\n curved = false,\r\n id,\r\n opacity,\r\n size,\r\n onContextMenu,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const tubeRef = useRef(null);\r\n const draggingId = useStore(state => state.draggingId);\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const center = useStore(state => state.centerPosition);\r\n const mounted = useRef(false);\r\n\r\n // Do opacity seperate from vertices for perf\r\n const { lineOpacity } = useSpring({\r\n from: {\r\n lineOpacity: 0\r\n },\r\n to: {\r\n lineOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n useSpring(() => {\r\n const from = curve.getPoint(0);\r\n const to = curve.getPoint(1);\r\n return {\r\n from: {\r\n // Animate from center first time, then from the actual from point\r\n fromVertices: !mounted.current\r\n ? [center?.x, center?.y, center?.z || 0]\r\n : [to?.x, to?.y, to?.z || 0],\r\n toVertices: [from?.x, from?.y, from?.z || 0]\r\n },\r\n to: {\r\n fromVertices: [from?.x, from?.y, from?.z || 0],\r\n toVertices: [to?.x, to?.y, to?.z || 0]\r\n },\r\n onChange: event => {\r\n const { fromVertices, toVertices } = event.value;\r\n const fromVector = new Vector3(...fromVertices);\r\n const toVector = new Vector3(...toVertices);\r\n\r\n const curve = getCurve(fromVector, 0, toVector, 0, curved, curveOffset);\r\n tubeRef.current.copy(new TubeGeometry(curve, 20, size / 2, 5, false));\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n };\r\n }, [animated, draggingId, curve, size]);\r\n\r\n useEffect(() => {\r\n // Handle mount operation for initial render\r\n mounted.current = true;\r\n }, []);\r\n\r\n return (\r\n {\r\n // context menu controls\r\n if (event.nativeEvent.buttons === 2) {\r\n event.stopPropagation();\r\n onContextMenu();\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nLine.defaultProps = {\r\n color: '#000',\r\n size: 1,\r\n opacity: 1\r\n};\r\n","import React, { FC, useMemo, useState } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Arrow, EdgeArrowPosition } from './Arrow';\r\nimport { Label } from './Label';\r\nimport {\r\n animationConfig,\r\n calculateEdgeCurveOffset,\r\n getArrowSize,\r\n getArrowVectors,\r\n getCurve,\r\n getLabelOffsetByType,\r\n getMidPoint,\r\n getVector\r\n} from '../utils';\r\nimport { Line } from './Line';\r\nimport { useStore } from '../store';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../types';\r\nimport { Html, useCursor } from 'glodrei';\r\nimport { useHoverIntent } from '../utils/useHoverIntent';\r\nimport { Euler, Vector3 } from 'three';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\n/**\r\n * Label positions relatively edge.\r\n *\r\n * - below: show label under the edge line\r\n * - above: show label above the edge line\r\n * - inline: show label along the edge line\r\n * - natural: normal text positions\r\n */\r\nexport type EdgeLabelPosition = 'below' | 'above' | 'inline' | 'natural';\r\n\r\n/**\r\n * Type of edge interpolation.\r\n *\r\n * - Linear is straight\r\n * - Curved is curved\r\n */\r\nexport type EdgeInterpolation = 'linear' | 'curved';\r\n\r\nexport interface EdgeProps {\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The unique identifier of the edge.\r\n */\r\n id: string;\r\n\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The placement of the edge arrow.\r\n */\r\n arrowPlacement?: EdgeArrowPosition;\r\n\r\n /**\r\n * The type of interpolation used to draw the edge.\r\n */\r\n interpolation: EdgeInterpolation;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * A function that is called when the edge is clicked.\r\n */\r\n onClick?: (edge: InternalGraphEdge, event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the edge is right-clicked.\r\n */\r\n onContextMenu?: (edge?: InternalGraphEdge) => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved over the edge.\r\n */\r\n onPointerOver?: (\r\n edge: InternalGraphEdge,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved out of the edge.\r\n */\r\n onPointerOut?: (\r\n edge: InternalGraphEdge,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nconst LABEL_PLACEMENT_OFFSET = 3;\r\n\r\nexport const Edge: FC = ({\r\n animated,\r\n arrowPlacement,\r\n contextMenu,\r\n disabled,\r\n labelPlacement,\r\n id,\r\n interpolation,\r\n labelFontUrl,\r\n onContextMenu,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n // UI states\r\n const [active, setActive] = useState(false);\r\n const [menuVisible, setMenuVisible] = useState(false);\r\n\r\n // Edge data\r\n const edges = useStore(state => state.edges);\r\n const edge = edges.find(e => e.id === id);\r\n const {\r\n target,\r\n source,\r\n label,\r\n labelVisible = false,\r\n size = 1,\r\n backgroundColor\r\n } = edge;\r\n const from = useStore(store => store.nodes.find(node => node.id === source));\r\n const to = useStore(store => store.nodes.find(node => node.id === target));\r\n\r\n // Edge properties\r\n const labelOffset = (size + theme.edge.label.fontSize) / 2;\r\n const [arrowLength, arrowSize] = useMemo(() => getArrowSize(size), [size]);\r\n const { curveOffset, curved } = useMemo(\r\n () =>\r\n calculateEdgeCurveOffset({\r\n edge,\r\n edges,\r\n curved: interpolation === 'curved'\r\n }),\r\n [edge, edges, interpolation]\r\n );\r\n\r\n const [curve, arrowPosition, arrowRotation] = useMemo(() => {\r\n const fromVector = getVector(from);\r\n const fromOffset = from.size;\r\n const toVector = getVector(to);\r\n const toOffset = to.size;\r\n\r\n let curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n toVector,\r\n toOffset,\r\n curved,\r\n curveOffset\r\n );\r\n\r\n const [arrowPosition, arrowRotation] = getArrowVectors(\r\n arrowPlacement,\r\n curve,\r\n arrowLength\r\n );\r\n\r\n if (arrowPlacement === 'end') {\r\n curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n arrowPosition,\r\n 0,\r\n curved,\r\n curveOffset\r\n );\r\n }\r\n\r\n return [curve, arrowPosition, arrowRotation];\r\n }, [from, to, curved, curveOffset, arrowPlacement, arrowLength]);\r\n\r\n const midPoint = useMemo(() => {\r\n let newMidPoint = getMidPoint(\r\n from.position,\r\n to.position,\r\n getLabelOffsetByType(labelOffset, labelPlacement)\r\n );\r\n\r\n if (curved) {\r\n // Offset the label to the mid point of the curve\r\n const offset = new Vector3().subVectors(newMidPoint, curve.getPoint(0.5));\r\n switch (labelPlacement) {\r\n case 'above':\r\n offset.y = offset.y - LABEL_PLACEMENT_OFFSET;\r\n break;\r\n case 'below':\r\n offset.y = offset.y + LABEL_PLACEMENT_OFFSET;\r\n break;\r\n }\r\n newMidPoint = newMidPoint.sub(offset);\r\n }\r\n\r\n return newMidPoint;\r\n }, [from.position, to.position, labelOffset, labelPlacement, curved, curve]);\r\n\r\n const isSelected = useStore(state => state.selections?.includes(id));\r\n const hasSelections = useStore(state => state.selections?.length);\r\n const isActive = useStore(state => state.actives?.includes(id));\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const selectionOpacity = hasSelections\r\n ? isSelected || isActive\r\n ? theme.edge.selectedOpacity\r\n : theme.edge.inactiveOpacity\r\n : theme.edge.opacity;\r\n\r\n const [{ labelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n labelPosition: center ? [center.x, center.y, center.z] : [0, 0, 0]\r\n },\r\n to: {\r\n labelPosition: [midPoint.x, midPoint.y, midPoint.z]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [midPoint, animated, draggingId]\r\n );\r\n\r\n const labelRotation = useMemo(\r\n () =>\r\n new Euler(\r\n 0,\r\n 0,\r\n labelPlacement === 'natural'\r\n ? 0\r\n : Math.atan(\r\n (to.position.y - from.position.y) /\r\n (to.position.x - from.position.x)\r\n )\r\n ),\r\n [\r\n to.position.x,\r\n to.position.y,\r\n from.position.x,\r\n from.position.y,\r\n labelPlacement\r\n ]\r\n );\r\n\r\n useCursor(active && !draggingId && onClick !== undefined, 'pointer');\r\n\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled,\r\n onPointerOver: (event: ThreeEvent) => {\r\n setActive(true);\r\n onPointerOver?.(edge, event);\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n setActive(false);\r\n onPointerOut?.(edge, event);\r\n }\r\n });\r\n\r\n const arrowComponent = useMemo(\r\n () =>\r\n arrowPlacement !== 'none' && (\r\n {\r\n if (!disabled) {\r\n setMenuVisible(true);\r\n onContextMenu?.(edge);\r\n }\r\n }}\r\n />\r\n ),\r\n [\r\n active,\r\n animated,\r\n arrowLength,\r\n arrowPlacement,\r\n arrowPosition,\r\n arrowRotation,\r\n arrowSize,\r\n disabled,\r\n edge,\r\n isActive,\r\n isSelected,\r\n onContextMenu,\r\n selectionOpacity,\r\n theme.arrow.activeFill,\r\n theme.arrow.fill\r\n ]\r\n );\r\n\r\n const labelComponent = useMemo(\r\n () =>\r\n labelVisible &&\r\n label && (\r\n \r\n \r\n \r\n ),\r\n [\r\n active,\r\n isActive,\r\n isSelected,\r\n label,\r\n labelFontUrl,\r\n labelPosition,\r\n labelRotation,\r\n labelVisible,\r\n selectionOpacity,\r\n theme.edge.label.activeColor,\r\n theme.edge.label.color,\r\n theme.edge.label.fontSize,\r\n theme.edge.label.maxWidth,\r\n theme.edge.label.ellipsis,\r\n theme.edge.label.stroke,\r\n theme.edge.label.backgroundColor,\r\n theme.edge.label.borderRadius\r\n ]\r\n );\r\n\r\n const menuComponent = useMemo(\r\n () =>\r\n menuVisible &&\r\n contextMenu && (\r\n \r\n {contextMenu({ data: edge, onClose: () => setMenuVisible(false) })}\r\n \r\n ),\r\n [menuVisible, contextMenu, midPoint, edge]\r\n );\r\n\r\n const lineComponent = useMemo(\r\n () => (\r\n {\r\n if (!disabled) {\r\n onClick?.(edge, event);\r\n }\r\n }}\r\n onPointerOver={pointerOver}\r\n onPointerOut={pointerOut}\r\n onContextMenu={() => {\r\n if (!disabled) {\r\n setMenuVisible(true);\r\n onContextMenu?.(edge);\r\n }\r\n }}\r\n />\r\n ),\r\n [\r\n active,\r\n animated,\r\n curve,\r\n curveOffset,\r\n curved,\r\n disabled,\r\n edge,\r\n id,\r\n isActive,\r\n isSelected,\r\n onClick,\r\n onContextMenu,\r\n pointerOut,\r\n pointerOver,\r\n selectionOpacity,\r\n size,\r\n theme.arrow.activeFill,\r\n theme.arrow.fill\r\n ]\r\n );\r\n\r\n return (\r\n \r\n {arrowComponent}\r\n {lineComponent}\r\n {menuComponent}\r\n {labelComponent}\r\n \r\n );\r\n};\r\n\r\nEdge.defaultProps = {\r\n labelPlacement: 'inline',\r\n arrowPlacement: 'end'\r\n};\r\n","import { useCallback, useRef } from 'react';\r\nimport {\r\n BoxGeometry,\r\n BufferGeometry,\r\n CylinderGeometry,\r\n Quaternion,\r\n TubeGeometry,\r\n Vector3\r\n} from 'three';\r\nimport { mergeBufferGeometries } from 'three-stdlib';\r\n\r\nimport { GraphState, useStore } from '../../store';\r\nimport { InternalGraphEdge } from '../../types';\r\nimport {\r\n getArrowSize,\r\n getArrowVectors,\r\n getVector,\r\n getCurve\r\n} from '../../utils';\r\nimport { EdgeArrowPosition } from '../Arrow';\r\nimport { EdgeInterpolation } from '../Edge';\r\n\r\nexport type UseEdgeGeometry = {\r\n getGeometries(edges: Array): Array;\r\n getGeometry(\r\n active: Array,\r\n inactive: Array\r\n ): BufferGeometry;\r\n};\r\n\r\nconst NULL_GEOMETRY = new BoxGeometry(0, 0, 0);\r\n\r\nexport function useEdgeGeometry(\r\n arrowPlacement: EdgeArrowPosition,\r\n interpolation: EdgeInterpolation\r\n): UseEdgeGeometry {\r\n // We don't want to rerun everything when the state changes,\r\n // but we do want to use the most recent nodes whenever `getGeometries`\r\n // or `getGeometry` is run, so we store it in a ref:\r\n const stateRef = useRef();\r\n const theme = useStore(state => state.theme);\r\n useStore(state => {\r\n stateRef.current = state;\r\n });\r\n\r\n const geometryCacheRef = useRef(new Map());\r\n\r\n const curved = interpolation === 'curved';\r\n const getGeometries = useCallback(\r\n (edges: Array): Array => {\r\n const geometries: Array = [];\r\n const cache = geometryCacheRef.current;\r\n\r\n const { nodes } = stateRef.current;\r\n\r\n edges.forEach(edge => {\r\n const { target, source, size = 1 } = edge;\r\n\r\n const from = nodes.find(node => node.id === source);\r\n const to = nodes.find(node => node.id === target);\r\n\r\n if (!from || !to) {\r\n return;\r\n }\r\n\r\n // Create hash so geometry can be reused if edge doesn't move:\r\n const hash = `fromX:${from.position.x},fromY:${from.position.y},toX:${to.position.x}},toY:${to.position.y}`;\r\n if (cache.has(hash)) {\r\n const geometry = cache.get(hash);\r\n geometries.push(geometry);\r\n return;\r\n }\r\n\r\n const fromVector = getVector(from);\r\n const fromOffset = from.size + theme.edge.label.fontSize;\r\n const toVector = getVector(to);\r\n const toOffset = to.size + theme.edge.label.fontSize;\r\n let curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n toVector,\r\n toOffset,\r\n curved\r\n );\r\n\r\n let edgeGeometry = new TubeGeometry(curve, 20, size / 2, 5, false);\r\n\r\n if (arrowPlacement === 'none') {\r\n geometries.push(edgeGeometry);\r\n cache.set(hash, edgeGeometry);\r\n return;\r\n }\r\n\r\n const [arrowLength, arrowSize] = getArrowSize(size);\r\n\r\n const [arrowPosition, arrowRotation] = getArrowVectors(\r\n arrowPlacement,\r\n curve,\r\n arrowLength\r\n );\r\n const quaternion = new Quaternion();\r\n quaternion.setFromUnitVectors(new Vector3(0, 1, 0), arrowRotation);\r\n\r\n const arrowGeometry = new CylinderGeometry(\r\n 0,\r\n arrowSize,\r\n arrowLength,\r\n 20,\r\n 1,\r\n true\r\n );\r\n arrowGeometry.applyQuaternion(quaternion);\r\n arrowGeometry.translate(\r\n arrowPosition.x,\r\n arrowPosition.y,\r\n arrowPosition.z\r\n );\r\n\r\n // Move edge so it doesn't stick through the arrow:\r\n if (arrowPlacement && arrowPlacement === 'end') {\r\n const curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n arrowPosition,\r\n 0,\r\n curved\r\n );\r\n edgeGeometry = new TubeGeometry(curve, 20, size / 2, 5, false);\r\n }\r\n\r\n const merged = mergeBufferGeometries([edgeGeometry, arrowGeometry]);\r\n geometries.push(merged);\r\n cache.set(hash, merged);\r\n });\r\n return geometries;\r\n },\r\n [arrowPlacement, curved, theme.edge.label.fontSize]\r\n );\r\n\r\n const getGeometry = useCallback(\r\n (\r\n active: Array,\r\n inactive: Array\r\n ): BufferGeometry => {\r\n const activeGeometries = getGeometries(active);\r\n const inactiveGeometries = getGeometries(inactive);\r\n\r\n return mergeBufferGeometries(\r\n [\r\n inactiveGeometries.length\r\n ? mergeBufferGeometries(inactiveGeometries)\r\n : NULL_GEOMETRY,\r\n activeGeometries.length\r\n ? mergeBufferGeometries(activeGeometries)\r\n : NULL_GEOMETRY\r\n ],\r\n true\r\n );\r\n },\r\n [getGeometries]\r\n );\r\n\r\n return {\r\n getGeometries,\r\n getGeometry\r\n };\r\n}\r\n","import { useCallback, useRef } from 'react';\r\n\r\nimport { useStore } from '../../store';\r\nimport { InternalGraphEdge } from '../../types';\r\n\r\nexport type EdgeEvents = {\r\n onClick?: (edge: InternalGraphEdge) => void;\r\n onContextMenu?: (edge?: InternalGraphEdge) => void;\r\n onPointerOver?: (edge: InternalGraphEdge) => void;\r\n onPointerOut?: (edge: InternalGraphEdge) => void;\r\n};\r\n\r\nexport function useEdgeEvents(\r\n events: EdgeEvents,\r\n contextMenu,\r\n disabled: boolean\r\n) {\r\n const { onClick, onContextMenu, onPointerOut, onPointerOver } = events;\r\n\r\n const edgeContextMenus = useStore(state => state.edgeContextMenus);\r\n const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\r\n\r\n const clickRef = useRef(false);\r\n const handleClick = useCallback(() => {\r\n clickRef.current = true;\r\n }, []);\r\n\r\n const contextMenuEventRef = useRef(false);\r\n const handleContextMenu = useCallback(() => {\r\n contextMenuEventRef.current = true;\r\n }, []);\r\n\r\n const handleIntersections = useCallback(\r\n (\r\n previous: Array,\r\n intersected: Array\r\n ) => {\r\n if (onClick && clickRef.current) {\r\n clickRef.current = false;\r\n if (!disabled) {\r\n intersected.forEach(edge => {\r\n onClick(edge);\r\n });\r\n }\r\n }\r\n\r\n if ((contextMenu || onContextMenu) && contextMenuEventRef.current) {\r\n contextMenuEventRef.current = false;\r\n if (!disabled) {\r\n intersected.forEach(edge => {\r\n if (!edgeContextMenus.has(edge.id)) {\r\n setEdgeContextMenus(new Set([...edgeContextMenus, edge.id]));\r\n onContextMenu?.(edge);\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (onPointerOver) {\r\n const over = intersected.filter(index => !previous.includes(index));\r\n over.forEach(edge => {\r\n onPointerOver(edge);\r\n });\r\n }\r\n\r\n if (onPointerOut) {\r\n const out = previous.filter(index => !intersected.includes(index));\r\n out.forEach(edge => {\r\n onPointerOut(edge);\r\n });\r\n }\r\n },\r\n [\r\n contextMenu,\r\n disabled,\r\n edgeContextMenus,\r\n setEdgeContextMenus,\r\n onClick,\r\n onContextMenu,\r\n onPointerOver,\r\n onPointerOut\r\n ]\r\n );\r\n\r\n return {\r\n handleClick,\r\n handleContextMenu,\r\n handleIntersections\r\n };\r\n}\r\n","import { SpringValue, useSpring } from '@react-spring/three';\r\nimport { useCallback, useEffect, useRef } from 'react';\r\nimport { BufferAttribute, BufferGeometry } from 'three';\r\n\r\nimport { Theme } from '../../themes';\r\nimport { animationConfig } from '../../utils';\r\n\r\nexport function useEdgePositionAnimation(\r\n geometry: BufferGeometry,\r\n animated: boolean\r\n): void {\r\n const geometryRef = useRef(geometry);\r\n\r\n useEffect(() => {\r\n geometryRef.current = geometry;\r\n }, [geometry]);\r\n\r\n const getAnimationPositions = useCallback(() => {\r\n const positions = geometryRef.current.getAttribute('position');\r\n const from = Array.from({\r\n length: positions.array.length\r\n }).fill(0) as Array;\r\n const to = Array.from(positions.array);\r\n return { from, to };\r\n }, []);\r\n\r\n const updateGeometryPosition = useCallback((positions: Array) => {\r\n const buffer = new Float32Array(positions);\r\n const newPosition = new BufferAttribute(buffer, 3, false);\r\n geometryRef.current.setAttribute('position', newPosition);\r\n newPosition.needsUpdate = true;\r\n }, []);\r\n\r\n useSpring(() => {\r\n if (!animated) {\r\n return null;\r\n }\r\n\r\n const animationPositions = getAnimationPositions();\r\n\r\n return {\r\n from: {\r\n positions: animationPositions.from\r\n },\r\n to: {\r\n positions: animationPositions.to\r\n },\r\n onChange: event => {\r\n updateGeometryPosition(event.value.positions);\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n };\r\n }, [animated]);\r\n}\r\n\r\nexport type UseEdgeOpacityAnimations = {\r\n activeOpacity: SpringValue;\r\n inactiveOpacity: SpringValue;\r\n};\r\n\r\nexport function useEdgeOpacityAnimation(\r\n animated: boolean,\r\n hasSelections: boolean,\r\n theme: Theme\r\n): UseEdgeOpacityAnimations {\r\n const [{ activeOpacity, inactiveOpacity }] = useSpring(() => {\r\n return {\r\n from: {\r\n activeOpacity: 0,\r\n inactiveOpacity: 0\r\n },\r\n to: {\r\n activeOpacity: hasSelections\r\n ? theme.edge.selectedOpacity\r\n : theme.edge.opacity,\r\n inactiveOpacity: hasSelections\r\n ? theme.edge.inactiveOpacity\r\n : theme.edge.opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n };\r\n }, [animated, hasSelections, theme]);\r\n\r\n return { activeOpacity, inactiveOpacity };\r\n}\r\n","import React, { FC, useCallback, useMemo } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Html } from 'glodrei';\r\nimport { ColorRepresentation, Euler } from 'three';\r\n\r\nimport { useStore } from '../../store';\r\nimport { Theme } from '../../themes';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../../types';\r\nimport {\r\n animationConfig,\r\n getLabelOffsetByType,\r\n getMidPoint\r\n} from '../../utils';\r\nimport { Label } from '../Label';\r\n\r\n/**\r\n * Label positions relatively edge\r\n *\r\n * below: show label under the edge line\r\n * above: show label above the edge line\r\n * inline: show label along the edge line\r\n * natural: normal text positions\r\n */\r\nexport type EdgeLabelPosition = 'below' | 'above' | 'inline' | 'natural';\r\n\r\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\r\n\r\nexport interface EdgeProps {\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The color of the edge.\r\n */\r\n color: ColorRepresentation;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * The edge object.\r\n */\r\n edge: InternalGraphEdge;\r\n\r\n /**\r\n * The URL of the font for the edge label.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The opacity of the edge.\r\n */\r\n opacity?: number;\r\n}\r\n\r\nexport const Edge: FC = ({\r\n animated,\r\n color,\r\n contextMenu,\r\n edge,\r\n labelFontUrl,\r\n labelPlacement,\r\n opacity\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const { target, source, label, labelVisible = false, size = 1 } = edge;\r\n\r\n const nodes = useStore(store => store.nodes);\r\n const from = nodes.find(node => node.id === source);\r\n const to = nodes.find(node => node.id === target);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n const labelOffset = (size + theme.edge.label.fontSize) / 2;\r\n\r\n const midPoint = useMemo(\r\n () =>\r\n getMidPoint(\r\n from.position,\r\n to.position,\r\n getLabelOffsetByType(labelOffset, labelPlacement)\r\n ),\r\n [from.position, to.position, labelOffset, labelPlacement]\r\n );\r\n\r\n const edgeContextMenus = useStore(state => state.edgeContextMenus);\r\n const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\r\n\r\n const [{ labelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n labelPosition: [0, 0, 0]\r\n },\r\n to: {\r\n labelPosition: [midPoint.x, midPoint.y, midPoint.z]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [midPoint, animated, draggingId]\r\n );\r\n\r\n const removeContextMenu = useCallback(\r\n (edge: InternalGraphEdge) => {\r\n edgeContextMenus.delete(edge.id);\r\n setEdgeContextMenus(new Set(edgeContextMenus.values()));\r\n },\r\n [edgeContextMenus, setEdgeContextMenus]\r\n );\r\n\r\n const labelRotation = useMemo(\r\n () =>\r\n new Euler(\r\n 0,\r\n 0,\r\n labelPlacement === 'natural'\r\n ? 0\r\n : Math.atan(\r\n (to.position.y - from.position.y) /\r\n (to.position.x - from.position.x)\r\n )\r\n ),\r\n [\r\n to.position.x,\r\n to.position.y,\r\n from.position.x,\r\n from.position.y,\r\n labelPlacement\r\n ]\r\n );\r\n\r\n return (\r\n \r\n {labelVisible && label && (\r\n \r\n \r\n \r\n )}\r\n {contextMenu && edgeContextMenus.has(edge.id) && (\r\n \r\n {contextMenu({\r\n data: edge,\r\n onClose: () => removeContextMenu(edge)\r\n })}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nEdge.defaultProps = {\r\n labelPlacement: 'inline'\r\n};\r\n","import React, { FC, useCallback, useEffect, useMemo, useRef } from 'react';\r\nimport { a } from '@react-spring/three';\r\nimport { useFrame } from '@react-three/fiber';\r\nimport { DoubleSide, Mesh, Raycaster, TubeGeometry } from 'three';\r\n\r\nimport { useStore } from '../../store';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../../types';\r\nimport { EdgeArrowPosition } from '../Arrow';\r\nimport { EdgeLabelPosition, EdgeInterpolation } from '../Edge';\r\nimport { useEdgeGeometry } from './useEdgeGeometry';\r\nimport { EdgeEvents, useEdgeEvents } from './useEdgeEvents';\r\nimport {\r\n useEdgePositionAnimation,\r\n useEdgeOpacityAnimation\r\n} from './useEdgeAnimations';\r\nimport { Edge } from './Edge';\r\n\r\nexport type EdgesProps = {\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The placement of the edge arrow.\r\n */\r\n arrowPlacement?: EdgeArrowPosition;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The array of edge objects.\r\n */\r\n edges: Array;\r\n\r\n /**\r\n * The URL of the font for the edge label.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The type of interpolation used to draw the edge.\r\n */\r\n interpolation?: EdgeInterpolation;\r\n} & EdgeEvents;\r\n\r\n/**\r\n * Three.js rendering starts to get slower if you have an individual mesh for each edge\r\n * and a high number of edges.\r\n *\r\n * Instead, we take the edges and split them into their different render states:\r\n *\r\n * * - Active (any edges that are marked as \"selected\" or \"active\" in the state)\r\n * * - Dragging (any edges that are connected to a node that is being dragged)\r\n * * - Intersecting (any edges that are currently intersected by the ray from the mouse position)\r\n * * - Inactive (any edges that aren't active, dragging, or intersected)\r\n *\r\n * We generate the geometry for each edge in each of these groups, and then merge them\r\n * into a single geometry for each group. This merged mesh is rendered as one object\r\n * which gives much better performance. This means that we only need to update geometry\r\n * and positions when edges move between the different states, rather than updating all\r\n * edges whenever any other edge changes.\r\n *\r\n * To get this all working, we have to do a few things outside the @react-three/fiber world,\r\n * specifically:\r\n *\r\n * * manually create edge/arrow geometries (see `useEdgeGeometry`)\r\n * * manually track mouse/edge interactions and fire events (see `useEdgeEvents`)\r\n * * manually update edge/arrow positions during aniamations (see `useEdgeAnimations`)\r\n */\r\nexport const Edges: FC = ({\r\n interpolation = 'linear',\r\n arrowPlacement = 'end',\r\n labelPlacement = 'inline',\r\n animated,\r\n contextMenu,\r\n disabled,\r\n edges,\r\n labelFontUrl,\r\n onClick,\r\n onContextMenu,\r\n onPointerOut,\r\n onPointerOver\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const { getGeometries, getGeometry } = useEdgeGeometry(\r\n arrowPlacement,\r\n interpolation\r\n );\r\n\r\n const draggingId = useStore(state => state.draggingId);\r\n const edgeMeshes = useStore(state => state.edgeMeshes);\r\n const setEdgeMeshes = useStore(state => state.setEdgeMeshes);\r\n const actives = useStore(state => state.actives || []);\r\n const selections = useStore(state => state.selections || []);\r\n\r\n const [active, inactive, draggingActive, draggingInactive] = useMemo(() => {\r\n const active: Array = [];\r\n const inactive: Array = [];\r\n const draggingActive: Array = [];\r\n const draggingInactive: Array = [];\r\n edges.forEach(edge => {\r\n if (draggingId === edge.source || draggingId === edge.target) {\r\n if (selections.includes(edge.id) || actives.includes(edge.id)) {\r\n draggingActive.push(edge);\r\n } else {\r\n draggingInactive.push(edge);\r\n }\r\n return;\r\n }\r\n\r\n if (selections.includes(edge.id) || actives.includes(edge.id)) {\r\n active.push(edge);\r\n } else {\r\n inactive.push(edge);\r\n }\r\n });\r\n return [active, inactive, draggingActive, draggingInactive];\r\n }, [edges, actives, selections, draggingId]);\r\n\r\n const hasSelections = !!selections.length;\r\n\r\n const staticEdgesGeometry = useMemo(\r\n () => getGeometry(active, inactive),\r\n [getGeometry, active, inactive]\r\n );\r\n\r\n const { activeOpacity, inactiveOpacity } = useEdgeOpacityAnimation(\r\n animated,\r\n hasSelections,\r\n theme\r\n );\r\n\r\n useEdgePositionAnimation(staticEdgesGeometry, animated);\r\n\r\n useEffect(() => {\r\n if (draggingId === null) {\r\n const edgeGeometries = getGeometries(edges);\r\n const edgeMeshes = edgeGeometries.map(edge => new Mesh(edge));\r\n setEdgeMeshes(edgeMeshes);\r\n }\r\n }, [getGeometries, setEdgeMeshes, edges, draggingId]);\r\n\r\n const staticEdgesRef = useRef(new Mesh());\r\n const dynamicEdgesRef = useRef(new Mesh());\r\n\r\n const intersect = useCallback(\r\n (raycaster: Raycaster): Array => {\r\n // Handle initial raycaster state:\r\n if (!raycaster.camera) {\r\n return [];\r\n }\r\n const intersections =\r\n raycaster.intersectObjects>(edgeMeshes);\r\n if (!intersections.length) {\r\n return [];\r\n }\r\n return intersections.map(\r\n intersection => edges[edgeMeshes.indexOf(intersection.object)]\r\n );\r\n },\r\n [edgeMeshes, edges]\r\n );\r\n\r\n const { handleClick, handleContextMenu, handleIntersections } = useEdgeEvents(\r\n {\r\n onClick,\r\n onContextMenu,\r\n onPointerOut,\r\n onPointerOver\r\n },\r\n contextMenu,\r\n disabled\r\n );\r\n\r\n const draggingIdRef = useRef(null);\r\n const intersectingRef = useRef>([]);\r\n\r\n useFrame(state => {\r\n staticEdgesRef.current.geometry = staticEdgesGeometry;\r\n\r\n if (disabled) {\r\n return;\r\n }\r\n\r\n const previousDraggingId = draggingIdRef.current;\r\n if (draggingId || (draggingId === null && previousDraggingId !== null)) {\r\n dynamicEdgesRef.current.geometry = getGeometry(\r\n draggingActive,\r\n draggingInactive\r\n );\r\n }\r\n\r\n draggingIdRef.current = draggingId;\r\n if (draggingId) {\r\n return;\r\n }\r\n\r\n const previousIntersecting = intersectingRef.current;\r\n const intersecting = intersect(state.raycaster);\r\n handleIntersections(previousIntersecting, intersecting);\r\n\r\n if (intersecting.join() !== previousIntersecting.join()) {\r\n dynamicEdgesRef.current.geometry = getGeometry(intersecting, []);\r\n }\r\n\r\n intersectingRef.current = intersecting;\r\n });\r\n\r\n return (\r\n \r\n {/* Static edges */}\r\n \r\n \r\n \r\n \r\n {/* Dynamic edges */}\r\n \r\n \r\n \r\n \r\n {edges.map(edge => (\r\n \r\n ))}\r\n \r\n );\r\n};\r\n","import React, { FC, useMemo, useState } from 'react';\r\nimport { ClusterGroup, animationConfig, useHoverIntent } from '../utils';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Color, DoubleSide } from 'three';\r\nimport { useStore } from '../store';\r\nimport { Label } from './Label';\r\nimport { useCursor } from 'glodrei';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport type ClusterEventArgs = Omit;\r\n\r\nexport interface ClusterProps extends ClusterGroup {\r\n /**\r\n * Whether the circle should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The radius of the circle. Default 1.\r\n */\r\n radius?: number;\r\n\r\n /**\r\n * The padding of the circle. Default 20.\r\n */\r\n padding?: number;\r\n\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * Whether the node is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * When the cluster was clicked.\r\n */\r\n onClick?: (cluster: ClusterEventArgs, event: ThreeEvent) => void;\r\n\r\n /**\r\n * When a cluster receives a pointer over event.\r\n */\r\n onPointerOver?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When cluster receives a pointer leave event.\r\n */\r\n onPointerOut?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nexport const Cluster: FC = ({\r\n animated,\r\n position,\r\n padding,\r\n labelFontUrl,\r\n disabled,\r\n radius,\r\n nodes,\r\n label,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const rad = Math.max(position.width, position.height) / 2;\r\n const offset = rad - radius + padding;\r\n const [active, setActive] = useState(false);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const isActive = useStore(state =>\r\n state.actives?.some(id => nodes.some(n => n.id === id))\r\n );\r\n\r\n const isSelected = useStore(state =>\r\n state.selections?.some(id => nodes.some(n => n.id === id))\r\n );\r\n\r\n const hasSelections = useStore(state => state.selections?.length > 0);\r\n\r\n const opacity = hasSelections\r\n ? isSelected || active || isActive\r\n ? theme.cluster?.selectedOpacity\r\n : theme.cluster?.inactiveOpacity\r\n : theme.cluster?.opacity;\r\n\r\n const { circleOpacity, circlePosition, labelPosition } = useSpring({\r\n from: {\r\n circlePosition: [center.x, center.y, -1],\r\n circleOpacity: 0,\r\n labelPosition: [0, -offset, 2]\r\n },\r\n to: {\r\n labelPosition: [0, -offset, 2],\r\n circlePosition: position ? [position.x, position.y, -1] : [0, 0, -1],\r\n circleOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedStroke = useMemo(\r\n () => new Color(theme.cluster?.stroke),\r\n [theme.cluster?.stroke]\r\n );\r\n\r\n const normalizedFill = useMemo(\r\n () => new Color(theme.cluster?.fill),\r\n [theme.cluster?.fill]\r\n );\r\n\r\n useCursor(active && onClick !== undefined, 'pointer');\r\n\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled,\r\n onPointerOver: (event: ThreeEvent) => {\r\n setActive(true);\r\n onPointerOver?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n setActive(false);\r\n onPointerOut?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n }\r\n });\r\n\r\n const cluster = useMemo(\r\n () =>\r\n theme.cluster && (\r\n ) => {\r\n if (!disabled) {\r\n onClick?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {theme.cluster?.label && (\r\n \r\n \r\n \r\n )}\r\n \r\n ),\r\n [\r\n theme.cluster,\r\n circlePosition,\r\n pointerOver,\r\n pointerOut,\r\n offset,\r\n normalizedFill,\r\n circleOpacity,\r\n rad,\r\n padding,\r\n normalizedStroke,\r\n labelPosition,\r\n label,\r\n opacity,\r\n labelFontUrl,\r\n disabled,\r\n onClick,\r\n nodes\r\n ]\r\n );\r\n\r\n return cluster;\r\n};\r\n\r\nCluster.defaultProps = {\r\n radius: 2,\r\n padding: 40\r\n};\r\n","import React, {\r\n FC,\r\n forwardRef,\r\n Fragment,\r\n ReactNode,\r\n Ref,\r\n useImperativeHandle,\r\n useMemo\r\n} from 'react';\r\nimport { useGraph } from './useGraph';\r\nimport { LayoutOverrides, LayoutTypes } from './layout';\r\nimport {\r\n NodeContextMenuProps,\r\n ContextMenuEvent,\r\n GraphEdge,\r\n GraphNode,\r\n InternalGraphEdge,\r\n InternalGraphNode,\r\n NodeRenderer,\r\n CollapseProps\r\n} from './types';\r\nimport { SizingType } from './sizing';\r\nimport {\r\n Cluster,\r\n ClusterEventArgs,\r\n Edge,\r\n EdgeArrowPosition,\r\n EdgeInterpolation,\r\n EdgeLabelPosition,\r\n Edges,\r\n Node\r\n} from './symbols';\r\nimport {\r\n CenterNodesParams,\r\n FitNodesParams,\r\n useCenterGraph\r\n} from './CameraControls';\r\nimport { LabelVisibilityType } from './utils';\r\nimport { useStore } from './store';\r\nimport Graph from 'graphology';\r\nimport { ThreeEvent, useThree } from '@react-three/fiber';\r\n\r\nexport interface GraphSceneProps {\r\n /**\r\n * Type of layout.\r\n */\r\n layoutType?: LayoutTypes;\r\n\r\n /**\r\n * List of ids that are selected.\r\n */\r\n selections?: string[];\r\n\r\n /**\r\n * List of ids that are active.\r\n */\r\n actives?: string[];\r\n\r\n /**\r\n * List of node ids that are collapsed.\r\n */\r\n collapsedNodeIds?: string[];\r\n\r\n /**\r\n * Animate or not the graph positions.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Nodes to pass to the graph.\r\n */\r\n nodes: GraphNode[];\r\n\r\n /**\r\n * Edges to pass to the graph.\r\n */\r\n edges: GraphEdge[];\r\n\r\n /**\r\n * Context menu element.\r\n */\r\n contextMenu?: (event: ContextMenuEvent) => ReactNode;\r\n\r\n /**\r\n * Type of sizing for nodes.\r\n */\r\n sizingType?: SizingType;\r\n\r\n /**\r\n * Type of visibility for labels.\r\n */\r\n labelType?: LabelVisibilityType;\r\n\r\n /**\r\n * Place of visibility for edge labels.\r\n */\r\n edgeLabelPosition?: EdgeLabelPosition;\r\n\r\n /**\r\n * Placement of edge arrows.\r\n */\r\n edgeArrowPosition?: EdgeArrowPosition;\r\n\r\n /**\r\n * Shape of edge.\r\n */\r\n edgeInterpolation?: EdgeInterpolation;\r\n\r\n /**\r\n * Font of label, same as troika-three-text\r\n * The URL of a custom font file to be used. Supported font formats are: * .ttf * .otf * .woff (.woff2 is not supported)\r\n * Default: The Roboto font loaded from Google Fonts CDN\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * Attribute based sizing property.\r\n */\r\n sizingAttribute?: string;\r\n\r\n /**\r\n * The default size to size nodes to. Default is 7.\r\n */\r\n defaultNodeSize?: number;\r\n\r\n /**\r\n * When using sizing attributes, the min size a node can be.\r\n */\r\n minNodeSize?: number;\r\n\r\n /**\r\n * When using sizing attributes, the max size a node can be.\r\n */\r\n maxNodeSize?: number;\r\n\r\n /**\r\n * Attribute used for clustering.\r\n */\r\n clusterAttribute?: string;\r\n\r\n /**\r\n * Disable interactions or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Allow dragging of nodes.\r\n */\r\n draggable?: boolean;\r\n\r\n /**\r\n * Render a custom node\r\n */\r\n renderNode?: NodeRenderer;\r\n\r\n /**\r\n * Advanced overrides for the layout.\r\n */\r\n layoutOverrides?: LayoutOverrides;\r\n\r\n /**\r\n * When a node was clicked.\r\n */\r\n onNodeClick?: (\r\n node: InternalGraphNode,\r\n props?: CollapseProps,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a node was double clicked.\r\n */\r\n onNodeDoubleClick?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a node context menu happened.\r\n */\r\n onNodeContextMenu?: (\r\n node: InternalGraphNode,\r\n props?: NodeContextMenuProps\r\n ) => void;\r\n\r\n /**\r\n * When node got a pointer over.\r\n */\r\n onNodePointerOver?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When node lost pointer over.\r\n */\r\n onNodePointerOut?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * Triggered after a node was dragged.\r\n */\r\n onNodeDragged?: (node: InternalGraphNode) => void;\r\n\r\n /**\r\n * When a edge context menu happened.\r\n */\r\n onEdgeContextMenu?: (edge?: InternalGraphEdge) => void;\r\n\r\n /**\r\n * When an edge was clicked.\r\n */\r\n onEdgeClick?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When edge got a pointer over.\r\n */\r\n onEdgePointerOver?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When edge lost pointer over.\r\n */\r\n onEdgePointerOut?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a cluster was clicked.\r\n */\r\n onClusterClick?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a cluster receives a pointer over event.\r\n */\r\n onClusterPointerOver?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When cluster receives a pointer leave event.\r\n */\r\n onClusterPointerOut?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nexport interface GraphSceneRef {\r\n /**\r\n * Reference to the graph object.\r\n */\r\n graph: Graph;\r\n\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `ids` are not currently in view. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerGraph: (nodeIds?: string[], opts?: CenterNodesParams) => void;\r\n\r\n /**\r\n * Fit all the given nodes into view of the camera.\r\n *\r\n * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\r\n * the view will fit to all nodes.\r\n *\r\n * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\r\n * only be fit if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the view will only be fit if one or more of the nodes\r\n * specified by `ids` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the view will be fit regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n fitNodesInView: (nodeIds?: string[], opts?: FitNodesParams) => void;\r\n\r\n /**\r\n * Calls render scene on the graph. this is useful when you want to manually render the graph\r\n * for things like screenshots.\r\n */\r\n renderScene: () => void;\r\n}\r\n\r\nexport const GraphScene: FC }> =\r\n forwardRef(\r\n (\r\n {\r\n onNodeClick,\r\n onNodeDoubleClick,\r\n onNodeContextMenu,\r\n onEdgeContextMenu,\r\n onEdgeClick,\r\n onEdgePointerOver,\r\n onEdgePointerOut,\r\n onNodePointerOver,\r\n onNodePointerOut,\r\n onClusterClick,\r\n onNodeDragged,\r\n onClusterPointerOver,\r\n onClusterPointerOut,\r\n contextMenu,\r\n animated,\r\n disabled,\r\n draggable,\r\n edgeLabelPosition,\r\n edgeArrowPosition,\r\n edgeInterpolation,\r\n labelFontUrl,\r\n renderNode,\r\n ...rest\r\n },\r\n ref\r\n ) => {\r\n const { layoutType, clusterAttribute } = rest;\r\n\r\n // Get the gl/scene/camera for render shortcuts\r\n const gl = useThree(state => state.gl);\r\n const scene = useThree(state => state.scene);\r\n const camera = useThree(state => state.camera);\r\n\r\n // Mount and build the graph\r\n useGraph(rest);\r\n\r\n if (\r\n clusterAttribute &&\r\n !(layoutType === 'forceDirected2d' || layoutType === 'forceDirected3d')\r\n ) {\r\n throw new Error(\r\n 'Clustering is only supported for the force directed layouts.'\r\n );\r\n }\r\n\r\n // Get the graph and nodes via the store for memo\r\n const graph = useStore(state => state.graph);\r\n const nodes = useStore(state => state.nodes);\r\n const edges = useStore(state => state.edges);\r\n const clusters = useStore(state => [...state.clusters.values()]);\r\n\r\n // Center the graph on the nodes\r\n const { centerNodesById, fitNodesInViewById, isCentered } =\r\n useCenterGraph({\r\n animated,\r\n disabled,\r\n layoutType\r\n });\r\n\r\n // Let's expose some helper methods\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n centerGraph: centerNodesById,\r\n fitNodesInView: fitNodesInViewById,\r\n graph,\r\n renderScene: () => gl.render(scene, camera)\r\n }),\r\n [centerNodesById, fitNodesInViewById, graph, gl, scene, camera]\r\n );\r\n\r\n const nodeComponents = useMemo(\r\n () =>\r\n nodes.map(n => (\r\n \r\n )),\r\n [\r\n animated,\r\n contextMenu,\r\n disabled,\r\n draggable,\r\n labelFontUrl,\r\n nodes,\r\n onNodeClick,\r\n onNodeContextMenu,\r\n onNodeDoubleClick,\r\n onNodeDragged,\r\n onNodePointerOut,\r\n onNodePointerOver,\r\n renderNode\r\n ]\r\n );\r\n\r\n const edgeComponents = useMemo(\r\n () =>\r\n animated ? (\r\n edges.map(e => (\r\n \r\n ))\r\n ) : (\r\n \r\n ),\r\n [\r\n animated,\r\n contextMenu,\r\n disabled,\r\n edgeArrowPosition,\r\n edgeInterpolation,\r\n edgeLabelPosition,\r\n edges,\r\n labelFontUrl,\r\n onEdgeClick,\r\n onEdgeContextMenu,\r\n onEdgePointerOut,\r\n onEdgePointerOver\r\n ]\r\n );\r\n\r\n const clusterComponents = useMemo(\r\n () =>\r\n clusters.map(c => (\r\n \r\n )),\r\n [\r\n animated,\r\n clusters,\r\n disabled,\r\n labelFontUrl,\r\n onClusterClick,\r\n onClusterPointerOut,\r\n onClusterPointerOver\r\n ]\r\n );\r\n\r\n return (\r\n isCentered && (\r\n \r\n {edgeComponents}\r\n {nodeComponents}\r\n {clusterComponents}\r\n \r\n )\r\n );\r\n }\r\n );\r\n\r\nGraphScene.defaultProps = {\r\n edgeInterpolation: 'linear'\r\n};\r\n","import { Theme } from './theme';\r\n\r\nexport const darkTheme: Theme = {\r\n canvas: {\r\n background: '#1E2026'\r\n },\r\n node: {\r\n fill: '#7A8C9E',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n },\r\n subLabel: {\r\n stroke: '#1E2026',\r\n color: '#ACBAC7',\r\n activeColor: '#1DE9AC'\r\n }\r\n },\r\n lasso: {\r\n border: '1px solid #55aaff',\r\n background: 'rgba(75, 160, 255, 0.1)'\r\n },\r\n ring: {\r\n fill: '#54616D',\r\n activeFill: '#1DE9AC'\r\n },\r\n edge: {\r\n fill: '#ffffff',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 4,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n }\r\n },\r\n arrow: {\r\n fill: '#474B56',\r\n activeFill: '#1DE9AC'\r\n },\r\n cluster: {\r\n stroke: '#474B56',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 4,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n }\r\n }\r\n};\r\n","import { Theme } from './theme';\r\n\r\nexport const lightTheme: Theme = {\r\n canvas: {\r\n background: '#fff'\r\n },\r\n node: {\r\n fill: '#7CA0AB',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.2,\r\n label: {\r\n color: '#2A6475',\r\n // stroke: '#fff',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n },\r\n subLabel: {\r\n color: '#ddd',\r\n stroke: 'transparent',\r\n activeColor: '#1DE9AC'\r\n }\r\n },\r\n lasso: {\r\n border: '1px solid #55aaff',\r\n background: 'rgba(75, 160, 255, 0.1)'\r\n },\r\n ring: {\r\n fill: '#D8E6EA',\r\n activeFill: '#1DE9AC'\r\n },\r\n edge: {\r\n fill: '#474B56',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n // stroke: '#fff',\r\n color: '#2A6475',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n }\r\n },\r\n arrow: {\r\n fill: '#D8E6EA',\r\n activeFill: '#1DE9AC'\r\n },\r\n cluster: {\r\n stroke: '#D8E6EA',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n stroke: '#1E2026',\r\n color: '#ACBAC7',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n }\r\n }\r\n};\r\n","import { Theme } from '../themes';\r\nimport Graph from 'graphology';\r\n\r\nexport type PathSelectionTypes = 'direct' | 'out' | 'in' | 'all';\r\n\r\n/**\r\n * Given a graph and a list of node ids, return the adjacent nodes and edges.\r\n *\r\n * TODO: This method could be improved with the introduction of graphology\r\n */\r\nexport function getAdjacents(\r\n graph: Graph,\r\n nodeIds: string | string[],\r\n type: PathSelectionTypes\r\n) {\r\n nodeIds = Array.isArray(nodeIds) ? nodeIds : [nodeIds];\r\n\r\n const nodes: string[] = [];\r\n const edges: string[] = [];\r\n\r\n for (const nodeId of nodeIds) {\r\n const graphLinks = [\r\n ...(graph.inEdgeEntries(nodeId) ?? []),\r\n ...(graph.outEdgeEntries(nodeId) ?? [])\r\n ];\r\n\r\n if (!graphLinks) {\r\n continue;\r\n }\r\n\r\n for (const link of graphLinks) {\r\n const linkId = link.attributes.id;\r\n\r\n if (type === 'in') {\r\n if (link.target === nodeId && !edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n } else if (type === 'out') {\r\n if (link.source === nodeId && !edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n } else {\r\n if (!edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n }\r\n\r\n if (type === 'out' || type === 'all') {\r\n const toId = link.target;\r\n if (!nodes.includes(toId as string)) {\r\n nodes.push(toId as string);\r\n }\r\n }\r\n\r\n if (type === 'in' || type === 'all') {\r\n if (!nodes.includes(link.source)) {\r\n nodes.push(link.source as string);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n nodes,\r\n edges\r\n };\r\n}\r\n\r\n/**\r\n * Set the vectors.\r\n */\r\nexport function prepareRay(event, vec, size) {\r\n const { offsetX, offsetY } = event;\r\n const { width, height } = size;\r\n vec.set((offsetX / width) * 2 - 1, -(offsetY / height) * 2 + 1);\r\n}\r\n\r\n/**\r\n * Create a lasso element.\r\n */\r\nexport function createElement(theme: Theme) {\r\n const element = document.createElement('div');\r\n element.style.pointerEvents = 'none';\r\n element.style.border = theme.lasso.border;\r\n element.style.backgroundColor = theme.lasso.background;\r\n element.style.position = 'fixed';\r\n return element;\r\n}\r\n","import React, {\r\n FC,\r\n PropsWithChildren,\r\n useCallback,\r\n useEffect,\r\n useRef\r\n} from 'react';\r\nimport { useThree } from '@react-three/fiber';\r\nimport { SelectionBox } from 'three-stdlib';\r\nimport { Mesh, Scene, TubeGeometry, Vector2 } from 'three';\r\nimport { useCameraControls } from '../CameraControls';\r\nimport { useStore } from '../store';\r\nimport { createElement, prepareRay } from './utils';\r\n\r\nexport type LassoType = 'none' | 'all' | 'node' | 'edge';\r\n\r\nexport type LassoProps = PropsWithChildren<{\r\n /**\r\n * Whether the lasso tool is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The type of the lasso tool.\r\n */\r\n type?: LassoType;\r\n\r\n /**\r\n * A function that is called when the lasso tool is used to select nodes.\r\n * The function receives an array of the ids of the selected nodes.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * A function that is called when the lasso tool is released, ending the selection.\r\n * The function receives an array of the ids of the selected nodes.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n}>;\r\n\r\nexport const Lasso: FC = ({\r\n children,\r\n type = 'none',\r\n onLasso,\r\n onLassoEnd,\r\n disabled\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const camera = useThree(state => state.camera);\r\n const gl = useThree(state => state.gl);\r\n const setEvents = useThree(state => state.setEvents);\r\n const size = useThree(state => state.size);\r\n const get = useThree(state => state.get);\r\n const scene = useThree(state => state.scene);\r\n\r\n const cameraControls = useCameraControls();\r\n\r\n const actives = useStore(state => state.actives);\r\n const setActives = useStore(state => state.setActives);\r\n const edges = useStore(state => state.edges);\r\n const edgeMeshes = useStore(state => state.edgeMeshes);\r\n\r\n const mountedRef = useRef(false);\r\n const selectionBoxRef = useRef(null);\r\n const edgeMeshSelectionBoxRef = useRef(null);\r\n const elementRef = useRef(createElement(theme));\r\n const vectorsRef = useRef<[Vector2, Vector2, Vector2] | null>(null);\r\n const isDownRef = useRef(false);\r\n const oldRaycasterEnabledRef = useRef(get().events.enabled);\r\n const oldControlsEnabledRef = useRef(\r\n cameraControls.controls?.enabled\r\n );\r\n\r\n useEffect(() => {\r\n if (mountedRef.current) {\r\n onLasso?.(actives);\r\n }\r\n\r\n mountedRef.current = true;\r\n }, [actives, onLasso]);\r\n\r\n const onPointerMove = useCallback(\r\n event => {\r\n if (isDownRef.current) {\r\n const [startPoint, pointTopLeft, pointBottomRight] = vectorsRef.current;\r\n\r\n pointBottomRight.x = Math.max(startPoint.x, event.clientX);\r\n pointBottomRight.y = Math.max(startPoint.y, event.clientY);\r\n pointTopLeft.x = Math.min(startPoint.x, event.clientX);\r\n pointTopLeft.y = Math.min(startPoint.y, event.clientY);\r\n elementRef.current.style.left = `${pointTopLeft.x}px`;\r\n elementRef.current.style.top = `${pointTopLeft.y}px`;\r\n elementRef.current.style.width = `${\r\n pointBottomRight.x - pointTopLeft.x\r\n }px`;\r\n elementRef.current.style.height = `${\r\n pointBottomRight.y - pointTopLeft.y\r\n }px`;\r\n\r\n prepareRay(event, selectionBoxRef.current.endPoint, size);\r\n prepareRay(event, edgeMeshSelectionBoxRef.current.endPoint, size);\r\n\r\n const allSelected = [];\r\n const edgesSelected = edgeMeshSelectionBoxRef.current\r\n .select()\r\n .sort(o => (o as any).uuid)\r\n .map(\r\n edge => edges[edgeMeshes.indexOf(edge as Mesh)].id\r\n );\r\n allSelected.push(...edgesSelected);\r\n\r\n const selected = selectionBoxRef.current\r\n .select()\r\n .sort(o => (o as any).uuid)\r\n .filter(\r\n o =>\r\n o.isMesh &&\r\n o.userData?.id &&\r\n (o.userData?.type === type || type === 'all')\r\n )\r\n .map(o => o.userData.id);\r\n allSelected.push(...selected);\r\n\r\n // Note: This probably isn't the best solution but\r\n // it prevents the render thrashing and causing flickering\r\n requestAnimationFrame(() => {\r\n setActives(allSelected);\r\n });\r\n\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true,\r\n capture: true,\r\n once: true\r\n });\r\n }\r\n },\r\n [edges, edgeMeshes, setActives, size, type]\r\n );\r\n\r\n const onPointerUp = useCallback(() => {\r\n if (isDownRef.current) {\r\n setEvents({ enabled: oldRaycasterEnabledRef.current });\r\n isDownRef.current = false;\r\n elementRef.current.parentElement?.removeChild(elementRef.current);\r\n cameraControls.controls.enabled = oldControlsEnabledRef.current;\r\n onLassoEnd?.(actives);\r\n\r\n document.removeEventListener('pointermove', onPointerMove);\r\n document.removeEventListener('pointerup', onPointerUp);\r\n }\r\n }, [setEvents, cameraControls.controls, onLassoEnd, actives, onPointerMove]);\r\n\r\n const onPointerDown = useCallback(\r\n event => {\r\n if (event.shiftKey) {\r\n // Let's capture the old props to restore them later\r\n oldRaycasterEnabledRef.current = get().events.enabled;\r\n oldControlsEnabledRef.current = cameraControls.controls?.enabled;\r\n\r\n // SelectionBox for all meshes\r\n selectionBoxRef.current = new SelectionBox(camera, scene);\r\n\r\n // SelectionBox for all Edge meshes (since they are combined into one geometry for rendering)\r\n const edgeScene = new Scene();\r\n if (edgeMeshes.length) {\r\n edgeScene.add(...edgeMeshes);\r\n }\r\n edgeMeshSelectionBoxRef.current = new SelectionBox(camera, edgeScene);\r\n\r\n vectorsRef.current = [\r\n // start point\r\n new Vector2(),\r\n // point top left\r\n new Vector2(),\r\n // point bottom right\r\n new Vector2()\r\n ];\r\n\r\n const [startPoint] = vectorsRef.current;\r\n\r\n cameraControls.controls.enabled = false;\r\n setEvents({ enabled: false });\r\n isDownRef.current = true;\r\n gl.domElement.parentElement?.appendChild(elementRef.current);\r\n elementRef.current.style.left = `${event.clientX}px`;\r\n elementRef.current.style.top = `${event.clientY}px`;\r\n elementRef.current.style.width = '0px';\r\n elementRef.current.style.height = '0px';\r\n startPoint.x = event.clientX;\r\n startPoint.y = event.clientY;\r\n\r\n prepareRay(event, selectionBoxRef.current.startPoint, size);\r\n prepareRay(event, edgeMeshSelectionBoxRef.current.startPoint, size);\r\n\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true,\r\n capture: true,\r\n once: true\r\n });\r\n document.addEventListener('pointerup', onPointerUp, { passive: true });\r\n }\r\n },\r\n [\r\n camera,\r\n cameraControls.controls,\r\n edgeMeshes,\r\n get,\r\n gl.domElement.parentElement,\r\n onPointerMove,\r\n onPointerUp,\r\n scene,\r\n setEvents,\r\n size\r\n ]\r\n );\r\n\r\n useEffect(() => {\r\n if (disabled || type === 'none') {\r\n return;\r\n }\r\n\r\n if (typeof window !== 'undefined') {\r\n document.addEventListener('pointerdown', onPointerDown, {\r\n passive: true\r\n });\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true\r\n });\r\n document.addEventListener('pointerup', onPointerUp, { passive: true });\r\n }\r\n\r\n return () => {\r\n if (typeof window !== 'undefined') {\r\n document.removeEventListener('pointerdown', onPointerDown);\r\n document.removeEventListener('pointermove', onPointerMove);\r\n document.removeEventListener('pointerup', onPointerUp);\r\n }\r\n };\r\n }, [type, disabled, onPointerDown, onPointerMove, onPointerUp]);\r\n\r\n return {children};\r\n};\r\n","import React, {\r\n RefObject,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useState\r\n} from 'react';\r\nimport { GraphCanvasRef } from '../GraphCanvas';\r\nimport { useHotkeys } from 'reakeys';\r\nimport { GraphEdge, GraphNode } from '../types';\r\nimport { findPath } from '../utils/paths';\r\nimport { getAdjacents, PathSelectionTypes } from './utils';\r\n\r\nexport type HotkeyTypes = 'selectAll' | 'deselect' | 'delete';\r\n\r\nexport type SelectionTypes = 'single' | 'multi' | 'multiModifier';\r\n\r\nexport interface SelectionProps {\r\n /**\r\n * Required ref for the graph.\r\n */\r\n ref: RefObject;\r\n\r\n /**\r\n * Current selections.\r\n *\r\n * Contains both nodes and edges ids.\r\n */\r\n selections?: string[];\r\n\r\n /**\r\n * Default active selections.\r\n */\r\n actives?: string[];\r\n\r\n /**\r\n * Node datas.\r\n */\r\n nodes?: GraphNode[];\r\n\r\n /**\r\n * Edge datas.\r\n */\r\n edges?: GraphEdge[];\r\n\r\n /**\r\n * Disabled or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Hotkey types\r\n */\r\n hotkeys?: HotkeyTypes[];\r\n\r\n /**\r\n * Whether to focus on select or not.\r\n */\r\n focusOnSelect?: boolean | 'singleOnly';\r\n\r\n /**\r\n * Type of selection.\r\n */\r\n type?: SelectionTypes;\r\n\r\n /**\r\n * Type of selection.\r\n */\r\n pathSelectionType?: PathSelectionTypes;\r\n\r\n /**\r\n * Whether it should active on hover or not.\r\n */\r\n pathHoverType?: PathSelectionTypes;\r\n\r\n /**\r\n * On selection change.\r\n */\r\n onSelection?: (selectionIds: string[]) => void;\r\n}\r\n\r\nexport interface SelectionResult {\r\n /**\r\n * Selections id array (of nodes and edges).\r\n */\r\n selections: string[];\r\n\r\n /**\r\n * The nodes/edges around the selections to highlight.\r\n */\r\n actives: string[];\r\n\r\n /**\r\n * Clear selections method.\r\n */\r\n clearSelections: (value?: string[]) => void;\r\n\r\n /**\r\n * A selection method.\r\n */\r\n addSelection: (value: string) => void;\r\n\r\n /**\r\n * Get the paths between two nodes.\r\n */\r\n selectNodePaths: (source: string, target: string) => void;\r\n\r\n /**\r\n * Remove selection method.\r\n */\r\n removeSelection: (value: string) => void;\r\n\r\n /**\r\n * Toggle existing selection on/off method.\r\n */\r\n toggleSelection: (value: string) => void;\r\n\r\n /**\r\n * Set internal selections.\r\n */\r\n setSelections: (value: string[]) => void;\r\n\r\n /**\r\n * On click event pass through.\r\n */\r\n onNodeClick?: (data: GraphNode) => void;\r\n\r\n /**\r\n * On canvas click event pass through.\r\n */\r\n onCanvasClick?: (event: MouseEvent) => void;\r\n\r\n /**\r\n * When the lasso happened.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the lasso ended.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n\r\n /**\r\n * When node got a pointer over.\r\n */\r\n onNodePointerOver?: (node: GraphNode) => void;\r\n\r\n /**\r\n * When node lost pointer over.\r\n */\r\n onNodePointerOut?: (node: GraphNode) => void;\r\n}\r\n\r\nexport const useSelection = ({\r\n selections = [],\r\n nodes = [],\r\n actives = [],\r\n focusOnSelect = true,\r\n type = 'single',\r\n pathHoverType = 'out',\r\n pathSelectionType = 'direct',\r\n ref,\r\n hotkeys = ['selectAll', 'deselect', 'delete'],\r\n disabled,\r\n onSelection\r\n}: SelectionProps): SelectionResult => {\r\n const [internalHovers, setInternalHovers] = useState([]);\r\n const [internalActives, setInternalActives] = useState(actives);\r\n const [internalSelections, setInternalSelections] =\r\n useState(selections);\r\n const [metaKeyDown, setMetaKeyDown] = useState(false);\r\n const isMulti = type === 'multi' || type === 'multiModifier';\r\n\r\n const addSelection = useCallback(\r\n (items: string | string[]) => {\r\n if (!disabled && items) {\r\n items = Array.isArray(items) ? items : [items];\r\n\r\n const filtered = items.filter(\r\n item => !internalSelections.includes(item)\r\n );\r\n if (filtered.length) {\r\n const next = [...internalSelections, ...filtered];\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n }\r\n },\r\n [disabled, internalSelections, onSelection]\r\n );\r\n\r\n const removeSelection = useCallback(\r\n (items: string | string[]) => {\r\n if (!disabled && items) {\r\n items = Array.isArray(items) ? items : [items];\r\n\r\n const next = internalSelections.filter(i => !items.includes(i));\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n },\r\n [disabled, internalSelections, onSelection]\r\n );\r\n\r\n const clearSelections = useCallback(\r\n (next: string | string[] = []) => {\r\n if (!disabled) {\r\n next = Array.isArray(next) ? next : [next];\r\n setInternalActives([]);\r\n setInternalSelections(next);\r\n onSelection?.(next);\r\n }\r\n },\r\n [disabled, onSelection]\r\n );\r\n\r\n const toggleSelection = useCallback(\r\n (item: string) => {\r\n const has = internalSelections.includes(item);\r\n if (has) {\r\n removeSelection(item);\r\n } else {\r\n if (!isMulti) {\r\n clearSelections(item);\r\n } else {\r\n addSelection(item);\r\n }\r\n }\r\n },\r\n [\r\n addSelection,\r\n clearSelections,\r\n internalSelections,\r\n isMulti,\r\n removeSelection\r\n ]\r\n );\r\n\r\n const onNodeClick = useCallback(\r\n (data: GraphNode) => {\r\n if (isMulti) {\r\n if (type === 'multiModifier') {\r\n if (metaKeyDown) {\r\n addSelection(data.id);\r\n } else {\r\n clearSelections(data.id);\r\n }\r\n } else {\r\n addSelection(data.id);\r\n }\r\n } else {\r\n clearSelections(data.id);\r\n }\r\n\r\n if (\r\n focusOnSelect === true ||\r\n (focusOnSelect === 'singleOnly' && !metaKeyDown)\r\n ) {\r\n if (!ref.current) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n const graph = ref.current.getGraph();\r\n const { nodes: adjacents } = getAdjacents(\r\n graph,\r\n [data.id],\r\n pathSelectionType\r\n );\r\n\r\n ref.current.fitNodesInView([data.id, ...adjacents], {\r\n fitOnlyIfNodesNotInView: true\r\n });\r\n }\r\n },\r\n [\r\n addSelection,\r\n clearSelections,\r\n focusOnSelect,\r\n isMulti,\r\n metaKeyDown,\r\n pathSelectionType,\r\n ref,\r\n type\r\n ]\r\n );\r\n\r\n const selectNodePaths = useCallback(\r\n (source: string, target: string) => {\r\n const graph = ref.current.getGraph();\r\n if (!graph) {\r\n throw new Error('Graph is not initialized');\r\n }\r\n\r\n const path = findPath(graph, source, target);\r\n clearSelections([source, target]);\r\n\r\n const result = [];\r\n for (let i = 0; i < path.length - 1; i++) {\r\n const from = path[i];\r\n const to = path[i + 1];\r\n const edge = graph.getEdgeAttributes(from, to);\r\n if (edge) {\r\n result.push(edge.id);\r\n }\r\n }\r\n\r\n setInternalActives([...path.map(p => p as string), ...result]);\r\n },\r\n [clearSelections, ref]\r\n );\r\n\r\n const onKeyDown = useCallback((event: KeyboardEvent) => {\r\n const element = event.target as any;\r\n const isSafe =\r\n element.tagName !== 'INPUT' &&\r\n element.tagName !== 'SELECT' &&\r\n element.tagName !== 'TEXTAREA' &&\r\n !element.isContentEditable;\r\n\r\n const isMeta = event.metaKey || event.ctrlKey;\r\n\r\n if (isSafe && isMeta) {\r\n event.preventDefault();\r\n setMetaKeyDown(true);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', onKeyDown);\r\n }\r\n\r\n return () => {\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', onKeyDown);\r\n }\r\n };\r\n }, [onKeyDown]);\r\n\r\n const onCanvasClick = useCallback(\r\n (event: MouseEvent) => {\r\n if (\r\n event.button !== 2 &&\r\n (internalSelections.length || internalActives.length)\r\n ) {\r\n clearSelections();\r\n setMetaKeyDown(false);\r\n\r\n // Only re-center if we have a single selection\r\n if (focusOnSelect && internalSelections.length === 1) {\r\n if (!ref.current) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n ref.current.fitNodesInView([], { fitOnlyIfNodesNotInView: true });\r\n }\r\n }\r\n },\r\n [\r\n clearSelections,\r\n focusOnSelect,\r\n internalActives.length,\r\n internalSelections.length,\r\n ref\r\n ]\r\n );\r\n\r\n const onLasso = useCallback((selections: string[]) => {\r\n setInternalActives(selections);\r\n }, []);\r\n\r\n const onLassoEnd = useCallback(\r\n (selections: string[]) => {\r\n clearSelections(selections);\r\n },\r\n [clearSelections]\r\n );\r\n\r\n const onNodePointerOver = useCallback(\r\n (data: GraphNode) => {\r\n if (pathHoverType) {\r\n const graph = ref.current.getGraph();\r\n if (!graph) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n const { nodes, edges } = getAdjacents(graph, [data.id], pathHoverType);\r\n setInternalHovers([...nodes, ...edges]);\r\n }\r\n },\r\n [pathHoverType, ref]\r\n );\r\n\r\n const onNodePointerOut = useCallback(() => {\r\n if (pathHoverType) {\r\n setInternalHovers([]);\r\n }\r\n }, [pathHoverType]);\r\n\r\n useEffect(() => {\r\n if (pathSelectionType !== 'direct' && internalSelections.length > 0) {\r\n const graph = ref.current?.getGraph();\r\n if (graph) {\r\n const { nodes, edges } = getAdjacents(\r\n graph,\r\n internalSelections,\r\n pathSelectionType\r\n );\r\n setInternalActives([...nodes, ...edges]);\r\n }\r\n }\r\n }, [internalSelections, pathSelectionType, ref]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Select All',\r\n keys: 'mod+a',\r\n disabled: !hotkeys.includes('selectAll'),\r\n category: 'Graph',\r\n description: 'Select all nodes and edges',\r\n callback: event => {\r\n event.preventDefault();\r\n\r\n if (!disabled && type !== 'single') {\r\n const next = nodes.map(n => n.id);\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n }\r\n },\r\n {\r\n name: 'Deselect Selections',\r\n category: 'Graph',\r\n disabled: !hotkeys.includes('deselect'),\r\n description: 'Deselect selected nodes and edges',\r\n keys: 'escape',\r\n callback: event => {\r\n if (!disabled) {\r\n event.preventDefault();\r\n onSelection?.([]);\r\n setInternalSelections([]);\r\n }\r\n }\r\n }\r\n ]);\r\n\r\n const joinedActives = useMemo(\r\n () => [...internalActives, ...internalHovers],\r\n [internalActives, internalHovers]\r\n );\r\n\r\n return {\r\n actives: joinedActives,\r\n onNodeClick,\r\n onNodePointerOver,\r\n onNodePointerOut,\r\n onLasso,\r\n onLassoEnd,\r\n selectNodePaths,\r\n onCanvasClick,\r\n selections: internalSelections,\r\n clearSelections,\r\n addSelection,\r\n removeSelection,\r\n toggleSelection,\r\n setSelections: setInternalSelections\r\n };\r\n};\r\n","import React, {\r\n FC,\r\n forwardRef,\r\n ReactNode,\r\n Ref,\r\n Suspense,\r\n useImperativeHandle,\r\n useRef,\r\n useMemo\r\n} from 'react';\r\nimport { Canvas } from '@react-three/fiber';\r\nimport { GraphScene, GraphSceneProps, GraphSceneRef } from './GraphScene';\r\nimport {\r\n CameraMode,\r\n CameraControls,\r\n CameraControlsRef\r\n} from './CameraControls';\r\nimport { Theme, lightTheme } from './themes';\r\nimport { createStore, Provider } from './store';\r\nimport Graph from 'graphology';\r\nimport { Lasso, LassoType } from './selection';\r\nimport ThreeCameraControls from 'camera-controls';\r\nimport css from './GraphCanvas.module.css';\r\n\r\nexport interface GraphCanvasProps extends Omit {\r\n /**\r\n * Theme to use for the graph.\r\n */\r\n theme?: Theme;\r\n\r\n /**\r\n * Type of camera interaction.\r\n */\r\n cameraMode?: CameraMode;\r\n\r\n /**\r\n * The maximum distance for the camera. Default is 50000.\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * The minimum distance for the camera. Default is 1000.\r\n */\r\n minDistance?: number;\r\n\r\n /**\r\n * The type of lasso selection.\r\n */\r\n lassoType?: LassoType;\r\n\r\n /**\r\n * Children to render in the canvas. Useful for things like lights.\r\n */\r\n children?: ReactNode;\r\n\r\n /**\r\n * Ability to extend Cavas gl options. For example { preserveDrawingBuffer: true }\r\n */\r\n glOptions?: Object;\r\n\r\n /**\r\n * When the canvas had a lasso selection.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the canvas had a lasso selection end.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the canvas was clicked but didn't hit a node/edge.\r\n */\r\n onCanvasClick?: (event: MouseEvent) => void;\r\n}\r\n\r\nexport type GraphCanvasRef = Omit &\r\n Omit & {\r\n /**\r\n * Get the graph object.\r\n */\r\n getGraph: () => Graph;\r\n\r\n /**\r\n * Get the camera controls.\r\n */\r\n getControls: () => ThreeCameraControls;\r\n\r\n /**\r\n * Export the canvas as a data URL.\r\n */\r\n exportCanvas: () => string;\r\n };\r\n\r\nconst GL_DEFAULTS = {\r\n alpha: true,\r\n antialias: true\r\n};\r\n\r\n// TODO: Fix type\r\nconst CAMERA_DEFAULTS: any = {\r\n position: [0, 0, 1000],\r\n near: 5,\r\n far: 50000,\r\n fov: 10\r\n};\r\n\r\nexport const GraphCanvas: FC }> =\r\n forwardRef(\r\n (\r\n {\r\n cameraMode,\r\n edges,\r\n children,\r\n nodes,\r\n theme,\r\n minDistance,\r\n maxDistance,\r\n onCanvasClick,\r\n animated,\r\n disabled,\r\n lassoType,\r\n onLasso,\r\n onLassoEnd,\r\n glOptions,\r\n ...rest\r\n },\r\n ref: Ref\r\n ) => {\r\n const rendererRef = useRef(null);\r\n const controlsRef = useRef(null);\r\n const canvasRef = useRef(null);\r\n\r\n useImperativeHandle(ref, () => ({\r\n centerGraph: (nodeIds, opts) =>\r\n rendererRef.current?.centerGraph(nodeIds, opts),\r\n fitNodesInView: (nodeIds, opts) =>\r\n rendererRef.current?.fitNodesInView(nodeIds, opts),\r\n zoomIn: () => controlsRef.current?.zoomIn(),\r\n zoomOut: () => controlsRef.current?.zoomOut(),\r\n dollyIn: distance => controlsRef.current?.dollyIn(distance),\r\n dollyOut: distance => controlsRef.current?.dollyOut(distance),\r\n panLeft: () => controlsRef.current?.panLeft(),\r\n panRight: () => controlsRef.current?.panRight(),\r\n panDown: () => controlsRef.current?.panDown(),\r\n panUp: () => controlsRef.current?.panUp(),\r\n resetControls: (animated?: boolean) =>\r\n controlsRef.current?.resetControls(animated),\r\n getControls: () => controlsRef.current?.controls,\r\n getGraph: () => rendererRef.current?.graph,\r\n exportCanvas: () => {\r\n rendererRef.current.renderScene();\r\n return canvasRef.current.toDataURL();\r\n }\r\n }));\r\n\r\n // Defaults to pass to the store\r\n const { selections, actives, collapsedNodeIds } = rest;\r\n\r\n // It's pretty hard to get good animation performance with large n of edges/nodes\r\n const finalAnimated =\r\n edges.length + nodes.length > 400 ? false : animated;\r\n\r\n const gl = useMemo(() => ({ ...glOptions, ...GL_DEFAULTS }), [glOptions]);\r\n\r\n // NOTE: The legacy/linear/flat flags are for color issues\r\n // Reference: https://github.com/protectwise/troika/discussions/213#discussioncomment-3086666\r\n return (\r\n
\r\n \r\n \r\n createStore({\r\n selections,\r\n actives,\r\n theme,\r\n collapsedNodeIds,\r\n canvasRef: canvasRef.current\r\n })\r\n }\r\n >\r\n {theme.canvas?.background && (\r\n \r\n )}\r\n \r\n {children}\r\n {theme.canvas?.fog && (\r\n \r\n )}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n }\r\n );\r\n\r\nGraphCanvas.defaultProps = {\r\n cameraMode: 'pan',\r\n layoutType: 'forceDirected2d',\r\n sizingType: 'default',\r\n labelType: 'auto',\r\n theme: lightTheme,\r\n animated: true,\r\n defaultNodeSize: 7,\r\n minNodeSize: 5,\r\n maxNodeSize: 15,\r\n lassoType: 'none',\r\n glOptions: {}\r\n};\r\n","import classNames from 'classnames';\r\nimport React, { FC, ReactNode } from 'react';\r\nimport css from './RadialSlice.module.css';\r\n\r\nexport interface MenuItem {\r\n /**\r\n * Label to display on the menu item.\r\n */\r\n label: string;\r\n\r\n /**\r\n * CSS Classname to apply to the slice.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * Optional icon to display on the menu item.\r\n */\r\n icon?: ReactNode;\r\n\r\n /**\r\n * Optional callback to detemine if the menu item is active.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Optional callback to handle when the menu item is clicked.\r\n */\r\n onClick?: (event: React.MouseEvent) => void;\r\n}\r\n\r\ninterface RadialSliceProps extends MenuItem {\r\n /**\r\n * The starting angle of the radial slice, in degrees.\r\n */\r\n startAngle: number;\r\n\r\n /**\r\n * The ending angle of the radial slice, in degrees.\r\n */\r\n endAngle: number;\r\n\r\n /**\r\n * The skew of the radial slice.\r\n */\r\n skew: number;\r\n\r\n /**\r\n * Whether the radial slice is polar (true) or not (false).\r\n */\r\n polar: boolean;\r\n\r\n /**\r\n * The central angle of the radial slice, in degrees.\r\n */\r\n centralAngle: number;\r\n\r\n /**\r\n * The radius of the radial slice.\r\n */\r\n radius: number;\r\n\r\n /**\r\n * The inner radius of the radial slice.\r\n */\r\n innerRadius: number;\r\n}\r\n\r\nexport const RadialSlice: FC = ({\r\n label,\r\n centralAngle,\r\n startAngle,\r\n endAngle,\r\n polar,\r\n radius,\r\n className,\r\n icon,\r\n innerRadius,\r\n skew,\r\n disabled,\r\n onClick\r\n}) => (\r\n 90 ? '100%' : '50%',\r\n height: centralAngle > 90 ? '100%' : '50%',\r\n bottom: centralAngle > 90 ? '50%' : 'initial',\r\n right: centralAngle > 90 ? '50%' : 'initial',\r\n transform: `rotate(${startAngle + endAngle}deg) skew(${skew}deg)`\r\n }}\r\n onClick={event => {\r\n if (!disabled) {\r\n onClick(event);\r\n }\r\n }}\r\n >\r\n \r\n 90 ? '50% + ' : ''\r\n }${radius}px) - ${innerRadius}px) / 2) - 4em)`\r\n }}\r\n >\r\n \r\n {icon}\r\n {label}\r\n \r\n \r\n \r\n \r\n);\r\n","import { MenuItem } from './RadialSlice';\r\n\r\nexport function calculateRadius(items: MenuItem[], startOffsetAngle: number) {\r\n const centralAngle = 360 / items.length || 360;\r\n const polar = centralAngle % 180 === 0;\r\n const deltaAngle = 90 - centralAngle;\r\n const startAngle = polar\r\n ? 45\r\n : startOffsetAngle + deltaAngle + centralAngle / 2;\r\n\r\n return { centralAngle, polar, startAngle, deltaAngle };\r\n}\r\n","import React, { FC, useLayoutEffect, useMemo, useRef } from 'react';\r\nimport { RadialSlice, MenuItem } from './RadialSlice';\r\nimport { calculateRadius } from './utils';\r\nimport css from './RadialMenu.module.css';\r\nimport classNames from 'classnames';\r\n\r\ninterface RadialMenuProps {\r\n /**\r\n * An array of menu items to be displayed in the radial menu.\r\n */\r\n items: MenuItem[];\r\n\r\n /**\r\n * The radius of the radial menu.\r\n */\r\n radius?: number;\r\n\r\n /**\r\n * The inner radius of the radial menu.\r\n */\r\n innerRadius?: number;\r\n\r\n /**\r\n * The starting offset angle for the first menu item.\r\n */\r\n startOffsetAngle?: number;\r\n\r\n /**\r\n * The CSS class name for the radial menu.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * A function that is called when the radial menu is closed.\r\n * The function receives the mouse event that triggered the closure.\r\n */\r\n onClose?: (event: React.MouseEvent) => void;\r\n}\r\n\r\nexport const RadialMenu: FC = ({\r\n items,\r\n radius,\r\n className,\r\n innerRadius,\r\n startOffsetAngle,\r\n onClose\r\n}) => {\r\n const { centralAngle, polar, startAngle, deltaAngle } = useMemo(\r\n () => calculateRadius(items, startOffsetAngle),\r\n [items, startOffsetAngle]\r\n );\r\n const timeout = useRef(null);\r\n\r\n useLayoutEffect(() => {\r\n const timer = timeout.current;\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n if (items.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n clearTimeout(timeout.current)}\r\n onPointerLeave={event => {\r\n clearTimeout(timeout.current);\r\n timeout.current = setTimeout(() => onClose?.(event), 500);\r\n }}\r\n >\r\n {items.map((slice, index) => (\r\n {\r\n slice?.onClick(event);\r\n onClose?.(event);\r\n }}\r\n />\r\n ))}\r\n \r\n );\r\n};\r\n\r\nRadialMenu.defaultProps = {\r\n radius: 175,\r\n innerRadius: 25,\r\n startOffsetAngle: 0\r\n};\r\n"],"names":["d3ForceRadial","tree","nodes","links","a","forceX","forceY","d3ForceX","d3ForceY","d3ForceSimulation","d3ForceCenter","d3ForceLink","d3ForceManyBody","d3ForceZ","_a","_b","n","disabled","theme","actives","selections","id","node","createContext","Sphere","ref","animated","DreiSvg","_c","curve","Edge","arrowPosition","arrowRotation","edge","active","inactive","draggingActive","draggingInactive","edgeMeshes","Fragment","css"],"mappings":"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"} \ No newline at end of file diff --git a/dist/index.umd.cjs b/dist/index.umd.cjs index 7d9432b8..dd004151 100644 --- a/dist/index.umd.cjs +++ b/dist/index.umd.cjs @@ -1933,7 +1933,7 @@ }); const strokeWidthFraction = strokeWidth / 10; const outerRadius = innerRadius + strokeWidthFraction; - return /* @__PURE__ */ jsxRuntime.jsx(glodrei.Billboard, { position: [0, 0, 0], children: /* @__PURE__ */ jsxRuntime.jsxs(three$1.a.mesh, { scale: ringSize, children: [ + return /* @__PURE__ */ jsxRuntime.jsx(glodrei.Billboard, { position: [0, 0, 0], children: /* @__PURE__ */ jsxRuntime.jsxs(three$1.a.mesh, { scale: ringSize, renderOrder: 1, children: [ /* @__PURE__ */ jsxRuntime.jsx( "ringGeometry", { @@ -1947,7 +1947,7 @@ attach: "material", color: normalizedColor, transparent: true, - depthTest: true, + depthTest: false, opacity: ringOpacity, side: three.DoubleSide, fog: true @@ -2003,7 +2003,7 @@ } ) ] }), - (showRing || selected || active) && /* @__PURE__ */ jsxRuntime.jsx(three$1.a.mesh, { position: [0, 0, 1], children: /* @__PURE__ */ jsxRuntime.jsx( + (showRing || selected || active) && /* @__PURE__ */ jsxRuntime.jsx(three$1.a.mesh, { position: [0, 0, 0], children: /* @__PURE__ */ jsxRuntime.jsx( Ring, { opacity: 1, diff --git a/dist/index.umd.cjs.map b/dist/index.umd.cjs.map index 16099515..5002d0db 100644 --- a/dist/index.umd.cjs.map +++ b/dist/index.umd.cjs.map @@ -1 +1 @@ -{"version":3,"file":"index.umd.cjs","sources":["../src/layout/depthUtils.ts","../src/layout/forceUtils.ts","../src/layout/layoutUtils.ts","../src/layout/forceInABox.ts","../src/layout/forceDirected.ts","../src/layout/circular2d.ts","../src/layout/hierarchical.ts","../src/layout/nooverlap.ts","../src/layout/forceatlas2.ts","../src/layout/custom.ts","../src/layout/layoutProvider.ts","../src/layout/recommender.ts","../src/utils/visibility.ts","../src/sizing/pageRank.ts","../src/sizing/centrality.ts","../src/sizing/attribute.ts","../src/sizing/nodeSizeProvider.ts","../src/utils/graph.ts","../src/utils/animation.ts","../src/utils/arrow.ts","../src/utils/position.ts","../src/utils/layout.ts","../src/utils/cluster.ts","../src/utils/useHoverIntent.ts","../src/utils/useDrag.ts","../src/utils/paths.ts","../src/store.ts","../src/collapse/utils.ts","../src/collapse/useCollapse.ts","../src/useGraph.ts","../src/symbols/Label.tsx","../src/symbols/Ring.tsx","../src/symbols/nodes/Sphere.tsx","../src/CameraControls/useCameraControls.ts","../src/CameraControls/CameraControls.tsx","../src/CameraControls/utils.ts","../src/CameraControls/useCenterGraph.ts","../src/symbols/nodes/Icon.tsx","../src/symbols/nodes/SphereWithIcon.tsx","../src/symbols/nodes/Svg.tsx","../src/symbols/nodes/SphereWithSvg.tsx","../src/symbols/Node.tsx","../src/symbols/Arrow.tsx","../src/symbols/Line.tsx","../src/symbols/Edge.tsx","../src/symbols/edges/useEdgeGeometry.ts","../src/symbols/edges/useEdgeEvents.ts","../src/symbols/edges/useEdgeAnimations.ts","../src/symbols/edges/Edge.tsx","../src/symbols/edges/Edges.tsx","../src/symbols/Cluster.tsx","../src/GraphScene.tsx","../src/themes/darkTheme.ts","../src/themes/lightTheme.ts","../src/selection/utils.ts","../src/selection/Lasso.tsx","../src/selection/useSelection.ts","../src/GraphCanvas.tsx","../src/RadialMenu/RadialSlice.tsx","../src/RadialMenu/utils.ts","../src/RadialMenu/RadialMenu.tsx"],"sourcesContent":["import { InternalGraphEdge, InternalGraphNode } from '../types';\r\n\r\nexport interface DepthNode {\r\n data: InternalGraphNode;\r\n ins: DepthNode[];\r\n out: DepthNode[];\r\n depth: number;\r\n}\r\n\r\n/**\r\n * Traverse the graph and get the depth of each node.\r\n */\r\nfunction traverseGraph(nodes: DepthNode[], nodeStack: DepthNode[] = []) {\r\n const currentDepth = nodeStack.length;\r\n\r\n for (const node of nodes) {\r\n const idx = nodeStack.indexOf(node);\r\n if (idx > -1) {\r\n const loop = [...nodeStack.slice(idx), node].map(d => d.data.id);\r\n throw new Error(\r\n `Invalid Graph: Circular node path detected: ${loop.join(' -> ')}.`\r\n );\r\n }\r\n\r\n if (currentDepth > node.depth) {\r\n node.depth = currentDepth;\r\n traverseGraph(node.out, [...nodeStack, node]);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Gets the depth of the graph's nodes. Used in the radial layout.\r\n */\r\nexport function getNodeDepth(\r\n nodes: InternalGraphNode[],\r\n links: InternalGraphEdge[]\r\n) {\r\n let invalid = false;\r\n\r\n const graph: { [key: string]: DepthNode } = nodes.reduce(\r\n (acc, cur) => ({\r\n ...acc,\r\n [cur.id]: {\r\n data: cur,\r\n out: [],\r\n depth: -1,\r\n ins: []\r\n }\r\n }),\r\n {}\r\n );\r\n\r\n try {\r\n for (const link of links) {\r\n const from = link.source;\r\n const to = link.target;\r\n\r\n if (!graph.hasOwnProperty(from)) {\r\n throw new Error(`Missing source Node ${from}`);\r\n }\r\n\r\n if (!graph.hasOwnProperty(to)) {\r\n throw new Error(`Missing target Node ${to}`);\r\n }\r\n\r\n const sourceNode = graph[from];\r\n const targetNode = graph[to];\r\n targetNode.ins.push(sourceNode);\r\n sourceNode.out.push(targetNode);\r\n }\r\n\r\n traverseGraph(Object.values(graph));\r\n } catch (e) {\r\n invalid = true;\r\n }\r\n\r\n const allDepths = Object.keys(graph).map(id => graph[id].depth);\r\n const maxDepth = Math.max(...allDepths);\r\n\r\n return {\r\n invalid,\r\n depths: graph,\r\n maxDepth: maxDepth || 1\r\n };\r\n}\r\n","import { forceRadial as d3ForceRadial } from 'd3-force-3d';\r\nimport { InternalGraphEdge, InternalGraphNode } from 'types';\r\nimport { getNodeDepth } from './depthUtils';\r\n\r\nconst RADIALS: DagMode[] = ['radialin', 'radialout'];\r\n\r\nexport type DagMode =\r\n | 'lr'\r\n | 'rl'\r\n | 'td'\r\n | 'but'\r\n | 'zout'\r\n | 'zin'\r\n | 'radialin'\r\n | 'radialout';\r\n\r\nexport interface ForceRadialInputs {\r\n nodes: InternalGraphNode[];\r\n edges: InternalGraphEdge[];\r\n mode: DagMode;\r\n nodeLevelRatio: number;\r\n}\r\n\r\n/**\r\n * Radial graph layout using D3 Force 3d.\r\n * Inspired by: https://github.com/vasturiano/three-forcegraph/blob/master/src/forcegraph-kapsule.js#L970-L1018\r\n */\r\nexport function forceRadial({\r\n nodes,\r\n edges,\r\n mode = 'lr',\r\n nodeLevelRatio = 2\r\n}: ForceRadialInputs) {\r\n const { depths, maxDepth, invalid } = getNodeDepth(nodes, edges);\r\n\r\n if (invalid) {\r\n return null;\r\n }\r\n\r\n const modeDistance = RADIALS.includes(mode) ? 1 : 5;\r\n const dagLevelDistance =\r\n (nodes.length / maxDepth) * nodeLevelRatio * modeDistance;\r\n\r\n if (mode) {\r\n const getFFn =\r\n (fix: boolean, invert: boolean) => (node: InternalGraphNode) =>\r\n !fix\r\n ? undefined\r\n : (depths[node.id].depth - maxDepth / 2) *\r\n dagLevelDistance *\r\n (invert ? -1 : 1);\r\n\r\n const fxFn = getFFn(['lr', 'rl'].includes(mode), mode === 'rl');\r\n const fyFn = getFFn(['td', 'bu'].includes(mode), mode === 'td');\r\n const fzFn = getFFn(['zin', 'zout'].includes(mode), mode === 'zout');\r\n\r\n nodes.forEach(node => {\r\n node.fx = fxFn(node);\r\n node.fy = fyFn(node);\r\n node.fz = fzFn(node);\r\n });\r\n }\r\n\r\n return RADIALS.includes(mode)\r\n ? d3ForceRadial(node => {\r\n const nodeDepth = depths[node.id];\r\n const depth =\r\n mode === 'radialin' ? maxDepth - nodeDepth.depth : nodeDepth.depth;\r\n return depth * dagLevelDistance;\r\n }).strength(1)\r\n : null;\r\n}\r\n","import Graph from 'graphology';\r\nimport { LayoutStrategy } from './types';\r\nimport { InternalGraphEdge, InternalGraphNode } from '../types';\r\n\r\n/**\r\n * Promise based tick helper.\r\n */\r\nexport function tick(layout: LayoutStrategy) {\r\n return new Promise((resolve, _reject) => {\r\n let stable: boolean | undefined;\r\n\r\n function run() {\r\n if (!stable) {\r\n stable = layout.step();\r\n run();\r\n } else {\r\n resolve(stable);\r\n }\r\n }\r\n\r\n run();\r\n });\r\n}\r\n\r\n/**\r\n * Helper function to turn the graph nodes/edges into an array for\r\n * easier manipulation.\r\n */\r\nexport function buildNodeEdges(graph: Graph) {\r\n const nodes: InternalGraphNode[] = [];\r\n const edges: InternalGraphEdge[] = [];\r\n\r\n graph.forEachNode((id, n: any) => {\r\n nodes.push({\r\n ...n,\r\n id,\r\n // This is for the clustering\r\n radius: n.size || 1\r\n });\r\n });\r\n\r\n graph.forEachEdge((id, l: any) => {\r\n edges.push({ ...l, id });\r\n });\r\n\r\n return { nodes, edges };\r\n}\r\n","import {\r\n forceSimulation,\r\n forceX,\r\n forceY,\r\n forceLink,\r\n forceManyBody,\r\n forceCollide\r\n} from 'd3-force-3d';\r\nimport { treemap, hierarchy } from 'd3-hierarchy';\r\n\r\n/**\r\n * Used for calculating clusterings of nodes.\r\n *\r\n * Modified version of: https://github.com/john-guerra/forceInABox\r\n *\r\n * Changes:\r\n * - Improved d3 import for tree shaking\r\n * - Fixed node lookup for edges using array\r\n * - Updated d3-force to use d3-force-3d\r\n * - Removed template logic\r\n */\r\nexport function forceInABox() {\r\n // d3 style\r\n const constant = (_: any) => () => _;\r\n const index = (d: any) => d.index;\r\n\r\n // Default values\r\n let id = index;\r\n let nodes = [];\r\n let links = []; // needed for the force version\r\n let tree;\r\n let size = [100, 100];\r\n let forceNodeSize = constant(1); // The expected node size used for computing the cluster node\r\n let forceCharge = constant(-1);\r\n let forceLinkDistance = constant(100);\r\n let forceLinkStrength = constant(0.1);\r\n let foci = {};\r\n let linkStrengthIntraCluster = 0.1;\r\n let linkStrengthInterCluster = 0.001;\r\n let templateNodes = [];\r\n let offset = [0, 0];\r\n let templateForce;\r\n let groupBy = d => d.cluster;\r\n let template = 'treemap';\r\n let enableGrouping = true;\r\n let strength = 0.1;\r\n\r\n function force(alpha) {\r\n if (!enableGrouping) {\r\n return force;\r\n }\r\n\r\n if (template === 'force') {\r\n // Do the tick of the template force and get the new focis\r\n templateForce.tick();\r\n getFocisFromTemplate();\r\n }\r\n\r\n for (let i = 0, n = nodes.length, node, k = alpha * strength; i < n; ++i) {\r\n node = nodes[i];\r\n node.vx += (foci[groupBy(node)].x - node.x) * k;\r\n node.vy += (foci[groupBy(node)].y - node.y) * k;\r\n }\r\n }\r\n\r\n function initialize() {\r\n if (!nodes) {\r\n return;\r\n }\r\n\r\n if (template === 'treemap') {\r\n initializeWithTreemap();\r\n } else {\r\n initializeWithForce();\r\n }\r\n }\r\n\r\n force.initialize = function (_) {\r\n nodes = _;\r\n initialize();\r\n };\r\n\r\n function getLinkKey(l) {\r\n let sourceID = groupBy(l.source),\r\n targetID = groupBy(l.target);\r\n\r\n return sourceID <= targetID\r\n ? sourceID + '~' + targetID\r\n : targetID + '~' + sourceID;\r\n }\r\n\r\n function computeClustersNodeCounts(nodes) {\r\n let clustersCounts = new Map(),\r\n tmpCount: any = {};\r\n\r\n nodes.forEach(function (d) {\r\n if (!clustersCounts.has(groupBy(d))) {\r\n clustersCounts.set(groupBy(d), { count: 0, sumforceNodeSize: 0 });\r\n }\r\n });\r\n\r\n nodes.forEach(function (d) {\r\n tmpCount = clustersCounts.get(groupBy(d));\r\n tmpCount.count = tmpCount.count + 1;\r\n tmpCount.sumforceNodeSize =\r\n tmpCount.sumforceNodeSize +\r\n // @ts-ignore\r\n Math.PI * (forceNodeSize(d) * forceNodeSize(d)) * 1.3;\r\n clustersCounts.set(groupBy(d), tmpCount);\r\n });\r\n\r\n return clustersCounts;\r\n }\r\n\r\n //Returns\r\n function computeClustersLinkCounts(links) {\r\n let dClusterLinks = new Map(),\r\n clusterLinks = [];\r\n\r\n links.forEach(function (l) {\r\n let key = getLinkKey(l),\r\n count;\r\n if (dClusterLinks.has(key)) {\r\n count = dClusterLinks.get(key);\r\n } else {\r\n count = 0;\r\n }\r\n count += 1;\r\n dClusterLinks.set(key, count);\r\n });\r\n\r\n dClusterLinks.forEach(function (value, key) {\r\n let source, target;\r\n source = key.split('~')[0];\r\n target = key.split('~')[1];\r\n if (source !== undefined && target !== undefined) {\r\n clusterLinks.push({\r\n source: source,\r\n target: target,\r\n count: value\r\n });\r\n }\r\n });\r\n\r\n return clusterLinks;\r\n }\r\n\r\n //Returns the metagraph of the clusters\r\n function getGroupsGraph() {\r\n let gnodes = [];\r\n let glinks = [];\r\n let dNodes = new Map();\r\n let c;\r\n let i;\r\n let cc;\r\n let clustersCounts;\r\n let clustersLinks;\r\n\r\n clustersCounts = computeClustersNodeCounts(nodes);\r\n clustersLinks = computeClustersLinkCounts(links);\r\n\r\n for (c of clustersCounts.keys()) {\r\n cc = clustersCounts.get(c);\r\n gnodes.push({\r\n id: c,\r\n size: cc.count,\r\n r: Math.sqrt(cc.sumforceNodeSize / Math.PI)\r\n }); // Uses approx meta-node size\r\n dNodes.set(c, i);\r\n }\r\n\r\n clustersLinks.forEach(function (l) {\r\n let source = dNodes.get(l.source),\r\n target = dNodes.get(l.target);\r\n if (source !== undefined && target !== undefined) {\r\n glinks.push({\r\n source: source,\r\n target: target,\r\n count: l.count\r\n });\r\n }\r\n });\r\n\r\n return { nodes: gnodes, links: glinks };\r\n }\r\n\r\n function getGroupsTree() {\r\n let children = [];\r\n let c;\r\n let cc;\r\n let clustersCounts;\r\n\r\n // @ts-ignore\r\n clustersCounts = computeClustersNodeCounts(force.nodes());\r\n\r\n for (c of clustersCounts.keys()) {\r\n cc = clustersCounts.get(c);\r\n children.push({ id: c, size: cc.count });\r\n }\r\n return { id: 'clustersTree', children: children };\r\n }\r\n\r\n function getFocisFromTemplate() {\r\n //compute foci\r\n // @ts-ignore\r\n foci.none = { x: 0, y: 0 };\r\n templateNodes.forEach(function (d) {\r\n if (template === 'treemap') {\r\n foci[d.data.id] = {\r\n x: d.x0 + (d.x1 - d.x0) / 2 - offset[0],\r\n y: d.y0 + (d.y1 - d.y0) / 2 - offset[1]\r\n };\r\n } else {\r\n foci[d.id] = {\r\n x: d.x - offset[0],\r\n y: d.y - offset[1]\r\n };\r\n }\r\n });\r\n return foci;\r\n }\r\n\r\n function initializeWithTreemap() {\r\n // @ts-ignore\r\n let sim = treemap().size(force.size());\r\n\r\n tree = hierarchy(getGroupsTree())\r\n .sum((d: any) => d.radius)\r\n .sort(function (a, b) {\r\n return b.height - a.height || b.value - a.value;\r\n });\r\n\r\n templateNodes = sim(tree).leaves();\r\n getFocisFromTemplate();\r\n }\r\n\r\n function checkLinksAsObjects() {\r\n // Check if links come in the format of indexes instead of objects\r\n let linkCount = 0;\r\n if (nodes.length === 0) return;\r\n\r\n links.forEach(function (link) {\r\n let source, target;\r\n if (!nodes) {\r\n return;\r\n }\r\n\r\n source = link.source;\r\n target = link.target;\r\n\r\n if (typeof link.source !== 'object') {\r\n source = nodes.find(n => n.id === link.source);\r\n }\r\n\r\n if (typeof link.target !== 'object') {\r\n target = nodes.find(n => n.id === link.target);\r\n }\r\n\r\n if (source === undefined || target === undefined) {\r\n throw Error(\r\n 'Error setting links, couldnt find nodes for a link (see it on the console)'\r\n );\r\n }\r\n link.source = source;\r\n link.target = target;\r\n link.index = linkCount++;\r\n });\r\n }\r\n\r\n function initializeWithForce() {\r\n let net;\r\n\r\n if (!nodes || !nodes.length) {\r\n return;\r\n }\r\n\r\n checkLinksAsObjects();\r\n\r\n net = getGroupsGraph();\r\n templateForce = forceSimulation(net.nodes)\r\n .force('x', forceX(size[0] / 2).strength(0.1))\r\n .force('y', forceY(size[1] / 2).strength(0.1))\r\n .force('collide', forceCollide(d => d.r).iterations(4))\r\n .force('charge', forceManyBody().strength(forceCharge))\r\n .force(\r\n 'links',\r\n forceLink(net.nodes.length ? net.links : [])\r\n .distance(forceLinkDistance)\r\n .strength(forceLinkStrength)\r\n );\r\n\r\n templateNodes = templateForce.nodes();\r\n\r\n getFocisFromTemplate();\r\n }\r\n\r\n force.template = function (x) {\r\n if (!arguments.length) {\r\n return template;\r\n }\r\n\r\n template = x;\r\n initialize();\r\n return force;\r\n };\r\n\r\n force.groupBy = function (x) {\r\n if (!arguments.length) {\r\n return groupBy;\r\n }\r\n\r\n if (typeof x === 'string') {\r\n groupBy = function (d) {\r\n return d[x];\r\n };\r\n\r\n return force;\r\n }\r\n\r\n groupBy = x;\r\n\r\n return force;\r\n };\r\n\r\n force.enableGrouping = function (x) {\r\n if (!arguments.length) {\r\n return enableGrouping;\r\n }\r\n\r\n enableGrouping = x;\r\n\r\n return force;\r\n };\r\n\r\n force.strength = function (x) {\r\n if (!arguments.length) {\r\n return strength;\r\n }\r\n\r\n strength = x;\r\n\r\n return force as any;\r\n };\r\n\r\n force.getLinkStrength = function (e) {\r\n if (enableGrouping) {\r\n if (groupBy(e.source) === groupBy(e.target)) {\r\n if (typeof linkStrengthIntraCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthIntraCluster(e);\r\n } else {\r\n return linkStrengthIntraCluster;\r\n }\r\n } else {\r\n if (typeof linkStrengthInterCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthInterCluster(e);\r\n } else {\r\n return linkStrengthInterCluster;\r\n }\r\n }\r\n } else {\r\n // Not grouping return the intracluster\r\n if (typeof linkStrengthIntraCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthIntraCluster(e);\r\n } else {\r\n return linkStrengthIntraCluster;\r\n }\r\n }\r\n };\r\n\r\n force.id = function (_) {\r\n return arguments.length ? ((id = _), force) : id;\r\n };\r\n\r\n force.size = function (_) {\r\n return arguments.length ? ((size = _), force) : size;\r\n };\r\n\r\n force.linkStrengthInterCluster = function (_) {\r\n return arguments.length\r\n ? ((linkStrengthInterCluster = _), force)\r\n : linkStrengthInterCluster;\r\n };\r\n\r\n force.linkStrengthIntraCluster = function (_) {\r\n return arguments.length\r\n ? ((linkStrengthIntraCluster = _), force)\r\n : linkStrengthIntraCluster;\r\n };\r\n\r\n force.nodes = function (_) {\r\n return arguments.length ? ((nodes = _), force) : nodes;\r\n };\r\n\r\n force.links = function (_) {\r\n if (!arguments.length) {\r\n return links;\r\n }\r\n\r\n if (_ === null) {\r\n links = [];\r\n } else {\r\n links = _;\r\n }\r\n\r\n initialize();\r\n\r\n return force;\r\n };\r\n\r\n force.template = function (x) {\r\n if (!arguments.length) {\r\n return template;\r\n }\r\n\r\n template = x;\r\n initialize();\r\n return force;\r\n };\r\n\r\n force.forceNodeSize = function (_) {\r\n return arguments.length\r\n ? ((forceNodeSize = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceNodeSize;\r\n };\r\n\r\n // Legacy support\r\n force.nodeSize = force.forceNodeSize;\r\n\r\n force.forceCharge = function (_) {\r\n return arguments.length\r\n ? ((forceCharge = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceCharge;\r\n };\r\n\r\n force.forceLinkDistance = function (_) {\r\n return arguments.length\r\n ? ((forceLinkDistance = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceLinkDistance;\r\n };\r\n\r\n force.forceLinkStrength = function (_) {\r\n return arguments.length\r\n ? ((forceLinkStrength = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceLinkStrength;\r\n };\r\n\r\n force.offset = function (_) {\r\n return arguments.length\r\n ? ((offset = typeof _ === 'function' ? _ : constant(+_)), force)\r\n : offset;\r\n };\r\n\r\n force.getFocis = getFocisFromTemplate;\r\n\r\n return force;\r\n}\r\n","import {\r\n forceSimulation as d3ForceSimulation,\r\n forceLink as d3ForceLink,\r\n forceCollide,\r\n forceManyBody as d3ForceManyBody,\r\n forceX as d3ForceX,\r\n forceY as d3ForceY,\r\n forceZ as d3ForceZ,\r\n forceCenter as d3ForceCenter\r\n} from 'd3-force-3d';\r\nimport { forceRadial, DagMode } from './forceUtils';\r\nimport { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\nimport { forceInABox } from './forceInABox';\r\nimport { FORCE_LAYOUTS } from './layoutProvider';\r\n\r\nexport interface ForceDirectedLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Center inertia for the layout. Default: 1.\r\n */\r\n centerInertia?: number;\r\n\r\n /**\r\n * Number of dimensions for the layout. 2d or 3d.\r\n */\r\n dimensions?: number;\r\n\r\n /**\r\n * Mode for the dag layout. Only applicable for dag layouts.\r\n */\r\n mode?: DagMode;\r\n\r\n /**\r\n * Distance between links.\r\n */\r\n linkDistance?: number;\r\n\r\n /**\r\n * Strength of the node repulsion.\r\n */\r\n nodeStrength?: number;\r\n\r\n /**\r\n * Strength of the cluster repulsion.\r\n */\r\n clusterStrength?: number;\r\n\r\n /**\r\n * The type of clustering.\r\n */\r\n clusterType?: 'force' | 'treemap';\r\n\r\n /**\r\n * Ratio of the distance between nodes on the same level.\r\n */\r\n nodeLevelRatio?: number;\r\n\r\n /**\r\n * LinkStrength between nodes of different clusters\r\n */\r\n linkStrengthInterCluster?: number | ((d: any) => number);\r\n\r\n /**\r\n * LinkStrength between nodes of the same cluster\r\n */\r\n linkStrengthIntraCluster?: number | ((d: any) => number);\r\n\r\n /**\r\n * Charge between the meta-nodes (Force template only)\r\n */\r\n forceLinkDistance?: number;\r\n\r\n /**\r\n * Used to compute the template force nodes size (Force template only)\r\n */\r\n forceLinkStrength?: number;\r\n\r\n /**\r\n * Used to compute the template force nodes size (Force template only)\r\n */\r\n forceCharge?: number;\r\n\r\n /**\r\n * Used to determine the simulation forceX and forceY values\r\n */\r\n forceLayout: (typeof FORCE_LAYOUTS)[number];\r\n}\r\n\r\nexport function forceDirected({\r\n graph,\r\n nodeLevelRatio = 2,\r\n mode = null,\r\n dimensions = 2,\r\n nodeStrength = -250,\r\n linkDistance = 100,\r\n clusterStrength = 0.5,\r\n linkStrengthInterCluster = 0.01,\r\n linkStrengthIntraCluster = 0.5,\r\n forceLinkDistance = 100,\r\n forceLinkStrength = 0.1,\r\n clusterType = 'force',\r\n forceCharge = -700,\r\n getNodePosition,\r\n drags,\r\n clusterAttribute,\r\n forceLayout\r\n}: ForceDirectedLayoutInputs): LayoutStrategy {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n // Dynamically adjust node strength based on the number of edges\r\n const is2d = dimensions === 2;\r\n const nodeStrengthAdjustment =\r\n is2d && edges.length > 25 ? nodeStrength * 2 : nodeStrength;\r\n\r\n let forceX;\r\n let forceY;\r\n if (forceLayout === 'forceDirected2d') {\r\n forceX = d3ForceX();\r\n forceY = d3ForceY();\r\n } else {\r\n forceX = d3ForceX(600).strength(0.05);\r\n forceY = d3ForceY(600).strength(0.05);\r\n }\r\n\r\n // Create the simulation\r\n const sim = d3ForceSimulation()\r\n .force('center', d3ForceCenter(0, 0))\r\n .force('link', d3ForceLink())\r\n .force('charge', d3ForceManyBody().strength(nodeStrengthAdjustment))\r\n .force('x', forceX)\r\n .force('y', forceY)\r\n .force('z', d3ForceZ())\r\n // Handles nodes not overlapping each other ( most relevant in clustering )\r\n .force(\r\n 'collide',\r\n forceCollide(d => d.radius + 10)\r\n )\r\n .force(\r\n 'dagRadial',\r\n forceRadial({\r\n nodes,\r\n edges,\r\n mode,\r\n nodeLevelRatio\r\n })\r\n )\r\n .stop();\r\n\r\n let groupingForce;\r\n if (clusterAttribute) {\r\n // Dynamically adjust cluster force charge based on the number of nodes\r\n let forceChargeAdjustment = forceCharge;\r\n if (nodes?.length) {\r\n const adjustmentFactor = Math.ceil(nodes.length / 200);\r\n forceChargeAdjustment = forceCharge * adjustmentFactor;\r\n }\r\n\r\n groupingForce = forceInABox()\r\n // Strength to foci\r\n .strength(clusterStrength)\r\n // Either treemap or force\r\n .template(clusterType)\r\n // Node attribute to group\r\n .groupBy(d => d.data[clusterAttribute])\r\n // The graph links. Must be called after setting the grouping attribute\r\n .links(edges)\r\n // Size of the chart\r\n .size([100, 100])\r\n // linkStrength between nodes of different clusters\r\n .linkStrengthInterCluster(linkStrengthInterCluster)\r\n // linkStrength between nodes of the same cluster\r\n .linkStrengthIntraCluster(linkStrengthIntraCluster)\r\n // linkDistance between meta-nodes on the template (Force template only)\r\n .forceLinkDistance(forceLinkDistance)\r\n // linkStrength between meta-nodes of the template (Force template only)\r\n .forceLinkStrength(forceLinkStrength)\r\n // Charge between the meta-nodes (Force template only)\r\n .forceCharge(forceChargeAdjustment)\r\n // Used to compute the template force nodes size (Force template only)\r\n .forceNodeSize(d => d.radius);\r\n }\r\n\r\n // Initialize the simulation\r\n let layout = sim.numDimensions(dimensions).nodes(nodes);\r\n\r\n if (groupingForce) {\r\n layout = layout.force('group', groupingForce);\r\n }\r\n\r\n // Run the force on the links\r\n if (linkDistance) {\r\n let linkForce = layout.force('link');\r\n if (linkForce) {\r\n linkForce\r\n .id(d => d.id)\r\n .links(edges)\r\n // When no mode passed, its a tree layout\r\n // so let's use a larger distance\r\n .distance(linkDistance);\r\n\r\n if (groupingForce) {\r\n linkForce = linkForce.strength(groupingForce?.getLinkStrength ?? 0.1);\r\n }\r\n }\r\n }\r\n\r\n const nodeMap = new Map(nodes.map(n => [n.id, n]));\r\n\r\n return {\r\n step() {\r\n // Run the simulation til we get a stable result\r\n while (sim.alpha() > 0.01) {\r\n sim.tick();\r\n }\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return nodeMap.get(id);\r\n }\r\n };\r\n}\r\n","import circular from 'graphology-layout/circular.js';\r\nimport { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface CircularLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Radius of the circle.\r\n */\r\n radius: 300;\r\n}\r\n\r\nexport function circular2d({\r\n graph,\r\n radius,\r\n drags,\r\n getNodePosition\r\n}: CircularLayoutInputs) {\r\n const layout = circular(graph, {\r\n scale: radius\r\n });\r\n\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return layout?.[id];\r\n }\r\n };\r\n}\r\n","import { InternalGraphEdge, InternalGraphNode } from 'types';\r\nimport { DepthNode, getNodeDepth } from './depthUtils';\r\nimport { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { hierarchy, stratify, tree } from 'd3-hierarchy';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface HierarchicalLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Direction of the layout. Default 'td'.\r\n */\r\n mode?: 'td' | 'lr';\r\n /**\r\n * Factor of distance between nodes. Default 1.\r\n */\r\n nodeSeparation?: number;\r\n /**\r\n * Size of each node. Default [50,50]\r\n */\r\n nodeSize?: [number, number];\r\n}\r\n\r\nconst DIRECTION_MAP = {\r\n td: {\r\n x: 'x',\r\n y: 'y',\r\n factor: -1\r\n },\r\n lr: {\r\n x: 'y',\r\n y: 'x',\r\n factor: 1\r\n }\r\n};\r\n\r\nexport function hierarchical({\r\n graph,\r\n drags,\r\n mode = 'td',\r\n nodeSeparation = 2,\r\n nodeSize = [60, 60],\r\n getNodePosition\r\n}: HierarchicalLayoutInputs): LayoutStrategy {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n // find root node by finding the nodes which have no incoming edges\r\n const parentNodes = nodes.filter(n => !edges.find(e => e.target === n.id));\r\n console.log('parentNodes', parentNodes);\r\n\r\n // if more than 1 root node, then we have multiple trees\r\n // insert a fake root node to connect all root nodes\r\n if (parentNodes.length > 1) {\r\n const fakeRootNode: InternalGraphNode = {\r\n id: 'fakeRoot',\r\n label: '',\r\n fill: '#fff',\r\n activeFill: '#fff',\r\n icon: '',\r\n data: {\r\n id: 'fakeRoot',\r\n loaded: true,\r\n extra: {\r\n id: 'fakeRoot',\r\n properties: {},\r\n labels: []\r\n },\r\n className: '',\r\n style: {\r\n label: ''\r\n }\r\n },\r\n position: {\r\n id: '',\r\n data: {},\r\n links: [],\r\n index: 0,\r\n x: 0,\r\n y: 0,\r\n z: 0,\r\n vx: 0,\r\n vy: 0\r\n }\r\n };\r\n\r\n // add fake root node to nodes\r\n nodes.push(fakeRootNode);\r\n\r\n // add edges from fake root to root nodes\r\n parentNodes.forEach(n => {\r\n edges.push({\r\n id: `fakeRoot-${n.id}`,\r\n source: 'fakeRoot',\r\n target: n.id,\r\n label: '',\r\n backgroundColor: '#fff'\r\n });\r\n });\r\n }\r\n\r\n const { depths } = getNodeDepth(nodes, edges);\r\n const rootNodes = Object.keys(depths).map(d => depths[d]);\r\n\r\n const root = stratify()\r\n .id(d => d.data.id)\r\n .parentId(d => d.ins?.[0]?.data?.id)(rootNodes);\r\n\r\n const treeRoot = tree()\r\n .separation(() => nodeSeparation)\r\n .nodeSize(nodeSize)(hierarchy(root));\r\n\r\n const treeNodes = treeRoot.descendants();\r\n const path = DIRECTION_MAP[mode];\r\n\r\n const mappedNodes = new Map(\r\n nodes.map(n => {\r\n const { x, y } = treeNodes.find((t: any) => t.data.id === n.id);\r\n return [\r\n n.id,\r\n {\r\n ...n,\r\n [path.x]: x * path.factor,\r\n [path.y]: y * path.factor,\r\n z: 0\r\n }\r\n ];\r\n })\r\n );\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return mappedNodes.get(id);\r\n }\r\n };\r\n}\r\n","import noverlapLayout from 'graphology-layout-noverlap';\r\nimport { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface NoOverlapLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Grid size. Default 20.\r\n */\r\n gridSize?: number;\r\n\r\n /**\r\n * Ratio of the layout. Default 10.\r\n */\r\n ratio?: number;\r\n\r\n /**\r\n * Maximum number of iterations. Default 50.\r\n */\r\n maxIterations?: number;\r\n\r\n /**\r\n * Margin between nodes. Default 10.\r\n */\r\n margin?: number;\r\n}\r\n\r\nexport function nooverlap({\r\n graph,\r\n margin,\r\n drags,\r\n getNodePosition,\r\n ratio,\r\n gridSize,\r\n maxIterations\r\n}: NoOverlapLayoutInputs) {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n const layout = noverlapLayout(graph, {\r\n maxIterations,\r\n inputReducer: (_key, attr) => ({\r\n ...attr,\r\n // Have to specify defaults for the engine\r\n x: attr.x || 0,\r\n y: attr.y || 0\r\n }),\r\n settings: {\r\n ratio,\r\n margin,\r\n gridSize\r\n }\r\n });\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return layout?.[id];\r\n }\r\n };\r\n}\r\n","import forceAtlas2Layout from 'graphology-layout-forceatlas2';\r\nimport { LayoutFactoryProps } from './types';\r\nimport random from 'graphology-layout/random.js';\r\n\r\nexport interface ForceAtlas2LayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Should the node’s sizes be taken into account. Default: false.\r\n */\r\n adjustSizes?: boolean;\r\n\r\n /**\r\n * whether to use the Barnes-Hut approximation to compute\r\n * repulsion in O(n*log(n)) rather than default O(n^2),\r\n * n being the number of nodes. Default: false.\r\n */\r\n barnesHutOptimize?: boolean;\r\n\r\n /**\r\n * Barnes-Hut approximation theta parameter. Default: 0.5.\r\n */\r\n barnesHutTheta?: number;\r\n\r\n /**\r\n * Influence of the edge’s weights on the layout. To consider edge weight, don’t\r\n * forget to pass weighted as true. Default: 1.\r\n */\r\n edgeWeightInfluence?: number;\r\n\r\n /**\r\n * Strength of the layout’s gravity. Default: 10.\r\n */\r\n gravity?: number;\r\n\r\n /**\r\n * Whether to use Noack’s LinLog model. Default: false.\r\n */\r\n linLogMode?: boolean;\r\n\r\n /**\r\n * Whether to consider edge weights when calculating repulsion. Default: false.\r\n */\r\n outboundAttractionDistribution?: boolean;\r\n\r\n /**\r\n * Scaling ratio for repulsion. Default: 100.\r\n */\r\n scalingRatio?: number;\r\n\r\n /**\r\n * Speed of the slowdown. Default: 1.\r\n */\r\n slowDown?: number;\r\n\r\n /**\r\n * Whether to use the strong gravity mode. Default: false.\r\n */\r\n strongGravityMode?: boolean;\r\n\r\n /**\r\n * Number of iterations to perform. Default: 50.\r\n */\r\n iterations?: number;\r\n}\r\n\r\nexport function forceAtlas2({\r\n graph,\r\n drags,\r\n iterations,\r\n ...rest\r\n}: ForceAtlas2LayoutInputs) {\r\n // Note: We need to assign a random position to each node\r\n // in order for the force atlas to work.\r\n // Reference: https://graphology.github.io/standard-library/layout-forceatlas2.html#pre-requisites\r\n random.assign(graph);\r\n\r\n const layout = forceAtlas2Layout(graph, {\r\n iterations,\r\n settings: rest\r\n });\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n // If we dragged, we need to use that position\r\n return (drags?.[id]?.position as any) || layout?.[id];\r\n }\r\n };\r\n}\r\n","import { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport function custom({ graph, drags, getNodePosition }: LayoutFactoryProps) {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n return getNodePosition(id, { graph, drags, nodes, edges });\r\n }\r\n };\r\n}\r\n","import { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { forceDirected, ForceDirectedLayoutInputs } from './forceDirected';\r\nimport { circular2d, CircularLayoutInputs } from './circular2d';\r\nimport { hierarchical, HierarchicalLayoutInputs } from './hierarchical';\r\nimport { NoOverlapLayoutInputs, nooverlap } from './nooverlap';\r\nimport { ForceAtlas2LayoutInputs, forceAtlas2 } from './forceatlas2';\r\nimport { custom } from './custom';\r\n\r\nexport type LayoutOverrides = Partial<\r\n | Omit\r\n | CircularLayoutInputs\r\n | HierarchicalLayoutInputs\r\n>;\r\n\r\nexport const FORCE_LAYOUTS = [\r\n 'forceDirected2d',\r\n 'treeTd2d',\r\n 'treeLr2d',\r\n 'radialOut2d',\r\n 'treeTd3d',\r\n 'treeLr3d',\r\n 'radialOut3d',\r\n 'forceDirected3d'\r\n];\r\n\r\nexport function layoutProvider({\r\n type,\r\n ...rest\r\n}: LayoutFactoryProps | LayoutOverrides): LayoutStrategy {\r\n if (FORCE_LAYOUTS.includes(type)) {\r\n const { nodeStrength, linkDistance, nodeLevelRatio } =\r\n rest as ForceDirectedLayoutInputs;\r\n\r\n if (type === 'forceDirected2d') {\r\n return forceDirected({\r\n ...rest,\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeTd2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'td',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeLr2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'lr',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'radialOut2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'radialout',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 100,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeTd3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'td',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 50\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeLr3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'lr',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'radialOut3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'radialout',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 100,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'forceDirected3d') {\r\n return forceDirected({\r\n ...rest,\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n }\r\n } else if (type === 'circular2d') {\r\n const { radius } = rest as CircularLayoutInputs;\r\n return circular2d({\r\n ...rest,\r\n radius: radius || 300\r\n } as CircularLayoutInputs);\r\n } else if (type === 'hierarchicalTd') {\r\n return hierarchical({ ...rest, mode: 'td' } as HierarchicalLayoutInputs);\r\n } else if (type === 'hierarchicalLr') {\r\n return hierarchical({ ...rest, mode: 'lr' } as HierarchicalLayoutInputs);\r\n } else if (type === 'nooverlap') {\r\n const { graph, maxIterations, ratio, margin, gridSize, ...settings } =\r\n rest as NoOverlapLayoutInputs;\r\n\r\n return nooverlap({\r\n type: 'nooverlap',\r\n graph,\r\n margin: margin || 10,\r\n maxIterations: maxIterations || 50,\r\n ratio: ratio || 10,\r\n gridSize: gridSize || 20,\r\n ...settings\r\n });\r\n } else if (type === 'forceatlas2') {\r\n const { graph, iterations, gravity, scalingRatio, ...settings } =\r\n rest as ForceAtlas2LayoutInputs;\r\n\r\n return forceAtlas2({\r\n type: 'forceatlas2',\r\n graph,\r\n ...settings,\r\n scalingRatio: scalingRatio || 100,\r\n gravity: gravity || 10,\r\n iterations: iterations || 50\r\n });\r\n } else if (type === 'custom') {\r\n return custom({\r\n type: 'custom',\r\n ...rest\r\n } as LayoutFactoryProps);\r\n }\r\n\r\n throw new Error(`Layout ${type} not found.`);\r\n}\r\n","import { GraphEdge, GraphNode } from '../types';\r\nimport { getNodeDepth } from './depthUtils';\r\nimport { LayoutTypes } from './types';\r\n\r\n/**\r\n * Given a set of nodes and edges, determine the type of layout that\r\n * is most ideal. This is very beta.\r\n */\r\nexport function recommendLayout(\r\n nodes: GraphNode[],\r\n edges: GraphEdge[]\r\n): LayoutTypes {\r\n const { invalid } = getNodeDepth(nodes as any[], edges as any[]);\r\n const nodeCount = nodes.length;\r\n\r\n if (!invalid) {\r\n // Large tree layouts\r\n if (nodeCount > 100) {\r\n return 'radialOut2d';\r\n } else {\r\n // Smaller tree layouts\r\n return 'treeTd2d';\r\n }\r\n }\r\n\r\n // Circular layouts\r\n return 'forceDirected2d';\r\n}\r\n","import { PerspectiveCamera } from 'three';\r\nimport { EdgeLabelPosition } from '../symbols';\r\n\r\nexport type LabelVisibilityType = 'all' | 'auto' | 'none' | 'nodes' | 'edges';\r\n\r\ninterface CalcLabelVisibilityArgs {\r\n nodeCount: number;\r\n nodePosition?: { x: number; y: number; z: number };\r\n labelType: LabelVisibilityType;\r\n camera?: PerspectiveCamera;\r\n}\r\n\r\nexport function calcLabelVisibility({\r\n nodeCount,\r\n nodePosition,\r\n labelType,\r\n camera\r\n}: CalcLabelVisibilityArgs) {\r\n return (shape: 'node' | 'edge', size: number) => {\r\n if (\r\n camera &&\r\n nodePosition &&\r\n camera?.position?.z / camera?.zoom - nodePosition?.z > 6000\r\n ) {\r\n return false;\r\n }\r\n\r\n if (labelType === 'all') {\r\n return true;\r\n } else if (labelType === 'nodes' && shape === 'node') {\r\n return true;\r\n } else if (labelType === 'edges' && shape === 'edge') {\r\n return true;\r\n } else if (labelType === 'auto' && shape === 'node') {\r\n if (size > 7) {\r\n return true;\r\n } else if (\r\n camera &&\r\n nodePosition &&\r\n camera.position.z / camera.zoom - nodePosition.z < 3000\r\n ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n}\r\n\r\nexport function getLabelOffsetByType(\r\n offset: number,\r\n position: EdgeLabelPosition\r\n): number {\r\n switch (position) {\r\n case 'above':\r\n return offset;\r\n case 'below':\r\n return -offset;\r\n case 'inline':\r\n case 'natural':\r\n default:\r\n return 0;\r\n }\r\n}\r\n","import pagerank from 'graphology-metrics/centrality/pagerank.js';\r\nimport { SizingStrategy, SizingStrategyInputs } from './types';\r\n\r\nexport function pageRankSizing({\r\n graph\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const ranks = pagerank(graph);\r\n\r\n return {\r\n ranks,\r\n getSizeForNode: (nodeID: string) => ranks[nodeID] * 80\r\n };\r\n}\r\n","import { SizingStrategy, SizingStrategyInputs } from './types';\r\nimport { degreeCentrality } from 'graphology-metrics/centrality/degree.js';\r\n\r\nexport function centralitySizing({\r\n graph\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const ranks = degreeCentrality(graph);\r\n\r\n return {\r\n ranks,\r\n getSizeForNode: (nodeID: string) => ranks[nodeID] * 20\r\n };\r\n}\r\n","import { SizingStrategy, SizingStrategyInputs } from './types';\r\n\r\nexport function attributeSizing({\r\n graph,\r\n attribute,\r\n defaultSize\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const map = new Map();\r\n\r\n if (attribute) {\r\n graph.forEachNode((id, node) => {\r\n const size = node.data?.[attribute];\r\n if (isNaN(size)) {\r\n console.warn(`Attribute ${size} is not a number for node ${node.id}`);\r\n }\r\n\r\n map.set(id, size || 0);\r\n });\r\n } else {\r\n console.warn('Attribute sizing configured but no attribute provided');\r\n }\r\n\r\n return {\r\n getSizeForNode: (nodeId: string) => {\r\n if (!attribute || !map) {\r\n return defaultSize;\r\n }\r\n\r\n return map.get(nodeId);\r\n }\r\n };\r\n}\r\n","import { pageRankSizing } from './pageRank';\r\nimport { centralitySizing } from './centrality';\r\nimport { attributeSizing } from './attribute';\r\nimport { SizingStrategyInputs } from './types';\r\nimport { scaleLinear } from 'd3-scale';\r\n\r\nexport type SizingType =\r\n | 'none'\r\n | 'pagerank'\r\n | 'centrality'\r\n | 'attribute'\r\n | 'default';\r\n\r\nexport interface NodeSizeProviderInputs extends SizingStrategyInputs {\r\n /**\r\n * The sizing strategy to use.\r\n */\r\n type: SizingType;\r\n}\r\n\r\nconst providers = {\r\n pagerank: pageRankSizing,\r\n centrality: centralitySizing,\r\n attribute: attributeSizing,\r\n none: ({ defaultSize }: SizingStrategyInputs) => ({\r\n getSizeForNode: (_id: string) => defaultSize\r\n })\r\n};\r\n\r\nexport function nodeSizeProvider({ type, ...rest }: NodeSizeProviderInputs) {\r\n const provider = providers[type]?.(rest);\r\n if (!provider && type !== 'default') {\r\n throw new Error(`Unknown sizing strategy: ${type}`);\r\n }\r\n\r\n const { graph, minSize, maxSize } = rest;\r\n const sizes = new Map();\r\n let min;\r\n let max;\r\n\r\n graph.forEachNode((id, node) => {\r\n let size;\r\n if (type === 'default') {\r\n size = node.size || rest.defaultSize;\r\n } else {\r\n size = provider.getSizeForNode(id);\r\n }\r\n\r\n if (min === undefined || size < min) {\r\n min = size;\r\n }\r\n\r\n if (max === undefined || size > max) {\r\n max = size;\r\n }\r\n\r\n sizes.set(id, size);\r\n });\r\n\r\n // Relatively scale the sizes\r\n if (type !== 'none') {\r\n const scale = scaleLinear()\r\n .domain([min, max])\r\n .rangeRound([minSize, maxSize]);\r\n\r\n for (const [nodeId, size] of sizes) {\r\n sizes.set(nodeId, scale(size));\r\n }\r\n }\r\n\r\n return sizes;\r\n}\r\n","import Graph from 'graphology';\r\nimport { nodeSizeProvider, SizingType } from '../sizing';\r\nimport {\r\n GraphEdge,\r\n GraphNode,\r\n InternalGraphEdge,\r\n InternalGraphNode\r\n} from '../types';\r\nimport { calcLabelVisibility, LabelVisibilityType } from './visibility';\r\nimport { LayoutStrategy } from '../layout';\r\n\r\n/**\r\n * Initialize the graph with the nodes/edges.\r\n */\r\nexport function buildGraph(\r\n graph: Graph,\r\n nodes: GraphNode[],\r\n edges: GraphEdge[]\r\n) {\r\n // TODO: We probably want to make this\r\n // smarter and only add/remove nodes\r\n graph.clear();\r\n\r\n for (const node of nodes) {\r\n try {\r\n graph.addNode(node.id, node);\r\n } catch ({ message }) {\r\n console.error(`[Graph] ${message}`);\r\n }\r\n }\r\n\r\n for (const edge of edges) {\r\n try {\r\n graph.addEdge(edge.source, edge.target, edge);\r\n } catch ({ message }) {\r\n console.error(`[Graph] ${message}`);\r\n }\r\n }\r\n\r\n return graph;\r\n}\r\n\r\ninterface TransformGraphInput {\r\n graph: Graph;\r\n layout: LayoutStrategy;\r\n sizingType?: SizingType;\r\n labelType?: LabelVisibilityType;\r\n sizingAttribute?: string;\r\n minNodeSize?: number;\r\n maxNodeSize?: number;\r\n defaultNodeSize?: number;\r\n}\r\n\r\n/**\r\n * Transform the graph into a format that is easier to work with.\r\n */\r\nexport function transformGraph({\r\n graph,\r\n layout,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n defaultNodeSize,\r\n minNodeSize,\r\n maxNodeSize\r\n}: TransformGraphInput) {\r\n const nodes: InternalGraphNode[] = [];\r\n const edges: InternalGraphEdge[] = [];\r\n const map = new Map();\r\n\r\n const sizes = nodeSizeProvider({\r\n graph,\r\n type: sizingType,\r\n attribute: sizingAttribute,\r\n minSize: minNodeSize,\r\n maxSize: maxNodeSize,\r\n defaultSize: defaultNodeSize\r\n });\r\n\r\n const nodeCount = graph.nodes().length;\r\n const checkVisibility = calcLabelVisibility({ nodeCount, labelType });\r\n\r\n graph.forEachNode((id, node) => {\r\n const position = layout.getNodePosition(id);\r\n const { data, fill, icon, label, size, ...rest } = node;\r\n const nodeSize = sizes.get(node.id);\r\n const labelVisible = checkVisibility('node', nodeSize);\r\n\r\n const nodeLinks = graph.inboundNeighbors(node.id) || [];\r\n const parents = nodeLinks.map(n => graph.getNodeAttributes(n));\r\n\r\n const n: InternalGraphNode = {\r\n ...(node as any),\r\n size: nodeSize,\r\n labelVisible,\r\n label,\r\n icon,\r\n fill,\r\n parents,\r\n data: {\r\n ...rest,\r\n ...(data ?? {})\r\n },\r\n position: {\r\n ...position,\r\n x: position.x || 0,\r\n y: position.y || 0,\r\n z: position.z || 1\r\n }\r\n };\r\n\r\n map.set(node.id, n);\r\n nodes.push(n);\r\n });\r\n\r\n graph.forEachEdge((_id, link) => {\r\n const from = map.get(link.source);\r\n const to = map.get(link.target);\r\n\r\n if (from && to) {\r\n const { data, id, label, size, ...rest } = link;\r\n const labelVisible = checkVisibility('edge', size);\r\n\r\n // TODO: Fix type\r\n edges.push({\r\n ...link,\r\n id,\r\n label,\r\n labelVisible,\r\n size,\r\n data: {\r\n ...rest,\r\n id,\r\n ...(data || {})\r\n }\r\n } as any);\r\n }\r\n });\r\n\r\n return {\r\n nodes,\r\n edges\r\n };\r\n}\r\n","export const animationConfig = {\r\n mass: 10,\r\n tension: 1000,\r\n friction: 300,\r\n // Decreasing precision to improve performance from 0.00001\r\n precision: 0.1\r\n};\r\n","import { Curve, Vector3 } from 'three';\r\n\r\nimport { EdgeArrowPosition } from '../symbols/Arrow';\r\n\r\n// Calculate the correct position for an arrow along a curve,\r\n// as well as the tangent to the curve at that point.\r\nexport function getArrowVectors(\r\n placement: EdgeArrowPosition,\r\n curve: Curve,\r\n arrowLength: number\r\n): [Vector3, Vector3] {\r\n const curveLength = curve.getLength();\r\n const absSize = placement === 'end' ? curveLength : curveLength / 2;\r\n const offset = placement === 'end' ? arrowLength / 2 : 0;\r\n const u = (absSize - offset) / curveLength;\r\n\r\n const position = curve.getPointAt(u);\r\n const rotation = curve.getTangentAt(u);\r\n\r\n return [position, rotation];\r\n}\r\n\r\nexport function getArrowSize(size: number): [number, number] {\r\n return [size + 6, 2 + size / 1.5];\r\n}\r\n","import { Curve, LineCurve3, QuadraticBezierCurve3, Vector3 } from 'three';\r\nimport { InternalGraphNode, InternalVector3 } from '../types';\r\n\r\nconst MULTI_EDGE_OFFSET_FACTOR = 0.7;\r\n\r\n/**\r\n * Get the midpoint given two points.\r\n */\r\nexport function getMidPoint(\r\n from: InternalVector3,\r\n to: InternalVector3,\r\n offset = 0\r\n) {\r\n const fromVector = new Vector3(from.x, from.y || 0, from.z || 0);\r\n const toVector = new Vector3(to.x, to.y || 0, to.z || 0);\r\n const midVector = new Vector3()\r\n .addVectors(fromVector, toVector)\r\n .divideScalar(2);\r\n\r\n return midVector.setLength(midVector.length() + offset);\r\n}\r\n\r\n/**\r\n * Calculate the center for a quadratic bezier curve.\r\n *\r\n * 1) Find the point halfway between the start and end points of the desired curve\r\n * 2) Find the vector pependicular to that point\r\n * 3) Find the point 1/4 the distance between start and end along that vector.\r\n */\r\nexport function getCurvePoints(\r\n from: Vector3,\r\n to: Vector3,\r\n offset = -1\r\n): [Vector3, Vector3, Vector3] {\r\n const fromVector = from.clone();\r\n const toVector = to.clone();\r\n const v = new Vector3().subVectors(toVector, fromVector);\r\n const vlen = v.length();\r\n const vn = v.clone().normalize();\r\n const vv = new Vector3().subVectors(toVector, fromVector).divideScalar(2);\r\n const k = Math.abs(vn.x) % 1;\r\n const b = new Vector3(-vn.y, vn.x - k * vn.z, k * vn.y).normalize();\r\n const vm = new Vector3()\r\n .add(fromVector)\r\n .add(vv)\r\n .add(b.multiplyScalar(vlen / 4).multiplyScalar(offset));\r\n\r\n return [from, vm, to];\r\n}\r\n\r\n/**\r\n * Get the curve given two points.\r\n */\r\nexport function getCurve(\r\n from: Vector3,\r\n fromOffset: number,\r\n to: Vector3,\r\n toOffset: number,\r\n curved: boolean,\r\n curveOffset?: number\r\n): Curve {\r\n const offsetFrom = getPointBetween(from, to, fromOffset);\r\n const offsetTo = getPointBetween(to, from, toOffset);\r\n return curved\r\n ? new QuadraticBezierCurve3(\r\n ...getCurvePoints(offsetFrom, offsetTo, curveOffset)\r\n )\r\n : new LineCurve3(offsetFrom, offsetTo);\r\n}\r\n\r\n/**\r\n * Create a threejs vector for a node.\r\n */\r\nexport function getVector(node: InternalGraphNode): Vector3 {\r\n return new Vector3(node.position.x, node.position.y, node.position.z || 0);\r\n}\r\n\r\n/**\r\n * Get the point between two vectors.\r\n */\r\nfunction getPointBetween(from: Vector3, to: Vector3, offset: number): Vector3 {\r\n const distance = from.distanceTo(to);\r\n return from.clone().add(\r\n to\r\n .clone()\r\n .sub(from)\r\n .multiplyScalar(offset / distance)\r\n );\r\n}\r\n\r\n/**\r\n * Given a node and a new vector set, update the node model.\r\n */\r\nexport function updateNodePosition(node: InternalGraphNode, offset: Vector3) {\r\n return {\r\n ...node,\r\n position: {\r\n ...node.position,\r\n x: node.position.x + offset.x,\r\n y: node.position.y + offset.y,\r\n z: node.position.z + offset.z\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Calculate the curve offset for an edge.\r\n * This is used to offset edges that are parallel to each other (same source and same target).\r\n * This will return a curveOffset of null if the edge is not parallel to any other edges.\r\n */\r\nexport function calculateEdgeCurveOffset({ edge, edges, curved }) {\r\n let updatedCurved = curved;\r\n let curveOffset: number;\r\n\r\n const parallelEdges = edges\r\n .filter(e => e.target === edge.target && e.source === edge.source)\r\n .map(e => e.id);\r\n\r\n if (parallelEdges.length > 1) {\r\n updatedCurved = true;\r\n const edgeIndex = parallelEdges.indexOf(edge.id);\r\n\r\n if (parallelEdges.length === 2) {\r\n curveOffset =\r\n edgeIndex === 0 ? MULTI_EDGE_OFFSET_FACTOR : -MULTI_EDGE_OFFSET_FACTOR;\r\n } else {\r\n curveOffset =\r\n (edgeIndex - Math.floor(parallelEdges.length / 2)) *\r\n MULTI_EDGE_OFFSET_FACTOR;\r\n }\r\n }\r\n\r\n return { curved: updatedCurved, curveOffset };\r\n}\r\n","import { InternalGraphNode } from '../types';\r\n\r\nexport interface CenterPositionVector {\r\n x: number;\r\n y: number;\r\n z: number;\r\n minX: number;\r\n maxX: number;\r\n minY: number;\r\n maxY: number;\r\n minZ: number;\r\n maxZ: number;\r\n height: number;\r\n width: number;\r\n}\r\n\r\n/**\r\n * Given a collection of nodes, get the center point.\r\n */\r\nexport function getLayoutCenter(\r\n nodes: InternalGraphNode[]\r\n): CenterPositionVector {\r\n let minX = Number.POSITIVE_INFINITY;\r\n let maxX = Number.NEGATIVE_INFINITY;\r\n let minY = Number.POSITIVE_INFINITY;\r\n let maxY = Number.NEGATIVE_INFINITY;\r\n let minZ = Number.POSITIVE_INFINITY;\r\n let maxZ = Number.NEGATIVE_INFINITY;\r\n\r\n for (let node of nodes) {\r\n minX = Math.min(minX, node.position.x);\r\n maxX = Math.max(maxX, node.position.x);\r\n minY = Math.min(minY, node.position.y);\r\n maxY = Math.max(maxY, node.position.y);\r\n minZ = Math.min(minZ, node.position.z);\r\n maxZ = Math.max(maxZ, node.position.z);\r\n }\r\n\r\n return {\r\n height: maxY - minY,\r\n width: maxX - minX,\r\n minX,\r\n maxX,\r\n minY,\r\n maxY,\r\n minZ,\r\n maxZ,\r\n x: (maxX + minX) / 2,\r\n y: (maxY + minY) / 2,\r\n z: (maxZ + minZ) / 2\r\n };\r\n}\r\n","import { InternalGraphNode } from '../types';\r\nimport { CenterPositionVector, getLayoutCenter } from './layout';\r\n\r\n/**\r\n * Given nodes and a attribute, find all the cluster groups.\r\n */\r\nexport function buildClusterGroups(\r\n nodes: InternalGraphNode[],\r\n clusterAttribute?: string\r\n) {\r\n if (!clusterAttribute) {\r\n return new Map();\r\n }\r\n\r\n return nodes.reduce((entryMap, e) => {\r\n const val = e.data[clusterAttribute];\r\n if (val) {\r\n entryMap.set(val, [...(entryMap.get(val) || []), e]);\r\n }\r\n return entryMap;\r\n }, new Map());\r\n}\r\n\r\nexport interface CalculateClustersInput {\r\n nodes: InternalGraphNode[];\r\n clusterAttribute?: string;\r\n}\r\n\r\nexport interface ClusterGroup {\r\n nodes: InternalGraphNode[];\r\n position: CenterPositionVector;\r\n label: string;\r\n}\r\n\r\n/**\r\n * Builds the cluster map.\r\n */\r\nexport function calculateClusters({\r\n nodes,\r\n clusterAttribute\r\n}: CalculateClustersInput) {\r\n const result = new Map();\r\n\r\n if (clusterAttribute) {\r\n const groups = buildClusterGroups(nodes, clusterAttribute);\r\n for (const [key, nodes] of groups) {\r\n const position = getLayoutCenter(nodes);\r\n result.set(key, {\r\n label: key,\r\n nodes,\r\n position\r\n });\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","import { useCallback, useRef } from 'react';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface HoverIntentOptions {\r\n interval?: number;\r\n sensitivity?: number;\r\n timeout?: number;\r\n disabled?: boolean;\r\n onPointerOver: (event: ThreeEvent) => void;\r\n onPointerOut: (event: ThreeEvent) => void;\r\n}\r\n\r\nexport interface HoverIntentResult {\r\n pointerOut: (event: ThreeEvent) => void;\r\n pointerOver: (event: ThreeEvent) => void;\r\n}\r\n\r\n/**\r\n * Hover intent identifies if the user actually is\r\n * intending to over by measuring the position of the mouse\r\n * once a pointer enters and determining if in a duration if\r\n * the mouse moved inside a certain threshold and fires the events.\r\n */\r\nexport const useHoverIntent = ({\r\n sensitivity = 7,\r\n interval = 50,\r\n timeout = 0,\r\n disabled,\r\n onPointerOver,\r\n onPointerOut\r\n}: HoverIntentOptions | undefined): HoverIntentResult => {\r\n const mouseOver = useRef(false);\r\n const timer = useRef(null);\r\n const state = useRef(0);\r\n const coords = useRef({\r\n x: null,\r\n y: null,\r\n px: null,\r\n py: null\r\n });\r\n\r\n const onMouseMove = useCallback((event: MouseEvent) => {\r\n coords.current.x = event.clientX;\r\n coords.current.y = event.clientY;\r\n }, []);\r\n\r\n const comparePosition = useCallback(\r\n (event: ThreeEvent) => {\r\n timer.current = clearTimeout(timer.current);\r\n const { px, x, py, y } = coords.current;\r\n\r\n if (Math.abs(px - x) + Math.abs(py - y) < sensitivity) {\r\n state.current = 1;\r\n onPointerOver(event);\r\n } else {\r\n coords.current.px = x;\r\n coords.current.py = y;\r\n timer.current = setTimeout(() => comparePosition(event), interval);\r\n }\r\n },\r\n [interval, onPointerOver, sensitivity]\r\n );\r\n\r\n const cleanup = useCallback(() => {\r\n clearTimeout(timer.current);\r\n if (typeof window !== 'undefined') {\r\n document.removeEventListener('mousemove', onMouseMove, false);\r\n }\r\n }, [onMouseMove]);\r\n\r\n const pointerOver = useCallback(\r\n (event: ThreeEvent) => {\r\n if (!disabled) {\r\n mouseOver.current = true;\r\n cleanup();\r\n\r\n if (state.current !== 1) {\r\n coords.current.px = event.pointer.x;\r\n coords.current.py = event.pointer.y;\r\n\r\n if (typeof window !== 'undefined') {\r\n document.addEventListener('mousemove', onMouseMove, false);\r\n }\r\n\r\n timer.current = setTimeout(() => comparePosition(event), timeout);\r\n }\r\n }\r\n },\r\n [cleanup, comparePosition, disabled, onMouseMove, timeout]\r\n );\r\n\r\n const delay = useCallback(\r\n (event: ThreeEvent) => {\r\n timer.current = clearTimeout(timer.current);\r\n state.current = 0;\r\n onPointerOut(event);\r\n },\r\n [onPointerOut]\r\n );\r\n\r\n const pointerOut = useCallback(\r\n (event: ThreeEvent) => {\r\n mouseOver.current = false;\r\n cleanup();\r\n\r\n if (state.current === 1) {\r\n timer.current = setTimeout(() => delay(event), timeout);\r\n }\r\n },\r\n [cleanup, delay, timeout]\r\n );\r\n\r\n return {\r\n pointerOver,\r\n pointerOut\r\n };\r\n};\r\n","import { useThree } from '@react-three/fiber';\r\nimport { useMemo } from 'react';\r\nimport { useGesture } from 'react-use-gesture';\r\nimport { Vector2, Vector3, Plane } from 'three';\r\nimport { InternalGraphPosition } from '../types';\r\n\r\ninterface DragParams {\r\n draggable: boolean;\r\n position: InternalGraphPosition;\r\n set: (position: Vector3) => void;\r\n onDragStart: () => void;\r\n onDragEnd: () => void;\r\n}\r\n\r\nexport const useDrag = ({\r\n draggable,\r\n set,\r\n position,\r\n onDragStart,\r\n onDragEnd\r\n}: DragParams) => {\r\n const camera = useThree(state => state.camera);\r\n const raycaster = useThree(state => state.raycaster);\r\n const size = useThree(state => state.size);\r\n const gl = useThree(state => state.gl);\r\n\r\n // Reference: https://codesandbox.io/s/react-three-draggable-cxu37\r\n const { mouse2D, mouse3D, offset, normal, plane } = useMemo(\r\n () => ({\r\n // Normalized 2D screen space mouse coords\r\n mouse2D: new Vector2(),\r\n // 3D world space mouse coords\r\n mouse3D: new Vector3(),\r\n // Drag point offset from object origin\r\n offset: new Vector3(),\r\n // Normal of the drag plane\r\n normal: new Vector3(),\r\n // Drag plane\r\n plane: new Plane()\r\n }),\r\n []\r\n );\r\n\r\n const clientRect = useMemo(\r\n () => gl.domElement.getBoundingClientRect(),\r\n [gl.domElement]\r\n );\r\n\r\n return useGesture(\r\n {\r\n onDragStart: ({ event }) => {\r\n // @ts-ignore\r\n const { eventObject, point } = event;\r\n\r\n // Save the offset of click point from object origin\r\n eventObject.getWorldPosition(offset).sub(point);\r\n\r\n // Set initial 3D cursor position (needed for onDrag plane calculation)\r\n mouse3D.copy(point);\r\n\r\n // Run user callback\r\n onDragStart();\r\n },\r\n onDrag: ({ event }) => {\r\n // Compute normalized mouse coordinates (screen space)\r\n const scrollX = window.scrollX || window.pageXOffset;\r\n const scrollY = window.scrollY || window.pageYOffset;\r\n\r\n const nx =\r\n ((event.clientX - (clientRect?.left ?? 0) + scrollX) / size.width) *\r\n 2 -\r\n 1;\r\n const ny =\r\n -((event.clientY - (clientRect?.top ?? 0) + scrollY) / size.height) *\r\n 2 +\r\n 1;\r\n\r\n // Unlike the mouse from useThree, this works offscreen\r\n mouse2D.set(nx, ny);\r\n\r\n // Update raycaster (otherwise it doesn't track offscreen)\r\n raycaster.setFromCamera(mouse2D, camera);\r\n\r\n // The drag plane is normal to the camera view\r\n camera.getWorldDirection(normal).negate();\r\n\r\n // Find the plane that's normal to the camera and contains our drag point\r\n plane.setFromNormalAndCoplanarPoint(normal, mouse3D);\r\n\r\n // Find the point of intersection\r\n raycaster.ray.intersectPlane(plane, mouse3D);\r\n\r\n // Update the object position with the original offset\r\n const updated = new Vector3(position.x, position.y, position.z)\r\n .copy(mouse3D)\r\n .add(offset);\r\n\r\n return set(updated);\r\n },\r\n onDragEnd\r\n },\r\n { drag: { enabled: draggable, threshold: 10 } }\r\n );\r\n};\r\n","import Graph from 'graphology';\r\nimport { bidirectional } from 'graphology-shortest-path';\r\n\r\nexport function findPath(graph: Graph, source: string, target: string) {\r\n return bidirectional(graph, source, target);\r\n}\r\n","import { StoreApi, create } from 'zustand';\r\nimport createContext from 'zustand/context';\r\nimport {\r\n InternalGraphEdge,\r\n InternalGraphNode,\r\n InternalGraphPosition\r\n} from './types';\r\nimport { BufferGeometry, Mesh, Vector3 } from 'three';\r\nimport {\r\n CenterPositionVector,\r\n ClusterGroup,\r\n getLayoutCenter,\r\n getVector,\r\n updateNodePosition\r\n} from './utils';\r\nimport Graph from 'graphology';\r\nimport { Theme } from './themes';\r\n\r\nexport type DragReferences = {\r\n [key: string]: InternalGraphNode;\r\n};\r\n\r\nexport interface GraphState {\r\n nodes: InternalGraphNode[];\r\n edges: InternalGraphEdge[];\r\n graph: Graph;\r\n clusters: Map;\r\n collapsedNodeIds?: string[];\r\n centerPosition?: CenterPositionVector;\r\n actives?: string[];\r\n selections?: string[];\r\n edgeContextMenus?: Set;\r\n setEdgeContextMenus: (edges: Set) => void;\r\n edgeMeshes: Array>;\r\n setEdgeMeshes: (edgeMeshes: Array>) => void;\r\n draggingId?: string | null;\r\n drags?: DragReferences;\r\n panning?: boolean;\r\n theme: Theme;\r\n setTheme: (theme: Theme) => void;\r\n setClusters: (clusters: Map) => void;\r\n setPanning: (panning: boolean) => void;\r\n setDrags: (drags: DragReferences) => void;\r\n setDraggingId: (id: string | null) => void;\r\n setActives: (actives: string[]) => void;\r\n setSelections: (selections: string[]) => void;\r\n setNodes: (nodes: InternalGraphNode[]) => void;\r\n setEdges: (edges: InternalGraphEdge[]) => void;\r\n setNodePosition: (id: string, position: InternalGraphPosition) => void;\r\n setCollapsedNodeIds: (nodeIds: string[]) => void;\r\n canvasRef: HTMLCanvasElement | null;\r\n}\r\n\r\nexport const { Provider, useStore } = createContext>();\r\n\r\nexport const createStore = ({\r\n actives = [],\r\n selections = [],\r\n collapsedNodeIds = [],\r\n theme,\r\n canvasRef = null\r\n}: Partial) =>\r\n create(set => ({\r\n theme: {\r\n ...theme,\r\n edge: {\r\n ...theme.edge,\r\n label: {\r\n ...theme.edge.label,\r\n fontSize: theme.edge.label.fontSize ?? 6\r\n }\r\n }\r\n },\r\n edges: [],\r\n nodes: [],\r\n collapsedNodeIds,\r\n clusters: new Map(),\r\n panning: false,\r\n draggingId: null,\r\n actives,\r\n edgeContextMenus: new Set(),\r\n edgeMeshes: [],\r\n selections,\r\n drags: {},\r\n graph: new Graph({ multi: true }),\r\n setTheme: theme => set(state => ({ ...state, theme })),\r\n setClusters: clusters => set(state => ({ ...state, clusters })),\r\n setEdgeContextMenus: edgeContextMenus =>\r\n set(state => ({\r\n ...state,\r\n edgeContextMenus\r\n })),\r\n setEdgeMeshes: edgeMeshes => set(state => ({ ...state, edgeMeshes })),\r\n setPanning: panning => set(state => ({ ...state, panning })),\r\n setDrags: drags => set(state => ({ ...state, drags })),\r\n setDraggingId: draggingId => set(state => ({ ...state, draggingId })),\r\n setActives: actives => set(state => ({ ...state, actives })),\r\n setSelections: selections => set(state => ({ ...state, selections })),\r\n setNodes: nodes =>\r\n set(state => ({\r\n ...state,\r\n nodes,\r\n centerPosition: getLayoutCenter(nodes)\r\n })),\r\n setEdges: edges => set(state => ({ ...state, edges })),\r\n setNodePosition: (id, position) =>\r\n set(state => {\r\n const node = state.nodes.find(n => n.id === id);\r\n const originalVector = getVector(node);\r\n const newVector = new Vector3(position.x, position.y, position.z);\r\n const offset = newVector.sub(originalVector);\r\n const nodes = [...state.nodes];\r\n\r\n if (state.selections?.includes(id)) {\r\n state.selections?.forEach(id => {\r\n const node = state.nodes.find(n => n.id === id);\r\n // Selections can contain edges:\r\n if (node) {\r\n const nodeIndex = state.nodes.indexOf(node);\r\n nodes[nodeIndex] = updateNodePosition(node, offset);\r\n }\r\n });\r\n } else {\r\n const nodeIndex = state.nodes.indexOf(node);\r\n nodes[nodeIndex] = updateNodePosition(node, offset);\r\n }\r\n\r\n return {\r\n ...state,\r\n drags: {\r\n ...state.drags,\r\n [id]: node\r\n },\r\n nodes\r\n };\r\n }),\r\n setCollapsedNodeIds: (nodeIds = []) =>\r\n set(state => ({ ...state, collapsedNodeIds: nodeIds })),\r\n canvasRef\r\n }));\r\n","import { GraphEdge, GraphNode } from '../types';\r\n\r\ninterface GetHiddenChildrenInput {\r\n nodeId: string;\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n currentHiddenNodes: GraphNode[];\r\n currentHiddenEdges: GraphEdge[];\r\n}\r\n\r\ninterface GetVisibleIdsInput {\r\n collapsedIds: string[];\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n}\r\n\r\ninterface GetExpandPathInput {\r\n nodeId: string;\r\n edges: GraphEdge[];\r\n visibleEdgeIds: string[];\r\n}\r\n\r\n/**\r\n * Get the children of a node id that is hidden.\r\n */\r\nfunction getHiddenChildren({\r\n nodeId,\r\n nodes,\r\n edges,\r\n currentHiddenNodes,\r\n currentHiddenEdges\r\n}: GetHiddenChildrenInput) {\r\n const hiddenNodes: GraphNode[] = [];\r\n const hiddenEdges: GraphEdge[] = [];\r\n const curHiddenNodeIds = currentHiddenNodes.map(n => n.id);\r\n const curHiddenEdgeIds = currentHiddenEdges.map(e => e.id);\r\n\r\n const outboundEdges = edges.filter(l => l.source === nodeId);\r\n const outboundEdgeNodeIds = outboundEdges.map(l => l.target);\r\n\r\n hiddenEdges.push(...outboundEdges);\r\n for (const outboundEdgeNodeId of outboundEdgeNodeIds) {\r\n const incomingEdges = edges.filter(\r\n l => l.target === outboundEdgeNodeId && l.source !== nodeId\r\n );\r\n let hideNode = false;\r\n\r\n // Check to see if any other edge is coming into this node\r\n if (incomingEdges.length === 0) {\r\n hideNode = true;\r\n } else if (\r\n incomingEdges.length > 0 &&\r\n !curHiddenNodeIds.includes(outboundEdgeNodeId)\r\n ) {\r\n // If all inbound links are hidden, hide this node as well\r\n const inboundNodeLinkIds = incomingEdges.map(l => l.id);\r\n if (inboundNodeLinkIds.every(i => curHiddenEdgeIds.includes(i))) {\r\n hideNode = true;\r\n }\r\n }\r\n if (hideNode) {\r\n // Need to hide this node and any children of this node\r\n const node = nodes.find(n => n.id === outboundEdgeNodeId);\r\n if (node) {\r\n hiddenNodes.push(node);\r\n }\r\n const nested = getHiddenChildren({\r\n nodeId: outboundEdgeNodeId,\r\n nodes,\r\n edges,\r\n currentHiddenEdges: hiddenEdges,\r\n currentHiddenNodes: hiddenNodes\r\n });\r\n hiddenEdges.push(...nested.hiddenEdges);\r\n hiddenNodes.push(...nested.hiddenNodes);\r\n }\r\n }\r\n\r\n const uniqueEdges: GraphEdge[] = Object.values(\r\n hiddenEdges.reduce(\r\n (acc, next) => ({\r\n ...acc,\r\n [next.id]: next\r\n }),\r\n {}\r\n )\r\n );\r\n\r\n const uniqueNodes: GraphNode[] = Object.values(\r\n hiddenNodes.reduce(\r\n (acc, next) => ({\r\n ...acc,\r\n [next.id]: next\r\n }),\r\n {}\r\n )\r\n );\r\n\r\n return {\r\n hiddenEdges: uniqueEdges,\r\n hiddenNodes: uniqueNodes\r\n };\r\n}\r\n\r\n/**\r\n * Get the visible nodes and edges given a collapsed set of ids.\r\n */\r\nexport const getVisibleEntities = ({\r\n collapsedIds,\r\n nodes,\r\n edges\r\n}: GetVisibleIdsInput) => {\r\n const curHiddenNodes = [];\r\n const curHiddenEdges = [];\r\n\r\n for (const collapsedId of collapsedIds) {\r\n const { hiddenEdges, hiddenNodes } = getHiddenChildren({\r\n nodeId: collapsedId,\r\n nodes,\r\n edges,\r\n currentHiddenEdges: curHiddenEdges,\r\n currentHiddenNodes: curHiddenNodes\r\n });\r\n\r\n curHiddenNodes.push(...hiddenNodes);\r\n curHiddenEdges.push(...hiddenEdges);\r\n }\r\n\r\n const hiddenNodeIds = curHiddenNodes.map(n => n.id);\r\n const hiddenEdgeIds = curHiddenEdges.map(e => e.id);\r\n const visibleNodes = nodes.filter(n => !hiddenNodeIds.includes(n.id));\r\n const visibleEdges = edges.filter(e => !hiddenEdgeIds.includes(e.id));\r\n\r\n return {\r\n visibleNodes,\r\n visibleEdges\r\n };\r\n};\r\n\r\n/**\r\n * Get the path to expand a node.\r\n */\r\nexport const getExpandPath = ({\r\n nodeId,\r\n edges,\r\n visibleEdgeIds\r\n}: GetExpandPathInput) => {\r\n const parentIds = [];\r\n const inboundEdges = edges.filter(l => l.target === nodeId);\r\n const inboundEdgeIds = inboundEdges.map(e => e.id);\r\n const hasVisibleInboundEdge = inboundEdgeIds.some(id =>\r\n visibleEdgeIds.includes(id)\r\n );\r\n\r\n if (hasVisibleInboundEdge) {\r\n // If there is a visible edge to this node, that means the node is\r\n // visible so no parents need to be expanded\r\n return parentIds;\r\n }\r\n\r\n const inboundEdgeNodeIds = inboundEdges.map(l => l.source);\r\n let addedParent = false;\r\n\r\n for (const inboundNodeId of inboundEdgeNodeIds) {\r\n if (!addedParent) {\r\n // Only want to expand a single path to the node, so if there\r\n // are multiple hidden incoming edges, only expand the first\r\n // to reduce how many nodes are expanded to get to the node\r\n parentIds.push(\r\n ...[\r\n inboundNodeId,\r\n ...getExpandPath({ nodeId: inboundNodeId, edges, visibleEdgeIds })\r\n ]\r\n );\r\n addedParent = true;\r\n }\r\n }\r\n\r\n return parentIds;\r\n};\r\n","import React, { useCallback } from 'react';\r\nimport { GraphEdge, GraphNode } from 'types';\r\nimport { getExpandPath, getVisibleEntities } from './utils';\r\n\r\nexport interface UseCollapseProps {\r\n /**\r\n * Current collapsed node ids.\r\n */\r\n collapsedNodeIds?: string[];\r\n\r\n /**\r\n * Node data.\r\n */\r\n nodes?: GraphNode[];\r\n\r\n /**\r\n * Edge data.\r\n */\r\n edges?: GraphEdge[];\r\n}\r\n\r\nexport interface CollpaseResult {\r\n /**\r\n * Determine if a node is currently collapsed\r\n */\r\n getIsCollapsed: (nodeId: string) => boolean;\r\n\r\n /**\r\n * Return a list of ids required to expand in order to view the provided node\r\n */\r\n getExpandPathIds: (nodeId: string) => string[];\r\n}\r\n\r\nexport const useCollapse = ({\r\n collapsedNodeIds = [],\r\n nodes = [],\r\n edges = []\r\n}: UseCollapseProps): CollpaseResult => {\r\n const getIsCollapsed = useCallback(\r\n (nodeId: string) => {\r\n const { visibleNodes } = getVisibleEntities({\r\n nodes,\r\n edges,\r\n collapsedIds: collapsedNodeIds\r\n });\r\n const visibleNodeIds = visibleNodes.map(n => n.id);\r\n\r\n return !visibleNodeIds.includes(nodeId);\r\n },\r\n [collapsedNodeIds, edges, nodes]\r\n );\r\n\r\n const getExpandPathIds = useCallback(\r\n (nodeId: string) => {\r\n const { visibleEdges } = getVisibleEntities({\r\n nodes,\r\n edges,\r\n collapsedIds: collapsedNodeIds\r\n });\r\n const visibleEdgeIds = visibleEdges.map(e => e.id);\r\n\r\n return getExpandPath({ nodeId, edges, visibleEdgeIds });\r\n },\r\n [collapsedNodeIds, edges, nodes]\r\n );\r\n\r\n return {\r\n getIsCollapsed,\r\n getExpandPathIds\r\n };\r\n};\r\n","import { useRef, useCallback, useEffect, useMemo } from 'react';\r\nimport { useThree } from '@react-three/fiber';\r\nimport { PerspectiveCamera } from 'three';\r\nimport { SizingType } from './sizing';\r\nimport {\r\n LayoutTypes,\r\n layoutProvider,\r\n LayoutStrategy,\r\n LayoutOverrides\r\n} from './layout';\r\nimport { LabelVisibilityType, calcLabelVisibility } from './utils/visibility';\r\nimport { tick } from './layout/layoutUtils';\r\nimport { GraphEdge, GraphNode } from './types';\r\nimport { buildGraph, transformGraph } from './utils/graph';\r\nimport { DragReferences, useStore } from './store';\r\nimport { getVisibleEntities } from './collapse';\r\nimport { calculateClusters } from './utils/cluster';\r\n\r\nexport interface GraphInputs {\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n collapsedNodeIds?: string[];\r\n layoutType?: LayoutTypes;\r\n sizingType?: SizingType;\r\n labelType?: LabelVisibilityType;\r\n sizingAttribute?: string;\r\n selections?: string[];\r\n actives?: string[];\r\n clusterAttribute?: string;\r\n defaultNodeSize?: number;\r\n minNodeSize?: number;\r\n maxNodeSize?: number;\r\n layoutOverrides?: LayoutOverrides;\r\n}\r\n\r\nexport const useGraph = ({\r\n layoutType,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n clusterAttribute,\r\n selections,\r\n nodes,\r\n edges,\r\n actives,\r\n collapsedNodeIds,\r\n defaultNodeSize,\r\n maxNodeSize,\r\n minNodeSize,\r\n layoutOverrides\r\n}: GraphInputs) => {\r\n const graph = useStore(state => state.graph);\r\n const setClusters = useStore(state => state.setClusters);\r\n const stateCollapsedNodeIds = useStore(state => state.collapsedNodeIds);\r\n const setEdges = useStore(state => state.setEdges);\r\n const stateNodes = useStore(state => state.nodes);\r\n const setNodes = useStore(state => state.setNodes);\r\n const setSelections = useStore(state => state.setSelections);\r\n const setActives = useStore(state => state.setActives);\r\n const drags = useStore(state => state.drags);\r\n const setDrags = useStore(state => state.setDrags);\r\n const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\r\n const layoutMounted = useRef(false);\r\n const layout = useRef(null);\r\n const camera = useThree(state => state.camera) as PerspectiveCamera;\r\n\r\n const { visibleEdges, visibleNodes } = useMemo(\r\n () =>\r\n getVisibleEntities({\r\n collapsedIds: stateCollapsedNodeIds,\r\n nodes,\r\n edges\r\n }),\r\n [stateCollapsedNodeIds, nodes, edges]\r\n );\r\n\r\n // Transient updates\r\n const dragRef = useRef(drags);\r\n useEffect(() => {\r\n dragRef.current = drags;\r\n }, [drags]);\r\n\r\n const updateLayout = useCallback(\r\n async (curLayout?: any) => {\r\n // Cache the layout provider\r\n layout.current =\r\n curLayout ||\r\n layoutProvider({\r\n ...layoutOverrides,\r\n type: layoutType,\r\n graph,\r\n drags: dragRef.current,\r\n clusterAttribute\r\n });\r\n\r\n // Run the layout\r\n await tick(layout.current);\r\n\r\n // Transform the graph\r\n const result = transformGraph({\r\n graph,\r\n layout: layout.current,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n maxNodeSize,\r\n minNodeSize,\r\n defaultNodeSize\r\n });\r\n\r\n // Calculate clusters\r\n const clusters = calculateClusters({\r\n nodes: result.nodes,\r\n clusterAttribute\r\n });\r\n\r\n // Set our store outputs\r\n setEdges(result.edges);\r\n setNodes(result.nodes);\r\n setClusters(clusters);\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [\r\n layoutOverrides,\r\n layoutType,\r\n clusterAttribute,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n maxNodeSize,\r\n minNodeSize,\r\n defaultNodeSize,\r\n setEdges,\r\n setNodes,\r\n setClusters\r\n ]\r\n );\r\n\r\n useEffect(() => {\r\n const nodes = stateNodes.map(node => ({\r\n ...node,\r\n labelVisible: calcLabelVisibility({\r\n nodeCount: stateNodes?.length,\r\n labelType,\r\n camera,\r\n nodePosition: node?.position\r\n })('node', node?.size)\r\n }));\r\n\r\n const isVisibilityUpdated = nodes.some(\r\n (node, i) => node.labelVisible !== stateNodes[i].labelVisible\r\n );\r\n\r\n if (isVisibilityUpdated) {\r\n setNodes(nodes);\r\n }\r\n }, [camera, camera.zoom, camera.position.z, setNodes, stateNodes, labelType]);\r\n\r\n useEffect(() => {\r\n // Let's set the store selections so its easier to access\r\n if (layoutMounted.current) {\r\n setSelections(selections);\r\n }\r\n }, [selections, setSelections]);\r\n\r\n useEffect(() => {\r\n // Let's set the store actives so its easier to access\r\n if (layoutMounted.current) {\r\n setActives(actives);\r\n }\r\n }, [actives, setActives]);\r\n\r\n // Create the nggraph graph object\r\n useEffect(() => {\r\n async function update() {\r\n layoutMounted.current = false;\r\n buildGraph(graph, visibleNodes, visibleEdges);\r\n await updateLayout();\r\n layoutMounted.current = true;\r\n }\r\n\r\n update();\r\n // eslint-disable-next-line\r\n }, [visibleNodes, visibleEdges]);\r\n\r\n useEffect(() => {\r\n // Let's set the store collapsedNodeIds so its easier to access\r\n if (layoutMounted.current) {\r\n setCollapsedNodeIds(collapsedNodeIds);\r\n }\r\n }, [collapsedNodeIds, setCollapsedNodeIds]);\r\n\r\n // Update layout on type changes\r\n useEffect(() => {\r\n if (layoutMounted.current) {\r\n // When a update is changed, discard all the previous drag positions\r\n // NOTE: This sets the transient and the state\r\n dragRef.current = {};\r\n setDrags({});\r\n\r\n // Recalculate the layout\r\n updateLayout();\r\n }\r\n }, [layoutType, updateLayout, setDrags]);\r\n\r\n // Update layout on size, label changes\r\n useEffect(() => {\r\n if (layoutMounted.current) {\r\n updateLayout(layout.current);\r\n }\r\n }, [sizingType, sizingAttribute, labelType, updateLayout]);\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { Billboard, RoundedBox, Text } from 'glodrei';\r\nimport { Color, ColorRepresentation, Euler } from 'three';\r\nimport ellipsize from 'ellipsize';\r\nimport { a } from '@react-spring/three';\r\n\r\nconst calculateTextSize = (\r\n text: string,\r\n fontSize: number,\r\n maxWidth: number,\r\n ellipsis: number,\r\n active: boolean\r\n) => {\r\n const shortText = ellipsis && !active ? ellipsize(text, ellipsis) : text;\r\n const lines = [];\r\n let currentLine = '';\r\n const words = shortText.split(' ');\r\n\r\n words.forEach(word => {\r\n const testLine = currentLine ? `${currentLine} ${word}` : word;\r\n const testWidth = testLine.length * fontSize * 1;\r\n\r\n if (testWidth > maxWidth) {\r\n lines.push(currentLine);\r\n currentLine = word;\r\n } else {\r\n currentLine = testLine;\r\n }\r\n });\r\n\r\n if (currentLine) {\r\n lines.push(currentLine);\r\n }\r\n\r\n const width =\r\n Math.min(\r\n maxWidth,\r\n lines.reduce(\r\n (max, line) => Math.max(max, line.length * fontSize * 0.4),\r\n 0\r\n )\r\n ) + 14;\r\n const height = lines.length * fontSize + 6;\r\n\r\n return { width, height, text: lines.join('\\n'), lineCount: lines.length };\r\n};\r\n\r\nexport interface LabelProps {\r\n /**\r\n * Text to render.\r\n */\r\n text: string;\r\n\r\n /**\r\n * Font URL.\r\n * Reference: https://github.com/reaviz/reagraph/issues/23\r\n */\r\n fontUrl?: string;\r\n\r\n /**\r\n * Size of the font.\r\n */\r\n fontSize?: number;\r\n\r\n /**\r\n * Color of the text.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Stroke of the text.\r\n */\r\n stroke?: ColorRepresentation;\r\n\r\n /**\r\n * Opacity for the label.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The lenth of which to start the ellipsis.\r\n */\r\n ellipsis?: number;\r\n\r\n /**\r\n * Whether the label is active ( dragging, hover, focus ).\r\n */\r\n active?: boolean;\r\n\r\n /**\r\n * Rotation of the label.\r\n */\r\n rotation?: Euler | [number, number, number];\r\n\r\n /**\r\n * Maximum width of the label.\r\n */\r\n maxWidth?: number;\r\n\r\n /**\r\n * Background color of the label.\r\n */\r\n backgroundColor?: ColorRepresentation;\r\n\r\n /**\r\n * Border radius of the label.\r\n */\r\n borderRadius?: number;\r\n\r\n /**\r\n * Type of the label.\r\n */\r\n type?: 'node' | 'edge';\r\n\r\n /**\r\n * label visible or not\r\n */\r\n labelVisible?: boolean;\r\n}\r\n\r\nexport const Label: FC = ({\r\n text,\r\n fontSize,\r\n fontUrl,\r\n color,\r\n opacity,\r\n stroke,\r\n active,\r\n rotation,\r\n maxWidth = 100,\r\n ellipsis = 100,\r\n backgroundColor,\r\n borderRadius,\r\n labelVisible = true\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const normalizedBackgroundColor = useMemo(\r\n () => new Color(backgroundColor),\r\n [backgroundColor]\r\n );\r\n const normalizedStroke = useMemo(\r\n () => (stroke ? new Color(stroke) : undefined),\r\n [stroke]\r\n );\r\n\r\n const {\r\n width,\r\n height,\r\n text: processedText,\r\n lineCount\r\n } = useMemo(\r\n () => calculateTextSize(text, fontSize, maxWidth, ellipsis, active),\r\n [text, fontSize, maxWidth, ellipsis, active]\r\n );\r\n\r\n return (\r\n \r\n {backgroundColor ? (\r\n \r\n \r\n \r\n {processedText}\r\n \r\n \r\n \r\n \r\n ) : (\r\n \r\n {processedText}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nLabel.defaultProps = {\r\n opacity: 1,\r\n fontSize: 4,\r\n color: '#2A6475',\r\n ellipsis: 100\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { Color, ColorRepresentation, DoubleSide } from 'three';\r\nimport { animationConfig } from '../utils/animation';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Billboard } from 'glodrei';\r\n\r\nexport interface RingProps {\r\n /**\r\n * The color of the ring.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Whether the ring should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The size of the ring.\r\n */\r\n size?: number;\r\n\r\n /**\r\n * The opacity of the ring.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The stroke width of the ring.\r\n */\r\n strokeWidth?: number;\r\n\r\n /**\r\n * The inner radius of the ring.\r\n * Default value: 4\r\n */\r\n innerRadius?: number;\r\n\r\n /**\r\n * The number of segments in the ring geometry.\r\n * Default value: 25\r\n */\r\n segments?: number;\r\n}\r\n\r\nexport const Ring: FC = ({\r\n color,\r\n size,\r\n opacity,\r\n animated,\r\n strokeWidth,\r\n innerRadius = 2,\r\n segments = 50\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n\r\n const { ringSize, ringOpacity } = useSpring({\r\n from: {\r\n ringOpacity: 0,\r\n ringSize: [0.00001, 0.00001, 0.00001]\r\n },\r\n to: {\r\n ringOpacity: opacity,\r\n ringSize: [size / 2, size / 2, 1]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const strokeWidthFraction = strokeWidth / 10;\r\n const outerRadius = innerRadius + strokeWidthFraction;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nRing.defaultProps = {\r\n color: '#D8E6EA',\r\n size: 1,\r\n opacity: 0.5,\r\n strokeWidth: 5\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { animationConfig } from '../../utils/animation';\r\nimport { Color, DoubleSide } from 'three';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Ring } from '../Ring';\r\nimport { useStore } from '../../store';\r\n\r\nexport const Sphere: FC = ({\r\n color,\r\n id,\r\n size,\r\n active,\r\n selected,\r\n opacity,\r\n animated,\r\n showRing\r\n}) => {\r\n const { scale, nodeOpacity } = useSpring({\r\n from: {\r\n // Note: This prevents incorrect scaling w/ 0\r\n scale: [0.00001, 0.00001, 0.00001],\r\n nodeOpacity: 0\r\n },\r\n to: {\r\n scale: active\r\n ? [size * 1.05, size * 1.05, size * 1.05]\r\n : [size, size, size],\r\n nodeOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const theme = useStore(state => state.theme);\r\n\r\n return (\r\n <>\r\n \r\n \r\n \r\n \r\n {(showRing || selected || active) && (\r\n \r\n \r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nSphere.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import CameraControls from 'camera-controls';\r\nimport { createContext, useContext } from 'react';\r\n\r\nexport interface CameraControlsContextProps {\r\n /**\r\n * The camera controls object.\r\n */\r\n controls: CameraControls | null;\r\n\r\n /**\r\n * A function that resets the camera controls.\r\n * If the optional `animated` argument is true, the reset is animated.\r\n */\r\n resetControls: (animated?: boolean) => void;\r\n\r\n /**\r\n * A function that zooms in the camera.\r\n */\r\n zoomIn: () => void;\r\n\r\n /**\r\n * A function that zooms out the camera.\r\n */\r\n zoomOut: () => void;\r\n\r\n /**\r\n * A function that dollies in the camera.\r\n */\r\n dollyIn: (distance?: number) => void;\r\n\r\n /**\r\n * A function that dollies out the camera.\r\n */\r\n dollyOut: (distance?: number) => void;\r\n\r\n /**\r\n * A function that pans the camera to the left.\r\n */\r\n panLeft: () => void;\r\n\r\n /**\r\n * A function that pans the camera to the right.\r\n */\r\n panRight: () => void;\r\n\r\n /**\r\n * A function that pans the camera upwards.\r\n */\r\n panUp: () => void;\r\n\r\n /**\r\n * A function that pans the camera downwards.\r\n */\r\n panDown: () => void;\r\n}\r\n\r\nexport const CameraControlsContext = createContext({\r\n controls: null,\r\n resetControls: () => undefined,\r\n zoomIn: () => undefined,\r\n zoomOut: () => undefined,\r\n dollyIn: () => undefined,\r\n dollyOut: () => undefined,\r\n panLeft: () => undefined,\r\n panRight: () => undefined,\r\n panUp: () => undefined,\r\n panDown: () => undefined\r\n});\r\n\r\nexport const useCameraControls = () => {\r\n const context = useContext(CameraControlsContext);\r\n\r\n if (context === undefined) {\r\n throw new Error(\r\n '`useCameraControls` hook must be used within a `ControlsProvider` component'\r\n );\r\n }\r\n\r\n return context;\r\n};\r\n","import React, {\r\n FC,\r\n useRef,\r\n useEffect,\r\n useCallback,\r\n forwardRef,\r\n Ref,\r\n useImperativeHandle,\r\n useMemo,\r\n ReactNode\r\n} from 'react';\r\nimport { useThree, useFrame, extend } from '@react-three/fiber';\r\nimport {\r\n MOUSE,\r\n Vector2,\r\n Vector3,\r\n Vector4,\r\n Quaternion,\r\n Matrix4,\r\n Spherical,\r\n Box3,\r\n Sphere,\r\n Raycaster,\r\n MathUtils\r\n} from 'three';\r\nimport ThreeCameraControls from 'camera-controls';\r\nimport {\r\n CameraControlsContext,\r\n CameraControlsContextProps\r\n} from './useCameraControls';\r\nimport { useHotkeys } from 'reakeys';\r\nimport * as holdEvent from 'hold-event';\r\nimport { useStore } from '../store';\r\n\r\n// Install the camera controls\r\n// Use a subset for better three shaking\r\nThreeCameraControls.install({\r\n THREE: {\r\n MOUSE: MOUSE,\r\n Vector2: Vector2,\r\n Vector3: Vector3,\r\n Vector4: Vector4,\r\n Quaternion: Quaternion,\r\n Matrix4: Matrix4,\r\n Spherical: Spherical,\r\n Box3: Box3,\r\n Sphere: Sphere,\r\n Raycaster: Raycaster,\r\n MathUtils: {\r\n DEG2RAD: MathUtils?.DEG2RAD,\r\n clamp: MathUtils?.clamp\r\n }\r\n }\r\n});\r\n\r\n// Extend r3f with the new controls\r\nextend({ ThreeCameraControls });\r\n\r\nconst KEY_CODES = {\r\n ARROW_LEFT: 37,\r\n ARROW_UP: 38,\r\n ARROW_RIGHT: 39,\r\n ARROW_DOWN: 40\r\n};\r\n\r\nconst leftKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_LEFT, 100);\r\nconst rightKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_RIGHT, 100);\r\nconst upKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_UP, 100);\r\nconst downKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_DOWN, 100);\r\n\r\nexport type CameraMode = 'pan' | 'rotate' | 'orbit';\r\n\r\nexport interface CameraControlsProps {\r\n /**\r\n * Mode of the camera.\r\n */\r\n mode?: CameraMode;\r\n\r\n /**\r\n * Children symbols.\r\n */\r\n children?: ReactNode;\r\n\r\n /**\r\n * Animate transitions to centering.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the controls are enabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The maximum distance for the camera.\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * The minimum distance for the camera.\r\n */\r\n minDistance?: number;\r\n}\r\n\r\nexport type CameraControlsRef = CameraControlsContextProps;\r\n\r\nexport const CameraControls: FC<\r\n CameraControlsProps & { ref?: Ref }\r\n> = forwardRef(\r\n (\r\n { mode, children, animated, disabled, minDistance, maxDistance },\r\n ref: Ref\r\n ) => {\r\n const cameraRef = useRef(null);\r\n const camera = useThree(state => state.camera);\r\n const gl = useThree(state => state.gl);\r\n const isOrbiting = mode === 'orbit';\r\n const setPanning = useStore(state => state.setPanning);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n useFrame((_state, delta) => {\r\n if (cameraRef.current?.enabled) {\r\n cameraRef.current?.update(delta);\r\n }\r\n\r\n if (isOrbiting) {\r\n cameraRef.current.azimuthAngle += 20 * delta * MathUtils.DEG2RAD;\r\n }\r\n }, -1);\r\n\r\n useEffect(() => () => cameraRef.current?.dispose(), []);\r\n\r\n const zoomIn = useCallback(() => {\r\n cameraRef.current?.zoom(camera.zoom / 2, animated);\r\n }, [animated, camera.zoom]);\r\n\r\n const zoomOut = useCallback(() => {\r\n cameraRef.current?.zoom(-camera.zoom / 2, animated);\r\n }, [animated, camera.zoom]);\r\n\r\n const dollyIn = useCallback(\r\n distance => {\r\n cameraRef.current?.dolly(distance, animated);\r\n },\r\n [animated]\r\n );\r\n\r\n const dollyOut = useCallback(\r\n distance => {\r\n cameraRef.current?.dolly(distance, animated);\r\n },\r\n [animated]\r\n );\r\n\r\n const panRight = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(-0.03 * event.deltaTime, 0, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panLeft = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0.03 * event.deltaTime, 0, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panUp = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0, 0.03 * event.deltaTime, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panDown = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0, -0.03 * event.deltaTime, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const onKeyDown = useCallback(\r\n event => {\r\n if (event.code === 'Space') {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n }\r\n }\r\n },\r\n [mode]\r\n );\r\n\r\n const onKeyUp = useCallback(\r\n event => {\r\n if (event.code === 'Space') {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n }\r\n }\r\n },\r\n [mode]\r\n );\r\n\r\n useEffect(() => {\r\n if (!disabled) {\r\n leftKey.addEventListener('holding', panLeft);\r\n rightKey.addEventListener('holding', panRight);\r\n upKey.addEventListener('holding', panUp);\r\n downKey.addEventListener('holding', panDown);\r\n\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', onKeyDown);\r\n window.addEventListener('keyup', onKeyUp);\r\n }\r\n }\r\n\r\n return () => {\r\n leftKey.removeEventListener('holding', panLeft);\r\n rightKey.removeEventListener('holding', panRight);\r\n upKey.removeEventListener('holding', panUp);\r\n downKey.removeEventListener('holding', panDown);\r\n\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', onKeyDown);\r\n window.removeEventListener('keyup', onKeyUp);\r\n }\r\n };\r\n }, [disabled, onKeyDown, onKeyUp, panDown, panLeft, panRight, panUp]);\r\n\r\n useEffect(() => {\r\n if (disabled) {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\r\n cameraRef.current.mouseButtons.middle = ThreeCameraControls.ACTION.NONE;\r\n cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.NONE;\r\n } else {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.TRUCK;\r\n cameraRef.current.mouseButtons.middle =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.DOLLY;\r\n }\r\n }, [disabled]);\r\n\r\n useEffect(() => {\r\n const onControl = () => setPanning(true);\r\n const onControlEnd = () => setPanning(false);\r\n\r\n const ref = cameraRef.current;\r\n if (ref) {\r\n ref.addEventListener('control', onControl);\r\n ref.addEventListener('controlend', onControlEnd);\r\n }\r\n\r\n return () => {\r\n if (ref) {\r\n ref.removeEventListener('control', onControl);\r\n ref.removeEventListener('controlend', onControlEnd);\r\n }\r\n };\r\n }, [cameraRef, setPanning]);\r\n\r\n useEffect(() => {\r\n // If a node is being dragged, disable the camera controls\r\n if (draggingId) {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\r\n } else {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n }\r\n }\r\n }, [draggingId, mode]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Zoom In',\r\n disabled,\r\n category: 'Graph',\r\n keys: 'command+shift+i',\r\n callback: event => {\r\n event.preventDefault();\r\n zoomIn();\r\n }\r\n },\r\n {\r\n name: 'Zoom Out',\r\n category: 'Graph',\r\n disabled,\r\n keys: 'command+shift+o',\r\n callback: event => {\r\n event.preventDefault();\r\n zoomOut();\r\n }\r\n }\r\n ]);\r\n\r\n const values = useMemo(\r\n () => ({\r\n controls: cameraRef.current,\r\n zoomIn: () => zoomIn(),\r\n zoomOut: () => zoomOut(),\r\n dollyIn: (distance = 1000) => dollyIn(distance),\r\n dollyOut: (distance = -1000) => dollyOut(distance),\r\n panLeft: (deltaTime = 100) => panLeft({ deltaTime }),\r\n panRight: (deltaTime = 100) => panRight({ deltaTime }),\r\n panDown: (deltaTime = 100) => panDown({ deltaTime }),\r\n panUp: (deltaTime = 100) => panUp({ deltaTime }),\r\n resetControls: (animated?: boolean) =>\r\n cameraRef.current?.reset(animated)\r\n }),\r\n // eslint-disable-next-line\r\n [zoomIn, zoomOut, panLeft, panRight, panDown, panUp, cameraRef.current]\r\n );\r\n\r\n useImperativeHandle(ref, () => values);\r\n\r\n return (\r\n \r\n \r\n {children}\r\n \r\n );\r\n }\r\n);\r\n\r\nCameraControls.defaultProps = {\r\n mode: 'rotate',\r\n minDistance: 1000,\r\n maxDistance: 50000\r\n};\r\n","import { PerspectiveCamera } from 'three';\r\nimport { InternalGraphPosition } from '../types';\r\n\r\n/**\r\n * Get the visible height at the z depth.\r\n * Ref: https://discourse.threejs.org/t/functions-to-calculate-the-visible-width-height-at-a-given-z-depth-from-a-perspective-camera/269\r\n */\r\nfunction visibleHeightAtZDepth(depth: number, camera: PerspectiveCamera) {\r\n // compensate for cameras not positioned at z=0\r\n const cameraOffset = camera.position.z;\r\n if (depth < cameraOffset) depth -= cameraOffset;\r\n else depth += cameraOffset;\r\n\r\n // vertical fov in radians\r\n const vFOV = ((camera.fov / camera.zoom) * Math.PI) / 180;\r\n\r\n // Math.abs to ensure the result is always positive\r\n return 2 * Math.tan(vFOV / 2) * Math.abs(depth);\r\n}\r\n\r\n/**\r\n * Get the visible width at the z depth.\r\n */\r\nfunction visibleWidthAtZDepth(depth: number, camera: PerspectiveCamera) {\r\n const height = visibleHeightAtZDepth(depth, camera);\r\n return height * camera.aspect;\r\n}\r\n\r\n/**\r\n * Returns whether the node is in view of the camera.\r\n */\r\nexport function isNodeInView(\r\n camera: PerspectiveCamera,\r\n nodePosition: InternalGraphPosition\r\n): boolean {\r\n const visibleWidth = visibleWidthAtZDepth(1, camera);\r\n const visibleHeight = visibleHeightAtZDepth(1, camera);\r\n\r\n // The boundary coordinates of the area visible to the camera relative to the scene\r\n const visibleArea = {\r\n x0: camera?.position?.x - visibleWidth / 2,\r\n x1: camera?.position?.x + visibleWidth / 2,\r\n y0: camera?.position?.y - visibleHeight / 2,\r\n y1: camera?.position?.y + visibleHeight / 2\r\n };\r\n\r\n return (\r\n nodePosition?.x > visibleArea.x0 &&\r\n nodePosition?.x < visibleArea.x1 &&\r\n nodePosition?.y > visibleArea.y0 &&\r\n nodePosition?.y < visibleArea.y1\r\n );\r\n}\r\n\r\n/**\r\n * Get the closest axis to a given angle.\r\n */\r\nexport function getClosestAxis(angle: number, axes: number[]) {\r\n return axes.reduce((prev, curr) =>\r\n Math.abs(curr - (angle % Math.PI)) < Math.abs(prev - (angle % Math.PI))\r\n ? curr\r\n : prev\r\n );\r\n}\r\n\r\n/**\r\n * Get how far an angle is from the closest 2D axis in radians.\r\n */\r\nexport function getDegreesToClosest2dAxis(\r\n horizontalAngle: number,\r\n verticalAngle: number\r\n) {\r\n const closestHorizontalAxis = getClosestAxis(horizontalAngle, [0, Math.PI]);\r\n const closestVerticalAxis = getClosestAxis(verticalAngle, [\r\n Math.PI / 2,\r\n (3 * Math.PI) / 2\r\n ]);\r\n\r\n return {\r\n horizontalRotation: closestHorizontalAxis - (horizontalAngle % Math.PI),\r\n verticalRotation: closestVerticalAxis - (verticalAngle % Math.PI)\r\n };\r\n}\r\n","import { useThree } from '@react-three/fiber';\r\nimport { useCameraControls } from './useCameraControls';\r\nimport { useCallback, useLayoutEffect, useRef, useState } from 'react';\r\nimport { Vector3, Box3, PerspectiveCamera } from 'three';\r\nimport { useHotkeys } from 'reakeys';\r\nimport { getLayoutCenter } from '../utils/layout';\r\nimport { InternalGraphNode } from '../types';\r\nimport { useStore } from '../store';\r\nimport { isNodeInView, getDegreesToClosest2dAxis } from './utils';\r\nimport { LayoutTypes } from 'layout/types';\r\n\r\nconst PADDING = 50;\r\n\r\nexport interface CenterNodesParams {\r\n animated?: boolean;\r\n centerOnlyIfNodesNotInView?: boolean;\r\n}\r\n\r\nexport interface FitNodesParams {\r\n animated?: boolean;\r\n fitOnlyIfNodesNotInView?: boolean;\r\n}\r\n\r\nexport interface CenterGraphInput {\r\n /**\r\n * Whether the animate the transition or not.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the center graph function is disabled or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The layout type of the graph used to determine rotation logic.\r\n */\r\n layoutType: LayoutTypes;\r\n}\r\n\r\nexport interface CenterGraphOutput {\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodes - An array of `InternalGraphNode` objects to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param animated - A boolean flag that determines whether the centering action should be animated.\r\n *\r\n * @param centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `nodes` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `nodes` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerNodes: (nodes: InternalGraphNode[], opts: CenterNodesParams) => void;\r\n\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `ids` are not currently in view. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerNodesById: (nodeIds: string[], opts?: CenterNodesParams) => void;\r\n\r\n /**\r\n * Fit all the given nodes into view of the camera.\r\n *\r\n * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\r\n * the view will fit to all nodes.\r\n *\r\n * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\r\n * only be fit if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the view will only be fit if one or more of the nodes\r\n * specified by `ids` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the view will be fit regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n fitNodesInViewById: (nodeIds: string[], opts?: FitNodesParams) => void;\r\n\r\n /**\r\n * Whether the graph is centered or not.\r\n */\r\n isCentered?: boolean;\r\n}\r\n\r\nexport const useCenterGraph = ({\r\n animated,\r\n disabled,\r\n layoutType\r\n}: CenterGraphInput): CenterGraphOutput => {\r\n const nodes = useStore(state => state.nodes);\r\n const [isCentered, setIsCentered] = useState(false);\r\n const invalidate = useThree(state => state.invalidate);\r\n const { controls } = useCameraControls();\r\n const camera = useThree(state => state.camera) as PerspectiveCamera;\r\n const mounted = useRef(false);\r\n\r\n const centerNodes = useCallback(\r\n async (nodes, opts?: CenterNodesParams) => {\r\n const animated = opts?.animated !== undefined ? opts?.animated : true;\r\n const centerOnlyIfNodesNotInView =\r\n opts?.centerOnlyIfNodesNotInView !== undefined\r\n ? opts?.centerOnlyIfNodesNotInView\r\n : false;\r\n\r\n if (\r\n !mounted.current ||\r\n !centerOnlyIfNodesNotInView ||\r\n (centerOnlyIfNodesNotInView &&\r\n nodes?.some(node => !isNodeInView(camera, node.position)))\r\n ) {\r\n // Centers the graph based on the central most node\r\n const { x, y, z } = getLayoutCenter(nodes);\r\n\r\n await controls.setTarget(x, y, z, animated);\r\n\r\n if (!isCentered) {\r\n setIsCentered(true);\r\n }\r\n\r\n invalidate();\r\n }\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [invalidate, controls, nodes]\r\n );\r\n\r\n const fitNodesInView = useCallback(\r\n async (\r\n nodes,\r\n opts: FitNodesParams = { animated: true, fitOnlyIfNodesNotInView: false }\r\n ) => {\r\n const { fitOnlyIfNodesNotInView } = opts;\r\n\r\n if (\r\n !fitOnlyIfNodesNotInView ||\r\n (fitOnlyIfNodesNotInView &&\r\n nodes?.some(node => !isNodeInView(camera, node.position)))\r\n ) {\r\n const { minX, maxX, minY, maxY, minZ, maxZ } = getLayoutCenter(nodes);\r\n\r\n if (!layoutType.includes('3d')) {\r\n // fitToBox will auto rotate to the closest axis including the z axis,\r\n // which is not desired for 2D graphs\r\n // So get the rotation to the closest flat axis for 2D graphs\r\n const { horizontalRotation, verticalRotation } =\r\n getDegreesToClosest2dAxis(\r\n controls?.azimuthAngle,\r\n controls?.polarAngle\r\n );\r\n\r\n void controls?.rotate(horizontalRotation, verticalRotation, true);\r\n }\r\n\r\n await controls?.zoomTo(1, opts?.animated);\r\n\r\n await controls?.fitToBox(\r\n new Box3(\r\n new Vector3(minX, minY, minZ),\r\n new Vector3(maxX, maxY, maxZ)\r\n ),\r\n opts?.animated,\r\n {\r\n cover: false,\r\n paddingLeft: PADDING,\r\n paddingRight: PADDING,\r\n paddingBottom: PADDING,\r\n paddingTop: PADDING\r\n }\r\n );\r\n }\r\n },\r\n [camera, controls, layoutType]\r\n );\r\n\r\n const getNodesById = useCallback(\r\n (nodeIds: string[]) => {\r\n let mappedNodes: InternalGraphNode[] | null = null;\r\n\r\n if (nodeIds?.length) {\r\n // Map the node ids to the actual nodes\r\n mappedNodes = nodeIds.reduce((acc, id) => {\r\n const node = nodes.find(n => n.id === id);\r\n if (node) {\r\n acc.push(node);\r\n } else {\r\n throw new Error(\r\n `Attempted to center ${id} but it was not found in the nodes`\r\n );\r\n }\r\n\r\n return acc;\r\n }, []);\r\n }\r\n\r\n return mappedNodes;\r\n },\r\n [nodes]\r\n );\r\n\r\n const centerNodesById = useCallback(\r\n (nodeIds: string[], opts: CenterNodesParams) => {\r\n const mappedNodes = getNodesById(nodeIds);\r\n\r\n centerNodes(mappedNodes || nodes, {\r\n animated,\r\n centerOnlyIfNodesNotInView: opts?.centerOnlyIfNodesNotInView\r\n });\r\n },\r\n [animated, centerNodes, getNodesById, nodes]\r\n );\r\n\r\n const fitNodesInViewById = useCallback(\r\n async (nodeIds: string[], opts: FitNodesParams) => {\r\n const mappedNodes = getNodesById(nodeIds);\r\n\r\n await fitNodesInView(mappedNodes || nodes, { animated, ...opts });\r\n },\r\n [animated, fitNodesInView, getNodesById, nodes]\r\n );\r\n\r\n useLayoutEffect(() => {\r\n async function load() {\r\n // Once we've loaded controls and we have nodes, let's recenter\r\n if (controls && nodes?.length) {\r\n if (!mounted.current) {\r\n // Center the graph once nodes are loaded on mount\r\n await centerNodes(nodes, { animated: false });\r\n await fitNodesInView(nodes, { animated: false });\r\n mounted.current = true;\r\n }\r\n }\r\n }\r\n\r\n load();\r\n }, [controls, centerNodes, nodes, animated, camera, fitNodesInView]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Center',\r\n disabled,\r\n category: 'Graph',\r\n keys: ['command+shift+c'],\r\n callback: () => centerNodes(nodes)\r\n }\r\n ]);\r\n\r\n return { centerNodes, centerNodesById, fitNodesInViewById, isCentered };\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { a, useSpring } from '@react-spring/three';\r\nimport { TextureLoader, LinearFilter, DoubleSide } from 'three';\r\nimport { animationConfig } from '../../utils';\r\nimport { NodeRendererProps } from '../../types';\r\n\r\nexport interface IconProps extends NodeRendererProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n}\r\n\r\nexport const Icon: FC = ({ image, id, size, opacity, animated }) => {\r\n const texture = useMemo(() => new TextureLoader().load(image), [image]);\r\n\r\n const { scale, spriteOpacity } = useSpring({\r\n from: {\r\n scale: [0.00001, 0.00001, 0.00001],\r\n spriteOpacity: 0\r\n },\r\n to: {\r\n scale: [size, size, size],\r\n spriteOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nIcon.defaultProps = {\r\n opacity: 1\r\n};\r\n","import React, { FC } from 'react';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Sphere } from './Sphere';\r\nimport { Icon } from './Icon';\r\n\r\nexport interface SphereWithIconProps extends NodeRendererProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n}\r\n\r\nexport const SphereWithIcon: FC = ({\r\n color,\r\n id,\r\n size,\r\n opacity,\r\n node,\r\n active,\r\n animated,\r\n image,\r\n selected\r\n}) => (\r\n <>\r\n \r\n \r\n \r\n);\r\n\r\nSphereWithIcon.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { a, useSpring } from '@react-spring/three';\r\nimport { animationConfig } from '../../utils';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Billboard, Svg as DreiSvg, SvgProps as DreiSvgProps } from 'glodrei';\r\nimport { Color, DoubleSide } from 'three';\r\n\r\nexport type SvgProps = NodeRendererProps &\r\n Omit & {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n };\r\n\r\nexport const Svg: FC = ({\r\n id,\r\n image,\r\n color,\r\n size,\r\n opacity,\r\n animated,\r\n ...rest\r\n}) => {\r\n const normalizedSize = size / 25;\r\n\r\n const { scale } = useSpring({\r\n from: {\r\n scale: [0.00001, 0.00001, 0.00001]\r\n },\r\n to: {\r\n scale: [normalizedSize, normalizedSize, normalizedSize]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nSvg.defaultProps = {\r\n opacity: 1\r\n};\r\n","import React, { FC } from 'react';\r\nimport { Sphere } from './Sphere';\r\nimport { Svg, SvgProps } from './Svg';\r\nimport { ColorRepresentation } from 'three';\r\n\r\nexport interface SphereWithSvgProps extends SvgProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n\r\n /**\r\n * The color of the svg fill.\r\n */\r\n svgFill?: ColorRepresentation;\r\n}\r\n\r\nexport const SphereWithSvg: FC = ({\r\n color,\r\n id,\r\n size,\r\n opacity,\r\n node,\r\n svgFill,\r\n active,\r\n animated,\r\n image,\r\n selected,\r\n ...rest\r\n}) => (\r\n <>\r\n \r\n \r\n \r\n);\r\n\r\nSphereWithSvg.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import React, {\r\n FC,\r\n ReactNode,\r\n useCallback,\r\n useMemo,\r\n useRef,\r\n useState\r\n} from 'react';\r\nimport { Group } from 'three';\r\nimport { animationConfig } from '../utils';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Sphere } from './nodes/Sphere';\r\nimport { Label } from './Label';\r\nimport {\r\n NodeContextMenuProps,\r\n ContextMenuEvent,\r\n InternalGraphNode,\r\n NodeRenderer,\r\n CollapseProps\r\n} from '../types';\r\nimport { Html, useCursor } from 'glodrei';\r\nimport { useCameraControls } from '../CameraControls';\r\nimport { useStore } from '../store';\r\nimport { useDrag } from '../utils/useDrag';\r\nimport { Icon } from './nodes';\r\nimport { useHoverIntent } from '../utils/useHoverIntent';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface NodeProps {\r\n /**\r\n * The unique identifier for the node.\r\n */\r\n id: string;\r\n\r\n /**\r\n * The parent nodes of the node.\r\n */\r\n parents?: string[];\r\n\r\n /**\r\n * Whether the node is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Whether the node is animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the node is draggable.\r\n */\r\n draggable?: boolean;\r\n\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The function to use to render the node.\r\n */\r\n renderNode?: NodeRenderer;\r\n\r\n /**\r\n * The context menu for the node.\r\n */\r\n contextMenu?: (event: ContextMenuEvent) => ReactNode;\r\n\r\n /**\r\n * The function to call when the pointer is over the node.\r\n */\r\n onPointerOver?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the pointer is out of the node.\r\n */\r\n onPointerOut?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is clicked.\r\n */\r\n onClick?: (\r\n node: InternalGraphNode,\r\n props?: CollapseProps,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is double clicked.\r\n */\r\n onDoubleClick?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is right clicked.\r\n */\r\n onContextMenu?: (\r\n node?: InternalGraphNode,\r\n props?: NodeContextMenuProps\r\n ) => void;\r\n\r\n /**\r\n * Triggered after a node was dragged.\r\n */\r\n onDragged?: (node: InternalGraphNode) => void;\r\n}\r\n\r\nexport const Node: FC = ({\r\n animated,\r\n disabled,\r\n id,\r\n draggable,\r\n labelFontUrl,\r\n contextMenu,\r\n onClick,\r\n onDoubleClick,\r\n onPointerOver,\r\n onDragged,\r\n onPointerOut,\r\n onContextMenu,\r\n renderNode\r\n}) => {\r\n const cameraControls = useCameraControls();\r\n const theme = useStore(state => state.theme);\r\n const node = useStore(state => state.nodes.find(n => n.id === id));\r\n const edges = useStore(state => state.edges);\r\n const draggingId = useStore(state => state.draggingId);\r\n const collapsedNodeIds = useStore(state => state.collapsedNodeIds);\r\n const setDraggingId = useStore(state => state.setDraggingId);\r\n const setNodePosition = useStore(state => state.setNodePosition);\r\n const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\r\n const isCollapsed = useStore(state => state.collapsedNodeIds.includes(id));\r\n const isActive = useStore(state => state.actives?.includes(id));\r\n const isSelected = useStore(state => state.selections?.includes(id));\r\n const hasSelections = useStore(state => state.selections?.length > 0);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const isDragging = draggingId === id;\r\n const {\r\n position,\r\n label,\r\n subLabel,\r\n size: nodeSize = 7,\r\n labelVisible = true\r\n } = node;\r\n\r\n const group = useRef(null);\r\n const [active, setActive] = useState(false);\r\n const [menuVisible, setMenuVisible] = useState(false);\r\n\r\n const shouldHighlight = active || isSelected || isActive;\r\n\r\n const selectionOpacity = hasSelections\r\n ? shouldHighlight\r\n ? theme.node.selectedOpacity\r\n : theme.node.inactiveOpacity\r\n : theme.node.opacity;\r\n\r\n const canCollapse = useMemo(() => {\r\n // If the node has outgoing edges, it can collapse via context menu\r\n const outboundLinks = edges.filter(l => l.source === id);\r\n\r\n return outboundLinks.length > 0 || isCollapsed;\r\n }, [edges, id, isCollapsed]);\r\n\r\n const onCollapse = useCallback(() => {\r\n if (canCollapse) {\r\n if (isCollapsed) {\r\n setCollapsedNodeIds(collapsedNodeIds.filter(p => p !== id));\r\n } else {\r\n setCollapsedNodeIds([...collapsedNodeIds, id]);\r\n }\r\n }\r\n }, [canCollapse, collapsedNodeIds, id, isCollapsed, setCollapsedNodeIds]);\r\n\r\n const [{ nodePosition, labelPosition, subLabelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n nodePosition: center ? [center.x, center.y, 0] : [0, 0, 0],\r\n labelPosition: [0, -(nodeSize + 4), 2],\r\n subLabelPosition: [0, -(nodeSize + 14), 2]\r\n },\r\n to: {\r\n nodePosition: position\r\n ? [\r\n position.x,\r\n position.y,\r\n shouldHighlight ? position.z + 50 : position.z\r\n ]\r\n : [0, 0, 0],\r\n labelPosition: [0, -(nodeSize + 4), 2],\r\n subLabelPosition: [0, -(nodeSize + 14), 2]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [isDragging, position, animated, nodeSize, shouldHighlight]\r\n );\r\n\r\n const bind = useDrag({\r\n draggable,\r\n position,\r\n // @ts-ignore\r\n set: pos => setNodePosition(id, pos),\r\n onDragStart: () => {\r\n setDraggingId(id);\r\n setActive(true);\r\n },\r\n onDragEnd: () => {\r\n setDraggingId(null);\r\n setActive(false);\r\n onDragged?.(node);\r\n }\r\n });\r\n\r\n useCursor(active && !draggingId && onClick !== undefined, 'pointer');\r\n useCursor(\r\n active && draggable && !isDragging && onClick === undefined,\r\n 'grab'\r\n );\r\n useCursor(isDragging, 'grabbing');\r\n\r\n const combinedActiveState = shouldHighlight || isDragging;\r\n const color = combinedActiveState\r\n ? node.activeFill || theme.node.activeFill\r\n : node.fill || theme.node.fill;\r\n\r\n const actualShowRing = node.showRing;\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled: disabled || isDragging,\r\n onPointerOver: (event: ThreeEvent) => {\r\n cameraControls.controls.truckSpeed = 0;\r\n setActive(true);\r\n onPointerOver?.(node, event);\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n cameraControls.controls.truckSpeed = 2.0;\r\n setActive(false);\r\n onPointerOut?.(node, event);\r\n }\r\n });\r\n\r\n const nodeComponent = useMemo(\r\n () =>\r\n renderNode ? (\r\n renderNode({\r\n id,\r\n color,\r\n size: nodeSize,\r\n active: combinedActiveState,\r\n opacity: selectionOpacity,\r\n animated,\r\n selected: isSelected,\r\n node\r\n })\r\n ) : (\r\n <>\r\n {node.icon ? (\r\n \r\n ) : (\r\n \r\n )}\r\n \r\n ),\r\n [\r\n renderNode,\r\n id,\r\n color,\r\n nodeSize,\r\n combinedActiveState,\r\n selectionOpacity,\r\n animated,\r\n isSelected,\r\n node,\r\n actualShowRing\r\n ]\r\n );\r\n\r\n const labelComponent = useMemo(\r\n () =>\r\n label && (\r\n <>\r\n \r\n \r\n \r\n {subLabel && (\r\n \r\n \r\n \r\n )}\r\n \r\n ),\r\n [\r\n active,\r\n isActive,\r\n isDragging,\r\n isSelected,\r\n label,\r\n labelFontUrl,\r\n labelPosition,\r\n labelVisible,\r\n selectionOpacity,\r\n subLabel,\r\n subLabelPosition,\r\n theme.node.label.activeColor,\r\n theme.node.label.color,\r\n theme.node.label.stroke,\r\n theme.node.subLabel?.activeColor,\r\n theme.node.subLabel?.color,\r\n theme.node.subLabel?.stroke,\r\n theme.node.label.fontSize,\r\n theme.node.label.maxWidth,\r\n theme.node.label.ellipsis,\r\n theme.node.label.backgroundColor,\r\n theme.node.label.borderRadius\r\n ]\r\n );\r\n\r\n const menuComponent = useMemo(\r\n () =>\r\n menuVisible &&\r\n contextMenu && (\r\n \r\n {contextMenu({\r\n data: node,\r\n canCollapse,\r\n isCollapsed,\r\n onCollapse,\r\n onClose: () => setMenuVisible(false)\r\n })}\r\n \r\n ),\r\n [menuVisible, contextMenu, node, canCollapse, isCollapsed, onCollapse]\r\n );\r\n\r\n return (\r\n ) => {\r\n if (!disabled && !isDragging) {\r\n onClick?.(\r\n node,\r\n {\r\n canCollapse,\r\n isCollapsed\r\n },\r\n event\r\n );\r\n }\r\n }}\r\n onDoubleClick={(event: ThreeEvent) => {\r\n event.stopPropagation();\r\n if (!disabled && !isDragging) {\r\n onDoubleClick?.(node, event);\r\n }\r\n }}\r\n onContextMenu={() => {\r\n if (!disabled) {\r\n setMenuVisible(true);\r\n onContextMenu?.(node, {\r\n canCollapse,\r\n isCollapsed,\r\n onCollapse\r\n });\r\n }\r\n }}\r\n {...(bind() as any)}\r\n >\r\n {nodeComponent}\r\n {menuComponent}\r\n {labelComponent}\r\n \r\n );\r\n};\r\n\r\nNode.defaultProps = {\r\n draggable: false\r\n};\r\n","import React, { FC, useMemo, useRef, useEffect, useCallback } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Color, ColorRepresentation, Mesh, DoubleSide, Vector3 } from 'three';\r\nimport { animationConfig } from '../utils';\r\nimport { useStore } from '../store';\r\n\r\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\r\n\r\nexport interface ArrowProps {\r\n /**\r\n * Whether the arrow should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The color of the arrow.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * The length of the arrow.\r\n */\r\n length: number;\r\n\r\n /**\r\n * The opacity of the arrow.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The position of the arrow in 3D space.\r\n */\r\n position: Vector3;\r\n\r\n /**\r\n * The rotation of the arrow in 3D space.\r\n */\r\n rotation: Vector3;\r\n\r\n /**\r\n * The size of the arrow.\r\n */\r\n size: number;\r\n\r\n /**\r\n * A function that is called when the arrow is right-clicked.\r\n */\r\n onContextMenu?: () => void;\r\n\r\n /**\r\n * A function that is called when the arrow is selected or deselected.\r\n */\r\n onActive?: (state: boolean) => void;\r\n}\r\n\r\nexport const Arrow: FC = ({\r\n animated,\r\n color,\r\n length,\r\n opacity,\r\n position,\r\n rotation,\r\n size,\r\n onActive,\r\n onContextMenu\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const meshRef = useRef(null);\r\n const draggingId = useStore(state => state.draggingId);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const [{ pos, arrowOpacity }] = useSpring(\r\n () => ({\r\n from: {\r\n pos: center ? [center.x, center.y, center.z] : [0, 0, 0],\r\n arrowOpacity: 0\r\n },\r\n to: {\r\n pos: [position.x, position.y, position.z],\r\n arrowOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [animated, draggingId, opacity, position]\r\n );\r\n\r\n const setQuaternion = useCallback(() => {\r\n const axis = new Vector3(0, 1, 0);\r\n meshRef.current?.quaternion.setFromUnitVectors(axis, rotation);\r\n }, [rotation, meshRef]);\r\n\r\n useEffect(() => setQuaternion(), [setQuaternion]);\r\n\r\n return (\r\n onActive(true)}\r\n onPointerOut={() => onActive(false)}\r\n onPointerDown={event => {\r\n // context menu controls\r\n if (event.nativeEvent.buttons === 2) {\r\n event.stopPropagation();\r\n onContextMenu();\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nArrow.defaultProps = {\r\n size: 1,\r\n opacity: 0.5,\r\n color: '#D8E6EA'\r\n};\r\n","import React, { FC, useEffect, useMemo, useRef } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { animationConfig, getCurve } from '../utils';\r\nimport {\r\n Vector3,\r\n TubeGeometry,\r\n ColorRepresentation,\r\n Color,\r\n Curve\r\n} from 'three';\r\nimport { useStore } from '../store';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface LineProps {\r\n /**\r\n * Whether the line should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The color of the line.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Whether the line should be curved.\r\n */\r\n curved: boolean;\r\n\r\n /**\r\n * The curve of the line in 3D space.\r\n */\r\n curve: Curve;\r\n\r\n /**\r\n * The unique identifier of the line.\r\n */\r\n id: string;\r\n\r\n /**\r\n * The opacity of the line.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The size of the line.\r\n */\r\n size?: number;\r\n\r\n /**\r\n * A function that is called when the line is clicked.\r\n */\r\n onClick?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the line is right-clicked.\r\n */\r\n onContextMenu?: () => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved over the line.\r\n */\r\n onPointerOver?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved out of the line.\r\n */\r\n onPointerOut?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * The offset of the curve.\r\n */\r\n curveOffset?: number;\r\n}\r\n\r\nexport const Line: FC = ({\r\n curveOffset,\r\n animated,\r\n color,\r\n curve,\r\n curved = false,\r\n id,\r\n opacity,\r\n size,\r\n onContextMenu,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const tubeRef = useRef(null);\r\n const draggingId = useStore(state => state.draggingId);\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const center = useStore(state => state.centerPosition);\r\n const mounted = useRef(false);\r\n\r\n // Do opacity seperate from vertices for perf\r\n const { lineOpacity } = useSpring({\r\n from: {\r\n lineOpacity: 0\r\n },\r\n to: {\r\n lineOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n useSpring(() => {\r\n const from = curve.getPoint(0);\r\n const to = curve.getPoint(1);\r\n return {\r\n from: {\r\n // Animate from center first time, then from the actual from point\r\n fromVertices: !mounted.current\r\n ? [center?.x, center?.y, center?.z || 0]\r\n : [to?.x, to?.y, to?.z || 0],\r\n toVertices: [from?.x, from?.y, from?.z || 0]\r\n },\r\n to: {\r\n fromVertices: [from?.x, from?.y, from?.z || 0],\r\n toVertices: [to?.x, to?.y, to?.z || 0]\r\n },\r\n onChange: event => {\r\n const { fromVertices, toVertices } = event.value;\r\n const fromVector = new Vector3(...fromVertices);\r\n const toVector = new Vector3(...toVertices);\r\n\r\n const curve = getCurve(fromVector, 0, toVector, 0, curved, curveOffset);\r\n tubeRef.current.copy(new TubeGeometry(curve, 20, size / 2, 5, false));\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n };\r\n }, [animated, draggingId, curve, size]);\r\n\r\n useEffect(() => {\r\n // Handle mount operation for initial render\r\n mounted.current = true;\r\n }, []);\r\n\r\n return (\r\n {\r\n // context menu controls\r\n if (event.nativeEvent.buttons === 2) {\r\n event.stopPropagation();\r\n onContextMenu();\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nLine.defaultProps = {\r\n color: '#000',\r\n size: 1,\r\n opacity: 1\r\n};\r\n","import React, { FC, useMemo, useState } from 'react';\nimport { useSpring, a } from '@react-spring/three';\nimport { Arrow, EdgeArrowPosition } from './Arrow';\nimport { Label } from './Label';\nimport {\n animationConfig,\n calculateEdgeCurveOffset,\n getArrowSize,\n getArrowVectors,\n getCurve,\n getLabelOffsetByType,\n getMidPoint,\n getVector\n} from '../utils';\nimport { Line } from './Line';\nimport { useStore } from '../store';\nimport { ContextMenuEvent, InternalGraphEdge } from '../types';\nimport { Html, useCursor } from 'glodrei';\nimport { useHoverIntent } from '../utils/useHoverIntent';\nimport { Euler, Vector3 } from 'three';\nimport { ThreeEvent } from '@react-three/fiber';\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 * 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 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) => React.ReactNode;\n\n /**\n * A function that is called when the edge is clicked.\n */\n onClick?: (edge: InternalGraphEdge, event: ThreeEvent) => 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\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\n ) => void;\n}\n\nconst LABEL_PLACEMENT_OFFSET = 3;\n\nexport const Edge: FC = ({\n animated,\n arrowPlacement,\n contextMenu,\n disabled,\n labelPlacement,\n id,\n interpolation,\n labelFontUrl,\n onContextMenu,\n onClick,\n onPointerOver,\n onPointerOut\n}) => {\n const theme = useStore(state => state.theme);\n const draggingId = useStore(state => state.draggingId);\n\n // UI states\n const [active, setActive] = useState(false);\n const [menuVisible, setMenuVisible] = useState(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 labelVisible = false,\n size = 1,\n backgroundColor\n } = edge;\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 // Edge properties\n const labelOffset = (size + theme.edge.label.fontSize) / 2;\n const [arrowLength, arrowSize] = useMemo(() => getArrowSize(size), [size]);\n const { curveOffset, curved } = useMemo(\n () =>\n calculateEdgeCurveOffset({\n edge,\n edges,\n curved: interpolation === 'curved'\n }),\n [edge, edges, interpolation]\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 arrowPlacement,\n curve,\n arrowLength\n );\n\n if (arrowPlacement === '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, arrowPlacement, 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 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 center = useStore(state => state.centerPosition);\n\n const selectionOpacity = hasSelections\n ? isSelected || isActive\n ? theme.edge.selectedOpacity\n : theme.edge.inactiveOpacity\n : theme.edge.opacity;\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 && !draggingId ? undefined : 0\n }\n }),\n [midPoint, animated, draggingId]\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 && !draggingId && onClick !== undefined, 'pointer');\n\n const { pointerOver, pointerOut } = useHoverIntent({\n disabled,\n onPointerOver: (event: ThreeEvent) => {\n setActive(true);\n onPointerOver?.(edge, event);\n },\n onPointerOut: (event: ThreeEvent) => {\n setActive(false);\n onPointerOut?.(edge, event);\n }\n });\n\n const arrowComponent = useMemo(\n () =>\n arrowPlacement !== 'none' && (\n {\n if (!disabled) {\n setMenuVisible(true);\n onContextMenu?.(edge);\n }\n }}\n />\n ),\n [\n active,\n animated,\n arrowLength,\n arrowPlacement,\n arrowPosition,\n arrowRotation,\n arrowSize,\n disabled,\n edge,\n isActive,\n isSelected,\n onContextMenu,\n selectionOpacity,\n theme.arrow.activeFill,\n theme.arrow.fill\n ]\n );\n\n const labelComponent = useMemo(\n () =>\n labelVisible &&\n label && (\n \n \n \n ),\n [\n active,\n isActive,\n isSelected,\n label,\n labelFontUrl,\n labelPosition,\n labelRotation,\n labelVisible,\n selectionOpacity,\n theme.edge.label.activeColor,\n theme.edge.label.color,\n theme.edge.label.fontSize,\n theme.edge.label.maxWidth,\n theme.edge.label.ellipsis,\n theme.edge.label.stroke,\n theme.edge.label.backgroundColor,\n theme.edge.label.borderRadius\n ]\n );\n\n const menuComponent = useMemo(\n () =>\n menuVisible &&\n contextMenu && (\n \n {contextMenu({ data: edge, onClose: () => setMenuVisible(false) })}\n \n ),\n [menuVisible, contextMenu, midPoint, edge]\n );\n\n const lineComponent = useMemo(\n () => (\n {\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 [\n active,\n animated,\n curve,\n curveOffset,\n curved,\n disabled,\n edge,\n id,\n isActive,\n isSelected,\n onClick,\n onContextMenu,\n pointerOut,\n pointerOver,\n selectionOpacity,\n size,\n theme.arrow.activeFill,\n theme.arrow.fill\n ]\n );\n\n return (\n \n {arrowComponent}\n {lineComponent}\n {menuComponent}\n {labelComponent}\n \n );\n};\n\nEdge.defaultProps = {\n labelPlacement: 'inline',\n arrowPlacement: 'end'\n};\n","import { useCallback, useRef } from 'react';\r\nimport {\r\n BoxGeometry,\r\n BufferGeometry,\r\n CylinderGeometry,\r\n Quaternion,\r\n TubeGeometry,\r\n Vector3\r\n} from 'three';\r\nimport { mergeBufferGeometries } from 'three-stdlib';\r\n\r\nimport { GraphState, useStore } from '../../store';\r\nimport { InternalGraphEdge } from '../../types';\r\nimport {\r\n getArrowSize,\r\n getArrowVectors,\r\n getVector,\r\n getCurve\r\n} from '../../utils';\r\nimport { EdgeArrowPosition } from '../Arrow';\r\nimport { EdgeInterpolation } from '../Edge';\r\n\r\nexport type UseEdgeGeometry = {\r\n getGeometries(edges: Array): Array;\r\n getGeometry(\r\n active: Array,\r\n inactive: Array\r\n ): BufferGeometry;\r\n};\r\n\r\nconst NULL_GEOMETRY = new BoxGeometry(0, 0, 0);\r\n\r\nexport function useEdgeGeometry(\r\n arrowPlacement: EdgeArrowPosition,\r\n interpolation: EdgeInterpolation\r\n): UseEdgeGeometry {\r\n // We don't want to rerun everything when the state changes,\r\n // but we do want to use the most recent nodes whenever `getGeometries`\r\n // or `getGeometry` is run, so we store it in a ref:\r\n const stateRef = useRef();\r\n const theme = useStore(state => state.theme);\r\n useStore(state => {\r\n stateRef.current = state;\r\n });\r\n\r\n const geometryCacheRef = useRef(new Map());\r\n\r\n const curved = interpolation === 'curved';\r\n const getGeometries = useCallback(\r\n (edges: Array): Array => {\r\n const geometries: Array = [];\r\n const cache = geometryCacheRef.current;\r\n\r\n const { nodes } = stateRef.current;\r\n\r\n edges.forEach(edge => {\r\n const { target, source, size = 1 } = edge;\r\n\r\n const from = nodes.find(node => node.id === source);\r\n const to = nodes.find(node => node.id === target);\r\n\r\n if (!from || !to) {\r\n return;\r\n }\r\n\r\n // Create hash so geometry can be reused if edge doesn't move:\r\n const hash = `fromX:${from.position.x},fromY:${from.position.y},toX:${to.position.x}},toY:${to.position.y}`;\r\n if (cache.has(hash)) {\r\n const geometry = cache.get(hash);\r\n geometries.push(geometry);\r\n return;\r\n }\r\n\r\n const fromVector = getVector(from);\r\n const fromOffset = from.size + theme.edge.label.fontSize;\r\n const toVector = getVector(to);\r\n const toOffset = to.size + theme.edge.label.fontSize;\r\n let curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n toVector,\r\n toOffset,\r\n curved\r\n );\r\n\r\n let edgeGeometry = new TubeGeometry(curve, 20, size / 2, 5, false);\r\n\r\n if (arrowPlacement === 'none') {\r\n geometries.push(edgeGeometry);\r\n cache.set(hash, edgeGeometry);\r\n return;\r\n }\r\n\r\n const [arrowLength, arrowSize] = getArrowSize(size);\r\n\r\n const [arrowPosition, arrowRotation] = getArrowVectors(\r\n arrowPlacement,\r\n curve,\r\n arrowLength\r\n );\r\n const quaternion = new Quaternion();\r\n quaternion.setFromUnitVectors(new Vector3(0, 1, 0), arrowRotation);\r\n\r\n const arrowGeometry = new CylinderGeometry(\r\n 0,\r\n arrowSize,\r\n arrowLength,\r\n 20,\r\n 1,\r\n true\r\n );\r\n arrowGeometry.applyQuaternion(quaternion);\r\n arrowGeometry.translate(\r\n arrowPosition.x,\r\n arrowPosition.y,\r\n arrowPosition.z\r\n );\r\n\r\n // Move edge so it doesn't stick through the arrow:\r\n if (arrowPlacement && arrowPlacement === 'end') {\r\n const curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n arrowPosition,\r\n 0,\r\n curved\r\n );\r\n edgeGeometry = new TubeGeometry(curve, 20, size / 2, 5, false);\r\n }\r\n\r\n const merged = mergeBufferGeometries([edgeGeometry, arrowGeometry]);\r\n geometries.push(merged);\r\n cache.set(hash, merged);\r\n });\r\n return geometries;\r\n },\r\n [arrowPlacement, curved, theme.edge.label.fontSize]\r\n );\r\n\r\n const getGeometry = useCallback(\r\n (\r\n active: Array,\r\n inactive: Array\r\n ): BufferGeometry => {\r\n const activeGeometries = getGeometries(active);\r\n const inactiveGeometries = getGeometries(inactive);\r\n\r\n return mergeBufferGeometries(\r\n [\r\n inactiveGeometries.length\r\n ? mergeBufferGeometries(inactiveGeometries)\r\n : NULL_GEOMETRY,\r\n activeGeometries.length\r\n ? mergeBufferGeometries(activeGeometries)\r\n : NULL_GEOMETRY\r\n ],\r\n true\r\n );\r\n },\r\n [getGeometries]\r\n );\r\n\r\n return {\r\n getGeometries,\r\n getGeometry\r\n };\r\n}\r\n","import { useCallback, useRef } from 'react';\r\n\r\nimport { useStore } from '../../store';\r\nimport { InternalGraphEdge } from '../../types';\r\n\r\nexport type EdgeEvents = {\r\n onClick?: (edge: InternalGraphEdge) => void;\r\n onContextMenu?: (edge?: InternalGraphEdge) => void;\r\n onPointerOver?: (edge: InternalGraphEdge) => void;\r\n onPointerOut?: (edge: InternalGraphEdge) => void;\r\n};\r\n\r\nexport function useEdgeEvents(\r\n events: EdgeEvents,\r\n contextMenu,\r\n disabled: boolean\r\n) {\r\n const { onClick, onContextMenu, onPointerOut, onPointerOver } = events;\r\n\r\n const edgeContextMenus = useStore(state => state.edgeContextMenus);\r\n const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\r\n\r\n const clickRef = useRef(false);\r\n const handleClick = useCallback(() => {\r\n clickRef.current = true;\r\n }, []);\r\n\r\n const contextMenuEventRef = useRef(false);\r\n const handleContextMenu = useCallback(() => {\r\n contextMenuEventRef.current = true;\r\n }, []);\r\n\r\n const handleIntersections = useCallback(\r\n (\r\n previous: Array,\r\n intersected: Array\r\n ) => {\r\n if (onClick && clickRef.current) {\r\n clickRef.current = false;\r\n if (!disabled) {\r\n intersected.forEach(edge => {\r\n onClick(edge);\r\n });\r\n }\r\n }\r\n\r\n if ((contextMenu || onContextMenu) && contextMenuEventRef.current) {\r\n contextMenuEventRef.current = false;\r\n if (!disabled) {\r\n intersected.forEach(edge => {\r\n if (!edgeContextMenus.has(edge.id)) {\r\n setEdgeContextMenus(new Set([...edgeContextMenus, edge.id]));\r\n onContextMenu?.(edge);\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (onPointerOver) {\r\n const over = intersected.filter(index => !previous.includes(index));\r\n over.forEach(edge => {\r\n onPointerOver(edge);\r\n });\r\n }\r\n\r\n if (onPointerOut) {\r\n const out = previous.filter(index => !intersected.includes(index));\r\n out.forEach(edge => {\r\n onPointerOut(edge);\r\n });\r\n }\r\n },\r\n [\r\n contextMenu,\r\n disabled,\r\n edgeContextMenus,\r\n setEdgeContextMenus,\r\n onClick,\r\n onContextMenu,\r\n onPointerOver,\r\n onPointerOut\r\n ]\r\n );\r\n\r\n return {\r\n handleClick,\r\n handleContextMenu,\r\n handleIntersections\r\n };\r\n}\r\n","import { SpringValue, useSpring } from '@react-spring/three';\r\nimport { useCallback, useEffect, useRef } from 'react';\r\nimport { BufferAttribute, BufferGeometry } from 'three';\r\n\r\nimport { Theme } from '../../themes';\r\nimport { animationConfig } from '../../utils';\r\n\r\nexport function useEdgePositionAnimation(\r\n geometry: BufferGeometry,\r\n animated: boolean\r\n): void {\r\n const geometryRef = useRef(geometry);\r\n\r\n useEffect(() => {\r\n geometryRef.current = geometry;\r\n }, [geometry]);\r\n\r\n const getAnimationPositions = useCallback(() => {\r\n const positions = geometryRef.current.getAttribute('position');\r\n const from = Array.from({\r\n length: positions.array.length\r\n }).fill(0) as Array;\r\n const to = Array.from(positions.array);\r\n return { from, to };\r\n }, []);\r\n\r\n const updateGeometryPosition = useCallback((positions: Array) => {\r\n const buffer = new Float32Array(positions);\r\n const newPosition = new BufferAttribute(buffer, 3, false);\r\n geometryRef.current.setAttribute('position', newPosition);\r\n newPosition.needsUpdate = true;\r\n }, []);\r\n\r\n useSpring(() => {\r\n if (!animated) {\r\n return null;\r\n }\r\n\r\n const animationPositions = getAnimationPositions();\r\n\r\n return {\r\n from: {\r\n positions: animationPositions.from\r\n },\r\n to: {\r\n positions: animationPositions.to\r\n },\r\n onChange: event => {\r\n updateGeometryPosition(event.value.positions);\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n };\r\n }, [animated]);\r\n}\r\n\r\nexport type UseEdgeOpacityAnimations = {\r\n activeOpacity: SpringValue;\r\n inactiveOpacity: SpringValue;\r\n};\r\n\r\nexport function useEdgeOpacityAnimation(\r\n animated: boolean,\r\n hasSelections: boolean,\r\n theme: Theme\r\n): UseEdgeOpacityAnimations {\r\n const [{ activeOpacity, inactiveOpacity }] = useSpring(() => {\r\n return {\r\n from: {\r\n activeOpacity: 0,\r\n inactiveOpacity: 0\r\n },\r\n to: {\r\n activeOpacity: hasSelections\r\n ? theme.edge.selectedOpacity\r\n : theme.edge.opacity,\r\n inactiveOpacity: hasSelections\r\n ? theme.edge.inactiveOpacity\r\n : theme.edge.opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n };\r\n }, [animated, hasSelections, theme]);\r\n\r\n return { activeOpacity, inactiveOpacity };\r\n}\r\n","import React, { FC, useCallback, useMemo } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Html } from 'glodrei';\r\nimport { ColorRepresentation, Euler } from 'three';\r\n\r\nimport { useStore } from '../../store';\r\nimport { Theme } from '../../themes';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../../types';\r\nimport {\r\n animationConfig,\r\n getLabelOffsetByType,\r\n getMidPoint\r\n} from '../../utils';\r\nimport { Label } from '../Label';\r\n\r\n/**\r\n * Label positions relatively edge\r\n *\r\n * below: show label under the edge line\r\n * above: show label above the edge line\r\n * inline: show label along the edge line\r\n * natural: normal text positions\r\n */\r\nexport type EdgeLabelPosition = 'below' | 'above' | 'inline' | 'natural';\r\n\r\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\r\n\r\nexport interface EdgeProps {\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The color of the edge.\r\n */\r\n color: ColorRepresentation;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * The edge object.\r\n */\r\n edge: InternalGraphEdge;\r\n\r\n /**\r\n * The URL of the font for the edge label.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The opacity of the edge.\r\n */\r\n opacity?: number;\r\n}\r\n\r\nexport const Edge: FC = ({\r\n animated,\r\n color,\r\n contextMenu,\r\n edge,\r\n labelFontUrl,\r\n labelPlacement,\r\n opacity\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const { target, source, label, labelVisible = false, size = 1 } = edge;\r\n\r\n const nodes = useStore(store => store.nodes);\r\n const from = nodes.find(node => node.id === source);\r\n const to = nodes.find(node => node.id === target);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n const labelOffset = (size + theme.edge.label.fontSize) / 2;\r\n\r\n const midPoint = useMemo(\r\n () =>\r\n getMidPoint(\r\n from.position,\r\n to.position,\r\n getLabelOffsetByType(labelOffset, labelPlacement)\r\n ),\r\n [from.position, to.position, labelOffset, labelPlacement]\r\n );\r\n\r\n const edgeContextMenus = useStore(state => state.edgeContextMenus);\r\n const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\r\n\r\n const [{ labelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n labelPosition: [0, 0, 0]\r\n },\r\n to: {\r\n labelPosition: [midPoint.x, midPoint.y, midPoint.z]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [midPoint, animated, draggingId]\r\n );\r\n\r\n const removeContextMenu = useCallback(\r\n (edge: InternalGraphEdge) => {\r\n edgeContextMenus.delete(edge.id);\r\n setEdgeContextMenus(new Set(edgeContextMenus.values()));\r\n },\r\n [edgeContextMenus, setEdgeContextMenus]\r\n );\r\n\r\n const labelRotation = useMemo(\r\n () =>\r\n new Euler(\r\n 0,\r\n 0,\r\n labelPlacement === 'natural'\r\n ? 0\r\n : Math.atan(\r\n (to.position.y - from.position.y) /\r\n (to.position.x - from.position.x)\r\n )\r\n ),\r\n [\r\n to.position.x,\r\n to.position.y,\r\n from.position.x,\r\n from.position.y,\r\n labelPlacement\r\n ]\r\n );\r\n\r\n return (\r\n \r\n {labelVisible && label && (\r\n \r\n \r\n \r\n )}\r\n {contextMenu && edgeContextMenus.has(edge.id) && (\r\n \r\n {contextMenu({\r\n data: edge,\r\n onClose: () => removeContextMenu(edge)\r\n })}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nEdge.defaultProps = {\r\n labelPlacement: 'inline'\r\n};\r\n","import React, { FC, useCallback, useEffect, useMemo, useRef } from 'react';\r\nimport { a } from '@react-spring/three';\r\nimport { useFrame } from '@react-three/fiber';\r\nimport { DoubleSide, Mesh, Raycaster, TubeGeometry } from 'three';\r\n\r\nimport { useStore } from '../../store';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../../types';\r\nimport { EdgeArrowPosition } from '../Arrow';\r\nimport { EdgeLabelPosition, EdgeInterpolation } from '../Edge';\r\nimport { useEdgeGeometry } from './useEdgeGeometry';\r\nimport { EdgeEvents, useEdgeEvents } from './useEdgeEvents';\r\nimport {\r\n useEdgePositionAnimation,\r\n useEdgeOpacityAnimation\r\n} from './useEdgeAnimations';\r\nimport { Edge } from './Edge';\r\n\r\nexport type EdgesProps = {\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The placement of the edge arrow.\r\n */\r\n arrowPlacement?: EdgeArrowPosition;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The array of edge objects.\r\n */\r\n edges: Array;\r\n\r\n /**\r\n * The URL of the font for the edge label.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The type of interpolation used to draw the edge.\r\n */\r\n interpolation?: EdgeInterpolation;\r\n} & EdgeEvents;\r\n\r\n/**\r\n * Three.js rendering starts to get slower if you have an individual mesh for each edge\r\n * and a high number of edges.\r\n *\r\n * Instead, we take the edges and split them into their different render states:\r\n *\r\n * * - Active (any edges that are marked as \"selected\" or \"active\" in the state)\r\n * * - Dragging (any edges that are connected to a node that is being dragged)\r\n * * - Intersecting (any edges that are currently intersected by the ray from the mouse position)\r\n * * - Inactive (any edges that aren't active, dragging, or intersected)\r\n *\r\n * We generate the geometry for each edge in each of these groups, and then merge them\r\n * into a single geometry for each group. This merged mesh is rendered as one object\r\n * which gives much better performance. This means that we only need to update geometry\r\n * and positions when edges move between the different states, rather than updating all\r\n * edges whenever any other edge changes.\r\n *\r\n * To get this all working, we have to do a few things outside the @react-three/fiber world,\r\n * specifically:\r\n *\r\n * * manually create edge/arrow geometries (see `useEdgeGeometry`)\r\n * * manually track mouse/edge interactions and fire events (see `useEdgeEvents`)\r\n * * manually update edge/arrow positions during aniamations (see `useEdgeAnimations`)\r\n */\r\nexport const Edges: FC = ({\r\n interpolation = 'linear',\r\n arrowPlacement = 'end',\r\n labelPlacement = 'inline',\r\n animated,\r\n contextMenu,\r\n disabled,\r\n edges,\r\n labelFontUrl,\r\n onClick,\r\n onContextMenu,\r\n onPointerOut,\r\n onPointerOver\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const { getGeometries, getGeometry } = useEdgeGeometry(\r\n arrowPlacement,\r\n interpolation\r\n );\r\n\r\n const draggingId = useStore(state => state.draggingId);\r\n const edgeMeshes = useStore(state => state.edgeMeshes);\r\n const setEdgeMeshes = useStore(state => state.setEdgeMeshes);\r\n const actives = useStore(state => state.actives || []);\r\n const selections = useStore(state => state.selections || []);\r\n\r\n const [active, inactive, draggingActive, draggingInactive] = useMemo(() => {\r\n const active: Array = [];\r\n const inactive: Array = [];\r\n const draggingActive: Array = [];\r\n const draggingInactive: Array = [];\r\n edges.forEach(edge => {\r\n if (draggingId === edge.source || draggingId === edge.target) {\r\n if (selections.includes(edge.id) || actives.includes(edge.id)) {\r\n draggingActive.push(edge);\r\n } else {\r\n draggingInactive.push(edge);\r\n }\r\n return;\r\n }\r\n\r\n if (selections.includes(edge.id) || actives.includes(edge.id)) {\r\n active.push(edge);\r\n } else {\r\n inactive.push(edge);\r\n }\r\n });\r\n return [active, inactive, draggingActive, draggingInactive];\r\n }, [edges, actives, selections, draggingId]);\r\n\r\n const hasSelections = !!selections.length;\r\n\r\n const staticEdgesGeometry = useMemo(\r\n () => getGeometry(active, inactive),\r\n [getGeometry, active, inactive]\r\n );\r\n\r\n const { activeOpacity, inactiveOpacity } = useEdgeOpacityAnimation(\r\n animated,\r\n hasSelections,\r\n theme\r\n );\r\n\r\n useEdgePositionAnimation(staticEdgesGeometry, animated);\r\n\r\n useEffect(() => {\r\n if (draggingId === null) {\r\n const edgeGeometries = getGeometries(edges);\r\n const edgeMeshes = edgeGeometries.map(edge => new Mesh(edge));\r\n setEdgeMeshes(edgeMeshes);\r\n }\r\n }, [getGeometries, setEdgeMeshes, edges, draggingId]);\r\n\r\n const staticEdgesRef = useRef(new Mesh());\r\n const dynamicEdgesRef = useRef(new Mesh());\r\n\r\n const intersect = useCallback(\r\n (raycaster: Raycaster): Array => {\r\n // Handle initial raycaster state:\r\n if (!raycaster.camera) {\r\n return [];\r\n }\r\n const intersections =\r\n raycaster.intersectObjects>(edgeMeshes);\r\n if (!intersections.length) {\r\n return [];\r\n }\r\n return intersections.map(\r\n intersection => edges[edgeMeshes.indexOf(intersection.object)]\r\n );\r\n },\r\n [edgeMeshes, edges]\r\n );\r\n\r\n const { handleClick, handleContextMenu, handleIntersections } = useEdgeEvents(\r\n {\r\n onClick,\r\n onContextMenu,\r\n onPointerOut,\r\n onPointerOver\r\n },\r\n contextMenu,\r\n disabled\r\n );\r\n\r\n const draggingIdRef = useRef(null);\r\n const intersectingRef = useRef>([]);\r\n\r\n useFrame(state => {\r\n staticEdgesRef.current.geometry = staticEdgesGeometry;\r\n\r\n if (disabled) {\r\n return;\r\n }\r\n\r\n const previousDraggingId = draggingIdRef.current;\r\n if (draggingId || (draggingId === null && previousDraggingId !== null)) {\r\n dynamicEdgesRef.current.geometry = getGeometry(\r\n draggingActive,\r\n draggingInactive\r\n );\r\n }\r\n\r\n draggingIdRef.current = draggingId;\r\n if (draggingId) {\r\n return;\r\n }\r\n\r\n const previousIntersecting = intersectingRef.current;\r\n const intersecting = intersect(state.raycaster);\r\n handleIntersections(previousIntersecting, intersecting);\r\n\r\n if (intersecting.join() !== previousIntersecting.join()) {\r\n dynamicEdgesRef.current.geometry = getGeometry(intersecting, []);\r\n }\r\n\r\n intersectingRef.current = intersecting;\r\n });\r\n\r\n return (\r\n \r\n {/* Static edges */}\r\n \r\n \r\n \r\n \r\n {/* Dynamic edges */}\r\n \r\n \r\n \r\n \r\n {edges.map(edge => (\r\n \r\n ))}\r\n \r\n );\r\n};\r\n","import React, { FC, useMemo, useState } from 'react';\r\nimport { ClusterGroup, animationConfig, useHoverIntent } from '../utils';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Color, DoubleSide } from 'three';\r\nimport { useStore } from '../store';\r\nimport { Label } from './Label';\r\nimport { useCursor } from 'glodrei';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport type ClusterEventArgs = Omit;\r\n\r\nexport interface ClusterProps extends ClusterGroup {\r\n /**\r\n * Whether the circle should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The radius of the circle. Default 1.\r\n */\r\n radius?: number;\r\n\r\n /**\r\n * The padding of the circle. Default 20.\r\n */\r\n padding?: number;\r\n\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * Whether the node is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * When the cluster was clicked.\r\n */\r\n onClick?: (cluster: ClusterEventArgs, event: ThreeEvent) => void;\r\n\r\n /**\r\n * When a cluster receives a pointer over event.\r\n */\r\n onPointerOver?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When cluster receives a pointer leave event.\r\n */\r\n onPointerOut?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nexport const Cluster: FC = ({\r\n animated,\r\n position,\r\n padding,\r\n labelFontUrl,\r\n disabled,\r\n radius,\r\n nodes,\r\n label,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const rad = Math.max(position.width, position.height) / 2;\r\n const offset = rad - radius + padding;\r\n const [active, setActive] = useState(false);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const isActive = useStore(state =>\r\n state.actives?.some(id => nodes.some(n => n.id === id))\r\n );\r\n\r\n const isSelected = useStore(state =>\r\n state.selections?.some(id => nodes.some(n => n.id === id))\r\n );\r\n\r\n const hasSelections = useStore(state => state.selections?.length > 0);\r\n\r\n const opacity = hasSelections\r\n ? isSelected || active || isActive\r\n ? theme.cluster?.selectedOpacity\r\n : theme.cluster?.inactiveOpacity\r\n : theme.cluster?.opacity;\r\n\r\n const { circleOpacity, circlePosition, labelPosition } = useSpring({\r\n from: {\r\n circlePosition: [center.x, center.y, -1],\r\n circleOpacity: 0,\r\n labelPosition: [0, -offset, 2]\r\n },\r\n to: {\r\n labelPosition: [0, -offset, 2],\r\n circlePosition: position ? [position.x, position.y, -1] : [0, 0, -1],\r\n circleOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedStroke = useMemo(\r\n () => new Color(theme.cluster?.stroke),\r\n [theme.cluster?.stroke]\r\n );\r\n\r\n const normalizedFill = useMemo(\r\n () => new Color(theme.cluster?.fill),\r\n [theme.cluster?.fill]\r\n );\r\n\r\n useCursor(active && onClick !== undefined, 'pointer');\r\n\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled,\r\n onPointerOver: (event: ThreeEvent) => {\r\n setActive(true);\r\n onPointerOver?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n setActive(false);\r\n onPointerOut?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n }\r\n });\r\n\r\n const cluster = useMemo(\r\n () =>\r\n theme.cluster && (\r\n ) => {\r\n if (!disabled) {\r\n onClick?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {theme.cluster?.label && (\r\n \r\n \r\n \r\n )}\r\n \r\n ),\r\n [\r\n theme.cluster,\r\n circlePosition,\r\n pointerOver,\r\n pointerOut,\r\n offset,\r\n normalizedFill,\r\n circleOpacity,\r\n rad,\r\n padding,\r\n normalizedStroke,\r\n labelPosition,\r\n label,\r\n opacity,\r\n labelFontUrl,\r\n disabled,\r\n onClick,\r\n nodes\r\n ]\r\n );\r\n\r\n return cluster;\r\n};\r\n\r\nCluster.defaultProps = {\r\n radius: 2,\r\n padding: 40\r\n};\r\n","import React, {\r\n FC,\r\n forwardRef,\r\n Fragment,\r\n ReactNode,\r\n Ref,\r\n useImperativeHandle,\r\n useMemo\r\n} from 'react';\r\nimport { useGraph } from './useGraph';\r\nimport { LayoutOverrides, LayoutTypes } from './layout';\r\nimport {\r\n NodeContextMenuProps,\r\n ContextMenuEvent,\r\n GraphEdge,\r\n GraphNode,\r\n InternalGraphEdge,\r\n InternalGraphNode,\r\n NodeRenderer,\r\n CollapseProps\r\n} from './types';\r\nimport { SizingType } from './sizing';\r\nimport {\r\n Cluster,\r\n ClusterEventArgs,\r\n Edge,\r\n EdgeArrowPosition,\r\n EdgeInterpolation,\r\n EdgeLabelPosition,\r\n Edges,\r\n Node\r\n} from './symbols';\r\nimport {\r\n CenterNodesParams,\r\n FitNodesParams,\r\n useCenterGraph\r\n} from './CameraControls';\r\nimport { LabelVisibilityType } from './utils';\r\nimport { useStore } from './store';\r\nimport Graph from 'graphology';\r\nimport { ThreeEvent, useThree } from '@react-three/fiber';\r\n\r\nexport interface GraphSceneProps {\r\n /**\r\n * Type of layout.\r\n */\r\n layoutType?: LayoutTypes;\r\n\r\n /**\r\n * List of ids that are selected.\r\n */\r\n selections?: string[];\r\n\r\n /**\r\n * List of ids that are active.\r\n */\r\n actives?: string[];\r\n\r\n /**\r\n * List of node ids that are collapsed.\r\n */\r\n collapsedNodeIds?: string[];\r\n\r\n /**\r\n * Animate or not the graph positions.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Nodes to pass to the graph.\r\n */\r\n nodes: GraphNode[];\r\n\r\n /**\r\n * Edges to pass to the graph.\r\n */\r\n edges: GraphEdge[];\r\n\r\n /**\r\n * Context menu element.\r\n */\r\n contextMenu?: (event: ContextMenuEvent) => ReactNode;\r\n\r\n /**\r\n * Type of sizing for nodes.\r\n */\r\n sizingType?: SizingType;\r\n\r\n /**\r\n * Type of visibility for labels.\r\n */\r\n labelType?: LabelVisibilityType;\r\n\r\n /**\r\n * Place of visibility for edge labels.\r\n */\r\n edgeLabelPosition?: EdgeLabelPosition;\r\n\r\n /**\r\n * Placement of edge arrows.\r\n */\r\n edgeArrowPosition?: EdgeArrowPosition;\r\n\r\n /**\r\n * Shape of edge.\r\n */\r\n edgeInterpolation?: EdgeInterpolation;\r\n\r\n /**\r\n * Font of label, same as troika-three-text\r\n * The URL of a custom font file to be used. Supported font formats are: * .ttf * .otf * .woff (.woff2 is not supported)\r\n * Default: The Roboto font loaded from Google Fonts CDN\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * Attribute based sizing property.\r\n */\r\n sizingAttribute?: string;\r\n\r\n /**\r\n * The default size to size nodes to. Default is 7.\r\n */\r\n defaultNodeSize?: number;\r\n\r\n /**\r\n * When using sizing attributes, the min size a node can be.\r\n */\r\n minNodeSize?: number;\r\n\r\n /**\r\n * When using sizing attributes, the max size a node can be.\r\n */\r\n maxNodeSize?: number;\r\n\r\n /**\r\n * Attribute used for clustering.\r\n */\r\n clusterAttribute?: string;\r\n\r\n /**\r\n * Disable interactions or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Allow dragging of nodes.\r\n */\r\n draggable?: boolean;\r\n\r\n /**\r\n * Render a custom node\r\n */\r\n renderNode?: NodeRenderer;\r\n\r\n /**\r\n * Advanced overrides for the layout.\r\n */\r\n layoutOverrides?: LayoutOverrides;\r\n\r\n /**\r\n * When a node was clicked.\r\n */\r\n onNodeClick?: (\r\n node: InternalGraphNode,\r\n props?: CollapseProps,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a node was double clicked.\r\n */\r\n onNodeDoubleClick?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a node context menu happened.\r\n */\r\n onNodeContextMenu?: (\r\n node: InternalGraphNode,\r\n props?: NodeContextMenuProps\r\n ) => void;\r\n\r\n /**\r\n * When node got a pointer over.\r\n */\r\n onNodePointerOver?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When node lost pointer over.\r\n */\r\n onNodePointerOut?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * Triggered after a node was dragged.\r\n */\r\n onNodeDragged?: (node: InternalGraphNode) => void;\r\n\r\n /**\r\n * When a edge context menu happened.\r\n */\r\n onEdgeContextMenu?: (edge?: InternalGraphEdge) => void;\r\n\r\n /**\r\n * When an edge was clicked.\r\n */\r\n onEdgeClick?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When edge got a pointer over.\r\n */\r\n onEdgePointerOver?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When edge lost pointer over.\r\n */\r\n onEdgePointerOut?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a cluster was clicked.\r\n */\r\n onClusterClick?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a cluster receives a pointer over event.\r\n */\r\n onClusterPointerOver?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When cluster receives a pointer leave event.\r\n */\r\n onClusterPointerOut?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nexport interface GraphSceneRef {\r\n /**\r\n * Reference to the graph object.\r\n */\r\n graph: Graph;\r\n\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `ids` are not currently in view. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerGraph: (nodeIds?: string[], opts?: CenterNodesParams) => void;\r\n\r\n /**\r\n * Fit all the given nodes into view of the camera.\r\n *\r\n * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\r\n * the view will fit to all nodes.\r\n *\r\n * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\r\n * only be fit if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the view will only be fit if one or more of the nodes\r\n * specified by `ids` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the view will be fit regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n fitNodesInView: (nodeIds?: string[], opts?: FitNodesParams) => void;\r\n\r\n /**\r\n * Calls render scene on the graph. this is useful when you want to manually render the graph\r\n * for things like screenshots.\r\n */\r\n renderScene: () => void;\r\n}\r\n\r\nexport const GraphScene: FC }> =\r\n forwardRef(\r\n (\r\n {\r\n onNodeClick,\r\n onNodeDoubleClick,\r\n onNodeContextMenu,\r\n onEdgeContextMenu,\r\n onEdgeClick,\r\n onEdgePointerOver,\r\n onEdgePointerOut,\r\n onNodePointerOver,\r\n onNodePointerOut,\r\n onClusterClick,\r\n onNodeDragged,\r\n onClusterPointerOver,\r\n onClusterPointerOut,\r\n contextMenu,\r\n animated,\r\n disabled,\r\n draggable,\r\n edgeLabelPosition,\r\n edgeArrowPosition,\r\n edgeInterpolation,\r\n labelFontUrl,\r\n renderNode,\r\n ...rest\r\n },\r\n ref\r\n ) => {\r\n const { layoutType, clusterAttribute } = rest;\r\n\r\n // Get the gl/scene/camera for render shortcuts\r\n const gl = useThree(state => state.gl);\r\n const scene = useThree(state => state.scene);\r\n const camera = useThree(state => state.camera);\r\n\r\n // Mount and build the graph\r\n useGraph(rest);\r\n\r\n if (\r\n clusterAttribute &&\r\n !(layoutType === 'forceDirected2d' || layoutType === 'forceDirected3d')\r\n ) {\r\n throw new Error(\r\n 'Clustering is only supported for the force directed layouts.'\r\n );\r\n }\r\n\r\n // Get the graph and nodes via the store for memo\r\n const graph = useStore(state => state.graph);\r\n const nodes = useStore(state => state.nodes);\r\n const edges = useStore(state => state.edges);\r\n const clusters = useStore(state => [...state.clusters.values()]);\r\n\r\n // Center the graph on the nodes\r\n const { centerNodesById, fitNodesInViewById, isCentered } =\r\n useCenterGraph({\r\n animated,\r\n disabled,\r\n layoutType\r\n });\r\n\r\n // Let's expose some helper methods\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n centerGraph: centerNodesById,\r\n fitNodesInView: fitNodesInViewById,\r\n graph,\r\n renderScene: () => gl.render(scene, camera)\r\n }),\r\n [centerNodesById, fitNodesInViewById, graph, gl, scene, camera]\r\n );\r\n\r\n const nodeComponents = useMemo(\r\n () =>\r\n nodes.map(n => (\r\n \r\n )),\r\n [\r\n animated,\r\n contextMenu,\r\n disabled,\r\n draggable,\r\n labelFontUrl,\r\n nodes,\r\n onNodeClick,\r\n onNodeContextMenu,\r\n onNodeDoubleClick,\r\n onNodeDragged,\r\n onNodePointerOut,\r\n onNodePointerOver,\r\n renderNode\r\n ]\r\n );\r\n\r\n const edgeComponents = useMemo(\r\n () =>\r\n animated ? (\r\n edges.map(e => (\r\n \r\n ))\r\n ) : (\r\n \r\n ),\r\n [\r\n animated,\r\n contextMenu,\r\n disabled,\r\n edgeArrowPosition,\r\n edgeInterpolation,\r\n edgeLabelPosition,\r\n edges,\r\n labelFontUrl,\r\n onEdgeClick,\r\n onEdgeContextMenu,\r\n onEdgePointerOut,\r\n onEdgePointerOver\r\n ]\r\n );\r\n\r\n const clusterComponents = useMemo(\r\n () =>\r\n clusters.map(c => (\r\n \r\n )),\r\n [\r\n animated,\r\n clusters,\r\n disabled,\r\n labelFontUrl,\r\n onClusterClick,\r\n onClusterPointerOut,\r\n onClusterPointerOver\r\n ]\r\n );\r\n\r\n return (\r\n isCentered && (\r\n \r\n {edgeComponents}\r\n {nodeComponents}\r\n {clusterComponents}\r\n \r\n )\r\n );\r\n }\r\n );\r\n\r\nGraphScene.defaultProps = {\r\n edgeInterpolation: 'linear'\r\n};\r\n","import { Theme } from './theme';\r\n\r\nexport const darkTheme: Theme = {\r\n canvas: {\r\n background: '#1E2026'\r\n },\r\n node: {\r\n fill: '#7A8C9E',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n },\r\n subLabel: {\r\n stroke: '#1E2026',\r\n color: '#ACBAC7',\r\n activeColor: '#1DE9AC'\r\n }\r\n },\r\n lasso: {\r\n border: '1px solid #55aaff',\r\n background: 'rgba(75, 160, 255, 0.1)'\r\n },\r\n ring: {\r\n fill: '#54616D',\r\n activeFill: '#1DE9AC'\r\n },\r\n edge: {\r\n fill: '#ffffff',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 4,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n }\r\n },\r\n arrow: {\r\n fill: '#474B56',\r\n activeFill: '#1DE9AC'\r\n },\r\n cluster: {\r\n stroke: '#474B56',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 4,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n }\r\n }\r\n};\r\n","import { Theme } from './theme';\r\n\r\nexport const lightTheme: Theme = {\r\n canvas: {\r\n background: '#fff'\r\n },\r\n node: {\r\n fill: '#7CA0AB',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.2,\r\n label: {\r\n color: '#2A6475',\r\n // stroke: '#fff',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n },\r\n subLabel: {\r\n color: '#ddd',\r\n stroke: 'transparent',\r\n activeColor: '#1DE9AC'\r\n }\r\n },\r\n lasso: {\r\n border: '1px solid #55aaff',\r\n background: 'rgba(75, 160, 255, 0.1)'\r\n },\r\n ring: {\r\n fill: '#D8E6EA',\r\n activeFill: '#1DE9AC'\r\n },\r\n edge: {\r\n fill: '#474B56',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n // stroke: '#fff',\r\n color: '#2A6475',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n }\r\n },\r\n arrow: {\r\n fill: '#D8E6EA',\r\n activeFill: '#1DE9AC'\r\n },\r\n cluster: {\r\n stroke: '#D8E6EA',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n stroke: '#1E2026',\r\n color: '#ACBAC7',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n }\r\n }\r\n};\r\n","import { Theme } from '../themes';\r\nimport Graph from 'graphology';\r\n\r\nexport type PathSelectionTypes = 'direct' | 'out' | 'in' | 'all';\r\n\r\n/**\r\n * Given a graph and a list of node ids, return the adjacent nodes and edges.\r\n *\r\n * TODO: This method could be improved with the introduction of graphology\r\n */\r\nexport function getAdjacents(\r\n graph: Graph,\r\n nodeIds: string | string[],\r\n type: PathSelectionTypes\r\n) {\r\n nodeIds = Array.isArray(nodeIds) ? nodeIds : [nodeIds];\r\n\r\n const nodes: string[] = [];\r\n const edges: string[] = [];\r\n\r\n for (const nodeId of nodeIds) {\r\n const graphLinks = [\r\n ...(graph.inEdgeEntries(nodeId) ?? []),\r\n ...(graph.outEdgeEntries(nodeId) ?? [])\r\n ];\r\n\r\n if (!graphLinks) {\r\n continue;\r\n }\r\n\r\n for (const link of graphLinks) {\r\n const linkId = link.attributes.id;\r\n\r\n if (type === 'in') {\r\n if (link.target === nodeId && !edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n } else if (type === 'out') {\r\n if (link.source === nodeId && !edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n } else {\r\n if (!edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n }\r\n\r\n if (type === 'out' || type === 'all') {\r\n const toId = link.target;\r\n if (!nodes.includes(toId as string)) {\r\n nodes.push(toId as string);\r\n }\r\n }\r\n\r\n if (type === 'in' || type === 'all') {\r\n if (!nodes.includes(link.source)) {\r\n nodes.push(link.source as string);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n nodes,\r\n edges\r\n };\r\n}\r\n\r\n/**\r\n * Set the vectors.\r\n */\r\nexport function prepareRay(event, vec, size) {\r\n const { offsetX, offsetY } = event;\r\n const { width, height } = size;\r\n vec.set((offsetX / width) * 2 - 1, -(offsetY / height) * 2 + 1);\r\n}\r\n\r\n/**\r\n * Create a lasso element.\r\n */\r\nexport function createElement(theme: Theme) {\r\n const element = document.createElement('div');\r\n element.style.pointerEvents = 'none';\r\n element.style.border = theme.lasso.border;\r\n element.style.backgroundColor = theme.lasso.background;\r\n element.style.position = 'fixed';\r\n return element;\r\n}\r\n","import React, {\r\n FC,\r\n PropsWithChildren,\r\n useCallback,\r\n useEffect,\r\n useRef\r\n} from 'react';\r\nimport { useThree } from '@react-three/fiber';\r\nimport { SelectionBox } from 'three-stdlib';\r\nimport { Mesh, Scene, TubeGeometry, Vector2 } from 'three';\r\nimport { useCameraControls } from '../CameraControls';\r\nimport { useStore } from '../store';\r\nimport { createElement, prepareRay } from './utils';\r\n\r\nexport type LassoType = 'none' | 'all' | 'node' | 'edge';\r\n\r\nexport type LassoProps = PropsWithChildren<{\r\n /**\r\n * Whether the lasso tool is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The type of the lasso tool.\r\n */\r\n type?: LassoType;\r\n\r\n /**\r\n * A function that is called when the lasso tool is used to select nodes.\r\n * The function receives an array of the ids of the selected nodes.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * A function that is called when the lasso tool is released, ending the selection.\r\n * The function receives an array of the ids of the selected nodes.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n}>;\r\n\r\nexport const Lasso: FC = ({\r\n children,\r\n type = 'none',\r\n onLasso,\r\n onLassoEnd,\r\n disabled\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const camera = useThree(state => state.camera);\r\n const gl = useThree(state => state.gl);\r\n const setEvents = useThree(state => state.setEvents);\r\n const size = useThree(state => state.size);\r\n const get = useThree(state => state.get);\r\n const scene = useThree(state => state.scene);\r\n\r\n const cameraControls = useCameraControls();\r\n\r\n const actives = useStore(state => state.actives);\r\n const setActives = useStore(state => state.setActives);\r\n const edges = useStore(state => state.edges);\r\n const edgeMeshes = useStore(state => state.edgeMeshes);\r\n\r\n const mountedRef = useRef(false);\r\n const selectionBoxRef = useRef(null);\r\n const edgeMeshSelectionBoxRef = useRef(null);\r\n const elementRef = useRef(createElement(theme));\r\n const vectorsRef = useRef<[Vector2, Vector2, Vector2] | null>(null);\r\n const isDownRef = useRef(false);\r\n const oldRaycasterEnabledRef = useRef(get().events.enabled);\r\n const oldControlsEnabledRef = useRef(\r\n cameraControls.controls?.enabled\r\n );\r\n\r\n useEffect(() => {\r\n if (mountedRef.current) {\r\n onLasso?.(actives);\r\n }\r\n\r\n mountedRef.current = true;\r\n }, [actives, onLasso]);\r\n\r\n const onPointerMove = useCallback(\r\n event => {\r\n if (isDownRef.current) {\r\n const [startPoint, pointTopLeft, pointBottomRight] = vectorsRef.current;\r\n\r\n pointBottomRight.x = Math.max(startPoint.x, event.clientX);\r\n pointBottomRight.y = Math.max(startPoint.y, event.clientY);\r\n pointTopLeft.x = Math.min(startPoint.x, event.clientX);\r\n pointTopLeft.y = Math.min(startPoint.y, event.clientY);\r\n elementRef.current.style.left = `${pointTopLeft.x}px`;\r\n elementRef.current.style.top = `${pointTopLeft.y}px`;\r\n elementRef.current.style.width = `${\r\n pointBottomRight.x - pointTopLeft.x\r\n }px`;\r\n elementRef.current.style.height = `${\r\n pointBottomRight.y - pointTopLeft.y\r\n }px`;\r\n\r\n prepareRay(event, selectionBoxRef.current.endPoint, size);\r\n prepareRay(event, edgeMeshSelectionBoxRef.current.endPoint, size);\r\n\r\n const allSelected = [];\r\n const edgesSelected = edgeMeshSelectionBoxRef.current\r\n .select()\r\n .sort(o => (o as any).uuid)\r\n .map(\r\n edge => edges[edgeMeshes.indexOf(edge as Mesh)].id\r\n );\r\n allSelected.push(...edgesSelected);\r\n\r\n const selected = selectionBoxRef.current\r\n .select()\r\n .sort(o => (o as any).uuid)\r\n .filter(\r\n o =>\r\n o.isMesh &&\r\n o.userData?.id &&\r\n (o.userData?.type === type || type === 'all')\r\n )\r\n .map(o => o.userData.id);\r\n allSelected.push(...selected);\r\n\r\n // Note: This probably isn't the best solution but\r\n // it prevents the render thrashing and causing flickering\r\n requestAnimationFrame(() => {\r\n setActives(allSelected);\r\n });\r\n\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true,\r\n capture: true,\r\n once: true\r\n });\r\n }\r\n },\r\n [edges, edgeMeshes, setActives, size, type]\r\n );\r\n\r\n const onPointerUp = useCallback(() => {\r\n if (isDownRef.current) {\r\n setEvents({ enabled: oldRaycasterEnabledRef.current });\r\n isDownRef.current = false;\r\n elementRef.current.parentElement?.removeChild(elementRef.current);\r\n cameraControls.controls.enabled = oldControlsEnabledRef.current;\r\n onLassoEnd?.(actives);\r\n\r\n document.removeEventListener('pointermove', onPointerMove);\r\n document.removeEventListener('pointerup', onPointerUp);\r\n }\r\n }, [setEvents, cameraControls.controls, onLassoEnd, actives, onPointerMove]);\r\n\r\n const onPointerDown = useCallback(\r\n event => {\r\n if (event.shiftKey) {\r\n // Let's capture the old props to restore them later\r\n oldRaycasterEnabledRef.current = get().events.enabled;\r\n oldControlsEnabledRef.current = cameraControls.controls?.enabled;\r\n\r\n // SelectionBox for all meshes\r\n selectionBoxRef.current = new SelectionBox(camera, scene);\r\n\r\n // SelectionBox for all Edge meshes (since they are combined into one geometry for rendering)\r\n const edgeScene = new Scene();\r\n if (edgeMeshes.length) {\r\n edgeScene.add(...edgeMeshes);\r\n }\r\n edgeMeshSelectionBoxRef.current = new SelectionBox(camera, edgeScene);\r\n\r\n vectorsRef.current = [\r\n // start point\r\n new Vector2(),\r\n // point top left\r\n new Vector2(),\r\n // point bottom right\r\n new Vector2()\r\n ];\r\n\r\n const [startPoint] = vectorsRef.current;\r\n\r\n cameraControls.controls.enabled = false;\r\n setEvents({ enabled: false });\r\n isDownRef.current = true;\r\n gl.domElement.parentElement?.appendChild(elementRef.current);\r\n elementRef.current.style.left = `${event.clientX}px`;\r\n elementRef.current.style.top = `${event.clientY}px`;\r\n elementRef.current.style.width = '0px';\r\n elementRef.current.style.height = '0px';\r\n startPoint.x = event.clientX;\r\n startPoint.y = event.clientY;\r\n\r\n prepareRay(event, selectionBoxRef.current.startPoint, size);\r\n prepareRay(event, edgeMeshSelectionBoxRef.current.startPoint, size);\r\n\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true,\r\n capture: true,\r\n once: true\r\n });\r\n document.addEventListener('pointerup', onPointerUp, { passive: true });\r\n }\r\n },\r\n [\r\n camera,\r\n cameraControls.controls,\r\n edgeMeshes,\r\n get,\r\n gl.domElement.parentElement,\r\n onPointerMove,\r\n onPointerUp,\r\n scene,\r\n setEvents,\r\n size\r\n ]\r\n );\r\n\r\n useEffect(() => {\r\n if (disabled || type === 'none') {\r\n return;\r\n }\r\n\r\n if (typeof window !== 'undefined') {\r\n document.addEventListener('pointerdown', onPointerDown, {\r\n passive: true\r\n });\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true\r\n });\r\n document.addEventListener('pointerup', onPointerUp, { passive: true });\r\n }\r\n\r\n return () => {\r\n if (typeof window !== 'undefined') {\r\n document.removeEventListener('pointerdown', onPointerDown);\r\n document.removeEventListener('pointermove', onPointerMove);\r\n document.removeEventListener('pointerup', onPointerUp);\r\n }\r\n };\r\n }, [type, disabled, onPointerDown, onPointerMove, onPointerUp]);\r\n\r\n return {children};\r\n};\r\n","import React, {\r\n RefObject,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useState\r\n} from 'react';\r\nimport { GraphCanvasRef } from '../GraphCanvas';\r\nimport { useHotkeys } from 'reakeys';\r\nimport { GraphEdge, GraphNode } from '../types';\r\nimport { findPath } from '../utils/paths';\r\nimport { getAdjacents, PathSelectionTypes } from './utils';\r\n\r\nexport type HotkeyTypes = 'selectAll' | 'deselect' | 'delete';\r\n\r\nexport type SelectionTypes = 'single' | 'multi' | 'multiModifier';\r\n\r\nexport interface SelectionProps {\r\n /**\r\n * Required ref for the graph.\r\n */\r\n ref: RefObject;\r\n\r\n /**\r\n * Current selections.\r\n *\r\n * Contains both nodes and edges ids.\r\n */\r\n selections?: string[];\r\n\r\n /**\r\n * Default active selections.\r\n */\r\n actives?: string[];\r\n\r\n /**\r\n * Node datas.\r\n */\r\n nodes?: GraphNode[];\r\n\r\n /**\r\n * Edge datas.\r\n */\r\n edges?: GraphEdge[];\r\n\r\n /**\r\n * Disabled or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Hotkey types\r\n */\r\n hotkeys?: HotkeyTypes[];\r\n\r\n /**\r\n * Whether to focus on select or not.\r\n */\r\n focusOnSelect?: boolean | 'singleOnly';\r\n\r\n /**\r\n * Type of selection.\r\n */\r\n type?: SelectionTypes;\r\n\r\n /**\r\n * Type of selection.\r\n */\r\n pathSelectionType?: PathSelectionTypes;\r\n\r\n /**\r\n * Whether it should active on hover or not.\r\n */\r\n pathHoverType?: PathSelectionTypes;\r\n\r\n /**\r\n * On selection change.\r\n */\r\n onSelection?: (selectionIds: string[]) => void;\r\n}\r\n\r\nexport interface SelectionResult {\r\n /**\r\n * Selections id array (of nodes and edges).\r\n */\r\n selections: string[];\r\n\r\n /**\r\n * The nodes/edges around the selections to highlight.\r\n */\r\n actives: string[];\r\n\r\n /**\r\n * Clear selections method.\r\n */\r\n clearSelections: (value?: string[]) => void;\r\n\r\n /**\r\n * A selection method.\r\n */\r\n addSelection: (value: string) => void;\r\n\r\n /**\r\n * Get the paths between two nodes.\r\n */\r\n selectNodePaths: (source: string, target: string) => void;\r\n\r\n /**\r\n * Remove selection method.\r\n */\r\n removeSelection: (value: string) => void;\r\n\r\n /**\r\n * Toggle existing selection on/off method.\r\n */\r\n toggleSelection: (value: string) => void;\r\n\r\n /**\r\n * Set internal selections.\r\n */\r\n setSelections: (value: string[]) => void;\r\n\r\n /**\r\n * On click event pass through.\r\n */\r\n onNodeClick?: (data: GraphNode) => void;\r\n\r\n /**\r\n * On canvas click event pass through.\r\n */\r\n onCanvasClick?: (event: MouseEvent) => void;\r\n\r\n /**\r\n * When the lasso happened.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the lasso ended.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n\r\n /**\r\n * When node got a pointer over.\r\n */\r\n onNodePointerOver?: (node: GraphNode) => void;\r\n\r\n /**\r\n * When node lost pointer over.\r\n */\r\n onNodePointerOut?: (node: GraphNode) => void;\r\n}\r\n\r\nexport const useSelection = ({\r\n selections = [],\r\n nodes = [],\r\n actives = [],\r\n focusOnSelect = true,\r\n type = 'single',\r\n pathHoverType = 'out',\r\n pathSelectionType = 'direct',\r\n ref,\r\n hotkeys = ['selectAll', 'deselect', 'delete'],\r\n disabled,\r\n onSelection\r\n}: SelectionProps): SelectionResult => {\r\n const [internalHovers, setInternalHovers] = useState([]);\r\n const [internalActives, setInternalActives] = useState(actives);\r\n const [internalSelections, setInternalSelections] =\r\n useState(selections);\r\n const [metaKeyDown, setMetaKeyDown] = useState(false);\r\n const isMulti = type === 'multi' || type === 'multiModifier';\r\n\r\n const addSelection = useCallback(\r\n (items: string | string[]) => {\r\n if (!disabled && items) {\r\n items = Array.isArray(items) ? items : [items];\r\n\r\n const filtered = items.filter(\r\n item => !internalSelections.includes(item)\r\n );\r\n if (filtered.length) {\r\n const next = [...internalSelections, ...filtered];\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n }\r\n },\r\n [disabled, internalSelections, onSelection]\r\n );\r\n\r\n const removeSelection = useCallback(\r\n (items: string | string[]) => {\r\n if (!disabled && items) {\r\n items = Array.isArray(items) ? items : [items];\r\n\r\n const next = internalSelections.filter(i => !items.includes(i));\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n },\r\n [disabled, internalSelections, onSelection]\r\n );\r\n\r\n const clearSelections = useCallback(\r\n (next: string | string[] = []) => {\r\n if (!disabled) {\r\n next = Array.isArray(next) ? next : [next];\r\n setInternalActives([]);\r\n setInternalSelections(next);\r\n onSelection?.(next);\r\n }\r\n },\r\n [disabled, onSelection]\r\n );\r\n\r\n const toggleSelection = useCallback(\r\n (item: string) => {\r\n const has = internalSelections.includes(item);\r\n if (has) {\r\n removeSelection(item);\r\n } else {\r\n if (!isMulti) {\r\n clearSelections(item);\r\n } else {\r\n addSelection(item);\r\n }\r\n }\r\n },\r\n [\r\n addSelection,\r\n clearSelections,\r\n internalSelections,\r\n isMulti,\r\n removeSelection\r\n ]\r\n );\r\n\r\n const onNodeClick = useCallback(\r\n (data: GraphNode) => {\r\n if (isMulti) {\r\n if (type === 'multiModifier') {\r\n if (metaKeyDown) {\r\n addSelection(data.id);\r\n } else {\r\n clearSelections(data.id);\r\n }\r\n } else {\r\n addSelection(data.id);\r\n }\r\n } else {\r\n clearSelections(data.id);\r\n }\r\n\r\n if (\r\n focusOnSelect === true ||\r\n (focusOnSelect === 'singleOnly' && !metaKeyDown)\r\n ) {\r\n if (!ref.current) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n const graph = ref.current.getGraph();\r\n const { nodes: adjacents } = getAdjacents(\r\n graph,\r\n [data.id],\r\n pathSelectionType\r\n );\r\n\r\n ref.current.fitNodesInView([data.id, ...adjacents], {\r\n fitOnlyIfNodesNotInView: true\r\n });\r\n }\r\n },\r\n [\r\n addSelection,\r\n clearSelections,\r\n focusOnSelect,\r\n isMulti,\r\n metaKeyDown,\r\n pathSelectionType,\r\n ref,\r\n type\r\n ]\r\n );\r\n\r\n const selectNodePaths = useCallback(\r\n (source: string, target: string) => {\r\n const graph = ref.current.getGraph();\r\n if (!graph) {\r\n throw new Error('Graph is not initialized');\r\n }\r\n\r\n const path = findPath(graph, source, target);\r\n clearSelections([source, target]);\r\n\r\n const result = [];\r\n for (let i = 0; i < path.length - 1; i++) {\r\n const from = path[i];\r\n const to = path[i + 1];\r\n const edge = graph.getEdgeAttributes(from, to);\r\n if (edge) {\r\n result.push(edge.id);\r\n }\r\n }\r\n\r\n setInternalActives([...path.map(p => p as string), ...result]);\r\n },\r\n [clearSelections, ref]\r\n );\r\n\r\n const onKeyDown = useCallback((event: KeyboardEvent) => {\r\n const element = event.target as any;\r\n const isSafe =\r\n element.tagName !== 'INPUT' &&\r\n element.tagName !== 'SELECT' &&\r\n element.tagName !== 'TEXTAREA' &&\r\n !element.isContentEditable;\r\n\r\n const isMeta = event.metaKey || event.ctrlKey;\r\n\r\n if (isSafe && isMeta) {\r\n event.preventDefault();\r\n setMetaKeyDown(true);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', onKeyDown);\r\n }\r\n\r\n return () => {\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', onKeyDown);\r\n }\r\n };\r\n }, [onKeyDown]);\r\n\r\n const onCanvasClick = useCallback(\r\n (event: MouseEvent) => {\r\n if (\r\n event.button !== 2 &&\r\n (internalSelections.length || internalActives.length)\r\n ) {\r\n clearSelections();\r\n setMetaKeyDown(false);\r\n\r\n // Only re-center if we have a single selection\r\n if (focusOnSelect && internalSelections.length === 1) {\r\n if (!ref.current) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n ref.current.fitNodesInView([], { fitOnlyIfNodesNotInView: true });\r\n }\r\n }\r\n },\r\n [\r\n clearSelections,\r\n focusOnSelect,\r\n internalActives.length,\r\n internalSelections.length,\r\n ref\r\n ]\r\n );\r\n\r\n const onLasso = useCallback((selections: string[]) => {\r\n setInternalActives(selections);\r\n }, []);\r\n\r\n const onLassoEnd = useCallback(\r\n (selections: string[]) => {\r\n clearSelections(selections);\r\n },\r\n [clearSelections]\r\n );\r\n\r\n const onNodePointerOver = useCallback(\r\n (data: GraphNode) => {\r\n if (pathHoverType) {\r\n const graph = ref.current.getGraph();\r\n if (!graph) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n const { nodes, edges } = getAdjacents(graph, [data.id], pathHoverType);\r\n setInternalHovers([...nodes, ...edges]);\r\n }\r\n },\r\n [pathHoverType, ref]\r\n );\r\n\r\n const onNodePointerOut = useCallback(() => {\r\n if (pathHoverType) {\r\n setInternalHovers([]);\r\n }\r\n }, [pathHoverType]);\r\n\r\n useEffect(() => {\r\n if (pathSelectionType !== 'direct' && internalSelections.length > 0) {\r\n const graph = ref.current?.getGraph();\r\n if (graph) {\r\n const { nodes, edges } = getAdjacents(\r\n graph,\r\n internalSelections,\r\n pathSelectionType\r\n );\r\n setInternalActives([...nodes, ...edges]);\r\n }\r\n }\r\n }, [internalSelections, pathSelectionType, ref]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Select All',\r\n keys: 'mod+a',\r\n disabled: !hotkeys.includes('selectAll'),\r\n category: 'Graph',\r\n description: 'Select all nodes and edges',\r\n callback: event => {\r\n event.preventDefault();\r\n\r\n if (!disabled && type !== 'single') {\r\n const next = nodes.map(n => n.id);\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n }\r\n },\r\n {\r\n name: 'Deselect Selections',\r\n category: 'Graph',\r\n disabled: !hotkeys.includes('deselect'),\r\n description: 'Deselect selected nodes and edges',\r\n keys: 'escape',\r\n callback: event => {\r\n if (!disabled) {\r\n event.preventDefault();\r\n onSelection?.([]);\r\n setInternalSelections([]);\r\n }\r\n }\r\n }\r\n ]);\r\n\r\n const joinedActives = useMemo(\r\n () => [...internalActives, ...internalHovers],\r\n [internalActives, internalHovers]\r\n );\r\n\r\n return {\r\n actives: joinedActives,\r\n onNodeClick,\r\n onNodePointerOver,\r\n onNodePointerOut,\r\n onLasso,\r\n onLassoEnd,\r\n selectNodePaths,\r\n onCanvasClick,\r\n selections: internalSelections,\r\n clearSelections,\r\n addSelection,\r\n removeSelection,\r\n toggleSelection,\r\n setSelections: setInternalSelections\r\n };\r\n};\r\n","import React, {\r\n FC,\r\n forwardRef,\r\n ReactNode,\r\n Ref,\r\n Suspense,\r\n useImperativeHandle,\r\n useRef,\r\n useMemo\r\n} from 'react';\r\nimport { Canvas } from '@react-three/fiber';\r\nimport { GraphScene, GraphSceneProps, GraphSceneRef } from './GraphScene';\r\nimport {\r\n CameraMode,\r\n CameraControls,\r\n CameraControlsRef\r\n} from './CameraControls';\r\nimport { Theme, lightTheme } from './themes';\r\nimport { createStore, Provider } from './store';\r\nimport Graph from 'graphology';\r\nimport { Lasso, LassoType } from './selection';\r\nimport ThreeCameraControls from 'camera-controls';\r\nimport css from './GraphCanvas.module.css';\r\n\r\nexport interface GraphCanvasProps extends Omit {\r\n /**\r\n * Theme to use for the graph.\r\n */\r\n theme?: Theme;\r\n\r\n /**\r\n * Type of camera interaction.\r\n */\r\n cameraMode?: CameraMode;\r\n\r\n /**\r\n * The maximum distance for the camera. Default is 50000.\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * The minimum distance for the camera. Default is 1000.\r\n */\r\n minDistance?: number;\r\n\r\n /**\r\n * The type of lasso selection.\r\n */\r\n lassoType?: LassoType;\r\n\r\n /**\r\n * Children to render in the canvas. Useful for things like lights.\r\n */\r\n children?: ReactNode;\r\n\r\n /**\r\n * Ability to extend Cavas gl options. For example { preserveDrawingBuffer: true }\r\n */\r\n glOptions?: Object;\r\n\r\n /**\r\n * When the canvas had a lasso selection.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the canvas had a lasso selection end.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the canvas was clicked but didn't hit a node/edge.\r\n */\r\n onCanvasClick?: (event: MouseEvent) => void;\r\n}\r\n\r\nexport type GraphCanvasRef = Omit &\r\n Omit & {\r\n /**\r\n * Get the graph object.\r\n */\r\n getGraph: () => Graph;\r\n\r\n /**\r\n * Get the camera controls.\r\n */\r\n getControls: () => ThreeCameraControls;\r\n\r\n /**\r\n * Export the canvas as a data URL.\r\n */\r\n exportCanvas: () => string;\r\n };\r\n\r\nconst GL_DEFAULTS = {\r\n alpha: true,\r\n antialias: true\r\n};\r\n\r\n// TODO: Fix type\r\nconst CAMERA_DEFAULTS: any = {\r\n position: [0, 0, 1000],\r\n near: 5,\r\n far: 50000,\r\n fov: 10\r\n};\r\n\r\nexport const GraphCanvas: FC }> =\r\n forwardRef(\r\n (\r\n {\r\n cameraMode,\r\n edges,\r\n children,\r\n nodes,\r\n theme,\r\n minDistance,\r\n maxDistance,\r\n onCanvasClick,\r\n animated,\r\n disabled,\r\n lassoType,\r\n onLasso,\r\n onLassoEnd,\r\n glOptions,\r\n ...rest\r\n },\r\n ref: Ref\r\n ) => {\r\n const rendererRef = useRef(null);\r\n const controlsRef = useRef(null);\r\n const canvasRef = useRef(null);\r\n\r\n useImperativeHandle(ref, () => ({\r\n centerGraph: (nodeIds, opts) =>\r\n rendererRef.current?.centerGraph(nodeIds, opts),\r\n fitNodesInView: (nodeIds, opts) =>\r\n rendererRef.current?.fitNodesInView(nodeIds, opts),\r\n zoomIn: () => controlsRef.current?.zoomIn(),\r\n zoomOut: () => controlsRef.current?.zoomOut(),\r\n dollyIn: distance => controlsRef.current?.dollyIn(distance),\r\n dollyOut: distance => controlsRef.current?.dollyOut(distance),\r\n panLeft: () => controlsRef.current?.panLeft(),\r\n panRight: () => controlsRef.current?.panRight(),\r\n panDown: () => controlsRef.current?.panDown(),\r\n panUp: () => controlsRef.current?.panUp(),\r\n resetControls: (animated?: boolean) =>\r\n controlsRef.current?.resetControls(animated),\r\n getControls: () => controlsRef.current?.controls,\r\n getGraph: () => rendererRef.current?.graph,\r\n exportCanvas: () => {\r\n rendererRef.current.renderScene();\r\n return canvasRef.current.toDataURL();\r\n }\r\n }));\r\n\r\n // Defaults to pass to the store\r\n const { selections, actives, collapsedNodeIds } = rest;\r\n\r\n // It's pretty hard to get good animation performance with large n of edges/nodes\r\n const finalAnimated =\r\n edges.length + nodes.length > 400 ? false : animated;\r\n\r\n const gl = useMemo(() => ({ ...glOptions, ...GL_DEFAULTS }), [glOptions]);\r\n\r\n // NOTE: The legacy/linear/flat flags are for color issues\r\n // Reference: https://github.com/protectwise/troika/discussions/213#discussioncomment-3086666\r\n return (\r\n
\r\n \r\n \r\n createStore({\r\n selections,\r\n actives,\r\n theme,\r\n collapsedNodeIds,\r\n canvasRef: canvasRef.current\r\n })\r\n }\r\n >\r\n {theme.canvas?.background && (\r\n \r\n )}\r\n \r\n {children}\r\n {theme.canvas?.fog && (\r\n \r\n )}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n }\r\n );\r\n\r\nGraphCanvas.defaultProps = {\r\n cameraMode: 'pan',\r\n layoutType: 'forceDirected2d',\r\n sizingType: 'default',\r\n labelType: 'auto',\r\n theme: lightTheme,\r\n animated: true,\r\n defaultNodeSize: 7,\r\n minNodeSize: 5,\r\n maxNodeSize: 15,\r\n lassoType: 'none',\r\n glOptions: {}\r\n};\r\n","import classNames from 'classnames';\r\nimport React, { FC, ReactNode } from 'react';\r\nimport css from './RadialSlice.module.css';\r\n\r\nexport interface MenuItem {\r\n /**\r\n * Label to display on the menu item.\r\n */\r\n label: string;\r\n\r\n /**\r\n * CSS Classname to apply to the slice.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * Optional icon to display on the menu item.\r\n */\r\n icon?: ReactNode;\r\n\r\n /**\r\n * Optional callback to detemine if the menu item is active.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Optional callback to handle when the menu item is clicked.\r\n */\r\n onClick?: (event: React.MouseEvent) => void;\r\n}\r\n\r\ninterface RadialSliceProps extends MenuItem {\r\n /**\r\n * The starting angle of the radial slice, in degrees.\r\n */\r\n startAngle: number;\r\n\r\n /**\r\n * The ending angle of the radial slice, in degrees.\r\n */\r\n endAngle: number;\r\n\r\n /**\r\n * The skew of the radial slice.\r\n */\r\n skew: number;\r\n\r\n /**\r\n * Whether the radial slice is polar (true) or not (false).\r\n */\r\n polar: boolean;\r\n\r\n /**\r\n * The central angle of the radial slice, in degrees.\r\n */\r\n centralAngle: number;\r\n\r\n /**\r\n * The radius of the radial slice.\r\n */\r\n radius: number;\r\n\r\n /**\r\n * The inner radius of the radial slice.\r\n */\r\n innerRadius: number;\r\n}\r\n\r\nexport const RadialSlice: FC = ({\r\n label,\r\n centralAngle,\r\n startAngle,\r\n endAngle,\r\n polar,\r\n radius,\r\n className,\r\n icon,\r\n innerRadius,\r\n skew,\r\n disabled,\r\n onClick\r\n}) => (\r\n 90 ? '100%' : '50%',\r\n height: centralAngle > 90 ? '100%' : '50%',\r\n bottom: centralAngle > 90 ? '50%' : 'initial',\r\n right: centralAngle > 90 ? '50%' : 'initial',\r\n transform: `rotate(${startAngle + endAngle}deg) skew(${skew}deg)`\r\n }}\r\n onClick={event => {\r\n if (!disabled) {\r\n onClick(event);\r\n }\r\n }}\r\n >\r\n \r\n 90 ? '50% + ' : ''\r\n }${radius}px) - ${innerRadius}px) / 2) - 4em)`\r\n }}\r\n >\r\n \r\n {icon}\r\n {label}\r\n \r\n \r\n \r\n \r\n);\r\n","import { MenuItem } from './RadialSlice';\r\n\r\nexport function calculateRadius(items: MenuItem[], startOffsetAngle: number) {\r\n const centralAngle = 360 / items.length || 360;\r\n const polar = centralAngle % 180 === 0;\r\n const deltaAngle = 90 - centralAngle;\r\n const startAngle = polar\r\n ? 45\r\n : startOffsetAngle + deltaAngle + centralAngle / 2;\r\n\r\n return { centralAngle, polar, startAngle, deltaAngle };\r\n}\r\n","import React, { FC, useLayoutEffect, useMemo, useRef } from 'react';\r\nimport { RadialSlice, MenuItem } from './RadialSlice';\r\nimport { calculateRadius } from './utils';\r\nimport css from './RadialMenu.module.css';\r\nimport classNames from 'classnames';\r\n\r\ninterface RadialMenuProps {\r\n /**\r\n * An array of menu items to be displayed in the radial menu.\r\n */\r\n items: MenuItem[];\r\n\r\n /**\r\n * The radius of the radial menu.\r\n */\r\n radius?: number;\r\n\r\n /**\r\n * The inner radius of the radial menu.\r\n */\r\n innerRadius?: number;\r\n\r\n /**\r\n * The starting offset angle for the first menu item.\r\n */\r\n startOffsetAngle?: number;\r\n\r\n /**\r\n * The CSS class name for the radial menu.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * A function that is called when the radial menu is closed.\r\n * The function receives the mouse event that triggered the closure.\r\n */\r\n onClose?: (event: React.MouseEvent) => void;\r\n}\r\n\r\nexport const RadialMenu: FC = ({\r\n items,\r\n radius,\r\n className,\r\n innerRadius,\r\n startOffsetAngle,\r\n onClose\r\n}) => {\r\n const { centralAngle, polar, startAngle, deltaAngle } = useMemo(\r\n () => calculateRadius(items, startOffsetAngle),\r\n [items, startOffsetAngle]\r\n );\r\n const timeout = useRef(null);\r\n\r\n useLayoutEffect(() => {\r\n const timer = timeout.current;\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n if (items.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n clearTimeout(timeout.current)}\r\n onPointerLeave={event => {\r\n clearTimeout(timeout.current);\r\n timeout.current = setTimeout(() => onClose?.(event), 500);\r\n }}\r\n >\r\n {items.map((slice, index) => (\r\n {\r\n slice?.onClick(event);\r\n onClose?.(event);\r\n }}\r\n />\r\n ))}\r\n \r\n );\r\n};\r\n\r\nRadialMenu.defaultProps = {\r\n radius: 175,\r\n innerRadius: 25,\r\n startOffsetAngle: 0\r\n};\r\n"],"names":["d3ForceRadial","nodes","links","treemap","hierarchy","forceSimulation","forceX","forceY","forceCollide","forceManyBody","forceLink","d3ForceX","d3ForceY","d3ForceSimulation","d3ForceCenter","d3ForceLink","d3ForceManyBody","d3ForceZ","_a","_b","stratify","tree","degreeCentrality","scaleLinear","n","Vector3","QuadraticBezierCurve3","LineCurve3","disabled","useRef","useCallback","useThree","useMemo","Vector2","Plane","useGesture","bidirectional","create","theme","actives","selections","id","node","useEffect","Color","jsx","Billboard","jsxs","RoundedBox","Text","a","useSpring","DoubleSide","Fragment","createContext","useContext","MOUSE","Vector4","Quaternion","Matrix4","Spherical","Box3","Sphere","Raycaster","MathUtils","extend","holdEvent","forwardRef","useFrame","ref","useHotkeys","animated","useImperativeHandle","useState","useLayoutEffect","TextureLoader","LinearFilter","DreiSvg","useCursor","_c","Html","curve","TubeGeometry","Edge","arrowPosition","arrowRotation","Euler","BoxGeometry","CylinderGeometry","mergeBufferGeometries","BufferAttribute","edge","active","inactive","draggingActive","draggingInactive","edgeMeshes","Mesh","SelectionBox","Scene","css","Canvas","Suspense"],"mappings":"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"} \ No newline at end of file +{"version":3,"file":"index.umd.cjs","sources":["../src/layout/depthUtils.ts","../src/layout/forceUtils.ts","../src/layout/layoutUtils.ts","../src/layout/forceInABox.ts","../src/layout/forceDirected.ts","../src/layout/circular2d.ts","../src/layout/hierarchical.ts","../src/layout/nooverlap.ts","../src/layout/forceatlas2.ts","../src/layout/custom.ts","../src/layout/layoutProvider.ts","../src/layout/recommender.ts","../src/utils/visibility.ts","../src/sizing/pageRank.ts","../src/sizing/centrality.ts","../src/sizing/attribute.ts","../src/sizing/nodeSizeProvider.ts","../src/utils/graph.ts","../src/utils/animation.ts","../src/utils/arrow.ts","../src/utils/position.ts","../src/utils/layout.ts","../src/utils/cluster.ts","../src/utils/useHoverIntent.ts","../src/utils/useDrag.ts","../src/utils/paths.ts","../src/store.ts","../src/collapse/utils.ts","../src/collapse/useCollapse.ts","../src/useGraph.ts","../src/symbols/Label.tsx","../src/symbols/Ring.tsx","../src/symbols/nodes/Sphere.tsx","../src/CameraControls/useCameraControls.ts","../src/CameraControls/CameraControls.tsx","../src/CameraControls/utils.ts","../src/CameraControls/useCenterGraph.ts","../src/symbols/nodes/Icon.tsx","../src/symbols/nodes/SphereWithIcon.tsx","../src/symbols/nodes/Svg.tsx","../src/symbols/nodes/SphereWithSvg.tsx","../src/symbols/Node.tsx","../src/symbols/Arrow.tsx","../src/symbols/Line.tsx","../src/symbols/Edge.tsx","../src/symbols/edges/useEdgeGeometry.ts","../src/symbols/edges/useEdgeEvents.ts","../src/symbols/edges/useEdgeAnimations.ts","../src/symbols/edges/Edge.tsx","../src/symbols/edges/Edges.tsx","../src/symbols/Cluster.tsx","../src/GraphScene.tsx","../src/themes/darkTheme.ts","../src/themes/lightTheme.ts","../src/selection/utils.ts","../src/selection/Lasso.tsx","../src/selection/useSelection.ts","../src/GraphCanvas.tsx","../src/RadialMenu/RadialSlice.tsx","../src/RadialMenu/utils.ts","../src/RadialMenu/RadialMenu.tsx"],"sourcesContent":["import { InternalGraphEdge, InternalGraphNode } from '../types';\r\n\r\nexport interface DepthNode {\r\n data: InternalGraphNode;\r\n ins: DepthNode[];\r\n out: DepthNode[];\r\n depth: number;\r\n}\r\n\r\n/**\r\n * Traverse the graph and get the depth of each node.\r\n */\r\nfunction traverseGraph(nodes: DepthNode[], nodeStack: DepthNode[] = []) {\r\n const currentDepth = nodeStack.length;\r\n\r\n for (const node of nodes) {\r\n const idx = nodeStack.indexOf(node);\r\n if (idx > -1) {\r\n const loop = [...nodeStack.slice(idx), node].map(d => d.data.id);\r\n throw new Error(\r\n `Invalid Graph: Circular node path detected: ${loop.join(' -> ')}.`\r\n );\r\n }\r\n\r\n if (currentDepth > node.depth) {\r\n node.depth = currentDepth;\r\n traverseGraph(node.out, [...nodeStack, node]);\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Gets the depth of the graph's nodes. Used in the radial layout.\r\n */\r\nexport function getNodeDepth(\r\n nodes: InternalGraphNode[],\r\n links: InternalGraphEdge[]\r\n) {\r\n let invalid = false;\r\n\r\n const graph: { [key: string]: DepthNode } = nodes.reduce(\r\n (acc, cur) => ({\r\n ...acc,\r\n [cur.id]: {\r\n data: cur,\r\n out: [],\r\n depth: -1,\r\n ins: []\r\n }\r\n }),\r\n {}\r\n );\r\n\r\n try {\r\n for (const link of links) {\r\n const from = link.source;\r\n const to = link.target;\r\n\r\n if (!graph.hasOwnProperty(from)) {\r\n throw new Error(`Missing source Node ${from}`);\r\n }\r\n\r\n if (!graph.hasOwnProperty(to)) {\r\n throw new Error(`Missing target Node ${to}`);\r\n }\r\n\r\n const sourceNode = graph[from];\r\n const targetNode = graph[to];\r\n targetNode.ins.push(sourceNode);\r\n sourceNode.out.push(targetNode);\r\n }\r\n\r\n traverseGraph(Object.values(graph));\r\n } catch (e) {\r\n invalid = true;\r\n }\r\n\r\n const allDepths = Object.keys(graph).map(id => graph[id].depth);\r\n const maxDepth = Math.max(...allDepths);\r\n\r\n return {\r\n invalid,\r\n depths: graph,\r\n maxDepth: maxDepth || 1\r\n };\r\n}\r\n","import { forceRadial as d3ForceRadial } from 'd3-force-3d';\r\nimport { InternalGraphEdge, InternalGraphNode } from 'types';\r\nimport { getNodeDepth } from './depthUtils';\r\n\r\nconst RADIALS: DagMode[] = ['radialin', 'radialout'];\r\n\r\nexport type DagMode =\r\n | 'lr'\r\n | 'rl'\r\n | 'td'\r\n | 'but'\r\n | 'zout'\r\n | 'zin'\r\n | 'radialin'\r\n | 'radialout';\r\n\r\nexport interface ForceRadialInputs {\r\n nodes: InternalGraphNode[];\r\n edges: InternalGraphEdge[];\r\n mode: DagMode;\r\n nodeLevelRatio: number;\r\n}\r\n\r\n/**\r\n * Radial graph layout using D3 Force 3d.\r\n * Inspired by: https://github.com/vasturiano/three-forcegraph/blob/master/src/forcegraph-kapsule.js#L970-L1018\r\n */\r\nexport function forceRadial({\r\n nodes,\r\n edges,\r\n mode = 'lr',\r\n nodeLevelRatio = 2\r\n}: ForceRadialInputs) {\r\n const { depths, maxDepth, invalid } = getNodeDepth(nodes, edges);\r\n\r\n if (invalid) {\r\n return null;\r\n }\r\n\r\n const modeDistance = RADIALS.includes(mode) ? 1 : 5;\r\n const dagLevelDistance =\r\n (nodes.length / maxDepth) * nodeLevelRatio * modeDistance;\r\n\r\n if (mode) {\r\n const getFFn =\r\n (fix: boolean, invert: boolean) => (node: InternalGraphNode) =>\r\n !fix\r\n ? undefined\r\n : (depths[node.id].depth - maxDepth / 2) *\r\n dagLevelDistance *\r\n (invert ? -1 : 1);\r\n\r\n const fxFn = getFFn(['lr', 'rl'].includes(mode), mode === 'rl');\r\n const fyFn = getFFn(['td', 'bu'].includes(mode), mode === 'td');\r\n const fzFn = getFFn(['zin', 'zout'].includes(mode), mode === 'zout');\r\n\r\n nodes.forEach(node => {\r\n node.fx = fxFn(node);\r\n node.fy = fyFn(node);\r\n node.fz = fzFn(node);\r\n });\r\n }\r\n\r\n return RADIALS.includes(mode)\r\n ? d3ForceRadial(node => {\r\n const nodeDepth = depths[node.id];\r\n const depth =\r\n mode === 'radialin' ? maxDepth - nodeDepth.depth : nodeDepth.depth;\r\n return depth * dagLevelDistance;\r\n }).strength(1)\r\n : null;\r\n}\r\n","import Graph from 'graphology';\r\nimport { LayoutStrategy } from './types';\r\nimport { InternalGraphEdge, InternalGraphNode } from '../types';\r\n\r\n/**\r\n * Promise based tick helper.\r\n */\r\nexport function tick(layout: LayoutStrategy) {\r\n return new Promise((resolve, _reject) => {\r\n let stable: boolean | undefined;\r\n\r\n function run() {\r\n if (!stable) {\r\n stable = layout.step();\r\n run();\r\n } else {\r\n resolve(stable);\r\n }\r\n }\r\n\r\n run();\r\n });\r\n}\r\n\r\n/**\r\n * Helper function to turn the graph nodes/edges into an array for\r\n * easier manipulation.\r\n */\r\nexport function buildNodeEdges(graph: Graph) {\r\n const nodes: InternalGraphNode[] = [];\r\n const edges: InternalGraphEdge[] = [];\r\n\r\n graph.forEachNode((id, n: any) => {\r\n nodes.push({\r\n ...n,\r\n id,\r\n // This is for the clustering\r\n radius: n.size || 1\r\n });\r\n });\r\n\r\n graph.forEachEdge((id, l: any) => {\r\n edges.push({ ...l, id });\r\n });\r\n\r\n return { nodes, edges };\r\n}\r\n","import {\r\n forceSimulation,\r\n forceX,\r\n forceY,\r\n forceLink,\r\n forceManyBody,\r\n forceCollide\r\n} from 'd3-force-3d';\r\nimport { treemap, hierarchy } from 'd3-hierarchy';\r\n\r\n/**\r\n * Used for calculating clusterings of nodes.\r\n *\r\n * Modified version of: https://github.com/john-guerra/forceInABox\r\n *\r\n * Changes:\r\n * - Improved d3 import for tree shaking\r\n * - Fixed node lookup for edges using array\r\n * - Updated d3-force to use d3-force-3d\r\n * - Removed template logic\r\n */\r\nexport function forceInABox() {\r\n // d3 style\r\n const constant = (_: any) => () => _;\r\n const index = (d: any) => d.index;\r\n\r\n // Default values\r\n let id = index;\r\n let nodes = [];\r\n let links = []; // needed for the force version\r\n let tree;\r\n let size = [100, 100];\r\n let forceNodeSize = constant(1); // The expected node size used for computing the cluster node\r\n let forceCharge = constant(-1);\r\n let forceLinkDistance = constant(100);\r\n let forceLinkStrength = constant(0.1);\r\n let foci = {};\r\n let linkStrengthIntraCluster = 0.1;\r\n let linkStrengthInterCluster = 0.001;\r\n let templateNodes = [];\r\n let offset = [0, 0];\r\n let templateForce;\r\n let groupBy = d => d.cluster;\r\n let template = 'treemap';\r\n let enableGrouping = true;\r\n let strength = 0.1;\r\n\r\n function force(alpha) {\r\n if (!enableGrouping) {\r\n return force;\r\n }\r\n\r\n if (template === 'force') {\r\n // Do the tick of the template force and get the new focis\r\n templateForce.tick();\r\n getFocisFromTemplate();\r\n }\r\n\r\n for (let i = 0, n = nodes.length, node, k = alpha * strength; i < n; ++i) {\r\n node = nodes[i];\r\n node.vx += (foci[groupBy(node)].x - node.x) * k;\r\n node.vy += (foci[groupBy(node)].y - node.y) * k;\r\n }\r\n }\r\n\r\n function initialize() {\r\n if (!nodes) {\r\n return;\r\n }\r\n\r\n if (template === 'treemap') {\r\n initializeWithTreemap();\r\n } else {\r\n initializeWithForce();\r\n }\r\n }\r\n\r\n force.initialize = function (_) {\r\n nodes = _;\r\n initialize();\r\n };\r\n\r\n function getLinkKey(l) {\r\n let sourceID = groupBy(l.source),\r\n targetID = groupBy(l.target);\r\n\r\n return sourceID <= targetID\r\n ? sourceID + '~' + targetID\r\n : targetID + '~' + sourceID;\r\n }\r\n\r\n function computeClustersNodeCounts(nodes) {\r\n let clustersCounts = new Map(),\r\n tmpCount: any = {};\r\n\r\n nodes.forEach(function (d) {\r\n if (!clustersCounts.has(groupBy(d))) {\r\n clustersCounts.set(groupBy(d), { count: 0, sumforceNodeSize: 0 });\r\n }\r\n });\r\n\r\n nodes.forEach(function (d) {\r\n tmpCount = clustersCounts.get(groupBy(d));\r\n tmpCount.count = tmpCount.count + 1;\r\n tmpCount.sumforceNodeSize =\r\n tmpCount.sumforceNodeSize +\r\n // @ts-ignore\r\n Math.PI * (forceNodeSize(d) * forceNodeSize(d)) * 1.3;\r\n clustersCounts.set(groupBy(d), tmpCount);\r\n });\r\n\r\n return clustersCounts;\r\n }\r\n\r\n //Returns\r\n function computeClustersLinkCounts(links) {\r\n let dClusterLinks = new Map(),\r\n clusterLinks = [];\r\n\r\n links.forEach(function (l) {\r\n let key = getLinkKey(l),\r\n count;\r\n if (dClusterLinks.has(key)) {\r\n count = dClusterLinks.get(key);\r\n } else {\r\n count = 0;\r\n }\r\n count += 1;\r\n dClusterLinks.set(key, count);\r\n });\r\n\r\n dClusterLinks.forEach(function (value, key) {\r\n let source, target;\r\n source = key.split('~')[0];\r\n target = key.split('~')[1];\r\n if (source !== undefined && target !== undefined) {\r\n clusterLinks.push({\r\n source: source,\r\n target: target,\r\n count: value\r\n });\r\n }\r\n });\r\n\r\n return clusterLinks;\r\n }\r\n\r\n //Returns the metagraph of the clusters\r\n function getGroupsGraph() {\r\n let gnodes = [];\r\n let glinks = [];\r\n let dNodes = new Map();\r\n let c;\r\n let i;\r\n let cc;\r\n let clustersCounts;\r\n let clustersLinks;\r\n\r\n clustersCounts = computeClustersNodeCounts(nodes);\r\n clustersLinks = computeClustersLinkCounts(links);\r\n\r\n for (c of clustersCounts.keys()) {\r\n cc = clustersCounts.get(c);\r\n gnodes.push({\r\n id: c,\r\n size: cc.count,\r\n r: Math.sqrt(cc.sumforceNodeSize / Math.PI)\r\n }); // Uses approx meta-node size\r\n dNodes.set(c, i);\r\n }\r\n\r\n clustersLinks.forEach(function (l) {\r\n let source = dNodes.get(l.source),\r\n target = dNodes.get(l.target);\r\n if (source !== undefined && target !== undefined) {\r\n glinks.push({\r\n source: source,\r\n target: target,\r\n count: l.count\r\n });\r\n }\r\n });\r\n\r\n return { nodes: gnodes, links: glinks };\r\n }\r\n\r\n function getGroupsTree() {\r\n let children = [];\r\n let c;\r\n let cc;\r\n let clustersCounts;\r\n\r\n // @ts-ignore\r\n clustersCounts = computeClustersNodeCounts(force.nodes());\r\n\r\n for (c of clustersCounts.keys()) {\r\n cc = clustersCounts.get(c);\r\n children.push({ id: c, size: cc.count });\r\n }\r\n return { id: 'clustersTree', children: children };\r\n }\r\n\r\n function getFocisFromTemplate() {\r\n //compute foci\r\n // @ts-ignore\r\n foci.none = { x: 0, y: 0 };\r\n templateNodes.forEach(function (d) {\r\n if (template === 'treemap') {\r\n foci[d.data.id] = {\r\n x: d.x0 + (d.x1 - d.x0) / 2 - offset[0],\r\n y: d.y0 + (d.y1 - d.y0) / 2 - offset[1]\r\n };\r\n } else {\r\n foci[d.id] = {\r\n x: d.x - offset[0],\r\n y: d.y - offset[1]\r\n };\r\n }\r\n });\r\n return foci;\r\n }\r\n\r\n function initializeWithTreemap() {\r\n // @ts-ignore\r\n let sim = treemap().size(force.size());\r\n\r\n tree = hierarchy(getGroupsTree())\r\n .sum((d: any) => d.radius)\r\n .sort(function (a, b) {\r\n return b.height - a.height || b.value - a.value;\r\n });\r\n\r\n templateNodes = sim(tree).leaves();\r\n getFocisFromTemplate();\r\n }\r\n\r\n function checkLinksAsObjects() {\r\n // Check if links come in the format of indexes instead of objects\r\n let linkCount = 0;\r\n if (nodes.length === 0) return;\r\n\r\n links.forEach(function (link) {\r\n let source, target;\r\n if (!nodes) {\r\n return;\r\n }\r\n\r\n source = link.source;\r\n target = link.target;\r\n\r\n if (typeof link.source !== 'object') {\r\n source = nodes.find(n => n.id === link.source);\r\n }\r\n\r\n if (typeof link.target !== 'object') {\r\n target = nodes.find(n => n.id === link.target);\r\n }\r\n\r\n if (source === undefined || target === undefined) {\r\n throw Error(\r\n 'Error setting links, couldnt find nodes for a link (see it on the console)'\r\n );\r\n }\r\n link.source = source;\r\n link.target = target;\r\n link.index = linkCount++;\r\n });\r\n }\r\n\r\n function initializeWithForce() {\r\n let net;\r\n\r\n if (!nodes || !nodes.length) {\r\n return;\r\n }\r\n\r\n checkLinksAsObjects();\r\n\r\n net = getGroupsGraph();\r\n templateForce = forceSimulation(net.nodes)\r\n .force('x', forceX(size[0] / 2).strength(0.1))\r\n .force('y', forceY(size[1] / 2).strength(0.1))\r\n .force('collide', forceCollide(d => d.r).iterations(4))\r\n .force('charge', forceManyBody().strength(forceCharge))\r\n .force(\r\n 'links',\r\n forceLink(net.nodes.length ? net.links : [])\r\n .distance(forceLinkDistance)\r\n .strength(forceLinkStrength)\r\n );\r\n\r\n templateNodes = templateForce.nodes();\r\n\r\n getFocisFromTemplate();\r\n }\r\n\r\n force.template = function (x) {\r\n if (!arguments.length) {\r\n return template;\r\n }\r\n\r\n template = x;\r\n initialize();\r\n return force;\r\n };\r\n\r\n force.groupBy = function (x) {\r\n if (!arguments.length) {\r\n return groupBy;\r\n }\r\n\r\n if (typeof x === 'string') {\r\n groupBy = function (d) {\r\n return d[x];\r\n };\r\n\r\n return force;\r\n }\r\n\r\n groupBy = x;\r\n\r\n return force;\r\n };\r\n\r\n force.enableGrouping = function (x) {\r\n if (!arguments.length) {\r\n return enableGrouping;\r\n }\r\n\r\n enableGrouping = x;\r\n\r\n return force;\r\n };\r\n\r\n force.strength = function (x) {\r\n if (!arguments.length) {\r\n return strength;\r\n }\r\n\r\n strength = x;\r\n\r\n return force as any;\r\n };\r\n\r\n force.getLinkStrength = function (e) {\r\n if (enableGrouping) {\r\n if (groupBy(e.source) === groupBy(e.target)) {\r\n if (typeof linkStrengthIntraCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthIntraCluster(e);\r\n } else {\r\n return linkStrengthIntraCluster;\r\n }\r\n } else {\r\n if (typeof linkStrengthInterCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthInterCluster(e);\r\n } else {\r\n return linkStrengthInterCluster;\r\n }\r\n }\r\n } else {\r\n // Not grouping return the intracluster\r\n if (typeof linkStrengthIntraCluster === 'function') {\r\n // @ts-ignore\r\n return linkStrengthIntraCluster(e);\r\n } else {\r\n return linkStrengthIntraCluster;\r\n }\r\n }\r\n };\r\n\r\n force.id = function (_) {\r\n return arguments.length ? ((id = _), force) : id;\r\n };\r\n\r\n force.size = function (_) {\r\n return arguments.length ? ((size = _), force) : size;\r\n };\r\n\r\n force.linkStrengthInterCluster = function (_) {\r\n return arguments.length\r\n ? ((linkStrengthInterCluster = _), force)\r\n : linkStrengthInterCluster;\r\n };\r\n\r\n force.linkStrengthIntraCluster = function (_) {\r\n return arguments.length\r\n ? ((linkStrengthIntraCluster = _), force)\r\n : linkStrengthIntraCluster;\r\n };\r\n\r\n force.nodes = function (_) {\r\n return arguments.length ? ((nodes = _), force) : nodes;\r\n };\r\n\r\n force.links = function (_) {\r\n if (!arguments.length) {\r\n return links;\r\n }\r\n\r\n if (_ === null) {\r\n links = [];\r\n } else {\r\n links = _;\r\n }\r\n\r\n initialize();\r\n\r\n return force;\r\n };\r\n\r\n force.template = function (x) {\r\n if (!arguments.length) {\r\n return template;\r\n }\r\n\r\n template = x;\r\n initialize();\r\n return force;\r\n };\r\n\r\n force.forceNodeSize = function (_) {\r\n return arguments.length\r\n ? ((forceNodeSize = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceNodeSize;\r\n };\r\n\r\n // Legacy support\r\n force.nodeSize = force.forceNodeSize;\r\n\r\n force.forceCharge = function (_) {\r\n return arguments.length\r\n ? ((forceCharge = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceCharge;\r\n };\r\n\r\n force.forceLinkDistance = function (_) {\r\n return arguments.length\r\n ? ((forceLinkDistance = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceLinkDistance;\r\n };\r\n\r\n force.forceLinkStrength = function (_) {\r\n return arguments.length\r\n ? ((forceLinkStrength = typeof _ === 'function' ? _ : constant(+_)),\r\n initialize(),\r\n force)\r\n : forceLinkStrength;\r\n };\r\n\r\n force.offset = function (_) {\r\n return arguments.length\r\n ? ((offset = typeof _ === 'function' ? _ : constant(+_)), force)\r\n : offset;\r\n };\r\n\r\n force.getFocis = getFocisFromTemplate;\r\n\r\n return force;\r\n}\r\n","import {\r\n forceSimulation as d3ForceSimulation,\r\n forceLink as d3ForceLink,\r\n forceCollide,\r\n forceManyBody as d3ForceManyBody,\r\n forceX as d3ForceX,\r\n forceY as d3ForceY,\r\n forceZ as d3ForceZ,\r\n forceCenter as d3ForceCenter\r\n} from 'd3-force-3d';\r\nimport { forceRadial, DagMode } from './forceUtils';\r\nimport { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\nimport { forceInABox } from './forceInABox';\r\nimport { FORCE_LAYOUTS } from './layoutProvider';\r\n\r\nexport interface ForceDirectedLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Center inertia for the layout. Default: 1.\r\n */\r\n centerInertia?: number;\r\n\r\n /**\r\n * Number of dimensions for the layout. 2d or 3d.\r\n */\r\n dimensions?: number;\r\n\r\n /**\r\n * Mode for the dag layout. Only applicable for dag layouts.\r\n */\r\n mode?: DagMode;\r\n\r\n /**\r\n * Distance between links.\r\n */\r\n linkDistance?: number;\r\n\r\n /**\r\n * Strength of the node repulsion.\r\n */\r\n nodeStrength?: number;\r\n\r\n /**\r\n * Strength of the cluster repulsion.\r\n */\r\n clusterStrength?: number;\r\n\r\n /**\r\n * The type of clustering.\r\n */\r\n clusterType?: 'force' | 'treemap';\r\n\r\n /**\r\n * Ratio of the distance between nodes on the same level.\r\n */\r\n nodeLevelRatio?: number;\r\n\r\n /**\r\n * LinkStrength between nodes of different clusters\r\n */\r\n linkStrengthInterCluster?: number | ((d: any) => number);\r\n\r\n /**\r\n * LinkStrength between nodes of the same cluster\r\n */\r\n linkStrengthIntraCluster?: number | ((d: any) => number);\r\n\r\n /**\r\n * Charge between the meta-nodes (Force template only)\r\n */\r\n forceLinkDistance?: number;\r\n\r\n /**\r\n * Used to compute the template force nodes size (Force template only)\r\n */\r\n forceLinkStrength?: number;\r\n\r\n /**\r\n * Used to compute the template force nodes size (Force template only)\r\n */\r\n forceCharge?: number;\r\n\r\n /**\r\n * Used to determine the simulation forceX and forceY values\r\n */\r\n forceLayout: (typeof FORCE_LAYOUTS)[number];\r\n}\r\n\r\nexport function forceDirected({\r\n graph,\r\n nodeLevelRatio = 2,\r\n mode = null,\r\n dimensions = 2,\r\n nodeStrength = -250,\r\n linkDistance = 100,\r\n clusterStrength = 0.5,\r\n linkStrengthInterCluster = 0.01,\r\n linkStrengthIntraCluster = 0.5,\r\n forceLinkDistance = 100,\r\n forceLinkStrength = 0.1,\r\n clusterType = 'force',\r\n forceCharge = -700,\r\n getNodePosition,\r\n drags,\r\n clusterAttribute,\r\n forceLayout\r\n}: ForceDirectedLayoutInputs): LayoutStrategy {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n // Dynamically adjust node strength based on the number of edges\r\n const is2d = dimensions === 2;\r\n const nodeStrengthAdjustment =\r\n is2d && edges.length > 25 ? nodeStrength * 2 : nodeStrength;\r\n\r\n let forceX;\r\n let forceY;\r\n if (forceLayout === 'forceDirected2d') {\r\n forceX = d3ForceX();\r\n forceY = d3ForceY();\r\n } else {\r\n forceX = d3ForceX(600).strength(0.05);\r\n forceY = d3ForceY(600).strength(0.05);\r\n }\r\n\r\n // Create the simulation\r\n const sim = d3ForceSimulation()\r\n .force('center', d3ForceCenter(0, 0))\r\n .force('link', d3ForceLink())\r\n .force('charge', d3ForceManyBody().strength(nodeStrengthAdjustment))\r\n .force('x', forceX)\r\n .force('y', forceY)\r\n .force('z', d3ForceZ())\r\n // Handles nodes not overlapping each other ( most relevant in clustering )\r\n .force(\r\n 'collide',\r\n forceCollide(d => d.radius + 10)\r\n )\r\n .force(\r\n 'dagRadial',\r\n forceRadial({\r\n nodes,\r\n edges,\r\n mode,\r\n nodeLevelRatio\r\n })\r\n )\r\n .stop();\r\n\r\n let groupingForce;\r\n if (clusterAttribute) {\r\n // Dynamically adjust cluster force charge based on the number of nodes\r\n let forceChargeAdjustment = forceCharge;\r\n if (nodes?.length) {\r\n const adjustmentFactor = Math.ceil(nodes.length / 200);\r\n forceChargeAdjustment = forceCharge * adjustmentFactor;\r\n }\r\n\r\n groupingForce = forceInABox()\r\n // Strength to foci\r\n .strength(clusterStrength)\r\n // Either treemap or force\r\n .template(clusterType)\r\n // Node attribute to group\r\n .groupBy(d => d.data[clusterAttribute])\r\n // The graph links. Must be called after setting the grouping attribute\r\n .links(edges)\r\n // Size of the chart\r\n .size([100, 100])\r\n // linkStrength between nodes of different clusters\r\n .linkStrengthInterCluster(linkStrengthInterCluster)\r\n // linkStrength between nodes of the same cluster\r\n .linkStrengthIntraCluster(linkStrengthIntraCluster)\r\n // linkDistance between meta-nodes on the template (Force template only)\r\n .forceLinkDistance(forceLinkDistance)\r\n // linkStrength between meta-nodes of the template (Force template only)\r\n .forceLinkStrength(forceLinkStrength)\r\n // Charge between the meta-nodes (Force template only)\r\n .forceCharge(forceChargeAdjustment)\r\n // Used to compute the template force nodes size (Force template only)\r\n .forceNodeSize(d => d.radius);\r\n }\r\n\r\n // Initialize the simulation\r\n let layout = sim.numDimensions(dimensions).nodes(nodes);\r\n\r\n if (groupingForce) {\r\n layout = layout.force('group', groupingForce);\r\n }\r\n\r\n // Run the force on the links\r\n if (linkDistance) {\r\n let linkForce = layout.force('link');\r\n if (linkForce) {\r\n linkForce\r\n .id(d => d.id)\r\n .links(edges)\r\n // When no mode passed, its a tree layout\r\n // so let's use a larger distance\r\n .distance(linkDistance);\r\n\r\n if (groupingForce) {\r\n linkForce = linkForce.strength(groupingForce?.getLinkStrength ?? 0.1);\r\n }\r\n }\r\n }\r\n\r\n const nodeMap = new Map(nodes.map(n => [n.id, n]));\r\n\r\n return {\r\n step() {\r\n // Run the simulation til we get a stable result\r\n while (sim.alpha() > 0.01) {\r\n sim.tick();\r\n }\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return nodeMap.get(id);\r\n }\r\n };\r\n}\r\n","import circular from 'graphology-layout/circular.js';\r\nimport { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface CircularLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Radius of the circle.\r\n */\r\n radius: 300;\r\n}\r\n\r\nexport function circular2d({\r\n graph,\r\n radius,\r\n drags,\r\n getNodePosition\r\n}: CircularLayoutInputs) {\r\n const layout = circular(graph, {\r\n scale: radius\r\n });\r\n\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return layout?.[id];\r\n }\r\n };\r\n}\r\n","import { InternalGraphEdge, InternalGraphNode } from 'types';\r\nimport { DepthNode, getNodeDepth } from './depthUtils';\r\nimport { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { hierarchy, stratify, tree } from 'd3-hierarchy';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface HierarchicalLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Direction of the layout. Default 'td'.\r\n */\r\n mode?: 'td' | 'lr';\r\n /**\r\n * Factor of distance between nodes. Default 1.\r\n */\r\n nodeSeparation?: number;\r\n /**\r\n * Size of each node. Default [50,50]\r\n */\r\n nodeSize?: [number, number];\r\n}\r\n\r\nconst DIRECTION_MAP = {\r\n td: {\r\n x: 'x',\r\n y: 'y',\r\n factor: -1\r\n },\r\n lr: {\r\n x: 'y',\r\n y: 'x',\r\n factor: 1\r\n }\r\n};\r\n\r\nexport function hierarchical({\r\n graph,\r\n drags,\r\n mode = 'td',\r\n nodeSeparation = 2,\r\n nodeSize = [60, 60],\r\n getNodePosition\r\n}: HierarchicalLayoutInputs): LayoutStrategy {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n // find root node by finding the nodes which have no incoming edges\r\n const parentNodes = nodes.filter(n => !edges.find(e => e.target === n.id));\r\n console.log('parentNodes', parentNodes);\r\n\r\n // if more than 1 root node, then we have multiple trees\r\n // insert a fake root node to connect all root nodes\r\n if (parentNodes.length > 1) {\r\n const fakeRootNode: InternalGraphNode = {\r\n id: 'fakeRoot',\r\n label: '',\r\n fill: '#fff',\r\n activeFill: '#fff',\r\n icon: '',\r\n data: {\r\n id: 'fakeRoot',\r\n loaded: true,\r\n extra: {\r\n id: 'fakeRoot',\r\n properties: {},\r\n labels: []\r\n },\r\n className: '',\r\n style: {\r\n label: ''\r\n }\r\n },\r\n position: {\r\n id: '',\r\n data: {},\r\n links: [],\r\n index: 0,\r\n x: 0,\r\n y: 0,\r\n z: 0,\r\n vx: 0,\r\n vy: 0\r\n }\r\n };\r\n\r\n // add fake root node to nodes\r\n nodes.push(fakeRootNode);\r\n\r\n // add edges from fake root to root nodes\r\n parentNodes.forEach(n => {\r\n edges.push({\r\n id: `fakeRoot-${n.id}`,\r\n source: 'fakeRoot',\r\n target: n.id,\r\n label: '',\r\n backgroundColor: '#fff'\r\n });\r\n });\r\n }\r\n\r\n const { depths } = getNodeDepth(nodes, edges);\r\n const rootNodes = Object.keys(depths).map(d => depths[d]);\r\n\r\n const root = stratify()\r\n .id(d => d.data.id)\r\n .parentId(d => d.ins?.[0]?.data?.id)(rootNodes);\r\n\r\n const treeRoot = tree()\r\n .separation(() => nodeSeparation)\r\n .nodeSize(nodeSize)(hierarchy(root));\r\n\r\n const treeNodes = treeRoot.descendants();\r\n const path = DIRECTION_MAP[mode];\r\n\r\n const mappedNodes = new Map(\r\n nodes.map(n => {\r\n const { x, y } = treeNodes.find((t: any) => t.data.id === n.id);\r\n return [\r\n n.id,\r\n {\r\n ...n,\r\n [path.x]: x * path.factor,\r\n [path.y]: y * path.factor,\r\n z: 0\r\n }\r\n ];\r\n })\r\n );\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return mappedNodes.get(id);\r\n }\r\n };\r\n}\r\n","import noverlapLayout from 'graphology-layout-noverlap';\r\nimport { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport interface NoOverlapLayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Grid size. Default 20.\r\n */\r\n gridSize?: number;\r\n\r\n /**\r\n * Ratio of the layout. Default 10.\r\n */\r\n ratio?: number;\r\n\r\n /**\r\n * Maximum number of iterations. Default 50.\r\n */\r\n maxIterations?: number;\r\n\r\n /**\r\n * Margin between nodes. Default 10.\r\n */\r\n margin?: number;\r\n}\r\n\r\nexport function nooverlap({\r\n graph,\r\n margin,\r\n drags,\r\n getNodePosition,\r\n ratio,\r\n gridSize,\r\n maxIterations\r\n}: NoOverlapLayoutInputs) {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n const layout = noverlapLayout(graph, {\r\n maxIterations,\r\n inputReducer: (_key, attr) => ({\r\n ...attr,\r\n // Have to specify defaults for the engine\r\n x: attr.x || 0,\r\n y: attr.y || 0\r\n }),\r\n settings: {\r\n ratio,\r\n margin,\r\n gridSize\r\n }\r\n });\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n if (getNodePosition) {\r\n const pos = getNodePosition(id, { graph, drags, nodes, edges });\r\n if (pos) {\r\n return pos;\r\n }\r\n }\r\n\r\n if (drags?.[id]?.position) {\r\n // If we dragged, we need to use that position\r\n return drags?.[id]?.position as any;\r\n }\r\n\r\n return layout?.[id];\r\n }\r\n };\r\n}\r\n","import forceAtlas2Layout from 'graphology-layout-forceatlas2';\r\nimport { LayoutFactoryProps } from './types';\r\nimport random from 'graphology-layout/random.js';\r\n\r\nexport interface ForceAtlas2LayoutInputs extends LayoutFactoryProps {\r\n /**\r\n * Should the node’s sizes be taken into account. Default: false.\r\n */\r\n adjustSizes?: boolean;\r\n\r\n /**\r\n * whether to use the Barnes-Hut approximation to compute\r\n * repulsion in O(n*log(n)) rather than default O(n^2),\r\n * n being the number of nodes. Default: false.\r\n */\r\n barnesHutOptimize?: boolean;\r\n\r\n /**\r\n * Barnes-Hut approximation theta parameter. Default: 0.5.\r\n */\r\n barnesHutTheta?: number;\r\n\r\n /**\r\n * Influence of the edge’s weights on the layout. To consider edge weight, don’t\r\n * forget to pass weighted as true. Default: 1.\r\n */\r\n edgeWeightInfluence?: number;\r\n\r\n /**\r\n * Strength of the layout’s gravity. Default: 10.\r\n */\r\n gravity?: number;\r\n\r\n /**\r\n * Whether to use Noack’s LinLog model. Default: false.\r\n */\r\n linLogMode?: boolean;\r\n\r\n /**\r\n * Whether to consider edge weights when calculating repulsion. Default: false.\r\n */\r\n outboundAttractionDistribution?: boolean;\r\n\r\n /**\r\n * Scaling ratio for repulsion. Default: 100.\r\n */\r\n scalingRatio?: number;\r\n\r\n /**\r\n * Speed of the slowdown. Default: 1.\r\n */\r\n slowDown?: number;\r\n\r\n /**\r\n * Whether to use the strong gravity mode. Default: false.\r\n */\r\n strongGravityMode?: boolean;\r\n\r\n /**\r\n * Number of iterations to perform. Default: 50.\r\n */\r\n iterations?: number;\r\n}\r\n\r\nexport function forceAtlas2({\r\n graph,\r\n drags,\r\n iterations,\r\n ...rest\r\n}: ForceAtlas2LayoutInputs) {\r\n // Note: We need to assign a random position to each node\r\n // in order for the force atlas to work.\r\n // Reference: https://graphology.github.io/standard-library/layout-forceatlas2.html#pre-requisites\r\n random.assign(graph);\r\n\r\n const layout = forceAtlas2Layout(graph, {\r\n iterations,\r\n settings: rest\r\n });\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n // If we dragged, we need to use that position\r\n return (drags?.[id]?.position as any) || layout?.[id];\r\n }\r\n };\r\n}\r\n","import { LayoutFactoryProps } from './types';\r\nimport { buildNodeEdges } from './layoutUtils';\r\n\r\nexport function custom({ graph, drags, getNodePosition }: LayoutFactoryProps) {\r\n const { nodes, edges } = buildNodeEdges(graph);\r\n\r\n return {\r\n step() {\r\n return true;\r\n },\r\n getNodePosition(id: string) {\r\n return getNodePosition(id, { graph, drags, nodes, edges });\r\n }\r\n };\r\n}\r\n","import { LayoutFactoryProps, LayoutStrategy } from './types';\r\nimport { forceDirected, ForceDirectedLayoutInputs } from './forceDirected';\r\nimport { circular2d, CircularLayoutInputs } from './circular2d';\r\nimport { hierarchical, HierarchicalLayoutInputs } from './hierarchical';\r\nimport { NoOverlapLayoutInputs, nooverlap } from './nooverlap';\r\nimport { ForceAtlas2LayoutInputs, forceAtlas2 } from './forceatlas2';\r\nimport { custom } from './custom';\r\n\r\nexport type LayoutOverrides = Partial<\r\n | Omit\r\n | CircularLayoutInputs\r\n | HierarchicalLayoutInputs\r\n>;\r\n\r\nexport const FORCE_LAYOUTS = [\r\n 'forceDirected2d',\r\n 'treeTd2d',\r\n 'treeLr2d',\r\n 'radialOut2d',\r\n 'treeTd3d',\r\n 'treeLr3d',\r\n 'radialOut3d',\r\n 'forceDirected3d'\r\n];\r\n\r\nexport function layoutProvider({\r\n type,\r\n ...rest\r\n}: LayoutFactoryProps | LayoutOverrides): LayoutStrategy {\r\n if (FORCE_LAYOUTS.includes(type)) {\r\n const { nodeStrength, linkDistance, nodeLevelRatio } =\r\n rest as ForceDirectedLayoutInputs;\r\n\r\n if (type === 'forceDirected2d') {\r\n return forceDirected({\r\n ...rest,\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeTd2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'td',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeLr2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'lr',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'radialOut2d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'radialout',\r\n dimensions: 2,\r\n nodeLevelRatio: nodeLevelRatio || 5,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 100,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeTd3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'td',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 50\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'treeLr3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'lr',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 50,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'radialOut3d') {\r\n return forceDirected({\r\n ...rest,\r\n mode: 'radialout',\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -500,\r\n linkDistance: linkDistance || 100,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n } else if (type === 'forceDirected3d') {\r\n return forceDirected({\r\n ...rest,\r\n dimensions: 3,\r\n nodeLevelRatio: nodeLevelRatio || 2,\r\n nodeStrength: nodeStrength || -250,\r\n linkDistance,\r\n forceLayout: type\r\n } as ForceDirectedLayoutInputs);\r\n }\r\n } else if (type === 'circular2d') {\r\n const { radius } = rest as CircularLayoutInputs;\r\n return circular2d({\r\n ...rest,\r\n radius: radius || 300\r\n } as CircularLayoutInputs);\r\n } else if (type === 'hierarchicalTd') {\r\n return hierarchical({ ...rest, mode: 'td' } as HierarchicalLayoutInputs);\r\n } else if (type === 'hierarchicalLr') {\r\n return hierarchical({ ...rest, mode: 'lr' } as HierarchicalLayoutInputs);\r\n } else if (type === 'nooverlap') {\r\n const { graph, maxIterations, ratio, margin, gridSize, ...settings } =\r\n rest as NoOverlapLayoutInputs;\r\n\r\n return nooverlap({\r\n type: 'nooverlap',\r\n graph,\r\n margin: margin || 10,\r\n maxIterations: maxIterations || 50,\r\n ratio: ratio || 10,\r\n gridSize: gridSize || 20,\r\n ...settings\r\n });\r\n } else if (type === 'forceatlas2') {\r\n const { graph, iterations, gravity, scalingRatio, ...settings } =\r\n rest as ForceAtlas2LayoutInputs;\r\n\r\n return forceAtlas2({\r\n type: 'forceatlas2',\r\n graph,\r\n ...settings,\r\n scalingRatio: scalingRatio || 100,\r\n gravity: gravity || 10,\r\n iterations: iterations || 50\r\n });\r\n } else if (type === 'custom') {\r\n return custom({\r\n type: 'custom',\r\n ...rest\r\n } as LayoutFactoryProps);\r\n }\r\n\r\n throw new Error(`Layout ${type} not found.`);\r\n}\r\n","import { GraphEdge, GraphNode } from '../types';\r\nimport { getNodeDepth } from './depthUtils';\r\nimport { LayoutTypes } from './types';\r\n\r\n/**\r\n * Given a set of nodes and edges, determine the type of layout that\r\n * is most ideal. This is very beta.\r\n */\r\nexport function recommendLayout(\r\n nodes: GraphNode[],\r\n edges: GraphEdge[]\r\n): LayoutTypes {\r\n const { invalid } = getNodeDepth(nodes as any[], edges as any[]);\r\n const nodeCount = nodes.length;\r\n\r\n if (!invalid) {\r\n // Large tree layouts\r\n if (nodeCount > 100) {\r\n return 'radialOut2d';\r\n } else {\r\n // Smaller tree layouts\r\n return 'treeTd2d';\r\n }\r\n }\r\n\r\n // Circular layouts\r\n return 'forceDirected2d';\r\n}\r\n","import { PerspectiveCamera } from 'three';\r\nimport { EdgeLabelPosition } from '../symbols';\r\n\r\nexport type LabelVisibilityType = 'all' | 'auto' | 'none' | 'nodes' | 'edges';\r\n\r\ninterface CalcLabelVisibilityArgs {\r\n nodeCount: number;\r\n nodePosition?: { x: number; y: number; z: number };\r\n labelType: LabelVisibilityType;\r\n camera?: PerspectiveCamera;\r\n}\r\n\r\nexport function calcLabelVisibility({\r\n nodeCount,\r\n nodePosition,\r\n labelType,\r\n camera\r\n}: CalcLabelVisibilityArgs) {\r\n return (shape: 'node' | 'edge', size: number) => {\r\n if (\r\n camera &&\r\n nodePosition &&\r\n camera?.position?.z / camera?.zoom - nodePosition?.z > 6000\r\n ) {\r\n return false;\r\n }\r\n\r\n if (labelType === 'all') {\r\n return true;\r\n } else if (labelType === 'nodes' && shape === 'node') {\r\n return true;\r\n } else if (labelType === 'edges' && shape === 'edge') {\r\n return true;\r\n } else if (labelType === 'auto' && shape === 'node') {\r\n if (size > 7) {\r\n return true;\r\n } else if (\r\n camera &&\r\n nodePosition &&\r\n camera.position.z / camera.zoom - nodePosition.z < 3000\r\n ) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n };\r\n}\r\n\r\nexport function getLabelOffsetByType(\r\n offset: number,\r\n position: EdgeLabelPosition\r\n): number {\r\n switch (position) {\r\n case 'above':\r\n return offset;\r\n case 'below':\r\n return -offset;\r\n case 'inline':\r\n case 'natural':\r\n default:\r\n return 0;\r\n }\r\n}\r\n","import pagerank from 'graphology-metrics/centrality/pagerank.js';\r\nimport { SizingStrategy, SizingStrategyInputs } from './types';\r\n\r\nexport function pageRankSizing({\r\n graph\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const ranks = pagerank(graph);\r\n\r\n return {\r\n ranks,\r\n getSizeForNode: (nodeID: string) => ranks[nodeID] * 80\r\n };\r\n}\r\n","import { SizingStrategy, SizingStrategyInputs } from './types';\r\nimport { degreeCentrality } from 'graphology-metrics/centrality/degree.js';\r\n\r\nexport function centralitySizing({\r\n graph\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const ranks = degreeCentrality(graph);\r\n\r\n return {\r\n ranks,\r\n getSizeForNode: (nodeID: string) => ranks[nodeID] * 20\r\n };\r\n}\r\n","import { SizingStrategy, SizingStrategyInputs } from './types';\r\n\r\nexport function attributeSizing({\r\n graph,\r\n attribute,\r\n defaultSize\r\n}: SizingStrategyInputs): SizingStrategy {\r\n const map = new Map();\r\n\r\n if (attribute) {\r\n graph.forEachNode((id, node) => {\r\n const size = node.data?.[attribute];\r\n if (isNaN(size)) {\r\n console.warn(`Attribute ${size} is not a number for node ${node.id}`);\r\n }\r\n\r\n map.set(id, size || 0);\r\n });\r\n } else {\r\n console.warn('Attribute sizing configured but no attribute provided');\r\n }\r\n\r\n return {\r\n getSizeForNode: (nodeId: string) => {\r\n if (!attribute || !map) {\r\n return defaultSize;\r\n }\r\n\r\n return map.get(nodeId);\r\n }\r\n };\r\n}\r\n","import { pageRankSizing } from './pageRank';\r\nimport { centralitySizing } from './centrality';\r\nimport { attributeSizing } from './attribute';\r\nimport { SizingStrategyInputs } from './types';\r\nimport { scaleLinear } from 'd3-scale';\r\n\r\nexport type SizingType =\r\n | 'none'\r\n | 'pagerank'\r\n | 'centrality'\r\n | 'attribute'\r\n | 'default';\r\n\r\nexport interface NodeSizeProviderInputs extends SizingStrategyInputs {\r\n /**\r\n * The sizing strategy to use.\r\n */\r\n type: SizingType;\r\n}\r\n\r\nconst providers = {\r\n pagerank: pageRankSizing,\r\n centrality: centralitySizing,\r\n attribute: attributeSizing,\r\n none: ({ defaultSize }: SizingStrategyInputs) => ({\r\n getSizeForNode: (_id: string) => defaultSize\r\n })\r\n};\r\n\r\nexport function nodeSizeProvider({ type, ...rest }: NodeSizeProviderInputs) {\r\n const provider = providers[type]?.(rest);\r\n if (!provider && type !== 'default') {\r\n throw new Error(`Unknown sizing strategy: ${type}`);\r\n }\r\n\r\n const { graph, minSize, maxSize } = rest;\r\n const sizes = new Map();\r\n let min;\r\n let max;\r\n\r\n graph.forEachNode((id, node) => {\r\n let size;\r\n if (type === 'default') {\r\n size = node.size || rest.defaultSize;\r\n } else {\r\n size = provider.getSizeForNode(id);\r\n }\r\n\r\n if (min === undefined || size < min) {\r\n min = size;\r\n }\r\n\r\n if (max === undefined || size > max) {\r\n max = size;\r\n }\r\n\r\n sizes.set(id, size);\r\n });\r\n\r\n // Relatively scale the sizes\r\n if (type !== 'none') {\r\n const scale = scaleLinear()\r\n .domain([min, max])\r\n .rangeRound([minSize, maxSize]);\r\n\r\n for (const [nodeId, size] of sizes) {\r\n sizes.set(nodeId, scale(size));\r\n }\r\n }\r\n\r\n return sizes;\r\n}\r\n","import Graph from 'graphology';\r\nimport { nodeSizeProvider, SizingType } from '../sizing';\r\nimport {\r\n GraphEdge,\r\n GraphNode,\r\n InternalGraphEdge,\r\n InternalGraphNode\r\n} from '../types';\r\nimport { calcLabelVisibility, LabelVisibilityType } from './visibility';\r\nimport { LayoutStrategy } from '../layout';\r\n\r\n/**\r\n * Initialize the graph with the nodes/edges.\r\n */\r\nexport function buildGraph(\r\n graph: Graph,\r\n nodes: GraphNode[],\r\n edges: GraphEdge[]\r\n) {\r\n // TODO: We probably want to make this\r\n // smarter and only add/remove nodes\r\n graph.clear();\r\n\r\n for (const node of nodes) {\r\n try {\r\n graph.addNode(node.id, node);\r\n } catch ({ message }) {\r\n console.error(`[Graph] ${message}`);\r\n }\r\n }\r\n\r\n for (const edge of edges) {\r\n try {\r\n graph.addEdge(edge.source, edge.target, edge);\r\n } catch ({ message }) {\r\n console.error(`[Graph] ${message}`);\r\n }\r\n }\r\n\r\n return graph;\r\n}\r\n\r\ninterface TransformGraphInput {\r\n graph: Graph;\r\n layout: LayoutStrategy;\r\n sizingType?: SizingType;\r\n labelType?: LabelVisibilityType;\r\n sizingAttribute?: string;\r\n minNodeSize?: number;\r\n maxNodeSize?: number;\r\n defaultNodeSize?: number;\r\n}\r\n\r\n/**\r\n * Transform the graph into a format that is easier to work with.\r\n */\r\nexport function transformGraph({\r\n graph,\r\n layout,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n defaultNodeSize,\r\n minNodeSize,\r\n maxNodeSize\r\n}: TransformGraphInput) {\r\n const nodes: InternalGraphNode[] = [];\r\n const edges: InternalGraphEdge[] = [];\r\n const map = new Map();\r\n\r\n const sizes = nodeSizeProvider({\r\n graph,\r\n type: sizingType,\r\n attribute: sizingAttribute,\r\n minSize: minNodeSize,\r\n maxSize: maxNodeSize,\r\n defaultSize: defaultNodeSize\r\n });\r\n\r\n const nodeCount = graph.nodes().length;\r\n const checkVisibility = calcLabelVisibility({ nodeCount, labelType });\r\n\r\n graph.forEachNode((id, node) => {\r\n const position = layout.getNodePosition(id);\r\n const { data, fill, icon, label, size, ...rest } = node;\r\n const nodeSize = sizes.get(node.id);\r\n const labelVisible = checkVisibility('node', nodeSize);\r\n\r\n const nodeLinks = graph.inboundNeighbors(node.id) || [];\r\n const parents = nodeLinks.map(n => graph.getNodeAttributes(n));\r\n\r\n const n: InternalGraphNode = {\r\n ...(node as any),\r\n size: nodeSize,\r\n labelVisible,\r\n label,\r\n icon,\r\n fill,\r\n parents,\r\n data: {\r\n ...rest,\r\n ...(data ?? {})\r\n },\r\n position: {\r\n ...position,\r\n x: position.x || 0,\r\n y: position.y || 0,\r\n z: position.z || 1\r\n }\r\n };\r\n\r\n map.set(node.id, n);\r\n nodes.push(n);\r\n });\r\n\r\n graph.forEachEdge((_id, link) => {\r\n const from = map.get(link.source);\r\n const to = map.get(link.target);\r\n\r\n if (from && to) {\r\n const { data, id, label, size, ...rest } = link;\r\n const labelVisible = checkVisibility('edge', size);\r\n\r\n // TODO: Fix type\r\n edges.push({\r\n ...link,\r\n id,\r\n label,\r\n labelVisible,\r\n size,\r\n data: {\r\n ...rest,\r\n id,\r\n ...(data || {})\r\n }\r\n } as any);\r\n }\r\n });\r\n\r\n return {\r\n nodes,\r\n edges\r\n };\r\n}\r\n","export const animationConfig = {\r\n mass: 10,\r\n tension: 1000,\r\n friction: 300,\r\n // Decreasing precision to improve performance from 0.00001\r\n precision: 0.1\r\n};\r\n","import { Curve, Vector3 } from 'three';\r\n\r\nimport { EdgeArrowPosition } from '../symbols/Arrow';\r\n\r\n// Calculate the correct position for an arrow along a curve,\r\n// as well as the tangent to the curve at that point.\r\nexport function getArrowVectors(\r\n placement: EdgeArrowPosition,\r\n curve: Curve,\r\n arrowLength: number\r\n): [Vector3, Vector3] {\r\n const curveLength = curve.getLength();\r\n const absSize = placement === 'end' ? curveLength : curveLength / 2;\r\n const offset = placement === 'end' ? arrowLength / 2 : 0;\r\n const u = (absSize - offset) / curveLength;\r\n\r\n const position = curve.getPointAt(u);\r\n const rotation = curve.getTangentAt(u);\r\n\r\n return [position, rotation];\r\n}\r\n\r\nexport function getArrowSize(size: number): [number, number] {\r\n return [size + 6, 2 + size / 1.5];\r\n}\r\n","import { Curve, LineCurve3, QuadraticBezierCurve3, Vector3 } from 'three';\r\nimport { InternalGraphNode, InternalVector3 } from '../types';\r\n\r\nconst MULTI_EDGE_OFFSET_FACTOR = 0.7;\r\n\r\n/**\r\n * Get the midpoint given two points.\r\n */\r\nexport function getMidPoint(\r\n from: InternalVector3,\r\n to: InternalVector3,\r\n offset = 0\r\n) {\r\n const fromVector = new Vector3(from.x, from.y || 0, from.z || 0);\r\n const toVector = new Vector3(to.x, to.y || 0, to.z || 0);\r\n const midVector = new Vector3()\r\n .addVectors(fromVector, toVector)\r\n .divideScalar(2);\r\n\r\n return midVector.setLength(midVector.length() + offset);\r\n}\r\n\r\n/**\r\n * Calculate the center for a quadratic bezier curve.\r\n *\r\n * 1) Find the point halfway between the start and end points of the desired curve\r\n * 2) Find the vector pependicular to that point\r\n * 3) Find the point 1/4 the distance between start and end along that vector.\r\n */\r\nexport function getCurvePoints(\r\n from: Vector3,\r\n to: Vector3,\r\n offset = -1\r\n): [Vector3, Vector3, Vector3] {\r\n const fromVector = from.clone();\r\n const toVector = to.clone();\r\n const v = new Vector3().subVectors(toVector, fromVector);\r\n const vlen = v.length();\r\n const vn = v.clone().normalize();\r\n const vv = new Vector3().subVectors(toVector, fromVector).divideScalar(2);\r\n const k = Math.abs(vn.x) % 1;\r\n const b = new Vector3(-vn.y, vn.x - k * vn.z, k * vn.y).normalize();\r\n const vm = new Vector3()\r\n .add(fromVector)\r\n .add(vv)\r\n .add(b.multiplyScalar(vlen / 4).multiplyScalar(offset));\r\n\r\n return [from, vm, to];\r\n}\r\n\r\n/**\r\n * Get the curve given two points.\r\n */\r\nexport function getCurve(\r\n from: Vector3,\r\n fromOffset: number,\r\n to: Vector3,\r\n toOffset: number,\r\n curved: boolean,\r\n curveOffset?: number\r\n): Curve {\r\n const offsetFrom = getPointBetween(from, to, fromOffset);\r\n const offsetTo = getPointBetween(to, from, toOffset);\r\n return curved\r\n ? new QuadraticBezierCurve3(\r\n ...getCurvePoints(offsetFrom, offsetTo, curveOffset)\r\n )\r\n : new LineCurve3(offsetFrom, offsetTo);\r\n}\r\n\r\n/**\r\n * Create a threejs vector for a node.\r\n */\r\nexport function getVector(node: InternalGraphNode): Vector3 {\r\n return new Vector3(node.position.x, node.position.y, node.position.z || 0);\r\n}\r\n\r\n/**\r\n * Get the point between two vectors.\r\n */\r\nfunction getPointBetween(from: Vector3, to: Vector3, offset: number): Vector3 {\r\n const distance = from.distanceTo(to);\r\n return from.clone().add(\r\n to\r\n .clone()\r\n .sub(from)\r\n .multiplyScalar(offset / distance)\r\n );\r\n}\r\n\r\n/**\r\n * Given a node and a new vector set, update the node model.\r\n */\r\nexport function updateNodePosition(node: InternalGraphNode, offset: Vector3) {\r\n return {\r\n ...node,\r\n position: {\r\n ...node.position,\r\n x: node.position.x + offset.x,\r\n y: node.position.y + offset.y,\r\n z: node.position.z + offset.z\r\n }\r\n };\r\n}\r\n\r\n/**\r\n * Calculate the curve offset for an edge.\r\n * This is used to offset edges that are parallel to each other (same source and same target).\r\n * This will return a curveOffset of null if the edge is not parallel to any other edges.\r\n */\r\nexport function calculateEdgeCurveOffset({ edge, edges, curved }) {\r\n let updatedCurved = curved;\r\n let curveOffset: number;\r\n\r\n const parallelEdges = edges\r\n .filter(e => e.target === edge.target && e.source === edge.source)\r\n .map(e => e.id);\r\n\r\n if (parallelEdges.length > 1) {\r\n updatedCurved = true;\r\n const edgeIndex = parallelEdges.indexOf(edge.id);\r\n\r\n if (parallelEdges.length === 2) {\r\n curveOffset =\r\n edgeIndex === 0 ? MULTI_EDGE_OFFSET_FACTOR : -MULTI_EDGE_OFFSET_FACTOR;\r\n } else {\r\n curveOffset =\r\n (edgeIndex - Math.floor(parallelEdges.length / 2)) *\r\n MULTI_EDGE_OFFSET_FACTOR;\r\n }\r\n }\r\n\r\n return { curved: updatedCurved, curveOffset };\r\n}\r\n","import { InternalGraphNode } from '../types';\r\n\r\nexport interface CenterPositionVector {\r\n x: number;\r\n y: number;\r\n z: number;\r\n minX: number;\r\n maxX: number;\r\n minY: number;\r\n maxY: number;\r\n minZ: number;\r\n maxZ: number;\r\n height: number;\r\n width: number;\r\n}\r\n\r\n/**\r\n * Given a collection of nodes, get the center point.\r\n */\r\nexport function getLayoutCenter(\r\n nodes: InternalGraphNode[]\r\n): CenterPositionVector {\r\n let minX = Number.POSITIVE_INFINITY;\r\n let maxX = Number.NEGATIVE_INFINITY;\r\n let minY = Number.POSITIVE_INFINITY;\r\n let maxY = Number.NEGATIVE_INFINITY;\r\n let minZ = Number.POSITIVE_INFINITY;\r\n let maxZ = Number.NEGATIVE_INFINITY;\r\n\r\n for (let node of nodes) {\r\n minX = Math.min(minX, node.position.x);\r\n maxX = Math.max(maxX, node.position.x);\r\n minY = Math.min(minY, node.position.y);\r\n maxY = Math.max(maxY, node.position.y);\r\n minZ = Math.min(minZ, node.position.z);\r\n maxZ = Math.max(maxZ, node.position.z);\r\n }\r\n\r\n return {\r\n height: maxY - minY,\r\n width: maxX - minX,\r\n minX,\r\n maxX,\r\n minY,\r\n maxY,\r\n minZ,\r\n maxZ,\r\n x: (maxX + minX) / 2,\r\n y: (maxY + minY) / 2,\r\n z: (maxZ + minZ) / 2\r\n };\r\n}\r\n","import { InternalGraphNode } from '../types';\r\nimport { CenterPositionVector, getLayoutCenter } from './layout';\r\n\r\n/**\r\n * Given nodes and a attribute, find all the cluster groups.\r\n */\r\nexport function buildClusterGroups(\r\n nodes: InternalGraphNode[],\r\n clusterAttribute?: string\r\n) {\r\n if (!clusterAttribute) {\r\n return new Map();\r\n }\r\n\r\n return nodes.reduce((entryMap, e) => {\r\n const val = e.data[clusterAttribute];\r\n if (val) {\r\n entryMap.set(val, [...(entryMap.get(val) || []), e]);\r\n }\r\n return entryMap;\r\n }, new Map());\r\n}\r\n\r\nexport interface CalculateClustersInput {\r\n nodes: InternalGraphNode[];\r\n clusterAttribute?: string;\r\n}\r\n\r\nexport interface ClusterGroup {\r\n nodes: InternalGraphNode[];\r\n position: CenterPositionVector;\r\n label: string;\r\n}\r\n\r\n/**\r\n * Builds the cluster map.\r\n */\r\nexport function calculateClusters({\r\n nodes,\r\n clusterAttribute\r\n}: CalculateClustersInput) {\r\n const result = new Map();\r\n\r\n if (clusterAttribute) {\r\n const groups = buildClusterGroups(nodes, clusterAttribute);\r\n for (const [key, nodes] of groups) {\r\n const position = getLayoutCenter(nodes);\r\n result.set(key, {\r\n label: key,\r\n nodes,\r\n position\r\n });\r\n }\r\n }\r\n\r\n return result;\r\n}\r\n","import { useCallback, useRef } from 'react';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface HoverIntentOptions {\r\n interval?: number;\r\n sensitivity?: number;\r\n timeout?: number;\r\n disabled?: boolean;\r\n onPointerOver: (event: ThreeEvent) => void;\r\n onPointerOut: (event: ThreeEvent) => void;\r\n}\r\n\r\nexport interface HoverIntentResult {\r\n pointerOut: (event: ThreeEvent) => void;\r\n pointerOver: (event: ThreeEvent) => void;\r\n}\r\n\r\n/**\r\n * Hover intent identifies if the user actually is\r\n * intending to over by measuring the position of the mouse\r\n * once a pointer enters and determining if in a duration if\r\n * the mouse moved inside a certain threshold and fires the events.\r\n */\r\nexport const useHoverIntent = ({\r\n sensitivity = 7,\r\n interval = 50,\r\n timeout = 0,\r\n disabled,\r\n onPointerOver,\r\n onPointerOut\r\n}: HoverIntentOptions | undefined): HoverIntentResult => {\r\n const mouseOver = useRef(false);\r\n const timer = useRef(null);\r\n const state = useRef(0);\r\n const coords = useRef({\r\n x: null,\r\n y: null,\r\n px: null,\r\n py: null\r\n });\r\n\r\n const onMouseMove = useCallback((event: MouseEvent) => {\r\n coords.current.x = event.clientX;\r\n coords.current.y = event.clientY;\r\n }, []);\r\n\r\n const comparePosition = useCallback(\r\n (event: ThreeEvent) => {\r\n timer.current = clearTimeout(timer.current);\r\n const { px, x, py, y } = coords.current;\r\n\r\n if (Math.abs(px - x) + Math.abs(py - y) < sensitivity) {\r\n state.current = 1;\r\n onPointerOver(event);\r\n } else {\r\n coords.current.px = x;\r\n coords.current.py = y;\r\n timer.current = setTimeout(() => comparePosition(event), interval);\r\n }\r\n },\r\n [interval, onPointerOver, sensitivity]\r\n );\r\n\r\n const cleanup = useCallback(() => {\r\n clearTimeout(timer.current);\r\n if (typeof window !== 'undefined') {\r\n document.removeEventListener('mousemove', onMouseMove, false);\r\n }\r\n }, [onMouseMove]);\r\n\r\n const pointerOver = useCallback(\r\n (event: ThreeEvent) => {\r\n if (!disabled) {\r\n mouseOver.current = true;\r\n cleanup();\r\n\r\n if (state.current !== 1) {\r\n coords.current.px = event.pointer.x;\r\n coords.current.py = event.pointer.y;\r\n\r\n if (typeof window !== 'undefined') {\r\n document.addEventListener('mousemove', onMouseMove, false);\r\n }\r\n\r\n timer.current = setTimeout(() => comparePosition(event), timeout);\r\n }\r\n }\r\n },\r\n [cleanup, comparePosition, disabled, onMouseMove, timeout]\r\n );\r\n\r\n const delay = useCallback(\r\n (event: ThreeEvent) => {\r\n timer.current = clearTimeout(timer.current);\r\n state.current = 0;\r\n onPointerOut(event);\r\n },\r\n [onPointerOut]\r\n );\r\n\r\n const pointerOut = useCallback(\r\n (event: ThreeEvent) => {\r\n mouseOver.current = false;\r\n cleanup();\r\n\r\n if (state.current === 1) {\r\n timer.current = setTimeout(() => delay(event), timeout);\r\n }\r\n },\r\n [cleanup, delay, timeout]\r\n );\r\n\r\n return {\r\n pointerOver,\r\n pointerOut\r\n };\r\n};\r\n","import { useThree } from '@react-three/fiber';\r\nimport { useMemo } from 'react';\r\nimport { useGesture } from 'react-use-gesture';\r\nimport { Vector2, Vector3, Plane } from 'three';\r\nimport { InternalGraphPosition } from '../types';\r\n\r\ninterface DragParams {\r\n draggable: boolean;\r\n position: InternalGraphPosition;\r\n set: (position: Vector3) => void;\r\n onDragStart: () => void;\r\n onDragEnd: () => void;\r\n}\r\n\r\nexport const useDrag = ({\r\n draggable,\r\n set,\r\n position,\r\n onDragStart,\r\n onDragEnd\r\n}: DragParams) => {\r\n const camera = useThree(state => state.camera);\r\n const raycaster = useThree(state => state.raycaster);\r\n const size = useThree(state => state.size);\r\n const gl = useThree(state => state.gl);\r\n\r\n // Reference: https://codesandbox.io/s/react-three-draggable-cxu37\r\n const { mouse2D, mouse3D, offset, normal, plane } = useMemo(\r\n () => ({\r\n // Normalized 2D screen space mouse coords\r\n mouse2D: new Vector2(),\r\n // 3D world space mouse coords\r\n mouse3D: new Vector3(),\r\n // Drag point offset from object origin\r\n offset: new Vector3(),\r\n // Normal of the drag plane\r\n normal: new Vector3(),\r\n // Drag plane\r\n plane: new Plane()\r\n }),\r\n []\r\n );\r\n\r\n const clientRect = useMemo(\r\n () => gl.domElement.getBoundingClientRect(),\r\n [gl.domElement]\r\n );\r\n\r\n return useGesture(\r\n {\r\n onDragStart: ({ event }) => {\r\n // @ts-ignore\r\n const { eventObject, point } = event;\r\n\r\n // Save the offset of click point from object origin\r\n eventObject.getWorldPosition(offset).sub(point);\r\n\r\n // Set initial 3D cursor position (needed for onDrag plane calculation)\r\n mouse3D.copy(point);\r\n\r\n // Run user callback\r\n onDragStart();\r\n },\r\n onDrag: ({ event }) => {\r\n // Compute normalized mouse coordinates (screen space)\r\n const scrollX = window.scrollX || window.pageXOffset;\r\n const scrollY = window.scrollY || window.pageYOffset;\r\n\r\n const nx =\r\n ((event.clientX - (clientRect?.left ?? 0) + scrollX) / size.width) *\r\n 2 -\r\n 1;\r\n const ny =\r\n -((event.clientY - (clientRect?.top ?? 0) + scrollY) / size.height) *\r\n 2 +\r\n 1;\r\n\r\n // Unlike the mouse from useThree, this works offscreen\r\n mouse2D.set(nx, ny);\r\n\r\n // Update raycaster (otherwise it doesn't track offscreen)\r\n raycaster.setFromCamera(mouse2D, camera);\r\n\r\n // The drag plane is normal to the camera view\r\n camera.getWorldDirection(normal).negate();\r\n\r\n // Find the plane that's normal to the camera and contains our drag point\r\n plane.setFromNormalAndCoplanarPoint(normal, mouse3D);\r\n\r\n // Find the point of intersection\r\n raycaster.ray.intersectPlane(plane, mouse3D);\r\n\r\n // Update the object position with the original offset\r\n const updated = new Vector3(position.x, position.y, position.z)\r\n .copy(mouse3D)\r\n .add(offset);\r\n\r\n return set(updated);\r\n },\r\n onDragEnd\r\n },\r\n { drag: { enabled: draggable, threshold: 10 } }\r\n );\r\n};\r\n","import Graph from 'graphology';\r\nimport { bidirectional } from 'graphology-shortest-path';\r\n\r\nexport function findPath(graph: Graph, source: string, target: string) {\r\n return bidirectional(graph, source, target);\r\n}\r\n","import { StoreApi, create } from 'zustand';\r\nimport createContext from 'zustand/context';\r\nimport {\r\n InternalGraphEdge,\r\n InternalGraphNode,\r\n InternalGraphPosition\r\n} from './types';\r\nimport { BufferGeometry, Mesh, Vector3 } from 'three';\r\nimport {\r\n CenterPositionVector,\r\n ClusterGroup,\r\n getLayoutCenter,\r\n getVector,\r\n updateNodePosition\r\n} from './utils';\r\nimport Graph from 'graphology';\r\nimport { Theme } from './themes';\r\n\r\nexport type DragReferences = {\r\n [key: string]: InternalGraphNode;\r\n};\r\n\r\nexport interface GraphState {\r\n nodes: InternalGraphNode[];\r\n edges: InternalGraphEdge[];\r\n graph: Graph;\r\n clusters: Map;\r\n collapsedNodeIds?: string[];\r\n centerPosition?: CenterPositionVector;\r\n actives?: string[];\r\n selections?: string[];\r\n edgeContextMenus?: Set;\r\n setEdgeContextMenus: (edges: Set) => void;\r\n edgeMeshes: Array>;\r\n setEdgeMeshes: (edgeMeshes: Array>) => void;\r\n draggingId?: string | null;\r\n drags?: DragReferences;\r\n panning?: boolean;\r\n theme: Theme;\r\n setTheme: (theme: Theme) => void;\r\n setClusters: (clusters: Map) => void;\r\n setPanning: (panning: boolean) => void;\r\n setDrags: (drags: DragReferences) => void;\r\n setDraggingId: (id: string | null) => void;\r\n setActives: (actives: string[]) => void;\r\n setSelections: (selections: string[]) => void;\r\n setNodes: (nodes: InternalGraphNode[]) => void;\r\n setEdges: (edges: InternalGraphEdge[]) => void;\r\n setNodePosition: (id: string, position: InternalGraphPosition) => void;\r\n setCollapsedNodeIds: (nodeIds: string[]) => void;\r\n canvasRef: HTMLCanvasElement | null;\r\n}\r\n\r\nexport const { Provider, useStore } = createContext>();\r\n\r\nexport const createStore = ({\r\n actives = [],\r\n selections = [],\r\n collapsedNodeIds = [],\r\n theme,\r\n canvasRef = null\r\n}: Partial) =>\r\n create(set => ({\r\n theme: {\r\n ...theme,\r\n edge: {\r\n ...theme.edge,\r\n label: {\r\n ...theme.edge.label,\r\n fontSize: theme.edge.label.fontSize ?? 6\r\n }\r\n }\r\n },\r\n edges: [],\r\n nodes: [],\r\n collapsedNodeIds,\r\n clusters: new Map(),\r\n panning: false,\r\n draggingId: null,\r\n actives,\r\n edgeContextMenus: new Set(),\r\n edgeMeshes: [],\r\n selections,\r\n drags: {},\r\n graph: new Graph({ multi: true }),\r\n setTheme: theme => set(state => ({ ...state, theme })),\r\n setClusters: clusters => set(state => ({ ...state, clusters })),\r\n setEdgeContextMenus: edgeContextMenus =>\r\n set(state => ({\r\n ...state,\r\n edgeContextMenus\r\n })),\r\n setEdgeMeshes: edgeMeshes => set(state => ({ ...state, edgeMeshes })),\r\n setPanning: panning => set(state => ({ ...state, panning })),\r\n setDrags: drags => set(state => ({ ...state, drags })),\r\n setDraggingId: draggingId => set(state => ({ ...state, draggingId })),\r\n setActives: actives => set(state => ({ ...state, actives })),\r\n setSelections: selections => set(state => ({ ...state, selections })),\r\n setNodes: nodes =>\r\n set(state => ({\r\n ...state,\r\n nodes,\r\n centerPosition: getLayoutCenter(nodes)\r\n })),\r\n setEdges: edges => set(state => ({ ...state, edges })),\r\n setNodePosition: (id, position) =>\r\n set(state => {\r\n const node = state.nodes.find(n => n.id === id);\r\n const originalVector = getVector(node);\r\n const newVector = new Vector3(position.x, position.y, position.z);\r\n const offset = newVector.sub(originalVector);\r\n const nodes = [...state.nodes];\r\n\r\n if (state.selections?.includes(id)) {\r\n state.selections?.forEach(id => {\r\n const node = state.nodes.find(n => n.id === id);\r\n // Selections can contain edges:\r\n if (node) {\r\n const nodeIndex = state.nodes.indexOf(node);\r\n nodes[nodeIndex] = updateNodePosition(node, offset);\r\n }\r\n });\r\n } else {\r\n const nodeIndex = state.nodes.indexOf(node);\r\n nodes[nodeIndex] = updateNodePosition(node, offset);\r\n }\r\n\r\n return {\r\n ...state,\r\n drags: {\r\n ...state.drags,\r\n [id]: node\r\n },\r\n nodes\r\n };\r\n }),\r\n setCollapsedNodeIds: (nodeIds = []) =>\r\n set(state => ({ ...state, collapsedNodeIds: nodeIds })),\r\n canvasRef\r\n }));\r\n","import { GraphEdge, GraphNode } from '../types';\r\n\r\ninterface GetHiddenChildrenInput {\r\n nodeId: string;\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n currentHiddenNodes: GraphNode[];\r\n currentHiddenEdges: GraphEdge[];\r\n}\r\n\r\ninterface GetVisibleIdsInput {\r\n collapsedIds: string[];\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n}\r\n\r\ninterface GetExpandPathInput {\r\n nodeId: string;\r\n edges: GraphEdge[];\r\n visibleEdgeIds: string[];\r\n}\r\n\r\n/**\r\n * Get the children of a node id that is hidden.\r\n */\r\nfunction getHiddenChildren({\r\n nodeId,\r\n nodes,\r\n edges,\r\n currentHiddenNodes,\r\n currentHiddenEdges\r\n}: GetHiddenChildrenInput) {\r\n const hiddenNodes: GraphNode[] = [];\r\n const hiddenEdges: GraphEdge[] = [];\r\n const curHiddenNodeIds = currentHiddenNodes.map(n => n.id);\r\n const curHiddenEdgeIds = currentHiddenEdges.map(e => e.id);\r\n\r\n const outboundEdges = edges.filter(l => l.source === nodeId);\r\n const outboundEdgeNodeIds = outboundEdges.map(l => l.target);\r\n\r\n hiddenEdges.push(...outboundEdges);\r\n for (const outboundEdgeNodeId of outboundEdgeNodeIds) {\r\n const incomingEdges = edges.filter(\r\n l => l.target === outboundEdgeNodeId && l.source !== nodeId\r\n );\r\n let hideNode = false;\r\n\r\n // Check to see if any other edge is coming into this node\r\n if (incomingEdges.length === 0) {\r\n hideNode = true;\r\n } else if (\r\n incomingEdges.length > 0 &&\r\n !curHiddenNodeIds.includes(outboundEdgeNodeId)\r\n ) {\r\n // If all inbound links are hidden, hide this node as well\r\n const inboundNodeLinkIds = incomingEdges.map(l => l.id);\r\n if (inboundNodeLinkIds.every(i => curHiddenEdgeIds.includes(i))) {\r\n hideNode = true;\r\n }\r\n }\r\n if (hideNode) {\r\n // Need to hide this node and any children of this node\r\n const node = nodes.find(n => n.id === outboundEdgeNodeId);\r\n if (node) {\r\n hiddenNodes.push(node);\r\n }\r\n const nested = getHiddenChildren({\r\n nodeId: outboundEdgeNodeId,\r\n nodes,\r\n edges,\r\n currentHiddenEdges: hiddenEdges,\r\n currentHiddenNodes: hiddenNodes\r\n });\r\n hiddenEdges.push(...nested.hiddenEdges);\r\n hiddenNodes.push(...nested.hiddenNodes);\r\n }\r\n }\r\n\r\n const uniqueEdges: GraphEdge[] = Object.values(\r\n hiddenEdges.reduce(\r\n (acc, next) => ({\r\n ...acc,\r\n [next.id]: next\r\n }),\r\n {}\r\n )\r\n );\r\n\r\n const uniqueNodes: GraphNode[] = Object.values(\r\n hiddenNodes.reduce(\r\n (acc, next) => ({\r\n ...acc,\r\n [next.id]: next\r\n }),\r\n {}\r\n )\r\n );\r\n\r\n return {\r\n hiddenEdges: uniqueEdges,\r\n hiddenNodes: uniqueNodes\r\n };\r\n}\r\n\r\n/**\r\n * Get the visible nodes and edges given a collapsed set of ids.\r\n */\r\nexport const getVisibleEntities = ({\r\n collapsedIds,\r\n nodes,\r\n edges\r\n}: GetVisibleIdsInput) => {\r\n const curHiddenNodes = [];\r\n const curHiddenEdges = [];\r\n\r\n for (const collapsedId of collapsedIds) {\r\n const { hiddenEdges, hiddenNodes } = getHiddenChildren({\r\n nodeId: collapsedId,\r\n nodes,\r\n edges,\r\n currentHiddenEdges: curHiddenEdges,\r\n currentHiddenNodes: curHiddenNodes\r\n });\r\n\r\n curHiddenNodes.push(...hiddenNodes);\r\n curHiddenEdges.push(...hiddenEdges);\r\n }\r\n\r\n const hiddenNodeIds = curHiddenNodes.map(n => n.id);\r\n const hiddenEdgeIds = curHiddenEdges.map(e => e.id);\r\n const visibleNodes = nodes.filter(n => !hiddenNodeIds.includes(n.id));\r\n const visibleEdges = edges.filter(e => !hiddenEdgeIds.includes(e.id));\r\n\r\n return {\r\n visibleNodes,\r\n visibleEdges\r\n };\r\n};\r\n\r\n/**\r\n * Get the path to expand a node.\r\n */\r\nexport const getExpandPath = ({\r\n nodeId,\r\n edges,\r\n visibleEdgeIds\r\n}: GetExpandPathInput) => {\r\n const parentIds = [];\r\n const inboundEdges = edges.filter(l => l.target === nodeId);\r\n const inboundEdgeIds = inboundEdges.map(e => e.id);\r\n const hasVisibleInboundEdge = inboundEdgeIds.some(id =>\r\n visibleEdgeIds.includes(id)\r\n );\r\n\r\n if (hasVisibleInboundEdge) {\r\n // If there is a visible edge to this node, that means the node is\r\n // visible so no parents need to be expanded\r\n return parentIds;\r\n }\r\n\r\n const inboundEdgeNodeIds = inboundEdges.map(l => l.source);\r\n let addedParent = false;\r\n\r\n for (const inboundNodeId of inboundEdgeNodeIds) {\r\n if (!addedParent) {\r\n // Only want to expand a single path to the node, so if there\r\n // are multiple hidden incoming edges, only expand the first\r\n // to reduce how many nodes are expanded to get to the node\r\n parentIds.push(\r\n ...[\r\n inboundNodeId,\r\n ...getExpandPath({ nodeId: inboundNodeId, edges, visibleEdgeIds })\r\n ]\r\n );\r\n addedParent = true;\r\n }\r\n }\r\n\r\n return parentIds;\r\n};\r\n","import React, { useCallback } from 'react';\r\nimport { GraphEdge, GraphNode } from 'types';\r\nimport { getExpandPath, getVisibleEntities } from './utils';\r\n\r\nexport interface UseCollapseProps {\r\n /**\r\n * Current collapsed node ids.\r\n */\r\n collapsedNodeIds?: string[];\r\n\r\n /**\r\n * Node data.\r\n */\r\n nodes?: GraphNode[];\r\n\r\n /**\r\n * Edge data.\r\n */\r\n edges?: GraphEdge[];\r\n}\r\n\r\nexport interface CollpaseResult {\r\n /**\r\n * Determine if a node is currently collapsed\r\n */\r\n getIsCollapsed: (nodeId: string) => boolean;\r\n\r\n /**\r\n * Return a list of ids required to expand in order to view the provided node\r\n */\r\n getExpandPathIds: (nodeId: string) => string[];\r\n}\r\n\r\nexport const useCollapse = ({\r\n collapsedNodeIds = [],\r\n nodes = [],\r\n edges = []\r\n}: UseCollapseProps): CollpaseResult => {\r\n const getIsCollapsed = useCallback(\r\n (nodeId: string) => {\r\n const { visibleNodes } = getVisibleEntities({\r\n nodes,\r\n edges,\r\n collapsedIds: collapsedNodeIds\r\n });\r\n const visibleNodeIds = visibleNodes.map(n => n.id);\r\n\r\n return !visibleNodeIds.includes(nodeId);\r\n },\r\n [collapsedNodeIds, edges, nodes]\r\n );\r\n\r\n const getExpandPathIds = useCallback(\r\n (nodeId: string) => {\r\n const { visibleEdges } = getVisibleEntities({\r\n nodes,\r\n edges,\r\n collapsedIds: collapsedNodeIds\r\n });\r\n const visibleEdgeIds = visibleEdges.map(e => e.id);\r\n\r\n return getExpandPath({ nodeId, edges, visibleEdgeIds });\r\n },\r\n [collapsedNodeIds, edges, nodes]\r\n );\r\n\r\n return {\r\n getIsCollapsed,\r\n getExpandPathIds\r\n };\r\n};\r\n","import { useRef, useCallback, useEffect, useMemo } from 'react';\r\nimport { useThree } from '@react-three/fiber';\r\nimport { PerspectiveCamera } from 'three';\r\nimport { SizingType } from './sizing';\r\nimport {\r\n LayoutTypes,\r\n layoutProvider,\r\n LayoutStrategy,\r\n LayoutOverrides\r\n} from './layout';\r\nimport { LabelVisibilityType, calcLabelVisibility } from './utils/visibility';\r\nimport { tick } from './layout/layoutUtils';\r\nimport { GraphEdge, GraphNode } from './types';\r\nimport { buildGraph, transformGraph } from './utils/graph';\r\nimport { DragReferences, useStore } from './store';\r\nimport { getVisibleEntities } from './collapse';\r\nimport { calculateClusters } from './utils/cluster';\r\n\r\nexport interface GraphInputs {\r\n nodes: GraphNode[];\r\n edges: GraphEdge[];\r\n collapsedNodeIds?: string[];\r\n layoutType?: LayoutTypes;\r\n sizingType?: SizingType;\r\n labelType?: LabelVisibilityType;\r\n sizingAttribute?: string;\r\n selections?: string[];\r\n actives?: string[];\r\n clusterAttribute?: string;\r\n defaultNodeSize?: number;\r\n minNodeSize?: number;\r\n maxNodeSize?: number;\r\n layoutOverrides?: LayoutOverrides;\r\n}\r\n\r\nexport const useGraph = ({\r\n layoutType,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n clusterAttribute,\r\n selections,\r\n nodes,\r\n edges,\r\n actives,\r\n collapsedNodeIds,\r\n defaultNodeSize,\r\n maxNodeSize,\r\n minNodeSize,\r\n layoutOverrides\r\n}: GraphInputs) => {\r\n const graph = useStore(state => state.graph);\r\n const setClusters = useStore(state => state.setClusters);\r\n const stateCollapsedNodeIds = useStore(state => state.collapsedNodeIds);\r\n const setEdges = useStore(state => state.setEdges);\r\n const stateNodes = useStore(state => state.nodes);\r\n const setNodes = useStore(state => state.setNodes);\r\n const setSelections = useStore(state => state.setSelections);\r\n const setActives = useStore(state => state.setActives);\r\n const drags = useStore(state => state.drags);\r\n const setDrags = useStore(state => state.setDrags);\r\n const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\r\n const layoutMounted = useRef(false);\r\n const layout = useRef(null);\r\n const camera = useThree(state => state.camera) as PerspectiveCamera;\r\n\r\n const { visibleEdges, visibleNodes } = useMemo(\r\n () =>\r\n getVisibleEntities({\r\n collapsedIds: stateCollapsedNodeIds,\r\n nodes,\r\n edges\r\n }),\r\n [stateCollapsedNodeIds, nodes, edges]\r\n );\r\n\r\n // Transient updates\r\n const dragRef = useRef(drags);\r\n useEffect(() => {\r\n dragRef.current = drags;\r\n }, [drags]);\r\n\r\n const updateLayout = useCallback(\r\n async (curLayout?: any) => {\r\n // Cache the layout provider\r\n layout.current =\r\n curLayout ||\r\n layoutProvider({\r\n ...layoutOverrides,\r\n type: layoutType,\r\n graph,\r\n drags: dragRef.current,\r\n clusterAttribute\r\n });\r\n\r\n // Run the layout\r\n await tick(layout.current);\r\n\r\n // Transform the graph\r\n const result = transformGraph({\r\n graph,\r\n layout: layout.current,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n maxNodeSize,\r\n minNodeSize,\r\n defaultNodeSize\r\n });\r\n\r\n // Calculate clusters\r\n const clusters = calculateClusters({\r\n nodes: result.nodes,\r\n clusterAttribute\r\n });\r\n\r\n // Set our store outputs\r\n setEdges(result.edges);\r\n setNodes(result.nodes);\r\n setClusters(clusters);\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [\r\n layoutOverrides,\r\n layoutType,\r\n clusterAttribute,\r\n sizingType,\r\n labelType,\r\n sizingAttribute,\r\n maxNodeSize,\r\n minNodeSize,\r\n defaultNodeSize,\r\n setEdges,\r\n setNodes,\r\n setClusters\r\n ]\r\n );\r\n\r\n useEffect(() => {\r\n const nodes = stateNodes.map(node => ({\r\n ...node,\r\n labelVisible: calcLabelVisibility({\r\n nodeCount: stateNodes?.length,\r\n labelType,\r\n camera,\r\n nodePosition: node?.position\r\n })('node', node?.size)\r\n }));\r\n\r\n const isVisibilityUpdated = nodes.some(\r\n (node, i) => node.labelVisible !== stateNodes[i].labelVisible\r\n );\r\n\r\n if (isVisibilityUpdated) {\r\n setNodes(nodes);\r\n }\r\n }, [camera, camera.zoom, camera.position.z, setNodes, stateNodes, labelType]);\r\n\r\n useEffect(() => {\r\n // Let's set the store selections so its easier to access\r\n if (layoutMounted.current) {\r\n setSelections(selections);\r\n }\r\n }, [selections, setSelections]);\r\n\r\n useEffect(() => {\r\n // Let's set the store actives so its easier to access\r\n if (layoutMounted.current) {\r\n setActives(actives);\r\n }\r\n }, [actives, setActives]);\r\n\r\n // Create the nggraph graph object\r\n useEffect(() => {\r\n async function update() {\r\n layoutMounted.current = false;\r\n buildGraph(graph, visibleNodes, visibleEdges);\r\n await updateLayout();\r\n layoutMounted.current = true;\r\n }\r\n\r\n update();\r\n // eslint-disable-next-line\r\n }, [visibleNodes, visibleEdges]);\r\n\r\n useEffect(() => {\r\n // Let's set the store collapsedNodeIds so its easier to access\r\n if (layoutMounted.current) {\r\n setCollapsedNodeIds(collapsedNodeIds);\r\n }\r\n }, [collapsedNodeIds, setCollapsedNodeIds]);\r\n\r\n // Update layout on type changes\r\n useEffect(() => {\r\n if (layoutMounted.current) {\r\n // When a update is changed, discard all the previous drag positions\r\n // NOTE: This sets the transient and the state\r\n dragRef.current = {};\r\n setDrags({});\r\n\r\n // Recalculate the layout\r\n updateLayout();\r\n }\r\n }, [layoutType, updateLayout, setDrags]);\r\n\r\n // Update layout on size, label changes\r\n useEffect(() => {\r\n if (layoutMounted.current) {\r\n updateLayout(layout.current);\r\n }\r\n }, [sizingType, sizingAttribute, labelType, updateLayout]);\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { Billboard, RoundedBox, Text } from 'glodrei';\r\nimport { Color, ColorRepresentation, Euler } from 'three';\r\nimport ellipsize from 'ellipsize';\r\nimport { a } from '@react-spring/three';\r\n\r\nconst calculateTextSize = (\r\n text: string,\r\n fontSize: number,\r\n maxWidth: number,\r\n ellipsis: number,\r\n active: boolean\r\n) => {\r\n const shortText = ellipsis && !active ? ellipsize(text, ellipsis) : text;\r\n const lines = [];\r\n let currentLine = '';\r\n const words = shortText.split(' ');\r\n\r\n words.forEach(word => {\r\n const testLine = currentLine ? `${currentLine} ${word}` : word;\r\n const testWidth = testLine.length * fontSize * 1;\r\n\r\n if (testWidth > maxWidth) {\r\n lines.push(currentLine);\r\n currentLine = word;\r\n } else {\r\n currentLine = testLine;\r\n }\r\n });\r\n\r\n if (currentLine) {\r\n lines.push(currentLine);\r\n }\r\n\r\n const width =\r\n Math.min(\r\n maxWidth,\r\n lines.reduce(\r\n (max, line) => Math.max(max, line.length * fontSize * 0.4),\r\n 0\r\n )\r\n ) + 14;\r\n const height = lines.length * fontSize + 6;\r\n\r\n return { width, height, text: lines.join('\\n'), lineCount: lines.length };\r\n};\r\n\r\nexport interface LabelProps {\r\n /**\r\n * Text to render.\r\n */\r\n text: string;\r\n\r\n /**\r\n * Font URL.\r\n * Reference: https://github.com/reaviz/reagraph/issues/23\r\n */\r\n fontUrl?: string;\r\n\r\n /**\r\n * Size of the font.\r\n */\r\n fontSize?: number;\r\n\r\n /**\r\n * Color of the text.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Stroke of the text.\r\n */\r\n stroke?: ColorRepresentation;\r\n\r\n /**\r\n * Opacity for the label.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The lenth of which to start the ellipsis.\r\n */\r\n ellipsis?: number;\r\n\r\n /**\r\n * Whether the label is active ( dragging, hover, focus ).\r\n */\r\n active?: boolean;\r\n\r\n /**\r\n * Rotation of the label.\r\n */\r\n rotation?: Euler | [number, number, number];\r\n\r\n /**\r\n * Maximum width of the label.\r\n */\r\n maxWidth?: number;\r\n\r\n /**\r\n * Background color of the label.\r\n */\r\n backgroundColor?: ColorRepresentation;\r\n\r\n /**\r\n * Border radius of the label.\r\n */\r\n borderRadius?: number;\r\n\r\n /**\r\n * Type of the label.\r\n */\r\n type?: 'node' | 'edge';\r\n\r\n /**\r\n * label visible or not\r\n */\r\n labelVisible?: boolean;\r\n}\r\n\r\nexport const Label: FC = ({\r\n text,\r\n fontSize,\r\n fontUrl,\r\n color,\r\n opacity,\r\n stroke,\r\n active,\r\n rotation,\r\n maxWidth = 100,\r\n ellipsis = 100,\r\n backgroundColor,\r\n borderRadius,\r\n labelVisible = true\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const normalizedBackgroundColor = useMemo(\r\n () => new Color(backgroundColor),\r\n [backgroundColor]\r\n );\r\n const normalizedStroke = useMemo(\r\n () => (stroke ? new Color(stroke) : undefined),\r\n [stroke]\r\n );\r\n\r\n const {\r\n width,\r\n height,\r\n text: processedText,\r\n lineCount\r\n } = useMemo(\r\n () => calculateTextSize(text, fontSize, maxWidth, ellipsis, active),\r\n [text, fontSize, maxWidth, ellipsis, active]\r\n );\r\n\r\n return (\r\n \r\n {backgroundColor ? (\r\n \r\n \r\n \r\n {processedText}\r\n \r\n \r\n \r\n \r\n ) : (\r\n \r\n {processedText}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nLabel.defaultProps = {\r\n opacity: 1,\r\n fontSize: 4,\r\n color: '#2A6475',\r\n ellipsis: 100\r\n};\r\n","import React, { FC, useMemo } from 'react';\nimport { Color, ColorRepresentation, DoubleSide } from 'three';\nimport { animationConfig } from '../utils/animation';\nimport { useSpring, a } from '@react-spring/three';\nimport { Billboard } from 'glodrei';\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 = ({\n color,\n size,\n opacity,\n animated,\n strokeWidth,\n innerRadius = 2,\n segments = 50\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 \n \n \n \n \n \n );\n};\n\nRing.defaultProps = {\n color: '#D8E6EA',\n size: 1,\n opacity: 0.5,\n strokeWidth: 5\n};\n","import React, { FC, useMemo } from 'react';\nimport { useSpring, a } from '@react-spring/three';\nimport { animationConfig } from '../../utils/animation';\nimport { Color, DoubleSide } from 'three';\nimport { NodeRendererProps } from '../../types';\nimport { Ring } from '../Ring';\nimport { useStore } from '../../store';\n\nexport const Sphere: FC = ({\n color,\n id,\n size,\n active,\n selected,\n opacity,\n animated,\n showRing\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: active\n ? [size * 1.05, size * 1.05, size * 1.05]\n : [size, size, size],\n nodeOpacity: opacity\n },\n config: {\n ...animationConfig,\n duration: animated ? undefined : 0\n }\n });\n\n const normalizedColor = useMemo(() => new Color(color), [color]);\n const theme = useStore(state => state.theme);\n\n return (\n <>\n \n \n \n \n {(showRing || selected || active) && (\n \n \n \n )}\n \n );\n};\n\nSphere.defaultProps = {\n opacity: 1,\n active: false\n};\n","import CameraControls from 'camera-controls';\r\nimport { createContext, useContext } from 'react';\r\n\r\nexport interface CameraControlsContextProps {\r\n /**\r\n * The camera controls object.\r\n */\r\n controls: CameraControls | null;\r\n\r\n /**\r\n * A function that resets the camera controls.\r\n * If the optional `animated` argument is true, the reset is animated.\r\n */\r\n resetControls: (animated?: boolean) => void;\r\n\r\n /**\r\n * A function that zooms in the camera.\r\n */\r\n zoomIn: () => void;\r\n\r\n /**\r\n * A function that zooms out the camera.\r\n */\r\n zoomOut: () => void;\r\n\r\n /**\r\n * A function that dollies in the camera.\r\n */\r\n dollyIn: (distance?: number) => void;\r\n\r\n /**\r\n * A function that dollies out the camera.\r\n */\r\n dollyOut: (distance?: number) => void;\r\n\r\n /**\r\n * A function that pans the camera to the left.\r\n */\r\n panLeft: () => void;\r\n\r\n /**\r\n * A function that pans the camera to the right.\r\n */\r\n panRight: () => void;\r\n\r\n /**\r\n * A function that pans the camera upwards.\r\n */\r\n panUp: () => void;\r\n\r\n /**\r\n * A function that pans the camera downwards.\r\n */\r\n panDown: () => void;\r\n}\r\n\r\nexport const CameraControlsContext = createContext({\r\n controls: null,\r\n resetControls: () => undefined,\r\n zoomIn: () => undefined,\r\n zoomOut: () => undefined,\r\n dollyIn: () => undefined,\r\n dollyOut: () => undefined,\r\n panLeft: () => undefined,\r\n panRight: () => undefined,\r\n panUp: () => undefined,\r\n panDown: () => undefined\r\n});\r\n\r\nexport const useCameraControls = () => {\r\n const context = useContext(CameraControlsContext);\r\n\r\n if (context === undefined) {\r\n throw new Error(\r\n '`useCameraControls` hook must be used within a `ControlsProvider` component'\r\n );\r\n }\r\n\r\n return context;\r\n};\r\n","import React, {\r\n FC,\r\n useRef,\r\n useEffect,\r\n useCallback,\r\n forwardRef,\r\n Ref,\r\n useImperativeHandle,\r\n useMemo,\r\n ReactNode\r\n} from 'react';\r\nimport { useThree, useFrame, extend } from '@react-three/fiber';\r\nimport {\r\n MOUSE,\r\n Vector2,\r\n Vector3,\r\n Vector4,\r\n Quaternion,\r\n Matrix4,\r\n Spherical,\r\n Box3,\r\n Sphere,\r\n Raycaster,\r\n MathUtils\r\n} from 'three';\r\nimport ThreeCameraControls from 'camera-controls';\r\nimport {\r\n CameraControlsContext,\r\n CameraControlsContextProps\r\n} from './useCameraControls';\r\nimport { useHotkeys } from 'reakeys';\r\nimport * as holdEvent from 'hold-event';\r\nimport { useStore } from '../store';\r\n\r\n// Install the camera controls\r\n// Use a subset for better three shaking\r\nThreeCameraControls.install({\r\n THREE: {\r\n MOUSE: MOUSE,\r\n Vector2: Vector2,\r\n Vector3: Vector3,\r\n Vector4: Vector4,\r\n Quaternion: Quaternion,\r\n Matrix4: Matrix4,\r\n Spherical: Spherical,\r\n Box3: Box3,\r\n Sphere: Sphere,\r\n Raycaster: Raycaster,\r\n MathUtils: {\r\n DEG2RAD: MathUtils?.DEG2RAD,\r\n clamp: MathUtils?.clamp\r\n }\r\n }\r\n});\r\n\r\n// Extend r3f with the new controls\r\nextend({ ThreeCameraControls });\r\n\r\nconst KEY_CODES = {\r\n ARROW_LEFT: 37,\r\n ARROW_UP: 38,\r\n ARROW_RIGHT: 39,\r\n ARROW_DOWN: 40\r\n};\r\n\r\nconst leftKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_LEFT, 100);\r\nconst rightKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_RIGHT, 100);\r\nconst upKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_UP, 100);\r\nconst downKey = new holdEvent.KeyboardKeyHold(KEY_CODES.ARROW_DOWN, 100);\r\n\r\nexport type CameraMode = 'pan' | 'rotate' | 'orbit';\r\n\r\nexport interface CameraControlsProps {\r\n /**\r\n * Mode of the camera.\r\n */\r\n mode?: CameraMode;\r\n\r\n /**\r\n * Children symbols.\r\n */\r\n children?: ReactNode;\r\n\r\n /**\r\n * Animate transitions to centering.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the controls are enabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The maximum distance for the camera.\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * The minimum distance for the camera.\r\n */\r\n minDistance?: number;\r\n}\r\n\r\nexport type CameraControlsRef = CameraControlsContextProps;\r\n\r\nexport const CameraControls: FC<\r\n CameraControlsProps & { ref?: Ref }\r\n> = forwardRef(\r\n (\r\n { mode, children, animated, disabled, minDistance, maxDistance },\r\n ref: Ref\r\n ) => {\r\n const cameraRef = useRef(null);\r\n const camera = useThree(state => state.camera);\r\n const gl = useThree(state => state.gl);\r\n const isOrbiting = mode === 'orbit';\r\n const setPanning = useStore(state => state.setPanning);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n useFrame((_state, delta) => {\r\n if (cameraRef.current?.enabled) {\r\n cameraRef.current?.update(delta);\r\n }\r\n\r\n if (isOrbiting) {\r\n cameraRef.current.azimuthAngle += 20 * delta * MathUtils.DEG2RAD;\r\n }\r\n }, -1);\r\n\r\n useEffect(() => () => cameraRef.current?.dispose(), []);\r\n\r\n const zoomIn = useCallback(() => {\r\n cameraRef.current?.zoom(camera.zoom / 2, animated);\r\n }, [animated, camera.zoom]);\r\n\r\n const zoomOut = useCallback(() => {\r\n cameraRef.current?.zoom(-camera.zoom / 2, animated);\r\n }, [animated, camera.zoom]);\r\n\r\n const dollyIn = useCallback(\r\n distance => {\r\n cameraRef.current?.dolly(distance, animated);\r\n },\r\n [animated]\r\n );\r\n\r\n const dollyOut = useCallback(\r\n distance => {\r\n cameraRef.current?.dolly(distance, animated);\r\n },\r\n [animated]\r\n );\r\n\r\n const panRight = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(-0.03 * event.deltaTime, 0, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panLeft = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0.03 * event.deltaTime, 0, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panUp = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0, 0.03 * event.deltaTime, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const panDown = useCallback(\r\n event => {\r\n if (!isOrbiting) {\r\n cameraRef.current?.truck(0, -0.03 * event.deltaTime, animated);\r\n }\r\n },\r\n [animated, isOrbiting]\r\n );\r\n\r\n const onKeyDown = useCallback(\r\n event => {\r\n if (event.code === 'Space') {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n }\r\n }\r\n },\r\n [mode]\r\n );\r\n\r\n const onKeyUp = useCallback(\r\n event => {\r\n if (event.code === 'Space') {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n }\r\n }\r\n },\r\n [mode]\r\n );\r\n\r\n useEffect(() => {\r\n if (!disabled) {\r\n leftKey.addEventListener('holding', panLeft);\r\n rightKey.addEventListener('holding', panRight);\r\n upKey.addEventListener('holding', panUp);\r\n downKey.addEventListener('holding', panDown);\r\n\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', onKeyDown);\r\n window.addEventListener('keyup', onKeyUp);\r\n }\r\n }\r\n\r\n return () => {\r\n leftKey.removeEventListener('holding', panLeft);\r\n rightKey.removeEventListener('holding', panRight);\r\n upKey.removeEventListener('holding', panUp);\r\n downKey.removeEventListener('holding', panDown);\r\n\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', onKeyDown);\r\n window.removeEventListener('keyup', onKeyUp);\r\n }\r\n };\r\n }, [disabled, onKeyDown, onKeyUp, panDown, panLeft, panRight, panUp]);\r\n\r\n useEffect(() => {\r\n if (disabled) {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\r\n cameraRef.current.mouseButtons.middle = ThreeCameraControls.ACTION.NONE;\r\n cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.NONE;\r\n } else {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.TRUCK;\r\n cameraRef.current.mouseButtons.middle =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n cameraRef.current.mouseButtons.wheel = ThreeCameraControls.ACTION.DOLLY;\r\n }\r\n }, [disabled]);\r\n\r\n useEffect(() => {\r\n const onControl = () => setPanning(true);\r\n const onControlEnd = () => setPanning(false);\r\n\r\n const ref = cameraRef.current;\r\n if (ref) {\r\n ref.addEventListener('control', onControl);\r\n ref.addEventListener('controlend', onControlEnd);\r\n }\r\n\r\n return () => {\r\n if (ref) {\r\n ref.removeEventListener('control', onControl);\r\n ref.removeEventListener('controlend', onControlEnd);\r\n }\r\n };\r\n }, [cameraRef, setPanning]);\r\n\r\n useEffect(() => {\r\n // If a node is being dragged, disable the camera controls\r\n if (draggingId) {\r\n cameraRef.current.mouseButtons.left = ThreeCameraControls.ACTION.NONE;\r\n } else {\r\n if (mode === 'rotate') {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.ROTATE;\r\n } else {\r\n cameraRef.current.mouseButtons.left =\r\n ThreeCameraControls.ACTION.TRUCK;\r\n }\r\n }\r\n }, [draggingId, mode]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Zoom In',\r\n disabled,\r\n category: 'Graph',\r\n keys: 'command+shift+i',\r\n callback: event => {\r\n event.preventDefault();\r\n zoomIn();\r\n }\r\n },\r\n {\r\n name: 'Zoom Out',\r\n category: 'Graph',\r\n disabled,\r\n keys: 'command+shift+o',\r\n callback: event => {\r\n event.preventDefault();\r\n zoomOut();\r\n }\r\n }\r\n ]);\r\n\r\n const values = useMemo(\r\n () => ({\r\n controls: cameraRef.current,\r\n zoomIn: () => zoomIn(),\r\n zoomOut: () => zoomOut(),\r\n dollyIn: (distance = 1000) => dollyIn(distance),\r\n dollyOut: (distance = -1000) => dollyOut(distance),\r\n panLeft: (deltaTime = 100) => panLeft({ deltaTime }),\r\n panRight: (deltaTime = 100) => panRight({ deltaTime }),\r\n panDown: (deltaTime = 100) => panDown({ deltaTime }),\r\n panUp: (deltaTime = 100) => panUp({ deltaTime }),\r\n resetControls: (animated?: boolean) =>\r\n cameraRef.current?.reset(animated)\r\n }),\r\n // eslint-disable-next-line\r\n [zoomIn, zoomOut, panLeft, panRight, panDown, panUp, cameraRef.current]\r\n );\r\n\r\n useImperativeHandle(ref, () => values);\r\n\r\n return (\r\n \r\n \r\n {children}\r\n \r\n );\r\n }\r\n);\r\n\r\nCameraControls.defaultProps = {\r\n mode: 'rotate',\r\n minDistance: 1000,\r\n maxDistance: 50000\r\n};\r\n","import { PerspectiveCamera } from 'three';\r\nimport { InternalGraphPosition } from '../types';\r\n\r\n/**\r\n * Get the visible height at the z depth.\r\n * Ref: https://discourse.threejs.org/t/functions-to-calculate-the-visible-width-height-at-a-given-z-depth-from-a-perspective-camera/269\r\n */\r\nfunction visibleHeightAtZDepth(depth: number, camera: PerspectiveCamera) {\r\n // compensate for cameras not positioned at z=0\r\n const cameraOffset = camera.position.z;\r\n if (depth < cameraOffset) depth -= cameraOffset;\r\n else depth += cameraOffset;\r\n\r\n // vertical fov in radians\r\n const vFOV = ((camera.fov / camera.zoom) * Math.PI) / 180;\r\n\r\n // Math.abs to ensure the result is always positive\r\n return 2 * Math.tan(vFOV / 2) * Math.abs(depth);\r\n}\r\n\r\n/**\r\n * Get the visible width at the z depth.\r\n */\r\nfunction visibleWidthAtZDepth(depth: number, camera: PerspectiveCamera) {\r\n const height = visibleHeightAtZDepth(depth, camera);\r\n return height * camera.aspect;\r\n}\r\n\r\n/**\r\n * Returns whether the node is in view of the camera.\r\n */\r\nexport function isNodeInView(\r\n camera: PerspectiveCamera,\r\n nodePosition: InternalGraphPosition\r\n): boolean {\r\n const visibleWidth = visibleWidthAtZDepth(1, camera);\r\n const visibleHeight = visibleHeightAtZDepth(1, camera);\r\n\r\n // The boundary coordinates of the area visible to the camera relative to the scene\r\n const visibleArea = {\r\n x0: camera?.position?.x - visibleWidth / 2,\r\n x1: camera?.position?.x + visibleWidth / 2,\r\n y0: camera?.position?.y - visibleHeight / 2,\r\n y1: camera?.position?.y + visibleHeight / 2\r\n };\r\n\r\n return (\r\n nodePosition?.x > visibleArea.x0 &&\r\n nodePosition?.x < visibleArea.x1 &&\r\n nodePosition?.y > visibleArea.y0 &&\r\n nodePosition?.y < visibleArea.y1\r\n );\r\n}\r\n\r\n/**\r\n * Get the closest axis to a given angle.\r\n */\r\nexport function getClosestAxis(angle: number, axes: number[]) {\r\n return axes.reduce((prev, curr) =>\r\n Math.abs(curr - (angle % Math.PI)) < Math.abs(prev - (angle % Math.PI))\r\n ? curr\r\n : prev\r\n );\r\n}\r\n\r\n/**\r\n * Get how far an angle is from the closest 2D axis in radians.\r\n */\r\nexport function getDegreesToClosest2dAxis(\r\n horizontalAngle: number,\r\n verticalAngle: number\r\n) {\r\n const closestHorizontalAxis = getClosestAxis(horizontalAngle, [0, Math.PI]);\r\n const closestVerticalAxis = getClosestAxis(verticalAngle, [\r\n Math.PI / 2,\r\n (3 * Math.PI) / 2\r\n ]);\r\n\r\n return {\r\n horizontalRotation: closestHorizontalAxis - (horizontalAngle % Math.PI),\r\n verticalRotation: closestVerticalAxis - (verticalAngle % Math.PI)\r\n };\r\n}\r\n","import { useThree } from '@react-three/fiber';\r\nimport { useCameraControls } from './useCameraControls';\r\nimport { useCallback, useLayoutEffect, useRef, useState } from 'react';\r\nimport { Vector3, Box3, PerspectiveCamera } from 'three';\r\nimport { useHotkeys } from 'reakeys';\r\nimport { getLayoutCenter } from '../utils/layout';\r\nimport { InternalGraphNode } from '../types';\r\nimport { useStore } from '../store';\r\nimport { isNodeInView, getDegreesToClosest2dAxis } from './utils';\r\nimport { LayoutTypes } from 'layout/types';\r\n\r\nconst PADDING = 50;\r\n\r\nexport interface CenterNodesParams {\r\n animated?: boolean;\r\n centerOnlyIfNodesNotInView?: boolean;\r\n}\r\n\r\nexport interface FitNodesParams {\r\n animated?: boolean;\r\n fitOnlyIfNodesNotInView?: boolean;\r\n}\r\n\r\nexport interface CenterGraphInput {\r\n /**\r\n * Whether the animate the transition or not.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the center graph function is disabled or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The layout type of the graph used to determine rotation logic.\r\n */\r\n layoutType: LayoutTypes;\r\n}\r\n\r\nexport interface CenterGraphOutput {\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodes - An array of `InternalGraphNode` objects to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param animated - A boolean flag that determines whether the centering action should be animated.\r\n *\r\n * @param centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `nodes` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `nodes` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerNodes: (nodes: InternalGraphNode[], opts: CenterNodesParams) => void;\r\n\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `ids` are not currently in view. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerNodesById: (nodeIds: string[], opts?: CenterNodesParams) => void;\r\n\r\n /**\r\n * Fit all the given nodes into view of the camera.\r\n *\r\n * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\r\n * the view will fit to all nodes.\r\n *\r\n * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\r\n * only be fit if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the view will only be fit if one or more of the nodes\r\n * specified by `ids` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the view will be fit regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n fitNodesInViewById: (nodeIds: string[], opts?: FitNodesParams) => void;\r\n\r\n /**\r\n * Whether the graph is centered or not.\r\n */\r\n isCentered?: boolean;\r\n}\r\n\r\nexport const useCenterGraph = ({\r\n animated,\r\n disabled,\r\n layoutType\r\n}: CenterGraphInput): CenterGraphOutput => {\r\n const nodes = useStore(state => state.nodes);\r\n const [isCentered, setIsCentered] = useState(false);\r\n const invalidate = useThree(state => state.invalidate);\r\n const { controls } = useCameraControls();\r\n const camera = useThree(state => state.camera) as PerspectiveCamera;\r\n const mounted = useRef(false);\r\n\r\n const centerNodes = useCallback(\r\n async (nodes, opts?: CenterNodesParams) => {\r\n const animated = opts?.animated !== undefined ? opts?.animated : true;\r\n const centerOnlyIfNodesNotInView =\r\n opts?.centerOnlyIfNodesNotInView !== undefined\r\n ? opts?.centerOnlyIfNodesNotInView\r\n : false;\r\n\r\n if (\r\n !mounted.current ||\r\n !centerOnlyIfNodesNotInView ||\r\n (centerOnlyIfNodesNotInView &&\r\n nodes?.some(node => !isNodeInView(camera, node.position)))\r\n ) {\r\n // Centers the graph based on the central most node\r\n const { x, y, z } = getLayoutCenter(nodes);\r\n\r\n await controls.setTarget(x, y, z, animated);\r\n\r\n if (!isCentered) {\r\n setIsCentered(true);\r\n }\r\n\r\n invalidate();\r\n }\r\n },\r\n // eslint-disable-next-line react-hooks/exhaustive-deps\r\n [invalidate, controls, nodes]\r\n );\r\n\r\n const fitNodesInView = useCallback(\r\n async (\r\n nodes,\r\n opts: FitNodesParams = { animated: true, fitOnlyIfNodesNotInView: false }\r\n ) => {\r\n const { fitOnlyIfNodesNotInView } = opts;\r\n\r\n if (\r\n !fitOnlyIfNodesNotInView ||\r\n (fitOnlyIfNodesNotInView &&\r\n nodes?.some(node => !isNodeInView(camera, node.position)))\r\n ) {\r\n const { minX, maxX, minY, maxY, minZ, maxZ } = getLayoutCenter(nodes);\r\n\r\n if (!layoutType.includes('3d')) {\r\n // fitToBox will auto rotate to the closest axis including the z axis,\r\n // which is not desired for 2D graphs\r\n // So get the rotation to the closest flat axis for 2D graphs\r\n const { horizontalRotation, verticalRotation } =\r\n getDegreesToClosest2dAxis(\r\n controls?.azimuthAngle,\r\n controls?.polarAngle\r\n );\r\n\r\n void controls?.rotate(horizontalRotation, verticalRotation, true);\r\n }\r\n\r\n await controls?.zoomTo(1, opts?.animated);\r\n\r\n await controls?.fitToBox(\r\n new Box3(\r\n new Vector3(minX, minY, minZ),\r\n new Vector3(maxX, maxY, maxZ)\r\n ),\r\n opts?.animated,\r\n {\r\n cover: false,\r\n paddingLeft: PADDING,\r\n paddingRight: PADDING,\r\n paddingBottom: PADDING,\r\n paddingTop: PADDING\r\n }\r\n );\r\n }\r\n },\r\n [camera, controls, layoutType]\r\n );\r\n\r\n const getNodesById = useCallback(\r\n (nodeIds: string[]) => {\r\n let mappedNodes: InternalGraphNode[] | null = null;\r\n\r\n if (nodeIds?.length) {\r\n // Map the node ids to the actual nodes\r\n mappedNodes = nodeIds.reduce((acc, id) => {\r\n const node = nodes.find(n => n.id === id);\r\n if (node) {\r\n acc.push(node);\r\n } else {\r\n throw new Error(\r\n `Attempted to center ${id} but it was not found in the nodes`\r\n );\r\n }\r\n\r\n return acc;\r\n }, []);\r\n }\r\n\r\n return mappedNodes;\r\n },\r\n [nodes]\r\n );\r\n\r\n const centerNodesById = useCallback(\r\n (nodeIds: string[], opts: CenterNodesParams) => {\r\n const mappedNodes = getNodesById(nodeIds);\r\n\r\n centerNodes(mappedNodes || nodes, {\r\n animated,\r\n centerOnlyIfNodesNotInView: opts?.centerOnlyIfNodesNotInView\r\n });\r\n },\r\n [animated, centerNodes, getNodesById, nodes]\r\n );\r\n\r\n const fitNodesInViewById = useCallback(\r\n async (nodeIds: string[], opts: FitNodesParams) => {\r\n const mappedNodes = getNodesById(nodeIds);\r\n\r\n await fitNodesInView(mappedNodes || nodes, { animated, ...opts });\r\n },\r\n [animated, fitNodesInView, getNodesById, nodes]\r\n );\r\n\r\n useLayoutEffect(() => {\r\n async function load() {\r\n // Once we've loaded controls and we have nodes, let's recenter\r\n if (controls && nodes?.length) {\r\n if (!mounted.current) {\r\n // Center the graph once nodes are loaded on mount\r\n await centerNodes(nodes, { animated: false });\r\n await fitNodesInView(nodes, { animated: false });\r\n mounted.current = true;\r\n }\r\n }\r\n }\r\n\r\n load();\r\n }, [controls, centerNodes, nodes, animated, camera, fitNodesInView]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Center',\r\n disabled,\r\n category: 'Graph',\r\n keys: ['command+shift+c'],\r\n callback: () => centerNodes(nodes)\r\n }\r\n ]);\r\n\r\n return { centerNodes, centerNodesById, fitNodesInViewById, isCentered };\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { a, useSpring } from '@react-spring/three';\r\nimport { TextureLoader, LinearFilter, DoubleSide } from 'three';\r\nimport { animationConfig } from '../../utils';\r\nimport { NodeRendererProps } from '../../types';\r\n\r\nexport interface IconProps extends NodeRendererProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n}\r\n\r\nexport const Icon: FC = ({ image, id, size, opacity, animated }) => {\r\n const texture = useMemo(() => new TextureLoader().load(image), [image]);\r\n\r\n const { scale, spriteOpacity } = useSpring({\r\n from: {\r\n scale: [0.00001, 0.00001, 0.00001],\r\n spriteOpacity: 0\r\n },\r\n to: {\r\n scale: [size, size, size],\r\n spriteOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nIcon.defaultProps = {\r\n opacity: 1\r\n};\r\n","import React, { FC } from 'react';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Sphere } from './Sphere';\r\nimport { Icon } from './Icon';\r\n\r\nexport interface SphereWithIconProps extends NodeRendererProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n}\r\n\r\nexport const SphereWithIcon: FC = ({\r\n color,\r\n id,\r\n size,\r\n opacity,\r\n node,\r\n active,\r\n animated,\r\n image,\r\n selected\r\n}) => (\r\n <>\r\n \r\n \r\n \r\n);\r\n\r\nSphereWithIcon.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import React, { FC, useMemo } from 'react';\r\nimport { a, useSpring } from '@react-spring/three';\r\nimport { animationConfig } from '../../utils';\r\nimport { NodeRendererProps } from '../../types';\r\nimport { Billboard, Svg as DreiSvg, SvgProps as DreiSvgProps } from 'glodrei';\r\nimport { Color, DoubleSide } from 'three';\r\n\r\nexport type SvgProps = NodeRendererProps &\r\n Omit & {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n };\r\n\r\nexport const Svg: FC = ({\r\n id,\r\n image,\r\n color,\r\n size,\r\n opacity,\r\n animated,\r\n ...rest\r\n}) => {\r\n const normalizedSize = size / 25;\r\n\r\n const { scale } = useSpring({\r\n from: {\r\n scale: [0.00001, 0.00001, 0.00001]\r\n },\r\n to: {\r\n scale: [normalizedSize, normalizedSize, normalizedSize]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nSvg.defaultProps = {\r\n opacity: 1\r\n};\r\n","import React, { FC } from 'react';\r\nimport { Sphere } from './Sphere';\r\nimport { Svg, SvgProps } from './Svg';\r\nimport { ColorRepresentation } from 'three';\r\n\r\nexport interface SphereWithSvgProps extends SvgProps {\r\n /**\r\n * The image to display on the icon.\r\n */\r\n image: string;\r\n\r\n /**\r\n * The color of the svg fill.\r\n */\r\n svgFill?: ColorRepresentation;\r\n}\r\n\r\nexport const SphereWithSvg: FC = ({\r\n color,\r\n id,\r\n size,\r\n opacity,\r\n node,\r\n svgFill,\r\n active,\r\n animated,\r\n image,\r\n selected,\r\n ...rest\r\n}) => (\r\n <>\r\n \r\n \r\n \r\n);\r\n\r\nSphereWithSvg.defaultProps = {\r\n opacity: 1,\r\n active: false\r\n};\r\n","import React, {\r\n FC,\r\n ReactNode,\r\n useCallback,\r\n useMemo,\r\n useRef,\r\n useState\r\n} from 'react';\r\nimport { Group } from 'three';\r\nimport { animationConfig } from '../utils';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Sphere } from './nodes/Sphere';\r\nimport { Label } from './Label';\r\nimport {\r\n NodeContextMenuProps,\r\n ContextMenuEvent,\r\n InternalGraphNode,\r\n NodeRenderer,\r\n CollapseProps\r\n} from '../types';\r\nimport { Html, useCursor } from 'glodrei';\r\nimport { useCameraControls } from '../CameraControls';\r\nimport { useStore } from '../store';\r\nimport { useDrag } from '../utils/useDrag';\r\nimport { Icon } from './nodes';\r\nimport { useHoverIntent } from '../utils/useHoverIntent';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface NodeProps {\r\n /**\r\n * The unique identifier for the node.\r\n */\r\n id: string;\r\n\r\n /**\r\n * The parent nodes of the node.\r\n */\r\n parents?: string[];\r\n\r\n /**\r\n * Whether the node is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Whether the node is animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the node is draggable.\r\n */\r\n draggable?: boolean;\r\n\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The function to use to render the node.\r\n */\r\n renderNode?: NodeRenderer;\r\n\r\n /**\r\n * The context menu for the node.\r\n */\r\n contextMenu?: (event: ContextMenuEvent) => ReactNode;\r\n\r\n /**\r\n * The function to call when the pointer is over the node.\r\n */\r\n onPointerOver?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the pointer is out of the node.\r\n */\r\n onPointerOut?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is clicked.\r\n */\r\n onClick?: (\r\n node: InternalGraphNode,\r\n props?: CollapseProps,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is double clicked.\r\n */\r\n onDoubleClick?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * The function to call when the node is right clicked.\r\n */\r\n onContextMenu?: (\r\n node?: InternalGraphNode,\r\n props?: NodeContextMenuProps\r\n ) => void;\r\n\r\n /**\r\n * Triggered after a node was dragged.\r\n */\r\n onDragged?: (node: InternalGraphNode) => void;\r\n}\r\n\r\nexport const Node: FC = ({\r\n animated,\r\n disabled,\r\n id,\r\n draggable,\r\n labelFontUrl,\r\n contextMenu,\r\n onClick,\r\n onDoubleClick,\r\n onPointerOver,\r\n onDragged,\r\n onPointerOut,\r\n onContextMenu,\r\n renderNode\r\n}) => {\r\n const cameraControls = useCameraControls();\r\n const theme = useStore(state => state.theme);\r\n const node = useStore(state => state.nodes.find(n => n.id === id));\r\n const edges = useStore(state => state.edges);\r\n const draggingId = useStore(state => state.draggingId);\r\n const collapsedNodeIds = useStore(state => state.collapsedNodeIds);\r\n const setDraggingId = useStore(state => state.setDraggingId);\r\n const setNodePosition = useStore(state => state.setNodePosition);\r\n const setCollapsedNodeIds = useStore(state => state.setCollapsedNodeIds);\r\n const isCollapsed = useStore(state => state.collapsedNodeIds.includes(id));\r\n const isActive = useStore(state => state.actives?.includes(id));\r\n const isSelected = useStore(state => state.selections?.includes(id));\r\n const hasSelections = useStore(state => state.selections?.length > 0);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const isDragging = draggingId === id;\r\n const {\r\n position,\r\n label,\r\n subLabel,\r\n size: nodeSize = 7,\r\n labelVisible = true\r\n } = node;\r\n\r\n const group = useRef(null);\r\n const [active, setActive] = useState(false);\r\n const [menuVisible, setMenuVisible] = useState(false);\r\n\r\n const shouldHighlight = active || isSelected || isActive;\r\n\r\n const selectionOpacity = hasSelections\r\n ? shouldHighlight\r\n ? theme.node.selectedOpacity\r\n : theme.node.inactiveOpacity\r\n : theme.node.opacity;\r\n\r\n const canCollapse = useMemo(() => {\r\n // If the node has outgoing edges, it can collapse via context menu\r\n const outboundLinks = edges.filter(l => l.source === id);\r\n\r\n return outboundLinks.length > 0 || isCollapsed;\r\n }, [edges, id, isCollapsed]);\r\n\r\n const onCollapse = useCallback(() => {\r\n if (canCollapse) {\r\n if (isCollapsed) {\r\n setCollapsedNodeIds(collapsedNodeIds.filter(p => p !== id));\r\n } else {\r\n setCollapsedNodeIds([...collapsedNodeIds, id]);\r\n }\r\n }\r\n }, [canCollapse, collapsedNodeIds, id, isCollapsed, setCollapsedNodeIds]);\r\n\r\n const [{ nodePosition, labelPosition, subLabelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n nodePosition: center ? [center.x, center.y, 0] : [0, 0, 0],\r\n labelPosition: [0, -(nodeSize + 4), 2],\r\n subLabelPosition: [0, -(nodeSize + 14), 2]\r\n },\r\n to: {\r\n nodePosition: position\r\n ? [\r\n position.x,\r\n position.y,\r\n shouldHighlight ? position.z + 50 : position.z\r\n ]\r\n : [0, 0, 0],\r\n labelPosition: [0, -(nodeSize + 4), 2],\r\n subLabelPosition: [0, -(nodeSize + 14), 2]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [isDragging, position, animated, nodeSize, shouldHighlight]\r\n );\r\n\r\n const bind = useDrag({\r\n draggable,\r\n position,\r\n // @ts-ignore\r\n set: pos => setNodePosition(id, pos),\r\n onDragStart: () => {\r\n setDraggingId(id);\r\n setActive(true);\r\n },\r\n onDragEnd: () => {\r\n setDraggingId(null);\r\n setActive(false);\r\n onDragged?.(node);\r\n }\r\n });\r\n\r\n useCursor(active && !draggingId && onClick !== undefined, 'pointer');\r\n useCursor(\r\n active && draggable && !isDragging && onClick === undefined,\r\n 'grab'\r\n );\r\n useCursor(isDragging, 'grabbing');\r\n\r\n const combinedActiveState = shouldHighlight || isDragging;\r\n const color = combinedActiveState\r\n ? node.activeFill || theme.node.activeFill\r\n : node.fill || theme.node.fill;\r\n\r\n const actualShowRing = node.showRing;\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled: disabled || isDragging,\r\n onPointerOver: (event: ThreeEvent) => {\r\n cameraControls.controls.truckSpeed = 0;\r\n setActive(true);\r\n onPointerOver?.(node, event);\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n cameraControls.controls.truckSpeed = 2.0;\r\n setActive(false);\r\n onPointerOut?.(node, event);\r\n }\r\n });\r\n\r\n const nodeComponent = useMemo(\r\n () =>\r\n renderNode ? (\r\n renderNode({\r\n id,\r\n color,\r\n size: nodeSize,\r\n active: combinedActiveState,\r\n opacity: selectionOpacity,\r\n animated,\r\n selected: isSelected,\r\n node\r\n })\r\n ) : (\r\n <>\r\n {node.icon ? (\r\n \r\n ) : (\r\n \r\n )}\r\n \r\n ),\r\n [\r\n renderNode,\r\n id,\r\n color,\r\n nodeSize,\r\n combinedActiveState,\r\n selectionOpacity,\r\n animated,\r\n isSelected,\r\n node,\r\n actualShowRing\r\n ]\r\n );\r\n\r\n const labelComponent = useMemo(\r\n () =>\r\n label && (\r\n <>\r\n \r\n \r\n \r\n {subLabel && (\r\n \r\n \r\n \r\n )}\r\n \r\n ),\r\n [\r\n active,\r\n isActive,\r\n isDragging,\r\n isSelected,\r\n label,\r\n labelFontUrl,\r\n labelPosition,\r\n labelVisible,\r\n selectionOpacity,\r\n subLabel,\r\n subLabelPosition,\r\n theme.node.label.activeColor,\r\n theme.node.label.color,\r\n theme.node.label.stroke,\r\n theme.node.subLabel?.activeColor,\r\n theme.node.subLabel?.color,\r\n theme.node.subLabel?.stroke,\r\n theme.node.label.fontSize,\r\n theme.node.label.maxWidth,\r\n theme.node.label.ellipsis,\r\n theme.node.label.backgroundColor,\r\n theme.node.label.borderRadius\r\n ]\r\n );\r\n\r\n const menuComponent = useMemo(\r\n () =>\r\n menuVisible &&\r\n contextMenu && (\r\n \r\n {contextMenu({\r\n data: node,\r\n canCollapse,\r\n isCollapsed,\r\n onCollapse,\r\n onClose: () => setMenuVisible(false)\r\n })}\r\n \r\n ),\r\n [menuVisible, contextMenu, node, canCollapse, isCollapsed, onCollapse]\r\n );\r\n\r\n return (\r\n ) => {\r\n if (!disabled && !isDragging) {\r\n onClick?.(\r\n node,\r\n {\r\n canCollapse,\r\n isCollapsed\r\n },\r\n event\r\n );\r\n }\r\n }}\r\n onDoubleClick={(event: ThreeEvent) => {\r\n event.stopPropagation();\r\n if (!disabled && !isDragging) {\r\n onDoubleClick?.(node, event);\r\n }\r\n }}\r\n onContextMenu={() => {\r\n if (!disabled) {\r\n setMenuVisible(true);\r\n onContextMenu?.(node, {\r\n canCollapse,\r\n isCollapsed,\r\n onCollapse\r\n });\r\n }\r\n }}\r\n {...(bind() as any)}\r\n >\r\n {nodeComponent}\r\n {menuComponent}\r\n {labelComponent}\r\n \r\n );\r\n};\r\n\r\nNode.defaultProps = {\r\n draggable: false\r\n};\r\n","import React, { FC, useMemo, useRef, useEffect, useCallback } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Color, ColorRepresentation, Mesh, DoubleSide, Vector3 } from 'three';\r\nimport { animationConfig } from '../utils';\r\nimport { useStore } from '../store';\r\n\r\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\r\n\r\nexport interface ArrowProps {\r\n /**\r\n * Whether the arrow should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The color of the arrow.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * The length of the arrow.\r\n */\r\n length: number;\r\n\r\n /**\r\n * The opacity of the arrow.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The position of the arrow in 3D space.\r\n */\r\n position: Vector3;\r\n\r\n /**\r\n * The rotation of the arrow in 3D space.\r\n */\r\n rotation: Vector3;\r\n\r\n /**\r\n * The size of the arrow.\r\n */\r\n size: number;\r\n\r\n /**\r\n * A function that is called when the arrow is right-clicked.\r\n */\r\n onContextMenu?: () => void;\r\n\r\n /**\r\n * A function that is called when the arrow is selected or deselected.\r\n */\r\n onActive?: (state: boolean) => void;\r\n}\r\n\r\nexport const Arrow: FC = ({\r\n animated,\r\n color,\r\n length,\r\n opacity,\r\n position,\r\n rotation,\r\n size,\r\n onActive,\r\n onContextMenu\r\n}) => {\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const meshRef = useRef(null);\r\n const draggingId = useStore(state => state.draggingId);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const [{ pos, arrowOpacity }] = useSpring(\r\n () => ({\r\n from: {\r\n pos: center ? [center.x, center.y, center.z] : [0, 0, 0],\r\n arrowOpacity: 0\r\n },\r\n to: {\r\n pos: [position.x, position.y, position.z],\r\n arrowOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [animated, draggingId, opacity, position]\r\n );\r\n\r\n const setQuaternion = useCallback(() => {\r\n const axis = new Vector3(0, 1, 0);\r\n meshRef.current?.quaternion.setFromUnitVectors(axis, rotation);\r\n }, [rotation, meshRef]);\r\n\r\n useEffect(() => setQuaternion(), [setQuaternion]);\r\n\r\n return (\r\n onActive(true)}\r\n onPointerOut={() => onActive(false)}\r\n onPointerDown={event => {\r\n // context menu controls\r\n if (event.nativeEvent.buttons === 2) {\r\n event.stopPropagation();\r\n onContextMenu();\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nArrow.defaultProps = {\r\n size: 1,\r\n opacity: 0.5,\r\n color: '#D8E6EA'\r\n};\r\n","import React, { FC, useEffect, useMemo, useRef } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { animationConfig, getCurve } from '../utils';\r\nimport {\r\n Vector3,\r\n TubeGeometry,\r\n ColorRepresentation,\r\n Color,\r\n Curve\r\n} from 'three';\r\nimport { useStore } from '../store';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport interface LineProps {\r\n /**\r\n * Whether the line should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The color of the line.\r\n */\r\n color?: ColorRepresentation;\r\n\r\n /**\r\n * Whether the line should be curved.\r\n */\r\n curved: boolean;\r\n\r\n /**\r\n * The curve of the line in 3D space.\r\n */\r\n curve: Curve;\r\n\r\n /**\r\n * The unique identifier of the line.\r\n */\r\n id: string;\r\n\r\n /**\r\n * The opacity of the line.\r\n */\r\n opacity?: number;\r\n\r\n /**\r\n * The size of the line.\r\n */\r\n size?: number;\r\n\r\n /**\r\n * A function that is called when the line is clicked.\r\n */\r\n onClick?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the line is right-clicked.\r\n */\r\n onContextMenu?: () => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved over the line.\r\n */\r\n onPointerOver?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved out of the line.\r\n */\r\n onPointerOut?: (event: ThreeEvent) => void;\r\n\r\n /**\r\n * The offset of the curve.\r\n */\r\n curveOffset?: number;\r\n}\r\n\r\nexport const Line: FC = ({\r\n curveOffset,\r\n animated,\r\n color,\r\n curve,\r\n curved = false,\r\n id,\r\n opacity,\r\n size,\r\n onContextMenu,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const tubeRef = useRef(null);\r\n const draggingId = useStore(state => state.draggingId);\r\n const normalizedColor = useMemo(() => new Color(color), [color]);\r\n const center = useStore(state => state.centerPosition);\r\n const mounted = useRef(false);\r\n\r\n // Do opacity seperate from vertices for perf\r\n const { lineOpacity } = useSpring({\r\n from: {\r\n lineOpacity: 0\r\n },\r\n to: {\r\n lineOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n useSpring(() => {\r\n const from = curve.getPoint(0);\r\n const to = curve.getPoint(1);\r\n return {\r\n from: {\r\n // Animate from center first time, then from the actual from point\r\n fromVertices: !mounted.current\r\n ? [center?.x, center?.y, center?.z || 0]\r\n : [to?.x, to?.y, to?.z || 0],\r\n toVertices: [from?.x, from?.y, from?.z || 0]\r\n },\r\n to: {\r\n fromVertices: [from?.x, from?.y, from?.z || 0],\r\n toVertices: [to?.x, to?.y, to?.z || 0]\r\n },\r\n onChange: event => {\r\n const { fromVertices, toVertices } = event.value;\r\n const fromVector = new Vector3(...fromVertices);\r\n const toVector = new Vector3(...toVertices);\r\n\r\n const curve = getCurve(fromVector, 0, toVector, 0, curved, curveOffset);\r\n tubeRef.current.copy(new TubeGeometry(curve, 20, size / 2, 5, false));\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n };\r\n }, [animated, draggingId, curve, size]);\r\n\r\n useEffect(() => {\r\n // Handle mount operation for initial render\r\n mounted.current = true;\r\n }, []);\r\n\r\n return (\r\n {\r\n // context menu controls\r\n if (event.nativeEvent.buttons === 2) {\r\n event.stopPropagation();\r\n onContextMenu();\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n );\r\n};\r\n\r\nLine.defaultProps = {\r\n color: '#000',\r\n size: 1,\r\n opacity: 1\r\n};\r\n","import React, { FC, useMemo, useState } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Arrow, EdgeArrowPosition } from './Arrow';\r\nimport { Label } from './Label';\r\nimport {\r\n animationConfig,\r\n calculateEdgeCurveOffset,\r\n getArrowSize,\r\n getArrowVectors,\r\n getCurve,\r\n getLabelOffsetByType,\r\n getMidPoint,\r\n getVector\r\n} from '../utils';\r\nimport { Line } from './Line';\r\nimport { useStore } from '../store';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../types';\r\nimport { Html, useCursor } from 'glodrei';\r\nimport { useHoverIntent } from '../utils/useHoverIntent';\r\nimport { Euler, Vector3 } from 'three';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\n/**\r\n * Label positions relatively edge.\r\n *\r\n * - below: show label under the edge line\r\n * - above: show label above the edge line\r\n * - inline: show label along the edge line\r\n * - natural: normal text positions\r\n */\r\nexport type EdgeLabelPosition = 'below' | 'above' | 'inline' | 'natural';\r\n\r\n/**\r\n * Type of edge interpolation.\r\n *\r\n * - Linear is straight\r\n * - Curved is curved\r\n */\r\nexport type EdgeInterpolation = 'linear' | 'curved';\r\n\r\nexport interface EdgeProps {\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The unique identifier of the edge.\r\n */\r\n id: string;\r\n\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The placement of the edge arrow.\r\n */\r\n arrowPlacement?: EdgeArrowPosition;\r\n\r\n /**\r\n * The type of interpolation used to draw the edge.\r\n */\r\n interpolation: EdgeInterpolation;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * A function that is called when the edge is clicked.\r\n */\r\n onClick?: (edge: InternalGraphEdge, event: ThreeEvent) => void;\r\n\r\n /**\r\n * A function that is called when the edge is right-clicked.\r\n */\r\n onContextMenu?: (edge?: InternalGraphEdge) => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved over the edge.\r\n */\r\n onPointerOver?: (\r\n edge: InternalGraphEdge,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * A function that is called when the mouse pointer is moved out of the edge.\r\n */\r\n onPointerOut?: (\r\n edge: InternalGraphEdge,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nconst LABEL_PLACEMENT_OFFSET = 3;\r\n\r\nexport const Edge: FC = ({\r\n animated,\r\n arrowPlacement,\r\n contextMenu,\r\n disabled,\r\n labelPlacement,\r\n id,\r\n interpolation,\r\n labelFontUrl,\r\n onContextMenu,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n // UI states\r\n const [active, setActive] = useState(false);\r\n const [menuVisible, setMenuVisible] = useState(false);\r\n\r\n // Edge data\r\n const edges = useStore(state => state.edges);\r\n const edge = edges.find(e => e.id === id);\r\n const {\r\n target,\r\n source,\r\n label,\r\n labelVisible = false,\r\n size = 1,\r\n backgroundColor\r\n } = edge;\r\n const from = useStore(store => store.nodes.find(node => node.id === source));\r\n const to = useStore(store => store.nodes.find(node => node.id === target));\r\n\r\n // Edge properties\r\n const labelOffset = (size + theme.edge.label.fontSize) / 2;\r\n const [arrowLength, arrowSize] = useMemo(() => getArrowSize(size), [size]);\r\n const { curveOffset, curved } = useMemo(\r\n () =>\r\n calculateEdgeCurveOffset({\r\n edge,\r\n edges,\r\n curved: interpolation === 'curved'\r\n }),\r\n [edge, edges, interpolation]\r\n );\r\n\r\n const [curve, arrowPosition, arrowRotation] = useMemo(() => {\r\n const fromVector = getVector(from);\r\n const fromOffset = from.size;\r\n const toVector = getVector(to);\r\n const toOffset = to.size;\r\n\r\n let curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n toVector,\r\n toOffset,\r\n curved,\r\n curveOffset\r\n );\r\n\r\n const [arrowPosition, arrowRotation] = getArrowVectors(\r\n arrowPlacement,\r\n curve,\r\n arrowLength\r\n );\r\n\r\n if (arrowPlacement === 'end') {\r\n curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n arrowPosition,\r\n 0,\r\n curved,\r\n curveOffset\r\n );\r\n }\r\n\r\n return [curve, arrowPosition, arrowRotation];\r\n }, [from, to, curved, curveOffset, arrowPlacement, arrowLength]);\r\n\r\n const midPoint = useMemo(() => {\r\n let newMidPoint = getMidPoint(\r\n from.position,\r\n to.position,\r\n getLabelOffsetByType(labelOffset, labelPlacement)\r\n );\r\n\r\n if (curved) {\r\n // Offset the label to the mid point of the curve\r\n const offset = new Vector3().subVectors(newMidPoint, curve.getPoint(0.5));\r\n switch (labelPlacement) {\r\n case 'above':\r\n offset.y = offset.y - LABEL_PLACEMENT_OFFSET;\r\n break;\r\n case 'below':\r\n offset.y = offset.y + LABEL_PLACEMENT_OFFSET;\r\n break;\r\n }\r\n newMidPoint = newMidPoint.sub(offset);\r\n }\r\n\r\n return newMidPoint;\r\n }, [from.position, to.position, labelOffset, labelPlacement, curved, curve]);\r\n\r\n const isSelected = useStore(state => state.selections?.includes(id));\r\n const hasSelections = useStore(state => state.selections?.length);\r\n const isActive = useStore(state => state.actives?.includes(id));\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const selectionOpacity = hasSelections\r\n ? isSelected || isActive\r\n ? theme.edge.selectedOpacity\r\n : theme.edge.inactiveOpacity\r\n : theme.edge.opacity;\r\n\r\n const [{ labelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n labelPosition: center ? [center.x, center.y, center.z] : [0, 0, 0]\r\n },\r\n to: {\r\n labelPosition: [midPoint.x, midPoint.y, midPoint.z]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [midPoint, animated, draggingId]\r\n );\r\n\r\n const labelRotation = useMemo(\r\n () =>\r\n new Euler(\r\n 0,\r\n 0,\r\n labelPlacement === 'natural'\r\n ? 0\r\n : Math.atan(\r\n (to.position.y - from.position.y) /\r\n (to.position.x - from.position.x)\r\n )\r\n ),\r\n [\r\n to.position.x,\r\n to.position.y,\r\n from.position.x,\r\n from.position.y,\r\n labelPlacement\r\n ]\r\n );\r\n\r\n useCursor(active && !draggingId && onClick !== undefined, 'pointer');\r\n\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled,\r\n onPointerOver: (event: ThreeEvent) => {\r\n setActive(true);\r\n onPointerOver?.(edge, event);\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n setActive(false);\r\n onPointerOut?.(edge, event);\r\n }\r\n });\r\n\r\n const arrowComponent = useMemo(\r\n () =>\r\n arrowPlacement !== 'none' && (\r\n {\r\n if (!disabled) {\r\n setMenuVisible(true);\r\n onContextMenu?.(edge);\r\n }\r\n }}\r\n />\r\n ),\r\n [\r\n active,\r\n animated,\r\n arrowLength,\r\n arrowPlacement,\r\n arrowPosition,\r\n arrowRotation,\r\n arrowSize,\r\n disabled,\r\n edge,\r\n isActive,\r\n isSelected,\r\n onContextMenu,\r\n selectionOpacity,\r\n theme.arrow.activeFill,\r\n theme.arrow.fill\r\n ]\r\n );\r\n\r\n const labelComponent = useMemo(\r\n () =>\r\n labelVisible &&\r\n label && (\r\n \r\n \r\n \r\n ),\r\n [\r\n active,\r\n isActive,\r\n isSelected,\r\n label,\r\n labelFontUrl,\r\n labelPosition,\r\n labelRotation,\r\n labelVisible,\r\n selectionOpacity,\r\n theme.edge.label.activeColor,\r\n theme.edge.label.color,\r\n theme.edge.label.fontSize,\r\n theme.edge.label.maxWidth,\r\n theme.edge.label.ellipsis,\r\n theme.edge.label.stroke,\r\n theme.edge.label.backgroundColor,\r\n theme.edge.label.borderRadius\r\n ]\r\n );\r\n\r\n const menuComponent = useMemo(\r\n () =>\r\n menuVisible &&\r\n contextMenu && (\r\n \r\n {contextMenu({ data: edge, onClose: () => setMenuVisible(false) })}\r\n \r\n ),\r\n [menuVisible, contextMenu, midPoint, edge]\r\n );\r\n\r\n const lineComponent = useMemo(\r\n () => (\r\n {\r\n if (!disabled) {\r\n onClick?.(edge, event);\r\n }\r\n }}\r\n onPointerOver={pointerOver}\r\n onPointerOut={pointerOut}\r\n onContextMenu={() => {\r\n if (!disabled) {\r\n setMenuVisible(true);\r\n onContextMenu?.(edge);\r\n }\r\n }}\r\n />\r\n ),\r\n [\r\n active,\r\n animated,\r\n curve,\r\n curveOffset,\r\n curved,\r\n disabled,\r\n edge,\r\n id,\r\n isActive,\r\n isSelected,\r\n onClick,\r\n onContextMenu,\r\n pointerOut,\r\n pointerOver,\r\n selectionOpacity,\r\n size,\r\n theme.arrow.activeFill,\r\n theme.arrow.fill\r\n ]\r\n );\r\n\r\n return (\r\n \r\n {arrowComponent}\r\n {lineComponent}\r\n {menuComponent}\r\n {labelComponent}\r\n \r\n );\r\n};\r\n\r\nEdge.defaultProps = {\r\n labelPlacement: 'inline',\r\n arrowPlacement: 'end'\r\n};\r\n","import { useCallback, useRef } from 'react';\r\nimport {\r\n BoxGeometry,\r\n BufferGeometry,\r\n CylinderGeometry,\r\n Quaternion,\r\n TubeGeometry,\r\n Vector3\r\n} from 'three';\r\nimport { mergeBufferGeometries } from 'three-stdlib';\r\n\r\nimport { GraphState, useStore } from '../../store';\r\nimport { InternalGraphEdge } from '../../types';\r\nimport {\r\n getArrowSize,\r\n getArrowVectors,\r\n getVector,\r\n getCurve\r\n} from '../../utils';\r\nimport { EdgeArrowPosition } from '../Arrow';\r\nimport { EdgeInterpolation } from '../Edge';\r\n\r\nexport type UseEdgeGeometry = {\r\n getGeometries(edges: Array): Array;\r\n getGeometry(\r\n active: Array,\r\n inactive: Array\r\n ): BufferGeometry;\r\n};\r\n\r\nconst NULL_GEOMETRY = new BoxGeometry(0, 0, 0);\r\n\r\nexport function useEdgeGeometry(\r\n arrowPlacement: EdgeArrowPosition,\r\n interpolation: EdgeInterpolation\r\n): UseEdgeGeometry {\r\n // We don't want to rerun everything when the state changes,\r\n // but we do want to use the most recent nodes whenever `getGeometries`\r\n // or `getGeometry` is run, so we store it in a ref:\r\n const stateRef = useRef();\r\n const theme = useStore(state => state.theme);\r\n useStore(state => {\r\n stateRef.current = state;\r\n });\r\n\r\n const geometryCacheRef = useRef(new Map());\r\n\r\n const curved = interpolation === 'curved';\r\n const getGeometries = useCallback(\r\n (edges: Array): Array => {\r\n const geometries: Array = [];\r\n const cache = geometryCacheRef.current;\r\n\r\n const { nodes } = stateRef.current;\r\n\r\n edges.forEach(edge => {\r\n const { target, source, size = 1 } = edge;\r\n\r\n const from = nodes.find(node => node.id === source);\r\n const to = nodes.find(node => node.id === target);\r\n\r\n if (!from || !to) {\r\n return;\r\n }\r\n\r\n // Create hash so geometry can be reused if edge doesn't move:\r\n const hash = `fromX:${from.position.x},fromY:${from.position.y},toX:${to.position.x}},toY:${to.position.y}`;\r\n if (cache.has(hash)) {\r\n const geometry = cache.get(hash);\r\n geometries.push(geometry);\r\n return;\r\n }\r\n\r\n const fromVector = getVector(from);\r\n const fromOffset = from.size + theme.edge.label.fontSize;\r\n const toVector = getVector(to);\r\n const toOffset = to.size + theme.edge.label.fontSize;\r\n let curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n toVector,\r\n toOffset,\r\n curved\r\n );\r\n\r\n let edgeGeometry = new TubeGeometry(curve, 20, size / 2, 5, false);\r\n\r\n if (arrowPlacement === 'none') {\r\n geometries.push(edgeGeometry);\r\n cache.set(hash, edgeGeometry);\r\n return;\r\n }\r\n\r\n const [arrowLength, arrowSize] = getArrowSize(size);\r\n\r\n const [arrowPosition, arrowRotation] = getArrowVectors(\r\n arrowPlacement,\r\n curve,\r\n arrowLength\r\n );\r\n const quaternion = new Quaternion();\r\n quaternion.setFromUnitVectors(new Vector3(0, 1, 0), arrowRotation);\r\n\r\n const arrowGeometry = new CylinderGeometry(\r\n 0,\r\n arrowSize,\r\n arrowLength,\r\n 20,\r\n 1,\r\n true\r\n );\r\n arrowGeometry.applyQuaternion(quaternion);\r\n arrowGeometry.translate(\r\n arrowPosition.x,\r\n arrowPosition.y,\r\n arrowPosition.z\r\n );\r\n\r\n // Move edge so it doesn't stick through the arrow:\r\n if (arrowPlacement && arrowPlacement === 'end') {\r\n const curve = getCurve(\r\n fromVector,\r\n fromOffset,\r\n arrowPosition,\r\n 0,\r\n curved\r\n );\r\n edgeGeometry = new TubeGeometry(curve, 20, size / 2, 5, false);\r\n }\r\n\r\n const merged = mergeBufferGeometries([edgeGeometry, arrowGeometry]);\r\n geometries.push(merged);\r\n cache.set(hash, merged);\r\n });\r\n return geometries;\r\n },\r\n [arrowPlacement, curved, theme.edge.label.fontSize]\r\n );\r\n\r\n const getGeometry = useCallback(\r\n (\r\n active: Array,\r\n inactive: Array\r\n ): BufferGeometry => {\r\n const activeGeometries = getGeometries(active);\r\n const inactiveGeometries = getGeometries(inactive);\r\n\r\n return mergeBufferGeometries(\r\n [\r\n inactiveGeometries.length\r\n ? mergeBufferGeometries(inactiveGeometries)\r\n : NULL_GEOMETRY,\r\n activeGeometries.length\r\n ? mergeBufferGeometries(activeGeometries)\r\n : NULL_GEOMETRY\r\n ],\r\n true\r\n );\r\n },\r\n [getGeometries]\r\n );\r\n\r\n return {\r\n getGeometries,\r\n getGeometry\r\n };\r\n}\r\n","import { useCallback, useRef } from 'react';\r\n\r\nimport { useStore } from '../../store';\r\nimport { InternalGraphEdge } from '../../types';\r\n\r\nexport type EdgeEvents = {\r\n onClick?: (edge: InternalGraphEdge) => void;\r\n onContextMenu?: (edge?: InternalGraphEdge) => void;\r\n onPointerOver?: (edge: InternalGraphEdge) => void;\r\n onPointerOut?: (edge: InternalGraphEdge) => void;\r\n};\r\n\r\nexport function useEdgeEvents(\r\n events: EdgeEvents,\r\n contextMenu,\r\n disabled: boolean\r\n) {\r\n const { onClick, onContextMenu, onPointerOut, onPointerOver } = events;\r\n\r\n const edgeContextMenus = useStore(state => state.edgeContextMenus);\r\n const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\r\n\r\n const clickRef = useRef(false);\r\n const handleClick = useCallback(() => {\r\n clickRef.current = true;\r\n }, []);\r\n\r\n const contextMenuEventRef = useRef(false);\r\n const handleContextMenu = useCallback(() => {\r\n contextMenuEventRef.current = true;\r\n }, []);\r\n\r\n const handleIntersections = useCallback(\r\n (\r\n previous: Array,\r\n intersected: Array\r\n ) => {\r\n if (onClick && clickRef.current) {\r\n clickRef.current = false;\r\n if (!disabled) {\r\n intersected.forEach(edge => {\r\n onClick(edge);\r\n });\r\n }\r\n }\r\n\r\n if ((contextMenu || onContextMenu) && contextMenuEventRef.current) {\r\n contextMenuEventRef.current = false;\r\n if (!disabled) {\r\n intersected.forEach(edge => {\r\n if (!edgeContextMenus.has(edge.id)) {\r\n setEdgeContextMenus(new Set([...edgeContextMenus, edge.id]));\r\n onContextMenu?.(edge);\r\n }\r\n });\r\n }\r\n }\r\n\r\n if (onPointerOver) {\r\n const over = intersected.filter(index => !previous.includes(index));\r\n over.forEach(edge => {\r\n onPointerOver(edge);\r\n });\r\n }\r\n\r\n if (onPointerOut) {\r\n const out = previous.filter(index => !intersected.includes(index));\r\n out.forEach(edge => {\r\n onPointerOut(edge);\r\n });\r\n }\r\n },\r\n [\r\n contextMenu,\r\n disabled,\r\n edgeContextMenus,\r\n setEdgeContextMenus,\r\n onClick,\r\n onContextMenu,\r\n onPointerOver,\r\n onPointerOut\r\n ]\r\n );\r\n\r\n return {\r\n handleClick,\r\n handleContextMenu,\r\n handleIntersections\r\n };\r\n}\r\n","import { SpringValue, useSpring } from '@react-spring/three';\r\nimport { useCallback, useEffect, useRef } from 'react';\r\nimport { BufferAttribute, BufferGeometry } from 'three';\r\n\r\nimport { Theme } from '../../themes';\r\nimport { animationConfig } from '../../utils';\r\n\r\nexport function useEdgePositionAnimation(\r\n geometry: BufferGeometry,\r\n animated: boolean\r\n): void {\r\n const geometryRef = useRef(geometry);\r\n\r\n useEffect(() => {\r\n geometryRef.current = geometry;\r\n }, [geometry]);\r\n\r\n const getAnimationPositions = useCallback(() => {\r\n const positions = geometryRef.current.getAttribute('position');\r\n const from = Array.from({\r\n length: positions.array.length\r\n }).fill(0) as Array;\r\n const to = Array.from(positions.array);\r\n return { from, to };\r\n }, []);\r\n\r\n const updateGeometryPosition = useCallback((positions: Array) => {\r\n const buffer = new Float32Array(positions);\r\n const newPosition = new BufferAttribute(buffer, 3, false);\r\n geometryRef.current.setAttribute('position', newPosition);\r\n newPosition.needsUpdate = true;\r\n }, []);\r\n\r\n useSpring(() => {\r\n if (!animated) {\r\n return null;\r\n }\r\n\r\n const animationPositions = getAnimationPositions();\r\n\r\n return {\r\n from: {\r\n positions: animationPositions.from\r\n },\r\n to: {\r\n positions: animationPositions.to\r\n },\r\n onChange: event => {\r\n updateGeometryPosition(event.value.positions);\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n };\r\n }, [animated]);\r\n}\r\n\r\nexport type UseEdgeOpacityAnimations = {\r\n activeOpacity: SpringValue;\r\n inactiveOpacity: SpringValue;\r\n};\r\n\r\nexport function useEdgeOpacityAnimation(\r\n animated: boolean,\r\n hasSelections: boolean,\r\n theme: Theme\r\n): UseEdgeOpacityAnimations {\r\n const [{ activeOpacity, inactiveOpacity }] = useSpring(() => {\r\n return {\r\n from: {\r\n activeOpacity: 0,\r\n inactiveOpacity: 0\r\n },\r\n to: {\r\n activeOpacity: hasSelections\r\n ? theme.edge.selectedOpacity\r\n : theme.edge.opacity,\r\n inactiveOpacity: hasSelections\r\n ? theme.edge.inactiveOpacity\r\n : theme.edge.opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n };\r\n }, [animated, hasSelections, theme]);\r\n\r\n return { activeOpacity, inactiveOpacity };\r\n}\r\n","import React, { FC, useCallback, useMemo } from 'react';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Html } from 'glodrei';\r\nimport { ColorRepresentation, Euler } from 'three';\r\n\r\nimport { useStore } from '../../store';\r\nimport { Theme } from '../../themes';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../../types';\r\nimport {\r\n animationConfig,\r\n getLabelOffsetByType,\r\n getMidPoint\r\n} from '../../utils';\r\nimport { Label } from '../Label';\r\n\r\n/**\r\n * Label positions relatively edge\r\n *\r\n * below: show label under the edge line\r\n * above: show label above the edge line\r\n * inline: show label along the edge line\r\n * natural: normal text positions\r\n */\r\nexport type EdgeLabelPosition = 'below' | 'above' | 'inline' | 'natural';\r\n\r\nexport type EdgeArrowPosition = 'none' | 'mid' | 'end';\r\n\r\nexport interface EdgeProps {\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The color of the edge.\r\n */\r\n color: ColorRepresentation;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * The edge object.\r\n */\r\n edge: InternalGraphEdge;\r\n\r\n /**\r\n * The URL of the font for the edge label.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The opacity of the edge.\r\n */\r\n opacity?: number;\r\n}\r\n\r\nexport const Edge: FC = ({\r\n animated,\r\n color,\r\n contextMenu,\r\n edge,\r\n labelFontUrl,\r\n labelPlacement,\r\n opacity\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const { target, source, label, labelVisible = false, size = 1 } = edge;\r\n\r\n const nodes = useStore(store => store.nodes);\r\n const from = nodes.find(node => node.id === source);\r\n const to = nodes.find(node => node.id === target);\r\n const draggingId = useStore(state => state.draggingId);\r\n\r\n const labelOffset = (size + theme.edge.label.fontSize) / 2;\r\n\r\n const midPoint = useMemo(\r\n () =>\r\n getMidPoint(\r\n from.position,\r\n to.position,\r\n getLabelOffsetByType(labelOffset, labelPlacement)\r\n ),\r\n [from.position, to.position, labelOffset, labelPlacement]\r\n );\r\n\r\n const edgeContextMenus = useStore(state => state.edgeContextMenus);\r\n const setEdgeContextMenus = useStore(state => state.setEdgeContextMenus);\r\n\r\n const [{ labelPosition }] = useSpring(\r\n () => ({\r\n from: {\r\n labelPosition: [0, 0, 0]\r\n },\r\n to: {\r\n labelPosition: [midPoint.x, midPoint.y, midPoint.z]\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated && !draggingId ? undefined : 0\r\n }\r\n }),\r\n [midPoint, animated, draggingId]\r\n );\r\n\r\n const removeContextMenu = useCallback(\r\n (edge: InternalGraphEdge) => {\r\n edgeContextMenus.delete(edge.id);\r\n setEdgeContextMenus(new Set(edgeContextMenus.values()));\r\n },\r\n [edgeContextMenus, setEdgeContextMenus]\r\n );\r\n\r\n const labelRotation = useMemo(\r\n () =>\r\n new Euler(\r\n 0,\r\n 0,\r\n labelPlacement === 'natural'\r\n ? 0\r\n : Math.atan(\r\n (to.position.y - from.position.y) /\r\n (to.position.x - from.position.x)\r\n )\r\n ),\r\n [\r\n to.position.x,\r\n to.position.y,\r\n from.position.x,\r\n from.position.y,\r\n labelPlacement\r\n ]\r\n );\r\n\r\n return (\r\n \r\n {labelVisible && label && (\r\n \r\n \r\n \r\n )}\r\n {contextMenu && edgeContextMenus.has(edge.id) && (\r\n \r\n {contextMenu({\r\n data: edge,\r\n onClose: () => removeContextMenu(edge)\r\n })}\r\n \r\n )}\r\n \r\n );\r\n};\r\n\r\nEdge.defaultProps = {\r\n labelPlacement: 'inline'\r\n};\r\n","import React, { FC, useCallback, useEffect, useMemo, useRef } from 'react';\r\nimport { a } from '@react-spring/three';\r\nimport { useFrame } from '@react-three/fiber';\r\nimport { DoubleSide, Mesh, Raycaster, TubeGeometry } from 'three';\r\n\r\nimport { useStore } from '../../store';\r\nimport { ContextMenuEvent, InternalGraphEdge } from '../../types';\r\nimport { EdgeArrowPosition } from '../Arrow';\r\nimport { EdgeLabelPosition, EdgeInterpolation } from '../Edge';\r\nimport { useEdgeGeometry } from './useEdgeGeometry';\r\nimport { EdgeEvents, useEdgeEvents } from './useEdgeEvents';\r\nimport {\r\n useEdgePositionAnimation,\r\n useEdgeOpacityAnimation\r\n} from './useEdgeAnimations';\r\nimport { Edge } from './Edge';\r\n\r\nexport type EdgesProps = {\r\n /**\r\n * Whether the edge should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The placement of the edge arrow.\r\n */\r\n arrowPlacement?: EdgeArrowPosition;\r\n\r\n /**\r\n * A function that returns the context menu for the edge.\r\n */\r\n contextMenu?: (event: Partial) => React.ReactNode;\r\n\r\n /**\r\n * Whether the edge should be disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The array of edge objects.\r\n */\r\n edges: Array;\r\n\r\n /**\r\n * The URL of the font for the edge label.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * The placement of the edge label.\r\n */\r\n labelPlacement?: EdgeLabelPosition;\r\n\r\n /**\r\n * The type of interpolation used to draw the edge.\r\n */\r\n interpolation?: EdgeInterpolation;\r\n} & EdgeEvents;\r\n\r\n/**\r\n * Three.js rendering starts to get slower if you have an individual mesh for each edge\r\n * and a high number of edges.\r\n *\r\n * Instead, we take the edges and split them into their different render states:\r\n *\r\n * * - Active (any edges that are marked as \"selected\" or \"active\" in the state)\r\n * * - Dragging (any edges that are connected to a node that is being dragged)\r\n * * - Intersecting (any edges that are currently intersected by the ray from the mouse position)\r\n * * - Inactive (any edges that aren't active, dragging, or intersected)\r\n *\r\n * We generate the geometry for each edge in each of these groups, and then merge them\r\n * into a single geometry for each group. This merged mesh is rendered as one object\r\n * which gives much better performance. This means that we only need to update geometry\r\n * and positions when edges move between the different states, rather than updating all\r\n * edges whenever any other edge changes.\r\n *\r\n * To get this all working, we have to do a few things outside the @react-three/fiber world,\r\n * specifically:\r\n *\r\n * * manually create edge/arrow geometries (see `useEdgeGeometry`)\r\n * * manually track mouse/edge interactions and fire events (see `useEdgeEvents`)\r\n * * manually update edge/arrow positions during aniamations (see `useEdgeAnimations`)\r\n */\r\nexport const Edges: FC = ({\r\n interpolation = 'linear',\r\n arrowPlacement = 'end',\r\n labelPlacement = 'inline',\r\n animated,\r\n contextMenu,\r\n disabled,\r\n edges,\r\n labelFontUrl,\r\n onClick,\r\n onContextMenu,\r\n onPointerOut,\r\n onPointerOver\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const { getGeometries, getGeometry } = useEdgeGeometry(\r\n arrowPlacement,\r\n interpolation\r\n );\r\n\r\n const draggingId = useStore(state => state.draggingId);\r\n const edgeMeshes = useStore(state => state.edgeMeshes);\r\n const setEdgeMeshes = useStore(state => state.setEdgeMeshes);\r\n const actives = useStore(state => state.actives || []);\r\n const selections = useStore(state => state.selections || []);\r\n\r\n const [active, inactive, draggingActive, draggingInactive] = useMemo(() => {\r\n const active: Array = [];\r\n const inactive: Array = [];\r\n const draggingActive: Array = [];\r\n const draggingInactive: Array = [];\r\n edges.forEach(edge => {\r\n if (draggingId === edge.source || draggingId === edge.target) {\r\n if (selections.includes(edge.id) || actives.includes(edge.id)) {\r\n draggingActive.push(edge);\r\n } else {\r\n draggingInactive.push(edge);\r\n }\r\n return;\r\n }\r\n\r\n if (selections.includes(edge.id) || actives.includes(edge.id)) {\r\n active.push(edge);\r\n } else {\r\n inactive.push(edge);\r\n }\r\n });\r\n return [active, inactive, draggingActive, draggingInactive];\r\n }, [edges, actives, selections, draggingId]);\r\n\r\n const hasSelections = !!selections.length;\r\n\r\n const staticEdgesGeometry = useMemo(\r\n () => getGeometry(active, inactive),\r\n [getGeometry, active, inactive]\r\n );\r\n\r\n const { activeOpacity, inactiveOpacity } = useEdgeOpacityAnimation(\r\n animated,\r\n hasSelections,\r\n theme\r\n );\r\n\r\n useEdgePositionAnimation(staticEdgesGeometry, animated);\r\n\r\n useEffect(() => {\r\n if (draggingId === null) {\r\n const edgeGeometries = getGeometries(edges);\r\n const edgeMeshes = edgeGeometries.map(edge => new Mesh(edge));\r\n setEdgeMeshes(edgeMeshes);\r\n }\r\n }, [getGeometries, setEdgeMeshes, edges, draggingId]);\r\n\r\n const staticEdgesRef = useRef(new Mesh());\r\n const dynamicEdgesRef = useRef(new Mesh());\r\n\r\n const intersect = useCallback(\r\n (raycaster: Raycaster): Array => {\r\n // Handle initial raycaster state:\r\n if (!raycaster.camera) {\r\n return [];\r\n }\r\n const intersections =\r\n raycaster.intersectObjects>(edgeMeshes);\r\n if (!intersections.length) {\r\n return [];\r\n }\r\n return intersections.map(\r\n intersection => edges[edgeMeshes.indexOf(intersection.object)]\r\n );\r\n },\r\n [edgeMeshes, edges]\r\n );\r\n\r\n const { handleClick, handleContextMenu, handleIntersections } = useEdgeEvents(\r\n {\r\n onClick,\r\n onContextMenu,\r\n onPointerOut,\r\n onPointerOver\r\n },\r\n contextMenu,\r\n disabled\r\n );\r\n\r\n const draggingIdRef = useRef(null);\r\n const intersectingRef = useRef>([]);\r\n\r\n useFrame(state => {\r\n staticEdgesRef.current.geometry = staticEdgesGeometry;\r\n\r\n if (disabled) {\r\n return;\r\n }\r\n\r\n const previousDraggingId = draggingIdRef.current;\r\n if (draggingId || (draggingId === null && previousDraggingId !== null)) {\r\n dynamicEdgesRef.current.geometry = getGeometry(\r\n draggingActive,\r\n draggingInactive\r\n );\r\n }\r\n\r\n draggingIdRef.current = draggingId;\r\n if (draggingId) {\r\n return;\r\n }\r\n\r\n const previousIntersecting = intersectingRef.current;\r\n const intersecting = intersect(state.raycaster);\r\n handleIntersections(previousIntersecting, intersecting);\r\n\r\n if (intersecting.join() !== previousIntersecting.join()) {\r\n dynamicEdgesRef.current.geometry = getGeometry(intersecting, []);\r\n }\r\n\r\n intersectingRef.current = intersecting;\r\n });\r\n\r\n return (\r\n \r\n {/* Static edges */}\r\n \r\n \r\n \r\n \r\n {/* Dynamic edges */}\r\n \r\n \r\n \r\n \r\n {edges.map(edge => (\r\n \r\n ))}\r\n \r\n );\r\n};\r\n","import React, { FC, useMemo, useState } from 'react';\r\nimport { ClusterGroup, animationConfig, useHoverIntent } from '../utils';\r\nimport { useSpring, a } from '@react-spring/three';\r\nimport { Color, DoubleSide } from 'three';\r\nimport { useStore } from '../store';\r\nimport { Label } from './Label';\r\nimport { useCursor } from 'glodrei';\r\nimport { ThreeEvent } from '@react-three/fiber';\r\n\r\nexport type ClusterEventArgs = Omit;\r\n\r\nexport interface ClusterProps extends ClusterGroup {\r\n /**\r\n * Whether the circle should be animated.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * The radius of the circle. Default 1.\r\n */\r\n radius?: number;\r\n\r\n /**\r\n * The padding of the circle. Default 20.\r\n */\r\n padding?: number;\r\n\r\n /**\r\n * The url for the label font.\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * Whether the node is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * When the cluster was clicked.\r\n */\r\n onClick?: (cluster: ClusterEventArgs, event: ThreeEvent) => void;\r\n\r\n /**\r\n * When a cluster receives a pointer over event.\r\n */\r\n onPointerOver?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When cluster receives a pointer leave event.\r\n */\r\n onPointerOut?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nexport const Cluster: FC = ({\r\n animated,\r\n position,\r\n padding,\r\n labelFontUrl,\r\n disabled,\r\n radius,\r\n nodes,\r\n label,\r\n onClick,\r\n onPointerOver,\r\n onPointerOut\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const rad = Math.max(position.width, position.height) / 2;\r\n const offset = rad - radius + padding;\r\n const [active, setActive] = useState(false);\r\n const center = useStore(state => state.centerPosition);\r\n\r\n const isActive = useStore(state =>\r\n state.actives?.some(id => nodes.some(n => n.id === id))\r\n );\r\n\r\n const isSelected = useStore(state =>\r\n state.selections?.some(id => nodes.some(n => n.id === id))\r\n );\r\n\r\n const hasSelections = useStore(state => state.selections?.length > 0);\r\n\r\n const opacity = hasSelections\r\n ? isSelected || active || isActive\r\n ? theme.cluster?.selectedOpacity\r\n : theme.cluster?.inactiveOpacity\r\n : theme.cluster?.opacity;\r\n\r\n const { circleOpacity, circlePosition, labelPosition } = useSpring({\r\n from: {\r\n circlePosition: [center.x, center.y, -1],\r\n circleOpacity: 0,\r\n labelPosition: [0, -offset, 2]\r\n },\r\n to: {\r\n labelPosition: [0, -offset, 2],\r\n circlePosition: position ? [position.x, position.y, -1] : [0, 0, -1],\r\n circleOpacity: opacity\r\n },\r\n config: {\r\n ...animationConfig,\r\n duration: animated ? undefined : 0\r\n }\r\n });\r\n\r\n const normalizedStroke = useMemo(\r\n () => new Color(theme.cluster?.stroke),\r\n [theme.cluster?.stroke]\r\n );\r\n\r\n const normalizedFill = useMemo(\r\n () => new Color(theme.cluster?.fill),\r\n [theme.cluster?.fill]\r\n );\r\n\r\n useCursor(active && onClick !== undefined, 'pointer');\r\n\r\n const { pointerOver, pointerOut } = useHoverIntent({\r\n disabled,\r\n onPointerOver: (event: ThreeEvent) => {\r\n setActive(true);\r\n onPointerOver?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n },\r\n onPointerOut: (event: ThreeEvent) => {\r\n setActive(false);\r\n onPointerOut?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n }\r\n });\r\n\r\n const cluster = useMemo(\r\n () =>\r\n theme.cluster && (\r\n ) => {\r\n if (!disabled) {\r\n onClick?.(\r\n {\r\n nodes,\r\n label\r\n },\r\n event\r\n );\r\n }\r\n }}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n {theme.cluster?.label && (\r\n \r\n \r\n \r\n )}\r\n \r\n ),\r\n [\r\n theme.cluster,\r\n circlePosition,\r\n pointerOver,\r\n pointerOut,\r\n offset,\r\n normalizedFill,\r\n circleOpacity,\r\n rad,\r\n padding,\r\n normalizedStroke,\r\n labelPosition,\r\n label,\r\n opacity,\r\n labelFontUrl,\r\n disabled,\r\n onClick,\r\n nodes\r\n ]\r\n );\r\n\r\n return cluster;\r\n};\r\n\r\nCluster.defaultProps = {\r\n radius: 2,\r\n padding: 40\r\n};\r\n","import React, {\r\n FC,\r\n forwardRef,\r\n Fragment,\r\n ReactNode,\r\n Ref,\r\n useImperativeHandle,\r\n useMemo\r\n} from 'react';\r\nimport { useGraph } from './useGraph';\r\nimport { LayoutOverrides, LayoutTypes } from './layout';\r\nimport {\r\n NodeContextMenuProps,\r\n ContextMenuEvent,\r\n GraphEdge,\r\n GraphNode,\r\n InternalGraphEdge,\r\n InternalGraphNode,\r\n NodeRenderer,\r\n CollapseProps\r\n} from './types';\r\nimport { SizingType } from './sizing';\r\nimport {\r\n Cluster,\r\n ClusterEventArgs,\r\n Edge,\r\n EdgeArrowPosition,\r\n EdgeInterpolation,\r\n EdgeLabelPosition,\r\n Edges,\r\n Node\r\n} from './symbols';\r\nimport {\r\n CenterNodesParams,\r\n FitNodesParams,\r\n useCenterGraph\r\n} from './CameraControls';\r\nimport { LabelVisibilityType } from './utils';\r\nimport { useStore } from './store';\r\nimport Graph from 'graphology';\r\nimport { ThreeEvent, useThree } from '@react-three/fiber';\r\n\r\nexport interface GraphSceneProps {\r\n /**\r\n * Type of layout.\r\n */\r\n layoutType?: LayoutTypes;\r\n\r\n /**\r\n * List of ids that are selected.\r\n */\r\n selections?: string[];\r\n\r\n /**\r\n * List of ids that are active.\r\n */\r\n actives?: string[];\r\n\r\n /**\r\n * List of node ids that are collapsed.\r\n */\r\n collapsedNodeIds?: string[];\r\n\r\n /**\r\n * Animate or not the graph positions.\r\n */\r\n animated?: boolean;\r\n\r\n /**\r\n * Nodes to pass to the graph.\r\n */\r\n nodes: GraphNode[];\r\n\r\n /**\r\n * Edges to pass to the graph.\r\n */\r\n edges: GraphEdge[];\r\n\r\n /**\r\n * Context menu element.\r\n */\r\n contextMenu?: (event: ContextMenuEvent) => ReactNode;\r\n\r\n /**\r\n * Type of sizing for nodes.\r\n */\r\n sizingType?: SizingType;\r\n\r\n /**\r\n * Type of visibility for labels.\r\n */\r\n labelType?: LabelVisibilityType;\r\n\r\n /**\r\n * Place of visibility for edge labels.\r\n */\r\n edgeLabelPosition?: EdgeLabelPosition;\r\n\r\n /**\r\n * Placement of edge arrows.\r\n */\r\n edgeArrowPosition?: EdgeArrowPosition;\r\n\r\n /**\r\n * Shape of edge.\r\n */\r\n edgeInterpolation?: EdgeInterpolation;\r\n\r\n /**\r\n * Font of label, same as troika-three-text\r\n * The URL of a custom font file to be used. Supported font formats are: * .ttf * .otf * .woff (.woff2 is not supported)\r\n * Default: The Roboto font loaded from Google Fonts CDN\r\n */\r\n labelFontUrl?: string;\r\n\r\n /**\r\n * Attribute based sizing property.\r\n */\r\n sizingAttribute?: string;\r\n\r\n /**\r\n * The default size to size nodes to. Default is 7.\r\n */\r\n defaultNodeSize?: number;\r\n\r\n /**\r\n * When using sizing attributes, the min size a node can be.\r\n */\r\n minNodeSize?: number;\r\n\r\n /**\r\n * When using sizing attributes, the max size a node can be.\r\n */\r\n maxNodeSize?: number;\r\n\r\n /**\r\n * Attribute used for clustering.\r\n */\r\n clusterAttribute?: string;\r\n\r\n /**\r\n * Disable interactions or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Allow dragging of nodes.\r\n */\r\n draggable?: boolean;\r\n\r\n /**\r\n * Render a custom node\r\n */\r\n renderNode?: NodeRenderer;\r\n\r\n /**\r\n * Advanced overrides for the layout.\r\n */\r\n layoutOverrides?: LayoutOverrides;\r\n\r\n /**\r\n * When a node was clicked.\r\n */\r\n onNodeClick?: (\r\n node: InternalGraphNode,\r\n props?: CollapseProps,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a node was double clicked.\r\n */\r\n onNodeDoubleClick?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a node context menu happened.\r\n */\r\n onNodeContextMenu?: (\r\n node: InternalGraphNode,\r\n props?: NodeContextMenuProps\r\n ) => void;\r\n\r\n /**\r\n * When node got a pointer over.\r\n */\r\n onNodePointerOver?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When node lost pointer over.\r\n */\r\n onNodePointerOut?: (\r\n node: InternalGraphNode,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * Triggered after a node was dragged.\r\n */\r\n onNodeDragged?: (node: InternalGraphNode) => void;\r\n\r\n /**\r\n * When a edge context menu happened.\r\n */\r\n onEdgeContextMenu?: (edge?: InternalGraphEdge) => void;\r\n\r\n /**\r\n * When an edge was clicked.\r\n */\r\n onEdgeClick?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When edge got a pointer over.\r\n */\r\n onEdgePointerOver?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When edge lost pointer over.\r\n */\r\n onEdgePointerOut?: (\r\n edge: InternalGraphEdge,\r\n event?: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a cluster was clicked.\r\n */\r\n onClusterClick?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When a cluster receives a pointer over event.\r\n */\r\n onClusterPointerOver?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n\r\n /**\r\n * When cluster receives a pointer leave event.\r\n */\r\n onClusterPointerOut?: (\r\n cluster: ClusterEventArgs,\r\n event: ThreeEvent\r\n ) => void;\r\n}\r\n\r\nexport interface GraphSceneRef {\r\n /**\r\n * Reference to the graph object.\r\n */\r\n graph: Graph;\r\n\r\n /**\r\n * Centers the graph on a specific node or list of nodes.\r\n *\r\n * @param nodeIds - An array of node IDs to center the graph on. If this parameter is omitted,\r\n * the graph will be centered on all nodes.\r\n *\r\n * @param opts.centerOnlyIfNodesNotInView - A boolean flag that determines whether the graph should\r\n * only be centered if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the graph will only be re-centered if one or more of the nodes\r\n * specified by `ids` are not currently in view. If this parameter is\r\n * `false` or omitted, the graph will be re-centered regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n centerGraph: (nodeIds?: string[], opts?: CenterNodesParams) => void;\r\n\r\n /**\r\n * Fit all the given nodes into view of the camera.\r\n *\r\n * @param nodeIds - An array of node IDs to fit the view on. If this parameter is omitted,\r\n * the view will fit to all nodes.\r\n *\r\n * @param opts.fitOnlyIfNodesNotInView - A boolean flag that determines whether the view should\r\n * only be fit if the nodes specified by `ids` are not currently in view. If this\r\n * parameter is `true`, the view will only be fit if one or more of the nodes\r\n * specified by `ids` are not currently visible in the viewport. If this parameter is\r\n * `false` or omitted, the view will be fit regardless of whether the nodes\r\n * are currently in view.\r\n */\r\n fitNodesInView: (nodeIds?: string[], opts?: FitNodesParams) => void;\r\n\r\n /**\r\n * Calls render scene on the graph. this is useful when you want to manually render the graph\r\n * for things like screenshots.\r\n */\r\n renderScene: () => void;\r\n}\r\n\r\nexport const GraphScene: FC }> =\r\n forwardRef(\r\n (\r\n {\r\n onNodeClick,\r\n onNodeDoubleClick,\r\n onNodeContextMenu,\r\n onEdgeContextMenu,\r\n onEdgeClick,\r\n onEdgePointerOver,\r\n onEdgePointerOut,\r\n onNodePointerOver,\r\n onNodePointerOut,\r\n onClusterClick,\r\n onNodeDragged,\r\n onClusterPointerOver,\r\n onClusterPointerOut,\r\n contextMenu,\r\n animated,\r\n disabled,\r\n draggable,\r\n edgeLabelPosition,\r\n edgeArrowPosition,\r\n edgeInterpolation,\r\n labelFontUrl,\r\n renderNode,\r\n ...rest\r\n },\r\n ref\r\n ) => {\r\n const { layoutType, clusterAttribute } = rest;\r\n\r\n // Get the gl/scene/camera for render shortcuts\r\n const gl = useThree(state => state.gl);\r\n const scene = useThree(state => state.scene);\r\n const camera = useThree(state => state.camera);\r\n\r\n // Mount and build the graph\r\n useGraph(rest);\r\n\r\n if (\r\n clusterAttribute &&\r\n !(layoutType === 'forceDirected2d' || layoutType === 'forceDirected3d')\r\n ) {\r\n throw new Error(\r\n 'Clustering is only supported for the force directed layouts.'\r\n );\r\n }\r\n\r\n // Get the graph and nodes via the store for memo\r\n const graph = useStore(state => state.graph);\r\n const nodes = useStore(state => state.nodes);\r\n const edges = useStore(state => state.edges);\r\n const clusters = useStore(state => [...state.clusters.values()]);\r\n\r\n // Center the graph on the nodes\r\n const { centerNodesById, fitNodesInViewById, isCentered } =\r\n useCenterGraph({\r\n animated,\r\n disabled,\r\n layoutType\r\n });\r\n\r\n // Let's expose some helper methods\r\n useImperativeHandle(\r\n ref,\r\n () => ({\r\n centerGraph: centerNodesById,\r\n fitNodesInView: fitNodesInViewById,\r\n graph,\r\n renderScene: () => gl.render(scene, camera)\r\n }),\r\n [centerNodesById, fitNodesInViewById, graph, gl, scene, camera]\r\n );\r\n\r\n const nodeComponents = useMemo(\r\n () =>\r\n nodes.map(n => (\r\n \r\n )),\r\n [\r\n animated,\r\n contextMenu,\r\n disabled,\r\n draggable,\r\n labelFontUrl,\r\n nodes,\r\n onNodeClick,\r\n onNodeContextMenu,\r\n onNodeDoubleClick,\r\n onNodeDragged,\r\n onNodePointerOut,\r\n onNodePointerOver,\r\n renderNode\r\n ]\r\n );\r\n\r\n const edgeComponents = useMemo(\r\n () =>\r\n animated ? (\r\n edges.map(e => (\r\n \r\n ))\r\n ) : (\r\n \r\n ),\r\n [\r\n animated,\r\n contextMenu,\r\n disabled,\r\n edgeArrowPosition,\r\n edgeInterpolation,\r\n edgeLabelPosition,\r\n edges,\r\n labelFontUrl,\r\n onEdgeClick,\r\n onEdgeContextMenu,\r\n onEdgePointerOut,\r\n onEdgePointerOver\r\n ]\r\n );\r\n\r\n const clusterComponents = useMemo(\r\n () =>\r\n clusters.map(c => (\r\n \r\n )),\r\n [\r\n animated,\r\n clusters,\r\n disabled,\r\n labelFontUrl,\r\n onClusterClick,\r\n onClusterPointerOut,\r\n onClusterPointerOver\r\n ]\r\n );\r\n\r\n return (\r\n isCentered && (\r\n \r\n {edgeComponents}\r\n {nodeComponents}\r\n {clusterComponents}\r\n \r\n )\r\n );\r\n }\r\n );\r\n\r\nGraphScene.defaultProps = {\r\n edgeInterpolation: 'linear'\r\n};\r\n","import { Theme } from './theme';\r\n\r\nexport const darkTheme: Theme = {\r\n canvas: {\r\n background: '#1E2026'\r\n },\r\n node: {\r\n fill: '#7A8C9E',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n },\r\n subLabel: {\r\n stroke: '#1E2026',\r\n color: '#ACBAC7',\r\n activeColor: '#1DE9AC'\r\n }\r\n },\r\n lasso: {\r\n border: '1px solid #55aaff',\r\n background: 'rgba(75, 160, 255, 0.1)'\r\n },\r\n ring: {\r\n fill: '#54616D',\r\n activeFill: '#1DE9AC'\r\n },\r\n edge: {\r\n fill: '#ffffff',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 4,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n }\r\n },\r\n arrow: {\r\n fill: '#474B56',\r\n activeFill: '#1DE9AC'\r\n },\r\n cluster: {\r\n stroke: '#474B56',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n color: '#202020',\r\n activeColor: '#000000',\r\n fontSize: 4,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#fafafa',\r\n borderRadius: 2\r\n }\r\n }\r\n};\r\n","import { Theme } from './theme';\r\n\r\nexport const lightTheme: Theme = {\r\n canvas: {\r\n background: '#fff'\r\n },\r\n node: {\r\n fill: '#7CA0AB',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.2,\r\n label: {\r\n color: '#2A6475',\r\n // stroke: '#fff',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n },\r\n subLabel: {\r\n color: '#ddd',\r\n stroke: 'transparent',\r\n activeColor: '#1DE9AC'\r\n }\r\n },\r\n lasso: {\r\n border: '1px solid #55aaff',\r\n background: 'rgba(75, 160, 255, 0.1)'\r\n },\r\n ring: {\r\n fill: '#D8E6EA',\r\n activeFill: '#1DE9AC'\r\n },\r\n edge: {\r\n fill: '#474B56',\r\n activeFill: '#1DE9AC',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n // stroke: '#fff',\r\n color: '#2A6475',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n }\r\n },\r\n arrow: {\r\n fill: '#D8E6EA',\r\n activeFill: '#1DE9AC'\r\n },\r\n cluster: {\r\n stroke: '#D8E6EA',\r\n opacity: 1,\r\n selectedOpacity: 1,\r\n inactiveOpacity: 0.1,\r\n label: {\r\n stroke: '#1E2026',\r\n color: '#ACBAC7',\r\n activeColor: '#1DE9AC',\r\n fontSize: 6,\r\n maxWidth: 100,\r\n ellipsis: 100,\r\n backgroundColor: '#1E2026',\r\n borderRadius: 2\r\n }\r\n }\r\n};\r\n","import { Theme } from '../themes';\r\nimport Graph from 'graphology';\r\n\r\nexport type PathSelectionTypes = 'direct' | 'out' | 'in' | 'all';\r\n\r\n/**\r\n * Given a graph and a list of node ids, return the adjacent nodes and edges.\r\n *\r\n * TODO: This method could be improved with the introduction of graphology\r\n */\r\nexport function getAdjacents(\r\n graph: Graph,\r\n nodeIds: string | string[],\r\n type: PathSelectionTypes\r\n) {\r\n nodeIds = Array.isArray(nodeIds) ? nodeIds : [nodeIds];\r\n\r\n const nodes: string[] = [];\r\n const edges: string[] = [];\r\n\r\n for (const nodeId of nodeIds) {\r\n const graphLinks = [\r\n ...(graph.inEdgeEntries(nodeId) ?? []),\r\n ...(graph.outEdgeEntries(nodeId) ?? [])\r\n ];\r\n\r\n if (!graphLinks) {\r\n continue;\r\n }\r\n\r\n for (const link of graphLinks) {\r\n const linkId = link.attributes.id;\r\n\r\n if (type === 'in') {\r\n if (link.target === nodeId && !edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n } else if (type === 'out') {\r\n if (link.source === nodeId && !edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n } else {\r\n if (!edges.includes(linkId)) {\r\n edges.push(linkId);\r\n }\r\n }\r\n\r\n if (type === 'out' || type === 'all') {\r\n const toId = link.target;\r\n if (!nodes.includes(toId as string)) {\r\n nodes.push(toId as string);\r\n }\r\n }\r\n\r\n if (type === 'in' || type === 'all') {\r\n if (!nodes.includes(link.source)) {\r\n nodes.push(link.source as string);\r\n }\r\n }\r\n }\r\n }\r\n\r\n return {\r\n nodes,\r\n edges\r\n };\r\n}\r\n\r\n/**\r\n * Set the vectors.\r\n */\r\nexport function prepareRay(event, vec, size) {\r\n const { offsetX, offsetY } = event;\r\n const { width, height } = size;\r\n vec.set((offsetX / width) * 2 - 1, -(offsetY / height) * 2 + 1);\r\n}\r\n\r\n/**\r\n * Create a lasso element.\r\n */\r\nexport function createElement(theme: Theme) {\r\n const element = document.createElement('div');\r\n element.style.pointerEvents = 'none';\r\n element.style.border = theme.lasso.border;\r\n element.style.backgroundColor = theme.lasso.background;\r\n element.style.position = 'fixed';\r\n return element;\r\n}\r\n","import React, {\r\n FC,\r\n PropsWithChildren,\r\n useCallback,\r\n useEffect,\r\n useRef\r\n} from 'react';\r\nimport { useThree } from '@react-three/fiber';\r\nimport { SelectionBox } from 'three-stdlib';\r\nimport { Mesh, Scene, TubeGeometry, Vector2 } from 'three';\r\nimport { useCameraControls } from '../CameraControls';\r\nimport { useStore } from '../store';\r\nimport { createElement, prepareRay } from './utils';\r\n\r\nexport type LassoType = 'none' | 'all' | 'node' | 'edge';\r\n\r\nexport type LassoProps = PropsWithChildren<{\r\n /**\r\n * Whether the lasso tool is disabled.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * The type of the lasso tool.\r\n */\r\n type?: LassoType;\r\n\r\n /**\r\n * A function that is called when the lasso tool is used to select nodes.\r\n * The function receives an array of the ids of the selected nodes.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * A function that is called when the lasso tool is released, ending the selection.\r\n * The function receives an array of the ids of the selected nodes.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n}>;\r\n\r\nexport const Lasso: FC = ({\r\n children,\r\n type = 'none',\r\n onLasso,\r\n onLassoEnd,\r\n disabled\r\n}) => {\r\n const theme = useStore(state => state.theme);\r\n const camera = useThree(state => state.camera);\r\n const gl = useThree(state => state.gl);\r\n const setEvents = useThree(state => state.setEvents);\r\n const size = useThree(state => state.size);\r\n const get = useThree(state => state.get);\r\n const scene = useThree(state => state.scene);\r\n\r\n const cameraControls = useCameraControls();\r\n\r\n const actives = useStore(state => state.actives);\r\n const setActives = useStore(state => state.setActives);\r\n const edges = useStore(state => state.edges);\r\n const edgeMeshes = useStore(state => state.edgeMeshes);\r\n\r\n const mountedRef = useRef(false);\r\n const selectionBoxRef = useRef(null);\r\n const edgeMeshSelectionBoxRef = useRef(null);\r\n const elementRef = useRef(createElement(theme));\r\n const vectorsRef = useRef<[Vector2, Vector2, Vector2] | null>(null);\r\n const isDownRef = useRef(false);\r\n const oldRaycasterEnabledRef = useRef(get().events.enabled);\r\n const oldControlsEnabledRef = useRef(\r\n cameraControls.controls?.enabled\r\n );\r\n\r\n useEffect(() => {\r\n if (mountedRef.current) {\r\n onLasso?.(actives);\r\n }\r\n\r\n mountedRef.current = true;\r\n }, [actives, onLasso]);\r\n\r\n const onPointerMove = useCallback(\r\n event => {\r\n if (isDownRef.current) {\r\n const [startPoint, pointTopLeft, pointBottomRight] = vectorsRef.current;\r\n\r\n pointBottomRight.x = Math.max(startPoint.x, event.clientX);\r\n pointBottomRight.y = Math.max(startPoint.y, event.clientY);\r\n pointTopLeft.x = Math.min(startPoint.x, event.clientX);\r\n pointTopLeft.y = Math.min(startPoint.y, event.clientY);\r\n elementRef.current.style.left = `${pointTopLeft.x}px`;\r\n elementRef.current.style.top = `${pointTopLeft.y}px`;\r\n elementRef.current.style.width = `${\r\n pointBottomRight.x - pointTopLeft.x\r\n }px`;\r\n elementRef.current.style.height = `${\r\n pointBottomRight.y - pointTopLeft.y\r\n }px`;\r\n\r\n prepareRay(event, selectionBoxRef.current.endPoint, size);\r\n prepareRay(event, edgeMeshSelectionBoxRef.current.endPoint, size);\r\n\r\n const allSelected = [];\r\n const edgesSelected = edgeMeshSelectionBoxRef.current\r\n .select()\r\n .sort(o => (o as any).uuid)\r\n .map(\r\n edge => edges[edgeMeshes.indexOf(edge as Mesh)].id\r\n );\r\n allSelected.push(...edgesSelected);\r\n\r\n const selected = selectionBoxRef.current\r\n .select()\r\n .sort(o => (o as any).uuid)\r\n .filter(\r\n o =>\r\n o.isMesh &&\r\n o.userData?.id &&\r\n (o.userData?.type === type || type === 'all')\r\n )\r\n .map(o => o.userData.id);\r\n allSelected.push(...selected);\r\n\r\n // Note: This probably isn't the best solution but\r\n // it prevents the render thrashing and causing flickering\r\n requestAnimationFrame(() => {\r\n setActives(allSelected);\r\n });\r\n\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true,\r\n capture: true,\r\n once: true\r\n });\r\n }\r\n },\r\n [edges, edgeMeshes, setActives, size, type]\r\n );\r\n\r\n const onPointerUp = useCallback(() => {\r\n if (isDownRef.current) {\r\n setEvents({ enabled: oldRaycasterEnabledRef.current });\r\n isDownRef.current = false;\r\n elementRef.current.parentElement?.removeChild(elementRef.current);\r\n cameraControls.controls.enabled = oldControlsEnabledRef.current;\r\n onLassoEnd?.(actives);\r\n\r\n document.removeEventListener('pointermove', onPointerMove);\r\n document.removeEventListener('pointerup', onPointerUp);\r\n }\r\n }, [setEvents, cameraControls.controls, onLassoEnd, actives, onPointerMove]);\r\n\r\n const onPointerDown = useCallback(\r\n event => {\r\n if (event.shiftKey) {\r\n // Let's capture the old props to restore them later\r\n oldRaycasterEnabledRef.current = get().events.enabled;\r\n oldControlsEnabledRef.current = cameraControls.controls?.enabled;\r\n\r\n // SelectionBox for all meshes\r\n selectionBoxRef.current = new SelectionBox(camera, scene);\r\n\r\n // SelectionBox for all Edge meshes (since they are combined into one geometry for rendering)\r\n const edgeScene = new Scene();\r\n if (edgeMeshes.length) {\r\n edgeScene.add(...edgeMeshes);\r\n }\r\n edgeMeshSelectionBoxRef.current = new SelectionBox(camera, edgeScene);\r\n\r\n vectorsRef.current = [\r\n // start point\r\n new Vector2(),\r\n // point top left\r\n new Vector2(),\r\n // point bottom right\r\n new Vector2()\r\n ];\r\n\r\n const [startPoint] = vectorsRef.current;\r\n\r\n cameraControls.controls.enabled = false;\r\n setEvents({ enabled: false });\r\n isDownRef.current = true;\r\n gl.domElement.parentElement?.appendChild(elementRef.current);\r\n elementRef.current.style.left = `${event.clientX}px`;\r\n elementRef.current.style.top = `${event.clientY}px`;\r\n elementRef.current.style.width = '0px';\r\n elementRef.current.style.height = '0px';\r\n startPoint.x = event.clientX;\r\n startPoint.y = event.clientY;\r\n\r\n prepareRay(event, selectionBoxRef.current.startPoint, size);\r\n prepareRay(event, edgeMeshSelectionBoxRef.current.startPoint, size);\r\n\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true,\r\n capture: true,\r\n once: true\r\n });\r\n document.addEventListener('pointerup', onPointerUp, { passive: true });\r\n }\r\n },\r\n [\r\n camera,\r\n cameraControls.controls,\r\n edgeMeshes,\r\n get,\r\n gl.domElement.parentElement,\r\n onPointerMove,\r\n onPointerUp,\r\n scene,\r\n setEvents,\r\n size\r\n ]\r\n );\r\n\r\n useEffect(() => {\r\n if (disabled || type === 'none') {\r\n return;\r\n }\r\n\r\n if (typeof window !== 'undefined') {\r\n document.addEventListener('pointerdown', onPointerDown, {\r\n passive: true\r\n });\r\n document.addEventListener('pointermove', onPointerMove, {\r\n passive: true\r\n });\r\n document.addEventListener('pointerup', onPointerUp, { passive: true });\r\n }\r\n\r\n return () => {\r\n if (typeof window !== 'undefined') {\r\n document.removeEventListener('pointerdown', onPointerDown);\r\n document.removeEventListener('pointermove', onPointerMove);\r\n document.removeEventListener('pointerup', onPointerUp);\r\n }\r\n };\r\n }, [type, disabled, onPointerDown, onPointerMove, onPointerUp]);\r\n\r\n return {children};\r\n};\r\n","import React, {\r\n RefObject,\r\n useCallback,\r\n useEffect,\r\n useMemo,\r\n useState\r\n} from 'react';\r\nimport { GraphCanvasRef } from '../GraphCanvas';\r\nimport { useHotkeys } from 'reakeys';\r\nimport { GraphEdge, GraphNode } from '../types';\r\nimport { findPath } from '../utils/paths';\r\nimport { getAdjacents, PathSelectionTypes } from './utils';\r\n\r\nexport type HotkeyTypes = 'selectAll' | 'deselect' | 'delete';\r\n\r\nexport type SelectionTypes = 'single' | 'multi' | 'multiModifier';\r\n\r\nexport interface SelectionProps {\r\n /**\r\n * Required ref for the graph.\r\n */\r\n ref: RefObject;\r\n\r\n /**\r\n * Current selections.\r\n *\r\n * Contains both nodes and edges ids.\r\n */\r\n selections?: string[];\r\n\r\n /**\r\n * Default active selections.\r\n */\r\n actives?: string[];\r\n\r\n /**\r\n * Node datas.\r\n */\r\n nodes?: GraphNode[];\r\n\r\n /**\r\n * Edge datas.\r\n */\r\n edges?: GraphEdge[];\r\n\r\n /**\r\n * Disabled or not.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Hotkey types\r\n */\r\n hotkeys?: HotkeyTypes[];\r\n\r\n /**\r\n * Whether to focus on select or not.\r\n */\r\n focusOnSelect?: boolean | 'singleOnly';\r\n\r\n /**\r\n * Type of selection.\r\n */\r\n type?: SelectionTypes;\r\n\r\n /**\r\n * Type of selection.\r\n */\r\n pathSelectionType?: PathSelectionTypes;\r\n\r\n /**\r\n * Whether it should active on hover or not.\r\n */\r\n pathHoverType?: PathSelectionTypes;\r\n\r\n /**\r\n * On selection change.\r\n */\r\n onSelection?: (selectionIds: string[]) => void;\r\n}\r\n\r\nexport interface SelectionResult {\r\n /**\r\n * Selections id array (of nodes and edges).\r\n */\r\n selections: string[];\r\n\r\n /**\r\n * The nodes/edges around the selections to highlight.\r\n */\r\n actives: string[];\r\n\r\n /**\r\n * Clear selections method.\r\n */\r\n clearSelections: (value?: string[]) => void;\r\n\r\n /**\r\n * A selection method.\r\n */\r\n addSelection: (value: string) => void;\r\n\r\n /**\r\n * Get the paths between two nodes.\r\n */\r\n selectNodePaths: (source: string, target: string) => void;\r\n\r\n /**\r\n * Remove selection method.\r\n */\r\n removeSelection: (value: string) => void;\r\n\r\n /**\r\n * Toggle existing selection on/off method.\r\n */\r\n toggleSelection: (value: string) => void;\r\n\r\n /**\r\n * Set internal selections.\r\n */\r\n setSelections: (value: string[]) => void;\r\n\r\n /**\r\n * On click event pass through.\r\n */\r\n onNodeClick?: (data: GraphNode) => void;\r\n\r\n /**\r\n * On canvas click event pass through.\r\n */\r\n onCanvasClick?: (event: MouseEvent) => void;\r\n\r\n /**\r\n * When the lasso happened.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the lasso ended.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n\r\n /**\r\n * When node got a pointer over.\r\n */\r\n onNodePointerOver?: (node: GraphNode) => void;\r\n\r\n /**\r\n * When node lost pointer over.\r\n */\r\n onNodePointerOut?: (node: GraphNode) => void;\r\n}\r\n\r\nexport const useSelection = ({\r\n selections = [],\r\n nodes = [],\r\n actives = [],\r\n focusOnSelect = true,\r\n type = 'single',\r\n pathHoverType = 'out',\r\n pathSelectionType = 'direct',\r\n ref,\r\n hotkeys = ['selectAll', 'deselect', 'delete'],\r\n disabled,\r\n onSelection\r\n}: SelectionProps): SelectionResult => {\r\n const [internalHovers, setInternalHovers] = useState([]);\r\n const [internalActives, setInternalActives] = useState(actives);\r\n const [internalSelections, setInternalSelections] =\r\n useState(selections);\r\n const [metaKeyDown, setMetaKeyDown] = useState(false);\r\n const isMulti = type === 'multi' || type === 'multiModifier';\r\n\r\n const addSelection = useCallback(\r\n (items: string | string[]) => {\r\n if (!disabled && items) {\r\n items = Array.isArray(items) ? items : [items];\r\n\r\n const filtered = items.filter(\r\n item => !internalSelections.includes(item)\r\n );\r\n if (filtered.length) {\r\n const next = [...internalSelections, ...filtered];\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n }\r\n },\r\n [disabled, internalSelections, onSelection]\r\n );\r\n\r\n const removeSelection = useCallback(\r\n (items: string | string[]) => {\r\n if (!disabled && items) {\r\n items = Array.isArray(items) ? items : [items];\r\n\r\n const next = internalSelections.filter(i => !items.includes(i));\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n },\r\n [disabled, internalSelections, onSelection]\r\n );\r\n\r\n const clearSelections = useCallback(\r\n (next: string | string[] = []) => {\r\n if (!disabled) {\r\n next = Array.isArray(next) ? next : [next];\r\n setInternalActives([]);\r\n setInternalSelections(next);\r\n onSelection?.(next);\r\n }\r\n },\r\n [disabled, onSelection]\r\n );\r\n\r\n const toggleSelection = useCallback(\r\n (item: string) => {\r\n const has = internalSelections.includes(item);\r\n if (has) {\r\n removeSelection(item);\r\n } else {\r\n if (!isMulti) {\r\n clearSelections(item);\r\n } else {\r\n addSelection(item);\r\n }\r\n }\r\n },\r\n [\r\n addSelection,\r\n clearSelections,\r\n internalSelections,\r\n isMulti,\r\n removeSelection\r\n ]\r\n );\r\n\r\n const onNodeClick = useCallback(\r\n (data: GraphNode) => {\r\n if (isMulti) {\r\n if (type === 'multiModifier') {\r\n if (metaKeyDown) {\r\n addSelection(data.id);\r\n } else {\r\n clearSelections(data.id);\r\n }\r\n } else {\r\n addSelection(data.id);\r\n }\r\n } else {\r\n clearSelections(data.id);\r\n }\r\n\r\n if (\r\n focusOnSelect === true ||\r\n (focusOnSelect === 'singleOnly' && !metaKeyDown)\r\n ) {\r\n if (!ref.current) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n const graph = ref.current.getGraph();\r\n const { nodes: adjacents } = getAdjacents(\r\n graph,\r\n [data.id],\r\n pathSelectionType\r\n );\r\n\r\n ref.current.fitNodesInView([data.id, ...adjacents], {\r\n fitOnlyIfNodesNotInView: true\r\n });\r\n }\r\n },\r\n [\r\n addSelection,\r\n clearSelections,\r\n focusOnSelect,\r\n isMulti,\r\n metaKeyDown,\r\n pathSelectionType,\r\n ref,\r\n type\r\n ]\r\n );\r\n\r\n const selectNodePaths = useCallback(\r\n (source: string, target: string) => {\r\n const graph = ref.current.getGraph();\r\n if (!graph) {\r\n throw new Error('Graph is not initialized');\r\n }\r\n\r\n const path = findPath(graph, source, target);\r\n clearSelections([source, target]);\r\n\r\n const result = [];\r\n for (let i = 0; i < path.length - 1; i++) {\r\n const from = path[i];\r\n const to = path[i + 1];\r\n const edge = graph.getEdgeAttributes(from, to);\r\n if (edge) {\r\n result.push(edge.id);\r\n }\r\n }\r\n\r\n setInternalActives([...path.map(p => p as string), ...result]);\r\n },\r\n [clearSelections, ref]\r\n );\r\n\r\n const onKeyDown = useCallback((event: KeyboardEvent) => {\r\n const element = event.target as any;\r\n const isSafe =\r\n element.tagName !== 'INPUT' &&\r\n element.tagName !== 'SELECT' &&\r\n element.tagName !== 'TEXTAREA' &&\r\n !element.isContentEditable;\r\n\r\n const isMeta = event.metaKey || event.ctrlKey;\r\n\r\n if (isSafe && isMeta) {\r\n event.preventDefault();\r\n setMetaKeyDown(true);\r\n }\r\n }, []);\r\n\r\n useEffect(() => {\r\n if (typeof window !== 'undefined') {\r\n window.addEventListener('keydown', onKeyDown);\r\n }\r\n\r\n return () => {\r\n if (typeof window !== 'undefined') {\r\n window.removeEventListener('keydown', onKeyDown);\r\n }\r\n };\r\n }, [onKeyDown]);\r\n\r\n const onCanvasClick = useCallback(\r\n (event: MouseEvent) => {\r\n if (\r\n event.button !== 2 &&\r\n (internalSelections.length || internalActives.length)\r\n ) {\r\n clearSelections();\r\n setMetaKeyDown(false);\r\n\r\n // Only re-center if we have a single selection\r\n if (focusOnSelect && internalSelections.length === 1) {\r\n if (!ref.current) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n ref.current.fitNodesInView([], { fitOnlyIfNodesNotInView: true });\r\n }\r\n }\r\n },\r\n [\r\n clearSelections,\r\n focusOnSelect,\r\n internalActives.length,\r\n internalSelections.length,\r\n ref\r\n ]\r\n );\r\n\r\n const onLasso = useCallback((selections: string[]) => {\r\n setInternalActives(selections);\r\n }, []);\r\n\r\n const onLassoEnd = useCallback(\r\n (selections: string[]) => {\r\n clearSelections(selections);\r\n },\r\n [clearSelections]\r\n );\r\n\r\n const onNodePointerOver = useCallback(\r\n (data: GraphNode) => {\r\n if (pathHoverType) {\r\n const graph = ref.current.getGraph();\r\n if (!graph) {\r\n throw new Error('No ref found for the graph canvas.');\r\n }\r\n\r\n const { nodes, edges } = getAdjacents(graph, [data.id], pathHoverType);\r\n setInternalHovers([...nodes, ...edges]);\r\n }\r\n },\r\n [pathHoverType, ref]\r\n );\r\n\r\n const onNodePointerOut = useCallback(() => {\r\n if (pathHoverType) {\r\n setInternalHovers([]);\r\n }\r\n }, [pathHoverType]);\r\n\r\n useEffect(() => {\r\n if (pathSelectionType !== 'direct' && internalSelections.length > 0) {\r\n const graph = ref.current?.getGraph();\r\n if (graph) {\r\n const { nodes, edges } = getAdjacents(\r\n graph,\r\n internalSelections,\r\n pathSelectionType\r\n );\r\n setInternalActives([...nodes, ...edges]);\r\n }\r\n }\r\n }, [internalSelections, pathSelectionType, ref]);\r\n\r\n useHotkeys([\r\n {\r\n name: 'Select All',\r\n keys: 'mod+a',\r\n disabled: !hotkeys.includes('selectAll'),\r\n category: 'Graph',\r\n description: 'Select all nodes and edges',\r\n callback: event => {\r\n event.preventDefault();\r\n\r\n if (!disabled && type !== 'single') {\r\n const next = nodes.map(n => n.id);\r\n onSelection?.(next);\r\n setInternalSelections(next);\r\n }\r\n }\r\n },\r\n {\r\n name: 'Deselect Selections',\r\n category: 'Graph',\r\n disabled: !hotkeys.includes('deselect'),\r\n description: 'Deselect selected nodes and edges',\r\n keys: 'escape',\r\n callback: event => {\r\n if (!disabled) {\r\n event.preventDefault();\r\n onSelection?.([]);\r\n setInternalSelections([]);\r\n }\r\n }\r\n }\r\n ]);\r\n\r\n const joinedActives = useMemo(\r\n () => [...internalActives, ...internalHovers],\r\n [internalActives, internalHovers]\r\n );\r\n\r\n return {\r\n actives: joinedActives,\r\n onNodeClick,\r\n onNodePointerOver,\r\n onNodePointerOut,\r\n onLasso,\r\n onLassoEnd,\r\n selectNodePaths,\r\n onCanvasClick,\r\n selections: internalSelections,\r\n clearSelections,\r\n addSelection,\r\n removeSelection,\r\n toggleSelection,\r\n setSelections: setInternalSelections\r\n };\r\n};\r\n","import React, {\r\n FC,\r\n forwardRef,\r\n ReactNode,\r\n Ref,\r\n Suspense,\r\n useImperativeHandle,\r\n useRef,\r\n useMemo\r\n} from 'react';\r\nimport { Canvas } from '@react-three/fiber';\r\nimport { GraphScene, GraphSceneProps, GraphSceneRef } from './GraphScene';\r\nimport {\r\n CameraMode,\r\n CameraControls,\r\n CameraControlsRef\r\n} from './CameraControls';\r\nimport { Theme, lightTheme } from './themes';\r\nimport { createStore, Provider } from './store';\r\nimport Graph from 'graphology';\r\nimport { Lasso, LassoType } from './selection';\r\nimport ThreeCameraControls from 'camera-controls';\r\nimport css from './GraphCanvas.module.css';\r\n\r\nexport interface GraphCanvasProps extends Omit {\r\n /**\r\n * Theme to use for the graph.\r\n */\r\n theme?: Theme;\r\n\r\n /**\r\n * Type of camera interaction.\r\n */\r\n cameraMode?: CameraMode;\r\n\r\n /**\r\n * The maximum distance for the camera. Default is 50000.\r\n */\r\n maxDistance?: number;\r\n\r\n /**\r\n * The minimum distance for the camera. Default is 1000.\r\n */\r\n minDistance?: number;\r\n\r\n /**\r\n * The type of lasso selection.\r\n */\r\n lassoType?: LassoType;\r\n\r\n /**\r\n * Children to render in the canvas. Useful for things like lights.\r\n */\r\n children?: ReactNode;\r\n\r\n /**\r\n * Ability to extend Cavas gl options. For example { preserveDrawingBuffer: true }\r\n */\r\n glOptions?: Object;\r\n\r\n /**\r\n * When the canvas had a lasso selection.\r\n */\r\n onLasso?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the canvas had a lasso selection end.\r\n */\r\n onLassoEnd?: (selections: string[]) => void;\r\n\r\n /**\r\n * When the canvas was clicked but didn't hit a node/edge.\r\n */\r\n onCanvasClick?: (event: MouseEvent) => void;\r\n}\r\n\r\nexport type GraphCanvasRef = Omit &\r\n Omit & {\r\n /**\r\n * Get the graph object.\r\n */\r\n getGraph: () => Graph;\r\n\r\n /**\r\n * Get the camera controls.\r\n */\r\n getControls: () => ThreeCameraControls;\r\n\r\n /**\r\n * Export the canvas as a data URL.\r\n */\r\n exportCanvas: () => string;\r\n };\r\n\r\nconst GL_DEFAULTS = {\r\n alpha: true,\r\n antialias: true\r\n};\r\n\r\n// TODO: Fix type\r\nconst CAMERA_DEFAULTS: any = {\r\n position: [0, 0, 1000],\r\n near: 5,\r\n far: 50000,\r\n fov: 10\r\n};\r\n\r\nexport const GraphCanvas: FC }> =\r\n forwardRef(\r\n (\r\n {\r\n cameraMode,\r\n edges,\r\n children,\r\n nodes,\r\n theme,\r\n minDistance,\r\n maxDistance,\r\n onCanvasClick,\r\n animated,\r\n disabled,\r\n lassoType,\r\n onLasso,\r\n onLassoEnd,\r\n glOptions,\r\n ...rest\r\n },\r\n ref: Ref\r\n ) => {\r\n const rendererRef = useRef(null);\r\n const controlsRef = useRef(null);\r\n const canvasRef = useRef(null);\r\n\r\n useImperativeHandle(ref, () => ({\r\n centerGraph: (nodeIds, opts) =>\r\n rendererRef.current?.centerGraph(nodeIds, opts),\r\n fitNodesInView: (nodeIds, opts) =>\r\n rendererRef.current?.fitNodesInView(nodeIds, opts),\r\n zoomIn: () => controlsRef.current?.zoomIn(),\r\n zoomOut: () => controlsRef.current?.zoomOut(),\r\n dollyIn: distance => controlsRef.current?.dollyIn(distance),\r\n dollyOut: distance => controlsRef.current?.dollyOut(distance),\r\n panLeft: () => controlsRef.current?.panLeft(),\r\n panRight: () => controlsRef.current?.panRight(),\r\n panDown: () => controlsRef.current?.panDown(),\r\n panUp: () => controlsRef.current?.panUp(),\r\n resetControls: (animated?: boolean) =>\r\n controlsRef.current?.resetControls(animated),\r\n getControls: () => controlsRef.current?.controls,\r\n getGraph: () => rendererRef.current?.graph,\r\n exportCanvas: () => {\r\n rendererRef.current.renderScene();\r\n return canvasRef.current.toDataURL();\r\n }\r\n }));\r\n\r\n // Defaults to pass to the store\r\n const { selections, actives, collapsedNodeIds } = rest;\r\n\r\n // It's pretty hard to get good animation performance with large n of edges/nodes\r\n const finalAnimated =\r\n edges.length + nodes.length > 400 ? false : animated;\r\n\r\n const gl = useMemo(() => ({ ...glOptions, ...GL_DEFAULTS }), [glOptions]);\r\n\r\n // NOTE: The legacy/linear/flat flags are for color issues\r\n // Reference: https://github.com/protectwise/troika/discussions/213#discussioncomment-3086666\r\n return (\r\n
\r\n \r\n \r\n createStore({\r\n selections,\r\n actives,\r\n theme,\r\n collapsedNodeIds,\r\n canvasRef: canvasRef.current\r\n })\r\n }\r\n >\r\n {theme.canvas?.background && (\r\n \r\n )}\r\n \r\n {children}\r\n {theme.canvas?.fog && (\r\n \r\n )}\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n }\r\n );\r\n\r\nGraphCanvas.defaultProps = {\r\n cameraMode: 'pan',\r\n layoutType: 'forceDirected2d',\r\n sizingType: 'default',\r\n labelType: 'auto',\r\n theme: lightTheme,\r\n animated: true,\r\n defaultNodeSize: 7,\r\n minNodeSize: 5,\r\n maxNodeSize: 15,\r\n lassoType: 'none',\r\n glOptions: {}\r\n};\r\n","import classNames from 'classnames';\r\nimport React, { FC, ReactNode } from 'react';\r\nimport css from './RadialSlice.module.css';\r\n\r\nexport interface MenuItem {\r\n /**\r\n * Label to display on the menu item.\r\n */\r\n label: string;\r\n\r\n /**\r\n * CSS Classname to apply to the slice.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * Optional icon to display on the menu item.\r\n */\r\n icon?: ReactNode;\r\n\r\n /**\r\n * Optional callback to detemine if the menu item is active.\r\n */\r\n disabled?: boolean;\r\n\r\n /**\r\n * Optional callback to handle when the menu item is clicked.\r\n */\r\n onClick?: (event: React.MouseEvent) => void;\r\n}\r\n\r\ninterface RadialSliceProps extends MenuItem {\r\n /**\r\n * The starting angle of the radial slice, in degrees.\r\n */\r\n startAngle: number;\r\n\r\n /**\r\n * The ending angle of the radial slice, in degrees.\r\n */\r\n endAngle: number;\r\n\r\n /**\r\n * The skew of the radial slice.\r\n */\r\n skew: number;\r\n\r\n /**\r\n * Whether the radial slice is polar (true) or not (false).\r\n */\r\n polar: boolean;\r\n\r\n /**\r\n * The central angle of the radial slice, in degrees.\r\n */\r\n centralAngle: number;\r\n\r\n /**\r\n * The radius of the radial slice.\r\n */\r\n radius: number;\r\n\r\n /**\r\n * The inner radius of the radial slice.\r\n */\r\n innerRadius: number;\r\n}\r\n\r\nexport const RadialSlice: FC = ({\r\n label,\r\n centralAngle,\r\n startAngle,\r\n endAngle,\r\n polar,\r\n radius,\r\n className,\r\n icon,\r\n innerRadius,\r\n skew,\r\n disabled,\r\n onClick\r\n}) => (\r\n 90 ? '100%' : '50%',\r\n height: centralAngle > 90 ? '100%' : '50%',\r\n bottom: centralAngle > 90 ? '50%' : 'initial',\r\n right: centralAngle > 90 ? '50%' : 'initial',\r\n transform: `rotate(${startAngle + endAngle}deg) skew(${skew}deg)`\r\n }}\r\n onClick={event => {\r\n if (!disabled) {\r\n onClick(event);\r\n }\r\n }}\r\n >\r\n \r\n 90 ? '50% + ' : ''\r\n }${radius}px) - ${innerRadius}px) / 2) - 4em)`\r\n }}\r\n >\r\n \r\n {icon}\r\n {label}\r\n \r\n \r\n \r\n \r\n);\r\n","import { MenuItem } from './RadialSlice';\r\n\r\nexport function calculateRadius(items: MenuItem[], startOffsetAngle: number) {\r\n const centralAngle = 360 / items.length || 360;\r\n const polar = centralAngle % 180 === 0;\r\n const deltaAngle = 90 - centralAngle;\r\n const startAngle = polar\r\n ? 45\r\n : startOffsetAngle + deltaAngle + centralAngle / 2;\r\n\r\n return { centralAngle, polar, startAngle, deltaAngle };\r\n}\r\n","import React, { FC, useLayoutEffect, useMemo, useRef } from 'react';\r\nimport { RadialSlice, MenuItem } from './RadialSlice';\r\nimport { calculateRadius } from './utils';\r\nimport css from './RadialMenu.module.css';\r\nimport classNames from 'classnames';\r\n\r\ninterface RadialMenuProps {\r\n /**\r\n * An array of menu items to be displayed in the radial menu.\r\n */\r\n items: MenuItem[];\r\n\r\n /**\r\n * The radius of the radial menu.\r\n */\r\n radius?: number;\r\n\r\n /**\r\n * The inner radius of the radial menu.\r\n */\r\n innerRadius?: number;\r\n\r\n /**\r\n * The starting offset angle for the first menu item.\r\n */\r\n startOffsetAngle?: number;\r\n\r\n /**\r\n * The CSS class name for the radial menu.\r\n */\r\n className?: string;\r\n\r\n /**\r\n * A function that is called when the radial menu is closed.\r\n * The function receives the mouse event that triggered the closure.\r\n */\r\n onClose?: (event: React.MouseEvent) => void;\r\n}\r\n\r\nexport const RadialMenu: FC = ({\r\n items,\r\n radius,\r\n className,\r\n innerRadius,\r\n startOffsetAngle,\r\n onClose\r\n}) => {\r\n const { centralAngle, polar, startAngle, deltaAngle } = useMemo(\r\n () => calculateRadius(items, startOffsetAngle),\r\n [items, startOffsetAngle]\r\n );\r\n const timeout = useRef(null);\r\n\r\n useLayoutEffect(() => {\r\n const timer = timeout.current;\r\n return () => clearTimeout(timer);\r\n }, []);\r\n\r\n if (items.length === 0) {\r\n return null;\r\n }\r\n\r\n return (\r\n clearTimeout(timeout.current)}\r\n onPointerLeave={event => {\r\n clearTimeout(timeout.current);\r\n timeout.current = setTimeout(() => onClose?.(event), 500);\r\n }}\r\n >\r\n {items.map((slice, index) => (\r\n {\r\n slice?.onClick(event);\r\n onClose?.(event);\r\n }}\r\n />\r\n ))}\r\n \r\n );\r\n};\r\n\r\nRadialMenu.defaultProps = {\r\n radius: 175,\r\n innerRadius: 25,\r\n startOffsetAngle: 0\r\n};\r\n"],"names":["d3ForceRadial","nodes","links","treemap","hierarchy","forceSimulation","forceX","forceY","forceCollide","forceManyBody","forceLink","d3ForceX","d3ForceY","d3ForceSimulation","d3ForceCenter","d3ForceLink","d3ForceManyBody","d3ForceZ","_a","_b","stratify","tree","degreeCentrality","scaleLinear","n","Vector3","QuadraticBezierCurve3","LineCurve3","disabled","useRef","useCallback","useThree","useMemo","Vector2","Plane","useGesture","bidirectional","create","theme","actives","selections","id","node","useEffect","Color","jsx","Billboard","jsxs","RoundedBox","Text","a","useSpring","DoubleSide","Fragment","createContext","useContext","MOUSE","Vector4","Quaternion","Matrix4","Spherical","Box3","Sphere","Raycaster","MathUtils","extend","holdEvent","forwardRef","useFrame","ref","useHotkeys","animated","useImperativeHandle","useState","useLayoutEffect","TextureLoader","LinearFilter","DreiSvg","useCursor","_c","Html","curve","TubeGeometry","Edge","arrowPosition","arrowRotation","Euler","BoxGeometry","CylinderGeometry","mergeBufferGeometries","BufferAttribute","edge","active","inactive","draggingActive","draggingInactive","edgeMeshes","Mesh","SelectionBox","Scene","css","Canvas","Suspense"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAYA,WAAS,cAAc,OAAoB,YAAyB,IAAI;AACtE,UAAM,eAAe,UAAU;AAE/B,eAAW,QAAQ,OAAO;AAClB,YAAA,MAAM,UAAU,QAAQ,IAAI;AAClC,UAAI,MAAM,IAAI;AACZ,cAAM,OAAO,CAAC,GAAG,UAAU,MAAM,GAAG,GAAG,IAAI,EAAE,IAAI,CAAK,MAAA,EAAE,KAAK,EAAE;AAC/D,cAAM,IAAI;AAAA,UACR,+CAA+C,KAAK,KAAK,MAAM,CAAC;AAAA,QAAA;AAAA,MAEpE;AAEI,UAAA,eAAe,KAAK,OAAO;AAC7B,aAAK,QAAQ;AACb,sBAAc,KAAK,KAAK,CAAC,GAAG,WAAW,IAAI,CAAC;AAAA,MAC9C;AAAA,IACF;AAAA,EACF;AAKgB,WAAA,aACd,OACA,OACA;AACA,QAAI,UAAU;AAEd,UAAM,QAAsC,MAAM;AAAA,MAChD,CAAC,KAAK,SAAS;AAAA,QACb,GAAG;AAAA,QACH,CAAC,IAAI,EAAE,GAAG;AAAA,UACR,MAAM;AAAA,UACN,KAAK,CAAC;AAAA,UACN,OAAO;AAAA,UACP,KAAK,CAAC;AAAA,QACR;AAAA,MAAA;AAAA,MAEF,CAAC;AAAA,IAAA;AAGC,QAAA;AACF,iBAAW,QAAQ,OAAO;AACxB,cAAM,OAAO,KAAK;AAClB,cAAM,KAAK,KAAK;AAEhB,YAAI,CAAC,MAAM,eAAe,IAAI,GAAG;AAC/B,gBAAM,IAAI,MAAM,uBAAuB,IAAI,EAAE;AAAA,QAC/C;AAEA,YAAI,CAAC,MAAM,eAAe,EAAE,GAAG;AAC7B,gBAAM,IAAI,MAAM,uBAAuB,EAAE,EAAE;AAAA,QAC7C;AAEM,cAAA,aAAa,MAAM,IAAI;AACvB,cAAA,aAAa,MAAM,EAAE;AAChB,mBAAA,IAAI,KAAK,UAAU;AACnB,mBAAA,IAAI,KAAK,UAAU;AAAA,MAChC;AAEc,oBAAA,OAAO,OAAO,KAAK,CAAC;AAAA,aAC3B,GAAG;AACA,gBAAA;AAAA,IACZ;AAEM,UAAA,YAAY,OAAO,KAAK,KAAK,EAAE,IAAI,CAAM,OAAA,MAAM,EAAE,EAAE,KAAK;AAC9D,UAAM,WAAW,KAAK,IAAI,GAAG,SAAS;AAE/B,WAAA;AAAA,MACL;AAAA,MACA,QAAQ;AAAA,MACR,UAAU,YAAY;AAAA,IAAA;AAAA,EAE1B;ACjFA,QAAM,UAAqB,CAAC,YAAY,WAAW;AAuB5C,WAAS,YAAY;AAAA,IAC1B;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,iBAAiB;AAAA,EACnB,GAAsB;AACpB,UAAM,EAAE,QAAQ,UAAU,QAAY,IAAA,aAAa,OAAO,KAAK;AAE/D,QAAI,SAAS;AACJ,aAAA;AAAA,IACT;AAEA,UAAM,eAAe,QAAQ,SAAS,IAAI,IAAI,IAAI;AAClD,UAAM,mBACH,MAAM,SAAS,WAAY,iBAAiB;AAE/C,QAAI,MAAM;AACR,YAAM,SACJ,CAAC,KAAc,WAAoB,CAAC,SAClC,CAAC,MACG,UACC,OAAO,KAAK,EAAE,EAAE,QAAQ,WAAW,KACpC,oBACC,SAAS,KAAK;AAEjB,YAAA,OAAO,OAAO,CAAC,MAAM,IAAI,EAAE,SAAS,IAAI,GAAG,SAAS,IAAI;AACxD,YAAA,OAAO,OAAO,CAAC,MAAM,IAAI,EAAE,SAAS,IAAI,GAAG,SAAS,IAAI;AACxD,YAAA,OAAO,OAAO,CAAC,OAAO,MAAM,EAAE,SAAS,IAAI,GAAG,SAAS,MAAM;AAEnE,YAAM,QAAQ,CAAQ,SAAA;AACf,aAAA,KAAK,KAAK,IAAI;AACd,aAAA,KAAK,KAAK,IAAI;AACd,aAAA,KAAK,KAAK,IAAI;AAAA,MAAA,CACpB;AAAA,IACH;AAEA,WAAO,QAAQ,SAAS,IAAI,IACxBA,sBAAc,CAAQ,SAAA;AAChB,YAAA,YAAY,OAAO,KAAK,EAAE;AAChC,YAAM,QACF,SAAS,aAAa,WAAW,UAAU,QAAQ,UAAU;AACjE,aAAO,QAAQ;AAAA,IAChB,CAAA,EAAE,SAAS,CAAC,IACX;AAAA,EACN;AChEO,WAAS,KAAK,QAAwB;AAC3C,WAAO,IAAI,QAAQ,CAAC,SAAS,YAAY;AACnC,UAAA;AAEJ,eAAS,MAAM;AACb,YAAI,CAAC,QAAQ;AACX,mBAAS,OAAO;AACZ;QAAA,OACC;AACL,kBAAQ,MAAM;AAAA,QAChB;AAAA,MACF;AAEI;IAAA,CACL;AAAA,EACH;AAMO,WAAS,eAAe,OAAc;AAC3C,UAAM,QAA6B,CAAA;AACnC,UAAM,QAA6B,CAAA;AAE7B,UAAA,YAAY,CAAC,IAAI,MAAW;AAChC,YAAM,KAAK;AAAA,QACT,GAAG;AAAA,QACH;AAAA;AAAA,QAEA,QAAQ,EAAE,QAAQ;AAAA,MAAA,CACnB;AAAA,IAAA,CACF;AAEK,UAAA,YAAY,CAAC,IAAI,MAAW;AAChC,YAAM,KAAK,EAAE,GAAG,GAAG,GAAI,CAAA;AAAA,IAAA,CACxB;AAEM,WAAA,EAAE,OAAO;EAClB;ACzBO,WAAS,cAAc;AAEtB,UAAA,WAAW,CAAC,MAAW,MAAM;AAC7B,UAAA,QAAQ,CAAC,MAAW,EAAE;AAG5B,QAAI,KAAK;AACT,QAAI,QAAQ,CAAA;AACZ,QAAI,QAAQ,CAAA;AACR,QAAA;AACA,QAAA,OAAO,CAAC,KAAK,GAAG;AAChB,QAAA,gBAAgB,SAAS,CAAC;AAC1B,QAAA,cAAc,SAAS,EAAE;AACzB,QAAA,oBAAoB,SAAS,GAAG;AAChC,QAAA,oBAAoB,SAAS,GAAG;AACpC,QAAI,OAAO,CAAA;AACX,QAAI,2BAA2B;AAC/B,QAAI,2BAA2B;AAC/B,QAAI,gBAAgB,CAAA;AAChB,QAAA,SAAS,CAAC,GAAG,CAAC;AACd,QAAA;AACA,QAAA,UAAU,OAAK,EAAE;AACrB,QAAI,WAAW;AACf,QAAI,iBAAiB;AACrB,QAAI,WAAW;AAEf,aAAS,MAAM,OAAO;AACpB,UAAI,CAAC,gBAAgB;AACZ,eAAA;AAAA,MACT;AAEA,UAAI,aAAa,SAAS;AAExB,sBAAc,KAAK;AACE;MACvB;AAEA,eAAS,IAAI,GAAG,IAAI,MAAM,QAAQ,MAAM,IAAI,QAAQ,UAAU,IAAI,GAAG,EAAE,GAAG;AACxE,eAAO,MAAM,CAAC;AACT,aAAA,OAAO,KAAK,QAAQ,IAAI,CAAC,EAAE,IAAI,KAAK,KAAK;AACzC,aAAA,OAAO,KAAK,QAAQ,IAAI,CAAC,EAAE,IAAI,KAAK,KAAK;AAAA,MAChD;AAAA,IACF;AAEA,aAAS,aAAa;AACpB,UAAI,CAAC,OAAO;AACV;AAAA,MACF;AAEA,UAAI,aAAa,WAAW;AACJ;MAAA,OACjB;AACe;MACtB;AAAA,IACF;AAEM,UAAA,aAAa,SAAU,GAAG;AACtB,cAAA;AACG;IAAA;AAGb,aAAS,WAAW,GAAG;AACjB,UAAA,WAAW,QAAQ,EAAE,MAAM,GAC7B,WAAW,QAAQ,EAAE,MAAM;AAE7B,aAAO,YAAY,WACf,WAAW,MAAM,WACjB,WAAW,MAAM;AAAA,IACvB;AAEA,aAAS,0BAA0BC,QAAO;AACxC,UAAI,iBAAiB,oBAAI,OACvB,WAAgB,CAAA;AAElBA,aAAM,QAAQ,SAAU,GAAG;AACzB,YAAI,CAAC,eAAe,IAAI,QAAQ,CAAC,CAAC,GAAG;AACpB,yBAAA,IAAI,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,kBAAkB,EAAA,CAAG;AAAA,QAClE;AAAA,MAAA,CACD;AAEDA,aAAM,QAAQ,SAAU,GAAG;AACzB,mBAAW,eAAe,IAAI,QAAQ,CAAC,CAAC;AAC/B,iBAAA,QAAQ,SAAS,QAAQ;AAClC,iBAAS,mBACP,SAAS;AAAA,QAET,KAAK,MAAM,cAAc,CAAC,IAAI,cAAc,CAAC,KAAK;AACpD,uBAAe,IAAI,QAAQ,CAAC,GAAG,QAAQ;AAAA,MAAA,CACxC;AAEM,aAAA;AAAA,IACT;AAGA,aAAS,0BAA0BC,QAAO;AACxC,UAAI,gBAAgB,oBAAI,OACtB,eAAe,CAAA;AAEjBA,aAAM,QAAQ,SAAU,GAAG;AACrB,YAAA,MAAM,WAAW,CAAC,GACpB;AACE,YAAA,cAAc,IAAI,GAAG,GAAG;AAClB,kBAAA,cAAc,IAAI,GAAG;AAAA,QAAA,OACxB;AACG,kBAAA;AAAA,QACV;AACS,iBAAA;AACK,sBAAA,IAAI,KAAK,KAAK;AAAA,MAAA,CAC7B;AAEa,oBAAA,QAAQ,SAAU,OAAO,KAAK;AAC1C,YAAI,QAAQ;AACZ,iBAAS,IAAI,MAAM,GAAG,EAAE,CAAC;AACzB,iBAAS,IAAI,MAAM,GAAG,EAAE,CAAC;AACrB,YAAA,WAAW,UAAa,WAAW,QAAW;AAChD,uBAAa,KAAK;AAAA,YAChB;AAAA,YACA;AAAA,YACA,OAAO;AAAA,UAAA,CACR;AAAA,QACH;AAAA,MAAA,CACD;AAEM,aAAA;AAAA,IACT;AAGA,aAAS,iBAAiB;AACxB,UAAI,SAAS,CAAA;AACb,UAAI,SAAS,CAAA;AACT,UAAA,6BAAa;AACb,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AACA,UAAA;AAEJ,uBAAiB,0BAA0B,KAAK;AAChD,sBAAgB,0BAA0B,KAAK;AAE1C,WAAA,KAAK,eAAe,QAAQ;AAC1B,aAAA,eAAe,IAAI,CAAC;AACzB,eAAO,KAAK;AAAA,UACV,IAAI;AAAA,UACJ,MAAM,GAAG;AAAA,UACT,GAAG,KAAK,KAAK,GAAG,mBAAmB,KAAK,EAAE;AAAA,QAAA,CAC3C;AACM,eAAA,IAAI,GAAG,CAAC;AAAA,MACjB;AAEc,oBAAA,QAAQ,SAAU,GAAG;AAC7B,YAAA,SAAS,OAAO,IAAI,EAAE,MAAM,GAC9B,SAAS,OAAO,IAAI,EAAE,MAAM;AAC1B,YAAA,WAAW,UAAa,WAAW,QAAW;AAChD,iBAAO,KAAK;AAAA,YACV;AAAA,YACA;AAAA,YACA,OAAO,EAAE;AAAA,UAAA,CACV;AAAA,QACH;AAAA,MAAA,CACD;AAED,aAAO,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,IACxC;AAEA,aAAS,gBAAgB;AACvB,UAAI,WAAW,CAAA;AACX,UAAA;AACA,UAAA;AACA,UAAA;AAGa,uBAAA,0BAA0B,MAAM,MAAO,CAAA;AAEnD,WAAA,KAAK,eAAe,QAAQ;AAC1B,aAAA,eAAe,IAAI,CAAC;AACzB,iBAAS,KAAK,EAAE,IAAI,GAAG,MAAM,GAAG,OAAO;AAAA,MACzC;AACO,aAAA,EAAE,IAAI,gBAAgB;IAC/B;AAEA,aAAS,uBAAuB;AAG9B,WAAK,OAAO,EAAE,GAAG,GAAG,GAAG;AACT,oBAAA,QAAQ,SAAU,GAAG;AACjC,YAAI,aAAa,WAAW;AACrB,eAAA,EAAE,KAAK,EAAE,IAAI;AAAA,YAChB,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,OAAO,CAAC;AAAA,YACtC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,IAAI,OAAO,CAAC;AAAA,UAAA;AAAA,QACxC,OACK;AACA,eAAA,EAAE,EAAE,IAAI;AAAA,YACX,GAAG,EAAE,IAAI,OAAO,CAAC;AAAA,YACjB,GAAG,EAAE,IAAI,OAAO,CAAC;AAAA,UAAA;AAAA,QAErB;AAAA,MAAA,CACD;AACM,aAAA;AAAA,IACT;AAEA,aAAS,wBAAwB;AAE/B,UAAI,MAAMC,YAAAA,QAAQ,EAAE,KAAK,MAAM,MAAM;AAErC,aAAOC,YAAAA,UAAU,eAAe,EAC7B,IAAI,CAAC,MAAW,EAAE,MAAM,EACxB,KAAK,SAAU,GAAG,GAAG;AACpB,eAAO,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE;AAAA,MAAA,CAC3C;AAEa,sBAAA,IAAI,IAAI,EAAE,OAAO;AACZ;IACvB;AAEA,aAAS,sBAAsB;AAE7B,UAAI,YAAY;AAChB,UAAI,MAAM,WAAW;AAAG;AAElB,YAAA,QAAQ,SAAU,MAAM;AAC5B,YAAI,QAAQ;AACZ,YAAI,CAAC,OAAO;AACV;AAAA,QACF;AAEA,iBAAS,KAAK;AACd,iBAAS,KAAK;AAEV,YAAA,OAAO,KAAK,WAAW,UAAU;AACnC,mBAAS,MAAM,KAAK,CAAA,MAAK,EAAE,OAAO,KAAK,MAAM;AAAA,QAC/C;AAEI,YAAA,OAAO,KAAK,WAAW,UAAU;AACnC,mBAAS,MAAM,KAAK,CAAA,MAAK,EAAE,OAAO,KAAK,MAAM;AAAA,QAC/C;AAEI,YAAA,WAAW,UAAa,WAAW,QAAW;AAC1C,gBAAA;AAAA,YACJ;AAAA,UAAA;AAAA,QAEJ;AACA,aAAK,SAAS;AACd,aAAK,SAAS;AACd,aAAK,QAAQ;AAAA,MAAA,CACd;AAAA,IACH;AAEA,aAAS,sBAAsB;AACzB,UAAA;AAEJ,UAAI,CAAC,SAAS,CAAC,MAAM,QAAQ;AAC3B;AAAA,MACF;AAEoB;AAEpB,YAAM,eAAe;AACL,sBAAAC,UAAAA,gBAAgB,IAAI,KAAK,EACtC,MAAM,KAAKC,iBAAO,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,CAAC,EAC5C,MAAM,KAAKC,UAAA,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,CAAC,EAC5C,MAAM,WAAWC,uBAAa,CAAA,MAAK,EAAE,CAAC,EAAE,WAAW,CAAC,CAAC,EACrD,MAAM,UAAUC,0BAAgB,SAAS,WAAW,CAAC,EACrD;AAAA,QACC;AAAA,QACAC,UAAAA,UAAU,IAAI,MAAM,SAAS,IAAI,QAAQ,CAAE,CAAA,EACxC,SAAS,iBAAiB,EAC1B,SAAS,iBAAiB;AAAA,MAAA;AAGjC,sBAAgB,cAAc;AAET;IACvB;AAEM,UAAA,WAAW,SAAU,GAAG;AACxB,UAAA,CAAC,UAAU,QAAQ;AACd,eAAA;AAAA,MACT;AAEW,iBAAA;AACA;AACJ,aAAA;AAAA,IAAA;AAGH,UAAA,UAAU,SAAU,GAAG;AACvB,UAAA,CAAC,UAAU,QAAQ;AACd,eAAA;AAAA,MACT;AAEI,UAAA,OAAO,MAAM,UAAU;AACzB,kBAAU,SAAU,GAAG;AACrB,iBAAO,EAAE,CAAC;AAAA,QAAA;AAGL,eAAA;AAAA,MACT;AAEU,gBAAA;AAEH,aAAA;AAAA,IAAA;AAGH,UAAA,iBAAiB,SAAU,GAAG;AAC9B,UAAA,CAAC,UAAU,QAAQ;AACd,eAAA;AAAA,MACT;AAEiB,uBAAA;AAEV,aAAA;AAAA,IAAA;AAGH,UAAA,WAAW,SAAU,GAAG;AACxB,UAAA,CAAC,UAAU,QAAQ;AACd,eAAA;AAAA,MACT;AAEW,iBAAA;AAEJ,aAAA;AAAA,IAAA;AAGH,UAAA,kBAAkB,SAAU,GAAG;AACnC,UAAI,gBAAgB;AAClB,YAAI,QAAQ,EAAE,MAAM,MAAM,QAAQ,EAAE,MAAM,GAAG;AACvC,cAAA,OAAO,6BAA6B,YAAY;AAElD,mBAAO,yBAAyB,CAAC;AAAA,UAAA,OAC5B;AACE,mBAAA;AAAA,UACT;AAAA,QAAA,OACK;AACD,cAAA,OAAO,6BAA6B,YAAY;AAElD,mBAAO,yBAAyB,CAAC;AAAA,UAAA,OAC5B;AACE,mBAAA;AAAA,UACT;AAAA,QACF;AAAA,MAAA,OACK;AAED,YAAA,OAAO,6BAA6B,YAAY;AAElD,iBAAO,yBAAyB,CAAC;AAAA,QAAA,OAC5B;AACE,iBAAA;AAAA,QACT;AAAA,MACF;AAAA,IAAA;AAGI,UAAA,KAAK,SAAU,GAAG;AACtB,aAAO,UAAU,UAAW,KAAK,GAAI,SAAS;AAAA,IAAA;AAG1C,UAAA,OAAO,SAAU,GAAG;AACxB,aAAO,UAAU,UAAW,OAAO,GAAI,SAAS;AAAA,IAAA;AAG5C,UAAA,2BAA2B,SAAU,GAAG;AAC5C,aAAO,UAAU,UACX,2BAA2B,GAAI,SACjC;AAAA,IAAA;AAGA,UAAA,2BAA2B,SAAU,GAAG;AAC5C,aAAO,UAAU,UACX,2BAA2B,GAAI,SACjC;AAAA,IAAA;AAGA,UAAA,QAAQ,SAAU,GAAG;AACzB,aAAO,UAAU,UAAW,QAAQ,GAAI,SAAS;AAAA,IAAA;AAG7C,UAAA,QAAQ,SAAU,GAAG;AACrB,UAAA,CAAC,UAAU,QAAQ;AACd,eAAA;AAAA,MACT;AAEA,UAAI,MAAM,MAAM;AACd,gBAAQ,CAAA;AAAA,MAAC,OACJ;AACG,gBAAA;AAAA,MACV;AAEW;AAEJ,aAAA;AAAA,IAAA;AAGH,UAAA,WAAW,SAAU,GAAG;AACxB,UAAA,CAAC,UAAU,QAAQ;AACd,eAAA;AAAA,MACT;AAEW,iBAAA;AACA;AACJ,aAAA;AAAA,IAAA;AAGH,UAAA,gBAAgB,SAAU,GAAG;AACjC,aAAO,UAAU,UACX,gBAAgB,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,CAAC,GAC7D,WAAA,GACA,SACE;AAAA,IAAA;AAIN,UAAM,WAAW,MAAM;AAEjB,UAAA,cAAc,SAAU,GAAG;AAC/B,aAAO,UAAU,UACX,cAAc,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,CAAC,GAC3D,WAAA,GACA,SACE;AAAA,IAAA;AAGA,UAAA,oBAAoB,SAAU,GAAG;AACrC,aAAO,UAAU,UACX,oBAAoB,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,CAAC,GACjE,WAAA,GACA,SACE;AAAA,IAAA;AAGA,UAAA,oBAAoB,SAAU,GAAG;AACrC,aAAO,UAAU,UACX,oBAAoB,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,CAAC,GACjE,WAAA,GACA,SACE;AAAA,IAAA;AAGA,UAAA,SAAS,SAAU,GAAG;AACnB,aAAA,UAAU,UACX,SAAS,OAAO,MAAM,aAAa,IAAI,SAAS,CAAC,CAAC,GAAI,SACxD;AAAA,IAAA;AAGN,UAAM,WAAW;AAEV,WAAA;AAAA,EACT;AC1XO,WAAS,cAAc;AAAA,IAC5B;AAAA,IACA,iBAAiB;AAAA,IACjB,OAAO;AAAA,IACP,aAAa;AAAA,IACb,eAAe;AAAA,IACf,eAAe;AAAA,IACf,kBAAkB;AAAA,IAClB,2BAA2B;AAAA,IAC3B,2BAA2B;AAAA,IAC3B,oBAAoB;AAAA,IACpB,oBAAoB;AAAA,IACpB,cAAc;AAAA,IACd,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAA8C;AAC5C,UAAM,EAAE,OAAO,MAAM,IAAI,eAAe,KAAK;AAG7C,UAAM,OAAO,eAAe;AAC5B,UAAM,yBACJ,QAAQ,MAAM,SAAS,KAAK,eAAe,IAAI;AAE7C,QAAA;AACA,QAAA;AACJ,QAAI,gBAAgB,mBAAmB;AACrC,eAASC,UAAS,OAAA;AAClB,eAASC,UAAS,OAAA;AAAA,IAAA,OACb;AACL,eAASD,UAAAA,OAAS,GAAG,EAAE,SAAS,IAAI;AACpC,eAASC,UAAAA,OAAS,GAAG,EAAE,SAAS,IAAI;AAAA,IACtC;AAGA,UAAM,MAAMC,UAAAA,gBACT,EAAA,MAAM,UAAUC,UAAc,YAAA,GAAG,CAAC,CAAC,EACnC,MAAM,QAAQC,UAAY,UAAA,CAAC,EAC3B,MAAM,UAAUC,UAAgB,cAAA,EAAE,SAAS,sBAAsB,CAAC,EAClE,MAAM,KAAK,MAAM,EACjB,MAAM,KAAK,MAAM,EACjB,MAAM,KAAKC,UAAAA,OAAU,CAAA,EAErB;AAAA,MACC;AAAA,MACAT,UAAAA,aAAa,CAAA,MAAK,EAAE,SAAS,EAAE;AAAA,IAAA,EAEhC;AAAA,MACC;AAAA,MACA,YAAY;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA,CACD;AAAA,MAEF,KAAK;AAEJ,QAAA;AACJ,QAAI,kBAAkB;AAEpB,UAAI,wBAAwB;AAC5B,UAAI,+BAAO,QAAQ;AACjB,cAAM,mBAAmB,KAAK,KAAK,MAAM,SAAS,GAAG;AACrD,gCAAwB,cAAc;AAAA,MACxC;AAEA,sBAAgB,YAEb,EAAA,SAAS,eAAe,EAExB,SAAS,WAAW,EAEpB,QAAQ,OAAK,EAAE,KAAK,gBAAgB,CAAC,EAErC,MAAM,KAAK,EAEX,KAAK,CAAC,KAAK,GAAG,CAAC,EAEf,yBAAyB,wBAAwB,EAEjD,yBAAyB,wBAAwB,EAEjD,kBAAkB,iBAAiB,EAEnC,kBAAkB,iBAAiB,EAEnC,YAAY,qBAAqB,EAEjC,cAAc,CAAA,MAAK,EAAE,MAAM;AAAA,IAChC;AAGA,QAAI,SAAS,IAAI,cAAc,UAAU,EAAE,MAAM,KAAK;AAEtD,QAAI,eAAe;AACR,eAAA,OAAO,MAAM,SAAS,aAAa;AAAA,IAC9C;AAGA,QAAI,cAAc;AACZ,UAAA,YAAY,OAAO,MAAM,MAAM;AACnC,UAAI,WAAW;AAEV,kBAAA,GAAG,OAAK,EAAE,EAAE,EACZ,MAAM,KAAK,EAGX,SAAS,YAAY;AAExB,YAAI,eAAe;AACjB,sBAAY,UAAU,UAAS,+CAAe,oBAAmB,GAAG;AAAA,QACtE;AAAA,MACF;AAAA,IACF;AAEM,UAAA,UAAU,IAAI,IAAI,MAAM,IAAI,CAAK,MAAA,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;AAE1C,WAAA;AAAA,MACL,OAAO;AAEE,eAAA,IAAI,MAAM,IAAI,MAAM;AACzB,cAAI,KAAK;AAAA,QACX;AACO,eAAA;AAAA,MACT;AAAA,MACA,gBAAgB,IAAY;;AAC1B,YAAI,iBAAiB;AACb,gBAAA,MAAM,gBAAgB,IAAI,EAAE,OAAO,OAAO,OAAO,OAAO;AAC9D,cAAI,KAAK;AACA,mBAAA;AAAA,UACT;AAAA,QACF;AAEI,aAAAU,MAAA,+BAAQ,QAAR,gBAAAA,IAAa,UAAU;AAElB,kBAAAC,MAAA,+BAAQ,QAAR,gBAAAA,IAAa;AAAA,QACtB;AAEO,eAAA,QAAQ,IAAI,EAAE;AAAA,MACvB;AAAA,IAAA;AAAA,EAEJ;AC7NO,WAAS,WAAW;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAyB;AACjB,UAAA,SAAS,SAAS,OAAO;AAAA,MAC7B,OAAO;AAAA,IAAA,CACR;AAED,UAAM,EAAE,OAAO,MAAM,IAAI,eAAe,KAAK;AAEtC,WAAA;AAAA,MACL,OAAO;AACE,eAAA;AAAA,MACT;AAAA,MACA,gBAAgB,IAAY;;AAC1B,YAAI,iBAAiB;AACb,gBAAA,MAAM,gBAAgB,IAAI,EAAE,OAAO,OAAO,OAAO,OAAO;AAC9D,cAAI,KAAK;AACA,mBAAA;AAAA,UACT;AAAA,QACF;AAEI,aAAAD,MAAA,+BAAQ,QAAR,gBAAAA,IAAa,UAAU;AAElB,kBAAAC,MAAA,+BAAQ,QAAR,gBAAAA,IAAa;AAAA,QACtB;AAEA,eAAO,iCAAS;AAAA,MAClB;AAAA,IAAA;AAAA,EAEJ;ACtBA,QAAM,gBAAgB;AAAA,IACpB,IAAI;AAAA,MACF,GAAG;AAAA,MACH,GAAG;AAAA,MACH,QAAQ;AAAA,IACV;AAAA,IACA,IAAI;AAAA,MACF,GAAG;AAAA,MACH,GAAG;AAAA,MACH,QAAQ;AAAA,IACV;AAAA,EACF;AAEO,WAAS,aAAa;AAAA,IAC3B;AAAA,IACA;AAAA,IACA,OAAO;AAAA,IACP,iBAAiB;AAAA,IACjB,WAAW,CAAC,IAAI,EAAE;AAAA,IAClB;AAAA,EACF,GAA6C;AAC3C,UAAM,EAAE,OAAO,MAAM,IAAI,eAAe,KAAK;AAG7C,UAAM,cAAc,MAAM,OAAO,CAAA,MAAK,CAAC,MAAM,KAAK,CAAA,MAAK,EAAE,WAAW,EAAE,EAAE,CAAC;AACjE,YAAA,IAAI,eAAe,WAAW;AAIlC,QAAA,YAAY,SAAS,GAAG;AAC1B,YAAM,eAAkC;AAAA,QACtC,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,MAAM;AAAA,QACN,YAAY;AAAA,QACZ,MAAM;AAAA,QACN,MAAM;AAAA,UACJ,IAAI;AAAA,UACJ,QAAQ;AAAA,UACR,OAAO;AAAA,YACL,IAAI;AAAA,YACJ,YAAY,CAAC;AAAA,YACb,QAAQ,CAAC;AAAA,UACX;AAAA,UACA,WAAW;AAAA,UACX,OAAO;AAAA,YACL,OAAO;AAAA,UACT;AAAA,QACF;AAAA,QACA,UAAU;AAAA,UACR,IAAI;AAAA,UACJ,MAAM,CAAC;AAAA,UACP,OAAO,CAAC;AAAA,UACR,OAAO;AAAA,UACP,GAAG;AAAA,UACH,GAAG;AAAA,UACH,GAAG;AAAA,UACH,IAAI;AAAA,UACJ,IAAI;AAAA,QACN;AAAA,MAAA;AAIF,YAAM,KAAK,YAAY;AAGvB,kBAAY,QAAQ,CAAK,MAAA;AACvB,cAAM,KAAK;AAAA,UACT,IAAI,YAAY,EAAE,EAAE;AAAA,UACpB,QAAQ;AAAA,UACR,QAAQ,EAAE;AAAA,UACV,OAAO;AAAA,UACP,iBAAiB;AAAA,QAAA,CAClB;AAAA,MAAA,CACF;AAAA,IACH;AAEA,UAAM,EAAE,OAAW,IAAA,aAAa,OAAO,KAAK;AACtC,UAAA,YAAY,OAAO,KAAK,MAAM,EAAE,IAAI,CAAA,MAAK,OAAO,CAAC,CAAC;AAExD,UAAM,OAAOC,YAAoB,SAAA,EAC9B,GAAG,CAAK,MAAA,EAAE,KAAK,EAAE,EACjB,SAAS,CAAA,MAAA;;AAAK,oBAAAD,OAAAD,MAAA,EAAE,QAAF,gBAAAA,IAAQ,OAAR,gBAAAC,IAAY,SAAZ,mBAAkB;AAAA,KAAE,EAAE,SAAS;AAEhD,UAAM,WAAWE,YAAAA,OACd,WAAW,MAAM,cAAc,EAC/B,SAAS,QAAQ,EAAEjB,sBAAU,IAAI,CAAC;AAE/B,UAAA,YAAY,SAAS;AACrB,UAAA,OAAO,cAAc,IAAI;AAE/B,UAAM,cAAc,IAAI;AAAA,MACtB,MAAM,IAAI,CAAK,MAAA;AACb,cAAM,EAAE,GAAG,MAAM,UAAU,KAAK,CAAC,MAAW,EAAE,KAAK,OAAO,EAAE,EAAE;AACvD,eAAA;AAAA,UACL,EAAE;AAAA,UACF;AAAA,YACE,GAAG;AAAA,YACH,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK;AAAA,YACnB,CAAC,KAAK,CAAC,GAAG,IAAI,KAAK;AAAA,YACnB,GAAG;AAAA,UACL;AAAA,QAAA;AAAA,MACF,CACD;AAAA,IAAA;AAGI,WAAA;AAAA,MACL,OAAO;AACE,eAAA;AAAA,MACT;AAAA,MACA,gBAAgB,IAAY;;AAC1B,YAAI,iBAAiB;AACb,gBAAA,MAAM,gBAAgB,IAAI,EAAE,OAAO,OAAO,OAAO,OAAO;AAC9D,cAAI,KAAK;AACA,mBAAA;AAAA,UACT;AAAA,QACF;AAEI,aAAAc,MAAA,+BAAQ,QAAR,gBAAAA,IAAa,UAAU;AAElB,kBAAAC,MAAA,+BAAQ,QAAR,gBAAAA,IAAa;AAAA,QACtB;AAEO,eAAA,YAAY,IAAI,EAAE;AAAA,MAC3B;AAAA,IAAA;AAAA,EAEJ;ACzHO,WAAS,UAAU;AAAA,IACxB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAA0B;AACxB,UAAM,EAAE,OAAO,MAAM,IAAI,eAAe,KAAK;AAEvC,UAAA,SAAS,eAAe,OAAO;AAAA,MACnC;AAAA,MACA,cAAc,CAAC,MAAM,UAAU;AAAA,QAC7B,GAAG;AAAA;AAAA,QAEH,GAAG,KAAK,KAAK;AAAA,QACb,GAAG,KAAK,KAAK;AAAA,MAAA;AAAA,MAEf,UAAU;AAAA,QACR;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA,CACD;AAEM,WAAA;AAAA,MACL,OAAO;AACE,eAAA;AAAA,MACT;AAAA,MACA,gBAAgB,IAAY;;AAC1B,YAAI,iBAAiB;AACb,gBAAA,MAAM,gBAAgB,IAAI,EAAE,OAAO,OAAO,OAAO,OAAO;AAC9D,cAAI,KAAK;AACA,mBAAA;AAAA,UACT;AAAA,QACF;AAEI,aAAAD,MAAA,+BAAQ,QAAR,gBAAAA,IAAa,UAAU;AAElB,kBAAAC,MAAA,+BAAQ,QAAR,gBAAAA,IAAa;AAAA,QACtB;AAEA,eAAO,iCAAS;AAAA,MAClB;AAAA,IAAA;AAAA,EAEJ;ACRO,WAAS,YAAY;AAAA,IAC1B;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,GAA4B;AAI1B,WAAO,OAAO,KAAK;AAEb,UAAA,SAAS,kBAAkB,OAAO;AAAA,MACtC;AAAA,MACA,UAAU;AAAA,IAAA,CACX;AAEM,WAAA;AAAA,MACL,OAAO;AACE,eAAA;AAAA,MACT;AAAA,MACA,gBAAgB,IAAY;;AAE1B,iBAAQD,MAAA,+BAAQ,QAAR,gBAAAA,IAAa,cAAoB,iCAAS;AAAA,MACpD;AAAA,IAAA;AAAA,EAEJ;ACtFO,WAAS,OAAO,EAAE,OAAO,OAAO,mBAAuC;AAC5E,UAAM,EAAE,OAAO,MAAM,IAAI,eAAe,KAAK;AAEtC,WAAA;AAAA,MACL,OAAO;AACE,eAAA;AAAA,MACT;AAAA,MACA,gBAAgB,IAAY;AAC1B,eAAO,gBAAgB,IAAI,EAAE,OAAO,OAAO,OAAO,OAAO;AAAA,MAC3D;AAAA,IAAA;AAAA,EAEJ;ACAO,QAAM,gBAAgB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEO,WAAS,eAAe;AAAA,IAC7B;AAAA,IACA,GAAG;AAAA,EACL,GAAyD;AACnD,QAAA,cAAc,SAAS,IAAI,GAAG;AAChC,YAAM,EAAE,cAAc,cAAc,eAAA,IAClC;AAEF,UAAI,SAAS,mBAAmB;AAC9B,eAAO,cAAc;AAAA,UACnB,GAAG;AAAA,UACH,YAAY;AAAA,UACZ,gBAAgB,kBAAkB;AAAA,UAClC,cAAc,gBAAgB;AAAA,UAC9B;AAAA,UACA,aAAa;AAAA,QAAA,CACe;AAAA,MAAA,WACrB,SAAS,YAAY;AAC9B,eAAO,cAAc;AAAA,UACnB,GAAG;AAAA,UACH,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,gBAAgB,kBAAkB;AAAA,UAClC,cAAc,gBAAgB;AAAA,UAC9B,cAAc,gBAAgB;AAAA,UAC9B,aAAa;AAAA,QAAA,CACe;AAAA,MAAA,WACrB,SAAS,YAAY;AAC9B,eAAO,cAAc;AAAA,UACnB,GAAG;AAAA,UACH,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,gBAAgB,kBAAkB;AAAA,UAClC,cAAc,gBAAgB;AAAA,UAC9B,cAAc,gBAAgB;AAAA,UAC9B,aAAa;AAAA,QAAA,CACe;AAAA,MAAA,WACrB,SAAS,eAAe;AACjC,eAAO,cAAc;AAAA,UACnB,GAAG;AAAA,UACH,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,gBAAgB,kBAAkB;AAAA,UAClC,cAAc,gBAAgB;AAAA,UAC9B,cAAc,gBAAgB;AAAA,UAC9B,aAAa;AAAA,QAAA,CACe;AAAA,MAAA,WACrB,SAAS,YAAY;AAC9B,eAAO,cAAc;AAAA,UACnB,GAAG;AAAA,UACH,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,gBAAgB,kBAAkB;AAAA,UAClC,cAAc,gBAAgB;AAAA,UAC9B,cAAc,gBAAgB;AAAA,QAAA,CACF;AAAA,MAAA,WACrB,SAAS,YAAY;AAC9B,eAAO,cAAc;AAAA,UACnB,GAAG;AAAA,UACH,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,gBAAgB,kBAAkB;AAAA,UAClC,cAAc,gBAAgB;AAAA,UAC9B,cAAc,gBAAgB;AAAA,UAC9B,aAAa;AAAA,QAAA,CACe;AAAA,MAAA,WACrB,SAAS,eAAe;AACjC,eAAO,cAAc;AAAA,UACnB,GAAG;AAAA,UACH,MAAM;AAAA,UACN,YAAY;AAAA,UACZ,gBAAgB,kBAAkB;AAAA,UAClC,cAAc,gBAAgB;AAAA,UAC9B,cAAc,gBAAgB;AAAA,UAC9B,aAAa;AAAA,QAAA,CACe;AAAA,MAAA,WACrB,SAAS,mBAAmB;AACrC,eAAO,cAAc;AAAA,UACnB,GAAG;AAAA,UACH,YAAY;AAAA,UACZ,gBAAgB,kBAAkB;AAAA,UAClC,cAAc,gBAAgB;AAAA,UAC9B;AAAA,UACA,aAAa;AAAA,QAAA,CACe;AAAA,MAChC;AAAA,IAAA,WACS,SAAS,cAAc;AAC1B,YAAA,EAAE,OAAW,IAAA;AACnB,aAAO,WAAW;AAAA,QAChB,GAAG;AAAA,QACH,QAAQ,UAAU;AAAA,MAAA,CACK;AAAA,IAAA,WAChB,SAAS,kBAAkB;AACpC,aAAO,aAAa,EAAE,GAAG,MAAM,MAAM,KAAkC,CAAA;AAAA,IAAA,WAC9D,SAAS,kBAAkB;AACpC,aAAO,aAAa,EAAE,GAAG,MAAM,MAAM,KAAkC,CAAA;AAAA,IAAA,WAC9D,SAAS,aAAa;AACzB,YAAA,EAAE,OAAO,eAAe,OAAO,QAAQ,UAAU,GAAG,SACxD,IAAA;AAEF,aAAO,UAAU;AAAA,QACf,MAAM;AAAA,QACN;AAAA,QACA,QAAQ,UAAU;AAAA,QAClB,eAAe,iBAAiB;AAAA,QAChC,OAAO,SAAS;AAAA,QAChB,UAAU,YAAY;AAAA,QACtB,GAAG;AAAA,MAAA,CACJ;AAAA,IAAA,WACQ,SAAS,eAAe;AACjC,YAAM,EAAE,OAAO,YAAY,SAAS,cAAc,GAAG,SACnD,IAAA;AAEF,aAAO,YAAY;AAAA,QACjB,MAAM;AAAA,QACN;AAAA,QACA,GAAG;AAAA,QACH,cAAc,gBAAgB;AAAA,QAC9B,SAAS,WAAW;AAAA,QACpB,YAAY,cAAc;AAAA,MAAA,CAC3B;AAAA,IAAA,WACQ,SAAS,UAAU;AAC5B,aAAO,OAAO;AAAA,QACZ,MAAM;AAAA,QACN,GAAG;AAAA,MAAA,CACkB;AAAA,IACzB;AAEA,UAAM,IAAI,MAAM,UAAU,IAAI,aAAa;AAAA,EAC7C;AClJgB,WAAA,gBACd,OACA,OACa;AACb,UAAM,EAAE,QAAY,IAAA,aAAa,OAAgB,KAAc;AAC/D,UAAM,YAAY,MAAM;AAExB,QAAI,CAAC,SAAS;AAEZ,UAAI,YAAY,KAAK;AACZ,eAAA;AAAA,MAAA,OACF;AAEE,eAAA;AAAA,MACT;AAAA,IACF;AAGO,WAAA;AAAA,EACT;ACfO,WAAS,oBAAoB;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAA4B;AACnB,WAAA,CAAC,OAAwB,SAAiB;;AAE7C,UAAA,UACA,kBACAA,MAAA,iCAAQ,aAAR,gBAAAA,IAAkB,MAAI,iCAAQ,SAAO,6CAAc,KAAI,KACvD;AACO,eAAA;AAAA,MACT;AAEA,UAAI,cAAc,OAAO;AAChB,eAAA;AAAA,MACE,WAAA,cAAc,WAAW,UAAU,QAAQ;AAC7C,eAAA;AAAA,MACE,WAAA,cAAc,WAAW,UAAU,QAAQ;AAC7C,eAAA;AAAA,MACE,WAAA,cAAc,UAAU,UAAU,QAAQ;AACnD,YAAI,OAAO,GAAG;AACL,iBAAA;AAAA,QACT,WACE,UACA,gBACA,OAAO,SAAS,IAAI,OAAO,OAAO,aAAa,IAAI,KACnD;AACO,iBAAA;AAAA,QACT;AAAA,MACF;AAEO,aAAA;AAAA,IAAA;AAAA,EAEX;AAEgB,WAAA,qBACd,QACA,UACQ;AACR,YAAQ,UAAU;AAAA,MAClB,KAAK;AACI,eAAA;AAAA,MACT,KAAK;AACH,eAAO,CAAC;AAAA,MACV,KAAK;AAAA,MACL,KAAK;AAAA,MACL;AACS,eAAA;AAAA,IACT;AAAA,EACF;AC5DO,WAAS,eAAe;AAAA,IAC7B;AAAA,EACF,GAAyC;AACjC,UAAA,QAAQ,SAAS,KAAK;AAErB,WAAA;AAAA,MACL;AAAA,MACA,gBAAgB,CAAC,WAAmB,MAAM,MAAM,IAAI;AAAA,IAAA;AAAA,EAExD;ACTO,WAAS,iBAAiB;AAAA,IAC/B;AAAA,EACF,GAAyC;AACjC,UAAA,QAAQI,2BAAiB,KAAK;AAE7B,WAAA;AAAA,MACL;AAAA,MACA,gBAAgB,CAAC,WAAmB,MAAM,MAAM,IAAI;AAAA,IAAA;AAAA,EAExD;ACVO,WAAS,gBAAgB;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAyC;AACjC,UAAA,0BAAU;AAEhB,QAAI,WAAW;AACP,YAAA,YAAY,CAAC,IAAI,SAAS;;AACxB,cAAA,QAAOJ,MAAA,KAAK,SAAL,gBAAAA,IAAY;AACrB,YAAA,MAAM,IAAI,GAAG;AACf,kBAAQ,KAAK,aAAa,IAAI,6BAA6B,KAAK,EAAE,EAAE;AAAA,QACtE;AAEI,YAAA,IAAI,IAAI,QAAQ,CAAC;AAAA,MAAA,CACtB;AAAA,IAAA,OACI;AACL,cAAQ,KAAK,uDAAuD;AAAA,IACtE;AAEO,WAAA;AAAA,MACL,gBAAgB,CAAC,WAAmB;AAC9B,YAAA,CAAC,aAAa,CAAC,KAAK;AACf,iBAAA;AAAA,QACT;AAEO,eAAA,IAAI,IAAI,MAAM;AAAA,MACvB;AAAA,IAAA;AAAA,EAEJ;ACXA,QAAM,YAAY;AAAA,IAChB,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,MAAM,CAAC,EAAE,mBAAyC;AAAA,MAChD,gBAAgB,CAAC,QAAgB;AAAA,IAAA;AAAA,EAErC;AAEO,WAAS,iBAAiB,EAAE,MAAM,GAAG,QAAgC;;AAC1E,UAAM,YAAWA,MAAA,UAAU,UAAV,gBAAAA,IAAA,gBAAkB;AAC/B,QAAA,CAAC,YAAY,SAAS,WAAW;AACnC,YAAM,IAAI,MAAM,4BAA4B,IAAI,EAAE;AAAA,IACpD;AAEA,UAAM,EAAE,OAAO,SAAS,QAAA,IAAY;AAC9B,UAAA,4BAAY;AACd,QAAA;AACA,QAAA;AAEE,UAAA,YAAY,CAAC,IAAI,SAAS;AAC1B,UAAA;AACJ,UAAI,SAAS,WAAW;AACf,eAAA,KAAK,QAAQ,KAAK;AAAA,MAAA,OACpB;AACE,eAAA,SAAS,eAAe,EAAE;AAAA,MACnC;AAEI,UAAA,QAAQ,UAAa,OAAO,KAAK;AAC7B,cAAA;AAAA,MACR;AAEI,UAAA,QAAQ,UAAa,OAAO,KAAK;AAC7B,cAAA;AAAA,MACR;AAEM,YAAA,IAAI,IAAI,IAAI;AAAA,IAAA,CACnB;AAGD,QAAI,SAAS,QAAQ;AACnB,YAAM,QAAQK,QAAAA,cACX,OAAO,CAAC,KAAK,GAAG,CAAC,EACjB,WAAW,CAAC,SAAS,OAAO,CAAC;AAEhC,iBAAW,CAAC,QAAQ,IAAI,KAAK,OAAO;AAClC,cAAM,IAAI,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC/B;AAAA,IACF;AAEO,WAAA;AAAA,EACT;ACzDgB,WAAA,WACd,OACA,OACA,OACA;AAGA,UAAM,MAAM;AAEZ,eAAW,QAAQ,OAAO;AACpB,UAAA;AACI,cAAA,QAAQ,KAAK,IAAI,IAAI;AAAA,MAAA,SACpB,EAAE,WAAW;AACZ,gBAAA,MAAM,WAAW,OAAO,EAAE;AAAA,MACpC;AAAA,IACF;AAEA,eAAW,QAAQ,OAAO;AACpB,UAAA;AACF,cAAM,QAAQ,KAAK,QAAQ,KAAK,QAAQ,IAAI;AAAA,MAAA,SACrC,EAAE,WAAW;AACZ,gBAAA,MAAM,WAAW,OAAO,EAAE;AAAA,MACpC;AAAA,IACF;AAEO,WAAA;AAAA,EACT;AAgBO,WAAS,eAAe;AAAA,IAC7B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAAwB;AACtB,UAAM,QAA6B,CAAA;AACnC,UAAM,QAA6B,CAAA;AAC7B,UAAA,0BAAU;AAEhB,UAAM,QAAQ,iBAAiB;AAAA,MAC7B;AAAA,MACA,MAAM;AAAA,MACN,WAAW;AAAA,MACX,SAAS;AAAA,MACT,SAAS;AAAA,MACT,aAAa;AAAA,IAAA,CACd;AAEK,UAAA,YAAY,MAAM,MAAA,EAAQ;AAChC,UAAM,kBAAkB,oBAAoB,EAAE,WAAW,UAAW,CAAA;AAE9D,UAAA,YAAY,CAAC,IAAI,SAAS;AACxB,YAAA,WAAW,OAAO,gBAAgB,EAAE;AACpC,YAAA,EAAE,MAAM,MAAM,MAAM,OAAO,MAAM,GAAG,KAAS,IAAA;AACnD,YAAM,WAAW,MAAM,IAAI,KAAK,EAAE;AAC5B,YAAA,eAAe,gBAAgB,QAAQ,QAAQ;AAErD,YAAM,YAAY,MAAM,iBAAiB,KAAK,EAAE,KAAK;AAC/C,YAAA,UAAU,UAAU,IAAI,CAAAC,OAAK,MAAM,kBAAkBA,EAAC,CAAC;AAE7D,YAAM,IAAuB;AAAA,QAC3B,GAAI;AAAA,QACJ,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM;AAAA,UACJ,GAAG;AAAA,UACH,GAAI,QAAQ,CAAC;AAAA,QACf;AAAA,QACA,UAAU;AAAA,UACR,GAAG;AAAA,UACH,GAAG,SAAS,KAAK;AAAA,UACjB,GAAG,SAAS,KAAK;AAAA,UACjB,GAAG,SAAS,KAAK;AAAA,QACnB;AAAA,MAAA;AAGE,UAAA,IAAI,KAAK,IAAI,CAAC;AAClB,YAAM,KAAK,CAAC;AAAA,IAAA,CACb;AAEK,UAAA,YAAY,CAAC,KAAK,SAAS;AAC/B,YAAM,OAAO,IAAI,IAAI,KAAK,MAAM;AAChC,YAAM,KAAK,IAAI,IAAI,KAAK,MAAM;AAE9B,UAAI,QAAQ,IAAI;AACd,cAAM,EAAE,MAAM,IAAI,OAAO,MAAM,GAAG,KAAS,IAAA;AACrC,cAAA,eAAe,gBAAgB,QAAQ,IAAI;AAGjD,cAAM,KAAK;AAAA,UACT,GAAG;AAAA,UACH;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA,MAAM;AAAA,YACJ,GAAG;AAAA,YACH;AAAA,YACA,GAAI,QAAQ,CAAC;AAAA,UACf;AAAA,QAAA,CACM;AAAA,MACV;AAAA,IAAA,CACD;AAEM,WAAA;AAAA,MACL;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AC/IO,QAAM,kBAAkB;AAAA,IAC7B,MAAM;AAAA,IACN,SAAS;AAAA,IACT,UAAU;AAAA;AAAA,IAEV,WAAW;AAAA,EACb;ACAgB,WAAA,gBACd,WACA,OACA,aACoB;AACd,UAAA,cAAc,MAAM;AAC1B,UAAM,UAAU,cAAc,QAAQ,cAAc,cAAc;AAClE,UAAM,SAAS,cAAc,QAAQ,cAAc,IAAI;AACjD,UAAA,KAAK,UAAU,UAAU;AAEzB,UAAA,WAAW,MAAM,WAAW,CAAC;AAC7B,UAAA,WAAW,MAAM,aAAa,CAAC;AAE9B,WAAA,CAAC,UAAU,QAAQ;AAAA,EAC5B;AAEO,WAAS,aAAa,MAAgC;AAC3D,WAAO,CAAC,OAAO,GAAG,IAAI,OAAO,GAAG;AAAA,EAClC;ACrBA,QAAM,2BAA2B;AAK1B,WAAS,YACd,MACA,IACA,SAAS,GACT;AACM,UAAA,aAAa,IAAIC,cAAQ,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,CAAC;AACzD,UAAA,WAAW,IAAIA,cAAQ,GAAG,GAAG,GAAG,KAAK,GAAG,GAAG,KAAK,CAAC;AACjD,UAAA,YAAY,IAAIA,MAAQ,QAAA,EAC3B,WAAW,YAAY,QAAQ,EAC/B,aAAa,CAAC;AAEjB,WAAO,UAAU,UAAU,UAAU,WAAW,MAAM;AAAA,EACxD;AASO,WAAS,eACd,MACA,IACA,SAAS,IACoB;AACvB,UAAA,aAAa,KAAK;AAClB,UAAA,WAAW,GAAG;AACpB,UAAM,IAAI,IAAIA,MAAA,QAAA,EAAU,WAAW,UAAU,UAAU;AACjD,UAAA,OAAO,EAAE;AACf,UAAM,KAAK,EAAE,MAAM,EAAE,UAAU;AACzB,UAAA,KAAK,IAAIA,MAAQ,QAAA,EAAE,WAAW,UAAU,UAAU,EAAE,aAAa,CAAC;AACxE,UAAM,IAAI,KAAK,IAAI,GAAG,CAAC,IAAI;AAC3B,UAAM,IAAI,IAAIA,MAAQ,QAAA,CAAC,GAAG,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG,CAAC,EAAE;AACxD,UAAM,KAAK,IAAIA,gBACZ,IAAI,UAAU,EACd,IAAI,EAAE,EACN,IAAI,EAAE,eAAe,OAAO,CAAC,EAAE,eAAe,MAAM,CAAC;AAEjD,WAAA,CAAC,MAAM,IAAI,EAAE;AAAA,EACtB;AAKO,WAAS,SACd,MACA,YACA,IACA,UACA,QACA,aACgB;AAChB,UAAM,aAAa,gBAAgB,MAAM,IAAI,UAAU;AACvD,UAAM,WAAW,gBAAgB,IAAI,MAAM,QAAQ;AACnD,WAAO,SACH,IAAIC,MAAA;AAAA,MACJ,GAAG,eAAe,YAAY,UAAU,WAAW;AAAA,IAEnD,IAAA,IAAIC,MAAW,WAAA,YAAY,QAAQ;AAAA,EACzC;AAKO,WAAS,UAAU,MAAkC;AACnD,WAAA,IAAIF,MAAAA,QAAQ,KAAK,SAAS,GAAG,KAAK,SAAS,GAAG,KAAK,SAAS,KAAK,CAAC;AAAA,EAC3E;AAKA,WAAS,gBAAgB,MAAe,IAAa,QAAyB;AACtE,UAAA,WAAW,KAAK,WAAW,EAAE;AAC5B,WAAA,KAAK,QAAQ;AAAA,MAClB,GACG,QACA,IAAI,IAAI,EACR,eAAe,SAAS,QAAQ;AAAA,IAAA;AAAA,EAEvC;AAKgB,WAAA,mBAAmB,MAAyB,QAAiB;AACpE,WAAA;AAAA,MACL,GAAG;AAAA,MACH,UAAU;AAAA,QACR,GAAG,KAAK;AAAA,QACR,GAAG,KAAK,SAAS,IAAI,OAAO;AAAA,QAC5B,GAAG,KAAK,SAAS,IAAI,OAAO;AAAA,QAC5B,GAAG,KAAK,SAAS,IAAI,OAAO;AAAA,MAC9B;AAAA,IAAA;AAAA,EAEJ;AAOO,WAAS,yBAAyB,EAAE,MAAM,OAAO,UAAU;AAChE,QAAI,gBAAgB;AAChB,QAAA;AAEJ,UAAM,gBAAgB,MACnB,OAAO,CAAK,MAAA,EAAE,WAAW,KAAK,UAAU,EAAE,WAAW,KAAK,MAAM,EAChE,IAAI,CAAA,MAAK,EAAE,EAAE;AAEZ,QAAA,cAAc,SAAS,GAAG;AACZ,sBAAA;AAChB,YAAM,YAAY,cAAc,QAAQ,KAAK,EAAE;AAE3C,UAAA,cAAc,WAAW,GAAG;AAE5B,sBAAA,cAAc,IAAI,2BAA2B,CAAC;AAAA,MAAA,OAC3C;AACL,uBACG,YAAY,KAAK,MAAM,cAAc,SAAS,CAAC,KAChD;AAAA,MACJ;AAAA,IACF;AAEO,WAAA,EAAE,QAAQ,eAAe;EAClC;AClHO,WAAS,gBACd,OACsB;AACtB,QAAI,OAAO,OAAO;AAClB,QAAI,OAAO,OAAO;AAClB,QAAI,OAAO,OAAO;AAClB,QAAI,OAAO,OAAO;AAClB,QAAI,OAAO,OAAO;AAClB,QAAI,OAAO,OAAO;AAElB,aAAS,QAAQ,OAAO;AACtB,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,CAAC;AACrC,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,CAAC;AACrC,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,CAAC;AACrC,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,CAAC;AACrC,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,CAAC;AACrC,aAAO,KAAK,IAAI,MAAM,KAAK,SAAS,CAAC;AAAA,IACvC;AAEO,WAAA;AAAA,MACL,QAAQ,OAAO;AAAA,MACf,OAAO,OAAO;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,IAAI,OAAO,QAAQ;AAAA,MACnB,IAAI,OAAO,QAAQ;AAAA,MACnB,IAAI,OAAO,QAAQ;AAAA,IAAA;AAAA,EAEvB;AC7CgB,WAAA,mBACd,OACA,kBACA;AACA,QAAI,CAAC,kBAAkB;AACrB,iCAAW,IAAI;AAAA,IACjB;AAEA,WAAO,MAAM,OAAO,CAAC,UAAU,MAAM;AAC7B,YAAA,MAAM,EAAE,KAAK,gBAAgB;AACnC,UAAI,KAAK;AACE,iBAAA,IAAI,KAAK,CAAC,GAAI,SAAS,IAAI,GAAG,KAAK,CAAA,GAAK,CAAC,CAAC;AAAA,MACrD;AACO,aAAA;AAAA,IAAA,GACF,oBAAA,IAAA,CAAK;AAAA,EACd;AAgBO,WAAS,kBAAkB;AAAA,IAChC;AAAA,IACA;AAAA,EACF,GAA2B;AACnB,UAAA,6BAAa;AAEnB,QAAI,kBAAkB;AACd,YAAA,SAAS,mBAAmB,OAAO,gBAAgB;AACzD,iBAAW,CAAC,KAAKxB,MAAK,KAAK,QAAQ;AAC3B,cAAA,WAAW,gBAAgBA,MAAK;AACtC,eAAO,IAAI,KAAK;AAAA,UACd,OAAO;AAAA,UACP,OAAAA;AAAAA,UACA;AAAA,QAAA,CACD;AAAA,MACH;AAAA,IACF;AAEO,WAAA;AAAA,EACT;ACjCa,QAAA,iBAAiB,CAAC;AAAA,IAC7B,cAAc;AAAA,IACd,WAAW;AAAA,IACX,UAAU;AAAA,IACV,UAAA2B;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAyD;AACjD,UAAA,YAAYC,aAAgB,KAAK;AACjC,UAAA,QAAQA,aAAmB,IAAI;AAC/B,UAAA,QAAQA,aAAe,CAAC;AAC9B,UAAM,SAASA,MAAAA,OAAO;AAAA,MACpB,GAAG;AAAA,MACH,GAAG;AAAA,MACH,IAAI;AAAA,MACJ,IAAI;AAAA,IAAA,CACL;AAEK,UAAA,cAAcC,kBAAY,CAAC,UAAsB;AAC9C,aAAA,QAAQ,IAAI,MAAM;AAClB,aAAA,QAAQ,IAAI,MAAM;AAAA,IAC3B,GAAG,CAAE,CAAA;AAEL,UAAM,kBAAkBA,MAAA;AAAA,MACtB,CAAC,UAAoC;AAC7B,cAAA,UAAU,aAAa,MAAM,OAAO;AAC1C,cAAM,EAAE,IAAI,GAAG,IAAI,MAAM,OAAO;AAE5B,YAAA,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,aAAa;AACrD,gBAAM,UAAU;AAChB,wBAAc,KAAK;AAAA,QAAA,OACd;AACL,iBAAO,QAAQ,KAAK;AACpB,iBAAO,QAAQ,KAAK;AACpB,gBAAM,UAAU,WAAW,MAAM,gBAAgB,KAAK,GAAG,QAAQ;AAAA,QACnE;AAAA,MACF;AAAA,MACA,CAAC,UAAU,eAAe,WAAW;AAAA,IAAA;AAGjC,UAAA,UAAUA,MAAAA,YAAY,MAAM;AAChC,mBAAa,MAAM,OAAO;AACtB,UAAA,OAAO,WAAW,aAAa;AACxB,iBAAA,oBAAoB,aAAa,aAAa,KAAK;AAAA,MAC9D;AAAA,IAAA,GACC,CAAC,WAAW,CAAC;AAEhB,UAAM,cAAcA,MAAA;AAAA,MAClB,CAAC,UAAoC;AACnC,YAAI,CAACF,WAAU;AACb,oBAAU,UAAU;AACZ;AAEJ,cAAA,MAAM,YAAY,GAAG;AAChB,mBAAA,QAAQ,KAAK,MAAM,QAAQ;AAC3B,mBAAA,QAAQ,KAAK,MAAM,QAAQ;AAE9B,gBAAA,OAAO,WAAW,aAAa;AACxB,uBAAA,iBAAiB,aAAa,aAAa,KAAK;AAAA,YAC3D;AAEA,kBAAM,UAAU,WAAW,MAAM,gBAAgB,KAAK,GAAG,OAAO;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,MACA,CAAC,SAAS,iBAAiBA,WAAU,aAAa,OAAO;AAAA,IAAA;AAG3D,UAAM,QAAQE,MAAA;AAAA,MACZ,CAAC,UAAoC;AAC7B,cAAA,UAAU,aAAa,MAAM,OAAO;AAC1C,cAAM,UAAU;AAChB,qBAAa,KAAK;AAAA,MACpB;AAAA,MACA,CAAC,YAAY;AAAA,IAAA;AAGf,UAAM,aAAaA,MAAA;AAAA,MACjB,CAAC,UAAoC;AACnC,kBAAU,UAAU;AACZ;AAEJ,YAAA,MAAM,YAAY,GAAG;AACvB,gBAAM,UAAU,WAAW,MAAM,MAAM,KAAK,GAAG,OAAO;AAAA,QACxD;AAAA,MACF;AAAA,MACA,CAAC,SAAS,OAAO,OAAO;AAAA,IAAA;AAGnB,WAAA;AAAA,MACL;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;ACtGa,QAAA,UAAU,CAAC;AAAA,IACtB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAkB;AAChB,UAAM,SAASC,MAAAA,SAAS,CAAS,UAAA,MAAM,MAAM;AAC7C,UAAM,YAAYA,MAAAA,SAAS,CAAS,UAAA,MAAM,SAAS;AACnD,UAAM,OAAOA,MAAAA,SAAS,CAAS,UAAA,MAAM,IAAI;AACzC,UAAM,KAAKA,MAAAA,SAAS,CAAS,UAAA,MAAM,EAAE;AAGrC,UAAM,EAAE,SAAS,SAAS,QAAQ,QAAQ,UAAUC,MAAA;AAAA,MAClD,OAAO;AAAA;AAAA,QAEL,SAAS,IAAIC,MAAAA,QAAQ;AAAA;AAAA,QAErB,SAAS,IAAIR,MAAAA,QAAQ;AAAA;AAAA,QAErB,QAAQ,IAAIA,MAAAA,QAAQ;AAAA;AAAA,QAEpB,QAAQ,IAAIA,MAAAA,QAAQ;AAAA;AAAA,QAEpB,OAAO,IAAIS,MAAAA,MAAM;AAAA,MAAA;AAAA,MAEnB,CAAC;AAAA,IAAA;AAGH,UAAM,aAAaF,MAAA;AAAA,MACjB,MAAM,GAAG,WAAW,sBAAsB;AAAA,MAC1C,CAAC,GAAG,UAAU;AAAA,IAAA;AAGT,WAAAG,gBAAA;AAAA,MACL;AAAA,QACE,aAAa,CAAC,EAAE,YAAY;AAEpB,gBAAA,EAAE,aAAa,MAAU,IAAA;AAG/B,sBAAY,iBAAiB,MAAM,EAAE,IAAI,KAAK;AAG9C,kBAAQ,KAAK,KAAK;AAGN;QACd;AAAA,QACA,QAAQ,CAAC,EAAE,YAAY;AAEf,gBAAA,UAAU,OAAO,WAAW,OAAO;AACnC,gBAAA,UAAU,OAAO,WAAW,OAAO;AAEnC,gBAAA,MACF,MAAM,YAAW,yCAAY,SAAQ,KAAK,WAAW,KAAK,QAC1D,IACF;AACI,gBAAA,KACJ,GAAG,MAAM,YAAW,yCAAY,QAAO,KAAK,WAAW,KAAK,UAC1D,IACF;AAGM,kBAAA,IAAI,IAAI,EAAE;AAGR,oBAAA,cAAc,SAAS,MAAM;AAGhC,iBAAA,kBAAkB,MAAM,EAAE,OAAO;AAGlC,gBAAA,8BAA8B,QAAQ,OAAO;AAGzC,oBAAA,IAAI,eAAe,OAAO,OAAO;AAG3C,gBAAM,UAAU,IAAIV,MAAQ,QAAA,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC,EAC3D,KAAK,OAAO,EACZ,IAAI,MAAM;AAEb,iBAAO,IAAI,OAAO;AAAA,QACpB;AAAA,QACA;AAAA,MACF;AAAA,MACA,EAAE,MAAM,EAAE,SAAS,WAAW,WAAW,KAAK;AAAA,IAAA;AAAA,EAElD;ACpGgB,WAAA,SAAS,OAAc,QAAgB,QAAgB;AAC9D,WAAAW,qCAAc,OAAO,QAAQ,MAAM;AAAA,EAC5C;ACgDO,QAAM,EAAE,UAAU,aAAa;AAE/B,QAAM,cAAc,CAAC;AAAA,IAC1B,UAAU,CAAC;AAAA,IACX,aAAa,CAAC;AAAA,IACd,mBAAmB,CAAC;AAAA,IACpB;AAAA,IACA,YAAY;AAAA,EACd,MACEC,QAAAA,OAAmB,CAAQ,SAAA;AAAA,IACzB,OAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM;AAAA,QACJ,GAAG,MAAM;AAAA,QACT,OAAO;AAAA,UACL,GAAG,MAAM,KAAK;AAAA,UACd,UAAU,MAAM,KAAK,MAAM,YAAY;AAAA,QACzC;AAAA,MACF;AAAA,IACF;AAAA,IACA,OAAO,CAAC;AAAA,IACR,OAAO,CAAC;AAAA,IACR;AAAA,IACA,8BAAc,IAAI;AAAA,IAClB,SAAS;AAAA,IACT,YAAY;AAAA,IACZ;AAAA,IACA,sCAAsB,IAAI;AAAA,IAC1B,YAAY,CAAC;AAAA,IACb;AAAA,IACA,OAAO,CAAC;AAAA,IACR,OAAO,IAAI,MAAM,EAAE,OAAO,MAAM;AAAA,IAChC,UAAU,CAAAC,WAAS,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,OAAAA,OAAAA,EAAQ;AAAA,IACrD,aAAa,cAAY,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,WAAW;AAAA,IAC9D,qBAAqB,CACnB,qBAAA,IAAI,CAAU,WAAA;AAAA,MACZ,GAAG;AAAA,MACH;AAAA,IAAA,EACA;AAAA,IACJ,eAAe,gBAAc,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,aAAa;AAAA,IACpE,YAAY,aAAW,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,UAAU;AAAA,IAC3D,UAAU,WAAS,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,QAAQ;AAAA,IACrD,eAAe,gBAAc,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,aAAa;AAAA,IACpE,YAAY,CAAAC,aAAW,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,SAAAA,SAAAA,EAAU;AAAA,IAC3D,eAAe,CAAAC,gBAAc,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,YAAAA,YAAAA,EAAa;AAAA,IACpE,UAAU,CACR,UAAA,IAAI,CAAU,WAAA;AAAA,MACZ,GAAG;AAAA,MACH;AAAA,MACA,gBAAgB,gBAAgB,KAAK;AAAA,IAAA,EACrC;AAAA,IACJ,UAAU,WAAS,IAAI,CAAA,WAAU,EAAE,GAAG,OAAO,QAAQ;AAAA,IACrD,iBAAiB,CAAC,IAAI,aACpB,IAAI,CAAS,UAAA;;AACX,YAAM,OAAO,MAAM,MAAM,KAAK,CAAK,MAAA,EAAE,OAAO,EAAE;AACxC,YAAA,iBAAiB,UAAU,IAAI;AAC/B,YAAA,YAAY,IAAIf,MAAQ,QAAA,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAC1D,YAAA,SAAS,UAAU,IAAI,cAAc;AAC3C,YAAM,QAAQ,CAAC,GAAG,MAAM,KAAK;AAE7B,WAAIP,MAAA,MAAM,eAAN,gBAAAA,IAAkB,SAAS,KAAK;AAC5B,SAAAC,MAAA,MAAA,eAAA,gBAAAA,IAAY,QAAQ,CAAAsB,QAAM;AAC9B,gBAAMC,QAAO,MAAM,MAAM,KAAK,CAAK,MAAA,EAAE,OAAOD,GAAE;AAE9C,cAAIC,OAAM;AACR,kBAAM,YAAY,MAAM,MAAM,QAAQA,KAAI;AAC1C,kBAAM,SAAS,IAAI,mBAAmBA,OAAM,MAAM;AAAA,UACpD;AAAA,QAAA;AAAA,MACD,OACI;AACL,cAAM,YAAY,MAAM,MAAM,QAAQ,IAAI;AAC1C,cAAM,SAAS,IAAI,mBAAmB,MAAM,MAAM;AAAA,MACpD;AAEO,aAAA;AAAA,QACL,GAAG;AAAA,QACH,OAAO;AAAA,UACL,GAAG,MAAM;AAAA,UACT,CAAC,EAAE,GAAG;AAAA,QACR;AAAA,QACA;AAAA,MAAA;AAAA,IACF,CACD;AAAA,IACH,qBAAqB,CAAC,UAAU,CAC9B,MAAA,IAAI,CAAU,WAAA,EAAE,GAAG,OAAO,kBAAkB,QAAU,EAAA;AAAA,IACxD;AAAA,EACF,EAAE;AClHJ,WAAS,kBAAkB;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,GAA2B;AACzB,UAAM,cAA2B,CAAA;AACjC,UAAM,cAA2B,CAAA;AACjC,UAAM,mBAAmB,mBAAmB,IAAI,CAAA,MAAK,EAAE,EAAE;AACzD,UAAM,mBAAmB,mBAAmB,IAAI,CAAA,MAAK,EAAE,EAAE;AAEzD,UAAM,gBAAgB,MAAM,OAAO,CAAK,MAAA,EAAE,WAAW,MAAM;AAC3D,UAAM,sBAAsB,cAAc,IAAI,CAAA,MAAK,EAAE,MAAM;AAE/C,gBAAA,KAAK,GAAG,aAAa;AACjC,eAAW,sBAAsB,qBAAqB;AACpD,YAAM,gBAAgB,MAAM;AAAA,QAC1B,CAAK,MAAA,EAAE,WAAW,sBAAsB,EAAE,WAAW;AAAA,MAAA;AAEvD,UAAI,WAAW;AAGX,UAAA,cAAc,WAAW,GAAG;AACnB,mBAAA;AAAA,MAAA,WAEX,cAAc,SAAS,KACvB,CAAC,iBAAiB,SAAS,kBAAkB,GAC7C;AAEA,cAAM,qBAAqB,cAAc,IAAI,CAAA,MAAK,EAAE,EAAE;AACtD,YAAI,mBAAmB,MAAM,CAAA,MAAK,iBAAiB,SAAS,CAAC,CAAC,GAAG;AACpD,qBAAA;AAAA,QACb;AAAA,MACF;AACA,UAAI,UAAU;AAEZ,cAAM,OAAO,MAAM,KAAK,CAAK,MAAA,EAAE,OAAO,kBAAkB;AACxD,YAAI,MAAM;AACR,sBAAY,KAAK,IAAI;AAAA,QACvB;AACA,cAAM,SAAS,kBAAkB;AAAA,UAC/B,QAAQ;AAAA,UACR;AAAA,UACA;AAAA,UACA,oBAAoB;AAAA,UACpB,oBAAoB;AAAA,QAAA,CACrB;AACW,oBAAA,KAAK,GAAG,OAAO,WAAW;AAC1B,oBAAA,KAAK,GAAG,OAAO,WAAW;AAAA,MACxC;AAAA,IACF;AAEA,UAAM,cAA2B,OAAO;AAAA,MACtC,YAAY;AAAA,QACV,CAAC,KAAK,UAAU;AAAA,UACd,GAAG;AAAA,UACH,CAAC,KAAK,EAAE,GAAG;AAAA,QAAA;AAAA,QAEb,CAAC;AAAA,MACH;AAAA,IAAA;AAGF,UAAM,cAA2B,OAAO;AAAA,MACtC,YAAY;AAAA,QACV,CAAC,KAAK,UAAU;AAAA,UACd,GAAG;AAAA,UACH,CAAC,KAAK,EAAE,GAAG;AAAA,QAAA;AAAA,QAEb,CAAC;AAAA,MACH;AAAA,IAAA;AAGK,WAAA;AAAA,MACL,aAAa;AAAA,MACb,aAAa;AAAA,IAAA;AAAA,EAEjB;AAKa,QAAA,qBAAqB,CAAC;AAAA,IACjC;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAA0B;AACxB,UAAM,iBAAiB,CAAA;AACvB,UAAM,iBAAiB,CAAA;AAEvB,eAAW,eAAe,cAAc;AACtC,YAAM,EAAE,aAAa,YAAY,IAAI,kBAAkB;AAAA,QACrD,QAAQ;AAAA,QACR;AAAA,QACA;AAAA,QACA,oBAAoB;AAAA,QACpB,oBAAoB;AAAA,MAAA,CACrB;AAEc,qBAAA,KAAK,GAAG,WAAW;AACnB,qBAAA,KAAK,GAAG,WAAW;AAAA,IACpC;AAEA,UAAM,gBAAgB,eAAe,IAAI,CAAA,MAAK,EAAE,EAAE;AAClD,UAAM,gBAAgB,eAAe,IAAI,CAAA,MAAK,EAAE,EAAE;AAC5C,UAAA,eAAe,MAAM,OAAO,CAAA,MAAK,CAAC,cAAc,SAAS,EAAE,EAAE,CAAC;AAC9D,UAAA,eAAe,MAAM,OAAO,CAAA,MAAK,CAAC,cAAc,SAAS,EAAE,EAAE,CAAC;AAE7D,WAAA;AAAA,MACL;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAKa,QAAA,gBAAgB,CAAC;AAAA,IAC5B;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAA0B;AACxB,UAAM,YAAY,CAAA;AAClB,UAAM,eAAe,MAAM,OAAO,CAAK,MAAA,EAAE,WAAW,MAAM;AAC1D,UAAM,iBAAiB,aAAa,IAAI,CAAA,MAAK,EAAE,EAAE;AACjD,UAAM,wBAAwB,eAAe;AAAA,MAAK,CAAA,OAChD,eAAe,SAAS,EAAE;AAAA,IAAA;AAG5B,QAAI,uBAAuB;AAGlB,aAAA;AAAA,IACT;AAEA,UAAM,qBAAqB,aAAa,IAAI,CAAA,MAAK,EAAE,MAAM;AACzD,QAAI,cAAc;AAElB,eAAW,iBAAiB,oBAAoB;AAC9C,UAAI,CAAC,aAAa;AAIN,kBAAA;AAAA,UACR,GAAG;AAAA,YACD;AAAA,YACA,GAAG,cAAc,EAAE,QAAQ,eAAe,OAAO,gBAAgB;AAAA,UACnE;AAAA,QAAA;AAEY,sBAAA;AAAA,MAChB;AAAA,IACF;AAEO,WAAA;AAAA,EACT;AClJa,QAAA,cAAc,CAAC;AAAA,IAC1B,mBAAmB,CAAC;AAAA,IACpB,QAAQ,CAAC;AAAA,IACT,QAAQ,CAAC;AAAA,EACX,MAAwC;AACtC,UAAM,iBAAiBZ,MAAA;AAAA,MACrB,CAAC,WAAmB;AACZ,cAAA,EAAE,aAAa,IAAI,mBAAmB;AAAA,UAC1C;AAAA,UACA;AAAA,UACA,cAAc;AAAA,QAAA,CACf;AACD,cAAM,iBAAiB,aAAa,IAAI,CAAA,MAAK,EAAE,EAAE;AAE1C,eAAA,CAAC,eAAe,SAAS,MAAM;AAAA,MACxC;AAAA,MACA,CAAC,kBAAkB,OAAO,KAAK;AAAA,IAAA;AAGjC,UAAM,mBAAmBA,MAAA;AAAA,MACvB,CAAC,WAAmB;AACZ,cAAA,EAAE,aAAa,IAAI,mBAAmB;AAAA,UAC1C;AAAA,UACA;AAAA,UACA,cAAc;AAAA,QAAA,CACf;AACD,cAAM,iBAAiB,aAAa,IAAI,CAAA,MAAK,EAAE,EAAE;AAEjD,eAAO,cAAc,EAAE,QAAQ,OAAO,eAAgB,CAAA;AAAA,MACxD;AAAA,MACA,CAAC,kBAAkB,OAAO,KAAK;AAAA,IAAA;AAG1B,WAAA;AAAA,MACL;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;ACnCa,QAAA,WAAW,CAAC;AAAA,IACvB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAmB;AACjB,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,cAAc,SAAS,CAAS,UAAA,MAAM,WAAW;AACvD,UAAM,wBAAwB,SAAS,CAAS,UAAA,MAAM,gBAAgB;AACtE,UAAM,WAAW,SAAS,CAAS,UAAA,MAAM,QAAQ;AACjD,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,KAAK;AAChD,UAAM,WAAW,SAAS,CAAS,UAAA,MAAM,QAAQ;AACjD,UAAM,gBAAgB,SAAS,CAAS,UAAA,MAAM,aAAa;AAC3D,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AACrD,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,WAAW,SAAS,CAAS,UAAA,MAAM,QAAQ;AACjD,UAAM,sBAAsB,SAAS,CAAS,UAAA,MAAM,mBAAmB;AACjE,UAAA,gBAAgBD,aAAgB,KAAK;AACrC,UAAA,SAASA,aAA8B,IAAI;AACjD,UAAM,SAASE,MAAAA,SAAS,CAAS,UAAA,MAAM,MAAM;AAEvC,UAAA,EAAE,cAAc,aAAA,IAAiBC,MAAA;AAAA,MACrC,MACE,mBAAmB;AAAA,QACjB,cAAc;AAAA,QACd;AAAA,QACA;AAAA,MAAA,CACD;AAAA,MACH,CAAC,uBAAuB,OAAO,KAAK;AAAA,IAAA;AAIhC,UAAA,UAAUH,aAAuB,KAAK;AAC5Cc,UAAAA,UAAU,MAAM;AACd,cAAQ,UAAU;AAAA,IAAA,GACjB,CAAC,KAAK,CAAC;AAEV,UAAM,eAAeb,MAAA;AAAA,MACnB,OAAO,cAAoB;AAElB,eAAA,UACL,aACA,eAAe;AAAA,UACb,GAAG;AAAA,UACH,MAAM;AAAA,UACN;AAAA,UACA,OAAO,QAAQ;AAAA,UACf;AAAA,QAAA,CACD;AAGG,cAAA,KAAK,OAAO,OAAO;AAGzB,cAAM,SAAS,eAAe;AAAA,UAC5B;AAAA,UACA,QAAQ,OAAO;AAAA,UACf;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA,CACD;AAGD,cAAM,WAAW,kBAAkB;AAAA,UACjC,OAAO,OAAO;AAAA,UACd;AAAA,QAAA,CACD;AAGD,iBAAS,OAAO,KAAK;AACrB,iBAAS,OAAO,KAAK;AACrB,oBAAY,QAAQ;AAAA,MACtB;AAAA;AAAA,MAEA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAGFa,UAAAA,UAAU,MAAM;AACR1C,YAAAA,SAAQ,WAAW,IAAI,CAAS,UAAA;AAAA,QACpC,GAAG;AAAA,QACH,cAAc,oBAAoB;AAAA,UAChC,WAAW,yCAAY;AAAA,UACvB;AAAA,UACA;AAAA,UACA,cAAc,6BAAM;AAAA,QAAA,CACrB,EAAE,QAAQ,6BAAM,IAAI;AAAA,MACrB,EAAA;AAEF,YAAM,sBAAsBA,OAAM;AAAA,QAChC,CAAC,MAAM,MAAM,KAAK,iBAAiB,WAAW,CAAC,EAAE;AAAA,MAAA;AAGnD,UAAI,qBAAqB;AACvB,iBAASA,MAAK;AAAA,MAChB;AAAA,IACF,GAAG,CAAC,QAAQ,OAAO,MAAM,OAAO,SAAS,GAAG,UAAU,YAAY,SAAS,CAAC;AAE5E0C,UAAAA,UAAU,MAAM;AAEd,UAAI,cAAc,SAAS;AACzB,sBAAc,UAAU;AAAA,MAC1B;AAAA,IAAA,GACC,CAAC,YAAY,aAAa,CAAC;AAE9BA,UAAAA,UAAU,MAAM;AAEd,UAAI,cAAc,SAAS;AACzB,mBAAW,OAAO;AAAA,MACpB;AAAA,IAAA,GACC,CAAC,SAAS,UAAU,CAAC;AAGxBA,UAAAA,UAAU,MAAM;AACd,qBAAe,SAAS;AACtB,sBAAc,UAAU;AACb,mBAAA,OAAO,cAAc,YAAY;AAC5C,cAAM,aAAa;AACnB,sBAAc,UAAU;AAAA,MAC1B;AAEO;IAAA,GAEN,CAAC,cAAc,YAAY,CAAC;AAE/BA,UAAAA,UAAU,MAAM;AAEd,UAAI,cAAc,SAAS;AACzB,4BAAoB,gBAAgB;AAAA,MACtC;AAAA,IAAA,GACC,CAAC,kBAAkB,mBAAmB,CAAC;AAG1CA,UAAAA,UAAU,MAAM;AACd,UAAI,cAAc,SAAS;AAGzB,gBAAQ,UAAU;AAClB,iBAAS,CAAE,CAAA;AAGE;MACf;AAAA,IACC,GAAA,CAAC,YAAY,cAAc,QAAQ,CAAC;AAGvCA,UAAAA,UAAU,MAAM;AACd,UAAI,cAAc,SAAS;AACzB,qBAAa,OAAO,OAAO;AAAA,MAC7B;AAAA,OACC,CAAC,YAAY,iBAAiB,WAAW,YAAY,CAAC;AAAA,EAC3D;AC7MA,QAAM,oBAAoB,CACxB,MACA,UACA,UACA,UACA,WACG;AACH,UAAM,YAAY,YAAY,CAAC,SAAS,UAAU,MAAM,QAAQ,IAAI;AACpE,UAAM,QAAQ,CAAA;AACd,QAAI,cAAc;AACZ,UAAA,QAAQ,UAAU,MAAM,GAAG;AAEjC,UAAM,QAAQ,CAAQ,SAAA;AACpB,YAAM,WAAW,cAAc,GAAG,WAAW,IAAI,IAAI,KAAK;AACpD,YAAA,YAAY,SAAS,SAAS,WAAW;AAE/C,UAAI,YAAY,UAAU;AACxB,cAAM,KAAK,WAAW;AACR,sBAAA;AAAA,MAAA,OACT;AACS,sBAAA;AAAA,MAChB;AAAA,IAAA,CACD;AAED,QAAI,aAAa;AACf,YAAM,KAAK,WAAW;AAAA,IACxB;AAEA,UAAM,QACJ,KAAK;AAAA,MACH;AAAA,MACA,MAAM;AAAA,QACJ,CAAC,KAAK,SAAS,KAAK,IAAI,KAAK,KAAK,SAAS,WAAW,GAAG;AAAA,QACzD;AAAA,MACF;AAAA,IACE,IAAA;AACA,UAAA,SAAS,MAAM,SAAS,WAAW;AAElC,WAAA,EAAE,OAAO,QAAQ,MAAM,MAAM,KAAK,IAAI,GAAG,WAAW,MAAM,OAAO;AAAA,EAC1E;AA2Ea,QAAA,QAAwB,CAAC;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW;AAAA,IACX,WAAW;AAAA,IACX;AAAA,IACA;AAAA,IACA,eAAe;AAAA,EACjB,MAAM;AACE,UAAA,kBAAkBX,cAAQ,MAAM,IAAIY,MAAAA,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC;AAC/D,UAAM,4BAA4BZ,MAAA;AAAA,MAChC,MAAM,IAAIY,MAAA,MAAM,eAAe;AAAA,MAC/B,CAAC,eAAe;AAAA,IAAA;AAElB,UAAM,mBAAmBZ,MAAA;AAAA,MACvB,MAAO,SAAS,IAAIY,MAAAA,MAAM,MAAM,IAAI;AAAA,MACpC,CAAC,MAAM;AAAA,IAAA;AAGH,UAAA;AAAA,MACJ;AAAA,MACA;AAAA,MACA,MAAM;AAAA,MACN;AAAA,IAAA,IACEZ,MAAA;AAAA,MACF,MAAM,kBAAkB,MAAM,UAAU,UAAU,UAAU,MAAM;AAAA,MAClE,CAAC,MAAM,UAAU,UAAU,UAAU,MAAM;AAAA,IAAA;AAG7C,WACGa,2BAAA,IAAAC,QAAA,WAAA,EACE,UACC,kBAAAD,+BAAC,QACC,EAAA,UAAAE,2BAAA;AAAA,MAACC,QAAA;AAAA,MAAA;AAAA,QACC,UAAU,CAAC,GAAG,YAAY,IAAI,EAAE;AAAA,QAChC,MAAM,CAAC,OAAO,QAAQ,CAAC;AAAA,QACvB,QAAQ;AAAA,QACR;AAAA,QAEA,UAAA;AAAA,UAAAH,2BAAA;AAAA,YAACI,QAAA;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN;AAAA,cACA,OAAO;AAAA,cACP,aAAa;AAAA,cACb,WAAU;AAAA,cACV,cAAc,SAAS,IAAI;AAAA,cAC3B,cAAc,SAAS,mBAAmB;AAAA,cAC1C,aAAa;AAAA,cACb;AAAA,cACA,cAAa;AAAA,cAEZ,UAAA;AAAA,YAAA;AAAA,UACH;AAAA,UACAJ,2BAAA;AAAA,YAACK,QAAAA,EAAE;AAAA,YAAF;AAAA,cACC,QAAO;AAAA,cACP;AAAA,cACA,WAAW;AAAA,cACX,OAAO;AAAA,YAAA;AAAA,UACT;AAAA,QAAA;AAAA,MAAA;AAAA,OAEJ,IAEAL,2BAAA;AAAA,MAACI,QAAA;AAAA,MAAA;AAAA,QACC,MAAM;AAAA,QACN;AAAA,QACA,OAAO;AAAA,QACP,aAAa;AAAA,QACb,WAAU;AAAA,QACV,cAAc,SAAS,IAAI;AAAA,QAC3B,cAAc;AAAA,QACd,aAAa;AAAA,QACb;AAAA,QACA,cAAa;AAAA,QACb;AAAA,QAEC,UAAA;AAAA,MAAA;AAAA,IAGP,EAAA,CAAA;AAAA,EAEJ;AAEA,QAAM,eAAe;AAAA,IACnB,SAAS;AAAA,IACT,UAAU;AAAA,IACV,OAAO;AAAA,IACP,UAAU;AAAA,EACZ;ACxKa,QAAA,OAAsB,CAAC;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd,WAAW;AAAA,EACb,MAAM;AACE,UAAA,kBAAkBjB,cAAQ,MAAM,IAAIY,MAAAA,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC;AAE/D,UAAM,EAAE,UAAU,YAAY,IAAIO,kBAAU;AAAA,MAC1C,MAAM;AAAA,QACJ,aAAa;AAAA,QACb,UAAU,CAAC,MAAS,MAAS,IAAO;AAAA,MACtC;AAAA,MACA,IAAI;AAAA,QACF,aAAa;AAAA,QACb,UAAU,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC;AAAA,MAClC;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,UAAU,WAAW,SAAY;AAAA,MACnC;AAAA,IAAA,CACD;AAED,UAAM,sBAAsB,cAAc;AAC1C,UAAM,cAAc,cAAc;AAElC,WACGN,2BAAAA,IAAAC,QAAAA,WAAA,EAAU,UAAU,CAAC,GAAG,GAAG,CAAC,GAC3B,UAAAC,2BAAAA,KAACG,QAAAA,EAAE,MAAF,EAAO,OAAO,UAAiB,aAAa,GAC3C,UAAA;AAAA,MAAAL,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,QAAO;AAAA,UACP,MAAM,CAAC,aAAa,aAAa,QAAQ;AAAA,QAAA;AAAA,MAC3C;AAAA,MACAA,2BAAA;AAAA,QAACK,QAAAA,EAAE;AAAA,QAAF;AAAA,UACC,QAAO;AAAA,UACP,OAAO;AAAA,UACP,aAAa;AAAA,UACb,WAAW;AAAA,UACX,SAAS;AAAA,UACT,MAAME,MAAA;AAAA,UACN,KAAK;AAAA,QAAA;AAAA,MACP;AAAA,IAAA,EACF,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,OAAK,eAAe;AAAA,IAClB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,IACT,aAAa;AAAA,EACf;AC5Fa,QAAA,SAAgC,CAAC;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;AACJ,UAAM,EAAE,OAAO,YAAY,IAAID,kBAAU;AAAA,MACvC,MAAM;AAAA;AAAA,QAEJ,OAAO,CAAC,MAAS,MAAS,IAAO;AAAA,QACjC,aAAa;AAAA,MACf;AAAA,MACA,IAAI;AAAA,QACF,OAAO,SACH,CAAC,OAAO,MAAM,OAAO,MAAM,OAAO,IAAI,IACtC,CAAC,MAAM,MAAM,IAAI;AAAA,QACrB,aAAa;AAAA,MACf;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,UAAU,WAAW,SAAY;AAAA,MACnC;AAAA,IAAA,CACD;AAEK,UAAA,kBAAkBnB,cAAQ,MAAM,IAAIY,MAAAA,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC;AAC/D,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAE3C,WAEIG,2BAAA,KAAAM,qBAAA,EAAA,UAAA;AAAA,MAACN,2BAAAA,KAAAG,QAAA,EAAE,MAAF,EAAO,UAAU,EAAE,IAAI,MAAM,OAAO,GAAG,OACtC,UAAA;AAAA,QAACL,+BAAA,kBAAA,EAAe,QAAO,YAAW,MAAM,CAAC,GAAG,IAAI,EAAE,GAAG;AAAA,QACrDA,2BAAA;AAAA,UAACK,QAAAA,EAAE;AAAA,UAAF;AAAA,YACC,QAAO;AAAA,YACP,MAAME,MAAA;AAAA,YACN,aAAa;AAAA,YACb,KAAK;AAAA,YACL,SAAS;AAAA,YACT,OAAO;AAAA,UAAA;AAAA,QACT;AAAA,MAAA,GACF;AAAA,OACE,YAAY,YAAY,WACxBP,2BAAA,IAACK,QAAE,EAAA,MAAF,EAAO,UAAU,CAAC,GAAG,GAAG,CAAC,GACxB,UAAAL,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,SAAS;AAAA,UACT,MAAM,OAAO;AAAA,UACb;AAAA,UACA,OAAO,MAAM,KAAK;AAAA,UAClB,aAAa;AAAA,QAAA;AAAA,MAAA,GAEjB;AAAA,IAEJ,EAAA,CAAA;AAAA,EAEJ;AAEA,SAAO,eAAe;AAAA,IACpB,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;ACda,QAAA,wBAAwBS,MAAAA,cAA0C;AAAA,IAC7E,UAAU;AAAA,IACV,eAAe,MAAM;AAAA,IACrB,QAAQ,MAAM;AAAA,IACd,SAAS,MAAM;AAAA,IACf,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,SAAS,MAAM;AAAA,IACf,UAAU,MAAM;AAAA,IAChB,OAAO,MAAM;AAAA,IACb,SAAS,MAAM;AAAA,EACjB,CAAC;AAEY,QAAA,oBAAoB,MAAM;AAC/B,UAAA,UAAUC,iBAAW,qBAAqB;AAEhD,QAAI,YAAY,QAAW;AACzB,YAAM,IAAI;AAAA,QACR;AAAA,MAAA;AAAA,IAEJ;AAEO,WAAA;AAAA,EACT;AC3CA,sBAAoB,QAAQ;AAAA,IAC1B,OAAO;AAAA,MAAA,OACLC,MAAA;AAAA,MAAA,SACAvB,MAAA;AAAA,MAAA,SACAR,MAAA;AAAA,MAAA,SACAgC,MAAA;AAAA,MAAA,YACAC,MAAA;AAAA,MAAA,SACAC,MAAA;AAAA,MAAA,WACAC,MAAA;AAAA,MAAA,MACAC,MAAA;AAAA,MAAA,QACAC,MAAA;AAAA,MAAA,WACAC,MAAA;AAAA,MACA,WAAW;AAAA,QACT,UAASC,WAAW,cAAXA,mBAAW;AAAA,QACpB,QAAOA,WAAW,cAAXA,mBAAW;AAAA,MACpB;AAAA,IACF;AAAA,EACF,CAAC;AAGDC,QAAAA,OAAO,EAAE,qBAAqB;AAE9B,QAAM,YAAY;AAAA,IAChB,YAAY;AAAA,IACZ,UAAU;AAAA,IACV,aAAa;AAAA,IACb,YAAY;AAAA,EACd;AAEA,QAAM,UAAU,IAAIC,qBAAU,gBAAgB,UAAU,YAAY,GAAG;AACvE,QAAM,WAAW,IAAIA,qBAAU,gBAAgB,UAAU,aAAa,GAAG;AACzE,QAAM,QAAQ,IAAIA,qBAAU,gBAAgB,UAAU,UAAU,GAAG;AACnE,QAAM,UAAU,IAAIA,qBAAU,gBAAgB,UAAU,YAAY,GAAG;AAsC1D,QAAA,iBAETC,MAAA;AAAA,IACF,CACE,EAAE,MAAM,UAAU,UAAU,UAAAvC,WAAU,aAAa,YAAY,GAC/D,QACG;AACG,YAAA,YAAYC,aAAmC,IAAI;AACzD,YAAM,SAASE,MAAAA,SAAS,CAAS,UAAA,MAAM,MAAM;AAC7C,YAAM,KAAKA,MAAAA,SAAS,CAAS,UAAA,MAAM,EAAE;AACrC,YAAM,aAAa,SAAS;AAC5B,YAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AACrD,YAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AAE5CqC,qBAAA,CAAC,QAAQ,UAAU;;AACtB,aAAAlD,MAAA,UAAU,YAAV,gBAAAA,IAAmB,SAAS;AACpB,WAAAC,MAAA,UAAA,YAAA,gBAAAA,IAAS,OAAO;AAAA,QAC5B;AAEA,YAAI,YAAY;AACd,oBAAU,QAAQ,gBAAgB,KAAK,QAAQ6C,MAAU,UAAA;AAAA,QAC3D;AAAA,MAAA,GACC,EAAE;AAELrB,YAAA,UAAU,MAAM,MAAA;;AAAM,gBAAAzB,MAAA,UAAU,YAAV,gBAAAA,IAAmB;AAAA,SAAW,CAAA,CAAE;AAEhD,YAAA,SAASY,MAAAA,YAAY,MAAM;;AAC/B,SAAAZ,MAAA,UAAU,YAAV,gBAAAA,IAAmB,KAAK,OAAO,OAAO,GAAG;AAAA,MACxC,GAAA,CAAC,UAAU,OAAO,IAAI,CAAC;AAEpB,YAAA,UAAUY,MAAAA,YAAY,MAAM;;AAChC,SAAAZ,MAAA,UAAU,YAAV,gBAAAA,IAAmB,KAAK,CAAC,OAAO,OAAO,GAAG;AAAA,MACzC,GAAA,CAAC,UAAU,OAAO,IAAI,CAAC;AAE1B,YAAM,UAAUY,MAAA;AAAA,QACd,CAAY,aAAA;;AACA,WAAAZ,MAAA,UAAA,YAAA,gBAAAA,IAAS,MAAM,UAAU;AAAA,QACrC;AAAA,QACA,CAAC,QAAQ;AAAA,MAAA;AAGX,YAAM,WAAWY,MAAA;AAAA,QACf,CAAY,aAAA;;AACA,WAAAZ,MAAA,UAAA,YAAA,gBAAAA,IAAS,MAAM,UAAU;AAAA,QACrC;AAAA,QACA,CAAC,QAAQ;AAAA,MAAA;AAGX,YAAM,WAAWY,MAAA;AAAA,QACf,CAAS,UAAA;;AACP,cAAI,CAAC,YAAY;AACf,aAAAZ,MAAA,UAAU,YAAV,gBAAAA,IAAmB,MAAM,QAAQ,MAAM,WAAW,GAAG;AAAA,UACvD;AAAA,QACF;AAAA,QACA,CAAC,UAAU,UAAU;AAAA,MAAA;AAGvB,YAAM,UAAUY,MAAA;AAAA,QACd,CAAS,UAAA;;AACP,cAAI,CAAC,YAAY;AACf,aAAAZ,MAAA,UAAU,YAAV,gBAAAA,IAAmB,MAAM,OAAO,MAAM,WAAW,GAAG;AAAA,UACtD;AAAA,QACF;AAAA,QACA,CAAC,UAAU,UAAU;AAAA,MAAA;AAGvB,YAAM,QAAQY,MAAA;AAAA,QACZ,CAAS,UAAA;;AACP,cAAI,CAAC,YAAY;AACf,aAAAZ,MAAA,UAAU,YAAV,gBAAAA,IAAmB,MAAM,GAAG,OAAO,MAAM,WAAW;AAAA,UACtD;AAAA,QACF;AAAA,QACA,CAAC,UAAU,UAAU;AAAA,MAAA;AAGvB,YAAM,UAAUY,MAAA;AAAA,QACd,CAAS,UAAA;;AACP,cAAI,CAAC,YAAY;AACf,aAAAZ,MAAA,UAAU,YAAV,gBAAAA,IAAmB,MAAM,GAAG,QAAQ,MAAM,WAAW;AAAA,UACvD;AAAA,QACF;AAAA,QACA,CAAC,UAAU,UAAU;AAAA,MAAA;AAGvB,YAAM,YAAYY,MAAA;AAAA,QAChB,CAAS,UAAA;AACH,cAAA,MAAM,SAAS,SAAS;AAC1B,gBAAI,SAAS,UAAU;AACrB,wBAAU,QAAQ,aAAa,OAC7B,oBAAoB,OAAO;AAAA,YAAA,OACxB;AACL,wBAAU,QAAQ,aAAa,OAC7B,oBAAoB,OAAO;AAAA,YAC/B;AAAA,UACF;AAAA,QACF;AAAA,QACA,CAAC,IAAI;AAAA,MAAA;AAGP,YAAM,UAAUA,MAAA;AAAA,QACd,CAAS,UAAA;AACH,cAAA,MAAM,SAAS,SAAS;AAC1B,gBAAI,SAAS,UAAU;AACrB,wBAAU,QAAQ,aAAa,OAC7B,oBAAoB,OAAO;AAAA,YAAA,OACxB;AACL,wBAAU,QAAQ,aAAa,OAC7B,oBAAoB,OAAO;AAAA,YAC/B;AAAA,UACF;AAAA,QACF;AAAA,QACA,CAAC,IAAI;AAAA,MAAA;AAGPa,YAAAA,UAAU,MAAM;AACd,YAAI,CAACf,WAAU;AACL,kBAAA,iBAAiB,WAAW,OAAO;AAClC,mBAAA,iBAAiB,WAAW,QAAQ;AACvC,gBAAA,iBAAiB,WAAW,KAAK;AAC/B,kBAAA,iBAAiB,WAAW,OAAO;AAEvC,cAAA,OAAO,WAAW,aAAa;AAC1B,mBAAA,iBAAiB,WAAW,SAAS;AACrC,mBAAA,iBAAiB,SAAS,OAAO;AAAA,UAC1C;AAAA,QACF;AAEA,eAAO,MAAM;AACH,kBAAA,oBAAoB,WAAW,OAAO;AACrC,mBAAA,oBAAoB,WAAW,QAAQ;AAC1C,gBAAA,oBAAoB,WAAW,KAAK;AAClC,kBAAA,oBAAoB,WAAW,OAAO;AAE1C,cAAA,OAAO,WAAW,aAAa;AAC1B,mBAAA,oBAAoB,WAAW,SAAS;AACxC,mBAAA,oBAAoB,SAAS,OAAO;AAAA,UAC7C;AAAA,QAAA;AAAA,MACF,GACC,CAACA,WAAU,WAAW,SAAS,SAAS,SAAS,UAAU,KAAK,CAAC;AAEpEe,YAAAA,UAAU,MAAM;AACd,YAAIf,WAAU;AACZ,oBAAU,QAAQ,aAAa,OAAO,oBAAoB,OAAO;AACjE,oBAAU,QAAQ,aAAa,SAAS,oBAAoB,OAAO;AACnE,oBAAU,QAAQ,aAAa,QAAQ,oBAAoB,OAAO;AAAA,QAAA,OAC7D;AACL,oBAAU,QAAQ,aAAa,OAAO,oBAAoB,OAAO;AACjE,oBAAU,QAAQ,aAAa,SAC7B,oBAAoB,OAAO;AAC7B,oBAAU,QAAQ,aAAa,QAAQ,oBAAoB,OAAO;AAAA,QACpE;AAAA,MAAA,GACC,CAACA,SAAQ,CAAC;AAEbe,YAAAA,UAAU,MAAM;AACR,cAAA,YAAY,MAAM,WAAW,IAAI;AACjC,cAAA,eAAe,MAAM,WAAW,KAAK;AAE3C,cAAM0B,OAAM,UAAU;AACtB,YAAIA,MAAK;AACPA,eAAI,iBAAiB,WAAW,SAAS;AACzCA,eAAI,iBAAiB,cAAc,YAAY;AAAA,QACjD;AAEA,eAAO,MAAM;AACX,cAAIA,MAAK;AACPA,iBAAI,oBAAoB,WAAW,SAAS;AAC5CA,iBAAI,oBAAoB,cAAc,YAAY;AAAA,UACpD;AAAA,QAAA;AAAA,MACF,GACC,CAAC,WAAW,UAAU,CAAC;AAE1B1B,YAAAA,UAAU,MAAM;AAEd,YAAI,YAAY;AACd,oBAAU,QAAQ,aAAa,OAAO,oBAAoB,OAAO;AAAA,QAAA,OAC5D;AACL,cAAI,SAAS,UAAU;AACrB,sBAAU,QAAQ,aAAa,OAC7B,oBAAoB,OAAO;AAAA,UAAA,OACxB;AACL,sBAAU,QAAQ,aAAa,OAC7B,oBAAoB,OAAO;AAAA,UAC/B;AAAA,QACF;AAAA,MAAA,GACC,CAAC,YAAY,IAAI,CAAC;AAEV2B,yBAAA;AAAA,QACT;AAAA,UACE,MAAM;AAAA,UACN,UAAA1C;AAAA,UACA,UAAU;AAAA,UACV,MAAM;AAAA,UACN,UAAU,CAAS,UAAA;AACjB,kBAAM,eAAe;AACd;UACT;AAAA,QACF;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,UAAU;AAAA,UACV,UAAAA;AAAA,UACA,MAAM;AAAA,UACN,UAAU,CAAS,UAAA;AACjB,kBAAM,eAAe;AACb;UACV;AAAA,QACF;AAAA,MAAA,CACD;AAED,YAAM,SAASI,MAAA;AAAA,QACb,OAAO;AAAA,UACL,UAAU,UAAU;AAAA,UACpB,QAAQ,MAAM,OAAO;AAAA,UACrB,SAAS,MAAM,QAAQ;AAAA,UACvB,SAAS,CAAC,WAAW,QAAS,QAAQ,QAAQ;AAAA,UAC9C,UAAU,CAAC,WAAW,SAAU,SAAS,QAAQ;AAAA,UACjD,SAAS,CAAC,YAAY,QAAQ,QAAQ,EAAE,WAAW;AAAA,UACnD,UAAU,CAAC,YAAY,QAAQ,SAAS,EAAE,WAAW;AAAA,UACrD,SAAS,CAAC,YAAY,QAAQ,QAAQ,EAAE,WAAW;AAAA,UACnD,OAAO,CAAC,YAAY,QAAQ,MAAM,EAAE,WAAW;AAAA,UAC/C,eAAe,CAACuC,cACd;;AAAA,oBAAArD,MAAA,UAAU,YAAV,gBAAAA,IAAmB,MAAMqD;AAAAA;AAAAA,QAAQ;AAAA;AAAA,QAGrC,CAAC,QAAQ,SAAS,SAAS,UAAU,SAAS,OAAO,UAAU,OAAO;AAAA,MAAA;AAGpDC,gCAAA,KAAK,MAAM,MAAM;AAErC,aACGzB,2BAAAA,KAAA,sBAAsB,UAAtB,EAA+B,OAAO,QACrC,UAAA;AAAA,QAAAF,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,KAAK;AAAA,YACL,MAAM,CAAC,QAAQ,GAAG,UAAU;AAAA,YAC5B,YAAY;AAAA,YACZ;AAAA,YACA,eAAa;AAAA,YACb;AAAA,UAAA;AAAA,QACF;AAAA,QACC;AAAA,MACH,EAAA,CAAA;AAAA,IAEJ;AAAA,EACF;AAEA,iBAAe,eAAe;AAAA,IAC5B,MAAM;AAAA,IACN,aAAa;AAAA,IACb,aAAa;AAAA,EACf;AC5VA,WAAS,sBAAsB,OAAe,QAA2B;AAEjE,UAAA,eAAe,OAAO,SAAS;AACrC,QAAI,QAAQ;AAAuB,eAAA;AAAA;AACrB,eAAA;AAGd,UAAM,OAAS,OAAO,MAAM,OAAO,OAAQ,KAAK,KAAM;AAG/C,WAAA,IAAI,KAAK,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,KAAK;AAAA,EAChD;AAKA,WAAS,qBAAqB,OAAe,QAA2B;AAChE,UAAA,SAAS,sBAAsB,OAAO,MAAM;AAClD,WAAO,SAAS,OAAO;AAAA,EACzB;AAKgB,WAAA,aACd,QACA,cACS;;AACH,UAAA,eAAe,qBAAqB,GAAG,MAAM;AAC7C,UAAA,gBAAgB,sBAAsB,GAAG,MAAM;AAGrD,UAAM,cAAc;AAAA,MAClB,MAAI3B,MAAA,iCAAQ,aAAR,gBAAAA,IAAkB,KAAI,eAAe;AAAA,MACzC,MAAIC,MAAA,iCAAQ,aAAR,gBAAAA,IAAkB,KAAI,eAAe;AAAA,MACzC,MAAI,sCAAQ,aAAR,mBAAkB,KAAI,gBAAgB;AAAA,MAC1C,MAAI,sCAAQ,aAAR,mBAAkB,KAAI,gBAAgB;AAAA,IAAA;AAG5C,YACE,6CAAc,KAAI,YAAY,OAC9B,6CAAc,KAAI,YAAY,OAC9B,6CAAc,KAAI,YAAY,OAC9B,6CAAc,KAAI,YAAY;AAAA,EAElC;AAKgB,WAAA,eAAe,OAAe,MAAgB;AAC5D,WAAO,KAAK;AAAA,MAAO,CAAC,MAAM,SACxB,KAAK,IAAI,OAAQ,QAAQ,KAAK,EAAG,IAAI,KAAK,IAAI,OAAQ,QAAQ,KAAK,EAAG,IAClE,OACA;AAAA,IAAA;AAAA,EAER;AAKgB,WAAA,0BACd,iBACA,eACA;AACA,UAAM,wBAAwB,eAAe,iBAAiB,CAAC,GAAG,KAAK,EAAE,CAAC;AACpE,UAAA,sBAAsB,eAAe,eAAe;AAAA,MACxD,KAAK,KAAK;AAAA,MACT,IAAI,KAAK,KAAM;AAAA,IAAA,CACjB;AAEM,WAAA;AAAA,MACL,oBAAoB,wBAAyB,kBAAkB,KAAK;AAAA,MACpE,kBAAkB,sBAAuB,gBAAgB,KAAK;AAAA,IAAA;AAAA,EAElE;ACvEA,QAAM,UAAU;AAmFH,QAAA,iBAAiB,CAAC;AAAA,IAC7B;AAAA,IACA,UAAAS;AAAA,IACA;AAAA,EACF,MAA2C;AACzC,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,CAAC,YAAY,aAAa,IAAI6C,eAAkB,KAAK;AAC3D,UAAM,aAAa1C,MAAAA,SAAS,CAAS,UAAA,MAAM,UAAU;AAC/C,UAAA,EAAE,aAAa;AACrB,UAAM,SAASA,MAAAA,SAAS,CAAS,UAAA,MAAM,MAAM;AACvC,UAAA,UAAUF,aAAgB,KAAK;AAErC,UAAM,cAAcC,MAAA;AAAA,MAClB,OAAO7B,QAAO,SAA6B;AACzC,cAAMsE,aAAW,6BAAM,cAAa,SAAY,6BAAM,WAAW;AACjE,cAAM,8BACJ,6BAAM,gCAA+B,SACjC,6BAAM,6BACN;AAEN,YACE,CAAC,QAAQ,WACT,CAAC,8BACA,+BACCtE,iCAAO,KAAK,CAAA,SAAQ,CAAC,aAAa,QAAQ,KAAK,QAAQ,KACzD;AAEA,gBAAM,EAAE,GAAG,GAAG,EAAE,IAAI,gBAAgBA,MAAK;AAEzC,gBAAM,SAAS,UAAU,GAAG,GAAG,GAAGsE,SAAQ;AAE1C,cAAI,CAAC,YAAY;AACf,0BAAc,IAAI;AAAA,UACpB;AAEW;QACb;AAAA,MACF;AAAA;AAAA,MAEA,CAAC,YAAY,UAAU,KAAK;AAAA,IAAA;AAG9B,UAAM,iBAAiBzC,MAAA;AAAA,MACrB,OACE7B,QACA,OAAuB,EAAE,UAAU,MAAM,yBAAyB,YAC/D;AACG,cAAA,EAAE,wBAA4B,IAAA;AAEpC,YACE,CAAC,2BACA,4BACCA,iCAAO,KAAK,CAAA,SAAQ,CAAC,aAAa,QAAQ,KAAK,QAAQ,KACzD;AACM,gBAAA,EAAE,MAAM,MAAM,MAAM,MAAM,MAAM,KAAS,IAAA,gBAAgBA,MAAK;AAEpE,cAAI,CAAC,WAAW,SAAS,IAAI,GAAG;AAIxB,kBAAA,EAAE,oBAAoB,iBAAA,IAC1B;AAAA,cACE,qCAAU;AAAA,cACV,qCAAU;AAAA,YAAA;AAGd,kBAAK,qCAAU,OAAO,oBAAoB,kBAAkB;AAAA,UAC9D;AAEA,iBAAM,qCAAU,OAAO,GAAG,6BAAM;AAEhC,iBAAM,qCAAU;AAAA,YACd,IAAI4D,MAAA;AAAA,cACF,IAAIpC,cAAQ,MAAM,MAAM,IAAI;AAAA,cAC5B,IAAIA,cAAQ,MAAM,MAAM,IAAI;AAAA,YAC9B;AAAA,YACA,6BAAM;AAAA,YACN;AAAA,cACE,OAAO;AAAA,cACP,aAAa;AAAA,cACb,cAAc;AAAA,cACd,eAAe;AAAA,cACf,YAAY;AAAA,YACd;AAAA;AAAA,QAEJ;AAAA,MACF;AAAA,MACA,CAAC,QAAQ,UAAU,UAAU;AAAA,IAAA;AAG/B,UAAM,eAAeK,MAAA;AAAA,MACnB,CAAC,YAAsB;AACrB,YAAI,cAA0C;AAE9C,YAAI,mCAAS,QAAQ;AAEnB,wBAAc,QAAQ,OAAO,CAAC,KAAK,OAAO;AACxC,kBAAM,OAAO,MAAM,KAAK,CAAK,MAAA,EAAE,OAAO,EAAE;AACxC,gBAAI,MAAM;AACR,kBAAI,KAAK,IAAI;AAAA,YAAA,OACR;AACL,oBAAM,IAAI;AAAA,gBACR,uBAAuB,EAAE;AAAA,cAAA;AAAA,YAE7B;AAEO,mBAAA;AAAA,UACT,GAAG,CAAE,CAAA;AAAA,QACP;AAEO,eAAA;AAAA,MACT;AAAA,MACA,CAAC,KAAK;AAAA,IAAA;AAGR,UAAM,kBAAkBA,MAAA;AAAA,MACtB,CAAC,SAAmB,SAA4B;AACxC,cAAA,cAAc,aAAa,OAAO;AAExC,oBAAY,eAAe,OAAO;AAAA,UAChC;AAAA,UACA,4BAA4B,6BAAM;AAAA,QAAA,CACnC;AAAA,MACH;AAAA,MACA,CAAC,UAAU,aAAa,cAAc,KAAK;AAAA,IAAA;AAG7C,UAAM,qBAAqBA,MAAA;AAAA,MACzB,OAAO,SAAmB,SAAyB;AAC3C,cAAA,cAAc,aAAa,OAAO;AAExC,cAAM,eAAe,eAAe,OAAO,EAAE,UAAU,GAAG,MAAM;AAAA,MAClE;AAAA,MACA,CAAC,UAAU,gBAAgB,cAAc,KAAK;AAAA,IAAA;AAGhD4C,UAAAA,gBAAgB,MAAM;AACpB,qBAAe,OAAO;AAEhB,YAAA,aAAY,+BAAO,SAAQ;AACzB,cAAA,CAAC,QAAQ,SAAS;AAEpB,kBAAM,YAAY,OAAO,EAAE,UAAU,MAAO,CAAA;AAC5C,kBAAM,eAAe,OAAO,EAAE,UAAU,MAAO,CAAA;AAC/C,oBAAQ,UAAU;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAEK;IAAA,GACJ,CAAC,UAAU,aAAa,OAAO,UAAU,QAAQ,cAAc,CAAC;AAExDJ,uBAAA;AAAA,MACT;AAAA,QACE,MAAM;AAAA,QACN,UAAA1C;AAAA,QACA,UAAU;AAAA,QACV,MAAM,CAAC,iBAAiB;AAAA,QACxB,UAAU,MAAM,YAAY,KAAK;AAAA,MACnC;AAAA,IAAA,CACD;AAED,WAAO,EAAE,aAAa,iBAAiB,oBAAoB,WAAW;AAAA,EACxE;ACpPa,QAAA,OAAsB,CAAC,EAAE,OAAO,IAAI,MAAM,SAAS,eAAe;AACvE,UAAA,UAAUI,cAAQ,MAAM,IAAI2C,MAAA,cAAA,EAAgB,KAAK,KAAK,GAAG,CAAC,KAAK,CAAC;AAEtE,UAAM,EAAE,OAAO,cAAc,IAAIxB,kBAAU;AAAA,MACzC,MAAM;AAAA,QACJ,OAAO,CAAC,MAAS,MAAS,IAAO;AAAA,QACjC,eAAe;AAAA,MACjB;AAAA,MACA,IAAI;AAAA,QACF,OAAO,CAAC,MAAM,MAAM,IAAI;AAAA,QACxB,eAAe;AAAA,MACjB;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,UAAU,WAAW,SAAY;AAAA,MACnC;AAAA,IAAA,CACD;AAGC,WAAAN,+BAACK,QAAAA,EAAE,QAAF,EAAS,UAAU,EAAE,IAAI,MAAM,OAAO,GAAG,OACxC,UAAAL,2BAAA;AAAA,MAACK,QAAAA,EAAE;AAAA,MAAF;AAAA,QACC,QAAO;AAAA,QACP,SAAS;AAAA,QACT,KAAK;AAAA,QACL,WAAW;AAAA,QACX,aAAa;AAAA,QACb,MAAME,MAAA;AAAA,QAEN,yCAAC,aAAU,EAAA,QAAO,OAAM,QAAQ,SAAS,WAAWwB,MAAAA,cAAc;AAAA,MAAA;AAAA,IAEtE,EAAA,CAAA;AAAA,EAEJ;AAEA,OAAK,eAAe;AAAA,IAClB,SAAS;AAAA,EACX;ACrCa,QAAA,iBAA0C,CAAC;AAAA,IACtD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAEI7B,2BAAA,KAAAM,qBAAA,EAAA,UAAA;AAAA,IAAAR,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,UAAU,KAAK;AAAA,MAAA;AAAA,IACjB;AAAA,IACAA,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,OAAO;AAAA,QACb;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA,GACF;AAGF,iBAAe,eAAe;AAAA,IAC5B,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;ACrCa,QAAA,MAAoB,CAAC;AAAA,IAChC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,MAAM;AACJ,UAAM,iBAAiB,OAAO;AAExB,UAAA,EAAE,MAAM,IAAIM,kBAAU;AAAA,MAC1B,MAAM;AAAA,QACJ,OAAO,CAAC,MAAS,MAAS,IAAO;AAAA,MACnC;AAAA,MACA,IAAI;AAAA,QACF,OAAO,CAAC,gBAAgB,gBAAgB,cAAc;AAAA,MACxD;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,UAAU,WAAW,SAAY;AAAA,MACnC;AAAA,IAAA,CACD;AAEK,UAAA,kBAAkBnB,cAAQ,MAAM,IAAIY,MAAAA,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC;AAE/D,0CACGM,QAAE,EAAA,OAAF,EAAQ,UAAU,EAAE,IAAI,MAAM,UAAU,OACvC,yCAACJ,mBAAU,EAAA,UAAU,CAAC,GAAG,GAAG,CAAC,GAC3B,UAAAD,2BAAA;AAAA,MAACgC,QAAA;AAAA,MAAA;AAAA,QACE,GAAG;AAAA,QACJ,KAAK;AAAA,QACL,cAAc;AAAA,UACZ,KAAK;AAAA,UACL,WAAW;AAAA,UACX,aAAa;AAAA,UACb,OAAO;AAAA,UACP;AAAA,UACA,MAAMzB,MAAA;AAAA,UACN,GAAI,KAAK,gBAAgB,CAAC;AAAA,QAC5B;AAAA,QACA,eAAe;AAAA;AAAA;AAAA,UAGb,UAAU,CAAC,KAAK,KAAK,CAAC;AAAA,UACtB,GAAI,KAAK,iBAAiB,CAAC;AAAA,QAC7B;AAAA,MAAA;AAAA,IAAA,EAEJ,CAAA,EACF,CAAA;AAAA,EAEJ;AAEA,MAAI,eAAe;AAAA,IACjB,SAAS;AAAA,EACX;ACrDa,QAAA,gBAAwC,CAAC;AAAA,IACpD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG;AAAA,EACL,MAEIL,2BAAA,KAAAM,qBAAA,EAAA,UAAA;AAAA,IAAAR,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,IACAA,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACE,GAAG;AAAA,QACJ;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP;AAAA,QACA;AAAA,MAAA;AAAA,IACF;AAAA,EAAA,GACF;AAGF,gBAAc,eAAe;AAAA,IAC3B,SAAS;AAAA,IACT,QAAQ;AAAA,EACV;ACyDa,QAAA,OAAsB,CAAC;AAAA,IAClC;AAAA,IACA,UAAAjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;;AACJ,UAAM,iBAAiB;AACvB,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AACrC,UAAA,OAAO,SAAS,CAAA,UAAS,MAAM,MAAM,KAAK,CAAK,MAAA,EAAE,OAAO,EAAE,CAAC;AACjE,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AACrD,UAAM,mBAAmB,SAAS,CAAS,UAAA,MAAM,gBAAgB;AACjE,UAAM,gBAAgB,SAAS,CAAS,UAAA,MAAM,aAAa;AAC3D,UAAM,kBAAkB,SAAS,CAAS,UAAA,MAAM,eAAe;AAC/D,UAAM,sBAAsB,SAAS,CAAS,UAAA,MAAM,mBAAmB;AACvE,UAAM,cAAc,SAAS,CAAA,UAAS,MAAM,iBAAiB,SAAS,EAAE,CAAC;AACzE,UAAM,WAAW,SAAS,CAAA,UAAA;;AAAS,cAAAV,MAAA,MAAM,YAAN,gBAAAA,IAAe,SAAS;AAAA,KAAG;AAC9D,UAAM,aAAa,SAAS,CAAA,UAAA;;AAAS,cAAAA,MAAA,MAAM,eAAN,gBAAAA,IAAkB,SAAS;AAAA,KAAG;AACnE,UAAM,gBAAgB,SAAS,CAAA,UAAA;;AAAS,eAAAA,MAAA,MAAM,eAAN,gBAAAA,IAAkB,UAAS;AAAA,KAAC;AACpE,UAAM,SAAS,SAAS,CAAS,UAAA,MAAM,cAAc;AAErD,UAAM,aAAa,eAAe;AAC5B,UAAA;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAM,WAAW;AAAA,MACjB,eAAe;AAAA,IACb,IAAA;AAEE,UAAA,QAAQW,aAAqB,IAAI;AACvC,UAAM,CAAC,QAAQ,SAAS,IAAI4C,eAAkB,KAAK;AACnD,UAAM,CAAC,aAAa,cAAc,IAAIA,eAAkB,KAAK;AAEvD,UAAA,kBAAkB,UAAU,cAAc;AAE1C,UAAA,mBAAmB,gBACrB,kBACE,MAAM,KAAK,kBACX,MAAM,KAAK,kBACb,MAAM,KAAK;AAET,UAAA,cAAczC,MAAAA,QAAQ,MAAM;AAEhC,YAAM,gBAAgB,MAAM,OAAO,CAAK,MAAA,EAAE,WAAW,EAAE;AAEhD,aAAA,cAAc,SAAS,KAAK;AAAA,IAClC,GAAA,CAAC,OAAO,IAAI,WAAW,CAAC;AAErB,UAAA,aAAaF,MAAAA,YAAY,MAAM;AACnC,UAAI,aAAa;AACf,YAAI,aAAa;AACf,8BAAoB,iBAAiB,OAAO,CAAK,MAAA,MAAM,EAAE,CAAC;AAAA,QAAA,OACrD;AACL,8BAAoB,CAAC,GAAG,kBAAkB,EAAE,CAAC;AAAA,QAC/C;AAAA,MACF;AAAA,IAAA,GACC,CAAC,aAAa,kBAAkB,IAAI,aAAa,mBAAmB,CAAC;AAExE,UAAM,CAAC,EAAE,cAAc,eAAe,iBAAA,CAAkB,IAAIqB,QAAA;AAAA,MAC1D,OAAO;AAAA,QACL,MAAM;AAAA,UACJ,cAAc,SAAS,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AAAA,UACzD,eAAe,CAAC,GAAG,EAAE,WAAW,IAAI,CAAC;AAAA,UACrC,kBAAkB,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,QAC3C;AAAA,QACA,IAAI;AAAA,UACF,cAAc,WACV;AAAA,YACA,SAAS;AAAA,YACT,SAAS;AAAA,YACT,kBAAkB,SAAS,IAAI,KAAK,SAAS;AAAA,UAAA,IAE7C,CAAC,GAAG,GAAG,CAAC;AAAA,UACZ,eAAe,CAAC,GAAG,EAAE,WAAW,IAAI,CAAC;AAAA,UACrC,kBAAkB,CAAC,GAAG,EAAE,WAAW,KAAK,CAAC;AAAA,QAC3C;AAAA,QACA,QAAQ;AAAA,UACN,GAAG;AAAA,UACH,UAAU,YAAY,CAAC,aAAa,SAAY;AAAA,QAClD;AAAA,MAAA;AAAA,MAEF,CAAC,YAAY,UAAU,UAAU,UAAU,eAAe;AAAA,IAAA;AAG5D,UAAM,OAAO,QAAQ;AAAA,MACnB;AAAA,MACA;AAAA;AAAA,MAEA,KAAK,CAAA,QAAO,gBAAgB,IAAI,GAAG;AAAA,MACnC,aAAa,MAAM;AACjB,sBAAc,EAAE;AAChB,kBAAU,IAAI;AAAA,MAChB;AAAA,MACA,WAAW,MAAM;AACf,sBAAc,IAAI;AAClB,kBAAU,KAAK;AACf,+CAAY;AAAA,MACd;AAAA,IAAA,CACD;AAED2B,YAAA,UAAU,UAAU,CAAC,cAAc,YAAY,QAAW,SAAS;AACnEA,YAAA;AAAA,MACE,UAAU,aAAa,CAAC,cAAc,YAAY;AAAA,MAClD;AAAA,IAAA;AAEFA,sBAAU,YAAY,UAAU;AAEhC,UAAM,sBAAsB,mBAAmB;AACzC,UAAA,QAAQ,sBACV,KAAK,cAAc,MAAM,KAAK,aAC9B,KAAK,QAAQ,MAAM,KAAK;AAE5B,UAAM,iBAAiB,KAAK;AAC5B,UAAM,EAAE,aAAa,WAAW,IAAI,eAAe;AAAA,MACjD,UAAUlD,aAAY;AAAA,MACtB,eAAe,CAAC,UAAoC;AAClD,uBAAe,SAAS,aAAa;AACrC,kBAAU,IAAI;AACd,uDAAgB,MAAM;AAAA,MACxB;AAAA,MACA,cAAc,CAAC,UAAoC;AACjD,uBAAe,SAAS,aAAa;AACrC,kBAAU,KAAK;AACf,qDAAe,MAAM;AAAA,MACvB;AAAA,IAAA,CACD;AAED,UAAM,gBAAgBI,MAAA;AAAA,MACpB,MACE,aACE,WAAW;AAAA,QACT;AAAA,QACA;AAAA,QACA,MAAM;AAAA,QACN,QAAQ;AAAA,QACR,SAAS;AAAA,QACT;AAAA,QACA,UAAU;AAAA,QACV;AAAA,MAAA,CACD,IAGEa,2BAAA,IAAAQ,WAAA,UAAA,EAAA,UAAA,KAAK,OACJR,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA,OAAO,KAAK,QAAQ;AAAA,UACpB,MAAM,WAAW;AAAA,UACjB,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,UAAU;AAAA,QAAA;AAAA,MAAA,IAGZA,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA,MAAM;AAAA,UACN,SAAS;AAAA,UACT;AAAA,UACA;AAAA,UACA;AAAA,UACA,QAAQ;AAAA,UACR,UAAU;AAAA,UACV,UAAU;AAAA,QAAA;AAAA,MAAA,GAGhB;AAAA,MAEJ;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAGF,UAAM,iBAAiBb,MAAA;AAAA,MACrB,MAAA;;AACE,wBAEIe,2BAAAA,KAAAM,WAAA,UAAA,EAAA,UAAA;AAAA,UAAAR,2BAAA,IAACK,QAAE,EAAA,OAAF,EAAQ,UAAU,eACjB,UAAAL,2BAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,SAAS;AAAA,cACT,SAAS;AAAA,cACT,QAAQ,MAAM,KAAK,MAAM;AAAA,cACzB,UAAU,MAAM,KAAK,MAAM;AAAA,cAC3B,UAAU,MAAM,KAAK,MAAM;AAAA,cAC3B,iBAAiB,MAAM,KAAK,MAAM;AAAA,cAClC,cAAc,MAAM,KAAK,MAAM;AAAA,cAC/B,QAAQ,cAAc,UAAU,cAAc;AAAA,cAC9C,OACE,cAAc,UAAU,cAAc,WAClC,MAAM,KAAK,MAAM,cACjB,MAAM,KAAK,MAAM;AAAA,cAEvB,MAAK;AAAA,cACL;AAAA,YAAA;AAAA,UAAA,GAEJ;AAAA,UACC,YACEA,2BAAA,IAAAK,UAAE,OAAF,EAAQ,UAAU,kBACjB,UAAAL,2BAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM;AAAA,cACN,SAAS;AAAA,cACT,UAAU,MAAM,KAAK,MAAM;AAAA,cAC3B,UAAU,MAAM,KAAK,MAAM;AAAA,cAC3B,UAAU,MAAM,KAAK,MAAM;AAAA,cAC3B,iBAAiB,MAAM,KAAK,MAAM;AAAA,cAClC,cAAc,MAAM,KAAK,MAAM;AAAA,cAC/B,SAAS;AAAA,cACT,SAAQ3B,MAAA,MAAM,KAAK,aAAX,gBAAAA,IAAqB;AAAA,cAC7B,QAAQ,cAAc,UAAU,cAAc;AAAA,cAC9C,OACE,cAAc,UAAU,cAAc,YAClCC,MAAA,MAAM,KAAK,aAAX,gBAAAA,IAAqB,eACrB4D,MAAA,MAAM,KAAK,aAAX,gBAAAA,IAAqB;AAAA,cAE3B;AAAA,YAAA;AAAA,UAAA,GAEJ;AAAA,QAAA,GAEJ;AAAA;AAAA,MAEJ;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,SACjB7D,MAAA,MAAM,KAAK,aAAX,gBAAAA,IAAqB;AAAA,SACrBC,MAAA,MAAM,KAAK,aAAX,gBAAAA,IAAqB;AAAA,SACrB,WAAM,KAAK,aAAX,mBAAqB;AAAA,QACrB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,MACnB;AAAA,IAAA;AAGF,UAAM,gBAAgBa,MAAA;AAAA,MACpB,MACE,eACA,eACEa,2BAAA,IAACmC,gBAAK,SAAS,MAAM,QAAQ,MAC1B,UAAY,YAAA;AAAA,QACX,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,MAAM,eAAe,KAAK;AAAA,MACpC,CAAA,GACH;AAAA,MAEJ,CAAC,aAAa,aAAa,MAAM,aAAa,aAAa,UAAU;AAAA,IAAA;AAIrE,WAAAjC,2BAAA;AAAA,MAACG,QAAAA,EAAE;AAAA,MAAF;AAAA,QACC,aAAa;AAAA,QACb,UAAU,EAAE,IAAI,MAAM,OAAO;AAAA,QAC7B,KAAK;AAAA,QACL,UAAU;AAAA,QACV,eAAe;AAAA,QACf,cAAc;AAAA,QACd,SAAS,CAAC,UAAkC;AACtC,cAAA,CAACtB,aAAY,CAAC,YAAY;AAC5B;AAAA,cACE;AAAA,cACA;AAAA,gBACE;AAAA,gBACA;AAAA,cACF;AAAA,cACA;AAAA;AAAA,UAEJ;AAAA,QACF;AAAA,QACA,eAAe,CAAC,UAAkC;AAChD,gBAAM,gBAAgB;AAClB,cAAA,CAACA,aAAY,CAAC,YAAY;AAC5B,2DAAgB,MAAM;AAAA,UACxB;AAAA,QACF;AAAA,QACA,eAAe,MAAM;AACnB,cAAI,CAACA,WAAU;AACb,2BAAe,IAAI;AACnB,2DAAgB,MAAM;AAAA,cACpB;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAAA,UAEJ;AAAA,QACF;AAAA,QACC,GAAI,KAAK;AAAA,QAET,UAAA;AAAA,UAAA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AAEA,OAAK,eAAe;AAAA,IAClB,WAAW;AAAA,EACb;ACxYa,QAAA,QAAwB,CAAC;AAAA,IACpC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;AACE,UAAA,kBAAkBI,cAAQ,MAAM,IAAIY,MAAAA,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC;AACzD,UAAA,UAAUf,aAAoB,IAAI;AACxC,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AACrD,UAAM,SAAS,SAAS,CAAS,UAAA,MAAM,cAAc;AAErD,UAAM,CAAC,EAAE,KAAK,aAAA,CAAc,IAAIsB,QAAA;AAAA,MAC9B,OAAO;AAAA,QACL,MAAM;AAAA,UACJ,KAAK,SAAS,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AAAA,UACvD,cAAc;AAAA,QAChB;AAAA,QACA,IAAI;AAAA,UACF,KAAK,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAAA,UACxC,cAAc;AAAA,QAChB;AAAA,QACA,QAAQ;AAAA,UACN,GAAG;AAAA,UACH,UAAU,YAAY,CAAC,aAAa,SAAY;AAAA,QAClD;AAAA,MAAA;AAAA,MAEF,CAAC,UAAU,YAAY,SAAS,QAAQ;AAAA,IAAA;AAGpC,UAAA,gBAAgBrB,MAAAA,YAAY,MAAM;;AACtC,YAAM,OAAO,IAAIL,MAAQ,QAAA,GAAG,GAAG,CAAC;AAChC,OAAAP,MAAA,QAAQ,YAAR,gBAAAA,IAAiB,WAAW,mBAAmB,MAAM;AAAA,IAAQ,GAC5D,CAAC,UAAU,OAAO,CAAC;AAEtByB,UAAAA,UAAU,MAAM,cAAA,GAAiB,CAAC,aAAa,CAAC;AAG9C,WAAAI,2BAAA;AAAA,MAACG,QAAAA,EAAE;AAAA,MAAF;AAAA,QACC,UAAU;AAAA,QACV,KAAK;AAAA,QACL,OAAO,CAAC,GAAG,GAAG,CAAC;AAAA,QACf,eAAe,MAAM,SAAS,IAAI;AAAA,QAClC,cAAc,MAAM,SAAS,KAAK;AAAA,QAClC,eAAe,CAAS,UAAA;AAElB,cAAA,MAAM,YAAY,YAAY,GAAG;AACnC,kBAAM,gBAAgB;AACR;UAChB;AAAA,QACF;AAAA,QAEA,UAAA;AAAA,UAAAL,2BAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAM,CAAC,GAAG,MAAM,QAAQ,IAAI,GAAG,IAAI;AAAA,cACnC,QAAO;AAAA,YAAA;AAAA,UACT;AAAA,UACAA,2BAAA;AAAA,YAACK,QAAAA,EAAE;AAAA,YAAF;AAAA,cACC,QAAO;AAAA,cACP,OAAO;AAAA,cACP,WAAW;AAAA,cACX,SAAS;AAAA,cACT,aAAa;AAAA,cACb,MAAME,MAAA;AAAA,cACN,KAAK;AAAA,YAAA;AAAA,UACP;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAEA,QAAM,eAAe;AAAA,IACnB,MAAM;AAAA,IACN,SAAS;AAAA,IACT,OAAO;AAAA,EACT;ACzDa,QAAA,OAAsB,CAAC;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,SAAS;AAAA,IACT;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;AACE,UAAA,UAAUvB,aAA4B,IAAI;AAChD,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AAC/C,UAAA,kBAAkBG,cAAQ,MAAM,IAAIY,MAAAA,MAAM,KAAK,GAAG,CAAC,KAAK,CAAC;AAC/D,UAAM,SAAS,SAAS,CAAS,UAAA,MAAM,cAAc;AAC/C,UAAA,UAAUf,aAAgB,KAAK;AAG/B,UAAA,EAAE,YAAY,IAAIsB,kBAAU;AAAA,MAChC,MAAM;AAAA,QACJ,aAAa;AAAA,MACf;AAAA,MACA,IAAI;AAAA,QACF,aAAa;AAAA,MACf;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,UAAU,WAAW,SAAY;AAAA,MACnC;AAAA,IAAA,CACD;AAEDA,YAAAA,UAAU,MAAM;AACR,YAAA,OAAO,MAAM,SAAS,CAAC;AACvB,YAAA,KAAK,MAAM,SAAS,CAAC;AACpB,aAAA;AAAA,QACL,MAAM;AAAA;AAAA,UAEJ,cAAc,CAAC,QAAQ,UACnB,CAAC,iCAAQ,GAAG,iCAAQ,IAAG,iCAAQ,MAAK,CAAC,IACrC,CAAC,yBAAI,GAAG,yBAAI,IAAG,yBAAI,MAAK,CAAC;AAAA,UAC7B,YAAY,CAAC,6BAAM,GAAG,6BAAM,IAAG,6BAAM,MAAK,CAAC;AAAA,QAC7C;AAAA,QACA,IAAI;AAAA,UACF,cAAc,CAAC,6BAAM,GAAG,6BAAM,IAAG,6BAAM,MAAK,CAAC;AAAA,UAC7C,YAAY,CAAC,yBAAI,GAAG,yBAAI,IAAG,yBAAI,MAAK,CAAC;AAAA,QACvC;AAAA,QACA,UAAU,CAAS,UAAA;AACjB,gBAAM,EAAE,cAAc,eAAe,MAAM;AAC3C,gBAAM,aAAa,IAAI1B,cAAQ,GAAG,YAAY;AAC9C,gBAAM,WAAW,IAAIA,cAAQ,GAAG,UAAU;AAE1C,gBAAMwD,SAAQ,SAAS,YAAY,GAAG,UAAU,GAAG,QAAQ,WAAW;AAC9D,kBAAA,QAAQ,KAAK,IAAIC,MAAaD,aAAAA,QAAO,IAAI,OAAO,GAAG,GAAG,KAAK,CAAC;AAAA,QACtE;AAAA,QACA,QAAQ;AAAA,UACN,GAAG;AAAA,UACH,UAAU,YAAY,CAAC,aAAa,SAAY;AAAA,QAClD;AAAA,MAAA;AAAA,OAED,CAAC,UAAU,YAAY,OAAO,IAAI,CAAC;AAEtCtC,UAAAA,UAAU,MAAM;AAEd,cAAQ,UAAU;AAAA,IACpB,GAAG,CAAE,CAAA;AAGH,WAAAI,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,UAAU,EAAE,IAAI,MAAM,OAAO;AAAA,QAC7B;AAAA,QACA;AAAA,QACA;AAAA,QACA,eAAe,CAAS,UAAA;AAElB,cAAA,MAAM,YAAY,YAAY,GAAG;AACnC,kBAAM,gBAAgB;AACR;UAChB;AAAA,QACF;AAAA,QAEA,UAAA;AAAA,UAAAF,2BAAA,IAAC,gBAAa,EAAA,QAAO,YAAW,KAAK,SAAS;AAAA,UAC9CA,2BAAA;AAAA,YAACK,QAAAA,EAAE;AAAA,YAAF;AAAA,cACC,QAAO;AAAA,cACP,SAAS;AAAA,cACT,aAAa;AAAA,cACb,OAAO;AAAA,YAAA;AAAA,UACT;AAAA,QAAA;AAAA,MAAA;AAAA,IAAA;AAAA,EAGN;AAEA,OAAK,eAAe;AAAA,IAClB,OAAO;AAAA,IACP,MAAM;AAAA,IACN,SAAS;AAAA,EACX;ACjEA,QAAM,yBAAyB;AAElBiC,QAAAA,SAAsB,CAAC;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAAvD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;AACJ,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AAGrD,UAAM,CAAC,QAAQ,SAAS,IAAI6C,eAAkB,KAAK;AACnD,UAAM,CAAC,aAAa,cAAc,IAAIA,eAAkB,KAAK;AAG7D,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,OAAO,MAAM,KAAK,CAAK,MAAA,EAAE,OAAO,EAAE;AAClC,UAAA;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe;AAAA,MACf,OAAO;AAAA,MACP;AAAA,IACE,IAAA;AACE,UAAA,OAAO,SAAS,CAAA,UAAS,MAAM,MAAM,KAAK,CAAQ,SAAA,KAAK,OAAO,MAAM,CAAC;AACrE,UAAA,KAAK,SAAS,CAAA,UAAS,MAAM,MAAM,KAAK,CAAQ,SAAA,KAAK,OAAO,MAAM,CAAC;AAGzE,UAAM,eAAe,OAAO,MAAM,KAAK,MAAM,YAAY;AACnD,UAAA,CAAC,aAAa,SAAS,IAAIzC,MAAA,QAAQ,MAAM,aAAa,IAAI,GAAG,CAAC,IAAI,CAAC;AACnE,UAAA,EAAE,aAAa,OAAA,IAAWA,MAAA;AAAA,MAC9B,MACE,yBAAyB;AAAA,QACvB;AAAA,QACA;AAAA,QACA,QAAQ,kBAAkB;AAAA,MAAA,CAC3B;AAAA,MACH,CAAC,MAAM,OAAO,aAAa;AAAA,IAAA;AAG7B,UAAM,CAAC,OAAO,eAAe,aAAa,IAAIA,cAAQ,MAAM;AACpD,YAAA,aAAa,UAAU,IAAI;AACjC,YAAM,aAAa,KAAK;AAClB,YAAA,WAAW,UAAU,EAAE;AAC7B,YAAM,WAAW,GAAG;AAEpB,UAAIiD,SAAQ;AAAA,QACV;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MAAA;AAGI,YAAA,CAACG,gBAAeC,cAAa,IAAI;AAAA,QACrC;AAAA,QACAJ;AAAAA,QACA;AAAA,MAAA;AAGF,UAAI,mBAAmB,OAAO;AAC5BA,iBAAQ;AAAA,UACN;AAAA,UACA;AAAA,UACAG;AAAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAEO,aAAA,CAACH,QAAOG,gBAAeC,cAAa;AAAA,IAAA,GAC1C,CAAC,MAAM,IAAI,QAAQ,aAAa,gBAAgB,WAAW,CAAC;AAEzD,UAAA,WAAWrD,MAAAA,QAAQ,MAAM;AAC7B,UAAI,cAAc;AAAA,QAChB,KAAK;AAAA,QACL,GAAG;AAAA,QACH,qBAAqB,aAAa,cAAc;AAAA,MAAA;AAGlD,UAAI,QAAQ;AAEJ,cAAA,SAAS,IAAIP,MAAQ,QAAA,EAAE,WAAW,aAAa,MAAM,SAAS,GAAG,CAAC;AACxE,gBAAQ,gBAAgB;AAAA,UACxB,KAAK;AACI,mBAAA,IAAI,OAAO,IAAI;AACtB;AAAA,UACF,KAAK;AACI,mBAAA,IAAI,OAAO,IAAI;AACtB;AAAA,QACF;AACc,sBAAA,YAAY,IAAI,MAAM;AAAA,MACtC;AAEO,aAAA;AAAA,IAAA,GACN,CAAC,KAAK,UAAU,GAAG,UAAU,aAAa,gBAAgB,QAAQ,KAAK,CAAC;AAE3E,UAAM,aAAa,SAAS,CAAA,UAAA;;AAAS,cAAAP,MAAA,MAAM,eAAN,gBAAAA,IAAkB,SAAS;AAAA,KAAG;AACnE,UAAM,gBAAgB,SAAS,CAAS,UAAA;;AAAA,cAAAA,MAAA,MAAM,eAAN,gBAAAA,IAAkB;AAAA,KAAM;AAChE,UAAM,WAAW,SAAS,CAAA,UAAA;;AAAS,cAAAA,MAAA,MAAM,YAAN,gBAAAA,IAAe,SAAS;AAAA,KAAG;AAC9D,UAAM,SAAS,SAAS,CAAS,UAAA,MAAM,cAAc;AAE/C,UAAA,mBAAmB,gBACrB,cAAc,WACZ,MAAM,KAAK,kBACX,MAAM,KAAK,kBACb,MAAM,KAAK;AAEf,UAAM,CAAC,EAAE,cAAe,CAAA,IAAIiC,QAAA;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,UACJ,eAAe,SAAS,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,GAAG,CAAC;AAAA,QACnE;AAAA,QACA,IAAI;AAAA,UACF,eAAe,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAAA,QACpD;AAAA,QACA,QAAQ;AAAA,UACN,GAAG;AAAA,UACH,UAAU,YAAY,CAAC,aAAa,SAAY;AAAA,QAClD;AAAA,MAAA;AAAA,MAEF,CAAC,UAAU,UAAU,UAAU;AAAA,IAAA;AAGjC,UAAM,gBAAgBnB,MAAA;AAAA,MACpB,MACE,IAAIsD,MAAA;AAAA,QACF;AAAA,QACA;AAAA,QACA,mBAAmB,YACf,IACA,KAAK;AAAA,WACJ,GAAG,SAAS,IAAI,KAAK,SAAS,MAC1B,GAAG,SAAS,IAAI,KAAK,SAAS;AAAA,QACrC;AAAA,MACJ;AAAA,MACF;AAAA,QACE,GAAG,SAAS;AAAA,QACZ,GAAG,SAAS;AAAA,QACZ,KAAK,SAAS;AAAA,QACd,KAAK,SAAS;AAAA,QACd;AAAA,MACF;AAAA,IAAA;AAGFR,YAAA,UAAU,UAAU,CAAC,cAAc,YAAY,QAAW,SAAS;AAEnE,UAAM,EAAE,aAAa,WAAW,IAAI,eAAe;AAAA,MACjD,UAAAlD;AAAA,MACA,eAAe,CAAC,UAAoC;AAClD,kBAAU,IAAI;AACd,uDAAgB,MAAM;AAAA,MACxB;AAAA,MACA,cAAc,CAAC,UAAoC;AACjD,kBAAU,KAAK;AACf,qDAAe,MAAM;AAAA,MACvB;AAAA,IAAA,CACD;AAED,UAAM,iBAAiBI,MAAA;AAAA,MACrB,MACE,mBAAmB,UACjBa,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA,OACE,cAAc,UAAU,WACpB,MAAM,MAAM,aACZ,MAAM,MAAM;AAAA,UAElB,QAAQ;AAAA,UACR,SAAS;AAAA,UACT,UAAU;AAAA,UACV,UAAU;AAAA,UACV,MAAM;AAAA,UACN,UAAU;AAAA,UACV,eAAe,MAAM;AACnB,gBAAI,CAACjB,WAAU;AACb,6BAAe,IAAI;AACnB,6DAAgB;AAAA,YAClB;AAAA,UACF;AAAA,QAAA;AAAA,MACF;AAAA,MAEJ;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM;AAAA,MACd;AAAA,IAAA;AAGF,UAAM,iBAAiBI,MAAA;AAAA,MACrB,MACE,gBACA,SACEa,2BAAAA,IAACK,UAAE,OAAF,EAAQ,UAAU,eACjB,UAAAL,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAM;AAAA,UACN,UAAU,MAAM,KAAK,MAAM;AAAA,UAC3B,SAAS;AAAA,UACT,QAAQ,MAAM,KAAK,MAAM;AAAA,UACzB,OACE,cAAc,UAAU,WACpB,MAAM,KAAK,MAAM,cACjB,MAAM,KAAK,MAAM;AAAA,UAEvB,SAAS;AAAA,UACT,UAAU,MAAM,KAAK,MAAM;AAAA,UAC3B,UAAU,MAAM,KAAK,MAAM;AAAA,UAC3B,UAAU;AAAA,UACV,iBACE,kBACI,kBACA,MAAM,KAAK,MAAM;AAAA,UAEvB,cAAc,MAAM,KAAK,MAAM;AAAA,QAAA;AAAA,MAAA,GAEnC;AAAA,MAEJ;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,QACjB,MAAM,KAAK,MAAM;AAAA,MACnB;AAAA,IAAA;AAGF,UAAM,gBAAgBb,MAAA;AAAA,MACpB,MACE,eACA,eACEa,2BAAAA,IAACmC,gBAAK,SAAS,MAAM,QAAQ,MAAM,UAAU,UAC1C,UAAY,YAAA,EAAE,MAAM,MAAM,SAAS,MAAM,eAAe,KAAK,EAAG,CAAA,GACnE;AAAA,MAEJ,CAAC,aAAa,aAAa,UAAU,IAAI;AAAA,IAAA;AAG3C,UAAM,gBAAgBhD,MAAA;AAAA,MACpB,MACEa,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,OACE,cAAc,UAAU,WACpB,MAAM,MAAM,aACZ,MAAM,MAAM;AAAA,UAElB;AAAA,UACA;AAAA,UACA;AAAA,UACA,SAAS;AAAA,UACT;AAAA,UACA,SAAS,CAAS,UAAA;AAChB,gBAAI,CAACjB,WAAU;AACb,iDAAU,MAAM;AAAA,YAClB;AAAA,UACF;AAAA,UACA,eAAe;AAAA,UACf,cAAc;AAAA,UACd,eAAe,MAAM;AACnB,gBAAI,CAACA,WAAU;AACb,6BAAe,IAAI;AACnB,6DAAgB;AAAA,YAClB;AAAA,UACF;AAAA,QAAA;AAAA,MACF;AAAA,MAEF;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,MAAM,MAAM;AAAA,QACZ,MAAM,MAAM;AAAA,MACd;AAAA,IAAA;AAGF,2CACG,SACE,EAAA,UAAA;AAAA,MAAA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACH,EAAA,CAAA;AAAA,EAEJ;AAEA,SAAK,eAAe;AAAA,IAClB,gBAAgB;AAAA,IAChB,gBAAgB;AAAA,EAClB;ACjaA,QAAM,gBAAgB,IAAI2D,MAAY,YAAA,GAAG,GAAG,CAAC;AAE7B,WAAA,gBACd,gBACA,eACiB;AAIjB,UAAM,WAAW1D,MAAAA;AACjB,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,aAAS,CAAS,UAAA;AAChB,eAAS,UAAU;AAAA,IAAA,CACpB;AAED,UAAM,mBAAmBA,MAAAA,OAAW,oBAAA,IAA6B,CAAA;AAEjE,UAAM,SAAS,kBAAkB;AACjC,UAAM,gBAAgBC,MAAA;AAAA,MACpB,CAAC,UAA2D;AAC1D,cAAM,aAAoC,CAAA;AAC1C,cAAM,QAAQ,iBAAiB;AAEzB,cAAA,EAAE,MAAM,IAAI,SAAS;AAE3B,cAAM,QAAQ,CAAQ,SAAA;AACpB,gBAAM,EAAE,QAAQ,QAAQ,OAAO,MAAM;AAErC,gBAAM,OAAO,MAAM,KAAK,CAAQ,SAAA,KAAK,OAAO,MAAM;AAClD,gBAAM,KAAK,MAAM,KAAK,CAAQ,SAAA,KAAK,OAAO,MAAM;AAE5C,cAAA,CAAC,QAAQ,CAAC,IAAI;AAChB;AAAA,UACF;AAGA,gBAAM,OAAO,SAAS,KAAK,SAAS,CAAC,UAAU,KAAK,SAAS,CAAC,QAAQ,GAAG,SAAS,CAAC,SAAS,GAAG,SAAS,CAAC;AACrG,cAAA,MAAM,IAAI,IAAI,GAAG;AACb,kBAAA,WAAW,MAAM,IAAI,IAAI;AAC/B,uBAAW,KAAK,QAAQ;AACxB;AAAA,UACF;AAEM,gBAAA,aAAa,UAAU,IAAI;AACjC,gBAAM,aAAa,KAAK,OAAO,MAAM,KAAK,MAAM;AAC1C,gBAAA,WAAW,UAAU,EAAE;AAC7B,gBAAM,WAAW,GAAG,OAAO,MAAM,KAAK,MAAM;AAC5C,cAAI,QAAQ;AAAA,YACV;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAGE,cAAA,eAAe,IAAIoD,MAAa,aAAA,OAAO,IAAI,OAAO,GAAG,GAAG,KAAK;AAEjE,cAAI,mBAAmB,QAAQ;AAC7B,uBAAW,KAAK,YAAY;AACtB,kBAAA,IAAI,MAAM,YAAY;AAC5B;AAAA,UACF;AAEA,gBAAM,CAAC,aAAa,SAAS,IAAI,aAAa,IAAI;AAE5C,gBAAA,CAAC,eAAe,aAAa,IAAI;AAAA,YACrC;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAEI,gBAAA,aAAa,IAAIxB,MAAAA;AACvB,qBAAW,mBAAmB,IAAIjC,cAAQ,GAAG,GAAG,CAAC,GAAG,aAAa;AAEjE,gBAAM,gBAAgB,IAAI+D,MAAA;AAAA,YACxB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAEF,wBAAc,gBAAgB,UAAU;AAC1B,wBAAA;AAAA,YACZ,cAAc;AAAA,YACd,cAAc;AAAA,YACd,cAAc;AAAA,UAAA;AAIZ,cAAA,kBAAkB,mBAAmB,OAAO;AAC9C,kBAAMP,SAAQ;AAAA,cACZ;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,cACA;AAAA,YAAA;AAEF,2BAAe,IAAIC,MAAaD,aAAAA,QAAO,IAAI,OAAO,GAAG,GAAG,KAAK;AAAA,UAC/D;AAEA,gBAAM,SAASQ,YAAA,sBAAsB,CAAC,cAAc,aAAa,CAAC;AAClE,qBAAW,KAAK,MAAM;AAChB,gBAAA,IAAI,MAAM,MAAM;AAAA,QAAA,CACvB;AACM,eAAA;AAAA,MACT;AAAA,MACA,CAAC,gBAAgB,QAAQ,MAAM,KAAK,MAAM,QAAQ;AAAA,IAAA;AAGpD,UAAM,cAAc3D,MAAA;AAAA,MAClB,CACE,QACA,aACmB;AACb,cAAA,mBAAmB,cAAc,MAAM;AACvC,cAAA,qBAAqB,cAAc,QAAQ;AAE1C,eAAA2D,YAAA;AAAA,UACL;AAAA,YACE,mBAAmB,SACfA,kCAAsB,kBAAkB,IACxC;AAAA,YACJ,iBAAiB,SACbA,kCAAsB,gBAAgB,IACtC;AAAA,UACN;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAAA,MACA,CAAC,aAAa;AAAA,IAAA;AAGT,WAAA;AAAA,MACL;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AC1JgB,WAAA,cACd,QACA,aACA7D,WACA;AACA,UAAM,EAAE,SAAS,eAAe,cAAc,kBAAkB;AAEhE,UAAM,mBAAmB,SAAS,CAAS,UAAA,MAAM,gBAAgB;AACjE,UAAM,sBAAsB,SAAS,CAAS,UAAA,MAAM,mBAAmB;AAEjE,UAAA,WAAWC,aAAO,KAAK;AACvB,UAAA,cAAcC,MAAAA,YAAY,MAAM;AACpC,eAAS,UAAU;AAAA,IACrB,GAAG,CAAE,CAAA;AAEC,UAAA,sBAAsBD,aAAO,KAAK;AAClC,UAAA,oBAAoBC,MAAAA,YAAY,MAAM;AAC1C,0BAAoB,UAAU;AAAA,IAChC,GAAG,CAAE,CAAA;AAEL,UAAM,sBAAsBA,MAAA;AAAA,MAC1B,CACE,UACA,gBACG;AACC,YAAA,WAAW,SAAS,SAAS;AAC/B,mBAAS,UAAU;AACnB,cAAI,CAACF,WAAU;AACb,wBAAY,QAAQ,CAAQ,SAAA;AAC1B,sBAAQ,IAAI;AAAA,YAAA,CACb;AAAA,UACH;AAAA,QACF;AAEK,aAAA,eAAe,kBAAkB,oBAAoB,SAAS;AACjE,8BAAoB,UAAU;AAC9B,cAAI,CAACA,WAAU;AACb,wBAAY,QAAQ,CAAQ,SAAA;AAC1B,kBAAI,CAAC,iBAAiB,IAAI,KAAK,EAAE,GAAG;AACd,oCAAA,oBAAI,IAAI,CAAC,GAAG,kBAAkB,KAAK,EAAE,CAAC,CAAC;AAC3D,+DAAgB;AAAA,cAClB;AAAA,YAAA,CACD;AAAA,UACH;AAAA,QACF;AAEA,YAAI,eAAe;AACX,gBAAA,OAAO,YAAY,OAAO,CAAA,UAAS,CAAC,SAAS,SAAS,KAAK,CAAC;AAClE,eAAK,QAAQ,CAAQ,SAAA;AACnB,0BAAc,IAAI;AAAA,UAAA,CACnB;AAAA,QACH;AAEA,YAAI,cAAc;AACV,gBAAA,MAAM,SAAS,OAAO,CAAA,UAAS,CAAC,YAAY,SAAS,KAAK,CAAC;AACjE,cAAI,QAAQ,CAAQ,SAAA;AAClB,yBAAa,IAAI;AAAA,UAAA,CAClB;AAAA,QACH;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACAA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAGK,WAAA;AAAA,MACL;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AClFgB,WAAA,yBACd,UACA,UACM;AACA,UAAA,cAAcC,aAAuB,QAAQ;AAEnDc,UAAAA,UAAU,MAAM;AACd,kBAAY,UAAU;AAAA,IAAA,GACrB,CAAC,QAAQ,CAAC;AAEP,UAAA,wBAAwBb,MAAAA,YAAY,MAAM;AAC9C,YAAM,YAAY,YAAY,QAAQ,aAAa,UAAU;AACvD,YAAA,OAAO,MAAM,KAAK;AAAA,QACtB,QAAQ,UAAU,MAAM;AAAA,MAAA,CACzB,EAAE,KAAK,CAAC;AACT,YAAM,KAAK,MAAM,KAAK,UAAU,KAAK;AAC9B,aAAA,EAAE,MAAM;IACjB,GAAG,CAAE,CAAA;AAEC,UAAA,yBAAyBA,kBAAY,CAAC,cAA6B;AACjE,YAAA,SAAS,IAAI,aAAa,SAAS;AACzC,YAAM,cAAc,IAAI4D,MAAgB,gBAAA,QAAQ,GAAG,KAAK;AAC5C,kBAAA,QAAQ,aAAa,YAAY,WAAW;AACxD,kBAAY,cAAc;AAAA,IAC5B,GAAG,CAAE,CAAA;AAELvC,YAAAA,UAAU,MAAM;AACd,UAAI,CAAC,UAAU;AACN,eAAA;AAAA,MACT;AAEA,YAAM,qBAAqB;AAEpB,aAAA;AAAA,QACL,MAAM;AAAA,UACJ,WAAW,mBAAmB;AAAA,QAChC;AAAA,QACA,IAAI;AAAA,UACF,WAAW,mBAAmB;AAAA,QAChC;AAAA,QACA,UAAU,CAAS,UAAA;AACM,iCAAA,MAAM,MAAM,SAAS;AAAA,QAC9C;AAAA,QACA,QAAQ;AAAA,UACN,GAAG;AAAA,UACH,UAAU,WAAW,SAAY;AAAA,QACnC;AAAA,MAAA;AAAA,IACF,GACC,CAAC,QAAQ,CAAC;AAAA,EACf;AAOgB,WAAA,wBACd,UACA,eACA,OAC0B;AAC1B,UAAM,CAAC,EAAE,eAAe,iBAAiB,IAAIA,kBAAU,MAAM;AACpD,aAAA;AAAA,QACL,MAAM;AAAA,UACJ,eAAe;AAAA,UACf,iBAAiB;AAAA,QACnB;AAAA,QACA,IAAI;AAAA,UACF,eAAe,gBACX,MAAM,KAAK,kBACX,MAAM,KAAK;AAAA,UACf,iBAAiB,gBACb,MAAM,KAAK,kBACX,MAAM,KAAK;AAAA,QACjB;AAAA,QACA,QAAQ;AAAA,UACN,GAAG;AAAA,UACH,UAAU,WAAW,SAAY;AAAA,QACnC;AAAA,MAAA;AAAA,IAED,GAAA,CAAC,UAAU,eAAe,KAAK,CAAC;AAE5B,WAAA,EAAE,eAAe;EAC1B;ACrBO,QAAM,OAAsB,CAAC;AAAA,IAClC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;AACJ,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AACrC,UAAA,EAAE,QAAQ,QAAQ,OAAO,eAAe,OAAO,OAAO,EAAM,IAAA;AAElE,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,OAAO,MAAM,KAAK,CAAQ,SAAA,KAAK,OAAO,MAAM;AAClD,UAAM,KAAK,MAAM,KAAK,CAAQ,SAAA,KAAK,OAAO,MAAM;AAChD,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AAErD,UAAM,eAAe,OAAO,MAAM,KAAK,MAAM,YAAY;AAEzD,UAAM,WAAWnB,MAAA;AAAA,MACf,MACE;AAAA,QACE,KAAK;AAAA,QACL,GAAG;AAAA,QACH,qBAAqB,aAAa,cAAc;AAAA,MAClD;AAAA,MACF,CAAC,KAAK,UAAU,GAAG,UAAU,aAAa,cAAc;AAAA,IAAA;AAG1D,UAAM,mBAAmB,SAAS,CAAS,UAAA,MAAM,gBAAgB;AACjE,UAAM,sBAAsB,SAAS,CAAS,UAAA,MAAM,mBAAmB;AAEvE,UAAM,CAAC,EAAE,cAAe,CAAA,IAAImB,QAAA;AAAA,MAC1B,OAAO;AAAA,QACL,MAAM;AAAA,UACJ,eAAe,CAAC,GAAG,GAAG,CAAC;AAAA,QACzB;AAAA,QACA,IAAI;AAAA,UACF,eAAe,CAAC,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAAA,QACpD;AAAA,QACA,QAAQ;AAAA,UACN,GAAG;AAAA,UACH,UAAU,YAAY,CAAC,aAAa,SAAY;AAAA,QAClD;AAAA,MAAA;AAAA,MAEF,CAAC,UAAU,UAAU,UAAU;AAAA,IAAA;AAGjC,UAAM,oBAAoBrB,MAAA;AAAA,MACxB,CAAC6D,UAA4B;AACV,yBAAA,OAAOA,MAAK,EAAE;AAC/B,4BAAoB,IAAI,IAAI,iBAAiB,OAAA,CAAQ,CAAC;AAAA,MACxD;AAAA,MACA,CAAC,kBAAkB,mBAAmB;AAAA,IAAA;AAGxC,UAAM,gBAAgB3D,MAAA;AAAA,MACpB,MACE,IAAIsD,MAAA;AAAA,QACF;AAAA,QACA;AAAA,QACA,mBAAmB,YACf,IACA,KAAK;AAAA,WACJ,GAAG,SAAS,IAAI,KAAK,SAAS,MAC1B,GAAG,SAAS,IAAI,KAAK,SAAS;AAAA,QACrC;AAAA,MACJ;AAAA,MACF;AAAA,QACE,GAAG,SAAS;AAAA,QACZ,GAAG,SAAS;AAAA,QACZ,KAAK,SAAS;AAAA,QACd,KAAK,SAAS;AAAA,QACd;AAAA,MACF;AAAA,IAAA;AAGF,2CACG,SACE,EAAA,UAAA;AAAA,MAAA,gBAAgB,SACdzC,2BAAAA,IAAAK,QAAA,EAAE,OAAF,EAAQ,UAAU,eACjB,UAAAL,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,MAAM;AAAA,UACN,SAAS;AAAA,UACT,QAAQ,MAAM,KAAK,MAAM;AAAA,UACzB;AAAA,UACA;AAAA,UACA,UAAU,MAAM,KAAK,MAAM;AAAA,UAC3B,UAAU,MAAM,KAAK,MAAM;AAAA,UAC3B,UAAU,MAAM,KAAK,MAAM;AAAA,UAC3B,UAAU;AAAA,UACV,iBAAiB,MAAM,KAAK,MAAM;AAAA,UAClC,cAAc,MAAM,KAAK,MAAM;AAAA,QAAA;AAAA,MAAA,GAEnC;AAAA,MAED,eAAe,iBAAiB,IAAI,KAAK,EAAE,KAC1CA,2BAAAA,IAACmC,QAAK,MAAA,EAAA,SAAS,MAAM,QAAQ,MAAM,UAAU,UAC1C,UAAY,YAAA;AAAA,QACX,MAAM;AAAA,QACN,SAAS,MAAM,kBAAkB,IAAI;AAAA,MACtC,CAAA,GACH;AAAA,IAEJ,EAAA,CAAA;AAAA,EAEJ;AAEA,OAAK,eAAe;AAAA,IAClB,gBAAgB;AAAA,EAClB;AChGa,QAAA,QAAwB,CAAC;AAAA,IACpC,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,iBAAiB;AAAA,IACjB;AAAA,IACA;AAAA,IACA,UAAApD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;AACJ,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AACrC,UAAA,EAAE,eAAe,YAAA,IAAgB;AAAA,MACrC;AAAA,MACA;AAAA,IAAA;AAGF,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AACrD,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AACrD,UAAM,gBAAgB,SAAS,CAAS,UAAA,MAAM,aAAa;AAC3D,UAAM,UAAU,SAAS,CAAA,UAAS,MAAM,WAAW,CAAA,CAAE;AACrD,UAAM,aAAa,SAAS,CAAA,UAAS,MAAM,cAAc,CAAA,CAAE;AAE3D,UAAM,CAAC,QAAQ,UAAU,gBAAgB,gBAAgB,IAAII,MAAAA,QAAQ,MAAM;AACzE,YAAM4D,UAAmC,CAAA;AACzC,YAAMC,YAAqC,CAAA;AAC3C,YAAMC,kBAA2C,CAAA;AACjD,YAAMC,oBAA6C,CAAA;AACnD,YAAM,QAAQ,CAAQ,SAAA;AACpB,YAAI,eAAe,KAAK,UAAU,eAAe,KAAK,QAAQ;AACxD,cAAA,WAAW,SAAS,KAAK,EAAE,KAAK,QAAQ,SAAS,KAAK,EAAE,GAAG;AAC7DD,4BAAe,KAAK,IAAI;AAAA,UAAA,OACnB;AACLC,8BAAiB,KAAK,IAAI;AAAA,UAC5B;AACA;AAAA,QACF;AAEI,YAAA,WAAW,SAAS,KAAK,EAAE,KAAK,QAAQ,SAAS,KAAK,EAAE,GAAG;AAC7DH,kBAAO,KAAK,IAAI;AAAA,QAAA,OACX;AACLC,oBAAS,KAAK,IAAI;AAAA,QACpB;AAAA,MAAA,CACD;AACD,aAAO,CAACD,SAAQC,WAAUC,iBAAgBC,iBAAgB;AAAA,OACzD,CAAC,OAAO,SAAS,YAAY,UAAU,CAAC;AAErC,UAAA,gBAAgB,CAAC,CAAC,WAAW;AAEnC,UAAM,sBAAsB/D,MAAA;AAAA,MAC1B,MAAM,YAAY,QAAQ,QAAQ;AAAA,MAClC,CAAC,aAAa,QAAQ,QAAQ;AAAA,IAAA;AAG1B,UAAA,EAAE,eAAe,gBAAA,IAAoB;AAAA,MACzC;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGF,6BAAyB,qBAAqB,QAAQ;AAEtDW,UAAAA,UAAU,MAAM;AACd,UAAI,eAAe,MAAM;AACjB,cAAA,iBAAiB,cAAc,KAAK;AAC1C,cAAMqD,cAAa,eAAe,IAAI,UAAQ,IAAIC,MAAA,KAAK,IAAI,CAAC;AAC5D,sBAAcD,WAAU;AAAA,MAC1B;AAAA,OACC,CAAC,eAAe,eAAe,OAAO,UAAU,CAAC;AAEpD,UAAM,iBAAiBnE,MAAAA,OAAO,IAAIoE,MAAAA,KAAM,CAAA;AACxC,UAAM,kBAAkBpE,MAAAA,OAAO,IAAIoE,MAAAA,KAAM,CAAA;AAEzC,UAAM,YAAYnE,MAAA;AAAA,MAChB,CAAC,cAAmD;AAE9C,YAAA,CAAC,UAAU,QAAQ;AACrB,iBAAO;QACT;AACM,cAAA,gBACJ,UAAU,iBAAqC,UAAU;AACvD,YAAA,CAAC,cAAc,QAAQ;AACzB,iBAAO;QACT;AACA,eAAO,cAAc;AAAA,UACnB,kBAAgB,MAAM,WAAW,QAAQ,aAAa,MAAM,CAAC;AAAA,QAAA;AAAA,MAEjE;AAAA,MACA,CAAC,YAAY,KAAK;AAAA,IAAA;AAGpB,UAAM,EAAE,aAAa,mBAAmB,oBAAwB,IAAA;AAAA,MAC9D;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACAF;AAAA,IAAA;AAGI,UAAA,gBAAgBC,aAAsB,IAAI;AAC1C,UAAA,kBAAkBA,aAAiC,CAAA,CAAE;AAE3DuC,UAAA,SAAS,CAAS,UAAA;AAChB,qBAAe,QAAQ,WAAW;AAElC,UAAIxC,WAAU;AACZ;AAAA,MACF;AAEA,YAAM,qBAAqB,cAAc;AACzC,UAAI,cAAe,eAAe,QAAQ,uBAAuB,MAAO;AACtE,wBAAgB,QAAQ,WAAW;AAAA,UACjC;AAAA,UACA;AAAA,QAAA;AAAA,MAEJ;AAEA,oBAAc,UAAU;AACxB,UAAI,YAAY;AACd;AAAA,MACF;AAEA,YAAM,uBAAuB,gBAAgB;AACvC,YAAA,eAAe,UAAU,MAAM,SAAS;AAC9C,0BAAoB,sBAAsB,YAAY;AAEtD,UAAI,aAAa,KAAA,MAAW,qBAAqB,QAAQ;AACvD,wBAAgB,QAAQ,WAAW,YAAY,cAAc,CAAE,CAAA;AAAA,MACjE;AAEA,sBAAgB,UAAU;AAAA,IAAA,CAC3B;AAED,WACGmB,2BAAAA,KAAA,SAAA,EAAM,SAAS,aAAa,eAAe,mBAE1C,UAAA;AAAA,MAACA,2BAAAA,KAAA,QAAA,EAAK,KAAK,gBACT,UAAA;AAAA,QAAAF,2BAAA;AAAA,UAACK,QAAAA,EAAE;AAAA,UAAF;AAAA,YACC,QAAO;AAAA,YACP,OAAO,MAAM,KAAK;AAAA,YAClB,WAAW;AAAA,YACX,KAAK;AAAA,YACL,SAAS;AAAA,YACT,MAAME,MAAA;AAAA,YACN,aAAa;AAAA,UAAA;AAAA,QACf;AAAA,QACAP,2BAAA;AAAA,UAACK,QAAAA,EAAE;AAAA,UAAF;AAAA,YACC,QAAO;AAAA,YACP,OAAO,MAAM,KAAK;AAAA,YAClB,WAAW;AAAA,YACX,KAAK;AAAA,YACL,SAAS;AAAA,YACT,MAAME,MAAA;AAAA,YACN,aAAa;AAAA,UAAA;AAAA,QACf;AAAA,MAAA,GACF;AAAA,MAEAL,2BAAAA,KAAC,QAAK,EAAA,KAAK,iBACT,UAAA;AAAA,QAAAF,2BAAA;AAAA,UAACK,QAAAA,EAAE;AAAA,UAAF;AAAA,YACC,QAAO;AAAA,YACP,OAAO,MAAM,KAAK;AAAA,YAClB,WAAW;AAAA,YACX,KAAK;AAAA,YACL,SAAS;AAAA,YACT,MAAME,MAAA;AAAA,YACN,aAAa;AAAA,UAAA;AAAA,QACf;AAAA,QACAP,2BAAA;AAAA,UAACK,QAAAA,EAAE;AAAA,UAAF;AAAA,YACC,QAAO;AAAA,YACP,OAAO,MAAM,KAAK;AAAA,YAClB,WAAW;AAAA,YACX,KAAK;AAAA,YACL,SAAS;AAAA,YACT,MAAME,MAAA;AAAA,YACN,aAAa;AAAA,UAAA;AAAA,QACf;AAAA,MAAA,GACF;AAAA,MACC,MAAM,IAAI,CACT,SAAAP,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC;AAAA,UACA;AAAA,UACA,OAAO,MAAM,KAAK,MAAM;AAAA,UACxB,UAAAjB;AAAA,UACA;AAAA,UAEA;AAAA,UACA;AAAA,QAAA;AAAA,QAFK,KAAK;AAAA,MAAA,CAIb;AAAA,IACH,EAAA,CAAA;AAAA,EAEJ;AC7Na,QAAA,UAA4B,CAAC;AAAA,IACxC;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAAA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;;AACJ,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,MAAM,KAAK,IAAI,SAAS,OAAO,SAAS,MAAM,IAAI;AAClD,UAAA,SAAS,MAAM,SAAS;AAC9B,UAAM,CAAC,QAAQ,SAAS,IAAI6C,eAAkB,KAAK;AACnD,UAAM,SAAS,SAAS,CAAS,UAAA,MAAM,cAAc;AAErD,UAAM,WAAW;AAAA,MAAS,CAAA,UAAA;;AACxB,gBAAAvD,MAAA,MAAM,YAAN,gBAAAA,IAAe,KAAK,CAAA,OAAM,MAAM,KAAK,CAAK,MAAA,EAAE,OAAO,EAAE;AAAA;AAAA,IAAC;AAGxD,UAAM,aAAa;AAAA,MAAS,CAAA,UAAA;;AAC1B,gBAAAA,MAAA,MAAM,eAAN,gBAAAA,IAAkB,KAAK,CAAA,OAAM,MAAM,KAAK,CAAK,MAAA,EAAE,OAAO,EAAE;AAAA;AAAA,IAAC;AAG3D,UAAM,gBAAgB,SAAS,CAAA,UAAA;;AAAS,eAAAA,MAAA,MAAM,eAAN,gBAAAA,IAAkB,UAAS;AAAA,KAAC;AAEpE,UAAM,UAAU,gBACZ,cAAc,UAAU,YACtBA,MAAA,MAAM,YAAN,gBAAAA,IAAe,mBACfC,MAAA,MAAM,YAAN,gBAAAA,IAAe,mBACjB,WAAM,YAAN,mBAAe;AAEnB,UAAM,EAAE,eAAe,gBAAgB,cAAA,IAAkBgC,QAAAA,UAAU;AAAA,MACjE,MAAM;AAAA,QACJ,gBAAgB,CAAC,OAAO,GAAG,OAAO,GAAG,EAAE;AAAA,QACvC,eAAe;AAAA,QACf,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;AAAA,MAC/B;AAAA,MACA,IAAI;AAAA,QACF,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;AAAA,QAC7B,gBAAgB,WAAW,CAAC,SAAS,GAAG,SAAS,GAAG,EAAE,IAAI,CAAC,GAAG,GAAG,EAAE;AAAA,QACnE,eAAe;AAAA,MACjB;AAAA,MACA,QAAQ;AAAA,QACN,GAAG;AAAA,QACH,UAAU,WAAW,SAAY;AAAA,MACnC;AAAA,IAAA,CACD;AAED,UAAM,mBAAmBnB,MAAA;AAAA,MACvB,MAAA;;AAAM,mBAAIY,MAAM,OAAA1B,MAAA,MAAM,YAAN,gBAAAA,IAAe,MAAM;AAAA;AAAA,MACrC,EAAC,WAAM,YAAN,mBAAe,MAAM;AAAA,IAAA;AAGxB,UAAM,iBAAiBc,MAAA;AAAA,MACrB,MAAA;;AAAM,mBAAIY,MAAM,OAAA1B,MAAA,MAAM,YAAN,gBAAAA,IAAe,IAAI;AAAA;AAAA,MACnC,EAAC,WAAM,YAAN,mBAAe,IAAI;AAAA,IAAA;AAGZ4D,YAAAA,UAAA,UAAU,YAAY,QAAW,SAAS;AAEpD,UAAM,EAAE,aAAa,WAAW,IAAI,eAAe;AAAA,MACjD,UAAAlD;AAAA,MACA,eAAe,CAAC,UAAoC;AAClD,kBAAU,IAAI;AACd;AAAA,UACE;AAAA,YACE;AAAA,YACA;AAAA,UACF;AAAA,UACA;AAAA;AAAA,MAEJ;AAAA,MACA,cAAc,CAAC,UAAoC;AACjD,kBAAU,KAAK;AACf;AAAA,UACE;AAAA,YACE;AAAA,YACA;AAAA,UACF;AAAA,UACA;AAAA;AAAA,MAEJ;AAAA,IAAA,CACD;AAED,UAAM,UAAUI,MAAA;AAAA,MACd,MACE;;AAAA,qBAAM,WACJe,2BAAA;AAAA,UAACG,QAAAA,EAAE;AAAA,UAAF;AAAA,YACC,UAAU;AAAA,YACV,eAAe;AAAA,YACf,cAAc;AAAA,YACd,SAAS,CAAC,UAAkC;AAC1C,kBAAI,CAACtB,WAAU;AACb;AAAA,kBACE;AAAA,oBACE;AAAA,oBACA;AAAA,kBACF;AAAA,kBACA;AAAA;AAAA,cAEJ;AAAA,YACF;AAAA,YAEA,UAAA;AAAA,cAAAmB,gCAAC,QACC,EAAA,UAAA;AAAA,gBAACF,+BAAA,gBAAA,EAAa,QAAO,YAAW,MAAM,CAAC,QAAQ,GAAG,GAAG,GAAG;AAAA,gBACxDA,2BAAA;AAAA,kBAACK,QAAAA,EAAE;AAAA,kBAAF;AAAA,oBACC,QAAO;AAAA,oBACP,OAAO;AAAA,oBACP,aAAa;AAAA,oBACb,WAAW;AAAA,oBACX,WAAShC,MAAA,MAAM,YAAN,gBAAAA,IAAe,QAAO,gBAAgB;AAAA,oBAC/C,MAAMkC,MAAA;AAAA,oBACN,KAAK;AAAA,kBAAA;AAAA,gBACP;AAAA,cAAA,GACF;AAAA,8CACC,QACC,EAAA,UAAA;AAAA,gBAAAP,2BAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,QAAO;AAAA,oBACP,MAAM,CAAC,QAAQ,MAAM,SAAS,GAAG;AAAA,kBAAA;AAAA,gBACnC;AAAA,gBACAA,2BAAA;AAAA,kBAACK,QAAAA,EAAE;AAAA,kBAAF;AAAA,oBACC,QAAO;AAAA,oBACP,OAAO;AAAA,oBACP,aAAa;AAAA,oBACb,WAAW;AAAA,oBACX,SAAS;AAAA,oBACT,MAAME,MAAA;AAAA,oBACN,KAAK;AAAA,kBAAA;AAAA,gBACP;AAAA,cAAA,GACF;AAAA,gBACCjC,MAAA,MAAM,YAAN,gBAAAA,IAAe,UACd0B,+BAACK,QAAAA,EAAE,OAAF,EAAQ,UAAU,eACjB,UAAAL,2BAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,MAAM;AAAA,kBACN;AAAA,kBACA,SAAS;AAAA,kBACT,QAAQ,MAAM,QAAQ,MAAM;AAAA,kBAC5B,QAAQ;AAAA,kBACR,QAAOkC,MAAA,MAAM,YAAN,gBAAAA,IAAe,MAAM;AAAA,kBAC5B,UAAU;AAAA,kBACV,UAAU,MAAM,QAAQ,MAAM;AAAA,kBAC9B,iBAAiB,MAAM,QAAQ,MAAM;AAAA,kBACrC,cAAc,MAAM,QAAQ,MAAM;AAAA,gBAAA;AAAA,cAAA,GAEtC;AAAA,YAAA;AAAA,UAAA;AAAA,QAEJ;AAAA;AAAA,MAEJ;AAAA,QACE,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACAnD;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAGK,WAAA;AAAA,EACT;AAEA,UAAQ,eAAe;AAAA,IACrB,QAAQ;AAAA,IACR,SAAS;AAAA,EACX;ACiEa,QAAA,aACXuC,MAAA;AAAA,IACE,CACE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAAvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,OAEL,QACG;AACG,YAAA,EAAE,YAAY,iBAAqB,IAAA;AAGzC,YAAM,KAAKG,MAAAA,SAAS,CAAS,UAAA,MAAM,EAAE;AACrC,YAAM,QAAQA,MAAAA,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,YAAM,SAASA,MAAAA,SAAS,CAAS,UAAA,MAAM,MAAM;AAG7C,eAAS,IAAI;AAEb,UACE,oBACA,EAAE,eAAe,qBAAqB,eAAe,oBACrD;AACA,cAAM,IAAI;AAAA,UACR;AAAA,QAAA;AAAA,MAEJ;AAGA,YAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,YAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,YAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AACrC,YAAA,WAAW,SAAS,CAAS,UAAA,CAAC,GAAG,MAAM,SAAS,OAAQ,CAAA,CAAC;AAG/D,YAAM,EAAE,iBAAiB,oBAAoB,WAAA,IAC3C,eAAe;AAAA,QACb;AAAA,QACA,UAAAH;AAAA,QACA;AAAA,MAAA,CACD;AAGH4C,YAAA;AAAA,QACE;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,gBAAgB;AAAA,UAChB;AAAA,UACA,aAAa,MAAM,GAAG,OAAO,OAAO,MAAM;AAAA,QAAA;AAAA,QAE5C,CAAC,iBAAiB,oBAAoB,OAAO,IAAI,OAAO,MAAM;AAAA,MAAA;AAGhE,YAAM,iBAAiBxC,MAAA;AAAA,QACrB,MACE,MAAM,IAAI,CACR,MAAAa,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC,IAAI,uBAAG;AAAA,YACP;AAAA,YACA;AAAA,YACA,UAAAjB;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT,eAAe;AAAA,YACf,eAAe;AAAA,YACf,eAAe;AAAA,YACf,cAAc;AAAA,YACd,WAAW;AAAA,UAAA;AAAA,UAbN,uBAAG;AAAA,QAAA,CAeX;AAAA,QACH;AAAA,UACE;AAAA,UACA;AAAA,UACAA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MAAA;AAGF,YAAM,iBAAiBI,MAAA;AAAA,QACrB,MACE,WACE,MAAM,IAAI,CACR,MAAAa,2BAAA;AAAA,UAACsC;AAAAA,UAAA;AAAA,YAEC,IAAI,EAAE;AAAA,YACN,UAAAvD;AAAA,YACA;AAAA,YACA;AAAA,YACA,gBAAgB;AAAA,YAChB,gBAAgB;AAAA,YAChB,eAAe;AAAA,YACf;AAAA,YACA,SAAS;AAAA,YACT,eAAe;AAAA,YACf,eAAe;AAAA,YACf,cAAc;AAAA,UAAA;AAAA,UAZT,EAAE;AAAA,QAcV,CAAA,IAEDiB,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA,UAAAjB;AAAA,YACA;AAAA,YACA;AAAA,YACA,gBAAgB;AAAA,YAChB,gBAAgB;AAAA,YAChB,eAAe;AAAA,YACf;AAAA,YACA,SAAS;AAAA,YACT,eAAe;AAAA,YACf,eAAe;AAAA,YACf,cAAc;AAAA,UAAA;AAAA,QAChB;AAAA,QAEJ;AAAA,UACE;AAAA,UACA;AAAA,UACAA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MAAA;AAGF,YAAM,oBAAoBI,MAAA;AAAA,QACxB,MACE,SAAS,IAAI,CACX,MAAAa,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YAEC;AAAA,YACA,UAAAjB;AAAA,YACA;AAAA,YACA,SAAS;AAAA,YACT,eAAe;AAAA,YACf,cAAc;AAAA,YACb,GAAG;AAAA,UAAA;AAAA,UAPC,EAAE;AAAA,QAAA,CASV;AAAA,QACH;AAAA,UACE;AAAA,UACA;AAAA,UACAA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,UACA;AAAA,QACF;AAAA,MAAA;AAIA,aAAA,8CACGyB,MACE,UAAA,EAAA,UAAA;AAAA,QAAA;AAAA,QACA;AAAA,QACA;AAAA,MACH,EAAA,CAAA;AAAA,IAGN;AAAA,EACF;AAEF,aAAW,eAAe;AAAA,IACxB,mBAAmB;AAAA,EACrB;ACxfO,QAAM,YAAmB;AAAA,IAC9B,QAAQ;AAAA,MACN,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,OAAO;AAAA,QACL,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,QACV,UAAU;AAAA,QACV,UAAU;AAAA,QACV,iBAAiB;AAAA,QACjB,cAAc;AAAA,MAChB;AAAA,MACA,UAAU;AAAA,QACR,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,OAAO;AAAA,QACL,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,QACV,UAAU;AAAA,QACV,UAAU;AAAA,QACV,iBAAiB;AAAA,QACjB,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,OAAO;AAAA,QACL,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,QACV,UAAU;AAAA,QACV,UAAU;AAAA,QACV,iBAAiB;AAAA,QACjB,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;ACpEO,QAAM,aAAoB;AAAA,IAC/B,QAAQ;AAAA,MACN,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,OAAO;AAAA,QACL,OAAO;AAAA;AAAA,QAEP,aAAa;AAAA,QACb,UAAU;AAAA,QACV,UAAU;AAAA,QACV,UAAU;AAAA,QACV,iBAAiB;AAAA,QACjB,cAAc;AAAA,MAChB;AAAA,MACA,UAAU;AAAA,QACR,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,aAAa;AAAA,MACf;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,QAAQ;AAAA,MACR,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,IACd;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,OAAO;AAAA;AAAA,QAEL,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,QACV,UAAU;AAAA,QACV,UAAU;AAAA,QACV,iBAAiB;AAAA,QACjB,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL,MAAM;AAAA,MACN,YAAY;AAAA,IACd;AAAA,IACA,SAAS;AAAA,MACP,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,iBAAiB;AAAA,MACjB,iBAAiB;AAAA,MACjB,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,OAAO;AAAA,QACP,aAAa;AAAA,QACb,UAAU;AAAA,QACV,UAAU;AAAA,QACV,UAAU;AAAA,QACV,iBAAiB;AAAA,QACjB,cAAc;AAAA,MAChB;AAAA,IACF;AAAA,EACF;AC/DgB,WAAA,aACd,OACA,SACA,MACA;AACA,cAAU,MAAM,QAAQ,OAAO,IAAI,UAAU,CAAC,OAAO;AAErD,UAAM,QAAkB,CAAA;AACxB,UAAM,QAAkB,CAAA;AAExB,eAAW,UAAU,SAAS;AAC5B,YAAM,aAAa;AAAA,QACjB,GAAI,MAAM,cAAc,MAAM,KAAK,CAAC;AAAA,QACpC,GAAI,MAAM,eAAe,MAAM,KAAK,CAAC;AAAA,MAAA;AAGvC,UAAI,CAAC,YAAY;AACf;AAAA,MACF;AAEA,iBAAW,QAAQ,YAAY;AACvB,cAAA,SAAS,KAAK,WAAW;AAE/B,YAAI,SAAS,MAAM;AACjB,cAAI,KAAK,WAAW,UAAU,CAAC,MAAM,SAAS,MAAM,GAAG;AACrD,kBAAM,KAAK,MAAM;AAAA,UACnB;AAAA,QAAA,WACS,SAAS,OAAO;AACzB,cAAI,KAAK,WAAW,UAAU,CAAC,MAAM,SAAS,MAAM,GAAG;AACrD,kBAAM,KAAK,MAAM;AAAA,UACnB;AAAA,QAAA,OACK;AACL,cAAI,CAAC,MAAM,SAAS,MAAM,GAAG;AAC3B,kBAAM,KAAK,MAAM;AAAA,UACnB;AAAA,QACF;AAEI,YAAA,SAAS,SAAS,SAAS,OAAO;AACpC,gBAAM,OAAO,KAAK;AAClB,cAAI,CAAC,MAAM,SAAS,IAAc,GAAG;AACnC,kBAAM,KAAK,IAAc;AAAA,UAC3B;AAAA,QACF;AAEI,YAAA,SAAS,QAAQ,SAAS,OAAO;AACnC,cAAI,CAAC,MAAM,SAAS,KAAK,MAAM,GAAG;AAC1B,kBAAA,KAAK,KAAK,MAAgB;AAAA,UAClC;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEO,WAAA;AAAA,MACL;AAAA,MACA;AAAA,IAAA;AAAA,EAEJ;AAKgB,WAAA,WAAW,OAAO,KAAK,MAAM;AACrC,UAAA,EAAE,SAAS,QAAY,IAAA;AACvB,UAAA,EAAE,OAAO,OAAW,IAAA;AACtB,QAAA,IAAK,UAAU,QAAS,IAAI,GAAG,EAAE,UAAU,UAAU,IAAI,CAAC;AAAA,EAChE;AAKO,WAAS,cAAc,OAAc;AACpC,UAAA,UAAU,SAAS,cAAc,KAAK;AAC5C,YAAQ,MAAM,gBAAgB;AACtB,YAAA,MAAM,SAAS,MAAM,MAAM;AAC3B,YAAA,MAAM,kBAAkB,MAAM,MAAM;AAC5C,YAAQ,MAAM,WAAW;AAClB,WAAA;AAAA,EACT;AC/Ca,QAAA,QAAwB,CAAC;AAAA,IACpC;AAAA,IACA,OAAO;AAAA,IACP;AAAA,IACA;AAAA,IACA,UAAAzB;AAAA,EACF,MAAM;;AACJ,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,SAASG,MAAAA,SAAS,CAAS,UAAA,MAAM,MAAM;AAC7C,UAAM,KAAKA,MAAAA,SAAS,CAAS,UAAA,MAAM,EAAE;AACrC,UAAM,YAAYA,MAAAA,SAAS,CAAS,UAAA,MAAM,SAAS;AACnD,UAAM,OAAOA,MAAAA,SAAS,CAAS,UAAA,MAAM,IAAI;AACzC,UAAM,MAAMA,MAAAA,SAAS,CAAS,UAAA,MAAM,GAAG;AACvC,UAAM,QAAQA,MAAAA,SAAS,CAAS,UAAA,MAAM,KAAK;AAE3C,UAAM,iBAAiB;AAEvB,UAAM,UAAU,SAAS,CAAS,UAAA,MAAM,OAAO;AAC/C,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AACrD,UAAM,QAAQ,SAAS,CAAS,UAAA,MAAM,KAAK;AAC3C,UAAM,aAAa,SAAS,CAAS,UAAA,MAAM,UAAU;AAE/C,UAAA,aAAaF,aAAgB,KAAK;AAClC,UAAA,kBAAkBA,aAA4B,IAAI;AAClD,UAAA,0BAA0BA,aAA4B,IAAI;AAChE,UAAM,aAAaA,MAAA,OAAuB,cAAc,KAAK,CAAC;AACxD,UAAA,aAAaA,aAA2C,IAAI;AAC5D,UAAA,YAAYA,aAAO,KAAK;AAC9B,UAAM,yBAAyBA,MAAAA,OAAgB,IAAI,EAAE,OAAO,OAAO;AACnE,UAAM,wBAAwBA,MAAA;AAAA,OAC5BX,MAAA,eAAe,aAAf,gBAAAA,IAAyB;AAAA,IAAA;AAG3ByB,UAAAA,UAAU,MAAM;AACd,UAAI,WAAW,SAAS;AACtB,2CAAU;AAAA,MACZ;AAEA,iBAAW,UAAU;AAAA,IAAA,GACpB,CAAC,SAAS,OAAO,CAAC;AAErB,UAAM,gBAAgBb,MAAA;AAAA,MACpB,CAAS,UAAA;AACP,YAAI,UAAU,SAAS;AACrB,gBAAM,CAAC,YAAY,cAAc,gBAAgB,IAAI,WAAW;AAEhE,2BAAiB,IAAI,KAAK,IAAI,WAAW,GAAG,MAAM,OAAO;AACzD,2BAAiB,IAAI,KAAK,IAAI,WAAW,GAAG,MAAM,OAAO;AACzD,uBAAa,IAAI,KAAK,IAAI,WAAW,GAAG,MAAM,OAAO;AACrD,uBAAa,IAAI,KAAK,IAAI,WAAW,GAAG,MAAM,OAAO;AACrD,qBAAW,QAAQ,MAAM,OAAO,GAAG,aAAa,CAAC;AACjD,qBAAW,QAAQ,MAAM,MAAM,GAAG,aAAa,CAAC;AAChD,qBAAW,QAAQ,MAAM,QAAQ,GAC/B,iBAAiB,IAAI,aAAa,CACpC;AACA,qBAAW,QAAQ,MAAM,SAAS,GAChC,iBAAiB,IAAI,aAAa,CACpC;AAEA,qBAAW,OAAO,gBAAgB,QAAQ,UAAU,IAAI;AACxD,qBAAW,OAAO,wBAAwB,QAAQ,UAAU,IAAI;AAEhE,gBAAM,cAAc,CAAA;AACd,gBAAA,gBAAgB,wBAAwB,QAC3C,SACA,KAAK,CAAA,MAAM,EAAU,IAAI,EACzB;AAAA,YACC,UAAQ,MAAM,WAAW,QAAQ,IAA0B,CAAC,EAAE;AAAA,UAAA;AAEtD,sBAAA,KAAK,GAAG,aAAa;AAE3B,gBAAA,WAAW,gBAAgB,QAC9B,SACA,KAAK,CAAA,MAAM,EAAU,IAAI,EACzB;AAAA,YACC,CAAA,MAAA;;AACE,uBAAE,YACFZ,MAAA,EAAE,aAAF,gBAAAA,IAAY,UACXC,MAAA,EAAE,aAAF,gBAAAA,IAAY,UAAS,QAAQ,SAAS;AAAA;AAAA,UAAA,EAE1C,IAAI,CAAK,MAAA,EAAE,SAAS,EAAE;AACb,sBAAA,KAAK,GAAG,QAAQ;AAI5B,gCAAsB,MAAM;AAC1B,uBAAW,WAAW;AAAA,UAAA,CACvB;AAEQ,mBAAA,iBAAiB,eAAe,eAAe;AAAA,YACtD,SAAS;AAAA,YACT,SAAS;AAAA,YACT,MAAM;AAAA,UAAA,CACP;AAAA,QACH;AAAA,MACF;AAAA,MACA,CAAC,OAAO,YAAY,YAAY,MAAM,IAAI;AAAA,IAAA;AAGtC,UAAA,cAAcW,MAAAA,YAAY,MAAM;;AACpC,UAAI,UAAU,SAAS;AACrB,kBAAU,EAAE,SAAS,uBAAuB,QAAS,CAAA;AACrD,kBAAU,UAAU;AACpB,SAAAZ,MAAA,WAAW,QAAQ,kBAAnB,gBAAAA,IAAkC,YAAY,WAAW;AAC1C,uBAAA,SAAS,UAAU,sBAAsB;AACxD,iDAAa;AAEJ,iBAAA,oBAAoB,eAAe,aAAa;AAChD,iBAAA,oBAAoB,aAAa,WAAW;AAAA,MACvD;AAAA,IAAA,GACC,CAAC,WAAW,eAAe,UAAU,YAAY,SAAS,aAAa,CAAC;AAE3E,UAAM,gBAAgBY,MAAA;AAAA,MACpB,CAAS,UAAA;;AACP,YAAI,MAAM,UAAU;AAEK,iCAAA,UAAU,MAAM,OAAO;AACxB,gCAAA,WAAUZ,MAAA,eAAe,aAAf,gBAAAA,IAAyB;AAGzD,0BAAgB,UAAU,IAAIgF,YAAa,aAAA,QAAQ,KAAK;AAGlD,gBAAA,YAAY,IAAIC,MAAAA;AACtB,cAAI,WAAW,QAAQ;AACX,sBAAA,IAAI,GAAG,UAAU;AAAA,UAC7B;AACA,kCAAwB,UAAU,IAAID,YAAa,aAAA,QAAQ,SAAS;AAEpE,qBAAW,UAAU;AAAA;AAAA,YAEnB,IAAIjE,cAAQ;AAAA;AAAA,YAEZ,IAAIA,cAAQ;AAAA;AAAA,YAEZ,IAAIA,cAAQ;AAAA,UAAA;AAGR,gBAAA,CAAC,UAAU,IAAI,WAAW;AAEhC,yBAAe,SAAS,UAAU;AACxB,oBAAA,EAAE,SAAS,MAAA,CAAO;AAC5B,oBAAU,UAAU;AACpB,WAAAd,MAAA,GAAG,WAAW,kBAAd,gBAAAA,IAA6B,YAAY,WAAW;AACpD,qBAAW,QAAQ,MAAM,OAAO,GAAG,MAAM,OAAO;AAChD,qBAAW,QAAQ,MAAM,MAAM,GAAG,MAAM,OAAO;AACpC,qBAAA,QAAQ,MAAM,QAAQ;AACtB,qBAAA,QAAQ,MAAM,SAAS;AAClC,qBAAW,IAAI,MAAM;AACrB,qBAAW,IAAI,MAAM;AAErB,qBAAW,OAAO,gBAAgB,QAAQ,YAAY,IAAI;AAC1D,qBAAW,OAAO,wBAAwB,QAAQ,YAAY,IAAI;AAEzD,mBAAA,iBAAiB,eAAe,eAAe;AAAA,YACtD,SAAS;AAAA,YACT,SAAS;AAAA,YACT,MAAM;AAAA,UAAA,CACP;AACD,mBAAS,iBAAiB,aAAa,aAAa,EAAE,SAAS,MAAM;AAAA,QACvE;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACA,eAAe;AAAA,QACf;AAAA,QACA;AAAA,QACA,GAAG,WAAW;AAAA,QACd;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAGFwB,UAAAA,UAAU,MAAM;AACV,UAAAf,aAAY,SAAS,QAAQ;AAC/B;AAAA,MACF;AAEI,UAAA,OAAO,WAAW,aAAa;AACxB,iBAAA,iBAAiB,eAAe,eAAe;AAAA,UACtD,SAAS;AAAA,QAAA,CACV;AACQ,iBAAA,iBAAiB,eAAe,eAAe;AAAA,UACtD,SAAS;AAAA,QAAA,CACV;AACD,iBAAS,iBAAiB,aAAa,aAAa,EAAE,SAAS,MAAM;AAAA,MACvE;AAEA,aAAO,MAAM;AACP,YAAA,OAAO,WAAW,aAAa;AACxB,mBAAA,oBAAoB,eAAe,aAAa;AAChD,mBAAA,oBAAoB,eAAe,aAAa;AAChD,mBAAA,oBAAoB,aAAa,WAAW;AAAA,QACvD;AAAA,MAAA;AAAA,IACF,GACC,CAAC,MAAMA,WAAU,eAAe,eAAe,WAAW,CAAC;AAEvD,WAAAiB,+BAAC,WAAO,SAAS,CAAA;AAAA,EAC1B;ACxFa,QAAA,eAAe,CAAC;AAAA,IAC3B,aAAa,CAAC;AAAA,IACd,QAAQ,CAAC;AAAA,IACT,UAAU,CAAC;AAAA,IACX,gBAAgB;AAAA,IAChB,OAAO;AAAA,IACP,gBAAgB;AAAA,IAChB,oBAAoB;AAAA,IACpB;AAAA,IACA,UAAU,CAAC,aAAa,YAAY,QAAQ;AAAA,IAC5C,UAAAjB;AAAA,IACA;AAAA,EACF,MAAuC;AACrC,UAAM,CAAC,gBAAgB,iBAAiB,IAAI6C,MAAA,SAAmB,CAAE,CAAA;AACjE,UAAM,CAAC,iBAAiB,kBAAkB,IAAIA,eAAmB,OAAO;AACxE,UAAM,CAAC,oBAAoB,qBAAqB,IAC9CA,eAAmB,UAAU;AAC/B,UAAM,CAAC,aAAa,cAAc,IAAIA,eAAkB,KAAK;AACvD,UAAA,UAAU,SAAS,WAAW,SAAS;AAE7C,UAAM,eAAe3C,MAAA;AAAA,MACnB,CAAC,UAA6B;AACxB,YAAA,CAACF,aAAY,OAAO;AACtB,kBAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAE7C,gBAAM,WAAW,MAAM;AAAA,YACrB,CAAQ,SAAA,CAAC,mBAAmB,SAAS,IAAI;AAAA,UAAA;AAE3C,cAAI,SAAS,QAAQ;AACnB,kBAAM,OAAO,CAAC,GAAG,oBAAoB,GAAG,QAAQ;AAChD,uDAAc;AACd,kCAAsB,IAAI;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,MACA,CAACA,WAAU,oBAAoB,WAAW;AAAA,IAAA;AAG5C,UAAM,kBAAkBE,MAAA;AAAA,MACtB,CAAC,UAA6B;AACxB,YAAA,CAACF,aAAY,OAAO;AACtB,kBAAQ,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;AAEvC,gBAAA,OAAO,mBAAmB,OAAO,CAAA,MAAK,CAAC,MAAM,SAAS,CAAC,CAAC;AAC9D,qDAAc;AACd,gCAAsB,IAAI;AAAA,QAC5B;AAAA,MACF;AAAA,MACA,CAACA,WAAU,oBAAoB,WAAW;AAAA,IAAA;AAG5C,UAAM,kBAAkBE,MAAA;AAAA,MACtB,CAAC,OAA0B,CAAA,MAAO;AAChC,YAAI,CAACF,WAAU;AACb,iBAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC,IAAI;AACzC,6BAAmB,CAAE,CAAA;AACrB,gCAAsB,IAAI;AAC1B,qDAAc;AAAA,QAChB;AAAA,MACF;AAAA,MACA,CAACA,WAAU,WAAW;AAAA,IAAA;AAGxB,UAAM,kBAAkBE,MAAA;AAAA,MACtB,CAAC,SAAiB;AACV,cAAA,MAAM,mBAAmB,SAAS,IAAI;AAC5C,YAAI,KAAK;AACP,0BAAgB,IAAI;AAAA,QAAA,OACf;AACL,cAAI,CAAC,SAAS;AACZ,4BAAgB,IAAI;AAAA,UAAA,OACf;AACL,yBAAa,IAAI;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAGF,UAAM,cAAcA,MAAA;AAAA,MAClB,CAAC,SAAoB;AACnB,YAAI,SAAS;AACX,cAAI,SAAS,iBAAiB;AAC5B,gBAAI,aAAa;AACf,2BAAa,KAAK,EAAE;AAAA,YAAA,OACf;AACL,8BAAgB,KAAK,EAAE;AAAA,YACzB;AAAA,UAAA,OACK;AACL,yBAAa,KAAK,EAAE;AAAA,UACtB;AAAA,QAAA,OACK;AACL,0BAAgB,KAAK,EAAE;AAAA,QACzB;AAEA,YACE,kBAAkB,QACjB,kBAAkB,gBAAgB,CAAC,aACpC;AACI,cAAA,CAAC,IAAI,SAAS;AACV,kBAAA,IAAI,MAAM,oCAAoC;AAAA,UACtD;AAEM,gBAAA,QAAQ,IAAI,QAAQ,SAAS;AAC7B,gBAAA,EAAE,OAAO,UAAA,IAAc;AAAA,YAC3B;AAAA,YACA,CAAC,KAAK,EAAE;AAAA,YACR;AAAA,UAAA;AAGF,cAAI,QAAQ,eAAe,CAAC,KAAK,IAAI,GAAG,SAAS,GAAG;AAAA,YAClD,yBAAyB;AAAA,UAAA,CAC1B;AAAA,QACH;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF;AAAA,IAAA;AAGF,UAAM,kBAAkBA,MAAA;AAAA,MACtB,CAAC,QAAgB,WAAmB;AAC5B,cAAA,QAAQ,IAAI,QAAQ,SAAS;AACnC,YAAI,CAAC,OAAO;AACJ,gBAAA,IAAI,MAAM,0BAA0B;AAAA,QAC5C;AAEA,cAAM,OAAO,SAAS,OAAO,QAAQ,MAAM;AAC3B,wBAAA,CAAC,QAAQ,MAAM,CAAC;AAEhC,cAAM,SAAS,CAAA;AACf,iBAAS,IAAI,GAAG,IAAI,KAAK,SAAS,GAAG,KAAK;AAClC,gBAAA,OAAO,KAAK,CAAC;AACb,gBAAA,KAAK,KAAK,IAAI,CAAC;AACrB,gBAAM,OAAO,MAAM,kBAAkB,MAAM,EAAE;AAC7C,cAAI,MAAM;AACD,mBAAA,KAAK,KAAK,EAAE;AAAA,UACrB;AAAA,QACF;AAEmB,2BAAA,CAAC,GAAG,KAAK,IAAI,OAAK,CAAW,GAAG,GAAG,MAAM,CAAC;AAAA,MAC/D;AAAA,MACA,CAAC,iBAAiB,GAAG;AAAA,IAAA;AAGjB,UAAA,YAAYA,kBAAY,CAAC,UAAyB;AACtD,YAAM,UAAU,MAAM;AAChB,YAAA,SACJ,QAAQ,YAAY,WACpB,QAAQ,YAAY,YACpB,QAAQ,YAAY,cACpB,CAAC,QAAQ;AAEL,YAAA,SAAS,MAAM,WAAW,MAAM;AAEtC,UAAI,UAAU,QAAQ;AACpB,cAAM,eAAe;AACrB,uBAAe,IAAI;AAAA,MACrB;AAAA,IACF,GAAG,CAAE,CAAA;AAELa,UAAAA,UAAU,MAAM;AACV,UAAA,OAAO,WAAW,aAAa;AAC1B,eAAA,iBAAiB,WAAW,SAAS;AAAA,MAC9C;AAEA,aAAO,MAAM;AACP,YAAA,OAAO,WAAW,aAAa;AAC1B,iBAAA,oBAAoB,WAAW,SAAS;AAAA,QACjD;AAAA,MAAA;AAAA,IACF,GACC,CAAC,SAAS,CAAC;AAEd,UAAM,gBAAgBb,MAAA;AAAA,MACpB,CAAC,UAAsB;AACrB,YACE,MAAM,WAAW,MAChB,mBAAmB,UAAU,gBAAgB,SAC9C;AACgB;AAChB,yBAAe,KAAK;AAGhB,cAAA,iBAAiB,mBAAmB,WAAW,GAAG;AAChD,gBAAA,CAAC,IAAI,SAAS;AACV,oBAAA,IAAI,MAAM,oCAAoC;AAAA,YACtD;AAEA,gBAAI,QAAQ,eAAe,CAAA,GAAI,EAAE,yBAAyB,MAAM;AAAA,UAClE;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE;AAAA,QACA;AAAA,QACA,gBAAgB;AAAA,QAChB,mBAAmB;AAAA,QACnB;AAAA,MACF;AAAA,IAAA;AAGI,UAAA,UAAUA,kBAAY,CAACU,gBAAyB;AACpD,yBAAmBA,WAAU;AAAA,IAC/B,GAAG,CAAE,CAAA;AAEL,UAAM,aAAaV,MAAA;AAAA,MACjB,CAACU,gBAAyB;AACxB,wBAAgBA,WAAU;AAAA,MAC5B;AAAA,MACA,CAAC,eAAe;AAAA,IAAA;AAGlB,UAAM,oBAAoBV,MAAA;AAAA,MACxB,CAAC,SAAoB;AACnB,YAAI,eAAe;AACX,gBAAA,QAAQ,IAAI,QAAQ,SAAS;AACnC,cAAI,CAAC,OAAO;AACJ,kBAAA,IAAI,MAAM,oCAAoC;AAAA,UACtD;AAEM,gBAAA,EAAE,OAAA7B,QAAO,UAAU,aAAa,OAAO,CAAC,KAAK,EAAE,GAAG,aAAa;AACrE,4BAAkB,CAAC,GAAGA,QAAO,GAAG,KAAK,CAAC;AAAA,QACxC;AAAA,MACF;AAAA,MACA,CAAC,eAAe,GAAG;AAAA,IAAA;AAGf,UAAA,mBAAmB6B,MAAAA,YAAY,MAAM;AACzC,UAAI,eAAe;AACjB,0BAAkB,CAAE,CAAA;AAAA,MACtB;AAAA,IAAA,GACC,CAAC,aAAa,CAAC;AAElBa,UAAAA,UAAU,MAAM;;AACd,UAAI,sBAAsB,YAAY,mBAAmB,SAAS,GAAG;AAC7D,cAAA,SAAQzB,MAAA,IAAI,YAAJ,gBAAAA,IAAa;AAC3B,YAAI,OAAO;AACT,gBAAM,EAAE,OAAAjB,QAAO,MAAU,IAAA;AAAA,YACvB;AAAA,YACA;AAAA,YACA;AAAA,UAAA;AAEF,6BAAmB,CAAC,GAAGA,QAAO,GAAG,KAAK,CAAC;AAAA,QACzC;AAAA,MACF;AAAA,IACC,GAAA,CAAC,oBAAoB,mBAAmB,GAAG,CAAC;AAEpCqE,uBAAA;AAAA,MACT;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU,CAAC,QAAQ,SAAS,WAAW;AAAA,QACvC,UAAU;AAAA,QACV,aAAa;AAAA,QACb,UAAU,CAAS,UAAA;AACjB,gBAAM,eAAe;AAEjB,cAAA,CAAC1C,aAAY,SAAS,UAAU;AAClC,kBAAM,OAAO,MAAM,IAAI,CAAA,MAAK,EAAE,EAAE;AAChC,uDAAc;AACd,kCAAsB,IAAI;AAAA,UAC5B;AAAA,QACF;AAAA,MACF;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,UAAU;AAAA,QACV,UAAU,CAAC,QAAQ,SAAS,UAAU;AAAA,QACtC,aAAa;AAAA,QACb,MAAM;AAAA,QACN,UAAU,CAAS,UAAA;AACjB,cAAI,CAACA,WAAU;AACb,kBAAM,eAAe;AACrB,uDAAc,CAAE;AAChB,kCAAsB,CAAE,CAAA;AAAA,UAC1B;AAAA,QACF;AAAA,MACF;AAAA,IAAA,CACD;AAED,UAAM,gBAAgBI,MAAA;AAAA,MACpB,MAAM,CAAC,GAAG,iBAAiB,GAAG,cAAc;AAAA,MAC5C,CAAC,iBAAiB,cAAc;AAAA,IAAA;AAG3B,WAAA;AAAA,MACL,SAAS;AAAA,MACT;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,eAAe;AAAA,IAAA;AAAA,EAEnB;;;;;ACrXA,QAAM,cAAc;AAAA,IAClB,OAAO;AAAA,IACP,WAAW;AAAA,EACb;AAGA,QAAM,kBAAuB;AAAA,IAC3B,UAAU,CAAC,GAAG,GAAG,GAAI;AAAA,IACrB,MAAM;AAAA,IACN,KAAK;AAAA,IACL,KAAK;AAAA,EACP;AAEa,QAAA,cACXmC,MAAA;AAAA,IACE,CACE;AAAA,MACE;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,UAAAvC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,GAAG;AAAA,OAEL,QACG;;AACG,YAAA,cAAcC,aAA6B,IAAI;AAC/C,YAAA,cAAcA,aAAiC,IAAI;AACnD,YAAA,YAAYA,aAAiC,IAAI;AAEvD2C,YAAA,oBAAoB,KAAK,OAAO;AAAA,QAC9B,aAAa,CAAC,SAAS,SACrB;;AAAA,kBAAAtD,MAAA,YAAY,YAAZ,gBAAAA,IAAqB,YAAY,SAAS;AAAA;AAAA,QAC5C,gBAAgB,CAAC,SAAS,SACxB;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB,eAAe,SAAS;AAAA;AAAA,QAC/C,QAAQ,MAAM;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA;AAAA,QACnC,SAAS,MAAM;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA;AAAA,QACpC,SAAS,CAAA,aAAY;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB,QAAQ;AAAA;AAAA,QAClD,UAAU,CAAA,aAAY;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB,SAAS;AAAA;AAAA,QACpD,SAAS,MAAM;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA;AAAA,QACpC,UAAU,MAAM;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA;AAAA,QACrC,SAAS,MAAM;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA;AAAA,QACpC,OAAO,MAAM;;AAAA,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA;AAAA,QAClC,eAAe,CAACqD,cACd;;AAAA,kBAAArD,MAAA,YAAY,YAAZ,gBAAAA,IAAqB,cAAcqD;AAAAA;AAAAA,QACrC,aAAa,MAAA;;AAAM,kBAAArD,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA;AAAA,QACxC,UAAU,MAAA;;AAAM,kBAAAA,MAAA,YAAY,YAAZ,gBAAAA,IAAqB;AAAA;AAAA,QACrC,cAAc,MAAM;AAClB,sBAAY,QAAQ;AACb,iBAAA,UAAU,QAAQ;QAC3B;AAAA,MACA,EAAA;AAGF,YAAM,EAAE,YAAY,SAAS,iBAAA,IAAqB;AAGlD,YAAM,gBACJ,MAAM,SAAS,MAAM,SAAS,MAAM,QAAQ;AAExC,YAAA,KAAKc,cAAQ,OAAO,EAAE,GAAG,WAAW,GAAG,gBAAgB,CAAC,SAAS,CAAC;AAIxE,aACGa,2BAAAA,IAAA,OAAA,EAAI,WAAWuD,MAAI,QAClB,UAAAvD,2BAAA;AAAA,QAACwD,MAAA;AAAA,QAAA;AAAA,UACC,QAAM;AAAA,UACN,QAAM;AAAA,UACN,KAAK;AAAA,UACL,MAAI;AAAA,UACJ;AAAA,UACA,QAAQ;AAAA,UACR,iBAAiB;AAAA,UAEjB,UAAAtD,2BAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,aAAa,MACX,YAAY;AAAA,gBACV;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA;AAAA,gBACA,WAAW,UAAU;AAAA,cAAA,CACtB;AAAA,cAGF,UAAA;AAAA,kBAAM7B,MAAA,MAAA,WAAA,gBAAAA,IAAQ,eACb2B,2BAAA,IAAC,SAAM,EAAA,QAAO,cAAa,MAAM,CAAC,MAAM,OAAO,UAAU,EAAG,CAAA;AAAA,gBAE9DA,2BAAAA,IAAC,gBAAa,EAAA,WAAW,EAAG,CAAA;AAAA,gBAC3B;AAAA,kBACA1B,MAAA,MAAM,WAAN,gBAAAA,IAAc,QACb0B,2BAAA,IAAC,SAAI,QAAO,OAAM,MAAM,CAAC,MAAM,OAAO,KAAK,KAAM,GAAI,GAAG;AAAA,gBAE1DA,2BAAA;AAAA,kBAAC;AAAA,kBAAA;AAAA,oBACC,MAAM;AAAA,oBACN,KAAK;AAAA,oBACL,UAAAjB;AAAA,oBACA;AAAA,oBACA;AAAA,oBACA;AAAA,oBAEA,UAAAiB,2BAAA;AAAA,sBAAC;AAAA,sBAAA;AAAA,wBACC,UAAAjB;AAAA,wBACA,MAAM;AAAA,wBACN;AAAA,wBACA;AAAA,wBAEA,yCAAC0E,gBACC,EAAA,UAAAzD,2BAAA;AAAA,0BAAC;AAAA,0BAAA;AAAA,4BACC,KAAK;AAAA,4BACL,UAAAjB;AAAA,4BACA,UAAU;AAAA,4BACV;AAAA,4BACA;AAAA,4BACC,GAAG;AAAA,0BAAA;AAAA,wBAAA,GAER;AAAA,sBAAA;AAAA,oBACF;AAAA,kBAAA;AAAA,gBACF;AAAA,cAAA;AAAA,YAAA;AAAA,UACF;AAAA,QAAA;AAAA,MAEJ,EAAA,CAAA;AAAA,IAEJ;AAAA,EACF;AAEF,cAAY,eAAe;AAAA,IACzB,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,YAAY;AAAA,IACZ,WAAW;AAAA,IACX,OAAO;AAAA,IACP,UAAU;AAAA,IACV,iBAAiB;AAAA,IACjB,aAAa;AAAA,IACb,aAAa;AAAA,IACb,WAAW;AAAA,IACX,WAAW,CAAC;AAAA,EACd;;;;;;;;;;;;;AC9Ka,QAAA,cAAoC,CAAC;AAAA,IAChD;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,UAAAA;AAAA,IACA;AAAA,EACF,MACEiB,2BAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,MAAK;AAAA,MACL,WAAW,WAAWuD,MAAI,WAAW,WAAW;AAAA,QAC9C,CAACA,MAAI,QAAQ,GAAGxE;AAAA,MAAA,CACjB;AAAA,MACD,OAAO;AAAA,QACL,OAAO,eAAe,KAAK,SAAS;AAAA,QACpC,QAAQ,eAAe,KAAK,SAAS;AAAA,QACrC,QAAQ,eAAe,KAAK,QAAQ;AAAA,QACpC,OAAO,eAAe,KAAK,QAAQ;AAAA,QACnC,WAAW,UAAU,aAAa,QAAQ,aAAa,IAAI;AAAA,MAC7D;AAAA,MACA,SAAS,CAAS,UAAA;AAChB,YAAI,CAACA,WAAU;AACb,kBAAQ,KAAK;AAAA,QACf;AAAA,MACF;AAAA,MAEA,UAAAiB,2BAAA;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,WAAWuD,MAAI;AAAA,UACf,OAAO;AAAA,YACL,WAAW,QAAQ,CAAC,IAAI,gBACrB,QAAQ,KAAK,gBAAgB,IAAI,EACpC;AAAA,UACF;AAAA,UAEA,UAAAvD,2BAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,WAAWuD,MAAI;AAAA,cACf,OAAO;AAAA,gBACL,KAAK,WACH,eAAe,KAAK,WAAW,EACjC,GAAG,MAAM,SAAS,WAAW;AAAA,cAC/B;AAAA,cAEA,UAAArD,2BAAA;AAAA,gBAAC;AAAA,gBAAA;AAAA,kBACC,WAAWqD,MAAI;AAAA,kBACf,OAAO;AAAA,oBACL,WAAW,UAAU,CAAC,QAAQ;AAAA,kBAChC;AAAA,kBACA,OAAO;AAAA,kBAEN,UAAA;AAAA,oBAAA;AAAA,oBACA;AAAA,kBAAA;AAAA,gBAAA;AAAA,cACH;AAAA,YAAA;AAAA,UACF;AAAA,QAAA;AAAA,MACF;AAAA,IAAA;AAAA,EACF;AC9Hc,WAAA,gBAAgB,OAAmB,kBAA0B;AACrE,UAAA,eAAe,MAAM,MAAM,UAAU;AACrC,UAAA,QAAQ,eAAe,QAAQ;AACrC,UAAM,aAAa,KAAK;AACxB,UAAM,aAAa,QACf,KACA,mBAAmB,aAAa,eAAe;AAEnD,WAAO,EAAE,cAAc,OAAO,YAAY,WAAW;AAAA,EACvD;;;;;AC4Ba,QAAA,aAAkC,CAAC;AAAA,IAC9C;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,MAAM;AACJ,UAAM,EAAE,cAAc,OAAO,YAAY,WAAe,IAAApE,MAAA;AAAA,MACtD,MAAM,gBAAgB,OAAO,gBAAgB;AAAA,MAC7C,CAAC,OAAO,gBAAgB;AAAA,IAAA;AAEpB,UAAA,UAAUH,aAAmB,IAAI;AAEvC6C,UAAAA,gBAAgB,MAAM;AACpB,YAAM,QAAQ,QAAQ;AACf,aAAA,MAAM,aAAa,KAAK;AAAA,IACjC,GAAG,CAAE,CAAA;AAED,QAAA,MAAM,WAAW,GAAG;AACf,aAAA;AAAA,IACT;AAGE,WAAA7B,2BAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAW,WAAW,IAAI,WAAW,SAAS;AAAA,QAC9C,gBAAgB,MAAM,aAAa,QAAQ,OAAO;AAAA,QAClD,gBAAgB,CAAS,UAAA;AACvB,uBAAa,QAAQ,OAAO;AAC5B,kBAAQ,UAAU,WAAW,MAAM,mCAAU,QAAQ,GAAG;AAAA,QAC1D;AAAA,QAEC,UAAM,MAAA,IAAI,CAAC,OAAO,UACjBA,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YAEE,GAAG;AAAA,YACJ;AAAA,YACA;AAAA,YACA;AAAA,YACA,UAAU,eAAe;AAAA,YACzB,MAAM,QAAQ,IAAI;AAAA,YAClB;AAAA,YACA;AAAA,YACA,SAAS,CAAS,UAAA;AAChB,6CAAO,QAAQ;AACf,iDAAU;AAAA,YACZ;AAAA,UAAA;AAAA,UAZK;AAAA,QAAA,CAcR;AAAA,MAAA;AAAA,IAAA;AAAA,EAGP;AAEA,aAAW,eAAe;AAAA,IACxB,QAAQ;AAAA,IACR,aAAa;AAAA,IACb,kBAAkB;AAAA,EACpB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"} \ No newline at end of file diff --git a/docs/demos/Layouts.story.tsx b/docs/demos/Layouts.story.tsx index 58b83400..1e10c112 100644 --- a/docs/demos/Layouts.story.tsx +++ b/docs/demos/Layouts.story.tsx @@ -12770,7 +12770,7 @@ export const Connection = () => { "fill": "#7456DB", "activeFill": "#2E233B", "icon": "/assets/zoomcharts/icons/Company.png", - "size":1, + "size": 1, "data": { "id": "4874442", "loaded": true, @@ -12839,7 +12839,7 @@ export const Connection = () => { "fill": "#1dc564", "activeFill": "#347851", "icon": "/assets/zoomcharts/icons/Officer.png", - "size":1, + "size": 1, "data": { "id": "157918667", "loaded": true, @@ -12885,7 +12885,7 @@ export const Connection = () => { "fill": "#7456DB", "activeFill": "#2E233B", "icon": "/assets/zoomcharts/icons/Company.png", - "size":1, + "size": 1, "data": { "id": "7320792", "loaded": true, @@ -12954,7 +12954,7 @@ export const Connection = () => { "fill": "#1dc564", "activeFill": "#347851", "icon": "/assets/zoomcharts/icons/Officer.png", - "size" : 1, + "size": 1, "data": { "id": "157918165", "loaded": true, @@ -13000,8 +13000,8 @@ export const Connection = () => { "fill": "red", "activeFill": "#2E233B", "icon": "/assets/zoomcharts/icons/Company.png", - "showRing":true, - "size":2, + "showRing": true, + "size": 2, "data": { "id": "487883", "loaded": true, @@ -13069,7 +13069,7 @@ export const Connection = () => { "fill": "#1dc564", "activeFill": "#347851", "icon": "/assets/zoomcharts/icons/Officer.png", - "size":1, + "size": 1, "data": { "id": "158016919", "loaded": true, @@ -13115,7 +13115,7 @@ export const Connection = () => { "fill": "#7456DB", "activeFill": "#2E233B", "icon": "/assets/zoomcharts/icons/Company.png", - "size":1, + "size": 1, "data": { "id": "32589261", "loaded": true, @@ -13180,7 +13180,7 @@ export const Connection = () => { "fill": "#1dc564", "activeFill": "#347851", "icon": "/assets/zoomcharts/icons/Officer.png", - "size":1, + "size": 1, "data": { "id": "752901", "loaded": true, @@ -13281,10 +13281,10 @@ export const Connection = () => { pathHoverType: "direct", pathSelectionType: "direct", // type:"multi", -// hotkeys:["selectAll"] -// focusOnSelect:true -// disabled:true -}); + // hotkeys:["selectAll"] + // focusOnSelect:true + // disabled:true + }); return { onNodePointerOut={onNodePointerOut} onNodeClick={onNodeClick} onCanvasClick={onCanvasClick} - onNodeDoubleClick={(node) => { console.log("node",node) }} + onNodeDoubleClick={(node) => { console.log("node", node) }} layoutType="forceDirected2d" draggable cameraMode="pan" edgeLabelPosition="natural" - edgeInterpolation='linear' + edgeInterpolation='linear' labelType="all" nodes={testData.nodes} edges={testData.edges} defaultNodeSize={1} - minNodeSize= {10} - maxNodeSize= {15} + minNodeSize={10} + maxNodeSize={15} edgeArrowPosition="none" renderNode={({ node, ...rest }) => ( @@ -13323,4 +13323,1548 @@ export const Connection = () => { }} /> +} + +export const Network = () => { + const theme: Theme = { + canvas: { + background: "#FAFAFA", + }, + node: { + fill: "#272727", + activeFill: "#1de9ac", + opacity: 1, + selectedOpacity: 1, + inactiveOpacity: 1, + showRing: false, + label: { + color: "#FFF", + activeColor: "#fafafa", + fontSize: 4, + ellipsis: 100, + maxWidth: 50, + backgroundColor: "#000", + borderRadius: 2, + }, + }, + edge: { + fill: "#d8e6ea", + activeFill: "#1DE9AC", + opacity: 1, + selectedOpacity: 1, + inactiveOpacity: 1, + label: { + color: "#FFF", + activeColor: "#fafafa", + fontSize: 4, + ellipsis: 100, + maxWidth: 50, + backgroundColor: "#00a2a1", + borderRadius: 4, + }, + }, + lasso: { + background: "#fff", + border: "none", + }, + arrow: { + fill: "#808080", + activeFill: "#1de9ac", + }, + ring: { + fill: "#464255", + activeFill: "#464255", + }, + } + + const testData = { + "nodes": [ + { + "id": "38941", + "label": "\"REDEMPTORIS MATER\" HOUSE OF FORMATION", + "fill": "#7456DB", + "showRing": true, + "size": 2, + "activeFill": "#A291DE", + "icon": "/assets/graph/company.svg", + "data": { + "id": "38941", + "loaded": true, + "extra": { + "id": "38941", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "labels": [ + "Company" + ], + "properties": { + "date_incorporated": "1994-09-07", + "id": 25657, + "last_accounts_type": "micro-entity", + "date_last_updated": "2024-07-18T11:00:36.140Z", + "company_status_display": "Active", + "address_string": "11 Harewood Avenue, London, NW1 6LD", + "company_type_display": "Private Limited Company by guarantee without share capital, use of `Limited` exemption", + "company_type_group": "Limited Company (LTD)", + "company_number": "02965770", + "name": "\"REDEMPTORIS MATER\" HOUSE OF FORMATION", + "is_company": 1, + "isRoot": 1 + } + }, + "style": { + "label": "\"REDEMPTORIS MATER\" HOUSE OF FORMATION" + }, + "links": [], + "className": "Company", + "fill": "#7456DB", + "showRing": true, + "size": 2 + } + }, + { + "id": "77779728", + "label": "Mr John Francis Green", + "fill": "#2B922F", + "showRing": false, + "size": 1, + "activeFill": "#84C29E", + "icon": "/assets/graph/officer.svg", + "data": { + "id": "77779728", + "loaded": true, + "extra": { + "id": "77779728", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:77779728", + "labels": [ + "Person" + ], + "properties": { + "date_of_birth": "1972-02-01", + "last_name": "Green", + "middle_name": "Francis", + "title": "Mr", + "gender_name": "Male", + "current": 1, + "nationality": "British", + "is_bobble": 0, + "name": "Mr John Francis Green", + "honours": "", + "id": 14175108, + "is_company": 0, + "first_name": "John", + "date_last_updated": "2024-08-01T19:39:14.727Z", + "isRoot": 0 + } + }, + "style": { + "label": "Mr John Francis Green" + }, + "links": [ + { + "id": "244692555", + "from": "77779728", + "to": "38941", + "extra": { + "id": "244692555", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692555", + "type": "OFFICER_OF", + "startNode": "77779728", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:77779728", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Charity Manager", + "officer_type_display": "Director", + "country_of_residence": "England", + "id_entity_type": 2, + "officer_profile_ref": "/officers/W96KfkinSLg0Rgu7bOb5m2Iv_rA/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964637, + "date_appointed": "2011-07-07", + "date_last_updated": "2024-07-12T10:17:46.967Z", + "id_person": 14175108, + "address_string": "11 Harewood Avenue, London, NW1 6LD", + "officer_ref": "/company/02965770/appointments/lgw_9GvDJ1d_v92S04TRDIrgDX0", + "name": "John Francis Green", + "is_company": 0 + } + }, + "label": "Director" + } + ], + "className": "MaleOfficer", + "fill": "#2B922F", + "showRing": false, + "size": 1 + } + }, + { + "id": "157922469", + "label": "Michael James Anderson", + "fill": "#2B922F", + "showRing": false, + "size": 1, + "activeFill": "#84C29E", + "icon": "/assets/graph/officer.svg", + "data": { + "id": "157922469", + "loaded": true, + "extra": { + "id": "157922469", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922469", + "labels": [ + "Person" + ], + "properties": { + "date_of_birth": "1949-08-01", + "last_name": "Anderson", + "title": "", + "middle_name": "James", + "gender_name": "Male", + "current": 1, + "nationality": "British", + "is_bobble": 0, + "name": "Michael James Anderson", + "honours": "", + "id": 18130669, + "is_company": 0, + "first_name": "Michael", + "date_last_updated": "2024-08-01T19:39:58.323Z", + "isRoot": 0 + } + }, + "style": { + "label": "Michael James Anderson" + }, + "links": [ + { + "id": "244692560", + "from": "157922469", + "to": "38941", + "extra": { + "id": "244692560", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692560", + "type": "OFFICER_OF", + "startNode": "157922469", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922469", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Property Manager", + "officer_type_display": "Director", + "country_of_residence": "England", + "id_entity_type": 2, + "officer_profile_ref": "/officers/4wKo7DAJ76mICapL93zEstRR_HY/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964632, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:10:04.240Z", + "id_person": 18130669, + "address_string": "Ground Floor, 17 Barlby Road, London, England, W10 6AN", + "officer_ref": "/company/02965770/appointments/oar4TRKlLPUeOUUE8P6Un3oFKv8", + "address_premises": "Ground Floor", + "name": "Michael James Anderson", + "is_company": 0 + } + }, + "label": "Director" + } + ], + "className": "MaleOfficer", + "fill": "#2B922F", + "showRing": false, + "size": 1 + } + }, + { + "id": "157922466", + "label": "Fr Lorenzo Andreini", + "fill": "#2B922F", + "showRing": false, + "size": 1, + "activeFill": "#84C29E", + "icon": "/assets/graph/officer.svg", + "data": { + "id": "157922466", + "loaded": true, + "extra": { + "id": "157922466", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922466", + "labels": [ + "Person" + ], + "properties": { + "date_of_birth": "1977-06-01", + "last_name": "Andreini", + "middle_name": "", + "title": "Fr", + "gender_name": "Male", + "current": 1, + "nationality": "Italian", + "name": "Fr Lorenzo Andreini", + "honours": "", + "id": 18130763, + "is_company": 0, + "first_name": "Lorenzo", + "date_last_updated": "2024-08-01T19:39:19.443Z", + "isRoot": 0 + } + }, + "style": { + "label": "Fr Lorenzo Andreini" + }, + "links": [ + { + "id": "244692561", + "from": "157922466", + "to": "38941", + "extra": { + "id": "244692561", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692561", + "type": "OFFICER_OF", + "startNode": "157922466", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922466", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Rector", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/qijpsIrFm0YUdnsQUhbSU0HC3Ao/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964633, + "date_appointed": "2015-09-01", + "date_last_updated": "2024-07-12T10:23:44.103Z", + "id_person": 18130763, + "address_string": "11, Harewood Avenue, London, England, NW1 6LD", + "officer_ref": "/company/02965770/appointments/B7Ra7QqJp41f6OsJGjAhphWLoDQ", + "address_premises": "11", + "name": "Lorenzo Andreini", + "is_company": 0 + } + }, + "label": "Director" + } + ], + "className": "MaleOfficer", + "fill": "#2B922F", + "showRing": false, + "size": 1 + } + }, + { + "id": "14806539", + "label": "Peter John Wallach", + "fill": "#2B922F", + "showRing": false, + "size": 1, + "activeFill": "#84C29E", + "icon": "/assets/graph/officer.svg", + "data": { + "id": "14806539", + "loaded": true, + "extra": { + "id": "14806539", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:14806539", + "labels": [ + "Person" + ], + "properties": { + "date_of_birth": "1941-03-01", + "last_name": "Wallach", + "title": "", + "middle_name": "John", + "gender_name": "Male", + "current": 1, + "nationality": "British", + "name": "Peter John Wallach", + "honours": "", + "id": 3246442, + "is_company": 0, + "first_name": "Peter", + "date_last_updated": "2024-08-01T19:39:38.550Z", + "isRoot": 0 + } + }, + "style": { + "label": "Peter John Wallach" + }, + "links": [ + { + "id": "244692551", + "from": "14806539", + "to": "38941", + "extra": { + "id": "244692551", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692551", + "type": "OFFICER_OF", + "startNode": "14806539", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:14806539", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Retired", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/6ArNnmmslBFBocADBCMKk7Lg9T0/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964641, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:17:46.363Z", + "id_person": 3246442, + "address_string": "9 Clovelly Road, Ealing, London, W5 5HF", + "officer_ref": "/company/02965770/appointments/GSs5GUU10lqcrSzrjdDoLUZfaDg", + "name": "Peter John Wallach", + "is_company": 0 + } + }, + "label": "Director" + }, + { + "id": "244692551", + "from": "14806539", + "to": "38941", + "extra": { + "id": "244692551", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692551", + "type": "OFFICER_OF", + "startNode": "14806539", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:14806539", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Retired", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/6ArNnmmslBFBocADBCMKk7Lg9T0/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964641, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:17:46.363Z", + "id_person": 3246442, + "address_string": "9 Clovelly Road, Ealing, London, W5 5HF", + "officer_ref": "/company/02965770/appointments/GSs5GUU10lqcrSzrjdDoLUZfaDg", + "name": "Peter John Wallach", + "is_company": 0 + } + }, + "label": "Director" + }, + { + "id": "286665898", + "from": "14806539", + "to": "4190873", + "extra": { + "id": "286665898", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:286665898", + "type": "OFFICER_OF", + "startNode": "14806539", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:14806539", + "endNode": "4190873", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:4190873", + "properties": { + "occupation": "Company Director", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/6ArNnmmslBFBocADBCMKk7Lg9T0/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 223197759, + "date_appointed": "2002-11-29", + "date_last_updated": "2024-07-21T04:18:25.933Z", + "id_person": 3246442, + "address_string": "Alderwick James & Co Suite 4, The Sanctuary 23 Oak Hill Grove, Surbiton, Surrey, KT6 6DU", + "officer_ref": "/company/04604319/appointments/PRbvJdh5rvX0VxlQ5gPg6sX-Xwk", + "name": "Peter John Wallach", + "is_company": 0 + } + }, + "label": "Director" + } + ], + "className": "MaleOfficer", + "fill": "#2B922F", + "showRing": false, + "size": 1 + } + }, + { + "id": "157922464", + "label": "Anthony Matthew Cook", + "fill": "#2B922F", + "showRing": false, + "size": 1, + "activeFill": "#84C29E", + "icon": "/assets/graph/officer.svg", + "data": { + "id": "157922464", + "loaded": true, + "extra": { + "id": "157922464", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922464", + "labels": [ + "Person" + ], + "properties": { + "date_of_birth": "1940-11-01", + "last_name": "Cook", + "title": "", + "middle_name": "Matthew", + "gender_name": "Male", + "current": 1, + "nationality": "British", + "is_bobble": 0, + "name": "Anthony Matthew Cook", + "honours": "", + "id": 18131132, + "is_company": 0, + "first_name": "Anthony", + "date_last_updated": "2024-08-01T19:38:23.423Z", + "isRoot": 0 + } + }, + "style": { + "label": "Anthony Matthew Cook" + }, + "links": [ + { + "id": "244692567", + "from": "157922464", + "to": "38941", + "extra": { + "id": "244692567", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692567", + "type": "OFFICER_OF", + "startNode": "157922464", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922464", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Retired", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/Vlfv8G1QvE_bLpTFCGN5-8G0zFA/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964635, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:33:18.437Z", + "id_person": 18131132, + "address_string": "36 Bromley Street, London, E1 0NB", + "officer_ref": "/company/02965770/appointments/HsCQR31HZyq6AenxswQPWUK8IkE", + "name": "Anthony Matthew Cook", + "is_company": 0 + } + }, + "label": "Director" + } + ], + "className": "MaleOfficer", + "fill": "#2B922F", + "showRing": false, + "size": 1 + } + }, + { + "id": "157922465", + "label": "Mr John David Hayward", + "fill": "#2B922F", + "showRing": false, + "size": 1, + "activeFill": "#84C29E", + "icon": "/assets/graph/officer.svg", + "data": { + "id": "157922465", + "loaded": true, + "extra": { + "id": "157922465", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922465", + "labels": [ + "Person" + ], + "properties": { + "date_of_birth": "1981-08-01", + "last_name": "Hayward", + "title": "Mr", + "middle_name": "David", + "gender_name": "Male", + "current": 1, + "nationality": "British", + "is_bobble": 0, + "name": "Mr John David Hayward", + "honours": "", + "id": 18131074, + "is_company": 0, + "first_name": "John", + "date_last_updated": "2024-08-01T19:38:39.907Z", + "isRoot": 0 + } + }, + "style": { + "label": "Mr John David Hayward" + }, + "links": [ + { + "id": "244692564", + "from": "157922465", + "to": "38941", + "extra": { + "id": "244692564", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692564", + "type": "OFFICER_OF", + "startNode": "157922465", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922465", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Charity Manager", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/Amu5WniD4tU3arjk8OWLMqiljWE/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964638, + "date_appointed": "2015-07-09", + "date_last_updated": "2024-07-12T10:23:44.817Z", + "id_person": 18131074, + "address_string": "42, Bluebell Avenue, London, United Kingdom, E12 6UJ", + "officer_ref": "/company/02965770/appointments/cCo-nH5nvSdBB5I7eCeOQrsQjCU", + "address_premises": "42", + "name": "John David Hayward", + "is_company": 0 + } + }, + "label": "Director" + } + ], + "className": "MaleOfficer", + "fill": "#2B922F", + "showRing": false, + "size": 1 + } + }, + { + "id": "157922457", + "label": "Dr Robert Christopher Richmond Horsburgh", + "fill": "#2B922F", + "showRing": false, + "size": 1, + "activeFill": "#84C29E", + "icon": "/assets/graph/officer.svg", + "data": { + "id": "157922457", + "loaded": true, + "extra": { + "id": "157922457", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "labels": [ + "Person" + ], + "properties": { + "date_of_birth": "1949-04-01", + "last_name": "Horsburgh", + "title": "Dr", + "middle_name": "Christopher Richmond", + "gender_name": "Male", + "current": 1, + "nationality": "British", + "is_bobble": 0, + "name": "Dr Robert Christopher Richmond Horsburgh", + "honours": "", + "id": 18130089, + "is_company": 0, + "first_name": "Robert", + "date_last_updated": "2024-08-01T19:40:24.647Z", + "isRoot": 0 + } + }, + "style": { + "label": "Dr Robert Christopher Richmond Horsburgh" + }, + "links": [ + { + "id": "244692558", + "from": "157922457", + "to": "38941", + "extra": { + "id": "244692558", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692558", + "type": "OFFICER_OF", + "startNode": "157922457", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Management Consultant", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/ZJBoGo8toy40kV1YATAZLgXbp4w/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964639, + "date_appointed": "2015-07-09", + "date_last_updated": "2024-07-12T10:33:18.240Z", + "id_person": 18130089, + "address_string": "18, Abbotsbury Gardens, Pinner, Middlesex, England, HA5 1SZ", + "officer_ref": "/company/02965770/appointments/6f1oaWPSman8aO-rfKh9h1oaBec", + "address_premises": "18", + "name": "Robert Christopher Richmond Horsburgh", + "is_company": 0 + } + }, + "label": "Director" + }, + { + "id": "287422644", + "from": "157922457", + "to": "30968833", + "extra": { + "id": "287422644", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:287422644", + "type": "OFFICER_OF", + "startNode": "157922457", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "endNode": "30968833", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:30968833", + "properties": { + "occupation": "It Consultant", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/ZJBoGo8toy40kV1YATAZLgXbp4w/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 314084954, + "date_appointed": "2017-03-20", + "date_last_updated": "2024-07-27T06:00:56.390Z", + "id_person": 18130089, + "address_string": "St George's Catholic School, Lanark Road, Maida Vale, London, W9 1RB", + "officer_ref": "/company/08148675/appointments/ZkMGSeGDVHgauF0Q5dISsLqgAfI", + "address_premises": "St George's Catholic School", + "name": "Robert Christopher Richmond Horsburgh", + "is_company": 0 + } + }, + "label": "Director" + }, + { + "id": "244692558", + "from": "157922457", + "to": "38941", + "extra": { + "id": "244692558", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692558", + "type": "OFFICER_OF", + "startNode": "157922457", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Management Consultant", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/ZJBoGo8toy40kV1YATAZLgXbp4w/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964639, + "date_appointed": "2015-07-09", + "date_last_updated": "2024-07-12T10:33:18.240Z", + "id_person": 18130089, + "address_string": "18, Abbotsbury Gardens, Pinner, Middlesex, England, HA5 1SZ", + "officer_ref": "/company/02965770/appointments/6f1oaWPSman8aO-rfKh9h1oaBec", + "address_premises": "18", + "name": "Robert Christopher Richmond Horsburgh", + "is_company": 0 + } + }, + "label": "Director" + }, + { + "id": "284824894", + "from": "157922457", + "to": "28747298", + "extra": { + "id": "284824894", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:284824894", + "type": "OFFICER_OF", + "startNode": "157922457", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "endNode": "28747298", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:28747298", + "properties": { + "occupation": "None Supplied", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/ZJBoGo8toy40kV1YATAZLgXbp4w/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 327573699, + "date_appointed": "2018-12-04", + "date_last_updated": "2024-07-08T16:42:45.460Z", + "id_person": 18130089, + "address_string": "St Vincent's Nursing Home, Wiltshire Lane, Eastcote, Pinner, Middlesex, England, HA5 2NB", + "officer_ref": "/company/02721809/appointments/OJ8E-sf2H7dIOAfM9z2bgpK2pqo", + "address_premises": "St Vincent's Nursing Home", + "name": "Robert Christopher Richmond Horsburgh", + "is_company": 0 + } + }, + "label": "Director" + }, + { + "id": "244692558", + "from": "157922457", + "to": "38941", + "extra": { + "id": "244692558", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692558", + "type": "OFFICER_OF", + "startNode": "157922457", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Management Consultant", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/ZJBoGo8toy40kV1YATAZLgXbp4w/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964639, + "date_appointed": "2015-07-09", + "date_last_updated": "2024-07-12T10:33:18.240Z", + "id_person": 18130089, + "address_string": "18, Abbotsbury Gardens, Pinner, Middlesex, England, HA5 1SZ", + "officer_ref": "/company/02965770/appointments/6f1oaWPSman8aO-rfKh9h1oaBec", + "address_premises": "18", + "name": "Robert Christopher Richmond Horsburgh", + "is_company": 0 + } + }, + "label": "Director" + } + ], + "className": "MaleOfficer", + "fill": "#2B922F", + "showRing": false, + "size": 1 + } + }, + { + "id": "157922467", + "label": "Terence Fergal Martin", + "fill": "#2B922F", + "showRing": false, + "size": 1, + "activeFill": "#84C29E", + "icon": "/assets/graph/officer.svg", + "data": { + "id": "157922467", + "loaded": true, + "extra": { + "id": "157922467", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922467", + "labels": [ + "Person" + ], + "properties": { + "date_of_birth": "1954-04-01", + "last_name": "Martin", + "title": "", + "middle_name": "Fergal", + "gender_name": "Male", + "current": 1, + "nationality": "British", + "name": "Terence Fergal Martin", + "honours": "", + "id": 18131075, + "is_company": 0, + "first_name": "Terence", + "date_last_updated": "2024-08-01T19:39:20.770Z", + "isRoot": 0 + } + }, + "style": { + "label": "Terence Fergal Martin" + }, + "links": [ + { + "id": "244692565", + "from": "157922467", + "to": "38941", + "extra": { + "id": "244692565", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692565", + "type": "OFFICER_OF", + "startNode": "157922467", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922467", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Catholic Book Publisher", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/vRfE_1ZqVJv-sA4WD7Y2VC94JpA/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964640, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:10:14.777Z", + "id_person": 18131075, + "address_string": "48 Selsdon Road, West Norwood, SE27 0PG", + "officer_ref": "/company/02965770/appointments/eyeL9zP8YKld8m2XJYvNTA8gI_M", + "name": "Terence Fergal Martin", + "is_company": 0 + } + }, + "label": "Director" + } + ], + "className": "MaleOfficer", + "fill": "#2B922F", + "showRing": false, + "size": 1 + } + }, + { + "id": "30968833", + "label": "THE CARDINAL HUME ACADEMIES TRUST", + "fill": "#7456DB", + "showRing": false, + "size": 1, + "activeFill": "#A291DE", + "icon": "/assets/graph/company.svg", + "data": { + "id": "30968833", + "loaded": true, + "extra": { + "id": "30968833", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:30968833", + "labels": [ + "Company" + ], + "properties": { + "date_incorporated": "2012-07-18", + "id": 2976663, + "date_last_updated": "2024-03-11T14:20:15.633Z", + "company_status_display": "Active", + "address_string": "St George's Catholic School Lanark Road, Maida Vale, London, W9 1RB", + "company_type_display": "Private Limited Company by guarantee without share capital, use of `Limited` exemption", + "company_type_group": "Limited Company (LTD)", + "company_number": "08148675", + "name": "THE CARDINAL HUME ACADEMIES TRUST", + "is_company": 1, + "isRoot": 0 + } + }, + "style": { + "label": "THE CARDINAL HUME ACADEMIES TRUST" + }, + "links": [], + "className": "Company", + "fill": "#7456DB", + "showRing": false, + "size": 1 + } + }, + { + "id": "28747298", + "label": "ST. VINCENT'S CHARITABLE TRUST", + "fill": "#7456DB", + "showRing": false, + "size": 1, + "activeFill": "#A291DE", + "icon": "/assets/graph/company.svg", + "data": { + "id": "28747298", + "loaded": true, + "extra": { + "id": "28747298", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:28747298", + "labels": [ + "Company" + ], + "properties": { + "date_incorporated": "1992-06-09", + "id": 2768122, + "last_accounts_type": "full", + "date_last_updated": "2024-06-20T12:00:21.613Z", + "company_status_display": "Active", + "address_string": "St Vincent's Nursing Home Wiltshire Lane, Eastcote, Pinner, Middlesex, England, HA5 2NB", + "company_type_display": "Private Limited Company by guarantee without share capital, use of `Limited` exemption", + "company_type_group": "Limited Company (LTD)", + "company_number": "02721809", + "name": "ST. VINCENT'S CHARITABLE TRUST", + "is_company": 1, + "isRoot": 0 + } + }, + "style": { + "label": "ST. VINCENT'S CHARITABLE TRUST" + }, + "links": [], + "className": "Company", + "fill": "#7456DB", + "showRing": false, + "size": 1 + } + }, + { + "id": "4190873", + "label": "THE ADDED RESOURCE LIMITED", + "fill": "#7456DB", + "showRing": false, + "size": 1, + "activeFill": "#A291DE", + "icon": "/assets/graph/company.svg", + "data": { + "id": "4190873", + "loaded": true, + "extra": { + "id": "4190873", + "elementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:4190873", + "labels": [ + "Company" + ], + "properties": { + "date_incorporated": "2002-11-29", + "date_dissolved": "2019-03-05", + "id": 2950403, + "date_last_updated": "2024-02-22T07:46:54.267Z", + "company_status_display": "Dissolved", + "address_string": "Alderwick James & Co Suite 4, The Sanctuary 23 Oak Hill Grove, Surbiton, Surrey, KT6 6DU", + "company_type_display": "Private limited company", + "company_type_group": "Limited Company (LTD)", + "company_number": "04604319", + "name": "THE ADDED RESOURCE LIMITED", + "is_company": 1, + "isRoot": 0 + } + }, + "style": { + "label": "THE ADDED RESOURCE LIMITED" + }, + "links": [], + "className": "Company", + "fill": "#7456DB", + "showRing": false, + "size": 1 + } + } + ], + "edges": [ + { + "id": "244692555", + "source": "77779728", + "target": "38941", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "244692555", + "from": "77779728", + "to": "38941", + "extra": { + "id": "244692555", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692555", + "type": "OFFICER_OF", + "startNode": "77779728", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:77779728", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Charity Manager", + "officer_type_display": "Director", + "country_of_residence": "England", + "id_entity_type": 2, + "officer_profile_ref": "/officers/W96KfkinSLg0Rgu7bOb5m2Iv_rA/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964637, + "date_appointed": "2011-07-07", + "date_last_updated": "2024-07-12T10:17:46.967Z", + "id_person": 14175108, + "address_string": "11 Harewood Avenue, London, NW1 6LD", + "officer_ref": "/company/02965770/appointments/lgw_9GvDJ1d_v92S04TRDIrgDX0", + "name": "John Francis Green", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "244692560", + "source": "157922469", + "target": "38941", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "244692560", + "from": "157922469", + "to": "38941", + "extra": { + "id": "244692560", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692560", + "type": "OFFICER_OF", + "startNode": "157922469", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922469", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Property Manager", + "officer_type_display": "Director", + "country_of_residence": "England", + "id_entity_type": 2, + "officer_profile_ref": "/officers/4wKo7DAJ76mICapL93zEstRR_HY/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964632, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:10:04.240Z", + "id_person": 18130669, + "address_string": "Ground Floor, 17 Barlby Road, London, England, W10 6AN", + "officer_ref": "/company/02965770/appointments/oar4TRKlLPUeOUUE8P6Un3oFKv8", + "address_premises": "Ground Floor", + "name": "Michael James Anderson", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "244692561", + "source": "157922466", + "target": "38941", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "244692561", + "from": "157922466", + "to": "38941", + "extra": { + "id": "244692561", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692561", + "type": "OFFICER_OF", + "startNode": "157922466", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922466", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Rector", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/qijpsIrFm0YUdnsQUhbSU0HC3Ao/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964633, + "date_appointed": "2015-09-01", + "date_last_updated": "2024-07-12T10:23:44.103Z", + "id_person": 18130763, + "address_string": "11, Harewood Avenue, London, England, NW1 6LD", + "officer_ref": "/company/02965770/appointments/B7Ra7QqJp41f6OsJGjAhphWLoDQ", + "address_premises": "11", + "name": "Lorenzo Andreini", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "244692551", + "source": "14806539", + "target": "38941", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "244692551", + "from": "14806539", + "to": "38941", + "extra": { + "id": "244692551", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692551", + "type": "OFFICER_OF", + "startNode": "14806539", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:14806539", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Retired", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/6ArNnmmslBFBocADBCMKk7Lg9T0/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964641, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:17:46.363Z", + "id_person": 3246442, + "address_string": "9 Clovelly Road, Ealing, London, W5 5HF", + "officer_ref": "/company/02965770/appointments/GSs5GUU10lqcrSzrjdDoLUZfaDg", + "name": "Peter John Wallach", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "244692567", + "source": "157922464", + "target": "38941", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "244692567", + "from": "157922464", + "to": "38941", + "extra": { + "id": "244692567", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692567", + "type": "OFFICER_OF", + "startNode": "157922464", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922464", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Retired", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/Vlfv8G1QvE_bLpTFCGN5-8G0zFA/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964635, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:33:18.437Z", + "id_person": 18131132, + "address_string": "36 Bromley Street, London, E1 0NB", + "officer_ref": "/company/02965770/appointments/HsCQR31HZyq6AenxswQPWUK8IkE", + "name": "Anthony Matthew Cook", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "244692564", + "source": "157922465", + "target": "38941", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "244692564", + "from": "157922465", + "to": "38941", + "extra": { + "id": "244692564", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692564", + "type": "OFFICER_OF", + "startNode": "157922465", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922465", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Charity Manager", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/Amu5WniD4tU3arjk8OWLMqiljWE/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964638, + "date_appointed": "2015-07-09", + "date_last_updated": "2024-07-12T10:23:44.817Z", + "id_person": 18131074, + "address_string": "42, Bluebell Avenue, London, United Kingdom, E12 6UJ", + "officer_ref": "/company/02965770/appointments/cCo-nH5nvSdBB5I7eCeOQrsQjCU", + "address_premises": "42", + "name": "John David Hayward", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "244692558", + "source": "157922457", + "target": "38941", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "244692558", + "from": "157922457", + "to": "38941", + "extra": { + "id": "244692558", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692558", + "type": "OFFICER_OF", + "startNode": "157922457", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Management Consultant", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/ZJBoGo8toy40kV1YATAZLgXbp4w/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964639, + "date_appointed": "2015-07-09", + "date_last_updated": "2024-07-12T10:33:18.240Z", + "id_person": 18130089, + "address_string": "18, Abbotsbury Gardens, Pinner, Middlesex, England, HA5 1SZ", + "officer_ref": "/company/02965770/appointments/6f1oaWPSman8aO-rfKh9h1oaBec", + "address_premises": "18", + "name": "Robert Christopher Richmond Horsburgh", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "244692565", + "source": "157922467", + "target": "38941", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "244692565", + "from": "157922467", + "to": "38941", + "extra": { + "id": "244692565", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:244692565", + "type": "OFFICER_OF", + "startNode": "157922467", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922467", + "endNode": "38941", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:38941", + "properties": { + "occupation": "Catholic Book Publisher", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/vRfE_1ZqVJv-sA4WD7Y2VC94JpA/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 311964640, + "date_appointed": "1995-06-08", + "date_last_updated": "2024-07-12T10:10:14.777Z", + "id_person": 18131075, + "address_string": "48 Selsdon Road, West Norwood, SE27 0PG", + "officer_ref": "/company/02965770/appointments/eyeL9zP8YKld8m2XJYvNTA8gI_M", + "name": "Terence Fergal Martin", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "287422644", + "source": "157922457", + "target": "30968833", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "287422644", + "from": "157922457", + "to": "30968833", + "extra": { + "id": "287422644", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:287422644", + "type": "OFFICER_OF", + "startNode": "157922457", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "endNode": "30968833", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:30968833", + "properties": { + "occupation": "It Consultant", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/ZJBoGo8toy40kV1YATAZLgXbp4w/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 314084954, + "date_appointed": "2017-03-20", + "date_last_updated": "2024-07-27T06:00:56.390Z", + "id_person": 18130089, + "address_string": "St George's Catholic School, Lanark Road, Maida Vale, London, W9 1RB", + "officer_ref": "/company/08148675/appointments/ZkMGSeGDVHgauF0Q5dISsLqgAfI", + "address_premises": "St George's Catholic School", + "name": "Robert Christopher Richmond Horsburgh", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "284824894", + "source": "157922457", + "target": "28747298", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "284824894", + "from": "157922457", + "to": "28747298", + "extra": { + "id": "284824894", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:284824894", + "type": "OFFICER_OF", + "startNode": "157922457", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:157922457", + "endNode": "28747298", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:28747298", + "properties": { + "occupation": "None Supplied", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/ZJBoGo8toy40kV1YATAZLgXbp4w/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 327573699, + "date_appointed": "2018-12-04", + "date_last_updated": "2024-07-08T16:42:45.460Z", + "id_person": 18130089, + "address_string": "St Vincent's Nursing Home, Wiltshire Lane, Eastcote, Pinner, Middlesex, England, HA5 2NB", + "officer_ref": "/company/02721809/appointments/OJ8E-sf2H7dIOAfM9z2bgpK2pqo", + "address_premises": "St Vincent's Nursing Home", + "name": "Robert Christopher Richmond Horsburgh", + "is_company": 0 + } + }, + "label": "Director" + } + }, + { + "id": "286665898", + "source": "14806539", + "target": "4190873", + "label": "Director", + "backgroundColor": "#00A2A1", + "data": { + "id": "286665898", + "from": "14806539", + "to": "4190873", + "extra": { + "id": "286665898", + "elementId": "5:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:286665898", + "type": "OFFICER_OF", + "startNode": "14806539", + "startNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:14806539", + "endNode": "4190873", + "endNodeElementId": "4:9143ec59-4bd2-40a1-b4c2-3921e2aa8d4f:4190873", + "properties": { + "occupation": "Company Director", + "officer_type_display": "Director", + "country_of_residence": "United Kingdom", + "id_entity_type": 2, + "officer_profile_ref": "/officers/6ArNnmmslBFBocADBCMKk7Lg9T0/appointments", + "entity_type_name": "Individual", + "officer_type_group": "Director", + "current": 1, + "id": 223197759, + "date_appointed": "2002-11-29", + "date_last_updated": "2024-07-21T04:18:25.933Z", + "id_person": 3246442, + "address_string": "Alderwick James & Co Suite 4, The Sanctuary 23 Oak Hill Grove, Surbiton, Surrey, KT6 6DU", + "officer_ref": "/company/04604319/appointments/PRbvJdh5rvX0VxlQ5gPg6sX-Xwk", + "name": "Peter John Wallach", + "is_company": 0 + } + }, + "label": "Director" + } + } + ] + } + + const ref = useRef(null); + const { selections, actives, onNodeClick, onCanvasClick, onNodePointerOver, onNodePointerOut } = useSelection({ + ref: ref, + nodes: testData.nodes, + edges: testData.edges, + pathHoverType: "direct", + pathSelectionType: "direct", + }); + + + return ( + + )} + /> } \ No newline at end of file diff --git a/src/symbols/Ring.tsx b/src/symbols/Ring.tsx index f56e3fd9..10450277 100644 --- a/src/symbols/Ring.tsx +++ b/src/symbols/Ring.tsx @@ -74,7 +74,7 @@ export const Ring: FC = ({ return ( - + = ({ attach="material" color={normalizedColor} transparent={true} - depthTest={true} + depthTest={false} opacity={ringOpacity} side={DoubleSide} fog={true} diff --git a/src/symbols/nodes/Sphere.tsx b/src/symbols/nodes/Sphere.tsx index bf618b20..280aa14f 100644 --- a/src/symbols/nodes/Sphere.tsx +++ b/src/symbols/nodes/Sphere.tsx @@ -51,7 +51,7 @@ export const Sphere: FC = ({ /> {(showRing || selected || active) && ( - + mode === "library" ? { + plugins: [ + svgrPlugin(), + tsconfigPaths(), + cssInjectedByJsPlugin(), + react(), + dts({ + insertTypesEntry: true, + include: ["src"] + }), + checker({ + typescript: true + }) + ], + test: { + globals: true, + environment: "jsdom" + }, + build: { + minify: false, + sourcemap: true, + copyPublicDir: false, + lib: { + entry: resolve("src", "index.ts"), + name: "reagraph", + fileName: "index" + }, + rollupOptions: { + plugins: [ + external({ + includeDependencies: true + }) + ] + } + } + } : { + plugins: [ + svgrPlugin(), + tsconfigPaths(), + react(), + checker({ + typescript: true + }) + ], + test: { + globals: true, + environment: "jsdom" + } + } +); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJEOlxcXFxjbGluY2hpbmZvc3lzdGVtc1xcXFxtbmFpXFxcXHBvY1xcXFxyZWFncmFwaFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiRDpcXFxcY2xpbmNoaW5mb3N5c3RlbXNcXFxcbW5haVxcXFxwb2NcXFxccmVhZ3JhcGhcXFxcdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0Q6L2NsaW5jaGluZm9zeXN0ZW1zL21uYWkvcG9jL3JlYWdyYXBoL3ZpdGUuY29uZmlnLnRzXCI7Ly8vIDxyZWZlcmVuY2UgdHlwZXM9XCJ2aXRlc3RcIiAvPlxyXG5cclxuaW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSc7XHJcbmltcG9ydCByZWFjdCBmcm9tICdAdml0ZWpzL3BsdWdpbi1yZWFjdCc7XHJcbmltcG9ydCBzdmdyUGx1Z2luIGZyb20gJ3ZpdGUtcGx1Z2luLXN2Z3InO1xyXG5pbXBvcnQgdHNjb25maWdQYXRocyBmcm9tICd2aXRlLXRzY29uZmlnLXBhdGhzJztcclxuaW1wb3J0IGNoZWNrZXIgZnJvbSAndml0ZS1wbHVnaW4tY2hlY2tlcic7XHJcbmltcG9ydCB7IHJlc29sdmUgfSBmcm9tICdwYXRoJztcclxuaW1wb3J0IGV4dGVybmFsIGZyb20gJ3JvbGx1cC1wbHVnaW4tcGVlci1kZXBzLWV4dGVybmFsJztcclxuaW1wb3J0IGR0cyBmcm9tICd2aXRlLXBsdWdpbi1kdHMnO1xyXG5pbXBvcnQgY3NzSW5qZWN0ZWRCeUpzUGx1Z2luIGZyb20gJ3ZpdGUtcGx1Z2luLWNzcy1pbmplY3RlZC1ieS1qcyc7XHJcblxyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoKHsgbW9kZSB9KSA9PlxyXG4gIG1vZGUgPT09ICdsaWJyYXJ5J1xyXG4gICAgPyB7XHJcbiAgICAgIHBsdWdpbnM6IFtcclxuICAgICAgICBzdmdyUGx1Z2luKCksXHJcbiAgICAgICAgdHNjb25maWdQYXRocygpLFxyXG4gICAgICAgIGNzc0luamVjdGVkQnlKc1BsdWdpbigpLFxyXG4gICAgICAgIHJlYWN0KCksXHJcbiAgICAgICAgZHRzKHtcclxuICAgICAgICAgIGluc2VydFR5cGVzRW50cnk6IHRydWUsXHJcbiAgICAgICAgICBpbmNsdWRlOiBbJ3NyYyddXHJcbiAgICAgICAgfSksXHJcbiAgICAgICAgY2hlY2tlcih7XHJcbiAgICAgICAgICB0eXBlc2NyaXB0OiB0cnVlXHJcbiAgICAgICAgfSlcclxuICAgICAgXSxcclxuICAgICAgdGVzdDoge1xyXG4gICAgICAgIGdsb2JhbHM6IHRydWUsXHJcbiAgICAgICAgZW52aXJvbm1lbnQ6ICdqc2RvbSdcclxuICAgICAgfSxcclxuICAgICAgYnVpbGQ6IHtcclxuICAgICAgICBtaW5pZnk6IGZhbHNlLFxyXG4gICAgICAgIHNvdXJjZW1hcDogdHJ1ZSxcclxuICAgICAgICBjb3B5UHVibGljRGlyOiBmYWxzZSxcclxuICAgICAgICBsaWI6IHtcclxuICAgICAgICAgIGVudHJ5OiByZXNvbHZlKCdzcmMnLCAnaW5kZXgudHMnKSxcclxuICAgICAgICAgIG5hbWU6ICdyZWFncmFwaCcsXHJcbiAgICAgICAgICBmaWxlTmFtZTogJ2luZGV4J1xyXG4gICAgICAgIH0sXHJcbiAgICAgICAgcm9sbHVwT3B0aW9uczoge1xyXG4gICAgICAgICAgcGx1Z2luczogW1xyXG4gICAgICAgICAgICBleHRlcm5hbCh7XHJcbiAgICAgICAgICAgICAgaW5jbHVkZURlcGVuZGVuY2llczogdHJ1ZVxyXG4gICAgICAgICAgICB9KVxyXG4gICAgICAgICAgXVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG4gICAgOiB7XHJcbiAgICAgIHBsdWdpbnM6IFtcclxuICAgICAgICBzdmdyUGx1Z2luKCksXHJcbiAgICAgICAgdHNjb25maWdQYXRocygpLFxyXG4gICAgICAgIHJlYWN0KCksXHJcbiAgICAgICAgY2hlY2tlcih7XHJcbiAgICAgICAgICB0eXBlc2NyaXB0OiB0cnVlXHJcbiAgICAgICAgfSlcclxuICAgICAgXSxcclxuICAgICAgdGVzdDoge1xyXG4gICAgICAgIGdsb2JhbHM6IHRydWUsXHJcbiAgICAgICAgZW52aXJvbm1lbnQ6ICdqc2RvbSdcclxuICAgICAgfVxyXG4gICAgfVxyXG4pO1xyXG4iXSwKICAibWFwcGluZ3MiOiAiO0FBRUEsU0FBUyxvQkFBb0I7QUFDN0IsT0FBTyxXQUFXO0FBQ2xCLE9BQU8sZ0JBQWdCO0FBQ3ZCLE9BQU8sbUJBQW1CO0FBQzFCLE9BQU8sYUFBYTtBQUNwQixTQUFTLGVBQWU7QUFDeEIsT0FBTyxjQUFjO0FBQ3JCLE9BQU8sU0FBUztBQUNoQixPQUFPLDJCQUEyQjtBQUVsQyxJQUFPLHNCQUFRO0FBQUEsRUFBYSxDQUFDLEVBQUUsS0FBSyxNQUNsQyxTQUFTLFlBQ0w7QUFBQSxJQUNBLFNBQVM7QUFBQSxNQUNQLFdBQVc7QUFBQSxNQUNYLGNBQWM7QUFBQSxNQUNkLHNCQUFzQjtBQUFBLE1BQ3RCLE1BQU07QUFBQSxNQUNOLElBQUk7QUFBQSxRQUNGLGtCQUFrQjtBQUFBLFFBQ2xCLFNBQVMsQ0FBQyxLQUFLO0FBQUEsTUFDakIsQ0FBQztBQUFBLE1BQ0QsUUFBUTtBQUFBLFFBQ04sWUFBWTtBQUFBLE1BQ2QsQ0FBQztBQUFBLElBQ0g7QUFBQSxJQUNBLE1BQU07QUFBQSxNQUNKLFNBQVM7QUFBQSxNQUNULGFBQWE7QUFBQSxJQUNmO0FBQUEsSUFDQSxPQUFPO0FBQUEsTUFDTCxRQUFRO0FBQUEsTUFDUixXQUFXO0FBQUEsTUFDWCxlQUFlO0FBQUEsTUFDZixLQUFLO0FBQUEsUUFDSCxPQUFPLFFBQVEsT0FBTyxVQUFVO0FBQUEsUUFDaEMsTUFBTTtBQUFBLFFBQ04sVUFBVTtBQUFBLE1BQ1o7QUFBQSxNQUNBLGVBQWU7QUFBQSxRQUNiLFNBQVM7QUFBQSxVQUNQLFNBQVM7QUFBQSxZQUNQLHFCQUFxQjtBQUFBLFVBQ3ZCLENBQUM7QUFBQSxRQUNIO0FBQUEsTUFDRjtBQUFBLElBQ0Y7QUFBQSxFQUNGLElBQ0U7QUFBQSxJQUNBLFNBQVM7QUFBQSxNQUNQLFdBQVc7QUFBQSxNQUNYLGNBQWM7QUFBQSxNQUNkLE1BQU07QUFBQSxNQUNOLFFBQVE7QUFBQSxRQUNOLFlBQVk7QUFBQSxNQUNkLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFDQSxNQUFNO0FBQUEsTUFDSixTQUFTO0FBQUEsTUFDVCxhQUFhO0FBQUEsSUFDZjtBQUFBLEVBQ0Y7QUFDSjsiLAogICJuYW1lcyI6IFtdCn0K