UNPKG

trassel

Version:
16 lines 566 kB
/** @preserve @license @cc_on * ---------------------------------------------------------- * trassel version 0.1.9 * Graph computing in JavaScript * https://fukurosan.github.io/Trassel/ * Copyright (c) 2024 Henrik Olofsson * All Rights Reserved. MIT License * https://mit-license.org/ * ---------------------------------------------------------- */ var Trassel=function(t){"use strict";const e=Object.freeze({DEFAULT_EDGE_STRENGTH:.7,DEFAULT_NODE_MASS:2e3,DEFAULT_NODE_RADIUS:50,DEFAULT_VISIBLE_EDGE_DISTANCE:350}),i=(t=[],i=[])=>{for(let i=0;i<t.length;i++){const r=t[i];if(r.index=i,r.radius=r.radius?r.radius:r.width?Math.max(r.width,r.height)/2:e.DEFAULT_NODE_RADIUS,r.mass=r.mass?r.mass:e.DEFAULT_NODE_MASS,r.fx&&(r.x=r.fx),r.fy&&(r.y=r.fy),isNaN(r.x)||isNaN(r.y)){const t=r.radius*Math.sqrt(.5+i),e=i*(Math.PI*(3-Math.sqrt(5)));r.x=t*Math.cos(e),r.y=t*Math.sin(e)}(isNaN(r.vx)||isNaN(r.vy))&&(r.vx=0,r.vy=0)}for(let r=0;r<i.length;r++){const n=i[r];if(n.index=r,n.strength||(n.strength=e.DEFAULT_EDGE_STRENGTH),n.source=t.find((t=>t.id===n.sourceNode)),n.target=t.find((t=>t.id===n.targetNode)),!n.source||!n.target)throw new Error(`Broken Edge ${n}`);if(!n.distance){const t=n.target.radius+n.source.radius;n.distance=t+(n.visibleDistance?n.visibleDistance:e.DEFAULT_VISIBLE_EDGE_DISTANCE)}n.visibleDistance||(n.visibleDistance=n.distance-n.target.radius-n.source.radius),isNaN(n.weight)&&(n.weight=1)}};class r{constructor(t,e=60){this.fn=t,this.timeout=null,this.running=!1,this.previousTimestamp=null,this.unprocessedTime=null,this.UPDATE_CAP=1e3/e}setUpdateCap(t){this.UPDATE_CAP=1e3/t}start(){this.running||(this.running=!0,this.previousTimestamp=null,this.unprocessedTime=null,this.run())}stop(){this.running=!1,this.previousTimestamp=null,this.unprocessedTime=null}run(){if(this.running){this.previousTimestamp||(this.previousTimestamp=Date.now()),this.unprocessedTime||(this.unprocessedTime=0),this.unprocessedTime>10*this.UPDATE_CAP&&(this.unprocessedTime=this.UPDATE_CAP);const t=Date.now(),e=t-this.previousTimestamp;this.previousTimestamp=t,this.unprocessedTime+=e,this.unprocessedTime>=this.UPDATE_CAP&&(this.unprocessedTime-=this.UPDATE_CAP,this.fn()),this.timeout=setTimeout((()=>{this.run()}),0)}}}class n{constructor(t=[]){this.isMassComputed=!1,this.isLargestRadiusComputed=!1,this.entities=[],this.quadrants=new Array(4),this.bounds={xStart:0,yStart:0,xEnd:1,yEnd:1},this.initialize(t)}initialize(t=[]){this.isMassComputed=!1,this.isLargestRadiusComputed=!1,this.entities=t,this.bounds=this.getBounds(),this.quadrants=new Array(4);for(let e=0;e<t.length;e++)this.addEntity(t[e])}update(){this.initialize(this.entities)}getBounds(){let t=0,e=0,i=1,r=1;for(let n=0;n<this.entities.length;n++){const o=this.entities[n];o.x-1<t&&(t=Math.floor(o.x-1)),o.x+1>i&&(i=Math.ceil(o.x+1)),o.y-1<e&&(e=Math.floor(o.y-1)),o.y+1>r&&(r=Math.ceil(o.y+1))}const n=i-t,o=r-e;if(n>o){const t=n-o;e-=t/2,r+=t/2}else if(o>n){const e=o-n;t-=e/2,i+=e/2}return{xStart:t,yStart:e,xEnd:i,yEnd:r}}addEntity(t){let e,i=this.quadrants;const r={entity:t,next:null};let n,o,s,a,h,u,l=this.bounds.xStart,c=this.bounds.yStart,d=this.bounds.xEnd,p=this.bounds.yEnd;for(;i.length;)if(n=(l+d)/2,o=(c+p)/2,s=t.x>=n,a=t.y>=o,s?l=n:d=n,a?c=o:p=o,e=i,h=a<<1|s,i=i[h],!i)return void(e[h]=r);const f=i.entity.x,_=i.entity.y;if(t.x===f&&t.y===_)return r.next=i,void(e[h]=r);let g,m,v=!0;for(;v;)e[h]=new Array(4),e=e[h],n=(l+d)/2,o=(c+p)/2,s=t.x>=n,a=t.y>=o,g=f>=n,m=_>=o,h=a<<1|s,u=m<<1|g,v=h===u,v&&(s?l=n:d=n,a?c=o:p=o);e[u]=i,e[h]=r}traverseTopBottom(t){const e=[];let i,r,n,o,s,a,h,u,l={quadNode:this.quadrants,xStart:this.bounds.xStart,xEnd:this.bounds.xEnd,yStart:this.bounds.yStart,yEnd:this.bounds.yEnd};for(;l;)i=l.quadNode,n=l.xStart,o=l.yStart,s=l.xEnd,a=l.yEnd,!t(i,n,o,s,a)&&i.length&&(h=(n+s)/2,u=(o+a)/2,(r=i[0])&&e.push({quadNode:r,xStart:n,yStart:o,xEnd:h,yEnd:u}),(r=i[1])&&e.push({quadNode:r,xStart:h,yStart:o,xEnd:s,yEnd:u}),(r=i[2])&&e.push({quadNode:r,xStart:n,yStart:u,xEnd:h,yEnd:a}),(r=i[3])&&e.push({quadNode:r,xStart:h,yStart:u,xEnd:s,yEnd:a})),l=e.pop()}traverseBottomTop(t){const e=[],i=[];let r,n,o,s,a,h,u,l,c={quadNode:this.quadrants,xStart:this.bounds.xStart,xEnd:this.bounds.xEnd,yStart:this.bounds.yStart,yEnd:this.bounds.yEnd};for(;c;)l=c.quadNode,l.length&&(n=c.xStart,o=c.yStart,s=c.xEnd,a=c.yEnd,h=(n+s)/2,u=(o+a)/2,(r=l[0])&&e.push({quadNode:r,xStart:n,yStart:o,xEnd:h,yEnd:u}),(r=l[1])&&e.push({quadNode:r,xStart:h,yStart:o,xEnd:s,yEnd:u}),(r=l[2])&&e.push({quadNode:r,xStart:n,yStart:u,xEnd:h,yEnd:a}),(r=l[3])&&e.push({quadNode:r,xStart:h,yStart:u,xEnd:s,yEnd:a})),i.push(c),c=e.pop();for(;c=i.pop();)t(c.quadNode,c.xStart,c.yStart,c.xEnd,c.yEnd)}computeMass(){this.isMassComputed||(this.traverseBottomTop((t=>{if(t.length){let e=0,i=0,r=0;for(let n=0;n<4;n++){const o=t[n];o&&(r+=o.mass,e+=o.mass*o.x,i+=o.mass*o.y)}t.x=e/r,t.y=i/r,t.mass=r}else{let e=0,i=t;do{e+=i.entity.mass}while(i=i.next);t.x=t.entity.x,t.y=t.entity.y,t.mass=e}})),this.isMassComputed=!0)}computeLargestRadius(t=0){this.isLargestRadiusComputed||(this.traverseBottomTop((e=>{if(e.entity)e.radius=e.entity.radius+t;else{e.radius=0;for(let t=0;t<4;t++)e[t]&&e[t].radius>e.radius&&(e.radius=e[t].radius)}})),this.isLargestRadiusComputed=!0)}}class o{constructor(t=[],e=[],i={}){this.nodes=t,this.edges=e,this.alpha=i.alpha||1,this.alphaMin=i.alphaMin||.001,this.alphaDecay=i.alphaDecay||1-Math.pow(this.alphaMin,1/300),this.alphaTarget=i.alphaTarget||0,this.velocityDecay=i.velocityDecay||.6,this.components=new Map,this.listeners=new Map([["layoutloopstart",new Set],["layoutupdate",new Set],["layoutloopend",new Set]]),this.loop=new r(this.runLoop.bind(this),i.updateCap?i.updateCap:60),this.initializeNodesAndEdges(),this.quadtree=new n(this.nodes),this.isAnimating=!1}on(t,e){this.listeners.has(t)||console.error(`No such event name: ${t}`),this.listeners.get(t).add(e)}triggerEvent(t){this.listeners.get(t).forEach((t=>t()))}runLoop(){this.update(),this.alpha<this.alphaMin&&(this.loop.stop(),this.triggerEvent("layoutloopend"))}updateNodesAndEdges(t,e){this.nodes=t,this.edges=e,this.initializeNodesAndEdges(),this.components.forEach((t=>this.initializeComponent(t)))}initializeNodesAndEdges(){i(this.nodes,this.edges),this.quadtree=new n(this.nodes)}initializeComponent(t){let e=this.nodes,i=this.edges;return t.nodeBindings&&(e=this.nodes.filter((e=>t.nodeBindings(e)))),t.edgeBindings&&(i=this.edges.filter((e=>t.edgeBindings(e)))),t.instance.initialize(e,i,{quadtree:this.quadtree,remove:()=>this.removeComponent(t.id)}),t}start(){this.triggerEvent("layoutloopstart"),this.loop.start()}stop(){this.loop.stop(),this.triggerEvent("layoutloopend")}setUpdateCap(t){this.loop.setUpdateCap(t)}addLayoutComponent(t,e,i=null,r=null){if(this.components.has(t))throw new Error("Component already exists: "+t);const n={id:t,instance:e,nodeBindings:i,edgeBindings:r};return this.initializeComponent(n),this.components.set(t,n),this}removeComponent(t){this.components.has(t)&&(this.components.get(t).instance.dismount(),this.components.delete(t))}findClosestNodeByCoordinates(t,e){let i,r=1/0;for(let n=0;n<this.nodes.length;++n){const o=this.nodes[n],s=t-o.x,a=e-o.y,h=s*s+a*a;h<r&&(i=o,r=h)}return i}animateState(t=[],e=300,i=!1){if(!t.length)return;this.nodeMap=this.nodes.reduce(((t,e)=>(t[e.id]=e,t)),{}),t.forEach((t=>{t.sourceX=isNaN(t.sourceX)?this.nodeMap[t.id].x:t.sourceX,t.sourceY=isNaN(t.sourceY)?this.nodeMap[t.id].y:t.sourceY}));const n=Date.now(),o=new r((()=>{const r=Date.now()-n,s=Math.min(r/e,100);t.forEach((t=>{const e=this.nodeMap[t.id];e.x=t.sourceX+(t.targetX-t.sourceX)*s,e.y=t.sourceY+(t.targetY-t.sourceY)*s})),r>e&&(o.stop(),this.isAnimating=!1,i&&t.forEach((t=>{const e=this.nodeMap[t.id];e.fx=e.x,e.fy=e.y}))),this.triggerEvent("layoutupdate")}),1/0);this.isAnimating=!0,o.start()}update(t=!0){if(!this.isAnimating){this.alpha+=(this.alphaTarget-this.alpha)*this.alphaDecay;for(const[,t]of this.components.entries())t.instance.execute(this.alpha);for(let t=0;t<this.nodes.length;t++){const e=this.nodes[t];null==e.fx?(e.vx*=this.velocityDecay,e.x+=e.vx):(e.x=e.fx,e.vx=0),null==e.fy?(e.vy*=this.velocityDecay,e.y+=e.vy):(e.y=e.fy,e.vy=0)}this.iteration=this.iteration?this.iteration+1:1,this.quadtree.update(),t&&this.triggerEvent("layoutupdate")}}}class s{constructor(t=[],e=[]){this.allNodes=[],this.allEdges=[],this.onlineNodes=new Set,this.nodeLookupMap=new Map,this.sourceToTargetMap=new Map,this.targetToSourceMap=new Map,this.nodeToNeighborsMap=new Map,this.edgeIndexes=new Map,this.offlineEdgeCounter=new Map,this.updateNodesAndEdges(t,e)}updateNodesAndEdges(t,e){t.forEach((t=>{!this.nodeLookupMap.has(t.id)&&this.onlineNodes.add(t.id)})),this.nodeLookupMap=new Map(t.map((t=>[t.id,t]))),this.allNodes.forEach((t=>{!this.nodeLookupMap.has(t)&&this.onlineNodes.delete(t)})),this.allNodes=t.map((t=>t.id)),this.allEdges=[...e];const i=new Map(this.allNodes.map((t=>[t,new Map]))),r=new Map(this.allNodes.map((t=>[t,new Map]))),n=new Map(this.allNodes.map((t=>[t,new Map]))),o=(t,e,i,r)=>{t.get(e).has(i)||t.get(e).set(i,{id:i,edges:[],weight:0});const n=t.get(e).get(i);n.edges.push(r),n.weight+=r.weight?r.weight:1};this.allEdges.forEach((t=>{o(i,t.sourceNode,t.targetNode,t),o(r,t.targetNode,t.sourceNode,t),o(n,t.sourceNode,t.targetNode,t),t.sourceNode!==t.targetNode&&o(n,t.targetNode,t.sourceNode,t)})),this.sourceToTargetMap=new Map(this.allNodes.map((t=>[t,[]]))),this.targetToSourceMap=new Map(this.allNodes.map((t=>[t,[]]))),this.nodeToNeighborsMap=new Map(this.allNodes.map((t=>[t,[]])));const s=(t,e)=>{for(const[i,r]of e)t.set(i,Array.from(r.values()))};s(this.sourceToTargetMap,i),s(this.targetToSourceMap,r),s(this.nodeToNeighborsMap,n),this.updateMetaData()}updateMetaData(){this.edgeIndexes=new Map;const t=new Map;let e;const i=this.getOnlineEdges();for(let r=0;r<i.length;r++){e=i[r];const n=e.sourceNode>e.targetNode?`${e.sourceNode}${e.targetNode}`:`${e.targetNode}${e.sourceNode}`;t.has(n)?t.get(n).push(e):t.set(n,[e])}for(const[,i]of t)for(let t=0;t<i.length;t++)e=i[t],this.edgeIndexes.set(e,{total:i.length,index:t});this.offlineEdgeCounter=new Map(this.allNodes.map((t=>[t,{sourceNode:0,targetNode:0,internal:0}])));const r=this.getOfflineEdges();for(let t=0;t<r.length;t++)e=r[t],e.sourceNode===e.targetNode?this.offlineEdgeCounter.get(e.sourceNode).internal++:(this.offlineEdgeCounter.get(e.sourceNode).sourceNode++,this.offlineEdgeCounter.get(e.targetNode).targetNode++)}getOnlineNodes(){return this.allNodes.filter((t=>this.onlineNodes.has(t))).map((t=>this.nodeLookupMap.get(t)))}getOfflineNodes(){return this.allNodes.filter((t=>!this.onlineNodes.has(t))).map((t=>this.nodeLookupMap.get(t)))}getOnlineEdges(){return this.allEdges.filter((t=>this.isEdgeOnline(t)))}getOfflineEdges(){return this.allEdges.filter((t=>!this.isEdgeOnline(t)))}isEdgeOnline(t){return this.onlineNodes.has(t.sourceNode)&&this.onlineNodes.has(t.targetNode)}isNodeOnline(t){return this.onlineNodes.has(t)}bringNodesOffline(t){t.forEach((t=>{this.onlineNodes.delete(t)})),this.updateMetaData()}bringNodesOnline(t){t.forEach((t=>{if(!this.nodeLookupMap.has(t))throw new Error(`No such node exists: ${t}`);this.onlineNodes.add(t)})),this.updateMetaData()}bringAllNodesOffline(){this.onlineNodes=new Set,this.updateMetaData()}bringAllNodesOnline(){this.onlineNodes=new Set(this.allNodes),this.updateMetaData()}getNeighbors(t,e=!1,i=!0,r=!0){let n;return n=e?this.sourceToTargetMap.get(t).map((t=>t.id)):this.nodeToNeighborsMap.get(t).map((t=>t.id)),i&&(n=n.filter((t=>this.onlineNodes.has(t)))),r&&(n=n.filter((e=>e!==t))),Array.from(new Set(n))}computeImplodeOrExplodeNode(t,e=!1,i=!0,r="single"){if(!this.nodeLookupMap.has(t))throw new Error(`No such node exists: ${t}`);if(!this.onlineNodes.has(t))throw new Error(`Input node is offline: ${t}`);const n=new Map,o=t=>{if(n.has(t))return n.get(t);const r=this.getNeighbors(t,i,!e,!0);return n.set(t,r),r},s=[],a=new Set,h=new Map([[t,0]]);let u,l=[t];for(;u=l.pop();){if(a.has(u))continue;if(a.add(u),"single"===r&&h.get(u)>1)continue;u!==t&&s.push(u);const e=o(u);for(let t=0;t<e.length;t++){const i=e[t];h.has(i)||h.set(i,h.get(u)+1)}if("leafs"===r)for(let t=0;t<e.length;t++){const i=e[t];0===o(i).filter((t=>t!==u)).length&&l.push(i)}else l=l.concat(e)}return s.filter((t=>e&&!this.onlineNodes.has(t)||!e&&this.onlineNodes.has(t)))}stageNodePositions(t=[],e=300,i=0,r=0){if(!t.length)return[];const n=[],o=t.filter((t=>this.getNeighbors(t,!1,!0,!0).length<2)).length;return t.map((t=>{const s=this.getNeighbors(t,!1,!0,!0);if(s.length<2){n.push(t);const s=n.length,a=o,h=Math.floor(359/a*s);return{id:t,x:i+1+e*Math.cos(h*Math.PI/180),y:r+1+e*Math.sin(h*Math.PI/180)}}{let e=0,i=0;for(let t=0;t<s.length;t++){const r=this.nodeLookupMap.get(s[t]);e+=r.x,i+=r.y}return e/=s.length,i/=s.length,{id:t,x:e,y:i}}}))}findShortestPathUnweighted(t,e,i=!0,r=!0){if(i&&(!this.onlineNodes.has(t)||!this.onlineNodes.has(e)))throw new Error("Start node or end node is not live.");if(t===e)return[t];const n=[t],o=new Map;let s;for(;(s=n.pop())&&s!==e;){const t=this.getNeighbors(s,r,i);let e;for(let r=0;r<t.length;r++)e=t[r],i&&!this.onlineNodes.has(e)||o.has(e)||(o.set(e,s),n.push(e))}if(s!==e)return null;let a=s;const h=[a];for(;a=o.get(a);)h.push(a);return h.reverse()}findShortestPathWeighted(t,e,i=!0,r=!0,n=!1){if(i&&(!this.onlineNodes.has(t)||!this.onlineNodes.has(e)))throw new Error("Start node or end node is not live.");if(t===e)return[{id:t,cost:0}];const o=t=>{let e=r?this.sourceToTargetMap.get(t):this.nodeToNeighborsMap.get(t);return i&&(e=e.filter((t=>this.onlineNodes.has(t.id)))),e=e.filter((e=>e.id!==t)),n||(e=e.map((t=>{const e=t.edges.reduce(((t,e)=>(e.weight?e.weight:1)<t.weight?e:t),{id:null,edges:[],weight:1/0});return{id:t.id,edges:[e],weight:e.weight?e.weight:1}}))),e},s=new Map,a=new Map([[t,0]]),h=[t],u=new Set;let l=null,c=null;for(;c=h.pop();){if(u.has(c))continue;u.add(c);const t=a.get(c),i=o(c);for(let r=0;r<i.length;r++){const n=i[r],o=a.has(n.id)?a.get(n.id):1/0,d=t+n.weight;l&&d>l||(d<o&&(a.set(n.id,d),s.set(n.id,c)),n.id!==e?u.has(n.id)||h.push(n.id):l=a.get(e))}}if(null===l)return null;let d=e;const p=[{id:e,weight:l}];for(;d=s.get(d);)p.push({id:d,weight:a.get(d)});return p.reverse()}computeStronglyConnectedComponents(t=!0){const e=t?Array.from(this.onlineNodes):[...this.allNodes],i=[],r=new Set,n=new Map,o=new Map;let s=0;const a=e=>{if(r.has(e))return;r.add(e);const o=this.getNeighbors(e,!0,t,!0);for(let t=0;t<o.length;t++){const i=o[t];n.has(i)||n.set(i,[]),n.get(i).push(e),a(i)}i.push(e)},h=t=>{if(r.add(t),o.has(s)||o.set(s,[]),o.get(s).push(t),n.has(t)){const e=n.get(t);for(let t=0;t<e.length;t++){const i=e[t];r.has(i)||h(i)}}};for(let t=0;t<e.length;t++){const i=e[t];a(i)}for(r.clear();i.length;){const t=i.pop();r.has(t)||(h(t),s++)}return Array.from(o.values())}BFS(t,e,i=!0,r=!0){if(!this.nodeLookupMap.has(t))throw new Error(`No such node exists: ${t}`);if(i&&!this.onlineNodes.has(t))throw new Error(`Input node is offline: ${t}`);const n=new Set;let o=[t],s=[],a=null;do{for(s=o.reverse(),o=[];a=s.pop();){if(n.has(a))continue;if(n.add(a),e(a))continue;let t;t=r?this.sourceToTargetMap.get(a).map((t=>t.id)):this.nodeToNeighborsMap.get(a).map((t=>t.id)),o=o.concat(i?t.filter((t=>this.onlineNodes.has(t))):t)}}while(o.length)}DFS(t,e,i=!0,r=!0){if(!this.nodeLookupMap.has(t))throw new Error(`No such node exists: ${t}`);if(i&&!this.onlineNodes.has(t))throw new Error(`Input node is offline: ${t}`);const n=new Set;let o=[],s=t;do{if(n.has(s))continue;if(n.add(s),e(s))continue;let t;t=r?this.sourceToTargetMap.get(s).map((t=>t.id)):this.nodeToNeighborsMap.get(s).map((t=>t.id)),o=o.concat(i?t.filter((t=>this.onlineNodes.has(t))).reverse():t.reverse())}while(s=o.pop())}}const a=4294967296;class h{constructor(){this.nodes=[],this.edges=[],this.random=function(){let t=1;return()=>(t=(1664525*t+1013904223)%a)/a}(),this.utils={quadtree:new n,remove:()=>{}}}randomize(){return 1e-6*(this.random()-.5)}getCenterCoordinates(){let t,e=1/0,i=-1/0,r=1/0,n=-1/0;for(let o=0;o<this.nodes.length;o++)t=this.nodes[o],t.x<e&&(e=t.x),t.y<r&&(r=t.y),t.x>i&&(i=t.x),t.y>n&&(n=t.y);return[(i-e)/2,(n-r)/2]}getAverageCoordinates(){return[this.nodes.reduce(((t,e)=>t+e.x),0)/this.nodes.length,this.nodes.reduce(((t,e)=>t+e.y),0)/this.nodes.length]}initialize(t,e,i){this.nodes=t,this.edges=e,this.utils=i}dismount(){}execute(){}}const u=(t,e)=>{const i=new Map(t.map((t=>[t.id,e.filter((e=>e.targetNode===t.id))]))),r=new Map(t.map((t=>[t.id,e.filter((e=>e.sourceNode===t.id))]))),n=t.filter((t=>!i.get(t.id).length&&r.get(t.id).length)),o=t.filter((t=>!i.get(t.id).length&&!r.get(t.id).length)),s=new Map([...o.map((t=>[t.id,0])),...n.map((t=>[t.id,1]))]),a=t=>{if(!s.has(t)){const e=Math.max(...i.get(t).map((t=>a(t.sourceNode))));s.set(t,e+1)}return s.get(t)},h=new Map;for(let e=0;e<t.length;e++){const i=a(t[e].id);h.has(i)||h.set(i,[]),h.get(i).push(t[e])}const u=Array.from(h.keys()).sort(((t,e)=>t-e)).map((t=>h.get(t))),l=u.map((()=>[])),c=[],d=new Set;for(let e=0;e<t.length;e++){const r=t[e].id,n=a(r),o=i.get(r).map((t=>t.sourceNode));for(let t=0;t<o.length;t++){const e=o[t],i=a(e);if(n-i>1){let t=e;for(let e=i+1;e<n;e++){const i="__FAKE_NODE__"+e+r+t;if(!d.has(i)){d.add(i);const t={id:i};l[e-1].push(t)}c.push({sourceNode:t,targetNode:i}),t=i}c.push({sourceNode:t,targetNode:r})}}}return{hierarchy:u,fakeNodesHierarchy:l,fakeEdges:c}};var l=(t,e)=>{const i=new Set,r=new Map,n=(t,o)=>{if(i.has(t))return;let s;i.add(t),o?(s=o,r.get(s).push(t)):(s=t,r.set(t,[t])),e.filter((e=>e.sourceNode!==e.targetNode&&(e.sourceNode===t||e.targetNode===t))).reduce(((t,e)=>(t.push(e.targetNode),t.push(e.sourceNode),t)),[]).forEach((t=>{n(t,s)}))};return t.forEach((t=>{n(t.id)})),[...r.values()].map((e=>e.map((e=>t.find((t=>t.id===e))))))};const c=(t,e)=>{let i=t.reduce(((t,e)=>(t.push([...e]),t)),[]);if(1===i.length)return i;const r=new Map,n=new Map;i.forEach(((t,e)=>{t.forEach(((t,i)=>{r.set(t.id,e),n.set(t.id,i)}))}));const o=e.filter((t=>r.get(t.sourceNode)===r.get(t.targetNode)-1)),s=t=>n.get(t),a=(t,e)=>{let i=t,r=0;for(;;){const t=e.map((t=>t.sum[i]>0?t.sum[i]:0)),n=t.indexOf(Math.max(...t));if(0===t[n])break;if(i=n,r++,r>9999)break}return i},h=(t,e=!1)=>(t.forEach(((i,r)=>{const h=new Map(i.map((t=>[t.id,[]])));o.forEach((t=>{!e&&h.has(t.targetNode)?h.get(t.targetNode).push(s(t.sourceNode)):e&&h.has(t.sourceNode)&&h.get(t.sourceNode).push(s(t.targetNode))}));const u=i.map((t=>{const e=h.get(t.id);return{node:t,sum:i.map((i=>{if(i.id===t.id)return 0;const r=h.get(i.id);let n=0,o=0;return e.forEach((t=>{r.forEach((e=>{t<e&&o++,t>e&&n++}))})),o-n}))}})),l=[],c=u.length;for(let t=0;t<c;t++){const t=u.map((t=>t.sum.reduce(((t,e)=>t+e),0))),e=a(t.indexOf(Math.max(...t)),u);l.push(u[e].node),u.forEach((t=>{t.sum.splice(e,1)})),u.splice(e,1)}(t=>{t.forEach(((t,e)=>{n.set(t.id,e)}))})(l),t[r]=l})),t);for(let t=0;t<1;t++)i=h(h(i).reverse(),!0).reverse();return i=h(i),i},d=(t,e)=>{const i=[...t],r=e.filter((t=>t.targetNode!==t.sourceNode)),n=new Map(i.map((t=>[t.id,0]))),o=new Map(i.map((t=>[t.id,0])));r.forEach((t=>{n.set(t.targetNode,n.get(t.targetNode)+1),o.set(t.sourceNode,o.get(t.sourceNode)+1)}));const s=[],a=[],h=(t=!1)=>{for(;;){let e=!1;for(let h=0;h<i.length;h++){const u=i[h];if(!t&&!o.get(u.id)&&n.get(u.id)||t&&o.get(u.id)&&!n.get(u.id)){e=!0,s.push(i.splice(h,1)[0]),h--;for(let e=0;e<r.length;e++){const i=r[e];(!t&&i.targetNode===u.id||t&&i.sourceNode===u.id)&&(o.set(i.sourceNode,o.get(i.sourceNode)-1),n.set(i.targetNode,n.get(i.targetNode)-1),a.push(r.splice(e,1)[0]),e--)}}}if(!e)break}};for(;i.length;){h(!1);for(let t=0;t<i.length;t++){const e=i[t];n.get(e.id)||o.get(e.id)||(i.splice(t,1),s.push(e),t--)}if(h(!0),i.length){const t=i.reduce(((t,e,i)=>{const r=o.get(e.id)-n.get(e.id);return r>t[1]&&(t=[e,r,i]),t}),[null,0,-1]);null===t[0]&&(t[0]=i[0],t[2]=0);for(let e=0;e<r.length;e++){const h=r[e];h.sourceNode===t[0].id&&(n.set(h.targetNode,n.get(h.targetNode)-1),a.push(h),r.splice(e,1),e--),h.targetNode===t[0].id&&(o.set(h.sourceNode,o.get(h.sourceNode)-1),r.splice(e,1),e--),s.push(i.splice(t[2],1)[0])}}}return a},p=(t,e)=>{const i=t.reduce(((t,e)=>(t.push([...e]),t)),[]),r=new Map;i.forEach(((t,e)=>{t.forEach((t=>{r.set(t.id,e)}))}));const n=new Map,o=t=>{i[t].forEach(((t,e)=>{null!==t&&n.set(t.id,e)}))},s=e.filter((t=>r.get(t.sourceNode)===r.get(t.targetNode)-1)),a=new Map,h=Math.max(...i.map((t=>t.length)));i.forEach(((t,e)=>{if(a.set(e,t.length),t.length<h){let e=!1;for(let i=t.length;i<h;i++)e?t.push(null):t.unshift(null),e=!e}}));const u=(t,e)=>{const i=new Map;return t.forEach((t=>{if(null===t)return;const r=e?"sourceNode":"targetNode",o=e?"targetNode":"sourceNode";let a=[0,0];s.forEach((e=>{var i;e[r]===t.id&&(a[0]+=(i=e[o],n.get(i)),a[1]+=1)})),a=Math.floor(a[0]/a[1]),i.set(t.id,isNaN(a)?0:a)})),i};return i.forEach(((t,e)=>{if(a.get(e)===h)return;if(1===i.length)return;let r;r=0===e||e!==i.length-1&&a.get(e)>a.get(e-1),o(e),o(r?e+1:e-1);const n=u(t,r);let s=!0;for(;!0===s;){s=!1;for(let e=0;e<t.length;e++){const i=t[e];if(null===i)continue;const r=n.get(i.id),o=0!==e&&null===t[e-1],a=e!==t.length-1&&null===t[e+1];r>e&&a?(t[e+1]=i,t[e]=null,e-2>-1&&(e-=2),s=!0):r<e&&o&&(t[e-1]=i,t[e]=null,e--,s=!0)}}})),i.map((t=>t.map((t=>t&&!`${t.id}`.toUpperCase().includes("FAKE")?t:null))))};var f=Object.freeze({__proto__:null,Animation:class extends h{constructor(t=0,e=0,i=1,r=!0){super(),this.xDestination=t,this.yDestination=e,this.strength=i,this.removeForceOnDestination=r}initialize(...t){super.initialize(...t)}execute(t){let e,i,r,n=0;for(let o=0;o<this.nodes.length;o++){e=this.nodes[o],i=e.targetX?e.targetX:this.xDestination,r=e.targetY?e.targetY:this.yDestination,!e.fx&&(e.fx=e.x),!e.fy&&(e.fy=e.y);const s=(i-e.x)*this.strength*t/2,a=(r-e.y)*this.strength*t/2;s>1?e.fx+=s:e.fx=i,a>1?e.fy+=a:e.fy=r,e.fx===i&&e.fy===r&&n++}if(this.removeForceOnDestination&&n===this.nodes.length){for(let t=0;t<this.nodes.length;t++)e=this.nodes[t],e.x=e.fx,e.y=e.fy,e.vx=0,e.vy=0,e.fx=void 0,e.fy=void 0;this.utils.remove()}}},Attraction:class extends h{constructor(t=!0,e=0,i=.05){super(),this.isHorizontal=t,this.coordinate=e,this.strength=i}initialize(...t){super.initialize(...t)}execute(t){let e;for(let i=0;i<this.nodes.length;i++)e=this.nodes[i],e[this.isHorizontal?"vx":"vy"]+=(this.coordinate-e[this.isHorizontal?"x":"y"])*this.strength*t}},BoundingBox:class extends h{constructor(t=null,e=null){super(),this.width=t,this.height=e,this.computedWidth=t,this.computedHeight=e,this.multiplier=5}getWidth(t){return t.width?t.width:2*t.radius}getHeight(t){return t.height?t.height:2*t.radius}initialize(...t){if(super.initialize(...t),this.width&&this.height)this.computedWidth=this.width,this.computedHeight=this.height;else{let t,e=0;for(let i=0;i<this.nodes.length;i++)t=this.nodes[i],e+=Math.max(e,this.getWidth(t)*this.multiplier,this.getHeight(t)*this.multiplier);this.width||this.height?this.width?this.height||(this.computedHeight=e-this.width>0?e-this.width:100):this.computedWidth=e-this.height>0?e-this.height:100:(this.computedWidth=e/2,this.computedHeight=e/2)}this.computedWidth=this.computedWidth/2,this.computedHeight=this.computedHeight/2}execute(){let t;for(let e=0;e<this.nodes.length;e++)t=this.nodes[e],t.x<-this.computedWidth?t.x=-this.computedWidth:t.x>this.computedWidth&&(t.x=this.computedWidth),t.y<-this.computedHeight?t.y=-this.computedHeight:t.y>this.computedHeight&&(t.y=this.computedHeight)}},Center:class extends h{constructor(t=0,e=0,i=1){super(),this.x=t,this.y=e,this.strength=i}initialize(...t){super.initialize(...t)}execute(){let t=0,e=0;for(let i=0;i<this.nodes.length;i++){const r=this.nodes[i];t+=r.x,e+=r.y}const i=(t/this.nodes.length-this.x)*this.strength,r=(e/this.nodes.length-this.y)*this.strength;for(let t=0;t<this.nodes.length;t++){const e=this.nodes[t];e.x-=i,e.y-=r}}},Cluster:class extends h{constructor(t=.7){super(),this.strength=t}initialize(...t){super.initialize(...t)}execute(t){let e,i=0,r=0,n=0;for(let t=0;t<this.nodes.length;t++){e=this.nodes[t];const o=e.mass**2;i+=e.x*o,r+=e.y*o,n+=o}const o=i/n,s=r/n,a=t*this.strength;for(let t=0;t<this.nodes.length;t++)e=this.nodes[t],e.vx-=(e.x-o)*a,e.vy-=(e.y-s)*a}},Collision:class extends h{constructor(t=1,e=5){super(),this.strength=t,this.radiusPadding=e}initialize(...t){super.initialize(...t)}execute(){let t,e;this.utils.quadtree.computeLargestRadius(this.radiusPadding);for(let i=0;i<this.nodes.length;i++)t=this.nodes[i],e=t.radius+this.radiusPadding,this.utils.quadtree.traverseTopBottom(((i,r,n,o,s)=>{const a=i.entity,h=i.radius+this.radiusPadding,u=e+h;if(!a)return r>t.x+u||o<t.x-u||n>t.y+u||s<t.y-u;{if(a.index>=t.index)return;let i=t.x-a.x,r=t.y-a.y,n=i*i+r*r;if(n<u*u){0===i&&(i=this.randomize(),n+=i*i),0===r&&(r=this.randomize(),n+=r*r);const o=Math.sqrt(n),s=(u-o)/o*this.strength,l=i*s,c=r*s,d=h*h,p=d/(e*e+d);t.vx+=l*p,t.vy+=c*p;const f=1-p;a.vx-=l*f,a.vy-=c*f}}}))}},D3Adapter:class extends h{constructor(t){super(),this.d3force=t}initialize(t,e,i){super.initialize(t,e,i),this.d3force.links&&"function"==typeof this.d3force.links&&this.d3force.links(e),this.d3force.initialize&&this.d3force.initialize(t,this.random)}execute(t){this.d3force(t)}},Fan:class extends h{constructor(t=(t=>t.type),e=.9,i=300,r=null,n=null){super(),this.computeGroup=t,this.strength=e,this.positionMap=new Map,this.centerX=r,this.centerY=n,this.space=i}initialize(...t){super.initialize(...t);const e=this.getAverageCoordinates();null===this.centerX&&(this.centerX=e[0]),null===this.centerY&&(this.centerY=e[1]),this.positionMap.clear();const i=new Map;this.nodes.forEach((t=>{const e=this.computeGroup(t);i.has(e)?i.get(e).push(t):i.set(e,[t])}));const r=Math.floor(360/i.size);Array.from(i.keys()).forEach(((t,e)=>{const n=(t=>{(t%=360)<0&&(t+=360);let e=2*Math.PI*t/360;return e<0&&(e+=2*Math.PI),e})(r*e),o=Math.cos(n),s=Math.sin(n);let a=[this.centerX+this.space*o,this.centerY+this.space*s];i.get(t).forEach((t=>{const e=2*t.radius,i=e*o+a[0],r=e*s+a[1];this.positionMap.set(t.id,[i,r]);a=[e*o+i,e*s+r]}))}))}execute(){let t;for(let e=0;e<this.nodes.length;e++){t=this.nodes[e];const i=this.positionMap.get(t.id);t.fx=i[0],t.fy=i[1]}}dismount(){this.nodes.forEach((t=>{delete t.fx,delete t.fy}))}},LayoutComponent:h,Grid:class extends h{constructor(t=!0,e=!0,i=.6,r,n=3){super(),this.useX=t,this.useY=e,this.strength=i,this.size=r,this.offsetMultiplier=n,this.maxSizeX=0,this.maxSizeY=0}getWidth(t){return t.width?t.width:2*t.radius}getHeight(t){return t.height?t.height:2*t.radius}initialize(...t){if(super.initialize(...t),this.size)return;let e;this.maxSizeX=0,this.maxSizeY=0;for(let t=0;t<this.nodes.length;t++)e=this.nodes[t],this.maxSizeX=Math.max(this.maxSizeX,this.getWidth(e)*this.offsetMultiplier),this.maxSizeY=Math.max(this.maxSizeY,this.getHeight(e)*this.offsetMultiplier);if(this.useY&&this.useX){const t=Math.max(this.maxSizeX,this.maxSizeY);this.maxSizeX=t,this.maxSizeY=t}}execute(t){const e=t*this.strength;for(let t=0;t<this.nodes.length;t++){const i=this.nodes[t];if(this.useY){const t=Math.round(i.y/this.maxSizeY)*this.maxSizeY;i.vy-=(i.y-t)*e}if(this.useX){const t=Math.round(i.x/this.maxSizeX)*this.maxSizeX;i.vx-=(i.x-t)*e}}}},Hierarchy:class extends h{constructor(t=null,e=!0,i,r=!0,n=null,o=null){super(),this.computeGroup=t,this.useY=e,this.distance=i,this.useLine=r,this.centerX=n,this.centerY=o,this.groups=[],this.offsetDistance=0,this.halfSize=0,this.halfWidth=0,this.orderMeasurement=0,this.offsetSizeMultiplier=4}getWidth(t){return t.width?t.width:2*t.radius}getHeight(t){return t.height?t.height:2*t.radius}initialize(...t){super.initialize(...t);const e=this.useY?this.getHeight:this.getWidth,i=this.useY?this.getWidth:this.getHeight;this.orderMeasurement=0;let r=this.distance?this.distance:0;if(this.nodes.forEach((t=>{this.distance||(r=Math.max(r,e(t))),this.orderMeasurement=Math.max(this.orderMeasurement,i(t))})),this.offsetDistance=r*this.offsetSizeMultiplier,this.offsetDistance<250&&(this.offsetDistance=250),this.orderMeasurement*=1.5,this.computeGroup){const t={};if(this.nodes.forEach((e=>{let i=this.computeGroup(e);null==i&&(i=0),t[i]?t[i].push(e):t[i]=[e]})),this.groups=Object.keys(t).sort(((t,e)=>{const i=parseInt(t),r=parseInt(e),n=isNaN(i)?t:i,o=isNaN(r)?t:r;return n<o?-1:n>o?1:0})).map((e=>t[e])),this.useLine){const t=d(this.nodes,this.edges);this.groups=c(this.groups,t),this.groups=p(this.groups,t)}}else{let t=l(this.nodes,this.edges).map((t=>{const e=d(t,this.edges),{hierarchy:i,fakeNodesHierarchy:r,fakeEdges:n}=u(t,e);if(this.useLine){const t=i.map(((t,e)=>[...t,...r[e]])),o=[...e,...n];let s=c(t,o);return s=p(s,[...e,...n]),s}return i}));if(this.useLine){const e=t.reduce(((t,e)=>Math.max(t,e.length)),0);t.forEach((t=>{const i=Math.max(...t.map((t=>t.length)));if(t.length<e)for(let r=t.length;r<e;r++)t.push(new Array(i).fill(null))}))}t=t.reduce(((t,e)=>(e.forEach(((e,i)=>{t[i]?t[i]=[...t[i],...e]:t[i]=e})),t)),[]),this.groups=t,this.halfSize=(this.groups.length-1)*this.offsetDistance/2,this.halfWidth=Math.max(...t.map((t=>t.length)))*this.orderMeasurement/2;const e=this.getAverageCoordinates();null===this.centerX&&(this.centerX=e[0]),null===this.centerY&&(this.centerY=e[1])}}execute(){const t=this.useY?"y":"x",e=this.useY?"x":"y",i=this.useY?this.centerY:this.centerX,r=this.useY?this.centerX:this.centerY;let n,o;for(let s=0;s<this.groups.length;s++){n=this.groups[s];const a=s*this.offsetDistance-this.halfSize;for(let s=0;s<n.length;s++)o=n[s],o&&(o["f"+t]=a+i,this.useLine&&(o["f"+e]=s*this.orderMeasurement-this.halfWidth+r))}}dismount(){this.nodes.forEach((t=>{delete t.fx,delete t.fy}))}},Link:class extends h{constructor(){super(),this.count=[],this.bias=[]}initialize(...t){super.initialize(...t),this.count=new Array(this.edges.length),this.bias=new Array(this.edges.length);for(let t=0;t<this.edges.length;t++){const e=this.edges[t];this.count[e.source.index]=(this.count[e.source.index]||0)+1,this.count[e.target.index]=(this.count[e.target.index]||0)+1}for(let t=0;t<this.edges.length;t++){const e=this.edges[t];this.bias[t]=this.count[e.source.index]/(this.count[e.source.index]+this.count[e.target.index])}}execute(t){let e,i,r,n,o,s,a,h;for(let u=0;u<this.edges.length;u++)h=this.edges[u],e=h.target.x+h.target.vx-h.source.x-h.source.vx||this.randomize(),i=h.target.y+h.target.vy-h.source.y-h.source.vy||this.randomize(),r=Math.sqrt(e*e+i*i),n=(r-h.distance)/r*t*h.strength,o=e*n,s=i*n,a=this.bias[u],h.target.vx-=o*a,h.target.vy-=s*a,a=1-a,h.source.vx+=o*a,h.source.vy+=s*a}},Matrix:class extends h{constructor(t=null,e=null){super(),this.centerX=t,this.centerY=e,this.maxSize=0,this.numberOfRowsAndColumns=0,this.halfSize=0,this.multiplier=2}getWidth(t){return t.width?t.width:2*t.radius}getHeight(t){return t.height?t.height:2*t.radius}initialize(...t){let e;super.initialize(...t),this.nodes=((t,e)=>{const i=new Map;return t.forEach((t=>i.set(t.id,[]))),e.forEach((e=>{e.sourceNode!==e.targetNode&&(i.get(e.sourceNode).push(t.findIndex((t=>t.id===e.targetNode))),i.get(e.targetNode).push(t.findIndex((t=>t.id===e.sourceNode))))})),l(t,e).map((t=>{const e=t.map(((t,e)=>({average:0,index:e}))),r=t=>e.findIndex((e=>e.index===t));for(let n=0;n<t.length+1;n++)t.forEach(((t,n)=>{const o=r(n);let s=o;i.get(t.id).forEach((t=>{const e=r(t);s+=e})),e[o].average=s/i.get(t.id).length+1})),e.sort(((t,e)=>t.average-e.average));return e.map((e=>t[e.index]))})).flat()})(this.nodes,this.edges),this.maxSize=0;for(let t=0;t<this.nodes.length;t++)e=this.nodes[t],this.maxSize=Math.max(this.maxSize,this.getWidth(e)*this.multiplier,this.getHeight(e)*this.multiplier);this.numberOfRowsAndColumns=Math.ceil(Math.sqrt(this.nodes.length)),this.halfSize=(this.numberOfRowsAndColumns-1)*this.maxSize/2;const i=this.getAverageCoordinates();null===this.centerX&&(this.centerX=i[0]),null===this.centerY&&(this.centerY=i[1])}execute(){let t=0,e=0;for(let i=0;i<this.nodes.length;i++){e===this.numberOfRowsAndColumns&&(e=0,t+=1),e+=1;const r=this.nodes[i];r.fx=(e-1)*this.maxSize-this.halfSize+this.centerX+r.radius,r.fy=t*this.maxSize-this.halfSize+this.centerY+r.radius}}dismount(){this.nodes.forEach((t=>{delete t.fx,delete t.fy}))}},NBody:class extends h{constructor(t=1.1,e=1/0,i=1,r=!0){super(),this.theta=t,this.distanceMax=e,this.distanceMin=i,this.isRepulse=r}initialize(...t){super.initialize(...t)}execute(t){let e;this.utils.quadtree.computeMass();for(let i=0;i<this.nodes.length;i++)e=this.nodes[i],this.utils.quadtree.traverseTopBottom(((i,r,n,o)=>{if(!i.mass)return!0;let s=i.x-e.x,a=i.y-e.y;const h=o-r;let u=s*s+a*a;if(h*h/this.theta<u){if(u<this.distanceMax){0===s&&(s=this.randomize(),u+=s*s),0===a&&(a=this.randomize(),u+=a*a),u<this.distanceMin&&(u=Math.sqrt(this.distanceMin*u));const r=(this.isRepulse?-i.mass*t:i.mass*t)/u;e.vx+=s*r,e.vy+=a*r}return!0}if(i.length||u>=this.distanceMax)return!1;if(i.entity!==e||i.next){0===s&&(s=this.randomize(),u+=s*s),0===a&&(a=this.randomize(),u+=a*a),u<this.distanceMin&&(u=Math.sqrt(this.distanceMin*u));do{if(i.entity!==e){const r=(this.isRepulse?-i.mass*t:i.mass*t)/u;e.vx+=s*r,e.vy+=a*r}}while(i=i.next)}}))}},Radial:class extends h{constructor(t=.9,e=null,i=null,r=1.2,n=null){super(),this.strength=t,this.centerX=e,this.centerY=i,this.sizeMultiplier=r,this.userProvidedDiameter=n,this.diameter=0}initialize(...t){super.initialize(...t),this.diameter=this.userProvidedDiameter?this.userProvidedDiameter:this.nodes.reduce(((t,e)=>t+2*e.radius),0)/3.14*this.sizeMultiplier;const e=this.getAverageCoordinates();null===this.centerX&&(this.centerX=e[0]),null===this.centerY&&(this.centerY=e[1])}execute(t){for(let e=0;e<this.nodes.length;e++){const i=this.nodes[e],r=i.x-this.centerX||1e-6,n=i.y-this.centerY||1e-6,o=Math.sqrt(r*r+n*n),s=(this.diameter-o)*this.strength*t/o;i.vx+=r*s,i.vy+=n*s}}},Tree:class extends h{constructor(t=!0,e=100,i=null,r=null){super(),this.isVerticalLayout=t,this.PADDING_PX=e,this.centerX=i,this.centerY=r,this.nodePositions=new Map}getWidth(t){return t.width?t.width:2*t.radius}getHeight(t){return t.height?t.height:2*t.radius}initialize(...t){super.initialize(...t);const e=d(this.nodes,this.edges),{hierarchy:i}=u([...this.nodes,{id:"FAKE__ISLAND"}],e);i[0]=i[0].filter((t=>"FAKE__ISLAND"!==t.id)),i[0].length?i[0]=[...i[0],...i.splice(1,1)[0]]:i.splice(0,1);let r=0;const n=i.map((t=>{const e=Math.max(...t.map((t=>this.isVerticalLayout?this.getHeight(t):this.getWidth(t)))),i=r+e/2;return r=i+e/2+this.PADDING_PX,i})),o=new Map(this.nodes.map((t=>[t.id,new Set])));e.forEach((t=>{o.get(t.targetNode).add(t.sourceNode)}));const s=[];let a=[],h=[],l=-1;do{l++;let t=null,e=null;const r=i.splice(0,1)[0].map((i=>{const r=h.find((t=>o.get(i.id).has(t.node.id))),a=this.isVerticalLayout?this.getWidth(i):this.getHeight(i),u={node:i,children:[],size:a,parent:r,previousSibling:e===r?t:null,levelOffset:n[l],orderOffset:null,modifier:null};return r?(e=r,r.children.push(u)):s.push(u),t=u,u}));a=a.concat(...r),h=r}while(i.length);const c=t=>{if(t.children&&t.children.forEach((t=>c(t))),t.previousSibling?t.orderOffset=t.previousSibling.orderOffset+t.previousSibling.size/2+this.PADDING_PX+t.size/2:t.orderOffset=0,1==t.children.length)t.modifier=t.orderOffset;else if(t.children.length>=2){let e=1/0,i=-e;for(let r=0;r<t.children.length;r++)e=Math.min(e,t.children[r].orderOffset),i=Math.max(i,t.children[r].orderOffset);t.modifier=t.orderOffset-(i-e)/2}};s.forEach((t=>c(t)));const p=(t,e)=>{t.orderOffset=t.orderOffset+e;for(let i=0;i<t.children.length;i++)p(t.children[i],t.modifier+e)};s.forEach((t=>p(t,0)));const f=t=>{const e=[];let i=[t];do{e.push(i),i=[],e[e.length-1].forEach((t=>i=i.concat(t.children)))}while(i.length);return e.shift(),e.map((t=>{const e={left:1/0,right:-1/0};return t.forEach((t=>{e.left=Math.min(e.left,t.orderOffset-(this.isVerticalLayout?this.getWidth(t.node)/2:this.getHeight(t.node)/2)),e.right=Math.max(e.right,t.orderOffset+(this.isVerticalLayout?this.getWidth(t.node)/2:this.getHeight(t.node)/2))})),e}))},_=(t,e)=>{let i=[t];for(;i.length;){const t=i.shift();i=i.concat(t.children),t.orderOffset+=e}},g=t=>{for(let e=0;e<t.children.length;e++)g(t.children[e]);if(!(t.children.length<2)){for(let e=0;e<t.children.length-1;e++){const i=t.children[e],r=f(i);for(let i=e+1;i<t.children.length;i++){const n=t.children[i],o=f(n);for(let s=0;s<Math.min(r.length,o.length);s++){const a=Math.max(r[s].right),h=Math.min(o[s].left);if(a>h){const r=a-h+this.PADDING_PX;_(n,r);const o=[];for(let r=e+1;r<i;r++)o.push(t.children[r]);if(o.length){const t=r/o.length/2;for(let e=0;e<o.length;e++)_(o[e],t)}}}}}if(!t.parent&&t.children.length){let e=0;t.children.forEach((t=>{e+=t.orderOffset})),t.orderOffset=e/t.children.length}}};g({children:s,levelOffset:0}),a.forEach((t=>{this.nodePositions.set(t.node,{y:this.isVerticalLayout?t.levelOffset:t.orderOffset,x:this.isVerticalLayout?t.orderOffset:t.levelOffset})}));const m=this.getAverageCoordinates();null===this.centerX&&(this.centerX=m[0]),null===this.centerY&&(this.centerY=m[1]);let v=0,y=0;this.nodePositions.forEach((t=>{v+=t.x,y+=t.y}));const E=v/this.nodePositions.size,T=y/this.nodePositions.size,x=this.centerX-E,b=this.centerY-T;this.nodePositions.forEach((t=>{t.x=x+t.x,t.y=b+t.y}))}execute(){let t,e;for(let i=0;i<this.nodes.length;i++)t=this.nodes[i],e=this.nodePositions.get(t),t.fx=e.x,t.x=e.x,t.fy=e.y,t.y=e.y}dismount(){this.nodes.forEach((t=>{delete t.fx,delete t.fy}))}},Force:class extends h{constructor(t=null,e=.1,i=.75){super(),this.size=t,this.gravity=i,this.speed=e,this.nodeDisplacementMap=new Map}initialize(...t){super.initialize(...t),this.nodeDisplacementMap=new Map(this.nodes.map((t=>[t,{dx:0,dy:0}])))}execute(t){const e=this.nodes.length,i=this.edges.length,r=this.size?this.size:2e4*e,n=Math.sqrt(r)/10,o=Math.sqrt(r/(1+e));let s,a,h;for(let t=0;t<e;t++){s=this.nodes[t];const i=this.nodeDisplacementMap.get(s);for(let t=0;t<e;t++)if(a=this.nodes[t],s.id!=a.id){const t=s.x-a.x,e=s.y-a.y,r=Math.sqrt(t*t+e*e)+.01;if(r>0){const n=o*o/r;i.dx+=t/r*n,i.dy+=e/r*n}}}for(let t=0;t<i;t++){h=this.edges[t];const e=h.source.x-h.target.x,i=h.source.y-h.target.y,r=Math.sqrt(e*e+i*i)+.01,n=r*r/o,s=this.nodeDisplacementMap.get(h.source),a=this.nodeDisplacementMap.get(h.target);r>0&&(s.dx-=e/r*n,s.dy-=i/r*n,a.dx+=e/r*n,a.dy+=i/r*n)}for(let i=0;i<e;i++){s=this.nodes[i];const e=this.nodeDisplacementMap.get(s),r=Math.sqrt(s.x*s.x+s.y*s.y),a=.01*o*this.gravity*r;e.dx-=a*s.x/r,e.dy-=a*s.y/r,e.dx*=this.speed,e.dy*=this.speed;const h=Math.sqrt(e.dx*e.dx+e.dy*e.dy);if(h>0){const i=Math.min(n*this.speed,h);s.vx+=e.dx/h*i*t,s.vy+=e.dy/h*i*t}}}},Connections:class extends h{constructor(t=null,e=!0,i=100,r=null,n=null){super(),this.groupBy=t,this.isVerticalLayout=e,this.PADDING_PX=i,this.centerX=r,this.centerY=n,this.nodePositions=new Map}getWidth(t){return t.width?t.width:2*t.radius}getHeight(t){return t.height?t.height:2*t.radius}initialize(...t){super.initialize(...t);let e=[];const i=d(this.nodes,this.edges);if(this.groupBy){const t={};this.nodes.forEach((e=>{const i=this.groupBy(e);t[i]||(t[i]=[]),t[i].push(e)})),Object.keys(t).sort().forEach((i=>{e.push(t[i])}))}else e=u([...this.nodes,{id:"FAKE__ISLAND"}],i).hierarchy,e[0]=e[0].filter((t=>"FAKE__ISLAND"!==t.id)),e[0].length?e[0]=[...e[0],...e.splice(1,1)[0]]:e.splice(0,1);let r=0;const n=e.map((t=>{const e=Math.max(...t.map((t=>this.isVerticalLayout?this.getHeight(t):this.getWidth(t)))),i=r+e/2;return r=i+e/2+this.PADDING_PX,i})),o=e.reduce(((t,e)=>{const i=e.reduce(((t,e)=>t+=this.isVerticalLayout?this.getWidth(e):this.getHeight(e)),0)+this.PADDING_PX*(e.length-1);return i>t?i:t}),1),s=new Map(this.nodes.map((t=>[t.id,new Set])));i.forEach((t=>{s.get(t.targetNode).add(t.sourceNode)}));let a=null;e.map((t=>{if(null===a)return void(a=t);const e=new Map,i=t=>{if(e.has(t))return e.get(t);const i=a.findIndex((e=>s.get(t).has(e.id)));return e.set(t,"number"==typeof i?i:-1),i};t.sort(((t,e)=>{const r=i(t.id),n=i(e.id);return r>n?1:r<n?-1:0})),a=t})),this.nodePositions=new Map;const h=new Map(this.nodes.map((t=>[t.id,this.isVerticalLayout?this.getWidth(t):this.getHeight(t)])));e.forEach(((t,e)=>{const i=t.reduce(((t,e)=>t+=h.get(e.id)),0),r=(o-i)/(t.length-1);let s=0;if(1===t.length){const i=t[0],r=o/2;this.nodePositions.set(i,{y:this.isVerticalLayout?r:n[e],x:this.isVerticalLayout?n[e]:r})}else t.forEach((t=>{const i=h.get(t.id),o=s+i/2;s=o+r+i/2,this.nodePositions.set(t,{y:this.isVerticalLayout?o:n[e],x:this.isVerticalLayout?n[e]:o})}))}));const l=this.getAverageCoordinates();null===this.centerX&&(this.centerX=l[0]),null===this.centerY&&(this.centerY=l[1]);let c=0,p=0;this.nodePositions.forEach((t=>{c+=t.x,p+=t.y}));const f=c/this.nodePositions.size,_=p/this.nodePositions.size,g=this.centerX-f,m=this.centerY-_;this.nodePositions.forEach((t=>{t.x=g+t.x,t.y=m+t.y}))}execute(){let t,e;for(let i=0;i<this.nodes.length;i++)t=this.nodes[i],e=this.nodePositions.get(t),t.fx=e.x,t.x=e.x,t.fy=e.y,t.y=e.y}dismount(){this.nodes.forEach((t=>{delete t.fx,delete t.fy}))}}});var _=setTimeout;function g(t){return Boolean(t&&void 0!==t.length)}function m(){}function v(t){if(!(this instanceof v))throw new TypeError("Promises must be constructed via new");if("function"!=typeof t)throw new TypeError("not a function");this._state=0,this._handled=!1,this._value=void 0,this._deferreds=[],R(t,this)}function y(t,e){for(;3===t._state;)t=t._value;0!==t._state?(t._handled=!0,v._immediateFn((function(){var i=1===t._state?e.onFulfilled:e.onRejected;if(null!==i){var r;try{r=i(t._value)}catch(t){return void T(e.promise,t)}E(e.promise,r)}else(1===t._state?E:T)(e.promise,t._value)}))):t._deferreds.push(e)}function E(t,e){try{if(e===t)throw new TypeError("A promise cannot be resolved with itself.");if(e&&("object"==typeof e||"function"==typeof e)){var i=e.then;if(e instanceof v)return t._state=3,t._value=e,void x(t);if("function"==typeof i)return void R((r=i,n=e,function(){r.apply(n,arguments)}),t)}t._state=1,t._value=e,x(t)}catch(e){T(t,e)}var r,n}function T(t,e){t._state=2,t._value=e,x(t)}function x(t){2===t._state&&0===t._deferreds.length&&v._immediateFn((function(){t._handled||v._unhandledRejectionFn(t._value)}));for(var e=0,i=t._deferreds.length;e<i;e++)y(t,t._deferreds[e]);t._deferreds=null}function b(t,e,i){this.onFulfilled="function"==typeof t?t:null,this.onRejected="function"==typeof e?e:null,this.promise=i}function R(t,e){var i=!1;try{t((function(t){i||(i=!0,E(e,t))}),(function(t){i||(i=!0,T(e,t))}))}catch(t){if(i)return;i=!0,T(e,t)}}v.prototype.catch=function(t){return this.then(null,t)},v.prototype.then=function(t,e){var i=new this.constructor(m);return y(this,new b(t,e,i)),i},v.prototype.finally=function(t){var e=this.constructor;return this.then((function(i){return e.resolve(t()).then((function(){return i}))}),(function(i){return e.resolve(t()).then((function(){return e.reject(i)}))}))},v.all=function(t){return new v((function(e,i){if(!g(t))return i(new TypeError("Promise.all accepts an array"));var r=Array.prototype.slice.call(t);if(0===r.length)return e([]);var n=r.length;function o(t,s){try{if(s&&("object"==typeof s||"function"==typeof s)){var a=s.then;if("function"==typeof a)return void a.call(s,(function(e){o(t,e)}),i)}r[t]=s,0==--n&&e(r)}catch(t){i(t)}}for(var s=0;s<r.length;s++)o(s,r[s])}))},v.allSettled=function(t){return new this((function(e,i){if(!t||void 0===t.length)return i(new TypeError(typeof t+" "+t+" is not iterable(cannot read property Symbol(Symbol.iterator))"));var r=Array.prototype.slice.call(t);if(0===r.length)return e([]);var n=r.length;function o(t,i){if(i&&("object"==typeof i||"function"==typeof i)){var s=i.then;if("function"==typeof s)return void s.call(i,(function(e){o(t,e)}),(function(i){r[t]={status:"rejected",reason:i},0==--n&&e(r)}))}r[t]={status:"fulfilled",value:i},0==--n&&e(r)}for(var s=0;s<r.length;s++)o(s,r[s])}))},v.resolve=function(t){return t&&"object"==typeof t&&t.constructor===v?t:new v((function(e){e(t)}))},v.reject=function(t){return new v((function(e,i){i(t)}))},v.race=function(t){return new v((function(e,i){if(!g(t))return i(new TypeError("Promise.race accepts an array"));for(var r=0,n=t.length;r<n;r++)v.resolve(t[r]).then(e,i)}))},v._immediateFn="function"==typeof setImmediate&&function(t){setImmediate(t)}||function(t){_(t,0)},v._unhandledRejectionFn=function(t){"undefined"!=typeof console&&console&&console.warn("Possible Unhandled Promise Rejection:",t)};var A="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},O=Object.getOwnPropertySymbols,I=Object.prototype.hasOwnProperty,S=Object.prototype.propertyIsEnumerable; /* object-assign (c) Sindre Sorhus @license MIT */function N(t){if(null==t)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(t)}var M=function(){try{if(!Object.assign)return!1;var t=new String("abc");if(t[5]="de","5"===Object.getOwnPropertyNames(t)[0])return!1;for(var e={},i=0;i<10;i++)e["_"+String.fromCharCode(i)]=i;if("0123456789"!==Object.getOwnPropertyNames(e).map((function(t){return e[t]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(t){r[t]=t})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(t){return!1}}()?Object.assign:function(t,e){for(var i,r,n=N(t),o=1;o<arguments.length;o++){for(var s in i=Object(arguments[o]))I.call(i,s)&&(n[s]=i[s]);if(O){r=O(i);for(var a=0;a<r.length;a++)S.call(i,r[a])&&(n[r[a]]=i[r[a]])}}return n};"undefined"==typeof globalThis&&("undefined"!=typeof self?self.globalThis=self:"undefined"!=typeof global&&(global.globalThis=global)),globalThis.Promise||(globalThis.Promise=v),Object.assign||(Object.assign=M);if(Date.now&&Date.prototype.getTime||(Date.now=function(){return(new Date).getTime()}),!globalThis.performance||!globalThis.performance.now){var P=Date.now();globalThis.performance||(globalThis.performance={}),globalThis.performance.now=function(){return Date.now()-P}}for(var w=Date.now(),D=["ms","moz","webkit","o"],C=0;C<D.length&&!globalThis.requestAnimationFrame;++C){var L=D[C];globalThis.requestAnimationFrame=globalThis[L+"RequestAnimationFrame"],globalThis.cancelAnimationFrame=globalThis[L+"CancelAnimationFrame"]||globalThis[L+"CancelRequestAnimationFrame"]}globalThis.requestAnimationFrame||(globalThis.requestAnimationFrame=function(t){if("function"!=typeof t)throw new TypeError(t+"is not a function");var e=Date.now(),i=16+w-e;return i<0&&(i=0),w=e,globalThis.self.setTimeout((function(){w=Date.now(),t(performance.now())}),i)}),globalThis.cancelAnimationFrame||(globalThis.cancelAnimationFrame=function(t){return clearTimeout(t)}),Math.sign||(Math.sign=function(t){return 0===(t=Number(t))||isNaN(t)?t:t>0?1:-1}),Number.isInteger||(Number.isInteger=function(t){return"number"==typeof t&&isFinite(t)&&Math.floor(t)===t}),globalThis.ArrayBuffer||(globalThis.ArrayBuffer=Array),globalThis.Float32Array||(globalThis.Float32Array=Array),globalThis.Uint32Array||(globalThis.Uint32Array=Array),globalThis.Uint16Array||(globalThis.Uint16Array=Array),globalThis.Uint8Array||(globalThis.Uint8Array=Array),globalThis.Int32Array||(globalThis.Int32Array=Array);var U=/iPhone/i,F=/iPod/i,G=/iPad/i,B=/\biOS-universal(?:.+)Mac\b/i,X=/\bAndroid(?:.+)Mobile\b/i,k=/Android/i,H=/(?:SD4930UR|\bSilk(?:.+)Mobile\b)/i,Y=/Silk/i,j=/Windows Phone/i,V=/\bWindows(?:.+)ARM\b/i,z=/BlackBerry/i,W=/BB10/i,q=/Opera Mini/i,K=/\b(CriOS|Chrome)(?:.+)Mobile/i,Z=/Mobile(?:.+)Firefox\b/i,$=function(t){return void 0!==t&&"MacIntel"===t.platform&&"number"==typeof t.maxTouchPoints&&t.maxTouchPoints>1&&"undefined"==typeof MSStream};var J,Q,tt,et,it,rt,nt,ot,st,at,ht,ut,lt,ct,dt,pt,ft,_t,gt,mt=function(t){var e={userAgent:"",platform:"",maxTouchPoints:0};t||"undefined"==typeof navigator?"string"==typeof t?e.userAgent=t:t&&t.userAgent&&(e={userAgent:t.userAgent,platform:t.platform,maxTouchPoints:t.maxTouchPoints||0}):e={userAgent:navigator.userAgent,platform:navigator.platform,maxTouchPoints:navigator.maxTouchPoints||0};var i=e.userAgent,r=i.split("[FBAN");void 0!==r[1]&&(i=r[0]),void 0!==(r=i.split("Twitter"))[1]&&(i=r[0]);var n=function(t){return function(e){return e.test(t)}}(i),o={apple:{phone:n(U)&&!n(j),ipod:n(F),tablet:!n(U)&&(n(G)||$(e))&&!n(j),universal:n(B),device:(n(U)||n(F)||n(G)||n(B)||$(e))&&!n(j)},amazon:{phone:n(H),tablet:!n(H)&&n(Y),device:n(H)||n(Y)},android:{phone:!n(j)&&n(H)||!n(j)&&n(X),tablet:!n(j)&&!n(H)&&!n(X)&&(n(Y)||n(k)),device:!n(j)&&(n(H)||n(Y)||n(X)||n(k))||n(/\bokhttp\b/i)},windows:{phone:n(j),tablet:n(V),device:n(j)||n(V)},other:{blackberry:n(z),blackberry10:n(W),opera:n(q),firefox:n(Z),chrome:n(K),device:n(z)||n(W)||n(q)||n(Z)||n(K)},any:!1,phone:!1,tablet:!1};return o.any=o.apple.device||o.android.device||o.windows.device||o.other.device,o.phone=o.apple.phone||o.android.phone||o.windows.phone,o.tablet=o.apple.tablet||o.android.tablet||o.windows.tablet,o}(globalThis.navigator);!function(t){t[t.WEBGL_LEGACY=0]="WEBGL_LEGACY",t[t.WEBGL=1]="WEBGL",t[t.WEBGL2=2]="WEBGL2"}(J||(J={})),function(t){t[t.UNKNOWN=0]="UNKNOWN",t[t.WEBGL=1]="WEBGL",t[t.CANVAS=2]="CANVAS"}(Q||(Q={})),function(t){t[t.COLOR=16384]="COLOR",t[t.DEPTH=256]="DEPTH",t[t.STENCIL=1024]="STENCIL"}(tt||(tt={})),function(t){t[t.NORMAL=0]="NORMAL",t[t.ADD=1]="ADD",t[t.MULTIPLY=2]="MULTIPLY",t[t.SCREEN=3]="SCREEN",t[t.OVERLAY=4]="OVERLAY",t[t.DARKEN=5]="DARKEN",t[t.LIGHTEN=6]="LIGHTEN",t[t.COLOR_DODGE=7]="COLOR_DODGE",t[t.COLOR_BURN=8]="COLOR_BURN",t[t.HARD_LIGHT=9]="HARD_LIGHT",t[t.SOFT_LIGHT=10]="SOFT_LIGHT",t[t.DIFFERENCE=11]="DIFFERENCE",t[t.EXCLUSION=12]="EXCLUSION",t[t.HUE=13]="HUE",t[t.SATURATION=14]="SATURATION",t[t.COLOR=15]="COLOR",t[t.LUMINOSITY=16]="LUMINOSITY",t[t.NORMAL_NPM=17]="NORMAL_NPM",t[t.ADD_NPM=18]="ADD_NPM",t[t.SCREEN_NPM=19]="SCREEN_NPM",t[t.NONE=20]="NONE",t[t.SRC_OVER=0]="SRC_OVER",t[t.SRC_IN=21]="SRC_IN",t[t.SRC_OUT=22]="SRC_OUT",t[t.SRC_ATOP=23]="SRC_ATOP",t[t.DST_OVER=24]="DST_OVER",t[t.DST_IN=25]="DST_IN",t[t.DST_OUT=26]="DST_OUT",t[t.DST_ATOP=27]="DST_ATOP",t[t.ERASE=26]="ERASE",t[t.SUBTRACT=2