@html-graph/html-graph 0.0.50 → 0.0.51

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/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(f,N){typeof exports=="object"&&typeof module<"u"?N(exports):typeof define=="function"&&define.amd?define(["exports"],N):(f=typeof globalThis<"u"?globalThis:f||self,N(f.HTMLGraph={}))})(this,function(f){"use strict";var ct=Object.defineProperty;var lt=(f,N,P)=>N in f?ct(f,N,{enumerable:!0,configurable:!0,writable:!0,value:P}):f[N]=P;var n=(f,N,P)=>lt(f,typeof N!="symbol"?N+"":N,P);class N{constructor(t,e,s,o,i){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:(t,e,s)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${s})`,this.edgesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${s})`},moveOnTop:t=>{this.currentZIndex+=1;const e=this.nodeIdToWrapperElementMap.get(t);e.style.zIndex=`${this.currentZIndex}`}},"edges-follow-node":{create:()=>{this.host.appendChild(this.nodesContainer),this.edgesContainer=this.nodesContainer},update:(t,e,s)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${s})`},moveOnTop:t=>{const e=this.nodeIdToWrapperElementMap.get(t);this.currentZIndex+=2,e.style.zIndex=`${this.currentZIndex}`,this.graphStore.getNodeAdjacentEdges(t).forEach(o=>{this.edgeIdToElementMap.get(o).style.zIndex=`${this.currentZIndex-1}`})}},"nodes-on-top":{create:()=>{this.host.appendChild(this.edgesContainer),this.host.appendChild(this.nodesContainer)},update:(t,e,s)=>{this.nodesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${s})`,this.edgesContainer.style.transform=`matrix(${t}, 0, 0, ${t}, ${e}, ${s})`},moveOnTop:t=>{this.currentZIndex+=1;const e=this.nodeIdToWrapperElementMap.get(t);e.style.zIndex=`${this.currentZIndex}`}}});this.graphStore=t,this.viewportTransformer=e,this.publicViewportTransformer=s,this.layersMode=o,this.backgroundDrawingFn=i,this.host=this.createHost(),this.canvas=this.createCanvas(),this.nodesContainer=this.createNodesContainer(),this.edgesContainer=this.createEdgesContainer();const h=this.canvas.getContext("2d");if(h===null)throw new Error("unable to get canvas context");this.canvasCtx=h,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(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.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[t,e]=this.viewportTransformer.getViewCoords(0,0),s=this.viewportTransformer.getViewScale();this.layers[this.layersMode].update(s,t,e)}attachNode(t){const e=this.graphStore.getNode(t),s=document.createElement("div");s.appendChild(e.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(e.element,t),this.nodeWrapperElementToIdMap.set(s,t),this.nodeIdToWrapperElementMap.set(t,s),this.updateNodeCoords(t,e.x,e.y),this.nodesResizeObserver.observe(s),s.style.visibility="visible"}detachNode(t){const e=this.graphStore.getNode(t);this.nodesResizeObserver.unobserve(e.element),this.nodesContainer.removeChild(e.element);const s=this.nodeIdToWrapperElementMap.get(t);s.removeChild(e.element),this.nodeElementToIdMap.delete(e.element),this.nodeWrapperElementToIdMap.delete(s),this.nodeIdToWrapperElementMap.delete(t)}attachEdge(t){const s=this.graphStore.getEdge(t).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(t,s),this.updateEdgeCoords(t),this.edgesContainer.appendChild(s)}detachEdge(t){const e=this.edgeIdToElementMap.get(t);this.edgeIdToElementMap.delete(t),this.edgesContainer.removeChild(e)}moveNodeOnTop(t){this.layers[this.layersMode].moveOnTop(t)}updateNodeCoordinates(t){const e=this.graphStore.getNode(t),s=this.graphStore.getNodeAdjacentEdges(t);this.updateNodeCoords(t,e.x,e.y),s.forEach(o=>{this.updateEdgeCoords(o)})}updatePortEdges(t){this.graphStore.getPortAdjacentEdges(t).forEach(s=>{this.updateEdgeCoords(s)})}getViewportDimensions(){const t=this.host.getBoundingClientRect();return[t.width,t.height]}createHost(){const t=document.createElement("div");return t.style.width="100%",t.style.height="100%",t.style.position="relative",t.style.overflow="hidden",t}createCanvas(){const t=document.createElement("canvas");return t.style.position="absolute",t.style.inset="0",t}createNodesContainer(){const t=document.createElement("div");return t.style.position="absolute",t.style.top="0",t.style.left="0",t.style.width="0",t.style.height="0",t}createEdgesContainer(){const t=document.createElement("div");return t.style.position="absolute",t.style.pointerEvents="none",t.style.top="0",t.style.left="0",t.style.width="0",t.style.height="0",t}createHostResizeObserver(){return new ResizeObserver(()=>{this.updateCanvasDimensions(),this.applyTransform()})}createNodesResizeObserver(){return new ResizeObserver(t=>{t.forEach(e=>{const s=e.target,o=this.nodeWrapperElementToIdMap.get(s),i=this.graphStore.getNode(o);this.updateNodeCoords(o,i.x,i.y),this.graphStore.getNodeAdjacentEdges(o).forEach(a=>{this.updateEdgeCoords(a)})})})}updateCanvasDimensions(){const{width:t,height:e}=this.host.getBoundingClientRect();this.canvas.width=t,this.canvas.height=e}updateNodeCoords(t,e,s){const o=this.nodeIdToWrapperElementMap.get(t),{width:i,height:h}=o.getBoundingClientRect(),a=this.viewportTransformer.getAbsScale(),c=this.graphStore.getNode(t),[l,d]=c.centerFn(i,h);o.style.transform=`matrix(1, 0, 0, 1, ${e-a*l}, ${s-a*d})`}updateEdgeCoords(t){const e=this.graphStore.getEdge(t),s=this.graphStore.getPort(e.from),o=this.graphStore.getPort(e.to),i=s.element.getBoundingClientRect(),h=o.element.getBoundingClientRect(),a=this.host.getBoundingClientRect(),[c,l]=this.viewportTransformer.getAbsCoords(i.left-a.left,i.top-a.top),[d,u]=this.viewportTransformer.getAbsCoords(h.left-a.left,h.top-a.top),g=this.viewportTransformer.getAbsScale(),[w,m]=s.centerFn(i.width*g,i.height*g),[C,p]=o.centerFn(h.width*g,h.height*g),E=w+c,v=m+l,y=C+d,A=p+u,b=Math.min(E,y),O=Math.min(v,A),V=Math.abs(y-E),D=Math.abs(A-v);e.controller.update(b,O,V,D,s,o)}}class P{constructor(){n(this,"state",{scale:1,x:0,y:0})}getViewCoords(t,e){return[(t-this.state.x)/this.state.scale,(e-this.state.y)/this.state.scale]}getViewScale(){return 1/this.state.scale}getAbsCoords(t,e){return[t*this.state.scale+this.state.x,e*this.state.scale+this.state.y]}getAbsScale(){return this.state.scale}patchState(t,e,s){this.state={scale:t??this.state.scale,x:e??this.state.x,y:s??this.state.y}}}class _{constructor(t){this.transformer=t}getViewCoords(t,e){return this.transformer.getViewCoords(t,e)}getViewScale(){return this.transformer.getViewScale()}getAbsCoords(t,e){return this.transformer.getAbsCoords(t,e)}getAbsScale(){return this.transformer.getAbsScale()}}class J{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(t,e,s,o,i){this.nodes[t]={element:e,x:s,y:o,centerFn:i},this.nodePorts[t]=Object.create(null)}hasNode(t){return this.nodes[t]!==void 0}getNode(t){return this.nodes[t]}updateNodeCoords(t,e,s){this.nodes[t].x=e,this.nodes[t].y=s}updateEdgeController(t,e){this.edges[t].controller=e}removeNode(t){this.getNodeAdjacentEdges(t).forEach(o=>{this.removeEdge(o)}),delete this.nodes[t];const s=this.nodePorts[t];Object.keys(s).forEach(o=>{delete this.portNodeId[o]}),delete this.nodePorts[t]}addPort(t,e,s,o,i){this.ports[t]={element:e,centerFn:o,direction:i},this.cycleEdges[t]={},this.incommingEdges[t]={},this.outcommingEdges[t]={},this.portNodeId[t]=s;const h=this.nodePorts[s];h!==void 0&&(h[t]=e)}getPort(t){return this.ports[t]}getPortNode(t){return this.portNodeId[t]}hasPort(t){return this.portNodeId[t]!==void 0}removePort(t){Object.keys(this.cycleEdges[t]).forEach(o=>{this.removeEdge(o)}),delete this.cycleEdges[t],Object.keys(this.incommingEdges[t]).forEach(o=>{this.removeEdge(o)}),delete this.incommingEdges[t],Object.keys(this.outcommingEdges[t]).forEach(o=>{this.removeEdge(o)}),delete this.outcommingEdges[t];const e=this.portNodeId[t];delete this.portNodeId[t];const s=this.nodePorts[e];delete s[t],delete this.ports[t]}addEdge(t,e,s,o){this.edges[t]={from:e,to:s,controller:o},e!==s?(this.outcommingEdges[e][t]=!0,this.incommingEdges[s][t]=!0):this.cycleEdges[e][t]=!0}getEdge(t){return this.edges[t]}hasEdge(t){return this.edges[t]!==void 0}removeEdge(t){const e=this.edges[t],s=e.from,o=e.to;delete this.cycleEdges[s][t],delete this.cycleEdges[o][t],delete this.incommingEdges[s][t],delete this.incommingEdges[o][t],delete this.outcommingEdges[s][t],delete this.outcommingEdges[o][t],delete this.edges[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=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(t){return Object.keys(this.incommingEdges[t]??{})}getPortOutcomingEdges(t){return Object.keys(this.outcommingEdges[t]??{})}getPortCycleEdges(t){return Object.keys(this.cycleEdges[t]??{})}getNodeIncomingEdges(t){const e=Object.keys(this.nodePorts[t]);let s=[];return e.forEach(o=>{s=[...s,...this.getPortIncomingEdges(o)]}),s}getNodeOutcomingEdges(t){const e=Object.keys(this.nodePorts[t]);let s=[];return e.forEach(o=>{s=[...s,...this.getPortOutcomingEdges(o)]}),s}getNodeCycleEdges(t){const e=Object.keys(this.nodePorts[t]);let s=[];return e.forEach(o=>{s=[...s,...this.getPortCycleEdges(o)]}),s}}const M=r=>{const{top:t,left:e,width:s,height:o}=r.element.getBoundingClientRect(),i=r.centerFn(s,o);return[e+i[0],t+i[1]]},S=(r,t,e)=>[t[0]*r[0]-t[1]*r[1]+((1-t[0])*e[0]+t[1]*e[1]),t[1]*r[0]+t[0]*r[1]+((1-t[0])*e[1]-t[1]*e[0])],T=(r,t,e)=>[t*Math.cos(r),e*Math.sin(r)],$=(r,t,e,s,o)=>{const h=[[0,0],[s,o],[s,-o]].map(d=>S(d,r,[0,0])).map(d=>[d[0]+t,d[1]+e]),a=`M ${h[0][0]} ${h[0][1]}`,c=`L ${h[1][0]} ${h[1][1]}`,l=`L ${h[2][0]} ${h[2][1]}`;return`${a} ${c} ${l}`};class W{constructor(t,e,s,o,i,h,a){n(this,"svg");n(this,"group");n(this,"line");n(this,"sourceArrow",null);n(this,"targetArrow",null);this.color=t,this.width=e,this.curvature=s,this.arrowLength=o,this.arrowWidth=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%",h&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),a&&(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,e,s,o,i,h){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const a=M(i),c=M(h),l=a[0]<=c[0]?1:-1,d=a[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${e}px)`,this.group.style.transform=`scale(${l}, ${d})`;const u=T(i.direction,l,d),g=T(h.direction,l,d),w=S([this.arrowLength,0],u,[0,0]),m=S([s-this.arrowLength,o],g,[s,o]),C=[w[0]+u[0]*this.curvature,w[1]+u[1]*this.curvature],p=[m[0]-g[0]*this.curvature,m[1]-g[1]*this.curvature],E=`M ${w[0]} ${w[1]} C ${C[0]} ${C[1]}, ${p[0]} ${p[1]}, ${m[0]} ${m[1]}`,v=this.sourceArrow?"":`M 0 0 L ${w[0]} ${w[1]} `,y=this.targetArrow?"":` M ${m[0]} ${m[1]} L ${s} ${o}`,A=`${v}${E}${y}`;if(this.line.setAttribute("d",A),this.sourceArrow){const b=$(u,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",b)}if(this.targetArrow){const b=$(g,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",b)}}}const F=(r,t)=>{const e=[];if(r.length>0&&e.push(`M ${r[0][0]} ${r[0][1]}`),r.length===2&&e.push(`L ${r[1][0]} ${r[1][1]}`),r.length>2){const s=r.length-1;let o=0,i=0,h=0;r.forEach((a,c)=>{let l=0,d=0,u=0;const g=c>0,w=c<s,m=g&&w;if(g&&(l=-o,d=-i,u=h),w){const b=r[c+1];o=b[0]-a[0],i=b[1]-a[1],h=Math.sqrt(o*o+i*i)}const p=Math.min((m?t:0)/h,c<s-1?.5:1),E=m?[a[0]+o*p,a[1]+i*p]:a,y=Math.min((m?t:0)/u,c>1?.5:1),A=m?[a[0]+l*y,a[1]+d*y]:a;c>0&&e.push(`L ${A[0]} ${A[1]}`),m&&e.push(`C ${a[0]} ${a[1]} ${a[0]} ${a[1]} ${E[0]} ${E[1]}`)})}return e.join(" ")};class j{constructor(t,e,s,o,i,h,a,c){n(this,"svg");n(this,"group");n(this,"line");n(this,"sourceArrow",null);n(this,"targetArrow",null);this.color=t,this.width=e,this.arrowLength=s,this.arrowWidth=o,this.arrowOffset=i,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%",h&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),a&&(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,e,s,o,i,h){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const a=M(i),c=M(h),l=a[0]<=c[0]?1:-1,d=a[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${e}px)`,this.group.style.transform=`scale(${l}, ${d})`;const u=T(i.direction,l,d),g=T(h.direction,l,d),w=this.sourceArrow?S([this.arrowLength,0],u,[0,0]):[0,0],m=this.targetArrow?S([s-this.arrowLength,o],g,[s,o]):[s,o],C=this.arrowLength+this.arrowOffset,p=S([C,0],u,[0,0]),E=S([s-C,o],g,[s,o]),v=F([w,p,E,m],this.roundness);if(this.line.setAttribute("d",v),this.sourceArrow){const y=$(u,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",y)}if(this.targetArrow){const y=$(g,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",y)}}}class R{constructor(t,e,s,o,i,h,a){n(this,"svg");n(this,"group");n(this,"line");n(this,"arrow",null);this.color=t,this.width=e,this.arrowLength=s,this.arrowWidth=o,this.radius=h,this.smallRadius=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%",i&&(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,e,s,o,i){this.svg.style.transform=`translate(${t}px, ${e}px)`;const h=T(i.direction,1,1),a=this.smallRadius,c=this.radius,l=Math.sqrt(a*a+c*c),d=a+c,u=this.arrowLength+l*(1-c/d),g=a*c/d,m=[[this.arrowLength,0],[u,g],[u,-g]].map(v=>S(v,h,[0,0])),C=[`M ${m[0][0]} ${m[0][1]}`,`A ${a} ${a} 0 0 1 ${m[1][0]} ${m[1][1]}`,`A ${c} ${c} 0 1 0 ${m[2][0]} ${m[2][1]}`,`A ${a} ${a} 0 0 1 ${m[0][0]} ${m[0][1]}`].join(" "),p=`M 0 0 L ${m[0][0]} ${m[0][1]} `,E=`${this.arrow!==null?"":p}${C}`;if(this.line.setAttribute("d",E),this.arrow){const v=$(h,0,0,this.arrowLength,this.arrowWidth);this.arrow.setAttribute("d",v)}}}class B{constructor(t,e,s,o,i,h,a,c){n(this,"svg");n(this,"group");n(this,"line");n(this,"arrow",null);n(this,"roundness");n(this,"linePoints");this.color=t,this.width=e,this.arrowLength=s,this.arrowWidth=o,this.side=h,this.minPortOffset=a,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%",i&&(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,u=this.arrowLength+l,g=this.roundness,w=u+2*d;console.log(g),this.linePoints=[[this.arrowLength,0],[u,0],[u,this.side],[w,this.side],[w,-this.side],[u,-this.side],[u,0],[this.arrowLength,0]]}update(t,e,s,o,i){this.svg.style.transform=`translate(${t}px, ${e}px)`;const h=T(i.direction,1,1),a=this.linePoints.map(d=>S(d,h,[0,0])),c=`M 0 0 L ${a[0][0]} ${a[0][1]} `,l=`${this.arrow?"":c}${F(a,this.roundness)}`;if(this.line.setAttribute("d",l),this.arrow){const d=$(h,0,0,this.arrowLength,this.arrowWidth);this.arrow.setAttribute("d",d)}}}class z{constructor(t,e,s,o,i,h,a,c,l,d){n(this,"svg");n(this,"group");n(this,"line");n(this,"sourceArrow",null);n(this,"targetArrow",null);n(this,"detourX");n(this,"detourY");this.color=t,this.width=e,this.arrowLength=s,this.arrowWidth=o,this.arrowOffset=i,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%",h&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),a&&(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,e,s,o,i,h){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const a=M(i),c=M(h),l=a[0]<=c[0]?1:-1,d=a[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${e}px)`,this.group.style.transform=`scale(${l}, ${d})`;const u=T(i.direction,l,d),g=T(h.direction,l,d),w=this.sourceArrow?S([this.arrowLength,0],u,[0,0]):[0,0],m=this.targetArrow?S([s-this.arrowLength,o],g,[s,o]):[s,o],C=this.arrowLength+this.arrowOffset,p=S([C,0],u,[0,0]),E=[p[0]+this.detourX,p[1]+this.detourY],v=S([s-C,o],g,[s,o]),y=[v[0]+this.detourX,v[1]+this.detourY],A=F([w,p,E,y,v,m],this.roundness);if(this.line.setAttribute("d",A),this.sourceArrow){const b=$(u,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",b)}if(this.targetArrow){const b=$(g,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",b)}}}var x=(r=>(r.Regular="regular",r.PortCycle="port-cycle",r.NodeCycle="node-cycle",r))(x||{});class K{constructor(t,e,s,o,i,h,a,c,l){n(this,"svg");n(this,"group");n(this,"line");n(this,"sourceArrow",null);n(this,"targetArrow",null);n(this,"detourX");n(this,"detourY");this.color=t,this.width=e,this.curvature=s,this.arrowLength=o,this.arrowWidth=i,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%",h&&(this.sourceArrow=document.createElementNS("http://www.w3.org/2000/svg","path"),this.sourceArrow.setAttribute("fill",this.color),this.group.appendChild(this.sourceArrow)),a&&(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,e,s,o,i,h){this.svg.style.width=`${s}px`,this.svg.style.height=`${o}px`;const a=M(i),c=M(h),l=a[0]<=c[0]?1:-1,d=a[1]<=c[1]?1:-1;this.svg.style.transform=`translate(${t}px, ${e}px)`,this.group.style.transform=`scale(${l}, ${d})`;const u=T(i.direction,l,d),g=T(h.direction,l,d),w=this.sourceArrow?S([this.arrowLength,0],u,[0,0]):[0,0],m=this.targetArrow?S([s-this.arrowLength,o],g,[s,o]):[s,o],C=this.arrowLength,p=S([C,0],u,[0,0]),E=[p[0]+this.detourX,p[1]+this.detourY],v=S([s-C,o],g,[s,o]),y=[v[0]+this.detourX,v[1]+this.detourY],A=[(E[0]+y[0])/2,(E[1]+y[1])/2],b=[p[0]-this.curvature*Math.cos(i.direction),p[1]-this.curvature*Math.sin(i.direction)],O=[v[0]+this.curvature*Math.cos(h.direction),v[1]+this.curvature*Math.sin(h.direction)],V=[p[0]+this.detourX,p[1]+this.detourY],D=[v[0]+this.detourX,v[1]+this.detourY],at=[`M ${w[0]} ${w[1]}`,`L ${p[0]} ${p[1]}`,`C ${b[0]} ${b[1]} ${V[0]} ${V[1]} ${A[0]} ${A[1]}`,`C ${D[0]} ${D[1]} ${O[0]} ${O[1]} ${v[0]} ${v[1]}`,`L ${m[0]} ${m[1]}`].join(" ");if(this.line.setAttribute("d",at),this.sourceArrow){const k=$(u,0,0,this.arrowLength,this.arrowWidth);this.sourceArrow.setAttribute("d",k)}if(this.targetArrow){const k=$(g,s,o,-this.arrowLength,this.arrowWidth);this.targetArrow.setAttribute("d",k)}}}const Y=r=>t=>t===x.PortCycle?new R(r.color,r.width,r.arrowLength,r.arrowWidth,r.hasSourceArrow||r.hasTargetArrow,r.cycleRadius,r.smallCycleRadius):t===x.NodeCycle?new K(r.color,r.width,r.curvature,r.arrowLength,r.arrowWidth,r.hasSourceArrow,r.hasTargetArrow,r.detourDistance,r.detourDirection):new W(r.color,r.width,r.curvature,r.arrowLength,r.arrowWidth,r.hasSourceArrow,r.hasTargetArrow),X=r=>t=>t===x.PortCycle?new B(r.color,r.width,r.arrowLength,r.arrowWidth,r.hasSourceArrow||r.hasTargetArrow,r.cycleSquareSide,r.arrowOffset,r.roundness):t===x.NodeCycle?new z(r.color,r.width,r.arrowLength,r.arrowWidth,r.arrowOffset,r.hasSourceArrow,r.hasTargetArrow,r.roundness,r.detourDistance,r.detourDirection):new j(r.color,r.width,r.arrowLength,r.arrowWidth,r.arrowOffset,r.hasSourceArrow,r.hasTargetArrow,r.roundness);class L{constructor(){n(this,"counter",0)}next(){const t=`${this.counter}`;return this.counter++,t}reset(){this.counter=0}}class Q{constructor(t,e,s,o,i,h){n(this,"nodeIdGenerator",new L);n(this,"portIdGenerator",new L);n(this,"edgeIdGenerator",new L);this.graphStore=t,this.htmlController=e,this.viewportTransformer=s,this.nodesCenterFn=o,this.portsCenterFn=i,this.portsDirection=h}moveNodeOnTop(t){if(!this.graphStore.hasNode(t))throw new Error("failed to move on top nonexisting node");this.htmlController.moveNodeOnTop(t)}addNode(t,e,s,o,i,h){if(t===void 0)do t=this.nodeIdGenerator.next();while(this.graphStore.hasNode(t));if(this.graphStore.hasNode(t))throw new Error("failed to add node with existing id");this.graphStore.addNode(t,e,s,o,h??this.nodesCenterFn),this.htmlController.attachNode(t),i!==void 0&&Object.entries(i).forEach(([a,c])=>{c instanceof HTMLElement?this.markPort(a,c,t,this.portsCenterFn,this.portsDirection):this.markPort(a,c.element,t,c.centerFn??this.portsCenterFn,c.direction??this.portsDirection)})}markPort(t,e,s,o,i){if(t===void 0)do t=this.portIdGenerator.next();while(this.graphStore.hasPort(t));if(!this.graphStore.hasNode(s))throw new Error("failed to set port on nonexisting node");if(this.graphStore.hasPort(t))throw new Error("failed to add port with existing id");this.graphStore.addPort(t,e,s,o??this.portsCenterFn,i??0)}updatePortEdges(t){if(!this.graphStore.hasPort(t))throw new Error("failed to unset nonexisting port");this.htmlController.updatePortEdges(t)}unmarkPort(t){if(!this.graphStore.hasPort(t))throw new Error("failed to unset nonexisting port");this.graphStore.getPortAdjacentEdges(t).forEach(e=>{this.removeEdge(e)}),this.graphStore.removePort(t)}addEdge(t,e,s,o){if(t===void 0)do t=this.edgeIdGenerator.next();while(this.graphStore.hasEdge(t));if(!this.graphStore.hasPort(e))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 i=x.Regular;const h=this.graphStore.getPortNode(e),a=this.graphStore.getPortNode(s);e===s?i=x.PortCycle:h===a&&(i=x.NodeCycle),this.graphStore.addEdge(t,e,s,o(i)),this.htmlController.attachEdge(t)}removeEdge(t){if(!this.graphStore.hasEdge(t))throw new Error("failed to remove nonexisting edge");this.htmlController.detachEdge(t),this.graphStore.removeEdge(t)}removeNode(t){if(!this.graphStore.hasNode(t))throw new Error("failed to remove nonexisting node");this.htmlController.detachNode(t),this.graphStore.removeNode(t)}patchViewportState(t,e,s){this.viewportTransformer.patchState(t,e,s),this.htmlController.applyTransform()}moveToNodes(t){if(t.length===0)return;const e=t.map(g=>this.graphStore.getNode(g)).filter(g=>g!==void 0);if(e.length<t.length)throw new Error("failed to move to nonexisting node");const[s,o]=e.reduce((g,w)=>[g[0]+w.x,g[1]+w.y],[0,0]),i=s/e.length,h=o/e.length,[a,c]=this.htmlController.getViewportDimensions(),l=this.viewportTransformer.getAbsScale(),d=i-l*a/2,u=h-l*c/2;this.patchViewportState(null,d,u)}updateNodeCoordinates(t,e,s){if(!this.graphStore.hasNode(t))throw new Error("failed to update coordinates of nonexisting node");this.graphStore.updateNodeCoords(t,e,s),this.htmlController.updateNodeCoordinates(t)}updateEdgeController(t,e){if(!this.graphStore.hasEdge(t))throw new Error("failed to update nonexisting edge");this.htmlController.detachEdge(t),this.graphStore.updateEdgeController(t,e),this.htmlController.attachEdge(t)}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()}destroy(){this.htmlController.destroy()}}class I{constructor(t,e,s,o,i){n(this,"publicViewportTransformer");n(this,"canvasController");const h=new P,a=new J;this.publicViewportTransformer=new _(h);const c=new N(a,h,this.publicViewportTransformer,t,e);this.canvasController=new Q(a,c,h,s,o,i)}}const G=(r,t)=>[r/2,t/2],tt=()=>()=>{},et=(r,t,e,s,o,i)=>{r.clearRect(0,0,r.canvas.width,r.canvas.height),r.fillStyle=i,r.fillRect(0,0,r.canvas.width,r.canvas.height);const h=t.getViewCoords(0,0),a=t.getViewScale(),c=s*a;let l=0,d=0,u=c/2;do u*=2,l=r.canvas.width/u,d=r.canvas.height/u;while(l*d>1e4);const g=h[0]-Math.floor(h[0]/u)*u,w=h[1]-Math.floor(h[1]/u)*u,m=o*a,C=2*Math.PI,p=g-u,E=w-u,v=r.canvas.width+g,y=r.canvas.height+w;r.fillStyle=e;for(let A=p;A<=v;A+=u)for(let b=E;b<=y;b+=u)r.beginPath(),r.arc(A,b,m,0,C),r.closePath(),r.fill()},st=(r,t,e,s)=>(o,i)=>{et(o,i,r,t,e,s)},rt=(r,t)=>{r.fillStyle=t,r.fillRect(0,0,r.canvas.width,r.canvas.height)},ot=r=>t=>{rt(t,r)},nt=r=>{switch(r==null?void 0:r.type){case"custom":return r.drawingFn;case"dots":return st(r.dotColor??"#d8d8d8",r.dotGap??25,r.dotRadius??1.5,r.color??"#ffffff");case"color":return ot(r.color??"#ffffff");default:return tt()}},U=r=>{switch(r==null?void 0:r.type){case"custom":return r.controllerFactory;case"straight":return X({color:r.color??"#5c5c5c",width:r.width??1,arrowLength:r.arrowLength??15,arrowWidth:r.arrowWidth??4,arrowOffset:r.arrowOffset??15,hasSourceArrow:r.hasSourceArrow??!1,hasTargetArrow:r.hasTargetArrow??!1,cycleSquareSide:r.cycleSquareSide??30,roundness:r.roundness??10,detourDistance:r.detourDistance??100,detourDirection:r.detourDirection??-Math.PI/2});default:return Y({color:r.color??"#5c5c5c",width:r.width??1,curvature:r.curvature??90,arrowLength:r.arrowLength??15,arrowWidth:r.arrowWidth??4,hasSourceArrow:r.hasSourceArrow??!1,hasTargetArrow:r.hasTargetArrow??!1,cycleRadius:r.cycleRadius??30,smallCycleRadius:r.smallCycleRadius??15,detourDistance:r.detourDistance??100,detourDirection:r.detourDirection??-Math.PI/2})}},it=r=>{var t,e,s,o;return{background:{drawingFn:nt(r.background??{type:"none"})},nodes:{centerFn:((t=r.nodes)==null?void 0:t.centerFn)??G},ports:{centerFn:((e=r.ports)==null?void 0:e.centerFn)??G,direction:((s=r.ports)==null?void 0:s.direction)??0},edges:{controllerFactory:U(r.edges??{})},layers:{mode:((o=r.layers)==null?void 0:o.mode)??"edges-follow-node"}}};class Z{constructor(t){n(this,"transformation");n(this,"di");n(this,"edgeControllerFactory");this.apiOptions=t;const e=it(this.apiOptions??{});this.di=new I(e.layers.mode,e.background.drawingFn,e.nodes.centerFn,e.ports.centerFn,e.ports.direction),this.transformation=this.di.publicViewportTransformer,this.edgeControllerFactory=e.edges.controllerFactory}addNode(t){return this.di.canvasController.addNode(t.id,t.element,t.x,t.y,t.ports,t.centerFn),this}moveNodeOnTop(t){return this.di.canvasController.moveNodeOnTop(t),this}removeNode(t){return this.di.canvasController.removeNode(t),this}markPort(t){return this.di.canvasController.markPort(t.id,t.element,t.nodeId,t.centerFn,t.direction),this}updatePortEdges(t){return this.di.canvasController.updatePortEdges(t),this}unmarkPort(t){return this.di.canvasController.unmarkPort(t),this}addEdge(t){const e=t.options!==void 0?U(t.options):this.edgeControllerFactory;return this.di.canvasController.addEdge(t.id,t.from,t.to,e),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}updateNodeCoordinates(t,e,s){return this.di.canvasController.updateNodeCoordinates(t,e,s),this}updateEdge(t,e){return e.controller!==void 0&&this.di.canvasController.updateEdgeController(t,e.controller),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 H{constructor(t,e){n(this,"transformation");n(this,"nodes",new Map);n(this,"grabbedNodeId",null);n(this,"onNodeDrag");n(this,"onBeforeNodeDrag");n(this,"nodeIdGenerator",new L);n(this,"element",null);n(this,"onCanvasMouseUp",()=>{this.setCursor(null),this.grabbedNodeId=null});n(this,"onCanvasMouseMove",t=>{this.grabbedNodeId!==null&&(t.stopPropagation(),this.dragNode(this.grabbedNodeId,t.movementX,t.movementY))});n(this,"onCanvasTouchStart",t=>{this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]});n(this,"onCanvasTouchMove",t=>{if(this.grabbedNodeId===null||t.touches.length!==1||this.previousTouchCoords===null)return;t.stopImmediatePropagation();const[e,s]=[t.touches[0].clientX-this.previousTouchCoords[0],t.touches[0].clientY-this.previousTouchCoords[1]];this.dragNode(this.grabbedNodeId,e,s),this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]});n(this,"onCanvasTouchEnd",t=>{t.touches.length>0?this.previousTouchCoords=[t.touches[0].clientX,t.touches[0].clientY]:(this.previousTouchCoords=null,this.grabbedNodeId=null)});n(this,"previousTouchCoords",null);var i,h;this.canvas=t,this.transformation=this.canvas.transformation;const s=()=>{};this.onNodeDrag=((i=e==null?void 0:e.events)==null?void 0:i.onNodeDrag)??s;const o=()=>!0;this.onBeforeNodeDrag=((h=e==null?void 0:e.events)==null?void 0:h.onBeforeNodeDrag)??o}addNode(t){let e=t.id;if(e===void 0)do e=this.nodeIdGenerator.next();while(this.nodes.has(e));this.canvas.addNode(t);const s=i=>{this.onBeforeNodeDrag({nodeId:e,element:t.element,x:t.x,y:t.y})&&(i.stopImmediatePropagation(),this.grabbedNodeId=e,this.setCursor("grab"),this.canvas.moveNodeOnTop(e))},o=i=>{this.onBeforeNodeDrag({nodeId:e,element:t.element,x:t.x,y:t.y})&&i.touches.length===1&&(this.grabbedNodeId=e,this.canvas.moveNodeOnTop(e))};return this.nodes.set(e,{element:t.element,onMouseDown:s,onTouchStart:o,x:t.x,y:t.y}),t.element.addEventListener("mousedown",s),t.element.addEventListener("touchstart",o),this}removeNode(t){const e=this.nodes.get(t);return e!==void 0&&(e.element.removeEventListener("mousedown",e.onMouseDown),e.element.removeEventListener("touchstart",e.onTouchStart)),this.canvas.removeNode(t),this.nodes.delete(t),this}markPort(t){return this.canvas.markPort(t),this}updatePortEdges(t){return this.canvas.updatePortEdges(t),this}unmarkPort(t){return this.canvas.unmarkPort(t),this}addEdge(t){return this.canvas.addEdge(t),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}updateNodeCoordinates(t,e,s){return this.canvas.updateNodeCoordinates(t,e,s),this}updateEdge(t,e){return this.canvas.updateEdge(t,e),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,e,s){const o=this.nodes.get(t);if(o===void 0)throw new Error("failed to drag nonexisting node");const[i,h]=this.transformation.getViewCoords(o.x,o.y),a=i+e,c=h+s,[l,d]=this.transformation.getAbsCoords(a,c);o.x=l,o.y=d,this.canvas.updateNodeCoordinates(t,l,d),this.onNodeDrag({nodeId:t,element:o.element,x:o.x,y:o.y})}}class q{constructor(t,e){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",t=>{if(!this.isMoving||!this.isShiftable)return;const e=-t.movementX,s=-t.movementY;this.moveViewport(e,s)});n(this,"onMouseUp",()=>{this.setCursor(null),this.isMoving=!1});n(this,"onWheelScroll",t=>{if(this.element===null||this.isScalable===!1)return;t.preventDefault();const{left:e,top:s}=this.element.getBoundingClientRect(),o=t.clientX-e,i=t.clientY-s,a=1/(t.deltaY<0?this.wheelSensitivity:1/this.wheelSensitivity);this.scaleViewport(a,o,i)});n(this,"onTouchStart",t=>{this.prevTouches=this.getAverageTouch(t)});n(this,"onTouchMove",t=>{if(this.prevTouches===null||this.element===null||!this.isShiftable)return;const e=this.getAverageTouch(t);if((e.touchesCnt===1||e.touchesCnt===2)&&this.moveViewport(-(e.x-this.prevTouches.x),-(e.y-this.prevTouches.y)),e.touchesCnt===2&&this.isScalable){const{left:s,top:o}=this.element.getBoundingClientRect(),i=this.prevTouches.x-s,h=this.prevTouches.y-o,c=1/(e.scale/this.prevTouches.scale);this.scaleViewport(c,i,h)}this.prevTouches=e,t.preventDefault()});n(this,"onTouchEnd",t=>{t.touches.length>0?this.prevTouches=this.getAverageTouch(t):this.prevTouches=null});var c,l,d,u,g,w,m,C,p,E,v,y;this.canvas=t,this.options=e,this.transformation=this.canvas.transformation;const s=((l=(c=this.options)==null?void 0:c.scale)==null?void 0:l.min)??null,o=((u=(d=this.options)==null?void 0:d.scale)==null?void 0:u.max)??null;this.isScalable=((w=(g=this.options)==null?void 0:g.scale)==null?void 0:w.enabled)!==!1,this.minViewScale=o!==null?1/o:null,this.maxViewScale=s!==null?1/s:null,this.isShiftable=((C=(m=this.options)==null?void 0:m.shift)==null?void 0:C.enabled)!==!1;const i=(E=(p=this.options)==null?void 0:p.scale)==null?void 0:E.wheelSensitivity;this.wheelSensitivity=i!==void 0?i:1.2;const h=()=>{};this.onTransform=((v=e==null?void 0:e.events)==null?void 0:v.onTransform)??h;const a=()=>!0;this.onBeforeTransform=((y=e==null?void 0:e.events)==null?void 0:y.onBeforeTransform)??a}addNode(t){return this.canvas.addNode(t),this}removeNode(t){return this.canvas.removeNode(t),this}markPort(t){return this.canvas.markPort(t),this}updatePortEdges(t){return this.canvas.updatePortEdges(t),this}unmarkPort(t){return this.canvas.unmarkPort(t),this}addEdge(t){return this.canvas.addEdge(t),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}updateNodeCoordinates(t,e,s){return this.canvas.updateNodeCoordinates(t,e,s),this}updateEdge(t,e){return this.canvas.updateEdge(t,e),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 e=[],s=t.touches.length;for(let c=0;c<s;c++)e.push([t.touches[c].clientX,t.touches[c].clientY]);const o=e.reduce((c,l)=>[c[0]+l[0],c[1]+l[1]],[0,0]),i=[o[0]/s,o[1]/s],a=e.map(c=>[c[0]-i[0],c[1]-i[1]]).reduce((c,l)=>c+Math.sqrt(l[0]*l[0]+l[1]*l[1]),0);return{x:i[0],y:i[1],scale:a/s,touchesCnt:s}}setCursor(t){this.element!==null&&(t!==null?this.element.style.cursor=t:this.element.style.removeProperty("cursor"))}moveViewport(t,e){const[s,o]=this.transformation.getAbsCoords(0,0),i=this.canvas.transformation.getAbsScale(),h={scale:i,x:s+i*t,y:o+i*e};this.onBeforeTransform({...h})&&(this.canvas.patchViewportState(h),this.onTransform(h))}scaleViewport(t,e,s){const[o,i]=this.canvas.transformation.getAbsCoords(0,0),h=this.canvas.transformation.getAbsScale(),a=h*t,c=h*(1-t)*e+o,l=h*(1-t)*s+i;if(this.maxViewScale!==null&&a>this.maxViewScale&&a>h||this.minViewScale!==null&&a<this.minViewScale&&a<h)return;const d={scale:a,x:c,y:l};this.onBeforeTransform({...d})&&(this.canvas.patchViewportState(d),this.onTransform(d))}}class ht{constructor(){n(this,"coreOptions");n(this,"dragOptions");n(this,"transformOptions");n(this,"isDraggable",!1);n(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 Z(this.coreOptions);return this.isDraggable&&(t=new H(t,this.dragOptions)),this.isTransformable&&(t=new q(t,this.transformOptions)),t}}f.BezierEdgeController=W,f.CanvasCore=Z,f.CycleCircleEdgeController=R,f.CycleSquareEdgeController=B,f.DetourStraightEdgeController=z,f.EdgeType=x,f.HtmlGraphBuilder=ht,f.StraightEdgeController=j,f.UserDraggableNodesCanvas=H,f.UserTransformableCanvas=q,f.createBezierEdgeControllerFactory=Y,f.createStraightEdgeControllerFactory=X,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@html-graph/html-graph",
3
3
  "author": "Dmitry Marov",
4
4
  "private": false,
5
- "version": "0.0.50",
5
+ "version": "0.0.51",
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",