@html-graph/html-graph 0.0.50 → 0.0.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -5
- package/dist/main.d.ts +181 -54
- package/dist/main.js +1053 -687
- package/dist/main.umd.cjs +1 -1
- package/package.json +9 -3
package/dist/main.umd.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(v,b){typeof exports=="object"&&typeof module<"u"?b(exports):typeof define=="function"&&define.amd?define(["exports"],b):(v=typeof globalThis<"u"?globalThis:v||self,b(v.HTMLGraph={}))})(this,function(v){"use strict";var ae=Object.defineProperty;var he=(v,b,x)=>b in v?ae(v,b,{enumerable:!0,configurable:!0,writable:!0,value:x}):v[b]=x;var n=(v,b,x)=>he(v,typeof b!="symbol"?b+"":b,x);class b{constructor(e,t,s,r,a){n(this,"canvasWrapper",null);n(this,"host");n(this,"nodesContainer");n(this,"edgesContainer");n(this,"canvas");n(this,"canvasCtx");n(this,"hostResizeObserver");n(this,"nodesResizeObserver");n(this,"nodeElementToIdMap",new Map);n(this,"nodeWrapperElementToIdMap",new Map);n(this,"nodeIdToWrapperElementMap",new Map);n(this,"edgeIdToElementMap",new Map);n(this,"currentZIndex",0);n(this,"layers",{"edges-on-top":{create:()=>{this.host.appendChild(this.nodesContainer),this.host.appendChild(this.edgesContainer)},update:(e,t,s)=>{this.nodesContainer.style.transform=`matrix(${e}, 0, 0, ${e}, ${t}, ${s})`,this.edgesContainer.style.transform=`matrix(${e}, 0, 0, ${e}, ${t}, ${s})`},moveOnTop:e=>{this.currentZIndex+=1;const t=this.nodeIdToWrapperElementMap.get(e);t.style.zIndex=`${this.currentZIndex}`}},"edges-follow-node":{create:()=>{this.host.appendChild(this.nodesContainer),this.edgesContainer=this.nodesContainer},update:(e,t,s)=>{this.nodesContainer.style.transform=`matrix(${e}, 0, 0, ${e}, ${t}, ${s})`},moveOnTop:e=>{const t=this.nodeIdToWrapperElementMap.get(e);this.currentZIndex+=2,t.style.zIndex=`${this.currentZIndex}`,this.graphStore.getNodeAdjacentEdges(e).forEach(r=>{this.edgeIdToElementMap.get(r).style.zIndex=`${this.currentZIndex-1}`})}},"nodes-on-top":{create:()=>{this.host.appendChild(this.edgesContainer),this.host.appendChild(this.nodesContainer)},update:(e,t,s)=>{this.nodesContainer.style.transform=`matrix(${e}, 0, 0, ${e}, ${t}, ${s})`,this.edgesContainer.style.transform=`matrix(${e}, 0, 0, ${e}, ${t}, ${s})`},moveOnTop:e=>{this.currentZIndex+=1;const t=this.nodeIdToWrapperElementMap.get(e);t.style.zIndex=`${this.currentZIndex}`}}});this.graphStore=e,this.viewportTransformer=t,this.publicViewportTransformer=s,this.layersMode=r,this.backgroundDrawingFn=a,this.host=this.createHost(),this.canvas=this.createCanvas(),this.nodesContainer=this.createNodesContainer(),this.edgesContainer=this.createEdgesContainer();const c=this.canvas.getContext("2d");if(c===null)throw new Error("unable to get canvas context");this.canvasCtx=c,this.host.appendChild(this.canvas),this.layers[this.layersMode].create(),this.hostResizeObserver=this.createHostResizeObserver(),this.hostResizeObserver.observe(this.host),this.nodesResizeObserver=this.createNodesResizeObserver()}clear(){Array.from(this.edgeIdToElementMap.keys()).forEach(e=>{this.detachEdge(e)}),Array.from(this.nodeElementToIdMap.values()).forEach(e=>{this.detachNode(e)})}attach(e){this.detach(),this.canvasWrapper=e,this.canvasWrapper.appendChild(this.host)}detach(){this.canvasWrapper!==null&&(this.canvasWrapper.removeChild(this.host),this.canvasWrapper=null)}destroy(){this.hostResizeObserver.disconnect(),this.nodesResizeObserver.disconnect(),this.host.removeChild(this.canvas),this.host.removeChild(this.edgesContainer),this.host.removeChild(this.nodesContainer),this.canvasWrapper!==null&&(this.canvasWrapper.removeChild(this.host),this.canvasWrapper=null)}applyTransform(){this.backgroundDrawingFn(this.canvasCtx,this.publicViewportTransformer);const[e,t]=this.viewportTransformer.getViewCoords(0,0),s=this.viewportTransformer.getViewScale();this.layers[this.layersMode].update(s,e,t)}attachNode(e){const t=this.graphStore.getNode(e),s=document.createElement("div");s.appendChild(t.element),s.style.position="absolute",s.style.top="0",s.style.left="0",s.style.zIndex=`${this.currentZIndex}`,this.currentZIndex+=1,s.style.visibility="hidden",this.nodesContainer.appendChild(s),this.nodeElementToIdMap.set(t.element,e),this.nodeWrapperElementToIdMap.set(s,e),this.nodeIdToWrapperElementMap.set(e,s),this.updateNodeCoords(e,t.x,t.y),this.nodesResizeObserver.observe(s),s.style.visibility="visible"}detachNode(e){const t=this.graphStore.getNode(e);this.nodesResizeObserver.unobserve(t.element),this.nodesContainer.removeChild(t.element);const s=this.nodeIdToWrapperElementMap.get(e);s.removeChild(t.element),this.nodeElementToIdMap.delete(t.element),this.nodeWrapperElementToIdMap.delete(s),this.nodeIdToWrapperElementMap.delete(e)}attachEdge(e){const s=this.graphStore.getEdge(e).controller.svg;s.style.transformOrigin="50% 50%",s.style.position="absolute",s.style.top="0",s.style.left="0",s.style.zIndex=`${this.currentZIndex}`,this.currentZIndex+=1,this.edgeIdToElementMap.set(e,s),this.updateEdgeCoords(e),this.edgesContainer.appendChild(s)}detachEdge(e){const t=this.edgeIdToElementMap.get(e);this.edgeIdToElementMap.delete(e),this.edgesContainer.removeChild(t)}moveNodeOnTop(e){this.layers[this.layersMode].moveOnTop(e)}updateNodeCoordinates(e){const t=this.graphStore.getNode(e),s=this.graphStore.getNodeAdjacentEdges(e);this.updateNodeCoords(e,t.x,t.y),s.forEach(r=>{this.updateEdgeCoords(r)})}updatePortEdges(e){this.graphStore.getPortAdjacentEdges(e).forEach(s=>{this.updateEdgeCoords(s)})}getViewportDimensions(){const e=this.host.getBoundingClientRect();return[e.width,e.height]}createHost(){const e=document.createElement("div");return e.style.width="100%",e.style.height="100%",e.style.position="relative",e.style.overflow="hidden",e}createCanvas(){const e=document.createElement("canvas");return e.style.position="absolute",e.style.inset="0",e}createNodesContainer(){const e=document.createElement("div");return e.style.position="absolute",e.style.top="0",e.style.left="0",e.style.width="0",e.style.height="0",e}createEdgesContainer(){const e=document.createElement("div");return e.style.position="absolute",e.style.pointerEvents="none",e.style.top="0",e.style.left="0",e.style.width="0",e.style.height="0",e}createHostResizeObserver(){return new ResizeObserver(()=>{this.updateCanvasDimensions(),this.applyTransform()})}createNodesResizeObserver(){return new ResizeObserver(e=>{e.forEach(t=>{const s=t.target,r=this.nodeWrapperElementToIdMap.get(s),a=this.graphStore.getNode(r);this.updateNodeCoords(r,a.x,a.y),this.graphStore.getNodeAdjacentEdges(r).forEach(h=>{this.updateEdgeCoords(h)})})})}updateCanvasDimensions(){const{width:e,height:t}=this.host.getBoundingClientRect();this.canvas.width=e,this.canvas.height=t}updateNodeCoords(e,t,s){const r=this.nodeIdToWrapperElementMap.get(e),{width:a,height:c}=r.getBoundingClientRect(),h=this.viewportTransformer.getAbsScale(),i=this.graphStore.getNode(e),[d,g]=i.centerFn(a,c);r.style.transform=`matrix(1, 0, 0, 1, ${t-h*d}, ${s-h*g})`}updateEdgeCoords(e){const t=this.graphStore.getEdge(e),s=this.graphStore.getPort(t.from),r=this.graphStore.getPort(t.to),a=s.element.getBoundingClientRect(),c=r.element.getBoundingClientRect(),h=this.host.getBoundingClientRect(),[i,d]=this.viewportTransformer.getAbsCoords(a.left-h.left,a.top-h.top),[g,l]=this.viewportTransformer.getAbsCoords(c.left-h.left,c.top-h.top),u=this.viewportTransformer.getAbsScale(),[w,m]=s.centerFn(a.width*u,a.height*u),[f,C]=r.centerFn(c.width*u,c.height*u),E=w+i,y=m+d,T=f+g,S=C+l,$=Math.min(E,T),N=Math.min(y,S),A=Math.abs(T-E),L=Math.abs(S-y);t.controller.update($,N,A,L,s,r)}}class x{constructor(){n(this,"state",{scale:1,x:0,y:0})}getViewCoords(e,t){return[(e-this.state.x)/this.state.scale,(t-this.state.y)/this.state.scale]}getViewScale(){return 1/this.state.scale}getAbsCoords(e,t){return[e*this.state.scale+this.state.x,t*this.state.scale+this.state.y]}getAbsScale(){return this.state.scale}patchState(e,t,s){this.state={scale:e??this.state.scale,x:t??this.state.x,y:s??this.state.y}}}class q{constructor(e){this.transformer=e}getViewCoords(e,t){return this.transformer.getViewCoords(e,t)}getViewScale(){return this.transformer.getViewScale()}getAbsCoords(e,t){return this.transformer.getAbsCoords(e,t)}getAbsScale(){return this.transformer.getAbsScale()}}class _{constructor(){n(this,"nodes",Object.create(null));n(this,"ports",Object.create(null));n(this,"nodePorts",Object.create(null));n(this,"portNodeId",Object.create(null));n(this,"edges",Object.create(null));n(this,"incommingEdges",Object.create(null));n(this,"outcommingEdges",Object.create(null));n(this,"cycleEdges",Object.create(null))}addNode(e,t,s,r,a){this.nodes[e]={element:t,x:s,y:r,centerFn:a},this.nodePorts[e]=Object.create(null)}hasNode(e){return this.nodes[e]!==void 0}getNode(e){return this.nodes[e]}updateNodeCoords(e,t,s){this.nodes[e].x=t,this.nodes[e].y=s}updateEdgeController(e,t){this.edges[e].controller=t}removeNode(e){this.getNodeAdjacentEdges(e).forEach(r=>{this.removeEdge(r)}),delete this.nodes[e];const s=this.nodePorts[e];Object.keys(s).forEach(r=>{delete this.portNodeId[r]}),delete this.nodePorts[e]}addPort(e,t,s,r,a){this.ports[e]={element:t,centerFn:r,direction:a},this.cycleEdges[e]={},this.incommingEdges[e]={},this.outcommingEdges[e]={},this.portNodeId[e]=s;const c=this.nodePorts[s];c!==void 0&&(c[e]=t)}getPort(e){return this.ports[e]}getPortNode(e){return this.portNodeId[e]}hasPort(e){return this.portNodeId[e]!==void 0}removePort(e){Object.keys(this.cycleEdges[e]).forEach(r=>{this.removeEdge(r)}),delete this.cycleEdges[e],Object.keys(this.incommingEdges[e]).forEach(r=>{this.removeEdge(r)}),delete this.incommingEdges[e],Object.keys(this.outcommingEdges[e]).forEach(r=>{this.removeEdge(r)}),delete this.outcommingEdges[e];const t=this.portNodeId[e];delete this.portNodeId[e];const s=this.nodePorts[t];delete s[e],delete this.ports[e]}addEdge(e,t,s,r){this.edges[e]={from:t,to:s,controller:r},t!==s?(this.outcommingEdges[t][e]=!0,this.incommingEdges[s][e]=!0):this.cycleEdges[t][e]=!0}getEdge(e){return this.edges[e]}hasEdge(e){return this.edges[e]!==void 0}removeEdge(e){const t=this.edges[e],s=t.from,r=t.to;delete this.cycleEdges[s][e],delete this.cycleEdges[r][e],delete this.incommingEdges[s][e],delete this.incommingEdges[r][e],delete this.outcommingEdges[s][e],delete this.outcommingEdges[r][e],delete this.edges[e]}getPortAdjacentEdges(e){return[...this.getPortIncomingEdges(e),...this.getPortOutcomingEdges(e),...this.getPortCycleEdges(e)]}getNodeAdjacentEdges(e){return[...this.getNodeIncomingEdges(e),...this.getNodeOutcomingEdges(e),...this.getNodeCycleEdges(e)]}clear(){this.nodes=Object.create(null),this.ports=Object.create(null),this.nodePorts=Object.create(null),this.portNodeId=Object.create(null),this.edges=Object.create(null),this.incommingEdges=Object.create(null),this.outcommingEdges=Object.create(null),this.cycleEdges=Object.create(null)}getPortIncomingEdges(e){return Object.keys(this.incommingEdges[e]??{})}getPortOutcomingEdges(e){return Object.keys(this.outcommingEdges[e]??{})}getPortCycleEdges(e){return Object.keys(this.cycleEdges[e]??{})}getNodeIncomingEdges(e){const t=Object.keys(this.nodePorts[e]);let s=[];return t.forEach(r=>{s=[...s,...this.getPortIncomingEdges(r)]}),s}getNodeOutcomingEdges(e){const t=Object.keys(this.nodePorts[e]);let s=[];return t.forEach(r=>{s=[...s,...this.getPortOutcomingEdges(r)]}),s}getNodeCycleEdges(e){const t=Object.keys(this.nodePorts[e]);let s=[];return t.forEach(r=>{s=[...s,...this.getPortCycleEdges(r)]}),s}}class p{static getPortCenter(e){const{top:t,left:s,width:r,height:a}=e.element.getBoundingClientRect(),c=e.centerFn(r,a);return[s+c[0],t+c[1]]}static rotate(e,t,s){return[t[0]*e[0]-t[1]*e[1]+((1-t[0])*s[0]+t[1]*s[1]),t[1]*e[0]+t[0]*e[1]+((1-t[0])*s[1]-t[1]*s[0])]}static getDirectionVector(e,t,s){return[t*Math.cos(e??0),s*Math.sin(e??0)]}static getArrowPath(e,t,s,r,a){const h=[[0,0],[r,a],[r,-a]].map(l=>this.rotate(l,e,[0,0])).map(l=>[l[0]+t,l[1]+s]),i=`M ${h[0][0]} ${h[0][1]}`,d=`L ${h[1][0]} ${h[1][1]}`,g=`L ${h[2][0]} ${h[2][1]}`;return`${i} ${d} ${g}`}static getArrowOffsetPath(e,t,s,r,a){const h=[[r,0],[r+a,0]].map(i=>this.rotate(i,e,[0,0])).map(i=>[i[0]+t,i[1]+s]);return`M ${h[0][0]} ${h[0][1]} L ${h[1][0]} ${h[1][1]}`}static createStraightPath(e){return e.map((t,s)=>`${s===0?"M":"L"} ${t[0]} ${t[1]}`).join(" ")}}class D{constructor(e,t,s,r,a,c,h){n(this,"svg");n(this,"group");n(this,"line");n(this,"sourceArrow",null);n(this,"targetArrow",null);this.color=e,this.width=t,this.curvature=s,this.arrowLength=r,this.arrowWidth=a,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",c&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),h&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(e,t,s,r,a,c){this.svg.style.width=`${s}px`,this.svg.style.height=`${r}px`;const h=p.getPortCenter(a),i=p.getPortCenter(c),d=h[0]<=i[0]?1:-1,g=h[1]<=i[1]?1:-1;this.svg.style.transform=`translate(${e}px, ${t}px)`,this.group.style.transform=`scale(${d}, ${g})`;const l=p.getDirectionVector(a.direction,d,g),u=p.getDirectionVector(c.direction,d,g),w=p.rotate([this.arrowLength,0],l,[0,0]),m=p.rotate([s-this.arrowLength,r],u,[s,r]),f=[w[0]+l[0]*this.curvature,w[1]+l[1]*this.curvature],C=[m[0]-u[0]*this.curvature,m[1]-u[1]*this.curvature],E=`M ${w[0]} ${w[1]} C ${f[0]} ${f[1]}, ${C[0]} ${C[1]}, ${m[0]} ${m[1]}`,y=this.sourceArrow?"":`M 0 0 L ${w[0]} ${w[1]} `,T=this.targetArrow?"":` M ${m[0]} ${m[1]} L ${s} ${r}`,S=`${y}${E}${T}`;if(this.line.setAttribute("d",S),this.sourceArrow){const $=p.getArrowPath(l,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",$)}if(this.targetArrow){const $=p.getArrowPath(u,s,r,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",$)}}}class F{constructor(e,t,s,r,a,c,h,i){n(this,"svg");n(this,"group");n(this,"line");n(this,"sourceArrow",null);n(this,"targetArrow",null);n(this,"roundness");this.color=e,this.width=t,this.arrowLength=s,this.arrowWidth=r,this.arrowOffset=a,this.roundness=Math.min(this.arrowOffset,i),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",c&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),h&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(e,t,s,r,a,c){this.svg.style.width=`${s}px`,this.svg.style.height=`${r}px`;const h=p.getPortCenter(a),i=p.getPortCenter(c),d=h[0]<=i[0]?1:-1,g=h[1]<=i[1]?1:-1;this.svg.style.transform=`translate(${e}px, ${t}px)`,this.group.style.transform=`scale(${d}, ${g})`;const l=p.getDirectionVector(a.direction,d,g),u=p.getDirectionVector(c.direction,d,g),w=this.sourceArrow?p.rotate([this.arrowLength,0],l,[0,0]):[0,0],m=this.targetArrow?p.rotate([s-this.arrowLength,r],u,[s,r]):[s,r],f=this.arrowLength+this.arrowOffset,C=f-this.roundness,E=s-f*2*d,y=Math.sqrt(E*E+r*r)/2,T=Math.min(this.roundness,y),S=p.rotate([C,0],l,[0,0]),$=p.rotate([s-C,r],u,[s,r]),N=p.rotate([f,0],l,[0,0]),A=p.rotate([s-f,r],u,[s,r]),L=(A[0]-N[0])/2,U=(A[1]-N[1])/2,O=T/y,Z=[N[0]+L*O,N[1]+U*O],H=[A[0]-L*O,A[1]-U*O],ie=[`M ${w[0]} ${w[1]}`,`L ${S[0]} ${S[1]}`,`C ${N[0]} ${N[1]} ${N[0]} ${N[1]} ${Z[0]} ${Z[1]}`,`L ${H[0]} ${H[1]}`,`C ${A[0]} ${A[1]} ${A[0]} ${A[1]} ${$[0]} ${$[1]}`,`L ${m[0]} ${m[1]}`].join(" ");if(this.line.setAttribute("d",ie),this.sourceArrow){const V=p.getArrowPath(l,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",V)}if(this.targetArrow){const V=p.getArrowPath(u,s,r,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",V)}}}class k{constructor(e,t,s,r,a,c,h){n(this,"svg");n(this,"group");n(this,"line");n(this,"arrow",null);this.color=e,this.width=t,this.arrowLength=s,this.arrowWidth=r,this.radius=c,this.smallRadius=h,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",a&&(this.arrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.arrow.setAttribute("fill",this.color),this.group.appendChild(this.arrow)),this.svg.style.overflow="visible",this.svg.style.width="0px",this.svg.style.height="0px"}update(e,t,s,r,a){this.svg.style.transform=`translate(${e}px, ${t}px)`;const c=p.getDirectionVector(a.direction,1,1),h=this.smallRadius,i=this.radius,d=Math.sqrt(h*h+i*i),g=h+i,l=this.arrowLength+d*(1-i/g),u=h*i/g,m=[[this.arrowLength,0],[l,u],[l,-u]].map(y=>p.rotate(y,c,[0,0])),f=[`M ${m[0][0]} ${m[0][1]}`,`A ${h} ${h} 0 0 1 ${m[1][0]} ${m[1][1]}`,`A ${i} ${i} 0 1 0 ${m[2][0]} ${m[2][1]}`,`A ${h} ${h} 0 0 1 ${m[0][0]} ${m[0][1]}`].join(" "),C=`M 0 0 L ${m[0][0]} ${m[0][1]} `,E=`${this.arrow!==null?"":C}${f}`;if(this.line.setAttribute("d",E),this.arrow){const y=p.getArrowPath(c,0,0,this.arrowLength,this.arrowWidth);this.arrow.setAttribute("d",y)}}}class j{constructor(e,t,s,r,a,c,h,i){n(this,"svg");n(this,"group");n(this,"line");n(this,"arrow",null);n(this,"roundness");n(this,"points");this.color=e,this.width=t,this.arrowLength=s,this.arrowWidth=r,this.side=c,this.minPortOffset=h,this.roundness=Math.min(i,this.minPortOffset,this.side/2),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",a&&(this.arrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.arrow.setAttribute("fill",this.color),this.group.appendChild(this.arrow)),this.svg.style.overflow="visible",this.svg.style.width="0px",this.svg.style.height="0px";const d=this.minPortOffset,g=this.side,l=this.arrowLength+d,u=this.roundness,w=l-u,m=l+u,f=g-u,C=l+2*g,E=C-u;console.log(u),this.points=[[this.arrowLength,0],[w,0],[l,u],[l,f],[m,g],[E,g],[C,f],[C,-f],[E,-g],[m,-g],[l,-f],[l,-u]]}update(e,t,s,r,a){this.svg.style.transform=`translate(${e}px, ${t}px)`;const c=p.getDirectionVector(a.direction,1,1),h=this.roundness,i=this.points.map(u=>p.rotate(u,c,[0,0])),d=[`M ${i[0][0]} ${i[0][1]}`,`L ${i[1][0]} ${i[1][1]}`,`A ${h} ${h} 0 0 1 ${i[2][0]} ${i[2][1]}`,`L ${i[3][0]} ${i[3][1]}`,`A ${h} ${h} 0 0 0 ${i[4][0]} ${i[4][1]}`,`L ${i[5][0]} ${i[5][1]}`,`A ${h} ${h} 0 0 0 ${i[6][0]} ${i[6][1]}`,`L ${i[7][0]} ${i[7][1]}`,`A ${h} ${h} 0 0 0 ${i[8][0]} ${i[8][1]}`,`L ${i[9][0]} ${i[9][1]}`,`A ${h} ${h} 0 0 0 ${i[10][0]} ${i[10][1]}`,`L ${i[11][0]} ${i[11][1]}`,`A ${h} ${h} 0 0 1 ${i[1][0]} ${i[1][1]}`].join(" "),g=`M 0 0 L ${i[0][0]} ${i[0][1]} `,l=`${this.arrow?"":g}${d}`;if(this.line.setAttribute("d",l),this.arrow){const u=p.getArrowPath(c,0,0,this.arrowLength,this.arrowWidth);this.arrow.setAttribute("d",u)}}}var M=(o=>(o.Regular="regular",o.Cycle="cycle",o))(M||{});const R=o=>e=>e==="cycle"?new k(o.color,o.width,o.arrowLength,o.arrowWidth,o.hasSourceArrow||o.hasTargetArrow,o.cycleRadius,o.smallCycleRadius):new D(o.color,o.width,o.curvature,o.arrowLength,o.arrowWidth,o.hasSourceArrow,o.hasTargetArrow),W=o=>e=>e===M.Cycle&&e==="cycle"?new j(o.color,o.width,o.arrowLength,o.arrowWidth,o.hasSourceArrow||o.hasTargetArrow,o.cycleSquareSide,o.arrowOffset,o.roundness):new F(o.color,o.width,o.arrowLength,o.arrowWidth,o.arrowOffset,o.hasSourceArrow,o.hasTargetArrow,o.roundness);class P{constructor(){n(this,"counter",0)}next(){const e=`${this.counter}`;return this.counter++,e}reset(){this.counter=0}}class J{constructor(e,t,s,r,a){n(this,"nodeIdGenerator",new P);n(this,"portIdGenerator",new P);n(this,"edgeIdGenerator",new P);this.graphStore=e,this.htmlController=t,this.viewportTransformer=s,this.nodesCenterFn=r,this.portsCenterFn=a}moveNodeOnTop(e){if(!this.graphStore.hasNode(e))throw new Error("failed to move on top nonexisting node");this.htmlController.moveNodeOnTop(e)}addNode(e,t,s,r,a,c){if(e===void 0)do e=this.nodeIdGenerator.next();while(this.graphStore.hasNode(e));if(this.graphStore.hasNode(e))throw new Error("failed to add node with existing id");this.graphStore.addNode(e,t,s,r,c??this.nodesCenterFn),this.htmlController.attachNode(e),a!==void 0&&Object.entries(a).forEach(([h,i])=>{i instanceof HTMLElement?this.markPort(h,i,e,this.portsCenterFn,null):this.markPort(h,i.element,e,i.centerFn??this.portsCenterFn,i.direction??null)})}markPort(e,t,s,r,a){if(e===void 0)do e=this.portIdGenerator.next();while(this.graphStore.hasPort(e));if(!this.graphStore.hasNode(s))throw new Error("failed to set port on nonexisting node");if(this.graphStore.hasPort(e))throw new Error("failed to add port with existing id");this.graphStore.addPort(e,t,s,r??this.portsCenterFn,a??null)}updatePortEdges(e){if(!this.graphStore.hasPort(e))throw new Error("failed to unset nonexisting port");this.htmlController.updatePortEdges(e)}unmarkPort(e){if(!this.graphStore.hasPort(e))throw new Error("failed to unset nonexisting port");this.graphStore.getPortAdjacentEdges(e).forEach(t=>{this.removeEdge(t)}),this.graphStore.removePort(e)}addEdge(e,t,s,r){if(e===void 0)do e=this.edgeIdGenerator.next();while(this.graphStore.hasEdge(e));if(!this.graphStore.hasPort(t))throw new Error("failed to add edge from nonexisting port");if(!this.graphStore.hasPort(s))throw new Error("failed to add edge to nonexisting port");let a=M.Regular;t===s&&(a=M.Cycle),this.graphStore.addEdge(e,t,s,r(a)),this.htmlController.attachEdge(e)}removeEdge(e){if(!this.graphStore.hasEdge(e))throw new Error("failed to remove nonexisting edge");this.htmlController.detachEdge(e),this.graphStore.removeEdge(e)}removeNode(e){if(!this.graphStore.hasNode(e))throw new Error("failed to remove nonexisting node");this.htmlController.detachNode(e),this.graphStore.removeNode(e)}patchViewportState(e,t,s){this.viewportTransformer.patchState(e,t,s),this.htmlController.applyTransform()}moveToNodes(e){if(e.length===0)return;const t=e.map(u=>this.graphStore.getNode(u)).filter(u=>u!==void 0);if(t.length<e.length)throw new Error("failed to move to nonexisting node");const[s,r]=t.reduce((u,w)=>[u[0]+w.x,u[1]+w.y],[0,0]),a=s/t.length,c=r/t.length,[h,i]=this.htmlController.getViewportDimensions(),d=this.viewportTransformer.getAbsScale(),g=a-d*h/2,l=c-d*i/2;this.patchViewportState(null,g,l)}updateNodeCoordinates(e,t,s){if(!this.graphStore.hasNode(e))throw new Error("failed to update coordinates of nonexisting node");this.graphStore.updateNodeCoords(e,t,s),this.htmlController.updateNodeCoordinates(e)}updateEdgeController(e,t){if(!this.graphStore.hasEdge(e))throw new Error("failed to update nonexisting edge");this.htmlController.detachEdge(e),this.graphStore.updateEdgeController(e,t),this.htmlController.attachEdge(e)}attach(e){this.htmlController.attach(e)}detach(){this.htmlController.detach()}clear(){this.htmlController.clear(),this.graphStore.clear(),this.nodeIdGenerator.reset(),this.portIdGenerator.reset(),this.edgeIdGenerator.reset()}destroy(){this.htmlController.destroy()}}class K{constructor(e,t,s,r){n(this,"publicViewportTransformer");n(this,"canvasController");const a=new x,c=new _;this.publicViewportTransformer=new q(a);const h=new b(c,a,this.publicViewportTransformer,e,t);this.canvasController=new J(c,h,a,s,r)}}const B=(o,e)=>[o/2,e/2],Q=()=>()=>{},I=(o,e,t,s,r,a)=>{o.clearRect(0,0,o.canvas.width,o.canvas.height),o.fillStyle=a,o.fillRect(0,0,o.canvas.width,o.canvas.height);const c=e.getViewCoords(0,0),h=e.getViewScale(),i=s*h;let d=0,g=0,l=i/2;do l*=2,d=o.canvas.width/l,g=o.canvas.height/l;while(d*g>1e4);const u=c[0]-Math.floor(c[0]/l)*l,w=c[1]-Math.floor(c[1]/l)*l,m=r*h,f=2*Math.PI,C=u-l,E=w-l,y=o.canvas.width+u,T=o.canvas.height+w;o.fillStyle=t;for(let S=C;S<=y;S+=l)for(let $=E;$<=T;$+=l)o.beginPath(),o.arc(S,$,m,0,f),o.closePath(),o.fill()},ee=(o,e,t,s)=>(r,a)=>{I(r,a,o,e,t,s)},te=(o,e)=>{o.fillStyle=e,o.fillRect(0,0,o.canvas.width,o.canvas.height)},se=o=>e=>{te(e,o)},re=o=>{switch(o==null?void 0:o.type){case"custom":return o.drawingFn;case"dots":return ee(o.dotColor??"#d8d8d8",o.dotGap??25,o.dotRadius??1.5,o.color??"#ffffff");case"color":return se(o.color??"#ffffff");default:return Q()}},z=o=>{switch(o==null?void 0:o.type){case"custom":return o.controllerFactory;case"straight":return W({color:o.color??"#5c5c5c",width:o.width??1,arrowLength:o.arrowLength??15,arrowWidth:o.arrowWidth??4,arrowOffset:o.arrowOffset??15,hasSourceArrow:o.hasSourceArrow??!1,hasTargetArrow:o.hasTargetArrow??!1,cycleSquareSide:o.cycleSquareSide??30,roundness:o.roundness??5});default:return R({color:o.color??"#5c5c5c",width:o.width??1,curvature:o.curvature??90,arrowLength:o.arrowLength??15,arrowWidth:o.arrowWidth??4,hasSourceArrow:o.hasSourceArrow??!1,hasTargetArrow:o.hasTargetArrow??!1,cycleRadius:o.cycleRadius??30,smallCycleRadius:o.smallCycleRadius??15})}},oe=o=>{var e,t,s;return{background:{drawingFn:re(o.background??{type:"none"})},nodes:{centerFn:((e=o.nodes)==null?void 0:e.centerFn)??B},ports:{centerFn:((t=o.ports)==null?void 0:t.centerFn)??B},edges:{controllerFactory:z(o.edges??{})},layers:{mode:((s=o.layers)==null?void 0:s.mode)??"edges-follow-node"}}};class G{constructor(e){n(this,"transformation");n(this,"di");n(this,"edgeControllerFactory");this.apiOptions=e;const t=oe(this.apiOptions??{});this.di=new K(t.layers.mode,t.background.drawingFn,t.nodes.centerFn,t.ports.centerFn),this.transformation=this.di.publicViewportTransformer,this.edgeControllerFactory=t.edges.controllerFactory}addNode(e){return this.di.canvasController.addNode(e.id,e.element,e.x,e.y,e.ports,e.centerFn),this}moveNodeOnTop(e){return this.di.canvasController.moveNodeOnTop(e),this}removeNode(e){return this.di.canvasController.removeNode(e),this}markPort(e){return this.di.canvasController.markPort(e.id,e.element,e.nodeId,e.centerFn,e.direction),this}updatePortEdges(e){return this.di.canvasController.updatePortEdges(e),this}unmarkPort(e){return this.di.canvasController.unmarkPort(e),this}addEdge(e){const t=e.options!==void 0?z(e.options):this.edgeControllerFactory;return this.di.canvasController.addEdge(e.id,e.from,e.to,t),this}removeEdge(e){return this.di.canvasController.removeEdge(e),this}patchViewportState(e){return this.di.canvasController.patchViewportState(e.scale??null,e.x??null,e.y??null),this}moveToNodes(e){return this.di.canvasController.moveToNodes(e),this}updateNodeCoordinates(e,t,s){return this.di.canvasController.updateNodeCoordinates(e,t,s),this}updateEdge(e,t){return t.controller!==void 0&&this.di.canvasController.updateEdgeController(e,t.controller),this}clear(){return this.di.canvasController.clear(),this}attach(e){return this.di.canvasController.attach(e),this}detach(){return this.di.canvasController.detach(),this}destroy(){this.di.canvasController.destroy()}}class Y{constructor(e,t){n(this,"transformation");n(this,"nodes",new Map);n(this,"grabbedNodeId",null);n(this,"onNodeDrag");n(this,"onBeforeNodeDrag");n(this,"nodeIdGenerator",new P);n(this,"element",null);n(this,"onCanvasMouseUp",()=>{this.setCursor(null),this.grabbedNodeId=null});n(this,"onCanvasMouseMove",e=>{this.grabbedNodeId!==null&&(e.stopPropagation(),this.dragNode(this.grabbedNodeId,e.movementX,e.movementY))});n(this,"onCanvasTouchStart",e=>{this.previousTouchCoords=[e.touches[0].clientX,e.touches[0].clientY]});n(this,"onCanvasTouchMove",e=>{if(this.grabbedNodeId===null||e.touches.length!==1||this.previousTouchCoords===null)return;e.stopImmediatePropagation();const[t,s]=[e.touches[0].clientX-this.previousTouchCoords[0],e.touches[0].clientY-this.previousTouchCoords[1]];this.dragNode(this.grabbedNodeId,t,s),this.previousTouchCoords=[e.touches[0].clientX,e.touches[0].clientY]});n(this,"onCanvasTouchEnd",e=>{e.touches.length>0?this.previousTouchCoords=[e.touches[0].clientX,e.touches[0].clientY]:(this.previousTouchCoords=null,this.grabbedNodeId=null)});n(this,"previousTouchCoords",null);var a,c;this.canvas=e,this.transformation=this.canvas.transformation;const s=()=>{};this.onNodeDrag=((a=t==null?void 0:t.events)==null?void 0:a.onNodeDrag)??s;const r=()=>!0;this.onBeforeNodeDrag=((c=t==null?void 0:t.events)==null?void 0:c.onBeforeNodeDrag)??r}addNode(e){let t=e.id;if(t===void 0)do t=this.nodeIdGenerator.next();while(this.nodes.has(t));this.canvas.addNode(e);const s=a=>{this.onBeforeNodeDrag({nodeId:t,element:e.element,x:e.x,y:e.y})&&(a.stopImmediatePropagation(),this.grabbedNodeId=t,this.setCursor("grab"),this.canvas.moveNodeOnTop(t))},r=a=>{this.onBeforeNodeDrag({nodeId:t,element:e.element,x:e.x,y:e.y})&&a.touches.length===1&&(this.grabbedNodeId=t,this.canvas.moveNodeOnTop(t))};return this.nodes.set(t,{element:e.element,onMouseDown:s,onTouchStart:r,x:e.x,y:e.y}),e.element.addEventListener("mousedown",s),e.element.addEventListener("touchstart",r),this}removeNode(e){const t=this.nodes.get(e);return t!==void 0&&(t.element.removeEventListener("mousedown",t.onMouseDown),t.element.removeEventListener("touchstart",t.onTouchStart)),this.canvas.removeNode(e),this.nodes.delete(e),this}markPort(e){return this.canvas.markPort(e),this}updatePortEdges(e){return this.canvas.updatePortEdges(e),this}unmarkPort(e){return this.canvas.unmarkPort(e),this}addEdge(e){return this.canvas.addEdge(e),this}removeEdge(e){return this.canvas.removeEdge(e),this}patchViewportState(e){return this.canvas.patchViewportState(e),this}moveToNodes(e){return this.canvas.moveToNodes(e),this}updateNodeCoordinates(e,t,s){return this.canvas.updateNodeCoordinates(e,t,s),this}updateEdge(e,t){return this.canvas.updateEdge(e,t),this}moveNodeOnTop(e){return this.canvas.moveNodeOnTop(e),this}clear(){return this.canvas.clear(),this.nodes.forEach(e=>{e.element.removeEventListener("mousedown",e.onMouseDown),e.element.removeEventListener("touchstart",e.onTouchStart)}),this.nodes.clear(),this}attach(e){return this.detach(),this.element=e,this.canvas.attach(this.element),this.element.addEventListener("mouseup",this.onCanvasMouseUp),this.element.addEventListener("mousemove",this.onCanvasMouseMove),this.element.addEventListener("touchstart",this.onCanvasTouchStart),this.element.addEventListener("touchmove",this.onCanvasTouchMove),this.element.addEventListener("touchend",this.onCanvasTouchEnd),this.element.addEventListener("touchcancel",this.onCanvasTouchEnd),this}detach(){return this.canvas.detach(),this.element!==null&&(this.element.removeEventListener("mouseup",this.onCanvasMouseUp),this.element.removeEventListener("mousemove",this.onCanvasMouseMove),this.element.removeEventListener("touchstart",this.onCanvasTouchStart),this.element.removeEventListener("touchmove",this.onCanvasTouchMove),this.element.removeEventListener("touchend",this.onCanvasTouchEnd),this.element.removeEventListener("touchcancel",this.onCanvasTouchEnd),this.element=null),this}destroy(){this.detach(),this.nodes.forEach(e=>{e.element.removeEventListener("mousedown",e.onMouseDown),e.element.removeEventListener("touchstart",e.onTouchStart)}),this.nodes.clear(),this.canvas.destroy()}setCursor(e){this.element!==null&&(e!==null?this.element.style.cursor=e:this.element.style.removeProperty("cursor"))}dragNode(e,t,s){const r=this.nodes.get(e);if(r===void 0)throw new Error("failed to drag nonexisting node");const[a,c]=this.transformation.getViewCoords(r.x,r.y),h=a+t,i=c+s,[d,g]=this.transformation.getAbsCoords(h,i);r.x=d,r.y=g,this.canvas.updateNodeCoordinates(e,d,g),this.onNodeDrag({nodeId:e,element:r.element,x:r.x,y:r.y})}}class X{constructor(e,t){n(this,"transformation");n(this,"element",null);n(this,"isMoving",!1);n(this,"prevTouches",null);n(this,"onTransform");n(this,"onBeforeTransform");n(this,"isScalable");n(this,"isShiftable");n(this,"minViewScale");n(this,"maxViewScale");n(this,"wheelSensitivity");n(this,"onMouseDown",()=>{this.setCursor("grab"),this.isMoving=!0});n(this,"onMouseMove",e=>{if(!this.isMoving||!this.isShiftable)return;const t=-e.movementX,s=-e.movementY;this.moveViewport(t,s)});n(this,"onMouseUp",()=>{this.setCursor(null),this.isMoving=!1});n(this,"onWheelScroll",e=>{if(this.element===null||this.isScalable===!1)return;e.preventDefault();const{left:t,top:s}=this.element.getBoundingClientRect(),r=e.clientX-t,a=e.clientY-s,h=1/(e.deltaY<0?this.wheelSensitivity:1/this.wheelSensitivity);this.scaleViewport(h,r,a)});n(this,"onTouchStart",e=>{this.prevTouches=this.getAverageTouch(e)});n(this,"onTouchMove",e=>{if(this.prevTouches===null||this.element===null||!this.isShiftable)return;const t=this.getAverageTouch(e);if((t.touchesCnt===1||t.touchesCnt===2)&&this.moveViewport(-(t.x-this.prevTouches.x),-(t.y-this.prevTouches.y)),t.touchesCnt===2&&this.isScalable){const{left:s,top:r}=this.element.getBoundingClientRect(),a=this.prevTouches.x-s,c=this.prevTouches.y-r,i=1/(t.scale/this.prevTouches.scale);this.scaleViewport(i,a,c)}this.prevTouches=t,e.preventDefault()});n(this,"onTouchEnd",e=>{e.touches.length>0?this.prevTouches=this.getAverageTouch(e):this.prevTouches=null});var i,d,g,l,u,w,m,f,C,E,y,T;this.canvas=e,this.options=t,this.transformation=this.canvas.transformation;const s=((d=(i=this.options)==null?void 0:i.scale)==null?void 0:d.min)??null,r=((l=(g=this.options)==null?void 0:g.scale)==null?void 0:l.max)??null;this.isScalable=((w=(u=this.options)==null?void 0:u.scale)==null?void 0:w.enabled)!==!1,this.minViewScale=r!==null?1/r:null,this.maxViewScale=s!==null?1/s:null,this.isShiftable=((f=(m=this.options)==null?void 0:m.shift)==null?void 0:f.enabled)!==!1;const a=(E=(C=this.options)==null?void 0:C.scale)==null?void 0:E.wheelSensitivity;this.wheelSensitivity=a!==void 0?a:1.2;const c=()=>{};this.onTransform=((y=t==null?void 0:t.events)==null?void 0:y.onTransform)??c;const h=()=>!0;this.onBeforeTransform=((T=t==null?void 0:t.events)==null?void 0:T.onBeforeTransform)??h}addNode(e){return this.canvas.addNode(e),this}removeNode(e){return this.canvas.removeNode(e),this}markPort(e){return this.canvas.markPort(e),this}updatePortEdges(e){return this.canvas.updatePortEdges(e),this}unmarkPort(e){return this.canvas.unmarkPort(e),this}addEdge(e){return this.canvas.addEdge(e),this}removeEdge(e){return this.canvas.removeEdge(e),this}patchViewportState(e){return this.canvas.patchViewportState(e),this}moveToNodes(e){return this.canvas.moveToNodes(e),this}updateNodeCoordinates(e,t,s){return this.canvas.updateNodeCoordinates(e,t,s),this}updateEdge(e,t){return this.canvas.updateEdge(e,t),this}moveNodeOnTop(e){return this.canvas.moveNodeOnTop(e),this}clear(){return this.canvas.clear(),this}attach(e){return this.detach(),this.element=e,this.canvas.attach(this.element),this.element.addEventListener("mousedown",this.onMouseDown),this.element.addEventListener("mousemove",this.onMouseMove),this.element.addEventListener("mouseup",this.onMouseUp),this.element.addEventListener("wheel",this.onWheelScroll),this.element.addEventListener("touchstart",this.onTouchStart),this.element.addEventListener("touchmove",this.onTouchMove),this.element.addEventListener("touchend",this.onTouchEnd),this.element.addEventListener("touchcancel",this.onTouchEnd),this}detach(){return this.canvas.detach(),this.element!==null&&(this.element.removeEventListener("mousedown",this.onMouseDown),this.element.removeEventListener("mousemove",this.onMouseMove),this.element.removeEventListener("mouseup",this.onMouseUp),this.element.removeEventListener("wheel",this.onWheelScroll),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd),this.element.removeEventListener("touchcancel",this.onTouchEnd),this.element=null),this}destroy(){this.detach(),this.canvas.destroy()}getAverageTouch(e){const t=[],s=e.touches.length;for(let i=0;i<s;i++)t.push([e.touches[i].clientX,e.touches[i].clientY]);const r=t.reduce((i,d)=>[i[0]+d[0],i[1]+d[1]],[0,0]),a=[r[0]/s,r[1]/s],h=t.map(i=>[i[0]-a[0],i[1]-a[1]]).reduce((i,d)=>i+Math.sqrt(d[0]*d[0]+d[1]*d[1]),0);return{x:a[0],y:a[1],scale:h/s,touchesCnt:s}}setCursor(e){this.element!==null&&(e!==null?this.element.style.cursor=e:this.element.style.removeProperty("cursor"))}moveViewport(e,t){const[s,r]=this.transformation.getAbsCoords(0,0),a=this.canvas.transformation.getAbsScale(),c={scale:a,x:s+a*e,y:r+a*t};this.onBeforeTransform({...c})&&(this.canvas.patchViewportState(c),this.onTransform(c))}scaleViewport(e,t,s){const[r,a]=this.canvas.transformation.getAbsCoords(0,0),c=this.canvas.transformation.getAbsScale(),h=c*e,i=c*(1-e)*t+r,d=c*(1-e)*s+a;if(this.maxViewScale!==null&&h>this.maxViewScale&&h>c||this.minViewScale!==null&&h<this.minViewScale&&h<c)return;const g={scale:h,x:i,y:d};this.onBeforeTransform({...g})&&(this.canvas.patchViewportState(g),this.onTransform(g))}}class ne{constructor(){n(this,"coreOptions");n(this,"dragOptions");n(this,"transformOptions");n(this,"isDraggable",!1);n(this,"isTransformable",!1)}setOptions(e){return this.coreOptions=e,this}setUserDraggableNodes(e){return this.isDraggable=!0,this.dragOptions=e,this}setUserTransformableCanvas(e){return this.isTransformable=!0,this.transformOptions=e,this}build(){let e=new G(this.coreOptions);return this.isDraggable&&(e=new Y(e,this.dragOptions)),this.isTransformable&&(e=new X(e,this.transformOptions)),e}}v.BezierEdgeController=D,v.CanvasCore=G,v.CycleCircleEdgeController=k,v.CycleSquareEdgeController=j,v.EdgeType=M,v.EdgeUtils=p,v.HtmlGraphBuilder=ne,v.StraightEdgeController=F,v.UserDraggableNodesCanvas=Y,v.UserTransformableCanvas=X,v.createBezierEdgeControllerFactory=R,v.createStraightEdgeControllerFactory=W,Object.defineProperty(v,Symbol.toStringTag,{value:"Module"})});
|
|
1
|
+
(function(C,$){typeof exports=="object"&&typeof module<"u"?$(exports):typeof define=="function"&&define.amd?define(["exports"],$):(C=typeof globalThis<"u"?globalThis:C||self,$(C.HTMLGraph={}))})(this,function(C){"use strict";var yt=Object.defineProperty;var At=(C,$,O)=>$ in C?yt(C,$,{enumerable:!0,configurable:!0,writable:!0,value:O}):C[$]=O;var a=(C,$,O)=>At(C,typeof $!="symbol"?$+"":$,O);const $=()=>{const e=document.createElement("div");return e.style.width="100%",e.style.height="100%",e.style.position="relative",e.style.overflow="hidden",e},O=()=>{const e=document.createElement("canvas");return e.style.position="absolute",e.style.inset="0",e},F=()=>{const e=document.createElement("div");return e.style.position="absolute",e.style.top="0",e.style.left="0",e.style.width="0",e.style.height="0",e};class et{constructor(t){a(this,"nodesContainer",F());a(this,"edgesContainer",F());this.host=t,this.host.appendChild(this.edgesContainer),this.host.appendChild(this.nodesContainer)}appendNodeElement(t){this.nodesContainer.appendChild(t)}removeNodeElement(t){this.nodesContainer.removeChild(t)}appendEdgeElement(t){this.edgesContainer.appendChild(t)}removeEdgeElement(t){this.edgesContainer.removeChild(t)}update(t,r,s){this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${r}, ${s})`,this.edgesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${r}, ${s})`}destroy(){this.host.removeChild(this.nodesContainer),this.host.removeChild(this.edgesContainer)}}class rt{constructor(t){a(this,"nodesContainer",F());a(this,"edgesContainer",F());this.host=t,this.host.appendChild(this.nodesContainer),this.host.appendChild(this.edgesContainer)}appendNodeElement(t){this.nodesContainer.appendChild(t)}removeNodeElement(t){this.nodesContainer.removeChild(t)}appendEdgeElement(t){this.edgesContainer.appendChild(t)}removeEdgeElement(t){this.edgesContainer.removeChild(t)}update(t,r,s){this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${r}, ${s})`,this.edgesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${r}, ${s})`}destroy(){this.host.removeChild(this.nodesContainer),this.host.removeChild(this.edgesContainer)}}class st{constructor(t){a(this,"container",F());this.host=t,this.host.appendChild(this.container)}appendNodeElement(t){this.container.appendChild(t)}removeNodeElement(t){this.container.removeChild(t)}appendEdgeElement(t){this.container.appendChild(t)}removeEdgeElement(t){this.container.removeChild(t)}update(t,r,s){this.container.style.transform=`matrix(${t}, 0, 0, ${t}, ${r}, ${s})`}destroy(){this.host.removeChild(this.container)}}const ot={"edges-on-top":e=>new rt(e),"edges-follow-node":e=>new st(e),"nodes-on-top":e=>new et(e)};class it{constructor(t,r,s,o,n){a(this,"canvasWrapper",null);a(this,"host",$());a(this,"canvas",O());a(this,"canvasCtx");a(this,"hostResizeObserver");a(this,"nodesResizeObserver");a(this,"nodeElementToIdMap",new Map);a(this,"nodeWrapperElementToIdMap",new Map);a(this,"nodeIdToWrapperElementMap",new Map);a(this,"edgeIdToElementMap",new Map);a(this,"layer");this.graphStore=t,this.viewportTransformer=r,this.publicViewportTransformer=s,this.layersMode=o,this.backgroundDrawingFn=n;const i=this.canvas.getContext("2d");if(i===null)throw new Error("unable to get canvas context");this.canvasCtx=i,this.host.appendChild(this.canvas),this.layer=ot[this.layersMode](this.host),this.hostResizeObserver=this.createHostResizeObserver(),this.hostResizeObserver.observe(this.host),this.nodesResizeObserver=this.createNodesResizeObserver()}clear(){Array.from(this.edgeIdToElementMap.keys()).forEach(t=>{this.detachEdge(t)}),Array.from(this.nodeElementToIdMap.values()).forEach(t=>{this.detachNode(t)})}attach(t){this.detach(),this.canvasWrapper=t,this.canvasWrapper.appendChild(this.host)}detach(){this.canvasWrapper!==null&&(this.canvasWrapper.removeChild(this.host),this.canvasWrapper=null)}destroy(){this.hostResizeObserver.disconnect(),this.nodesResizeObserver.disconnect(),this.host.removeChild(this.canvas),this.layer.destroy(),this.detach()}applyTransform(){this.backgroundDrawingFn(this.canvasCtx,this.publicViewportTransformer);const[t,r]=this.viewportTransformer.getViewCoords(0,0),s=this.viewportTransformer.getViewScale();this.layer.update(s,t,r)}attachNode(t){const r=this.graphStore.getNode(t),s=document.createElement("div");s.appendChild(r.element),s.style.position="absolute",s.style.top="0",s.style.left="0",s.style.visibility="hidden",this.layer.appendNodeElement(s),this.nodeElementToIdMap.set(r.element,t),this.nodeWrapperElementToIdMap.set(s,t),this.nodeIdToWrapperElementMap.set(t,s),this.updateNodeCoords(t),this.updateNodePriority(t),this.nodesResizeObserver.observe(s),s.style.visibility="visible"}detachNode(t){const r=this.graphStore.getNode(t);this.nodesResizeObserver.unobserve(r.element);const s=this.nodeIdToWrapperElementMap.get(t);s.removeChild(r.element),this.layer.removeNodeElement(s),this.nodeElementToIdMap.delete(r.element),this.nodeWrapperElementToIdMap.delete(s),this.nodeIdToWrapperElementMap.delete(t)}attachEdge(t){const s=this.graphStore.getEdge(t).controller.svg;s.style.position="absolute",s.style.top="0",s.style.left="0",this.edgeIdToElementMap.set(t,s),this.updateEdgeCoords(t),this.updateEdgePriority(t),this.layer.appendEdgeElement(s)}detachEdge(t){const r=this.edgeIdToElementMap.get(t);this.edgeIdToElementMap.delete(t),this.layer.removeEdgeElement(r)}updateNodePriority(t){const r=this.graphStore.getNode(t),s=this.nodeIdToWrapperElementMap.get(t);s.style.zIndex=`${r.priority}`}updateEdgePriority(t){const r=this.graphStore.getEdge(t);this.edgeIdToElementMap.get(t).style.zIndex=`${r.priority}`}updateNodeCoordinates(t){const r=this.graphStore.getNodeAdjacentEdges(t);this.updateNodeCoords(t),r.forEach(s=>{this.updateEdgeCoords(s)})}updatePortEdges(t){this.graphStore.getPortAdjacentEdges(t).forEach(s=>{this.updateEdgeCoords(s)})}getViewportDimensions(){const t=this.host.getBoundingClientRect();return[t.width,t.height]}createHostResizeObserver(){return new ResizeObserver(()=>{this.updateCanvasDimensions(),this.applyTransform()})}createNodesResizeObserver(){return new ResizeObserver(t=>{t.forEach(r=>{const s=r.target,o=this.nodeWrapperElementToIdMap.get(s);this.updateNodeCoords(o),this.graphStore.getNodeAdjacentEdges(o).forEach(i=>{this.updateEdgeCoords(i)})})})}updateCanvasDimensions(){const{width:t,height:r}=this.host.getBoundingClientRect();this.canvas.width=t,this.canvas.height=r}updateNodeCoords(t){const r=this.nodeIdToWrapperElementMap.get(t),{width:s,height:o}=r.getBoundingClientRect(),n=this.viewportTransformer.getAbsScale(),i=this.graphStore.getNode(t),[h,c]=i.centerFn(s,o);r.style.transform=`matrix(1, 0, 0, 1, ${i.x-n*h}, ${i.y-n*c})`}updateEdgeCoords(t){const r=this.graphStore.getEdge(t),s=this.graphStore.getPort(r.from),o=this.graphStore.getPort(r.to),n=s.element.getBoundingClientRect(),i=o.element.getBoundingClientRect(),h=this.host.getBoundingClientRect(),[c,l]=this.viewportTransformer.getAbsCoords(n.left-h.left,n.top-h.top),[d,g]=this.viewportTransformer.getAbsCoords(i.left-h.left,i.top-h.top),u=this.viewportTransformer.getAbsScale(),[v,w]=s.centerFn(n.width*u,n.height*u),[f,m]=o.centerFn(i.width*u,i.height*u),E=v+c,p=w+l,y=f+d,b=m+g,S=Math.min(E,y),M=Math.min(p,b),D=Math.abs(y-E),V=Math.abs(b-p);r.controller.update(S,M,D,V,s,o)}}class nt{constructor(){a(this,"state",{scale:1,x:0,y:0})}getViewCoords(t,r){return[(t-this.state.x)/this.state.scale,(r-this.state.y)/this.state.scale]}getViewScale(){return 1/this.state.scale}getAbsCoords(t,r){return[t*this.state.scale+this.state.x,r*this.state.scale+this.state.y]}getAbsScale(){return this.state.scale}patchState(t,r,s){this.state={scale:t??this.state.scale,x:r??this.state.x,y:s??this.state.y}}}class at{constructor(t){this.transformer=t}getViewCoords(t,r){return this.transformer.getViewCoords(t,r)}getViewScale(){return this.transformer.getViewScale()}getAbsCoords(t,r){return this.transformer.getAbsCoords(t,r)}getAbsScale(){return this.transformer.getAbsScale()}}class ht{constructor(){a(this,"nodes",new Map);a(this,"ports",new Map);a(this,"nodePorts",new Map);a(this,"portNodeId",new Map);a(this,"edges",new Map);a(this,"incommingEdges",new Map);a(this,"outcommingEdges",new Map);a(this,"cycleEdges",new Map)}addNode(t,r,s,o,n,i){this.nodes.set(t,{element:r,x:s,y:o,centerFn:n,priority:i}),this.nodePorts.set(t,new Map)}getNode(t){return this.nodes.get(t)}removeNode(t){this.getNodeAdjacentEdges(t).forEach(o=>{this.removeEdge(o)}),this.nodes.delete(t),this.nodePorts.get(t).forEach((o,n)=>{this.portNodeId.delete(n)}),this.nodePorts.delete(t)}addPort(t,r,s,o,n){this.ports.set(t,{element:r,centerFn:o,direction:n}),this.cycleEdges.set(t,new Set),this.incommingEdges.set(t,new Set),this.outcommingEdges.set(t,new Set),this.portNodeId.set(t,s),this.nodePorts.get(s).set(t,r)}getPort(t){return this.ports.get(t)}getPortNode(t){return this.portNodeId.get(t)}removePort(t){this.cycleEdges.get(t).forEach(s=>{this.removeEdge(s)}),this.cycleEdges.delete(t),this.incommingEdges.get(t).forEach(s=>{this.removeEdge(s)}),this.incommingEdges.delete(t),this.outcommingEdges.get(t).forEach(s=>{this.removeEdge(s)}),this.outcommingEdges.get(t);const r=this.portNodeId.get(t);this.portNodeId.delete(t),this.nodePorts.get(r).delete(t),this.ports.delete(t)}addEdge(t,r,s,o,n){this.edges.set(t,{from:r,to:s,controller:o,priority:n}),r!==s?(this.outcommingEdges.get(r).add(t),this.incommingEdges.get(s).add(t)):this.cycleEdges.get(r).add(t)}getEdge(t){return this.edges.get(t)}removeEdge(t){const r=this.edges.get(t),s=r.from,o=r.to;this.cycleEdges.get(s).delete(t),this.cycleEdges.get(o).delete(t),this.incommingEdges.get(s).delete(t),this.incommingEdges.get(o).delete(t),this.outcommingEdges.get(s).delete(t),this.outcommingEdges.get(o).delete(t),this.edges.delete(t)}getPortAdjacentEdges(t){return[...this.getPortIncomingEdges(t),...this.getPortOutcomingEdges(t),...this.getPortCycleEdges(t)]}getNodeAdjacentEdges(t){return[...this.getNodeIncomingEdges(t),...this.getNodeOutcomingEdges(t),...this.getNodeCycleEdges(t)]}clear(){this.nodes.clear(),this.ports.clear(),this.nodePorts.clear(),this.portNodeId.clear(),this.edges.clear(),this.incommingEdges.clear(),this.outcommingEdges.clear(),this.cycleEdges.clear()}getPortIncomingEdges(t){return Array.from(this.incommingEdges.get(t))}getPortOutcomingEdges(t){return Array.from(this.outcommingEdges.get(t))}getPortCycleEdges(t){return Array.from(this.cycleEdges.get(t))}getNodeIncomingEdges(t){const r=Array.from(this.nodePorts.get(t).keys());let s=[];return r.forEach(o=>{s=[...s,...this.getPortIncomingEdges(o)]}),s}getNodeOutcomingEdges(t){const r=Array.from(this.nodePorts.get(t).keys());let s=[];return r.forEach(o=>{s=[...s,...this.getPortOutcomingEdges(o)]}),s}getNodeCycleEdges(t){const r=Array.from(this.nodePorts.get(t).keys());let s=[];return r.forEach(o=>{s=[...s,...this.getPortCycleEdges(o)]}),s}}const L=e=>{const{top:t,left:r,width:s,height:o}=e.element.getBoundingClientRect(),n=e.centerFn(s,o);return[r+n[0],t+n[1]]},A=(e,t,r)=>[t[0]*e[0]-t[1]*e[1]+((1-t[0])*r[0]+t[1]*r[1]),t[1]*e[0]+t[0]*e[1]+((1-t[0])*r[1]-t[1]*r[0])],N=(e,t,r)=>[t*Math.cos(e),r*Math.sin(e)],T=(e,t,r,s,o)=>{const i=[[0,0],[s,o],[s,-o]].map(d=>A(d,e,[0,0])).map(d=>[d[0]+t,d[1]+r]),h=`M ${i[0][0]} ${i[0][1]}`,c=`L ${i[1][0]} ${i[1][1]}`,l=`L ${i[2][0]} ${i[2][1]}`;return`${h} ${c} ${l}`};class z{constructor(t,r,s,o,n,i,h){a(this,"svg");a(this,"group");a(this,"line");a(this,"sourceArrow",null);a(this,"targetArrow",null);this.color=t,this.width=r,this.curvature=s,this.arrowLength=o,this.arrowWidth=n,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",i&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),h&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,r,s,o,n,i){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const h=L(n),c=L(i),l=h[0]<=c[0]?1:-1,d=h[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${r}px)`,this.group.style.transform=`scale(${l}, ${d})`;const g=N(n.direction,l,d),u=N(i.direction,l,d),v=A([this.arrowLength,0],g,[0,0]),w=A([s-this.arrowLength,o],u,[s,o]),f=[v[0]+g[0]*this.curvature,v[1]+g[1]*this.curvature],m=[w[0]-u[0]*this.curvature,w[1]-u[1]*this.curvature],E=`M ${v[0]} ${v[1]} C ${f[0]} ${f[1]}, ${m[0]} ${m[1]}, ${w[0]} ${w[1]}`,p=this.sourceArrow?"":`M 0 0 L ${v[0]} ${v[1]} `,y=this.targetArrow?"":` M ${w[0]} ${w[1]} L ${s} ${o}`,b=`${p}${E}${y}`;if(this.line.setAttribute("d",b),this.sourceArrow){const S=T(g,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",S)}if(this.targetArrow){const S=T(u,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",S)}}}const W=(e,t)=>{const r=[];if(e.length>0&&r.push(`M ${e[0][0]} ${e[0][1]}`),e.length===2&&r.push(`L ${e[1][0]} ${e[1][1]}`),e.length>2){const s=e.length-1;let o=0,n=0,i=0;e.forEach((h,c)=>{let l=0,d=0,g=0;const u=c>0,v=c<s,w=u&&v;if(u&&(l=-o,d=-n,g=i),v){const S=e[c+1];o=S[0]-h[0],n=S[1]-h[1],i=Math.sqrt(o*o+n*n)}const m=Math.min((w?t:0)/i,c<s-1?.5:1),E=w?[h[0]+o*m,h[1]+n*m]:h,y=Math.min((w?t:0)/g,c>1?.5:1),b=w?[h[0]+l*y,h[1]+d*y]:h;c>0&&r.push(`L ${b[0]} ${b[1]}`),w&&r.push(`C ${h[0]} ${h[1]} ${h[0]} ${h[1]} ${E[0]} ${E[1]}`)})}return r.join(" ")};class X{constructor(t,r,s,o,n,i,h,c){a(this,"svg");a(this,"group");a(this,"line");a(this,"sourceArrow",null);a(this,"targetArrow",null);this.color=t,this.width=r,this.arrowLength=s,this.arrowWidth=o,this.arrowOffset=n,this.roundness=c,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",i&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),h&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,r,s,o,n,i){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const h=L(n),c=L(i),l=h[0]<=c[0]?1:-1,d=h[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${r}px)`,this.group.style.transform=`scale(${l}, ${d})`;const g=N(n.direction,l,d),u=N(i.direction,l,d),v=this.sourceArrow?A([this.arrowLength,0],g,[0,0]):[0,0],w=this.targetArrow?A([s-this.arrowLength,o],u,[s,o]):[s,o],f=this.arrowLength+this.arrowOffset,m=A([f,0],g,[0,0]),E=A([s-f,o],u,[s,o]),p=W([v,m,E,w],this.roundness);if(this.line.setAttribute("d",p),this.sourceArrow){const y=T(g,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",y)}if(this.targetArrow){const y=T(u,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",y)}}}class G{constructor(t,r,s,o,n,i,h,c){a(this,"svg");a(this,"group");a(this,"line");a(this,"sourceArrow",null);a(this,"targetArrow",null);this.color=t,this.width=r,this.arrowLength=s,this.arrowWidth=o,this.arrowOffset=n,this.roundness=c,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",i&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),h&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,r,s,o,n,i){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const h=L(n),c=L(i),l=h[0]<=c[0]?1:-1,d=h[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${r}px)`,this.group.style.transform=`scale(${l}, ${d})`;const g=N(n.direction,l,d),u=N(i.direction,l,d),v=this.sourceArrow?A([this.arrowLength,0],g,[0,0]):[0,0],w=this.targetArrow?A([s-this.arrowLength,o],u,[s,o]):[s,o],f=this.arrowLength+this.arrowOffset,m=A([f,0],g,[0,0]),E=A([s-f,o],u,[s,o]),p=Math.max((m[0]+E[0])/2,f),y=o/2,b=[l>0?p:-f,m[1]],S=[b[0],y],M=[l>0?s-p:s+f,E[1]],D=[M[0],y],V=W([v,m,b,S,D,M,E,w],this.roundness);if(this.line.setAttribute("d",V),this.sourceArrow){const x=T(g,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",x)}if(this.targetArrow){const x=T(u,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",x)}}}class j{constructor(t,r,s,o,n,i,h,c){a(this,"svg");a(this,"group");a(this,"line");a(this,"sourceArrow",null);a(this,"targetArrow",null);this.color=t,this.width=r,this.arrowLength=s,this.arrowWidth=o,this.arrowOffset=n,this.roundness=c,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",i&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),h&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,r,s,o,n,i){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const h=L(n),c=L(i),l=h[0]<=c[0]?1:-1,d=h[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${r}px)`,this.group.style.transform=`scale(${l}, ${d})`;const g=N(n.direction,l,d),u=N(i.direction,l,d),v=this.sourceArrow?A([this.arrowLength,0],g,[0,0]):[0,0],w=this.targetArrow?A([s-this.arrowLength,o],u,[s,o]):[s,o],f=this.arrowLength+this.arrowOffset,m=A([f,0],g,[0,0]),E=A([s-f,o],u,[s,o]),p=Math.max((m[1]+E[1])/2,f),y=s/2,b=[m[0],d>0?p:-f],S=[y,b[1]],M=[E[0],d>0?o-p:o+f],D=[y,M[1]],V=W([v,m,b,S,D,M,E,w],this.roundness);if(this.line.setAttribute("d",V),this.sourceArrow){const x=T(g,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",x)}if(this.targetArrow){const x=T(u,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",x)}}}class H{constructor(t,r,s,o,n,i,h){a(this,"svg");a(this,"group");a(this,"line");a(this,"arrow",null);this.color=t,this.width=r,this.arrowLength=s,this.arrowWidth=o,this.radius=i,this.smallRadius=h,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",n&&(this.arrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.arrow.setAttribute("fill",this.color),this.group.appendChild(this.arrow)),this.svg.style.overflow="visible",this.svg.style.width="0px",this.svg.style.height="0px"}update(t,r,s,o,n){this.svg.style.transform=`translate(${t}px, ${r}px)`;const i=N(n.direction,1,1),h=this.smallRadius,c=this.radius,l=Math.sqrt(h*h+c*c),d=h+c,g=this.arrowLength+l*(1-c/d),u=h*c/d,w=[[this.arrowLength,0],[g,u],[g,-u]].map(p=>A(p,i,[0,0])),f=[`M ${w[0][0]} ${w[0][1]}`,`A ${h} ${h} 0 0 1 ${w[1][0]} ${w[1][1]}`,`A ${c} ${c} 0 1 0 ${w[2][0]} ${w[2][1]}`,`A ${h} ${h} 0 0 1 ${w[0][0]} ${w[0][1]}`].join(" "),m=`M 0 0 L ${w[0][0]} ${w[0][1]} `,E=`${this.arrow!==null?"":m}${f}`;if(this.line.setAttribute("d",E),this.arrow){const p=T(i,0,0,this.arrowLength,this.arrowWidth);this.arrow.setAttribute("d",p)}}}class k{constructor(t,r,s,o,n,i,h,c){a(this,"svg");a(this,"group");a(this,"line");a(this,"arrow",null);a(this,"roundness");a(this,"linePoints");this.color=t,this.width=r,this.arrowLength=s,this.arrowWidth=o,this.side=i,this.minPortOffset=h,this.roundness=Math.min(c,this.minPortOffset,this.side/2),this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",n&&(this.arrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.arrow.setAttribute("fill",this.color),this.group.appendChild(this.arrow)),this.svg.style.overflow="visible",this.svg.style.width="0px",this.svg.style.height="0px";const l=this.minPortOffset,d=this.side,g=this.arrowLength+l,u=this.roundness,v=g+2*d;console.log(u),this.linePoints=[[this.arrowLength,0],[g,0],[g,this.side],[v,this.side],[v,-this.side],[g,-this.side],[g,0],[this.arrowLength,0]]}update(t,r,s,o,n){this.svg.style.transform=`translate(${t}px, ${r}px)`;const i=N(n.direction,1,1),h=this.linePoints.map(d=>A(d,i,[0,0])),c=`M 0 0 L ${h[0][0]} ${h[0][1]} `,l=`${this.arrow?"":c}${W(h,this.roundness)}`;if(this.line.setAttribute("d",l),this.arrow){const d=T(i,0,0,this.arrowLength,this.arrowWidth);this.arrow.setAttribute("d",d)}}}class R{constructor(t,r,s,o,n,i,h,c,l,d){a(this,"svg");a(this,"group");a(this,"line");a(this,"sourceArrow",null);a(this,"targetArrow",null);a(this,"detourX");a(this,"detourY");this.color=t,this.width=r,this.arrowLength=s,this.arrowWidth=o,this.arrowOffset=n,this.roundness=c,this.detourX=Math.cos(d)*l,this.detourY=Math.sin(d)*l,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",i&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),h&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,r,s,o,n,i){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const h=L(n),c=L(i),l=h[0]<=c[0]?1:-1,d=h[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${r}px)`,this.group.style.transform=`scale(${l}, ${d})`;const g=N(n.direction,l,d),u=N(i.direction,l,d),v=this.sourceArrow?A([this.arrowLength,0],g,[0,0]):[0,0],w=this.targetArrow?A([s-this.arrowLength,o],u,[s,o]):[s,o],f=this.arrowLength+this.arrowOffset,m=A([f,0],g,[0,0]),E=[m[0]+this.detourX,m[1]+this.detourY],p=A([s-f,o],u,[s,o]),y=[p[0]+this.detourX,p[1]+this.detourY],b=W([v,m,E,y,p,w],this.roundness);if(this.line.setAttribute("d",b),this.sourceArrow){const S=T(g,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",S)}if(this.targetArrow){const S=T(u,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",S)}}}var P=(e=>(e.Regular="regular",e.PortCycle="port-cycle",e.NodeCycle="node-cycle",e))(P||{});class ct{constructor(t,r,s,o,n,i,h,c,l){a(this,"svg");a(this,"group");a(this,"line");a(this,"sourceArrow",null);a(this,"targetArrow",null);a(this,"detourX");a(this,"detourY");this.color=t,this.width=r,this.curvature=s,this.arrowLength=o,this.arrowWidth=n,this.detourX=Math.cos(l)*c,this.detourY=Math.sin(l)*c,this.svg=document.createElementNS("http://www.w3.org/2000/svg","svg"),this.svg.style.pointerEvents="none",this.group=document.createElementNS("http://www.w3.org/2000/svg","g"),this.svg.appendChild(this.group),this.line=document.createElementNS("http://www.w3.org/2000/svg","path"),this.line.setAttribute("stroke",this.color),this.line.setAttribute("stroke-width",`${this.width}`),this.line.setAttribute("fill","none"),this.group.appendChild(this.line),this.group.style.transformOrigin="50% 50%",i&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),h&&(this.targetArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.targetArrow.setAttribute("fill",this.color),this.group.appendChild(this.targetArrow)),this.svg.style.overflow="visible"}update(t,r,s,o,n,i){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const h=L(n),c=L(i),l=h[0]<=c[0]?1:-1,d=h[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${r}px)`,this.group.style.transform=`scale(${l}, ${d})`;const g=N(n.direction,l,d),u=N(i.direction,l,d),v=this.sourceArrow?A([this.arrowLength,0],g,[0,0]):[0,0],w=this.targetArrow?A([s-this.arrowLength,o],u,[s,o]):[s,o],f=this.arrowLength,m=A([f,0],g,[0,0]),E=[m[0]+this.detourX,m[1]+this.detourY],p=A([s-f,o],u,[s,o]),y=[p[0]+this.detourX,p[1]+this.detourY],b=[(E[0]+y[0])/2,(E[1]+y[1])/2],S=[m[0]-this.curvature*Math.cos(n.direction),m[1]-this.curvature*Math.sin(n.direction)],M=[p[0]+this.curvature*Math.cos(i.direction),p[1]+this.curvature*Math.sin(i.direction)],D=[m[0]+this.detourX,m[1]+this.detourY],V=[p[0]+this.detourX,p[1]+this.detourY],x=[`M ${v[0]} ${v[1]}`,`L ${m[0]} ${m[1]}`,`C ${S[0]} ${S[1]} ${D[0]} ${D[1]} ${b[0]} ${b[1]}`,`C ${V[0]} ${V[1]} ${M[0]} ${M[1]} ${p[0]} ${p[1]}`,`L ${w[0]} ${w[1]}`].join(" ");if(this.line.setAttribute("d",x),this.sourceArrow){const Y=T(g,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",Y)}if(this.targetArrow){const Y=T(u,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",Y)}}}const U=e=>t=>t===P.PortCycle?new H(e.color,e.width,e.arrowLength,e.arrowWidth,e.hasSourceArrow||e.hasTargetArrow,e.cycleRadius,e.smallCycleRadius):t===P.NodeCycle?new ct(e.color,e.width,e.curvature,e.arrowLength,e.arrowWidth,e.hasSourceArrow,e.hasTargetArrow,e.detourDistance,e.detourDirection):new z(e.color,e.width,e.curvature,e.arrowLength,e.arrowWidth,e.hasSourceArrow,e.hasTargetArrow),_=e=>t=>t===P.PortCycle?new k(e.color,e.width,e.arrowLength,e.arrowWidth,e.hasSourceArrow||e.hasTargetArrow,e.cycleSquareSide,e.arrowOffset,e.roundness):t===P.NodeCycle?new R(e.color,e.width,e.arrowLength,e.arrowWidth,e.arrowOffset,e.hasSourceArrow,e.hasTargetArrow,e.roundness,e.detourDistance,e.detourDirection):new X(e.color,e.width,e.arrowLength,e.arrowWidth,e.arrowOffset,e.hasSourceArrow,e.hasTargetArrow,e.roundness),J=e=>t=>t===P.PortCycle?new k(e.color,e.width,e.arrowLength,e.arrowWidth,e.hasSourceArrow||e.hasTargetArrow,e.cycleSquareSide,e.arrowOffset,e.roundness):t===P.NodeCycle?new R(e.color,e.width,e.arrowLength,e.arrowWidth,e.arrowOffset,e.hasSourceArrow,e.hasTargetArrow,e.roundness,e.detourDistance,e.detourDirection):new G(e.color,e.width,e.arrowLength,e.arrowWidth,e.arrowOffset,e.hasSourceArrow,e.hasTargetArrow,e.roundness),K=e=>t=>t===P.PortCycle?new k(e.color,e.width,e.arrowLength,e.arrowWidth,e.hasSourceArrow||e.hasTargetArrow,e.cycleSquareSide,e.arrowOffset,e.roundness):t===P.NodeCycle?new R(e.color,e.width,e.arrowLength,e.arrowWidth,e.arrowOffset,e.hasSourceArrow,e.hasTargetArrow,e.roundness,e.detourDistance,e.detourDirection):new j(e.color,e.width,e.arrowLength,e.arrowWidth,e.arrowOffset,e.hasSourceArrow,e.hasTargetArrow,e.roundness);class B{constructor(){a(this,"counter",0)}create(){const t=`${this.counter}`;return this.counter++,t}reset(){this.counter=0}}class lt{constructor(){a(this,"priority",0)}create(){const t=this.priority;return this.priority++,t}push(t){this.priority=Math.max(this.priority,t)}reset(){this.priority=0}}class dt{constructor(t,r,s,o,n,i){a(this,"nodeIdGenerator",new B);a(this,"portIdGenerator",new B);a(this,"edgeIdGenerator",new B);a(this,"priorityGenerator",new lt);this.graphStore=t,this.htmlController=r,this.viewportTransformer=s,this.nodesCenterFn=o,this.portsCenterFn=n,this.portsDirection=i}moveNodeOnTop(t){const r=this.graphStore.getNode(t);if(r===void 0)throw new Error("failed to move on top nonexisting node");const s=this.priorityGenerator.create(),o=this.priorityGenerator.create();r.priority=o,this.htmlController.updateNodePriority(t),this.graphStore.getNodeAdjacentEdges(t).forEach(i=>{const h=this.graphStore.getEdge(i);h.priority=s,this.htmlController.updateEdgePriority(i)})}addNode(t,r,s,o,n,i,h){if(t===void 0)do t=this.nodeIdGenerator.create();while(this.graphStore.getNode(t)!==void 0);if(this.graphStore.getNode(t)!==void 0)throw new Error("failed to add node with existing id");h!==void 0&&this.priorityGenerator.push(h),this.graphStore.addNode(t,r,s,o,i??this.nodesCenterFn,h??this.priorityGenerator.create()),this.htmlController.attachNode(t),n!==void 0&&n.forEach((c,l)=>{c instanceof HTMLElement?this.markPort(l,c,t,this.portsCenterFn,this.portsDirection):this.markPort(l,c.element,t,c.centerFn??this.portsCenterFn,c.direction??this.portsDirection)})}updateNode(t,r,s,o,n){const i=this.graphStore.getNode(t);if(i===void 0)throw new Error("failed to update nonexisting node");i.x=r??i.x,i.y=s??i.y,i.centerFn=n??i.centerFn,this.htmlController.updateNodeCoordinates(t),o!==void 0&&(i.priority=o,this.htmlController.updateNodePriority(t))}markPort(t,r,s,o,n){if(t===void 0)do t=this.portIdGenerator.create();while(this.graphStore.getPort(t)!==void 0);if(this.graphStore.getNode(s)===void 0)throw new Error("failed to set port on nonexisting node");if(this.graphStore.getPort(t)!==void 0)throw new Error("failed to add port with existing id");this.graphStore.addPort(t,r,s,o??this.portsCenterFn,n??0)}updatePort(t,r){const s=this.graphStore.getPort(t);if(s===void 0)throw new Error("failed to unset nonexisting port");s.direction=(r==null?void 0:r.direction)??s.direction,s.centerFn=(r==null?void 0:r.centerFn)??s.centerFn,this.htmlController.updatePortEdges(t)}unmarkPort(t){if(this.graphStore.getPort(t)===void 0)throw new Error("failed to unset nonexisting port");this.graphStore.getPortAdjacentEdges(t).forEach(r=>{this.removeEdge(r)}),this.graphStore.removePort(t)}addEdge(t,r,s,o,n){if(t===void 0)do t=this.edgeIdGenerator.create();while(this.graphStore.getEdge(t)!==void 0);if(this.graphStore.getPort(r)===void 0)throw new Error("failed to add edge from nonexisting port");if(this.graphStore.getPort(s)===void 0)throw new Error("failed to add edge to nonexisting port");if(this.graphStore.getEdge(t)!==void 0)throw new Error("failed to add edge with existing id");let i=P.Regular;const h=this.graphStore.getPortNode(r),c=this.graphStore.getPortNode(s);r===s?i=P.PortCycle:h===c&&(i=P.NodeCycle),n!==void 0&&this.priorityGenerator.push(n),this.graphStore.addEdge(t,r,s,o(i),n??this.priorityGenerator.create()),this.htmlController.attachEdge(t)}updateEdge(t,r){const s=this.graphStore.getEdge(t);if(s===void 0)throw new Error("failed to update nonexisting edge");r.controller!==void 0&&(this.htmlController.detachEdge(t),s.controller=r.controller,this.htmlController.attachEdge(t)),r.priority!==void 0&&(s.priority=r.priority,this.htmlController.updateEdgePriority(t))}removeEdge(t){if(this.graphStore.getEdge(t)===void 0)throw new Error("failed to remove nonexisting edge");this.htmlController.detachEdge(t),this.graphStore.removeEdge(t)}removeNode(t){if(this.graphStore.getNode(t)===void 0)throw new Error("failed to remove nonexisting node");this.htmlController.detachNode(t),this.graphStore.removeNode(t)}patchViewportState(t,r,s){this.viewportTransformer.patchState(t,r,s),this.htmlController.applyTransform()}moveToNodes(t){if(t.length===0)return;const r=t.map(u=>this.graphStore.getNode(u)).filter(u=>u!==void 0);if(r.length<t.length)throw new Error("failed to move to nonexisting node");const[s,o]=r.reduce((u,v)=>[u[0]+v.x,u[1]+v.y],[0,0]),n=s/r.length,i=o/r.length,[h,c]=this.htmlController.getViewportDimensions(),l=this.viewportTransformer.getAbsScale(),d=n-l*h/2,g=i-l*c/2;this.patchViewportState(null,d,g)}attach(t){this.htmlController.attach(t)}detach(){this.htmlController.detach()}clear(){this.htmlController.clear(),this.graphStore.clear(),this.nodeIdGenerator.reset(),this.portIdGenerator.reset(),this.edgeIdGenerator.reset(),this.priorityGenerator.reset()}destroy(){this.htmlController.destroy()}}class gt{constructor(t,r,s,o,n){a(this,"publicViewportTransformer");a(this,"canvasController");const i=new nt,h=new ht;this.publicViewportTransformer=new at(i);const c=new it(h,i,this.publicViewportTransformer,t,r);this.canvasController=new dt(h,c,i,s,o,n)}}const Q=(e,t)=>[e/2,t/2],ut=()=>()=>{},wt=(e,t,r,s,o,n)=>{e.clearRect(0,0,e.canvas.width,e.canvas.height),e.fillStyle=n,e.fillRect(0,0,e.canvas.width,e.canvas.height);const i=t.getViewCoords(0,0),h=t.getViewScale(),c=s*h;let l=0,d=0,g=c/2;do g*=2,l=e.canvas.width/g,d=e.canvas.height/g;while(l*d>1e4);const u=i[0]-Math.floor(i[0]/g)*g,v=i[1]-Math.floor(i[1]/g)*g,w=o*h,f=2*Math.PI,m=u-g,E=v-g,p=e.canvas.width+u,y=e.canvas.height+v;e.fillStyle=r;for(let b=m;b<=p;b+=g)for(let S=E;S<=y;S+=g)e.beginPath(),e.arc(b,S,w,0,f),e.closePath(),e.fill()},mt=(e,t,r,s)=>(o,n)=>{wt(o,n,e,t,r,s)},vt=(e,t)=>{e.fillStyle=t,e.fillRect(0,0,e.canvas.width,e.canvas.height)},pt=e=>t=>{vt(t,e)},ft=e=>{switch(e==null?void 0:e.type){case"custom":return e.drawingFn;case"dots":return mt(e.dotColor??"#d8d8d8",e.dotGap??25,e.dotRadius??1.5,e.color??"#ffffff");case"color":return pt(e.color??"#ffffff");default:return ut()}},Z=e=>{switch(e==null?void 0:e.type){case"custom":return e.controllerFactory;case"straight":return _({color:e.color??"#5c5c5c",width:e.width??1,arrowLength:e.arrowLength??15,arrowWidth:e.arrowWidth??4,arrowOffset:e.arrowOffset??15,hasSourceArrow:e.hasSourceArrow??!1,hasTargetArrow:e.hasTargetArrow??!1,cycleSquareSide:e.cycleSquareSide??30,roundness:e.roundness??10,detourDistance:e.detourDistance??100,detourDirection:e.detourDirection??-Math.PI/2});case"horizontal":return J({color:e.color??"#5c5c5c",width:e.width??1,arrowLength:e.arrowLength??15,arrowWidth:e.arrowWidth??4,arrowOffset:e.arrowOffset??15,hasSourceArrow:e.hasSourceArrow??!1,hasTargetArrow:e.hasTargetArrow??!1,cycleSquareSide:e.cycleSquareSide??30,roundness:e.roundness??10,detourDistance:e.detourDistance??100,detourDirection:e.detourDirection??-Math.PI/2});case"vertical":return K({color:e.color??"#5c5c5c",width:e.width??1,arrowLength:e.arrowLength??15,arrowWidth:e.arrowWidth??4,arrowOffset:e.arrowOffset??15,hasSourceArrow:e.hasSourceArrow??!1,hasTargetArrow:e.hasTargetArrow??!1,cycleSquareSide:e.cycleSquareSide??30,roundness:e.roundness??10,detourDistance:e.detourDistance??100,detourDirection:e.detourDirection??-Math.PI/2});default:return U({color:e.color??"#5c5c5c",width:e.width??1,curvature:e.curvature??90,arrowLength:e.arrowLength??15,arrowWidth:e.arrowWidth??4,hasSourceArrow:e.hasSourceArrow??!1,hasTargetArrow:e.hasTargetArrow??!1,cycleRadius:e.cycleRadius??30,smallCycleRadius:e.smallCycleRadius??15,detourDistance:e.detourDistance??100,detourDirection:e.detourDirection??-Math.PI/2})}},Et=e=>{var t,r,s,o;return{background:{drawingFn:ft(e.background??{type:"none"})},nodes:{centerFn:((t=e.nodes)==null?void 0:t.centerFn)??Q},ports:{centerFn:((r=e.ports)==null?void 0:r.centerFn)??Q,direction:((s=e.ports)==null?void 0:s.direction)??0},edges:{controllerFactory:Z(e.edges??{})},layers:{mode:((o=e.layers)==null?void 0:o.mode)??"edges-follow-node"}}};class q{constructor(t){a(this,"transformation");a(this,"di");a(this,"edgeControllerFactory");this.apiOptions=t;const r=Et(this.apiOptions??{});this.di=new gt(r.layers.mode,r.background.drawingFn,r.nodes.centerFn,r.ports.centerFn,r.ports.direction),this.transformation=this.di.publicViewportTransformer,this.edgeControllerFactory=r.edges.controllerFactory}addNode(t){return this.di.canvasController.addNode(t.id,t.element,t.x,t.y,t.ports,t.centerFn,t.priority),this}updateNode(t,r){return this.di.canvasController.updateNode(t,r.x,r.y,r.priority,r.centerFn),this}removeNode(t){return this.di.canvasController.removeNode(t),this}moveNodeOnTop(t){return this.di.canvasController.moveNodeOnTop(t),this}markPort(t){return this.di.canvasController.markPort(t.id,t.element,t.nodeId,t.centerFn,t.direction),this}updatePort(t,r){return this.di.canvasController.updatePort(t,r),this}unmarkPort(t){return this.di.canvasController.unmarkPort(t),this}addEdge(t){const r=t.options!==void 0?Z(t.options):this.edgeControllerFactory;return this.di.canvasController.addEdge(t.id,t.from,t.to,r,t.priority),this}updateEdge(t,r){return this.di.canvasController.updateEdge(t,r),this}removeEdge(t){return this.di.canvasController.removeEdge(t),this}patchViewportState(t){return this.di.canvasController.patchViewportState(t.scale??null,t.x??null,t.y??null),this}moveToNodes(t){return this.di.canvasController.moveToNodes(t),this}clear(){return this.di.canvasController.clear(),this}attach(t){return this.di.canvasController.attach(t),this}detach(){return this.di.canvasController.detach(),this}destroy(){this.di.canvasController.destroy()}}class I{constructor(t,r){a(this,"transformation");a(this,"nodes",new Map);a(this,"grabbedNodeId",null);a(this,"onNodeDrag");a(this,"onBeforeNodeDrag");a(this,"nodeIdGenerator",new B);a(this,"element",null);a(this,"onCanvasMouseUp",()=>{this.setCursor(null),this.grabbedNodeId=null});a(this,"onCanvasMouseMove",t=>{this.grabbedNodeId!==null&&(t.stopPropagation(),this.dragNode(this.grabbedNodeId,t.movementX,t.movementY))});a(this,"onCanvasTouchStart",t=>{this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]});a(this,"onCanvasTouchMove",t=>{if(this.grabbedNodeId===null||t.touches.length!==1||this.previousTouchCoords===null)return;t.stopImmediatePropagation();const[r,s]=[t.touches[0].clientX-this.previousTouchCoords[0],t.touches[0].clientY-this.previousTouchCoords[1]];this.dragNode(this.grabbedNodeId,r,s),this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]});a(this,"onCanvasTouchEnd",t=>{t.touches.length>0?this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]:(this.previousTouchCoords=null,this.grabbedNodeId=null)});a(this,"previousTouchCoords",null);var n,i;this.canvas=t,this.transformation=this.canvas.transformation;const s=()=>{};this.onNodeDrag=((n=r==null?void 0:r.events)==null?void 0:n.onNodeDrag)??s;const o=()=>!0;this.onBeforeNodeDrag=((i=r==null?void 0:r.events)==null?void 0:i.onBeforeNodeDrag)??o}addNode(t){let r=t.id;if(r===void 0)do r=this.nodeIdGenerator.create();while(this.nodes.has(r));this.canvas.addNode(t);const s=n=>{this.onBeforeNodeDrag({nodeId:r,element:t.element,x:t.x,y:t.y})&&(n.stopImmediatePropagation(),this.grabbedNodeId=r,this.setCursor("grab"),this.canvas.moveNodeOnTop(r))},o=n=>{this.onBeforeNodeDrag({nodeId:r,element:t.element,x:t.x,y:t.y})&&n.touches.length===1&&(this.grabbedNodeId=r,this.canvas.moveNodeOnTop(r))};return this.nodes.set(r,{element:t.element,onMouseDown:s,onTouchStart:o,x:t.x,y:t.y}),t.element.addEventListener("mousedown",s),t.element.addEventListener("touchstart",o),this}updateNode(t,r){return this.canvas.updateNode(t,r),this}removeNode(t){const r=this.nodes.get(t);return r!==void 0&&(r.element.removeEventListener("mousedown",r.onMouseDown),r.element.removeEventListener("touchstart",r.onTouchStart)),this.canvas.removeNode(t),this.nodes.delete(t),this}markPort(t){return this.canvas.markPort(t),this}updatePort(t,r){return this.canvas.updatePort(t,r),this}unmarkPort(t){return this.canvas.unmarkPort(t),this}addEdge(t){return this.canvas.addEdge(t),this}updateEdge(t,r){return this.canvas.updateEdge(t,r),this}removeEdge(t){return this.canvas.removeEdge(t),this}patchViewportState(t){return this.canvas.patchViewportState(t),this}moveToNodes(t){return this.canvas.moveToNodes(t),this}moveNodeOnTop(t){return this.canvas.moveNodeOnTop(t),this}clear(){return this.canvas.clear(),this.nodes.forEach(t=>{t.element.removeEventListener("mousedown",t.onMouseDown),t.element.removeEventListener("touchstart",t.onTouchStart)}),this.nodes.clear(),this}attach(t){return this.detach(),this.element=t,this.canvas.attach(this.element),this.element.addEventListener("mouseup",this.onCanvasMouseUp),this.element.addEventListener("mousemove",this.onCanvasMouseMove),this.element.addEventListener("touchstart",this.onCanvasTouchStart),this.element.addEventListener("touchmove",this.onCanvasTouchMove),this.element.addEventListener("touchend",this.onCanvasTouchEnd),this.element.addEventListener("touchcancel",this.onCanvasTouchEnd),this}detach(){return this.canvas.detach(),this.element!==null&&(this.element.removeEventListener("mouseup",this.onCanvasMouseUp),this.element.removeEventListener("mousemove",this.onCanvasMouseMove),this.element.removeEventListener("touchstart",this.onCanvasTouchStart),this.element.removeEventListener("touchmove",this.onCanvasTouchMove),this.element.removeEventListener("touchend",this.onCanvasTouchEnd),this.element.removeEventListener("touchcancel",this.onCanvasTouchEnd),this.element=null),this}destroy(){this.detach(),this.nodes.forEach(t=>{t.element.removeEventListener("mousedown",t.onMouseDown),t.element.removeEventListener("touchstart",t.onTouchStart)}),this.nodes.clear(),this.canvas.destroy()}setCursor(t){this.element!==null&&(t!==null?this.element.style.cursor=t:this.element.style.removeProperty("cursor"))}dragNode(t,r,s){const o=this.nodes.get(t);if(o===void 0)throw new Error("failed to drag nonexisting node");const[n,i]=this.transformation.getViewCoords(o.x,o.y),h=n+r,c=i+s,[l,d]=this.transformation.getAbsCoords(h,c);o.x=l,o.y=d,this.canvas.updateNode(t,{x:l,y:d}),this.onNodeDrag({nodeId:t,element:o.element,x:o.x,y:o.y})}}class tt{constructor(t,r){a(this,"transformation");a(this,"element",null);a(this,"isMoving",!1);a(this,"prevTouches",null);a(this,"onTransform");a(this,"onBeforeTransform");a(this,"isScalable");a(this,"isShiftable");a(this,"minViewScale");a(this,"maxViewScale");a(this,"wheelSensitivity");a(this,"onMouseDown",()=>{this.setCursor("grab"),this.isMoving=!0});a(this,"onMouseMove",t=>{if(!this.isMoving||!this.isShiftable)return;const r=-t.movementX,s=-t.movementY;this.moveViewport(r,s)});a(this,"onMouseUp",()=>{this.setCursor(null),this.isMoving=!1});a(this,"onWheelScroll",t=>{if(this.element===null||this.isScalable===!1)return;t.preventDefault();const{left:r,top:s}=this.element.getBoundingClientRect(),o=t.clientX-r,n=t.clientY-s,h=1/(t.deltaY<0?this.wheelSensitivity:1/this.wheelSensitivity);this.scaleViewport(h,o,n)});a(this,"onTouchStart",t=>{this.prevTouches=this.getAverageTouch(t)});a(this,"onTouchMove",t=>{if(this.prevTouches===null||this.element===null||!this.isShiftable)return;const r=this.getAverageTouch(t);if((r.touchesCnt===1||r.touchesCnt===2)&&this.moveViewport(-(r.x-this.prevTouches.x),-(r.y-this.prevTouches.y)),r.touchesCnt===2&&this.isScalable){const{left:s,top:o}=this.element.getBoundingClientRect(),n=this.prevTouches.x-s,i=this.prevTouches.y-o,c=1/(r.scale/this.prevTouches.scale);this.scaleViewport(c,n,i)}this.prevTouches=r,t.preventDefault()});a(this,"onTouchEnd",t=>{t.touches.length>0?this.prevTouches=this.getAverageTouch(t):this.prevTouches=null});var c,l,d,g,u,v,w,f,m,E,p,y;this.canvas=t,this.options=r,this.transformation=this.canvas.transformation;const s=((l=(c=this.options)==null?void 0:c.scale)==null?void 0:l.min)??null,o=((g=(d=this.options)==null?void 0:d.scale)==null?void 0:g.max)??null;this.isScalable=((v=(u=this.options)==null?void 0:u.scale)==null?void 0:v.enabled)!==!1,this.minViewScale=o!==null?1/o:null,this.maxViewScale=s!==null?1/s:null,this.isShiftable=((f=(w=this.options)==null?void 0:w.shift)==null?void 0:f.enabled)!==!1;const n=(E=(m=this.options)==null?void 0:m.scale)==null?void 0:E.wheelSensitivity;this.wheelSensitivity=n!==void 0?n:1.2;const i=()=>{};this.onTransform=((p=r==null?void 0:r.events)==null?void 0:p.onTransform)??i;const h=()=>!0;this.onBeforeTransform=((y=r==null?void 0:r.events)==null?void 0:y.onBeforeTransform)??h}addNode(t){return this.canvas.addNode(t),this}updateNode(t,r){return this.canvas.updateNode(t,r),this}removeNode(t){return this.canvas.removeNode(t),this}markPort(t){return this.canvas.markPort(t),this}updatePort(t,r){return this.canvas.updatePort(t,r),this}unmarkPort(t){return this.canvas.unmarkPort(t),this}addEdge(t){return this.canvas.addEdge(t),this}updateEdge(t,r){return this.canvas.updateEdge(t,r),this}removeEdge(t){return this.canvas.removeEdge(t),this}patchViewportState(t){return this.canvas.patchViewportState(t),this}moveToNodes(t){return this.canvas.moveToNodes(t),this}moveNodeOnTop(t){return this.canvas.moveNodeOnTop(t),this}clear(){return this.canvas.clear(),this}attach(t){return this.detach(),this.element=t,this.canvas.attach(this.element),this.element.addEventListener("mousedown",this.onMouseDown),this.element.addEventListener("mousemove",this.onMouseMove),this.element.addEventListener("mouseup",this.onMouseUp),this.element.addEventListener("wheel",this.onWheelScroll),this.element.addEventListener("touchstart",this.onTouchStart),this.element.addEventListener("touchmove",this.onTouchMove),this.element.addEventListener("touchend",this.onTouchEnd),this.element.addEventListener("touchcancel",this.onTouchEnd),this}detach(){return this.canvas.detach(),this.element!==null&&(this.element.removeEventListener("mousedown",this.onMouseDown),this.element.removeEventListener("mousemove",this.onMouseMove),this.element.removeEventListener("mouseup",this.onMouseUp),this.element.removeEventListener("wheel",this.onWheelScroll),this.element.removeEventListener("touchstart",this.onTouchStart),this.element.removeEventListener("touchmove",this.onTouchMove),this.element.removeEventListener("touchend",this.onTouchEnd),this.element.removeEventListener("touchcancel",this.onTouchEnd),this.element=null),this}destroy(){this.detach(),this.canvas.destroy()}getAverageTouch(t){const r=[],s=t.touches.length;for(let c=0;c<s;c++)r.push([t.touches[c].clientX,t.touches[c].clientY]);const o=r.reduce((c,l)=>[c[0]+l[0],c[1]+l[1]],[0,0]),n=[o[0]/s,o[1]/s],h=r.map(c=>[c[0]-n[0],c[1]-n[1]]).reduce((c,l)=>c+Math.sqrt(l[0]*l[0]+l[1]*l[1]),0);return{x:n[0],y:n[1],scale:h/s,touchesCnt:s}}setCursor(t){this.element!==null&&(t!==null?this.element.style.cursor=t:this.element.style.removeProperty("cursor"))}moveViewport(t,r){const[s,o]=this.transformation.getAbsCoords(0,0),n=this.canvas.transformation.getAbsScale(),i={scale:n,x:s+n*t,y:o+n*r};this.onBeforeTransform({...i})&&(this.canvas.patchViewportState(i),this.onTransform(i))}scaleViewport(t,r,s){const[o,n]=this.canvas.transformation.getAbsCoords(0,0),i=this.canvas.transformation.getAbsScale(),h=i*t,c=i*(1-t)*r+o,l=i*(1-t)*s+n;if(this.maxViewScale!==null&&h>this.maxViewScale&&h>i||this.minViewScale!==null&&h<this.minViewScale&&h<i)return;const d={scale:h,x:c,y:l};this.onBeforeTransform({...d})&&(this.canvas.patchViewportState(d),this.onTransform(d))}}class Ct{constructor(){a(this,"coreOptions");a(this,"dragOptions");a(this,"transformOptions");a(this,"isDraggable",!1);a(this,"isTransformable",!1)}setOptions(t){return this.coreOptions=t,this}setUserDraggableNodes(t){return this.isDraggable=!0,this.dragOptions=t,this}setUserTransformableCanvas(t){return this.isTransformable=!0,this.transformOptions=t,this}build(){let t=new q(this.coreOptions);return this.isDraggable&&(t=new I(t,this.dragOptions)),this.isTransformable&&(t=new tt(t,this.transformOptions)),t}}C.BezierEdgeController=z,C.CanvasCore=q,C.CycleCircleEdgeController=H,C.CycleSquareEdgeController=k,C.DetourStraightEdgeController=R,C.EdgeType=P,C.HorizontalEdgeController=G,C.HtmlGraphBuilder=Ct,C.StraightEdgeController=X,C.UserDraggableNodesCanvas=I,C.UserTransformableCanvas=tt,C.VerticalEdgeController=j,C.createBezierEdgeControllerFactory=U,C.createHorizontalEdgeControllerFactory=J,C.createStraightEdgeControllerFactory=_,C.createVerticalEdgeControllerFactory=K,Object.defineProperty(C,Symbol.toStringTag,{value:"Module"})});
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@html-graph/html-graph",
|
|
3
|
-
"author": "Dmitry Marov",
|
|
3
|
+
"author": "Dmitry Marov <d.marov94@gmail.com>",
|
|
4
4
|
"private": false,
|
|
5
|
-
"version": "0.0.
|
|
5
|
+
"version": "0.0.52",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"main": "dist/main.js",
|
|
8
8
|
"types": "dist/main.d.ts",
|
|
@@ -37,15 +37,21 @@
|
|
|
37
37
|
"preview": "vite preview",
|
|
38
38
|
"before-build": "npm run lint && npm run check-formatting",
|
|
39
39
|
"release-next-version": "tsx ./scripts/release-next-version.ts",
|
|
40
|
-
"make-deps-graph": "npx depcruise lib --include-only \"^lib\" --output-type dot > ./deps-graph/deps-graph.dot"
|
|
40
|
+
"make-deps-graph": "npx depcruise lib --include-only \"^lib\" --output-type dot > ./deps-graph/deps-graph.dot",
|
|
41
|
+
"test": "jest",
|
|
42
|
+
"test:watch": "jest --watch"
|
|
41
43
|
},
|
|
42
44
|
"devDependencies": {
|
|
43
45
|
"@eslint/js": "^9.9.1",
|
|
46
|
+
"@types/jest": "^29.5.14",
|
|
44
47
|
"@types/node": "^22.5.0",
|
|
45
48
|
"dependency-cruiser": "^16.7.0",
|
|
46
49
|
"eslint": "^9.9.1",
|
|
47
50
|
"globals": "^15.9.0",
|
|
51
|
+
"jest": "^29.7.0",
|
|
48
52
|
"prettier": "3.3.3",
|
|
53
|
+
"ts-jest": "^29.2.5",
|
|
54
|
+
"ts-node": "^10.9.2",
|
|
49
55
|
"tsx": "^4.18.0",
|
|
50
56
|
"typescript": "^5.5.3",
|
|
51
57
|
"typescript-eslint": "^8.3.0",
|