drawui-core 0.2.0 → 0.2.2

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/index.cjs CHANGED
@@ -1,4 +1,43 @@
1
- 'use strict';var Y={identity(){return {a:1,b:0,c:0,d:1,e:0,f:0}},translation(d,e){return {a:1,b:0,c:0,d:1,e:d,f:e}},rotation(d){let e=Math.cos(d),t=Math.sin(d);return {a:e,b:t,c:-t,d:e,e:0,f:0}},scale(d,e){return {a:d,b:0,c:0,d:e,e:0,f:0}},multiply(d,e){return {a:d.a*e.a+d.b*e.c,b:d.a*e.b+d.b*e.d,c:d.c*e.a+d.d*e.c,d:d.c*e.b+d.d*e.d,e:d.e*e.a+d.f*e.c+e.e,f:d.e*e.b+d.f*e.d+e.f}},apply(d,e){return {x:d.a*e.x+d.c*e.y+d.e,y:d.b*e.x+d.d*e.y+d.f}},invert(d){let e=d.a*d.d-d.b*d.c;if(Math.abs(e)<1e-10)return null;let t=1/e;return {a:d.d*t,b:-d.b*t,c:-d.c*t,d:d.a*t,e:(d.c*d.f-d.d*d.e)*t,f:(d.b*d.e-d.a*d.f)*t}},createCameraMatrix(d){let e=Y.scale(d.zoom,d.zoom),t=Y.translation(d.x,d.y);return Y.multiply(t,e)}};var ee=class{x=0;y=0;zoom=1;minZoom=.1;maxZoom=10;getMatrix(){return Y.createCameraMatrix({x:this.x,y:this.y,zoom:this.zoom})}getInverseMatrix(){return Y.invert(this.getMatrix())}screenToPage(e){let t=this.getInverseMatrix();return t?Y.apply(t,e):e}pageToScreen(e){return Y.apply(this.getMatrix(),e)}translate(e,t){this.x+=e,this.y+=t;}zoomAt(e,t){let i=this.screenToPage(e);this.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.zoom*t));let n=this.pageToScreen(i);this.x+=e.x-n.x,this.y+=e.y-n.y;}reset(){this.x=0,this.y=0,this.zoom=1;}getZoom(){return this.zoom}fitBounds(e,t=50){let i=window.innerWidth,n=window.innerHeight,s=(i-t*2)/e.width,r=(n-t*2)/e.height,o=Math.min(s,r,this.maxZoom);this.zoom=Math.max(this.minZoom,o),this.x=(i-e.width*this.zoom)/2-e.x*this.zoom,this.y=(n-e.height*this.zoom)/2-e.y*this.zoom;}};var Ne={primary:"#3b82f6",selection:{outline:"#3b82f6",handleStroke:"#3b82f6",handleFill:"#ffffff",outlineFill:"rgba(59, 130, 246, 0.1)",shadow:"#3b82f6"},grid:"#e5e7eb",text:"#1f2937",editBorder:"#3b82f6",brushFill:"rgba(59, 130, 246, 0.08)",brushStroke:"rgba(59, 130, 246, 0.8)",guide:"rgba(59, 130, 246, 0.6)",lineHighlight:"rgba(59, 130, 246, 0.4)",genDot:"#3b82f6",genLine:"rgba(59, 130, 246, 0.55)"},v={...Ne,selection:{...Ne.selection}},Me=new Set;function Ge(d){return Me.add(d),()=>Me.delete(d)}function de(d){d.selection&&Object.assign(v.selection,d.selection);for(let e of Object.keys(d)){if(e==="selection")continue;let t=d[e];t!==void 0&&(v[e]=t);}Me.forEach(e=>e());}function Oe(){return v}function q(d,e){let t=Re(d);if(!t)return d;let i=parseInt(t,16),n=i>>16&255,s=i>>8&255,r=i&255;return `rgba(${n}, ${s}, ${r}, ${e})`}function ze(d,e){let t=Re(d);if(!t)return d;let i=parseInt(t,16),n=e<0?0:255,s=Math.abs(e),r=o=>Math.round((n-o)*s+o).toString(16).padStart(2,"0");return `#${r(i>>16&255)}${r(i>>8&255)}${r(i&255)}`}function Re(d){let e=d.replace("#","").trim();return /^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(e)?e.length===3?e.split("").map(t=>t+t).join(""):e:null}var H=class{context;constructor(e){this.context=e;}getCursor(e){return null}dispose(){}};var He={"zh-CN":{"save.success":"\u5DF2\u4FDD\u5B58","save.fail":"\u4FDD\u5B58\u5931\u8D25","tool.select":"\u9009\u62E9\u5DE5\u5177","tool.hand":"\u62D6\u62FD\u89C6\u53E3","tool.rectangle":"\u77E9\u5F62","tool.rounded-rectangle":"\u5706\u89D2\u77E9\u5F62","tool.circle":"\u5706\u5F62","tool.ellipse":"\u692D\u5706","tool.diamond":"\u83F1\u5F62","tool.triangle":"\u4E09\u89D2\u5F62","tool.hexagon":"\u516D\u8FB9\u5F62","tool.parallelogram":"\u5E73\u884C\u56DB\u8FB9\u5F62","tool.trapezoid":"\u68AF\u5F62","tool.pentagon":"\u4E94\u8FB9\u5F62","tool.octagon":"\u516B\u8FB9\u5F62","tool.star":"\u661F\u5F62","tool.uml-class":"UML \u7C7B\u56FE","tool.uml-interface":"UML \u63A5\u53E3","tool.line":"\u76F4\u7EBF","tool.arrow":"\u7EBF\u6761","tool.text":"\u6587\u672C","tool.draw":"\u753B\u7B14","tool.pen":"\u753B\u7B14","tool.highlighter":"\u8367\u5149\u7B14","tool.eraser":"\u6A61\u76AE\u64E6","status.none":"\u672A\u9009\u62E9","status.selected":"\u5DF2\u9009\u62E9 {n} \u4E2A\u56FE\u5F62","toolbar.select":"\u9009\u62E9 (V)","toolbar.hand":"\u62D6\u62FD\u89C6\u53E3 (H)","toolbar.shapes":"\u5F62\u72B6","toolbar.grid":"\u7F51\u683C","toolbar.undo":"\u64A4\u9500 (Ctrl+Z)","toolbar.redo":"\u91CD\u505A (Ctrl+Shift+Z)","toolbar.arrow":"\u7BAD\u5934","toolbar.text":"\u6587\u672C","toolbar.pen":"\u753B\u7B14","toolbar.highlighter":"\u8367\u5149\u7B14","toolbar.eraser":"\u6A61\u76AE\u64E6","toolbar.uml-class":"UML \u7C7B\u56FE","toolbar.uml-interface":"UML \u63A5\u53E3","zoom.in":"\u653E\u5927","zoom.out":"\u7F29\u5C0F","zoom.reset":"\u91CD\u7F6E","style.stroke":"\u8FB9\u6846","style.fill":"\u586B\u5145","style.text":"\u6587\u5B57","style.highlight":"\u9AD8\u4EAE","style.none":"\u65E0","style.connection":"\u8FDE\u7EBF","style.arrow":"\u7BAD\u5934","style.dashed":"\u865A\u7EBF","style.solid":"\u5B9E\u7EBF","style.connection.straight":"\u76F4\u7EBF","style.connection.polyline":"\u6298\u7EBF","style.connection.orthogonal":"\u76F4\u89D2\u6298\u7EBF","style.connection.curve":"\u66F2\u7EBF","style.arrowhead.none":"\u65E0\u7BAD\u5934","style.arrowhead.end":"\u7EC8\u70B9\u7BAD\u5934","style.arrowhead.start":"\u8D77\u70B9\u7BAD\u5934","style.arrowhead.both":"\u53CC\u7BAD\u5934","style.arrowhead.inheritance":"\u7EE7\u627F","style.arrowhead.composition":"\u7EC4\u5408","style.arrowhead.aggregation":"\u805A\u5408","menu.title":"\u9009\u62E9\u65B0\u56FE\u5F62","menu.cancel":"\u70B9\u51FB\u7A7A\u767D\u5904\u53D6\u6D88","shape.rectangle":"\u77E9\u5F62","shape.rounded-rectangle":"\u5706\u89D2","shape.circle":"\u5706\u5F62","shape.ellipse":"\u692D\u5706","shape.diamond":"\u83F1\u5F62","shape.triangle":"\u4E09\u89D2","shape.hexagon":"\u516D\u8FB9\u5F62","shape.parallelogram":"\u5E73\u884C","shape.trapezoid":"\u68AF\u5F62","shape.pentagon":"\u4E94\u8FB9\u5F62","shape.octagon":"\u516B\u8FB9\u5F62","shape.star":"\u661F\u5F62","shape.uml-class":"\u7C7B\u56FE","shape.uml-interface":"\u63A5\u53E3","uml.drag":"\u62D6\u62FD\u6392\u5E8F","uml.delete":"\u5220\u9664\u8BE5\u884C","uml.textColor":"\u6587\u5B57\u989C\u8272","uml.defaultColor":"\u9ED8\u8BA4\u989C\u8272","uml.fontSize":"\u5B57\u53F7","uml.strikethrough":"\u5220\u9664\u7EBF","uml.attribute":"\u5C5E\u6027","uml.method":"\u65B9\u6CD5","minimap.title":"\u5C0F\u5730\u56FE","minimap.expand":"\u5C55\u5F00\u5C0F\u5730\u56FE","minimap.collapse":"\u6536\u8D77\u5C0F\u5730\u56FE","tool.mind-map":"\u601D\u7EF4\u5BFC\u56FE","toolbar.mind-map":"\u601D\u7EF4\u5BFC\u56FE","shape.mind-map":"\u601D\u7EF4\u5BFC\u56FE","mindmap.defaultRoot":"\u4E2D\u5FC3\u4E3B\u9898","mindmap.defaultBranch":"\u5206\u652F\u4E3B\u9898","mindmap.nodeText":"\u8282\u70B9\u6587\u672C","mindmap.addChild":"\u5B50\u8282\u70B9","mindmap.addSibling":"\u5144\u5F1F\u8282\u70B9","mindmap.deleteNode":"\u5220\u9664\u8282\u70B9","mindmap.color":"\u989C\u8272","mindmap.levelColor":"\u9ED8\u8BA4\u5C42\u7EA7\u8272","mindmap.icon":"\u56FE\u6807","mindmap.noIcon":"\u65E0\u56FE\u6807","mindmap.note":"\u5C5E\u6027\u8BF4\u660E","mindmap.notePlaceholder":"\u8BF4\u660E\u5185\u5BB9\uFF08\u53EF\u9009\uFF09","mindmap.noteColor":"\u8BF4\u660E\u989C\u8272","mindmap.noteColorDefault":"\u540C\u8282\u70B9\u8272","mindmap.collapse":"\u6298\u53E0","mindmap.expand":"\u5C55\u5F00","mindmap.close":"\u5173\u95ED\u7F16\u8F91","mindmap.more":"\u66F4\u591A\u8BBE\u7F6E"},"en-US":{"save.success":"Saved","save.fail":"Save failed","tool.select":"Select tool","tool.hand":"Pan view","tool.rectangle":"Rectangle","tool.rounded-rectangle":"Rounded rectangle","tool.circle":"Circle","tool.ellipse":"Ellipse","tool.diamond":"Diamond","tool.triangle":"Triangle","tool.hexagon":"Hexagon","tool.parallelogram":"Parallelogram","tool.trapezoid":"Trapezoid","tool.pentagon":"Pentagon","tool.octagon":"Octagon","tool.star":"Star","tool.uml-class":"UML class","tool.uml-interface":"UML interface","tool.line":"Line","tool.arrow":"Line","tool.text":"Text","tool.draw":"Pen","tool.pen":"Pen","tool.highlighter":"Highlighter","tool.eraser":"Eraser","status.none":"Nothing selected","status.selected":"{n} shapes selected","toolbar.select":"Select (V)","toolbar.hand":"Pan view (H)","toolbar.shapes":"Shapes","toolbar.grid":"Grid","toolbar.undo":"Undo (Ctrl+Z)","toolbar.redo":"Redo (Ctrl+Shift+Z)","toolbar.arrow":"Arrow","toolbar.text":"Text","toolbar.pen":"Pen","toolbar.highlighter":"Highlighter","toolbar.eraser":"Eraser","toolbar.uml-class":"UML class","toolbar.uml-interface":"UML interface","zoom.in":"Zoom in","zoom.out":"Zoom out","zoom.reset":"Reset","style.stroke":"Border","style.fill":"Fill","style.text":"Text","style.highlight":"Highlight","style.none":"None","style.connection":"Connection","style.arrow":"Arrow head","style.dashed":"Dashed","style.solid":"Solid","style.connection.straight":"Straight","style.connection.polyline":"Polyline","style.connection.orthogonal":"Orthogonal","style.connection.curve":"Curve","style.arrowhead.none":"None","style.arrowhead.end":"End","style.arrowhead.start":"Start","style.arrowhead.both":"Both","style.arrowhead.inheritance":"Inheritance","style.arrowhead.composition":"Composition","style.arrowhead.aggregation":"Aggregation","menu.title":"Create shape","menu.cancel":"Click empty space to cancel","shape.rectangle":"Rectangle","shape.rounded-rectangle":"Rounded","shape.circle":"Circle","shape.ellipse":"Ellipse","shape.diamond":"Diamond","shape.triangle":"Triangle","shape.hexagon":"Hexagon","shape.parallelogram":"Parallelogram","shape.trapezoid":"Trapezoid","shape.pentagon":"Pentagon","shape.octagon":"Octagon","shape.star":"Star","shape.uml-class":"Class","shape.uml-interface":"Interface","uml.drag":"Drag to reorder","uml.delete":"Delete row","uml.textColor":"Text color","uml.defaultColor":"Default color","uml.fontSize":"Font size","uml.strikethrough":"Strikethrough","uml.attribute":"Attributes","uml.method":"Methods","minimap.title":"Minimap","minimap.expand":"Expand minimap","minimap.collapse":"Collapse minimap","tool.mind-map":"Mind map","toolbar.mind-map":"Mind map","shape.mind-map":"Mind map","mindmap.defaultRoot":"Central topic","mindmap.defaultBranch":"Branch topic","mindmap.nodeText":"Node text","mindmap.addChild":"Child","mindmap.addSibling":"Sibling","mindmap.deleteNode":"Delete node","mindmap.color":"Color","mindmap.levelColor":"Default level color","mindmap.icon":"Icon","mindmap.noIcon":"No icon","mindmap.note":"Note","mindmap.notePlaceholder":"Note content (optional)","mindmap.noteColor":"Note color","mindmap.noteColorDefault":"Same as node","mindmap.collapse":"Collapse","mindmap.expand":"Expand","mindmap.close":"Close editor","mindmap.more":"More settings"}},ce="zh-CN",ve=new Set;function ue(d){ce!==d&&(ce=d,ve.forEach(e=>e()));}function $e(){return ce}function Ke(d){return ve.add(d),()=>ve.delete(d)}function z(d,e){let i=He[ce][d]??He["zh-CN"][d];if(e)for(let[n,s]of Object.entries(e))i=i.replace(new RegExp(`\\{${n}\\}`,"g"),String(s));return i}var Te=["#ef4444","#f59e0b","#10b981","#3b82f6","#8b5cf6","#ec4899"],pe=14,We=40,Ye=80,Xe=240;function ge(d,e){return d.color??Te[e%Te.length]}function Ve(d){let e=d.text||"",t=0;for(let n of e)t+=/[\u2e80-\u9fff\uf900-\ufaff\uff00-\uffef\u3000-\u303f]/.test(n)?1:.6;let i=Math.max(80,Math.min(240,Math.ceil(t*14)+24));return d.icon&&(i+=26),{width:i,height:40}}function ye(d){let e={...d};return d.children&&(e.children=d.children.map(t=>ye(t))),e}function me(d,e,t){if(d.id===e)return {...d,...t};let i=d.children??[],n=i.map(s=>me(s,e,t));return n.some((s,r)=>s!==i[r])?{...d,children:n}:d}function Pe(d,e,t){if(d.id===e)return {...d,children:[...d.children??[],t],collapsed:false};let i=d.children??[],n=i.map(s=>Pe(s,e,t));return n.some((s,r)=>s!==i[r])?{...d,children:n}:d}function Ie(d,e,t){let i=d.children??[];for(let n=0;n<i.length;n++){if(i[n].id===e){let r=[...i];return r.splice(n+1,0,t),{...d,children:r}}let s=Ie(i[n],e,t);if(s!==i[n])return {...d,children:i.map(r=>r===i[n]?s:r)}}return d}function Ce(d,e){if(d.id===e)return null;let t=d.children??[],i=t.map(n=>Ce(n,e)).filter(n=>n!==null);return i.length!==t.length||i.some((n,s)=>n!==t[s])?{...d,children:i}:d}function F(d,e){if(d.id===e)return d;for(let t of d.children??[]){let i=F(t,e);if(i)return i}return null}function ke(d,e){if(d.id===e)return 0;for(let t of d.children??[]){let i=ke(t,e);if(i!==-1)return i+1}return -1}function te(d,e){for(let t of d.children??[]){if(t.id===e)return d;let i=te(t,e);if(i)return i}return null}function Be(d){let e=1;for(let t of d.children??[])e+=Be(t);return e}function _e(d,e){e.set(d.id,Ve(d));for(let t of d.children??[])_e(t,e);}function k(d){let e=new Map;_e(d,e);let t=new Map,i=c=>{let p=c.collapsed?[]:c.children??[];if(p.length===0)t.set(c.id,e.get(c.id).height);else {let g=0;for(let m of p)g+=i(m);g+=16*(p.length-1),t.set(c.id,Math.max(e.get(c.id).height,g));}return t.get(c.id)};i(d);let n=new Map,s=(c,p,g,m)=>{let y=t.get(c.id),w=e.get(c.id);if(n.set(c.id,{x:g,y:m+y/2,depth:p,width:w.width,height:w.height}),c.collapsed)return;let f=m;for(let T of c.children??[]){let M=e.get(T.id);s(T,p+1,g+w.width/2+48+M.width/2,f),f+=t.get(T.id)+16;}};s(d,0,0,-t.get(d.id)/2);let r=1/0,o=-1/0,a=1/0,h=-1/0;n.forEach(c=>{r=Math.min(r,c.x-c.width/2),o=Math.max(o,c.x+c.width/2),a=Math.min(a,c.y-c.height/2),h=Math.max(h,c.y+c.height/2);});let l=(r+o)/2,u=(a+h)/2;return n.forEach(c=>{c.x-=l,c.y-=u;}),{positions:n,width:o-r,height:h-a}}var Fe={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},Ze={rectangle:{width:120,height:60},"rounded-rectangle":{width:120,height:60,borderRadius:8},circle:{width:80,height:80},ellipse:{width:100,height:70},diamond:{width:100,height:80},triangle:{width:100,height:90},hexagon:{width:100,height:90},parallelogram:{width:120,height:60},trapezoid:{width:120,height:70},pentagon:{width:100,height:90},octagon:{width:100,height:90},star:{width:100,height:100}},W=14,V=22,X=36,$=14,L=8,ne=160,qe=["rectangle","rounded-rectangle","circle","ellipse","diamond","triangle","hexagon","parallelogram","trapezoid","pentagon","octagon","star","uml-class","uml-interface","mind-map"];function fe(d){return qe.includes(d)}function Ee(d,e,t){let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,n=Ze[d]||{width:120,height:60},s=n.width,r=n.height,o=n.radius??s/2,a=n.borderRadius??8,h=t??{...Fe};switch(d){case "rounded-rectangle":return {id:i,type:"rounded-rectangle",x:e.x,y:e.y,width:s,height:r,borderRadius:a,rotation:0,style:h};case "circle":return {id:i,type:"circle",x:e.x,y:e.y,radius:o,rotation:0,style:h};case "ellipse":return {id:i,type:"ellipse",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "diamond":return {id:i,type:"diamond",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "triangle":return {id:i,type:"triangle",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "hexagon":return {id:i,type:"hexagon",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "parallelogram":return {id:i,type:"parallelogram",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "trapezoid":return {id:i,type:"trapezoid",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "pentagon":return {id:i,type:"pentagon",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "octagon":return {id:i,type:"octagon",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "star":return {id:i,type:"star",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h};case "uml-class":{let l="ClassName",u=[{id:`attr_${Date.now()}_1`,visibility:"+",name:"field",type:"string"}],c=[{id:`meth_${Date.now()}_1`,visibility:"+",name:"method",params:"param",returnType:"void"}],{width:p,height:g}=xe(l,u,c);return {id:i,type:"uml-class",x:e.x,y:e.y,width:p,height:g,className:l,attributes:u,methods:c,rotation:0,style:{...h,fillColor:"#ffffff"}}}case "uml-interface":{let l="Interface",u=[{id:`meth_${Date.now()}_1`,visibility:"+",name:"method",params:"type",returnType:"type"}],c=W*.6,p=u.map(f=>`${f.visibility} ${f.name}(${f.params}): ${f.returnType}`),g=Math.max(l.length,...p.map(f=>f.length),0),m=Math.max(ne,g*c+$*2),y=u.length>0?u.length*V+L*2:L*2,w=X+y;return {id:i,type:"uml-interface",x:e.x,y:e.y,width:m,height:w,className:l,methods:u,rotation:0,style:{...h,fillColor:"#ffffff"}}}case "mind-map":{let l=g=>`mm_${g}_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,u={id:l("root"),text:z("mindmap.defaultRoot"),children:[{id:l("b1"),text:z("mindmap.defaultBranch")},{id:l("b2"),text:z("mindmap.defaultBranch")},{id:l("b3"),text:z("mindmap.defaultBranch")}]},{width:c,height:p}=k(u);return {id:i,type:"mind-map",x:e.x,y:e.y,width:c,height:p,root:u,rotation:0,style:{...h,fillColor:"#ffffff"}}}default:return {id:i,type:"rectangle",x:e.x,y:e.y,width:s,height:r,rotation:0,style:h}}}function xe(d,e,t){let i=W*.6,n=[d];for(let u of e)n.push(`${u.visibility} ${u.name}: ${u.type}`);for(let u of t)n.push(`${u.visibility} ${u.name}(${u.params}): ${u.returnType}`);let r=Math.max(...n.map(u=>u.length),0)*i+$*2,o=Math.max(ne,r),a=e.length>0?e.length*V+L*2:L*2,h=t.length>0?t.length*V+L*2:L*2,l=X+a+h;return {width:o,height:l}}var R=class extends H{type;constructor(e,t){super(e),this.type=t;}onPointerDown(e,t){let i=Ee(this.type,e);this.context.commitHistory(),this.context.addShape(i),this.context.selectShape(i.id,false);}onPointerMove(e,t){}onPointerUp(e,t){this.context.setActiveTool("select");}onKeyDown(e){}onKeyUp(e){}getCursor(e){return this.context.getMindMapCursorHitAtPoint(e)?"pointer":"crosshair"}};var De=14,Se=class extends H{type="eraser";erasing=false;lastPoint=null;erasedIds=new Set;onPointerDown(e){this.erasing=true,this.lastPoint=e,this.erasedIds.clear(),this.context.commitHistory(),this.context.setEraserPoint(e),this.eraseAt(e);}onPointerMove(e){if(!this.erasing||!this.lastPoint)return;let t=this.lastPoint,i=Math.hypot(e.x-t.x,e.y-t.y),n=Math.max(1,Math.ceil(i/Math.max(this.brushRadius()*.5,1)));for(let s=1;s<=n;s++){let r=s/n;this.eraseAt({x:t.x+(e.x-t.x)*r,y:t.y+(e.y-t.y)*r});}this.lastPoint=e,this.context.setEraserPoint(e);}onPointerUp(){this.erasing=false,this.lastPoint=null,this.erasedIds.clear(),this.context.setEraserPoint(null);}onKeyDown(){}onKeyUp(){}getCursor(){return this.erasing?"grabbing":"crosshair"}dispose(){this.erasing=false,this.lastPoint=null,this.erasedIds.clear(),this.context.setEraserPoint(null);}brushRadius(){return De/this.context.getCamera().getZoom()}eraseAt(e){let t=this.context.getShapesInBrushRadius(e,this.brushRadius());for(let i of t)this.erasedIds.has(i.id)||(this.erasedIds.add(i.id),this.context.deleteShape(i.id));}};var ie=class d{ctx;width=0;height=0;dpr=window.devicePixelRatio||1;showGrid=false;textLayoutCache=new Map;static TEXT_CACHE_LIMIT=500;constructor(e){let t=e.getContext("2d");if(!t)throw new Error("Failed to get Canvas 2D context");this.ctx=t;}resize(e,t){this.width=e,this.height=t;let i=Math.ceil(e*this.dpr),n=Math.ceil(t*this.dpr);(this.ctx.canvas.width!==i||this.ctx.canvas.height!==n)&&(this.ctx.canvas.width=i,this.ctx.canvas.height=n,this.ctx.canvas.style.width=`${e}px`,this.ctx.canvas.style.height=`${t}px`);}setShowGrid(e){this.showGrid=e;}render(e,t,i,n,s,r,o,a,h,l){let u=this.ctx,c=t.getZoom(),p=t.x,g=t.y;u.setTransform(1,0,0,1,0,0),u.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height);let m=this.dpr*c;u.setTransform(m,0,0,m,m*p,m*g),this.showGrid&&this.drawGrid(u,c,p,g);let y=null;for(let f of e)if(f.type==="arrow"&&(f.startBinding||f.endBinding)){y=new Map,e.forEach(T=>y.set(T.id,T));break}let w=y??new Map;e.forEach(f=>{u.save(),u.translate(f.x,f.y),u.rotate(f.rotation);let T=i.has(f.id);this.drawShape(u,f,T,c,w,h,l),u.restore();}),o&&this.drawGenerationPreview(u,o,c),n&&this.drawBrushRect(u,n,c),s&&s.length>0&&this.drawSnapGuides(u,s,c),r&&this.drawConnectingTargetHighlight(u,r,e,c),a&&this.drawEraserBrush(u,a,c),u.setTransform(1,0,0,1,0,0);}drawEraserBrush(e,t,i){let n=De/i;e.beginPath(),e.arc(t.x,t.y,n,0,Math.PI*2),e.fillStyle=q(v.primary,.12),e.fill(),e.strokeStyle=q(v.primary,.55),e.lineWidth=1.5/i,e.stroke();}drawConnectingTargetHighlight(e,t,i,n){let s=i.find(h=>h.id===t);if(!s||s.type==="line"||s.type==="arrow"||s.type==="draw")return;let r=this.getShapeWorldBounds(s),o=[{x:r.x+r.width/2,y:r.y},{x:r.x+r.width,y:r.y+r.height/2},{x:r.x+r.width/2,y:r.y+r.height},{x:r.x,y:r.y+r.height/2}],a=6/n;e.save(),o.forEach(h=>{e.beginPath(),e.arc(h.x,h.y,a,0,Math.PI*2),e.fillStyle=v.selection.handleFill,e.fill(),e.strokeStyle=v.primary,e.lineWidth=2/n,e.stroke();}),e.restore();}getShapeWorldBounds(e){let t=this.getShapeBounds(e);return {x:e.x+t.x,y:e.y+t.y,width:t.width,height:t.height}}drawBrushRect(e,t,i){e.save(),e.fillStyle=v.brushFill,e.strokeStyle=v.brushStroke,e.lineWidth=1.5/i,e.setLineDash([4/i,4/i]),e.beginPath(),e.rect(t.x,t.y,t.width,t.height),e.fill(),e.stroke(),e.restore();}drawGrid(e,t,i,n){let s=-i,r=-n,o=s+this.width/t,a=r+this.height/t,h=20;for(;h*t<10;)h*=2;e.strokeStyle=v.grid,e.lineWidth=1/t,e.beginPath();for(let l=Math.floor(s/h)*h;l<=o;l+=h)e.moveTo(l,r),e.lineTo(l,a);for(let l=Math.floor(r/h)*h;l<=a;l+=h)e.moveTo(s,l),e.lineTo(o,l);e.stroke();}drawShape(e,t,i,n,s,r,o){switch(this.applyStyle(e,t.style,n),t.type){case "rectangle":this.drawRectangle(e,t,i);break;case "rounded-rectangle":this.drawRoundedRectangle(e,t,i);break;case "circle":this.drawCircle(e,t,i);break;case "ellipse":this.drawEllipse(e,t,i);break;case "diamond":this.drawDiamond(e,t,i);break;case "triangle":this.drawTriangle(e,t,i);break;case "hexagon":this.drawHexagon(e,t,i);break;case "parallelogram":this.drawParallelogram(e,t,i);break;case "trapezoid":this.drawTrapezoid(e,t,i);break;case "pentagon":this.drawPentagon(e,t,i);break;case "octagon":this.drawOctagon(e,t,i);break;case "star":this.drawStar(e,t,i);break;case "uml-class":this.drawUmlClass(e,t,i);break;case "uml-interface":this.drawUmlInterface(e,t,i);break;case "mind-map":this.drawMindMap(e,t,i,r,o);break;case "line":this.drawLine(e,t,s,i,n);break;case "arrow":this.drawArrow(e,t,s,i,n);break;case "text":this.drawText(e,t);break;case "draw":this.drawFreehand(e,t);break}if(t.text&&t.type!=="text"&&t.type!=="line"&&t.type!=="arrow"&&t.type!=="draw"&&this.drawShapeText(e,t),i){let a=t.type==="line"||t.type==="arrow"||t.type==="draw";t.type==="mind-map"||(a?this.drawSelectionHandles(e,t,n):(this.drawSelectionOutline(e,t,n),this.drawSelectionHandles(e,t,n)));}}applyStyle(e,t,i){e.strokeStyle=t.strokeColor,e.fillStyle=t.fillColor,e.lineWidth=t.strokeWidth/i,e.lineCap="round",e.lineJoin="round",t.strokeDash?e.setLineDash(t.strokeDash):e.setLineDash([]);}drawRectangle(e,t,i){e.beginPath(),e.rect(-t.width/2,-t.height/2,t.width,t.height),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawRoundedRectangle(e,t,i){let{width:n,height:s,borderRadius:r}=t;e.beginPath(),e.roundRect(-n/2,-s/2,n,s,r),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawCircle(e,t,i){e.beginPath(),e.arc(0,0,t.radius,0,Math.PI*2),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawEllipse(e,t,i){e.beginPath(),e.ellipse(0,0,t.width/2,t.height/2,0,0,Math.PI*2),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawDiamond(e,t,i){e.beginPath(),e.moveTo(0,-t.height/2),e.lineTo(t.width/2,0),e.lineTo(0,t.height/2),e.lineTo(-t.width/2,0),e.closePath(),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawTriangle(e,t,i){e.beginPath(),e.moveTo(0,-t.height/2),e.lineTo(t.width/2,t.height/2),e.lineTo(-t.width/2,t.height/2),e.closePath(),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawHexagon(e,t,i){let n=t.width/2,s=t.height/2;e.beginPath();for(let r=0;r<6;r++){let o=r*Math.PI/3-Math.PI/2,a=n*Math.cos(o),h=s*Math.sin(o);r===0?e.moveTo(a,h):e.lineTo(a,h);}e.closePath(),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawParallelogram(e,t,i){let{width:n,height:s}=t,r=n*.2;e.beginPath(),e.moveTo(-n/2+r,-s/2),e.lineTo(n/2,-s/2),e.lineTo(n/2-r,s/2),e.lineTo(-n/2,s/2),e.closePath(),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawTrapezoid(e,t,i){let{width:n,height:s}=t,r=n*.15;e.beginPath(),e.moveTo(-n/2+r,-s/2),e.lineTo(n/2-r,-s/2),e.lineTo(n/2,s/2),e.lineTo(-n/2,s/2),e.closePath(),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawPentagon(e,t,i){let n=t.width/2,s=t.height/2;e.beginPath();for(let r=0;r<5;r++){let o=r*2*Math.PI/5-Math.PI/2,a=n*Math.cos(o),h=s*Math.sin(o);r===0?e.moveTo(a,h):e.lineTo(a,h);}e.closePath(),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawOctagon(e,t,i){let n=t.width/2,s=t.height/2;e.beginPath();for(let r=0;r<8;r++){let o=r*Math.PI/4-Math.PI/8,a=n*Math.cos(o),h=s*Math.sin(o);r===0?e.moveTo(a,h):e.lineTo(a,h);}e.closePath(),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawStar(e,t,i){let n=t.width/2,s=t.height/2,r=5,o=.4;e.beginPath();for(let a=0;a<r*2;a++){let h=a*Math.PI/r-Math.PI/2,l=a%2===0?1:o,u=n*l*Math.cos(h),c=s*l*Math.sin(h);a===0?e.moveTo(u,c):e.lineTo(u,c);}e.closePath(),t.style.fillColor!=="transparent"&&e.fill(),e.stroke();}drawUmlClass(e,t,i){let{width:n,height:s,className:r,attributes:o,methods:a}=t,h=n/2,l=s/2,u=X,c=o.length>0?o.length*V+L*2:L*2;e.beginPath(),e.rect(-h,-l,n,s),t.style.fillColor!=="transparent"&&(e.fillStyle=t.style.fillColor,e.fill()),e.stroke(),e.beginPath(),e.moveTo(-h,-l+u),e.lineTo(h,-l+u),e.moveTo(-h,-l+u+c),e.lineTo(h,-l+u+c),e.stroke(),e.save(),e.textBaseline="middle";let p=n-$*2,g=f=>{if(e.measureText(f).width<=p)return f;let T="\u2026",M=0,b=f.length;for(;M<b;){let I=M+b+1>>1;e.measureText(f.slice(0,I)+T).width<=p?M=I:b=I-1;}return f.slice(0,M)+T},m=(f,T,M,b,I,E,B)=>{let O=b||W,K=I||"#1f2937";e.font=`${O}px sans-serif`,e.fillStyle=K,e.textAlign=B;let A=g(f);if(e.fillText(A,T,M),E){let N=e.measureText(A).width,he=T;e.strokeStyle=K,e.beginPath(),e.moveTo(he,M),e.lineTo(he+N,M),e.stroke();}};e.font=`bold ${t.fontSize||W}px sans-serif`,e.textAlign="center",e.fillStyle=t.textColor||"#1f2937",e.fillText(g(r),0,-l+u/2);let y=-l+u+L+V/2;o.forEach((f,T)=>{let M=`${f.visibility} ${f.name}: ${f.type}`;m(M,-h+$,y+T*V,f.fontSize||t.fontSize||0,f.textColor||t.textColor||"",!!f.strikethrough,"left");});let w=-l+u+c+L+V/2;a.forEach((f,T)=>{let M=`${f.visibility} ${f.name}(${f.params}): ${f.returnType}`;m(M,-h+$,w+T*V,f.fontSize||t.fontSize||0,f.textColor||t.textColor||"",!!f.strikethrough,"left");}),e.restore();}drawUmlInterface(e,t,i){let{width:n,height:s,className:r,methods:o}=t,a=n/2,h=s/2,l=X;e.beginPath(),e.rect(-a,-h,n,s),t.style.fillColor!=="transparent"&&(e.fillStyle=t.style.fillColor,e.fill()),e.stroke(),e.beginPath(),e.moveTo(-a,-h+l),e.lineTo(a,-h+l),e.stroke(),e.save(),e.textBaseline="middle";let u=n-$*2,c=y=>{if(e.measureText(y).width<=u)return y;let w="\u2026",f=0,T=y.length;for(;f<T;){let M=f+T+1>>1;e.measureText(y.slice(0,M)+w).width<=u?f=M:T=M-1;}return y.slice(0,f)+w},p=(y,w,f,T,M,b,I)=>{let E=T||W,B=M||"#1f2937";e.font=`${E}px sans-serif`,e.fillStyle=B,e.textAlign=I;let O=c(y);if(e.fillText(O,w,f),b){let K=e.measureText(O).width,A=w;e.strokeStyle=B,e.beginPath(),e.moveTo(A,f),e.lineTo(A+K,f),e.stroke();}};e.font=`bold ${t.fontSize||W}px sans-serif`,e.textAlign="center",e.fillStyle=t.textColor||"#1f2937";let g=`<<${r||"Interface"}>>`;e.fillText(c(g),0,-h+l/2);let m=-h+l+L+V/2;o.forEach((y,w)=>{let f=`${y.visibility} ${y.name}(${y.params}): ${y.returnType}`;p(f,-a+$,m+w*V,y.fontSize||t.fontSize||0,y.textColor||t.textColor||"",!!y.strikethrough,"left");}),e.restore();}static DEFAULT_CORNER_RADIUS=10;static ROUTE_CLEARANCE=30;static CONNECTION_LEAD=24;static CONNECTED_PAD=8;drawMindMap(e,t,i,n,s){let o=k(t.root).positions;this.drawMindMapConnections(e,t.root,o),this.drawMindMapNodes(e,t,o,n,s);}drawMindMapConnections(e,t,i){let n=s=>{if(s.collapsed)return;let r=i.get(s.id);if(r)for(let o of s.children??[]){let a=i.get(o.id);if(!a)continue;let h=ge(o,a.depth);e.strokeStyle=h,e.lineWidth=2,e.lineCap="round",e.beginPath(),e.moveTo(r.x+r.width/2,r.y);let l=(r.x+r.width/2+(a.x-a.width/2))/2;e.bezierCurveTo(l,r.y,l,a.y,a.x-a.width/2,a.y),e.stroke(),n(o);}};n(t);}drawMindMapNodes(e,t,i,n,s){let r=t.root,o=a=>{let h=i.get(a.id);if(!h)return;let l=ge(a,h.depth),u=h.width/2,c=h.height/2;if(e.fillStyle="#ffffff",e.strokeStyle=l,e.lineWidth=2,e.beginPath(),e.roundRect(h.x-u,h.y-c,h.width,h.height,6),e.fill(),e.stroke(),s&&s.shapeId===t.id&&s.nodeId===a.id&&(e.fillStyle=q(v.primary,.06),e.strokeStyle=q(v.primary,.55),e.lineWidth=2,e.beginPath(),e.roundRect(h.x-u,h.y-c,h.width,h.height,6),e.fill(),e.stroke()),n&&n.shapeId===t.id&&n.nodeId===a.id&&(e.fillStyle=q(v.primary,.12),e.strokeStyle=v.primary,e.lineWidth=2.5,e.beginPath(),e.roundRect(h.x-u,h.y-c,h.width,h.height,6),e.fill(),e.stroke()),a.children&&a.children.length>0&&(e.fillStyle="#ffffff",e.strokeStyle=l,e.lineWidth=2,e.beginPath(),e.arc(h.x+u+10,h.y,8,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle=l,e.font="bold 13px sans-serif",e.textAlign="center",e.textBaseline="middle",e.fillText(a.collapsed?"+":"\u2212",h.x+u+10,h.y+.5)),a.note){let I=a.noteColor??l;e.font="11px sans-serif";let E=Math.min(e.measureText(a.note).width+12,130),B=16;e.fillStyle=I,e.beginPath(),e.roundRect(h.x-u,h.y-c-B+2,E,B,4),e.fill(),e.fillStyle="#ffffff",e.font="11px sans-serif",e.textAlign="left",e.textBaseline="middle",e.fillText(e.measureText(a.note).width+12>130?a.note.slice(0,12)+"\u2026":a.note,h.x-u+6,h.y-c-B/2+2);}e.font=`${14}px sans-serif`;let y=a.icon?18:0,w=h.width-y-(a.icon?8:0)-16,f=this.ellipsizeText(e,a.text||"",w),T=e.measureText(f).width,M=y+(y?8:0)+T,b=h.x-M/2;if(e.textBaseline="middle",a.icon&&(e.font="16px sans-serif",e.textAlign="left",e.fillStyle="#1f2937",e.fillText(a.icon,b,h.y+1),b+=y+8),e.font=`${14}px sans-serif`,e.textAlign="left",e.fillStyle="#1f2937",e.fillText(f,b,h.y),!a.collapsed)for(let I of a.children??[])o(I);};o(r);}ellipsizeText(e,t,i){if(i<=0)return "";if(e.measureText(t).width<=i)return t;let n="\u2026",s=0,r=t.length;for(;s<r;){let o=s+r+1>>1;e.measureText(t.slice(0,o)+n).width<=i?s=o:r=o-1;}return t.slice(0,s)+n}drawLine(e,t,i,n,s){if(t.points.length<2)return;let r=t.points.map(l=>({x:l.x,y:l.y}));r.length>=2&&(r[0]=this.clampToShapeOutline(r[0],i,t.id,r[r.length-1]),r[r.length-1]=this.clampToShapeOutline(r[r.length-1],i,t.id,r[0]));let o=r.map(l=>({x:l.x-t.x,y:l.y-t.y})),a=t.connectionType||"straight",h=a==="straight"?this.getAlignedPoints(o):this.buildPathPoints(o,a,this.collectRoutingObstacles(t.id,o[0],o[o.length-1],i,{x:t.x,y:t.y}),{fromN:this.getDockNormal(r[0],i,t.id),toN:this.getDockNormal(r[r.length-1],i,t.id)});if(a==="straight"){e.beginPath(),e.moveTo(o[0].x,o[0].y);for(let l=1;l<o.length;l++)e.lineTo(o[l].x,o[l].y);e.stroke(),e.setLineDash([]);}else a==="orthogonal"?this.drawSharpPolyline(e,h):this.drawRoundedPolyline(e,h,d.DEFAULT_CORNER_RADIUS),e.stroke(),e.setLineDash([]);n&&this.drawLinearHighlight(e,h,s);}drawArrow(e,t,i,n,s){if(t.points.length<2)return;let r=t.points.map(c=>({x:c.x,y:c.y}));if(t.startBinding){let c=i.get(t.startBinding.toShapeId);c&&(r[0]=this.getBindingPoint(c,t.startBinding));}if(t.endBinding){let c=i.get(t.endBinding.toShapeId);c&&(r[r.length-1]=this.getBindingPoint(c,t.endBinding));}r[0]=this.clampToShapeOutline(r[0],i,t.id,r[r.length-1]),r[r.length-1]=this.clampToShapeOutline(r[r.length-1],i,t.id,r[0]);let o=r.map(c=>({x:c.x-t.x,y:c.y-t.y})),a=t.connectionType||"straight",h=t.arrowHead??"end";!!t.dashed?e.setLineDash([8,5]):e.setLineDash([]);let u;if(a==="straight"){let c=this.getAlignedPoints(o);u=c,e.beginPath(),e.moveTo(c[0].x,c[0].y);for(let p=1;p<c.length;p++)e.lineTo(c[p].x,c[p].y);e.stroke(),this.drawArrowHeads(e,c,h);}else u=this.buildPathPoints(o,a,this.collectRoutingObstacles(t.id,o[0],o[o.length-1],i,{x:t.x,y:t.y}),{fromN:this.getDockNormal(r[0],i,t.id),toN:this.getDockNormal(r[r.length-1],i,t.id)}),a==="orthogonal"?this.drawSharpPolyline(e,u):this.drawRoundedPolyline(e,u,d.DEFAULT_CORNER_RADIUS),e.stroke(),this.drawArrowHeads(e,u,h);e.setLineDash([]),n&&this.drawLinearHighlight(e,u,s);}drawLinearHighlight(e,t,i){if(!(!t||t.length<2)){e.save(),e.strokeStyle=v.lineHighlight,e.lineWidth=7/i,e.lineCap="round",e.lineJoin="round",e.setLineDash([]),e.beginPath(),e.moveTo(t[0].x,t[0].y);for(let n=1;n<t.length;n++)e.lineTo(t[n].x,t[n].y);e.stroke(),e.restore();}}drawGenerationPreview(e,t,i){let{from:n,to:s,type:r}=t;e.save(),e.beginPath(),e.arc(n.x,n.y,7/i,0,Math.PI*2),e.fillStyle=v.genDot,e.fill(),e.strokeStyle=v.genLine,e.lineWidth=2/i,e.setLineDash([5/i,4/i]),e.lineCap="round",e.beginPath(),e.moveTo(n.x,n.y),e.lineTo(s.x,s.y),e.stroke(),r&&this.drawPreviewShapeOutline(e,s,r,i),e.restore();}drawPreviewShapeOutline(e,t,i,n){let h=t.x,l=t.y;switch(e.strokeStyle=v.genLine,e.lineWidth=1.5/n,e.setLineDash([6/n,4/n]),e.beginPath(),i){case "circle":case "ellipse":e.ellipse(h,l,i==="circle"?40:120/2,i==="circle"?40:60/2,0,0,Math.PI*2);break;case "diamond":e.moveTo(h,l-30),e.lineTo(h+60,l),e.lineTo(h,l+30),e.lineTo(h-60,l),e.closePath();break;case "triangle":e.moveTo(h,l-30),e.lineTo(h+60,l+30),e.lineTo(h-60,l+30),e.closePath();break;case "hexagon":for(let u=0;u<6;u++){let c=u*Math.PI/3-Math.PI/2,p=h+60*Math.cos(c),g=l+30*Math.sin(c);u===0?e.moveTo(p,g):e.lineTo(p,g);}e.closePath();break;case "parallelogram":e.moveTo(h-60+18,l-30),e.lineTo(h+60,l-30),e.lineTo(h+60-18,l+30),e.lineTo(h-60,l+30),e.closePath();break;default:e.roundRect(h-60,l-30,120,60,i==="rounded-rectangle"?8:4);break}e.stroke();}static ALIGN_TOLERANCE=8;getAlignedPoints(e){if(e.length<2)return e;let t=e[0],i=e[e.length-1],n=i.x-t.x,s=i.y-t.y,r=d.ALIGN_TOLERANCE;if(Math.abs(s)<=r){let o=(t.y+i.y)/2;return e.map(a=>({x:a.x,y:o}))}if(Math.abs(n)<=r){let o=(t.x+i.x)/2;return e.map(a=>({x:o,y:a.y}))}return e}buildPathPoints(e,t,i=[],n={}){if(e.length<2||t==="straight")return e;switch(t){case "polyline":return this.generatePolylinePoints(e,i,n);case "orthogonal":return this.generateOrthogonalPoints(e,i,n);case "curve":return this.generateCurvePoints(e);default:return e}}drawRoundedPolyline(e,t,i){if(e.beginPath(),!(t.length<2)){if(t.length===2||i<=0){e.moveTo(t[0].x,t[0].y);for(let n=1;n<t.length;n++)e.lineTo(t[n].x,t[n].y);return}e.moveTo(t[0].x,t[0].y);for(let n=1;n<t.length-1;n++){let s=t[n-1],r=t[n],o=t[n+1],a=r.x-s.x,h=r.y-s.y,l=o.x-r.x,u=o.y-r.y,c=Math.hypot(a,h),p=Math.hypot(l,u);if(c<1e-6||p<1e-6){e.lineTo(r.x,r.y);continue}let g=Math.min(i,c*.5,p*.5),m=r.x-a/c*g,y=r.y-h/c*g,w=r.x+l/p*g,f=r.y+u/p*g;e.lineTo(m,y),e.arcTo(r.x,r.y,w,f,g);}e.lineTo(t[t.length-1].x,t[t.length-1].y);}}drawSharpPolyline(e,t){if(e.beginPath(),!(t.length<2)){e.moveTo(t[0].x,t[0].y);for(let i=1;i<t.length;i++)e.lineTo(t[i].x,t[i].y);}}drawSnapGuides(e,t,i){e.save(),e.strokeStyle=v.guide,e.lineWidth=1/i,e.setLineDash([6/i,4/i]),e.beginPath();for(let n of t)n.type==="horizontal"?(e.moveTo(n.start,n.position),e.lineTo(n.end,n.position)):(e.moveTo(n.position,n.start),e.lineTo(n.position,n.end));e.stroke(),e.restore();}generatePolylinePoints(e,t=[],i={}){if(e.length<2)return e;let n=[];n.push(e[0]);let s=e.length-1,r=d.CONNECTION_LEAD;for(let o=1;o<e.length;o++){let a=e[o-1],h=e[o],l=o===1,u=o===s,c=l&&i.fromN?{x:a.x+i.fromN.x*r,y:a.y+i.fromN.y*r}:a,p=u&&i.toN?{x:h.x+i.toN.x*r,y:h.y+i.toN.y*r}:h;l&&i.fromN&&n.push(c);let g=this.computeOrthogonalRoute(c,p,t);for(let m of g)n.push(m);u&&i.toN&&n.push(h);}return this.collapseLinePoints(n)}generateOrthogonalPoints(e,t=[],i={}){return this.generatePolylinePoints(e,t,i)}collapseLinePoints(e){let t=[];for(let i of e){let n=t.length;if(!(n>0&&Math.abs(t[n-1].x-i.x)<1e-6&&Math.abs(t[n-1].y-i.y)<1e-6)){if(n>=2){let s=t[n-2],r=t[n-1];if(Math.abs(s.y-r.y)<1e-6&&Math.abs(r.y-i.y)<1e-6||Math.abs(s.x-r.x)<1e-6&&Math.abs(r.x-i.x)<1e-6){t[n-1]=i;continue}}t.push(i);}}return t}computeOrthogonalRoute(e,t,i=[]){let n=t.x-e.x,s=t.y-e.y;if(Math.abs(n)<1||Math.abs(s)<1)return [t];let r=e.x+n/2,o=e.y+s/2,a=i.length>0,h=[[{x:r,y:e.y},{x:r,y:t.y},t],[{x:e.x,y:o},{x:t.x,y:o},t],[{x:t.x,y:e.y},t],[{x:e.x,y:t.y},t]];if(a){for(let u of h)if(!this.routeHitsObstacles(e,u,i))return u;let l=this.routeOrthogonalAvoidance(e,t,i);return l&&l.length>0?l:i.length>0&&!this.routeHitsObstacles(e,h[0],i)?h[0]:this.routeHitsObstacles(e,h[1],i)?[t]:h[1]}return Math.abs(n)>=Math.abs(s)?[{x:r,y:e.y},{x:r,y:t.y},t]:[{x:e.x,y:o},{x:t.x,y:o},t]}collectRoutingObstacles(e,t,i,n,s){if(!n||n.size===0)return [];let r=[];return n.forEach((o,a)=>{if(a===e)return;let h=this.getShapeBounds(o),l={x:o.x+h.x-s.x,y:o.y+h.y-s.y,width:h.width,height:h.height};l.pad=this.pointInRect(t,l)||this.pointInRect(i,l)?d.CONNECTED_PAD:d.ROUTE_CLEARANCE,r.push(l);}),r}pointInRect(e,t){return e.x>=t.x&&e.x<=t.x+t.width&&e.y>=t.y&&e.y<=t.y+t.height}routeHitsObstacles(e,t,i){let n=[e,...t];for(let s=1;s<n.length;s++)if(this.segmentHitsObstacle(n[s-1],n[s],i))return true;return false}segmentHitsObstacle(e,t,i){for(let n of i){let s=n.pad??d.ROUTE_CLEARANCE,r=n.y-s,o=n.y+n.height+s,a=n.x-s,h=n.x+n.width+s;if(Math.abs(e.y-t.y)<.5){if(e.y>=r&&e.y<=o){let l=Math.min(e.x,t.x);if(Math.max(e.x,t.x)>=a&&l<=h)return true}}else if(e.x>=a&&e.x<=h){let l=Math.min(e.y,t.y);if(Math.max(e.y,t.y)>=r&&l<=o)return true}}return false}routeOrthogonalAvoidance(e,t,i){let n=new Set([e.x,t.x]),s=new Set([e.y,t.y]);for(let x of i){let S=x.pad??d.ROUTE_CLEARANCE;n.add(x.x-S),n.add(x.x+x.width+S),s.add(x.y-S),s.add(x.y+x.height+S);}let r=[...n].sort((x,S)=>x-S),o=[...s].sort((x,S)=>x-S),a=r.length,h=o.length,l=x=>{for(let S=0;S<a;S++)if(Math.abs(r[S]-x)<1e-6)return S;return 0},u=x=>{for(let S=0;S<h;S++)if(Math.abs(o[S]-x)<1e-6)return S;return 0},c=l(e.x),p=u(e.y),g=l(t.x),m=u(t.y),y=[],w=[];for(let x=0;x<a;x++)y.push(new Array(h).fill(true)),w.push(new Array(h).fill(true));for(let x of i){let S=x.pad??d.ROUTE_CLEARANCE,P=x.x-S,C=x.x+x.width+S,_=x.y-S,U=x.y+x.height+S;for(let D=0;D<a-1;D++)if(!(r[D+1]<=P||r[D]>=C))for(let G=0;G<h;G++)o[G]>_&&o[G]<U&&(y[D][G]=false);for(let D=0;D<h-1;D++)if(!(o[D+1]<=_||o[D]>=U))for(let G=0;G<a;G++)r[G]>P&&r[G]<C&&(w[G][D]=false);}let f=a*h,T=1/0,M=new Float64Array(f).fill(T),b=new Int32Array(f).fill(-1),I=new Uint8Array(f),E=x=>{let S=x%a,P=x/a|0;return Math.abs(r[S]-t.x)+Math.abs(o[P]-t.y)},B=(x,S)=>x%a===S%a,O=p*a+c,K=m*a+g;M[O]=0;let A=[O],N=[E(O)],he=x=>{let S=M[x]+E(x);A.push(x),N.push(S);let P=A.length-1;for(;P>0;){let C=P-1>>1;if(N[C]<=N[P])break;[A[C],A[P]]=[A[P],A[C]],[N[C],N[P]]=[N[P],N[C]],P=C;}},Ue=()=>{let x=A[0],S=A.pop(),P=N.pop();if(A.length){A[0]=S,N[0]=P;let C=0;for(;;){let _=C*2+1,U=_+1,D=C;if(_<A.length&&N[_]<N[D]&&(D=_),U<A.length&&N[U]<N[D]&&(D=U),D===C)break;[A[D],A[C]]=[A[C],A[D]],[N[D],N[C]]=[N[C],N[D]],C=D;}}return x},le=(x,S,P)=>{let C=x%a,_=S%a,U=M[x]+(Math.abs(_-C)===0?Math.abs(o[S/a|0]-o[x/a|0]):Math.abs(r[_]-r[C]))+P;U<M[S]&&(M[S]=U,b[S]=x,I[S]||he(S));};for(;A.length;){let x=Ue();if(x===K||I[x]){if(x===K)break;continue}I[x]=1;let S=x%a,P=x/a|0,C=b[x],_=C>=0?B(C,x)?"v":"h":"",U=D=>{let G=B(x,D)?"v":"h";return _!==""&&_!==G?24:0};S+1<a&&y[S][P]&&le(x,P*a+S+1,U(P*a+S+1)),S-1>=0&&y[S-1][P]&&le(x,P*a+S-1,U(P*a+S-1)),P+1<h&&w[S][P]&&le(x,(P+1)*a+S,U((P+1)*a+S)),P-1>=0&&w[S][P-1]&&le(x,(P-1)*a+S,U((P-1)*a+S));}if(M[K]===T)return null;let be=[];for(let x=K;x!==-1;x=b[x])be.push({x:r[x%a],y:o[x/a|0]});be.reverse();let J=[];for(let x of be){let S=J.length;if(S>=2){let P=J[S-2],C=J[S-1];if(Math.abs(P.y-C.y)<1e-6&&Math.abs(C.y-x.y)<1e-6||Math.abs(P.x-C.x)<1e-6&&Math.abs(C.x-x.x)<1e-6){J[S-1]=x;continue}}J.push(x);}return J.slice(1)}generateCurvePoints(e){if(e.length<2)return e;let t=[],i=20,n=e[0],s=n;t.push(n);for(let r=1;r<e.length;r++){let o=e[r],a=this.computeCurveControlPoint(s,o);for(let h=1;h<=i;h++){let l=h/i,u=(1-l)*(1-l)*s.x+2*(1-l)*l*a.x+l*l*o.x,c=(1-l)*(1-l)*s.y+2*(1-l)*l*a.y+l*l*o.y;t.push({x:u,y:c});}s=o;}return t}computeCurveControlPoint(e,t){let i=t.x-e.x,n=t.y-e.y,s=Math.sqrt(i*i+n*n);if(s<1)return {x:e.x,y:e.y};let r=(e.x+t.x)/2,o=(e.y+t.y)/2,a=-n/s,h=i/s,l=Math.min(s*.2,30);return {x:r+a*l,y:o+h*l}}getDisplayLines(e,t,i,n,s,r){let o=n*1.3,a=Math.max(1,Math.floor(r/o)),h=`${t.id}\0${i}\0${n}\0${s}x${r}\0${a}`,l=this.textLayoutCache.get(h);if(l)return l;let u=i.split(`
2
- `),c=[];for(let g of u){let m=this.wrapLine(e,g,s);for(let y of m)c.push(y);}let p=c.slice(0,a);return c.length>a&&p.length>0&&(p[p.length-1]=this.truncateLine(e,p[p.length-1],s)),this.textLayoutCache.size>=d.TEXT_CACHE_LIMIT&&this.textLayoutCache.clear(),this.textLayoutCache.set(h,p),p}drawShapeText(e,t){let i=t.text||"";if(!i)return;let n=t.fontSize||16;e.font=`${n}px sans-serif`,e.fillStyle=t.textColor||"#1f2937";let s=this.getTextBounds(t),r=n*1.3,o=this.getDisplayLines(e,t,i,n,s.width,s.height),h=-(o.length*r)/2+r/2;e.textAlign="center",e.textBaseline="middle",o.forEach((l,u)=>{let c=h+u*r;e.fillText(l,0,c);});}getTextBounds(e){switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return {width:e.width*.85,height:e.height*.85};case "circle":return {width:e.radius*2*.85,height:e.radius*2*.85};default:return {width:100,height:40}}}wrapLine(e,t,i){if(!t)return [""];let n=[],s="";for(let r of t){let o=s+r;e.measureText(o).width>i&&s?(n.push(s),s=r):s=o;}return s&&n.push(s),n}truncateLine(e,t,i){if(!t)return "...";let n="...",s=t;for(;s.length>0&&e.measureText(s+n).width>i;)s=s.slice(0,-1);return s+n}getBindingPoint(e,t){if(t.isPrecise&&t.normalizedAnchor){let i=this.getShapePageBounds(e),n={x:i.x+i.width*t.normalizedAnchor.x,y:i.y+i.height*t.normalizedAnchor.y},s={x:e.x,y:e.y};return this.nearestPointOnShapeOutline(e,s,n)}if(t.handle){let i=this.getShapeBounds(e);switch(t.handle){case "top":return {x:e.x,y:e.y+i.y};case "bottom":return {x:e.x,y:e.y+i.y+i.height};case "left":return {x:e.x+i.x,y:e.y};case "right":return {x:e.x+i.x+i.width,y:e.y}}}return {x:e.x,y:e.y}}getDockNormal(e,t,i){if(!t||t.size===0)return;let n=null,s=1/0,r=.5;if(t.forEach((l,u)=>{if(u===i)return;let c=this.getShapePageBounds(l);if(e.x>=c.x-r&&e.x<=c.x+c.width+r&&e.y>=c.y-r&&e.y<=c.y+c.height+r){let p=(e.x-l.x)**2+(e.y-l.y)**2;p<s&&(s=p,n=l);}}),!n)return;let o=n,a=e.x-o.x,h=e.y-o.y;return Math.abs(h)>Math.abs(a)?{x:0,y:h<0?-1:1}:{x:a<0?-1:1,y:0}}getShapePageBounds(e){let t=this.getShapeBounds(e);return {x:e.x+t.x,y:e.y+t.y,width:t.width,height:t.height}}clampToShapeOutline(e,t,i,n){if(!t||t.size===0)return e;let s=null,r=1/0;if(t.forEach((a,h)=>{if(h===i)return;let l=this.getShapePageBounds(a);if(e.x>l.x&&e.x<l.x+l.width&&e.y>l.y&&e.y<l.y+l.height){let u=(a.x-n.x)**2+(a.y-n.y)**2;u<r&&(r=u,s=a);}}),!s)return e;let o=s;return this.nearestPointOnShapeOutline(o,{x:o.x,y:o.y},e)}nearestPointOnShapeOutline(e,t,i){let n=i.x-t.x,s=i.y-t.y,r=Math.hypot(n,s);if(r<1e-6)return {x:t.x,y:t.y};let o=n/r,a=s/r,h=Math.max(1e4,r*2),l={x:t.x+o*h,y:t.y+a*h},u=this.intersectShapeOutlineWithSegment(e,t,l);if(u.length===0)return i;let c=u[0],p=(c.x-t.x)**2+(c.y-t.y)**2;for(let g=1;g<u.length;g++){let m=(u[g].x-t.x)**2+(u[g].y-t.y)**2;m<p&&(p=m,c=u[g]);}return c}intersectShapeOutlineWithSegment(e,t,i){let n={x:t.x-e.x,y:t.y-e.y},s={x:i.x-e.x,y:i.y-e.y};return this.intersectLocalShapeOutlineWithSegment(e,n,s).map(o=>({x:o.x+e.x,y:o.y+e.y}))}intersectLocalShapeOutlineWithSegment(e,t,i){switch(e.type){case "rectangle":case "rounded-rectangle":{let n=e.width,s=e.height,r={x:-n/2,y:-s/2,width:n,height:s};return this.intersectSegmentRect(t,i,r)}case "ellipse":case "diamond":case "triangle":{let n=e.width,s=e.height,r={x:-n/2,y:-s/2,width:n,height:s};return this.intersectSegmentRect(t,i,r)}case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":{let n=e.width,s=e.height,r={x:-n/2,y:-s/2,width:n,height:s};return this.intersectSegmentRect(t,i,r)}case "circle":{let n=e.radius;return this.intersectSegmentCircle(t,i,{x:0,y:0},n)}default:return []}}intersectSegmentRect(e,t,i){let n=i.x,s=i.y,r=i.width,o=i.height,a=[[{x:n,y:s},{x:n+r,y:s}],[{x:n+r,y:s},{x:n+r,y:s+o}],[{x:n+r,y:s+o},{x:n,y:s+o}],[{x:n,y:s+o},{x:n,y:s}]],h=[];for(let[l,u]of a){let c=this.segmentIntersection(e,t,l,u);c&&h.push(c);}return h}segmentIntersection(e,t,i,n){let s=e.x,r=e.y,o=t.x,a=t.y,h=i.x,l=i.y,u=n.x,c=n.y,p=(s-o)*(l-c)-(r-a)*(h-u);if(Math.abs(p)<1e-9)return null;let g=((s-h)*(l-c)-(r-l)*(h-u))/p,m=-((s-o)*(r-l)-(r-a)*(s-h))/p;return g<0||g>1||m<0||m>1?null:{x:s+g*(o-s),y:r+g*(a-r)}}intersectSegmentCircle(e,t,i,n){let s=t.x-e.x,r=t.y-e.y,o=e.x-i.x,a=e.y-i.y,h=s*s+r*r,l=2*(o*s+a*r),u=o*o+a*a-n*n,c=l*l-4*h*u;if(c<0)return [];c=Math.sqrt(c);let p=(-l-c)/(2*h),g=(-l+c)/(2*h),m=[];return p>=0&&p<=1&&m.push({x:e.x+p*s,y:e.y+p*r}),g>=0&&g<=1&&Math.abs(g-p)>1e-6&&m.push({x:e.x+g*s,y:e.y+g*r}),m}drawArrowHead(e,t,i){let n=Math.atan2(i.y-t.y,i.x-t.x),s=12;e.beginPath(),e.moveTo(i.x,i.y),e.lineTo(i.x-s*Math.cos(n-Math.PI/6),i.y-s*Math.sin(n-Math.PI/6)),e.moveTo(i.x,i.y),e.lineTo(i.x-s*Math.cos(n+Math.PI/6),i.y-s*Math.sin(n+Math.PI/6)),e.stroke();}drawInheritanceHead(e,t,i){let n=Math.atan2(i.y-t.y,i.x-t.x),s=14,r=i.x,o=i.y,a=i.x-s*Math.cos(n),h=i.y-s*Math.sin(n),l=a+s*.5*Math.cos(n-Math.PI/2),u=h+s*.5*Math.sin(n-Math.PI/2),c=a+s*.5*Math.cos(n+Math.PI/2),p=h+s*.5*Math.sin(n+Math.PI/2);e.save(),e.fillStyle="#ffffff",e.beginPath(),e.moveTo(r,o),e.lineTo(l,u),e.lineTo(c,p),e.closePath(),e.fill(),e.stroke(),e.restore();}drawDiamondHead(e,t,i,n){let s=Math.atan2(i.y-t.y,i.x-t.x),r=14,o=i.x,a=i.y,h=i.x-r*.5*Math.cos(s),l=i.y-r*.5*Math.sin(s),u=i.x-r*Math.cos(s),c=i.y-r*Math.sin(s),p=h+r*.4*Math.cos(s-Math.PI/2),g=l+r*.4*Math.sin(s-Math.PI/2),m=h+r*.4*Math.cos(s+Math.PI/2),y=l+r*.4*Math.sin(s+Math.PI/2);e.save(),e.fillStyle=n?"#1f2937":"#ffffff",e.beginPath(),e.moveTo(o,a),e.lineTo(p,g),e.lineTo(u,c),e.lineTo(m,y),e.closePath(),e.fill(),e.stroke(),e.restore();}drawArrowHeads(e,t,i){if(i!=="none"){if(i==="start"||i==="both"){let n=t[0],s=t[1];this.drawArrowHead(e,s,n);}if(i==="end"||i==="both"){let n=t.length,s=t[n-2],r=t[n-1];this.drawArrowHead(e,s,r);}if(i==="inheritance"){let n=t.length,s=t[n-2],r=t[n-1];this.drawInheritanceHead(e,s,r);}if(i==="aggregation"){let n=t[0],s=t[1];this.drawDiamondHead(e,s,n,false);}if(i==="composition"){let n=t[0],s=t[1];this.drawDiamondHead(e,s,n,true);}}}drawText(e,t){if(!t.text)return;let i=t.fontSize;e.font=`${i}px sans-serif`,e.textAlign="center",e.textBaseline="middle";let n=t.width,s=t.height,r=i*1.3,o=this.getDisplayLines(e,t,t.text,i,n,s),a=o.length*r,h=-a/2+r/2;if(t.highlightColor&&t.highlightColor!=="transparent"){e.fillStyle=t.highlightColor;let l=i*.15;e.beginPath(),e.roundRect(-n/2-l,-a/2-l,n+l*2,a+l*2,4),e.fill();}e.fillStyle=t.textColor||"#1f2937",o.forEach((l,u)=>{let c=h+u*r;e.fillText(l,0,c);});}drawFreehand(e,t){if(t.points.length<2)return;let i=t.points.map(n=>({x:n.x-t.x,y:n.y-t.y}));e.beginPath(),e.moveTo(i[0].x,i[0].y);for(let n=1;n<i.length-1;n++){let s=(i[n].x+i[n+1].x)/2,r=(i[n].y+i[n+1].y)/2;e.quadraticCurveTo(i[n].x,i[n].y,s,r);}e.lineTo(i[i.length-1].x,i[i.length-1].y),e.stroke();}drawSelectionOutline(e,t,i){let n=this.getShapeBounds(t);e.strokeStyle=v.selection.outline,e.lineWidth=1/i,e.setLineDash([]),e.save(),e.shadowColor=v.selection.shadow,e.shadowBlur=8,e.shadowOffsetX=0,e.shadowOffsetY=0,e.beginPath(),e.roundRect(n.x-2,n.y-2,n.width+4,n.height+4,4),e.stroke(),e.restore(),e.fillStyle=v.selection.outlineFill,e.beginPath(),e.roundRect(n.x-2,n.y-2,n.width+4,n.height+4,4),e.fill();}drawSelectionHandles(e,t,i){let n=8/i;if((t.type==="line"||t.type==="arrow"||t.type==="draw")&&t.points&&t.points.length>=2){let r=t.points.map(u=>({x:u.x-t.x,y:u.y-t.y})),o=r[0],a=r[r.length-1];e.fillStyle=v.selection.handleFill,e.strokeStyle=v.selection.handleStroke,e.lineWidth=2/i,e.setLineDash([]),[o,a].forEach(u=>{e.beginPath(),e.arc(u.x,u.y,n/2,0,Math.PI*2),e.fill(),e.stroke();});let h=(o.x+a.x)/2,l=(o.y+a.y)/2;e.beginPath(),e.arc(h,l,7/i,0,Math.PI*2),e.fillStyle=v.selection.handleFill,e.fill(),e.strokeStyle=v.primary,e.lineWidth=1.5/i,e.stroke(),e.beginPath(),e.arc(h,l,3/i,0,Math.PI*2),e.fillStyle=v.genDot,e.fill();}else {let r=this.getShapeBounds(t),o=n,a=[{x:r.x,y:r.y},{x:r.x+r.width,y:r.y},{x:r.x+r.width,y:r.y+r.height},{x:r.x,y:r.y+r.height}];e.fillStyle=v.selection.handleFill,e.strokeStyle=v.selection.handleStroke,e.lineWidth=2/i,e.setLineDash([]),a.forEach(g=>{e.beginPath(),e.roundRect(g.x-o/2,g.y-o/2,o,o,2),e.fill(),e.stroke();});let h=9/i;[{x:r.x+r.width/2,y:r.y},{x:r.x+r.width,y:r.y+r.height/2},{x:r.x+r.width/2,y:r.y+r.height},{x:r.x,y:r.y+r.height/2}].forEach(g=>{e.beginPath(),e.arc(g.x,g.y,h,0,Math.PI*2),e.fillStyle=v.selection.handleFill,e.fill(),e.strokeStyle=v.primary,e.lineWidth=1.5/i,e.stroke(),e.beginPath(),e.arc(g.x,g.y,h*.45,0,Math.PI*2),e.fillStyle=v.primary,e.fill();});let u=26/i,c=r.x+r.width/2,p=r.y-u;e.strokeStyle="#94a3b8",e.lineWidth=1.5/i,e.setLineDash([]),e.beginPath(),e.moveTo(c,r.y),e.lineTo(c,p),e.stroke(),e.beginPath(),e.arc(c,p,8/i,0,Math.PI*2),e.fillStyle=v.selection.handleFill,e.fill(),e.strokeStyle=v.primary,e.lineWidth=1.6/i,e.stroke(),this.drawRotateIcon(e,c,p,i);}}drawRotateIcon(e,t,i,n){let s=8/n;e.save(),e.translate(t,i),e.strokeStyle=v.primary,e.lineWidth=1.8/n,e.lineCap="round",e.beginPath(),e.arc(0,0,s*.5,Math.PI*.18,Math.PI*1.6,false),e.stroke();let r=Math.PI*.18,o=Math.cos(r)*s*.5,a=Math.sin(r)*s*.5,h=1;e.beginPath(),e.moveTo(o,a),e.lineTo(o-Math.cos(r)*s*.26+h*Math.sin(r)*s*.16,a-Math.sin(r)*s*.26-h*Math.cos(r)*s*.16),e.moveTo(o,a),e.lineTo(o-Math.cos(r)*s*.26-h*Math.sin(r)*s*.16,a-Math.sin(r)*s*.26+h*Math.cos(r)*s*.16),e.stroke(),e.restore();}getShapeBounds(e){switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:-e.width/2,y:-e.height/2,width:e.width,height:e.height};case "circle":return {x:-e.radius,y:-e.radius,width:e.radius*2,height:e.radius*2};case "line":case "arrow":case "draw":if(e.points.length===0)return {x:0,y:0,width:0,height:0};let t=1/0,i=1/0,n=-1/0,s=-1/0;return e.points.forEach(r=>{t=Math.min(t,r.x-e.x),i=Math.min(i,r.y-e.y),n=Math.max(n,r.x-e.x),s=Math.max(s,r.y-e.y);}),{x:t,y:i,width:n-t,height:s-i};case "text":{let r=e;return {x:-r.width/2,y:-r.height/2,width:r.width,height:r.height}}default:return {x:0,y:0,width:0,height:0}}}};var j={create(d=0,e=0){return {x:d,y:e}},add(d,e){return {x:d.x+e.x,y:d.y+e.y}},subtract(d,e){return {x:d.x-e.x,y:d.y-e.y}},multiply(d,e){return {x:d.x*e,y:d.y*e}},divide(d,e){return {x:d.x/e,y:d.y/e}},dot(d,e){return d.x*e.x+d.y*e.y},length(d){return Math.sqrt(d.x*d.x+d.y*d.y)},normalize(d){let e=j.length(d);return e===0?{x:0,y:0}:{x:d.x/e,y:d.y/e}},distance(d,e){return j.length(j.subtract(d,e))},rotate(d,e){let t=Math.cos(e),i=Math.sin(e);return {x:d.x*t-d.y*i,y:d.x*i+d.y*t}},clone(d){return {x:d.x,y:d.y}},equals(d,e){return d.x===e.x&&d.y===e.y}};function Z(d,e,t,i=8){let n=[];if(t==="horizontal"){let s=Math.min(d.x,e.x),r=Math.max(d.x+d.width,e.x+e.width),o=Math.abs(d.y-e.y)<=i,a=Math.abs(d.y+d.height-(e.y+e.height))<=i,h=Math.abs(d.y+d.height/2-(e.y+e.height/2))<=i;o&&n.push({type:"horizontal",position:(d.y+e.y)/2,start:s,end:r}),a&&n.push({type:"horizontal",position:(d.y+d.height+e.y+e.height)/2,start:s,end:r}),h&&!(o&&a)&&n.push({type:"horizontal",position:(d.y+d.height/2+e.y+e.height/2)/2,start:s,end:r});}else {let s=Math.min(d.y,e.y),r=Math.max(d.y+d.height,e.y+e.height),o=Math.abs(d.x-e.x)<=i,a=Math.abs(d.x+d.width-(e.x+e.width))<=i,h=Math.abs(d.x+d.width/2-(e.x+e.width/2))<=i;o&&n.push({type:"vertical",position:(d.x+e.x)/2,start:s,end:r}),a&&n.push({type:"vertical",position:(d.x+d.width+e.x+e.width)/2,start:s,end:r}),h&&!(o&&a)&&n.push({type:"vertical",position:(d.x+d.width/2+e.x+e.width/2)/2,start:s,end:r});}return n}var se=class d extends H{type="select";state="idle";translatingState=null;resizingState=null;generatingState=null;hoverGenPoint=null;rotatingState=null;draggingArrowId=null;draggingTerminal=null;pendingHistoryCommit=false;brushStart={x:0,y:0};brushShiftKey=false;defaultGenType(e){if(e){let t=this.context.getShapes().find(i=>i.id===e);if(t&&fe(t.type))return t.type}return "rectangle"}genPreviewOf(e,t){return {from:e.point,to:t,type:this.defaultGenType(e.sourceShapeId)}}genContext(e,t){return {from:e.point,to:t,sourceShapeId:e.sourceShapeId,edge:e.edge}}onPointerDown(e,t){let i=this.context.getShapes(),n=this.context.getSelectedIds(),s=this.hitTestArrowTerminal(e,i);if(s&&n.includes(s.shapeId)){this.state="dragging-terminal",this.draggingArrowId=s.shapeId,this.draggingTerminal=s.terminal,this.pendingHistoryCommit=true,this.context.updateArrowBinding(s.shapeId,s.terminal,null);return}let r=this.hitGenPoint(e,i,n);if(r){this.state="generating",this.generatingState={source:r,startPoint:e,hasMoved:false},this.pendingHistoryCommit=true,this.context.setGenerationPreview(this.genPreviewOf(r,this.genPreviewTarget(r,e,false)));return}let o=this.hitTest(e,i,n);if(o.handle==="rotation"){this.state="rotating",this.pendingHistoryCommit=true;let a=o.shape;this.rotatingState={shapeId:a.id,center:{x:a.x,y:a.y},startAngle:Math.atan2(e.y-a.y,e.x-a.x),startRotation:a.rotation};return}if(o.handle&&o.shape&&o.shape.type!=="mind-map"){this.state="resizing",this.resizingState={startPoint:e,startShape:o.shape,handle:o.handle},this.pendingHistoryCommit=true;return}if(o.shape){let a=o.shape,h=a.type==="line"||a.type==="arrow"||a.type==="draw",l=n.includes(a.id);if(h&&!l){this.context.selectShape(a.id,t.shiftKey);return}this.state="translating",this.pendingHistoryCommit=true,l||this.context.selectShape(a.id,t.shiftKey);let u=this.context.getSelectedIds(),c=new Map,p=new Map,g=new Map;u.forEach(m=>{let y=i.find(w=>w.id===m);y&&(c.set(m,{x:y.x,y:y.y}),p.set(m,y.rotation),g.set(m,this.getShapeWorldBounds(y)));}),this.translatingState={startPoint:e,startPositions:c,startRotation:p,startBounds:g};}else this.state="brushing",this.brushStart=e,this.brushShiftKey=t.shiftKey,t.shiftKey||this.context.selectShape("",false);}onPointerMove(e,t){let i=this.context.getShapes();if(this.state==="translating"&&this.translatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleTranslating(e,t);else if(this.state==="generating"&&this.generatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleGenerating(e,i);else if(this.state==="rotating"&&this.rotatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleRotating(e,t);else if(this.state==="resizing"&&this.resizingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleResizing(e);else if(this.state==="dragging-terminal"&&this.draggingArrowId&&this.draggingTerminal){this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false);let n=i.find(s=>s.id===this.draggingArrowId);if(n){let s=this.draggingTerminal==="start"?e:n.points[n.points.length-1],r=this.draggingTerminal==="start"?n.points[0]:e,o=this.computeSnapGuidesForArrow(s,r,e,n,i);this.context.setSnapGuides(o);let a=e;if(o.length>0){let u=o.filter(p=>p.type==="horizontal"),c=o.filter(p=>p.type==="vertical");if(u.length>0){let p=u[0].position,g=Math.abs(e.y-p);for(let m of u){let y=Math.abs(e.y-m.position);y<g&&(g=y,p=m.position);}a={...a,y:p};}else if(c.length>0){let p=c[0].position,g=Math.abs(e.x-p);for(let m of c){let y=Math.abs(e.x-m.position);y<g&&(g=y,p=m.position);}a={...a,x:p};}}let h=this.draggingTerminal==="start"?0:n.points.length-1,l=[...n.points];l[h]=a,this.context.updateShape(this.draggingArrowId,{points:l});}}else if(this.state==="brushing")this.handleBrushing(e);else {let n=this.context.getSelectedIds(),s=this.hitGenPoint(e,i,n);s?(this.hoverGenPoint=s,this.context.setGenerationPreview(this.genPreviewOf(s,this.genPreviewTarget(s,e,false)))):this.hoverGenPoint&&(this.hoverGenPoint=null,this.context.setGenerationPreview(null));}}onPointerUp(e,t){if(this.state==="dragging-terminal"&&this.draggingArrowId&&this.draggingTerminal){let i=this.context.getShapes(),n=this.findBindingNearPoint(e,i,this.draggingArrowId);n&&this.context.updateArrowBinding(this.draggingArrowId,this.draggingTerminal,n.toShapeId,n.binding);}if(this.state==="generating"&&this.generatingState){let i=this.generatingState,n=this.context.getShapes(),s=i.source,r=this.findBindingNearPoint(e,n,s.sourceShapeId);if(r)this.context.connectToExisting(this.genContext(s,e),r.toShapeId,r.binding);else if(!i.hasMoved)this.context.createGeneratedConnection(this.genContext(s,this.genPreviewTarget(s,s.point,false)),{type:this.defaultGenType(s.sourceShapeId)});else {let o=this.context.createFloatingLine(this.genContext(s,e));this.context.openGenerationMenu({context:this.genContext(s,e),existingArrowId:o,defaultShapeType:this.defaultGenType(s.sourceShapeId)});}this.generatingState=null,this.context.setGenerationPreview(null);}this.state==="brushing"&&this.context.setBrushRect(null),this.context.setConnectingTarget(null),this.hoverGenPoint=null,this.pendingHistoryCommit=false,this.state="idle",this.draggingArrowId=null,this.draggingTerminal=null,this.translatingState=null,this.resizingState=null,this.rotatingState=null,this.context.setSnapGuides([]);}onKeyDown(e){if(e.key==="Delete"||e.key==="Backspace"){let t=this.context.getSelectedIds();t.length>0&&(this.context.commitHistory(),t.forEach(i=>{this.context.deleteShape(i);}));}e.key==="Escape"&&(this.context.selectShape("",false),this.context.setSnapGuides([]),this.state="idle"),(e.key==="+"||e.key==="=")&&e.shiftKey&&(this.context.commitHistory(),this.handleRotation(15)),e.key==="-"&&e.shiftKey&&(this.context.commitHistory(),this.handleRotation(-15)),e.key==="ArrowUp"&&(e.preventDefault(),this.context.commitHistory(),this.handleNudge(0,-5)),e.key==="ArrowDown"&&(e.preventDefault(),this.context.commitHistory(),this.handleNudge(0,5)),e.key==="ArrowLeft"&&(e.preventDefault(),this.context.commitHistory(),this.handleNudge(-5,0)),e.key==="ArrowRight"&&(e.preventDefault(),this.context.commitHistory(),this.handleNudge(5,0));}onKeyUp(e){}getCursor(e){switch(this.state){case "translating":return "grabbing";case "generating":return "crosshair";case "rotating":return "grabbing";case "resizing":return this.resizingState?this.getHandleCursor(this.resizingState.handle,this.resizingState.startShape):"default";case "dragging-terminal":return "crosshair";case "brushing":return "crosshair"}let t=this.context.getShapes(),i=this.context.getSelectedIds();if(this.context.getMindMapCursorHitAtPoint(e))return "pointer";if(this.hitGenPoint(e,t,i))return "crosshair";if(this.hitTestArrowTerminal(e,t)&&i.includes(this.hitTestArrowTerminal(e,t).shapeId))return "move";let n=this.hitTest(e,t,i);return n.handle==="rotation"?"grab":n.handle?this.getHandleCursor(n.handle,n.shape):n.shape?"move":null}getHandleCursor(e,t){let n={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315}[e];if(n===void 0)return "grab";let s=((n+t.rotation*180/Math.PI)%360+360)%360,r=Math.round(s/45)%4;return ["ew-resize","nwse-resize","ns-resize","nesw-resize"][r]}static ALIGN_SNAP_THRESHOLD=8;handleTranslating(e,t){if(!this.translatingState)return;let i=j.subtract(e,this.translatingState.startPoint),n={...i};t.shiftKey&&(Math.abs(i.x)>Math.abs(i.y)?n.y=0:n.x=0);let s=this.context.getShapes(),r=this.context.getSelectedIds(),o=new Set(r),a=[],h=[];if(this.translatingState.startBounds.forEach(l=>{h.push({x:l.x+n.x,y:l.y+n.y,width:l.width,height:l.height});}),!t.shiftKey&&h.length>0){let l=[];for(let p of s)o.has(p.id)||p.type==="line"||p.type==="arrow"||p.type==="draw"||l.push(this.getShapeWorldBounds(p));let u=[],c=[];for(let p of h){let g=[p.y,p.y+p.height/2,p.y+p.height],m=[p.x,p.x+p.width/2,p.x+p.width];for(let y of l){let w=[y.y,y.y+y.height/2,y.y+y.height];for(let T of g)for(let M of w){let b=M-T;Math.abs(b)<=d.ALIGN_SNAP_THRESHOLD&&u.push(b);}let f=[y.x,y.x+y.width/2,y.x+y.width];for(let T of m)for(let M of f){let b=M-T;Math.abs(b)<=d.ALIGN_SNAP_THRESHOLD&&c.push(b);}}}if(u.length>0){let p=u[0];for(let g of u)Math.abs(g)<Math.abs(p)&&(p=g);n.y+=p;}if(c.length>0){let p=c[0];for(let g of c)Math.abs(g)<Math.abs(p)&&(p=g);n.x+=p;}this.translatingState.startBounds.forEach(p=>{let g={x:p.x+n.x,y:p.y+n.y,width:p.width,height:p.height};for(let m of l)a.push(...Z(g,m,"horizontal",1)),a.push(...Z(g,m,"vertical",1));});}this.translatingState.startPositions.forEach((l,u)=>{this.context.updateShape(u,{x:l.x+n.x,y:l.y+n.y});}),this.context.setSnapGuides(this.mergeGuides(a));}handleResizing(e){if(!this.resizingState)return;let t=this.resizingState.startShape,i=this.resizingState.handle,n=this.resizingState.startPoint;if(!i||i==="rotation")return;let r={nw:[-1,-1],n:[0,-1],ne:[1,-1],w:[-1,0],e:[1,0],sw:[-1,1],s:[0,1],se:[1,1]}[i];if(!r)return;let[o,a]=r,h=j.subtract(e,n),l=[];for(let b of this.context.getShapes())b.id!==t.id&&(b.type==="line"||b.type==="arrow"||b.type==="draw"||l.push(this.getShapeWorldBounds(b)));let u=20,c=this.getShapeWorldBounds(t),p=c.x,g=c.y,m=c.x+c.width,y=c.y+c.height;o===1?m=Math.max(p+u,m+h.x):o===-1&&(p=Math.min(m-u,p+h.x)),a===1?y=Math.max(g+u,y+h.y):a===-1&&(g=Math.min(y-u,g+h.y));let w=(b,I)=>{let E=null;for(let B of I){let O=B-b;Math.abs(O)<=d.ALIGN_SNAP_THRESHOLD&&(E===null||Math.abs(O)<Math.abs(E))&&(E=O);}return E};if(o!==0&&l.length>0){let b=[];for(let E of l)b.push(E.x,E.x+E.width/2,E.x+E.width);let I=w(o===1?m:p,b);I!==null&&(o===1?m+=I:p+=I);}if(a!==0&&l.length>0){let b=[];for(let E of l)b.push(E.y,E.y+E.height/2,E.y+E.height);let I=w(a===1?y:g,b);I!==null&&(a===1?y+=I:g+=I);}let f={x:p,y:g,width:m-p,height:y-g},T=[];for(let b of l)o!==0&&T.push(...Z(f,b,"vertical",1)),a!==0&&T.push(...Z(f,b,"horizontal",1));this.context.setSnapGuides(this.mergeGuides(T));let M={};if(t.type==="circle"){let b=Math.max(10,Math.max(o!==0?f.width/2:0,a!==0?f.height/2:0));if(M.radius=b,o!==0){let I=o===1?c.x:c.x+c.width;M.x=o===1?I+b:I-b;}if(a!==0){let I=a===1?c.y:c.y+c.height;M.y=a===1?I+b:I-b;}}else "width"in t&&o!==0&&(M.width=f.width,M.x=f.x+f.width/2),"height"in t&&a!==0&&(M.height=f.height,M.y=f.y+f.height/2);Object.keys(M).length>0&&this.context.updateShape(t.id,M);}mergeGuides(e){let t=new Map;for(let i of e){let n=`${i.type}\0${Math.round(i.position*2)/2}`,s=t.get(n);s?(s.start=Math.min(s.start,i.start),s.end=Math.max(s.end,i.end)):t.set(n,{...i});}return [...t.values()]}handleRotation(e){let t=this.context.getSelectedIds(),i=this.context.getShapes();t.forEach(n=>{let s=i.find(r=>r.id===n);s&&this.context.updateShape(n,{rotation:s.rotation+e*Math.PI/180});});}handleNudge(e,t){let i=this.context.getSelectedIds(),n=this.context.getShapes();i.forEach(s=>{let r=n.find(o=>o.id===s);r&&this.context.updateShape(s,{x:r.x+e,y:r.y+t});});}handleBrushing(e){let t=Math.min(this.brushStart.x,e.x),i=Math.min(this.brushStart.y,e.y),n=Math.abs(e.x-this.brushStart.x),s=Math.abs(e.y-this.brushStart.y);this.context.setBrushRect({x:t,y:i,width:n,height:s});let r=this.context.getShapes(),o=[];for(let a of r){let h=this.getShapeWorldBounds(a);this.rectsIntersect({x:t,y:i,width:n,height:s},h)&&o.push(a.id);}if(this.brushShiftKey){let a=this.context.getSelectedIds(),h=new Set([...a,...o]);this.context.selectShapes([...h]);}else this.context.selectShapes(o);}getShapeWorldBounds(e){switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:e.x-e.width/2,y:e.y-e.height/2,width:e.width,height:e.height};case "circle":return {x:e.x-e.radius,y:e.y-e.radius,width:e.radius*2,height:e.radius*2};case "line":case "arrow":case "draw":{if(!e.points||e.points.length===0)return {x:e.x,y:e.y,width:0,height:0};let t=1/0,i=1/0,n=-1/0,s=-1/0;return e.points.forEach(r=>{t=Math.min(t,r.x),i=Math.min(i,r.y),n=Math.max(n,r.x),s=Math.max(s,r.y);}),{x:t,y:i,width:n-t,height:s-i}}case "text":{let t=e;return {x:e.x-t.width/2,y:e.y-t.height/2,width:t.width,height:t.height}}default:{let t=e;return {x:t.x,y:t.y,width:0,height:0}}}}rectsIntersect(e,t){return e.x<t.x+t.width&&e.x+e.width>t.x&&e.y<t.y+t.height&&e.y+e.height>t.y}hitTest(e,t,i){for(let n=t.length-1;n>=0;n--){let s=t[n];if(i.includes(s.id)){let r=this.getHitHandle(e,s);if(r)return {shape:s,handle:r}}if(this.isPointInShape(e,s))return {shape:s,handle:null}}return {shape:null,handle:null}}getHitHandle(e,t){if(t.type==="mind-map")return null;let i=14,n=this.getShapeBounds(t),s=Math.cos(-t.rotation),r=Math.sin(-t.rotation),o=e.x-t.x,a=e.y-t.y,h=o*s-a*r,l=o*r+a*s,u=[{type:"nw",x:n.x,y:n.y},{type:"ne",x:n.x+n.width,y:n.y},{type:"se",x:n.x+n.width,y:n.y+n.height},{type:"sw",x:n.x,y:n.y+n.height},{type:"rotation",x:n.x+n.width/2,y:n.y-26}];for(let c of u)if(Math.abs(h-c.x)<i&&Math.abs(l-c.y)<i)return c.type;return null}static GEN_HIT_THRESHOLD=14;static CLICK_MOVE_THRESHOLD=6;computeGenPoints(e,t){let i=[];for(let n of t){let s=e.find(r=>r.id===n);if(s){if(s.type==="line"||s.type==="arrow"||s.type==="draw"){if(s.points&&s.points.length>=2){let r=this.getShapeWorldBounds(s);i.push({point:{x:r.x+r.width/2,y:r.y+r.height/2},sourceShapeId:s.id});}}else if(s.type==="rectangle"||s.type==="rounded-rectangle"||s.type==="ellipse"||s.type==="diamond"||s.type==="triangle"||s.type==="hexagon"||s.type==="parallelogram"||s.type==="trapezoid"||s.type==="pentagon"||s.type==="octagon"||s.type==="star"||s.type==="uml-class"||s.type==="uml-interface"||s.type==="circle"){let r=this.getShapeBounds(s),o={x:s.x,y:s.y};i.push({point:{x:o.x+r.x+r.width/2,y:o.y+r.y},edge:"n",sourceShapeId:s.id}),i.push({point:{x:o.x+r.x+r.width,y:o.y+r.y+r.height/2},edge:"e",sourceShapeId:s.id}),i.push({point:{x:o.x+r.x+r.width/2,y:o.y+r.y+r.height},edge:"s",sourceShapeId:s.id}),i.push({point:{x:o.x+r.x,y:o.y+r.y+r.height/2},edge:"w",sourceShapeId:s.id});}}}return i}hitGenPoint(e,t,i){let n=d.GEN_HIT_THRESHOLD,s=null,r=n;for(let o of this.computeGenPoints(t,i)){let a=Math.hypot(o.point.x-e.x,o.point.y-e.y);a<=r&&(r=a,s=o);}return s}genPreviewTarget(e,t,i){if(i)return t;let n=96;if(e.edge)switch(e.edge){case "n":return {x:e.point.x,y:e.point.y-n};case "s":return {x:e.point.x,y:e.point.y+n};case "e":return {x:e.point.x+n,y:e.point.y};case "w":return {x:e.point.x-n,y:e.point.y}}return {x:e.point.x,y:e.point.y-n}}handleGenerating(e,t){if(!this.generatingState)return;let i=this.generatingState,n=i.source;Math.hypot(e.x-i.startPoint.x,e.y-i.startPoint.y)>d.CLICK_MOVE_THRESHOLD&&(i.hasMoved=true);let r=this.findBindingNearPoint(e,t,n.sourceShapeId),o=r?this.bindingPosition(r.toShapeId,r.binding,t):i.hasMoved?e:this.genPreviewTarget(n,e,false);this.context.setConnectingTarget(r?r.toShapeId:null),this.context.setGenerationPreview({from:n.point,to:o,type:r?void 0:this.defaultGenType(n.sourceShapeId)});}handleRotating(e,t){if(!this.rotatingState)return;let i=this.rotatingState,n=Math.atan2(e.y-i.center.y,e.x-i.center.x),s=i.startRotation+(n-i.startAngle);t.shiftKey&&(s=Math.round(s/(Math.PI/12))*(Math.PI/12)),this.context.updateShape(i.shapeId,{rotation:s});}bindingPosition(e,t,i){let n=i.find(r=>r.id===e);if(!n)return {x:0,y:0};let s=this.getShapeWorldBounds(n);if(t.handle)switch(t.handle){case "top":return {x:n.x,y:s.y};case "bottom":return {x:n.x,y:s.y+s.height};case "left":return {x:s.x,y:n.y};case "right":return {x:s.x+s.width,y:n.y}}return t.normalizedAnchor?{x:s.x+s.width*t.normalizedAnchor.x,y:s.y+s.height*t.normalizedAnchor.y}:{x:n.x,y:n.y}}isPointInShape(e,t){let i=e.x-t.x,n=e.y-t.y;switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return Math.abs(i)<=t.width/2&&Math.abs(n)<=t.height/2;case "circle":return i*i+n*n<=t.radius*t.radius;case "hexagon":return this.isPointInHexagon(i,n,t.width,t.height);case "line":case "arrow":case "draw":for(let s=0;s<t.points.length-1;s++){let r=t.points[s],o=t.points[s+1];if(this.pointToLineDistance(e,r,o)<10)return true}return false;case "text":return Math.abs(i)<=50&&Math.abs(n)<=t.fontSize/2;default:return false}}isPointInHexagon(e,t,i,n){let s=Math.abs(e),r=Math.abs(t),o=i/2,a=n/2;return s<=o&&r<=a&&s/o+r/a<=1.5}pointToLineDistance(e,t,i){let n=e.x-t.x,s=e.y-t.y,r=i.x-t.x,o=i.y-t.y,a=n*r+s*o,h=r*r+o*o,l=-1;h!==0&&(l=a/h);let u,c;l<0?(u=t.x,c=t.y):l>1?(u=i.x,c=i.y):(u=t.x+l*r,c=t.y+l*o);let p=e.x-u,g=e.y-c;return Math.sqrt(p*p+g*g)}getShapeBounds(e){switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:-e.width/2,y:-e.height/2,width:e.width,height:e.height};case "circle":return {x:-e.radius,y:-e.radius,width:e.radius*2,height:e.radius*2};case "hexagon":return {x:-e.width/2,y:-e.height/2,width:e.width,height:e.height};case "line":case "arrow":case "draw":if(e.points.length===0)return {x:0,y:0,width:0,height:0};let t=1/0,i=1/0,n=-1/0,s=-1/0;return e.points.forEach(r=>{t=Math.min(t,r.x-e.x),i=Math.min(i,r.y-e.y),n=Math.max(n,r.x-e.x),s=Math.max(s,r.y-e.y);}),{x:t,y:i,width:n-t,height:s-i};case "text":return {x:-50,y:-e.fontSize/2,width:100,height:e.fontSize};default:return {x:0,y:0,width:0,height:0}}}hitTestArrowTerminal(e,t){for(let n of t){if(n.type!=="arrow")continue;let s=n;if(s.points.length<2)continue;let r=s.points[0],o=s.points[s.points.length-1],a=Math.sqrt(Math.pow(e.x-r.x,2)+Math.pow(e.y-r.y,2)),h=Math.sqrt(Math.pow(e.x-o.x,2)+Math.pow(e.y-o.y,2));if(a<20)return {shapeId:s.id,terminal:"start"};if(h<20)return {shapeId:s.id,terminal:"end"}}return null}findShapeNearPoint(e,t,i){for(let s=t.length-1;s>=0;s--){let r=t[s];if(i&&r.id===i||r.type==="arrow"||r.type==="line"||r.type==="draw")continue;let o;switch(r.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":o=this.pointToRectDistance(e,{x:r.x-r.width/2,y:r.y-r.height/2,width:r.width,height:r.height});break;case "circle":o=Math.sqrt(Math.pow(e.x-r.x,2)+Math.pow(e.y-r.y,2))-r.radius;break;case "hexagon":{let a=r.width/2,h=r.height/2,l=Math.abs(e.x-r.x),u=Math.abs(e.y-r.y);o=l/a+u/h-1;break}default:continue}if(o<=30)return r}return null}pointToRectDistance(e,t){let i=Math.max(t.x,Math.min(e.x,t.x+t.width)),n=Math.max(t.y,Math.min(e.y,t.y+t.height));return Math.sqrt(Math.pow(e.x-i,2)+Math.pow(e.y-n,2))}static SNAP_THRESHOLD=32;static HANDLE_SNAP_DISTANCE=18;static ANCHOR_EPS=.001;computeSnapGuidesForArrow(e,t,i,n,s){let r=this.draggingTerminal==="start"?n.endBinding:n.startBinding,o=r?s.find(g=>g.id===r.toShapeId):null;if(!o)return [];let a=this.findShapeNearPoint(i,s,n.id);if(!a)return [];let h=this.getShapeWorldBounds(o),l=this.getShapeWorldBounds(a),u=t.x-e.x,c=t.y-e.y,p=Math.abs(u)>=Math.abs(c)?"horizontal":"vertical";return Z(h,l,p)}findBindingNearPoint(e,t,i){let n;for(let s=t.length-1;s>=0;s--){let r=t[s];if(i&&r.id===i||r.type==="arrow"||r.type==="line"||r.type==="draw")continue;let o=this.getPageBounds(r),a=d.SNAP_THRESHOLD;if(e.x<o.x-a||e.x>o.x+o.width+a||e.y<o.y-a||e.y>o.y+o.height+a)continue;let h={x:r.x,y:r.y},l=[{handle:"top",pos:{x:h.x,y:o.y}},{handle:"bottom",pos:{x:h.x,y:o.y+o.height}},{handle:"left",pos:{x:o.x,y:h.y}},{handle:"right",pos:{x:o.x+o.width,y:h.y}}];for(let c of l){let p=Math.hypot(c.pos.x-e.x,c.pos.y-e.y);p<=d.HANDLE_SNAP_DISTANCE&&(!n||p<n.distance)&&(n={toShapeId:r.id,binding:{toShapeId:r.id,handle:c.handle,isPrecise:false},distance:p});}let u=this.nearestPointOnShapeOutline(r,e);if(u&&u.distance<=d.SNAP_THRESHOLD&&(!n||u.distance<n.distance)){let c=this.computeNormalizedAnchor(o,u.point);n={toShapeId:r.id,binding:{toShapeId:r.id,isPrecise:true,normalizedAnchor:c},distance:u.distance};}}if(n)return {toShapeId:n.toShapeId,binding:n.binding}}getPageBounds(e){switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return {x:e.x-e.width/2,y:e.y-e.height/2,width:e.width,height:e.height};case "circle":return {x:e.x-e.radius,y:e.y-e.radius,width:e.radius*2,height:e.radius*2};default:return {x:e.x-50,y:e.y-50,width:100,height:100}}}computeNormalizedAnchor(e,t){let i=d.ANCHOR_EPS,n=e.width>0?(t.x-e.x)/e.width:.5,s=e.height>0?(t.y-e.y)/e.height:.5;return n=Math.max(i,Math.min(1-i,n)),s=Math.max(i,Math.min(1-i,s)),{x:n,y:s}}nearestPointOnShapeOutline(e,t){let i={x:t.x-e.x,y:t.y-e.y},n=this.nearestLocalPointOnShapeOutline(e,i);if(!n)return null;let s={x:n.point.x+e.x,y:n.point.y+e.y};return {point:s,distance:Math.hypot(s.x-t.x,s.y-t.y)}}nearestLocalPointOnShapeOutline(e,t){switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":{let i=e.width,n=e.height;return this.nearestPointOnRectOutlineLocal(t,{x:-i/2,y:-n/2,width:i,height:n})}case "circle":{let i=e.radius;return this.nearestPointOnCircleOutlineLocal(t,{x:0,y:0},i)}default:return null}}nearestPointOnRectOutlineLocal(e,t){let i=[[{x:t.x,y:t.y},{x:t.x+t.width,y:t.y}],[{x:t.x+t.width,y:t.y},{x:t.x+t.width,y:t.y+t.height}],[{x:t.x+t.width,y:t.y+t.height},{x:t.x,y:t.y+t.height}],[{x:t.x,y:t.y+t.height},{x:t.x,y:t.y}]],n=null;for(let[s,r]of i){let o=this.nearestPointOnSegment(e,s,r);(!n||o.distance<n.distance)&&(n=o);}return n}nearestPointOnCircleOutlineLocal(e,t,i){let n=e.x-t.x,s=e.y-t.y,r=Math.hypot(n,s);if(r<1e-9)return {point:{x:t.x+i,y:t.y},distance:i};let o=t.x+n/r*i,a=t.y+s/r*i,h={x:o,y:a};return {point:h,distance:Math.hypot(h.x-e.x,h.y-e.y)}}nearestPointOnSegment(e,t,i){let n=i.x-t.x,s=i.y-t.y,r=n*n+s*s,o=r>0?((e.x-t.x)*n+(e.y-t.y)*s)/r:0;o=Math.max(0,Math.min(1,o));let a=t.x+o*n,h=t.y+o*s,l={x:a,y:h};return {point:l,distance:Math.hypot(l.x-e.x,l.y-e.y)}}};var re=class d extends H{type="hand";state="idle";startScreenPoint={x:0,y:0};initialCameraPos={x:0,y:0};static DRAG_THRESHOLD=4;onPointerDown(e,t){this.startScreenPoint={x:t.clientX,y:t.clientY};let i=this.context.getCamera();this.initialCameraPos={x:i.x,y:i.y},this.state="pointing";}onPointerMove(e,t){if(this.state!=="idle"){if(this.state==="pointing"){let i=t.clientX-this.startScreenPoint.x,n=t.clientY-this.startScreenPoint.y;if(Math.hypot(i,n)<d.DRAG_THRESHOLD)return;this.state="dragging",this.applyCameraDelta(i,n);return}if(this.state==="dragging"){let i=t.clientX-this.startScreenPoint.x,n=t.clientY-this.startScreenPoint.y;this.applyCameraDelta(i,n);}}}onPointerUp(e,t){if(this.state!=="idle"){if(this.state==="dragging"){let i=this.context.getCamera();this.initialCameraPos={x:i.x,y:i.y},this.startScreenPoint={x:t.clientX,y:t.clientY};}this.state="idle";}}onKeyDown(e){e.key==="Escape"&&this.state!=="idle"&&(this.context.setCameraPosition(this.initialCameraPos.x,this.initialCameraPos.y),this.state="idle");}onKeyUp(e){}getCursor(e){return this.state==="dragging"||this.state==="pointing"?"grabbing":"grab"}applyCameraDelta(e,t){this.context.setCameraPosition(this.initialCameraPos.x+e,this.initialCameraPos.y+t);}};var je={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},oe=class extends H{type="line";isDrawing=false;startPoint={x:0,y:0};currentShape=null;onPointerDown(e,t){this.isDrawing=true,this.startPoint=e,this.currentShape={id:`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:"line",x:e.x,y:e.y,points:[e],rotation:0,style:{...je}},this.context.commitHistory(),this.context.addShape(this.currentShape);}onPointerMove(e,t){!this.isDrawing||!this.currentShape||this.context.updateShape(this.currentShape.id,{points:[this.startPoint,e]});}onPointerUp(e,t){this.isDrawing=false,this.currentShape=null,this.context.setActiveTool("select");}onKeyDown(e){}onKeyUp(e){}getCursor(){return "crosshair"}};var Je={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:4,strokeDash:null},Qe={strokeColor:"rgba(255, 235, 59, 0.5)",fillColor:"transparent",strokeWidth:16,strokeDash:null},et=4e3,Q=class extends H{type;mode;isDrawing=false;points=[];currentShapeId=null;committed=false;fadeTimer=null;constructor(e,t){super(e),this.mode=t,this.type=t==="pen"?"pen":"highlighter";}onPointerDown(e,t){this.isDrawing=true,this.committed=false,this.currentShapeId=null,this.points=[{...e}];}onPointerMove(e,t){if(this.isDrawing)if(this.points.push({...e}),!this.committed&&this.points.length>=2){this.context.commitHistory();let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;this.currentShapeId=i;let n=this.points[0],s=this.mode==="pen"?{...Je}:{...Qe},r={id:i,type:"draw",x:n.x,y:n.y,points:this.points.map(o=>({...o})),rotation:0,style:s};this.context.addShape(r),this.committed=true;}else this.committed&&this.currentShapeId&&this.context.updateShape(this.currentShapeId,{points:this.points.map(i=>({...i}))});}onPointerUp(e,t){if(!this.isDrawing||(this.isDrawing=false,!this.committed||!this.currentShapeId))return;let i=this.currentShapeId;this.currentShapeId=null,this.mode==="highlighter"&&(this.fadeTimer=setTimeout(()=>{this.context.deleteShape(i);},et));}onKeyDown(e){}onKeyUp(e){}getCursor(){return "crosshair"}dispose(){this.fadeTimer&&(clearTimeout(this.fadeTimer),this.fadeTimer=null);}};var tt={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},ae=class extends H{type="arrow";isDrawing=false;startPoint={x:0,y:0};currentShapeId=null;startBindingInfo=null;onPointerDown(e,t){this.isDrawing=true,this.startPoint=e,this.startBindingInfo=null;let i=this.context.getShapes(),n=this.findShapeBinding(e,i),s=e;n&&(s=this.getBindingPosition(n.toShapeId,n.handle,i),this.startBindingInfo={...n,position:s});let r=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;this.currentShapeId=r;let o={id:r,type:"arrow",x:s.x,y:s.y,points:[s],rotation:0,style:{...tt},startBinding:n?{toShapeId:n.toShapeId,handle:n.handle}:void 0,connectionType:"straight",arrowHead:"end",dashed:false};this.context.commitHistory(),this.context.addShape(o);}onPointerMove(e,t){if(!this.isDrawing||!this.currentShapeId)return;let i=this.context.getShapes(),n=this.findShapeBinding(e,i),s=e;n&&(s=this.getBindingPosition(n.toShapeId,n.handle,i));let r=this.startBindingInfo?.position||this.startPoint,o=this.computeSnapGuides(r,s,n,i);this.context.setSnapGuides(o),this.context.updateShape(this.currentShapeId,{points:[r,s],endBinding:n?{toShapeId:n.toShapeId,handle:n.handle}:void 0});}onPointerUp(e,t){this.isDrawing=false,this.currentShapeId=null,this.startBindingInfo=null,this.context.setSnapGuides([]),this.context.setActiveTool("select");}onKeyDown(e){}onKeyUp(e){}getCursor(){return "crosshair"}computeSnapGuides(e,t,i,n){let s=this.startBindingInfo?n.find(c=>c.id===this.startBindingInfo.toShapeId):null,r=i?n.find(c=>c.id===i.toShapeId):null;if(!s||!r)return [];let o=this.getShapeBounds(s),a=this.getShapeBounds(r),h=t.x-e.x,l=t.y-e.y,u=Math.abs(h)>=Math.abs(l)?"horizontal":"vertical";return Z(o,a,u)}getShapeBounds(e){switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":return {x:e.x-e.width/2,y:e.y-e.height/2,width:e.width,height:e.height};case "circle":return {x:e.x-e.radius,y:e.y-e.radius,width:e.radius*2,height:e.radius*2};case "text":return {x:e.x-e.width/2,y:e.y-e.height/2,width:e.width,height:e.height};default:return {x:e.x-50,y:e.y-20,width:100,height:40}}}findShapeBinding(e,t){for(let n=t.length-1;n>=0;n--){let s=t[n];if(s.type==="arrow"||s.type==="line"||s.type==="draw")continue;let r;switch(s.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "uml-class":case "uml-interface":r=this.pointToRectDistance(e,{x:s.x-s.width/2,y:s.y-s.height/2,width:s.width,height:s.height});break;case "circle":{let o=Math.sqrt(Math.pow(e.x-s.x,2)+Math.pow(e.y-s.y,2));r=Math.abs(o-s.radius);break}case "hexagon":{let o=s.width/2,a=s.height/2,h=Math.abs(e.x-s.x),l=Math.abs(e.y-s.y);r=h/o+l/a-1;break}default:continue}if(r<=40){let o=this.getClosestHandle(e,s);return {toShapeId:s.id,handle:o}}}}pointToRectDistance(e,t){let i=Math.max(t.x,Math.min(e.x,t.x+t.width)),n=Math.max(t.y,Math.min(e.y,t.y+t.height));return Math.sqrt(Math.pow(e.x-i,2)+Math.pow(e.y-n,2))}getClosestHandle(e,t){let i=e.x-t.x,n=e.y-t.y;if(t.type==="circle"||t.type==="hexagon"){let h=Math.atan2(n,i);return h>=-Math.PI/4&&h<Math.PI/4?"right":h>=Math.PI/4&&h<3*Math.PI/4?"bottom":h>=3*Math.PI/4||h<-(3*Math.PI)/4?"left":"top"}let s="width"in t?t.width:100,r="height"in t?t.height:100,o=Math.abs(i)/(s/2),a=Math.abs(n)/(r/2);return o>a?i>0?"right":"left":n>0?"bottom":"top"}getBindingPosition(e,t,i){let n=i.find(s=>s.id===e);if(!n)return {x:0,y:0};switch(n.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":return this.getRectBindingPosition(n,t);case "circle":return this.getCircleBindingPosition(n,t);case "hexagon":return this.getRectBindingPosition(n,t);default:return {x:n.x,y:n.y}}}getRectBindingPosition(e,t){switch(t){case "top":return {x:e.x,y:e.y-e.height/2};case "bottom":return {x:e.x,y:e.y+e.height/2};case "left":return {x:e.x-e.width/2,y:e.y};case "right":return {x:e.x+e.width/2,y:e.y}}}getCircleBindingPosition(e,t){switch(t){case "top":return {x:e.x,y:e.y-e.radius};case "bottom":return {x:e.x,y:e.y+e.radius};case "left":return {x:e.x-e.radius,y:e.y};case "right":return {x:e.x+e.radius,y:e.y}}}};var nt={strokeColor:"transparent",fillColor:"transparent",strokeWidth:0,strokeDash:null},we=class extends H{type="text";onPointerDown(e,t){let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,n={id:i,type:"text",x:e.x,y:e.y,rotation:0,style:{...nt},text:"",fontSize:16,textColor:"#1f2937",width:200,height:24};this.context.commitHistory(),this.context.addShape(n),this.context.enterEditing(i);}onPointerMove(e,t){}onPointerUp(e,t){}onKeyDown(e){}onKeyUp(e){}getCursor(){return "text"}};var Ae="drawui-canvas-data",it=50,Le=class{canvas;renderer;camera;tools=new Map;activeTool="select";shapes=[];selectedIds=[];listeners=new Set;notificationListeners=new Set;uiListeners=new Set;isPanning=false;panStart={x:0,y:0};dragStartPositions=new Map;lastClickTime=0;lastClickShapeId=null;editingShapeId=null;textInput=null;textOverlay=null;isNewTextShape=false;originalTextValue="";undoStack=[];redoStack=[];isUndoing=false;brushRect=null;snapGuides=[];connectingTargetId=null;genPreview=null;eraserPoint=null;mindMapEditingShapeId=null;mindMapSelectedNode=null;mindMapHoverNode=null;renderScheduled=false;pointerIsDown=false;notifyScheduled=false;persist=true;constructor(e,t={}){this.canvas=e,this.persist=t.persist??!t.shapes,t.theme&&de(t.theme),t.language&&ue(t.language);let i=e.getBoundingClientRect();this.renderer=new ie(e),this.renderer.resize(i.width,i.height),this.camera=new ee;let n={addShape:s=>this.addShape(s),updateShape:(s,r)=>this.updateShape(s,r),deleteShape:s=>this.deleteShape(s),selectShape:(s,r)=>this.selectShape(s,r),selectShapes:s=>this.selectShapes(s),getShapes:()=>[...this.shapes],getSelectedIds:()=>[...this.selectedIds],setActiveTool:s=>this.setActiveTool(s),screenToPage:s=>this.screenToPage(s),getCamera:()=>this.camera,panBy:(s,r)=>this.panBy(s,r),setCameraPosition:(s,r)=>this.setCameraPosition(s,r),getShapeAtPoint:(s,r)=>this.getShapeAtPoint(s,r),getShapesInBrushRadius:(s,r)=>this.getShapesInBrushRadius(s,r),setEraserPoint:s=>this.setEraserPoint(s),updateArrowBinding:(s,r,o,a)=>this.updateArrowBinding(s,r,o,a),enterEditing:s=>this.enterEditing(s),exitEditing:()=>this.exitEditing(),commitHistory:()=>this.commitHistory(),setBrushRect:s=>this.setBrushRect(s),setSnapGuides:s=>this.setSnapGuides(s),setConnectingTarget:s=>this.setConnectingTarget(s),setGenerationPreview:s=>this.setGenerationPreview(s),openGenerationMenu:s=>this.openGenerationMenu(s),createGeneratedConnection:(s,r)=>this.createGeneratedConnection(s,r),createFloatingLine:s=>this.createFloatingLine(s),connectToExisting:(s,r,o)=>this.connectToExisting(s,r,o),updateSelectedShapesStyle:s=>this.updateSelectedShapesStyle(s),updateSelectedShapesText:s=>this.updateSelectedShapesText(s),updateConnectionType:s=>this.updateConnectionType(s),getMindMapCursorHitAtPoint:s=>this.getMindMapCursorHitAtPoint(s),selectMindMapNode:(s,r)=>this.selectMindMapNode(s,r)};this.tools.set("select",new se(n)),this.tools.set("hand",new re(n)),this.tools.set("rectangle",new R(n,"rectangle")),this.tools.set("rounded-rectangle",new R(n,"rounded-rectangle")),this.tools.set("circle",new R(n,"circle")),this.tools.set("ellipse",new R(n,"ellipse")),this.tools.set("diamond",new R(n,"diamond")),this.tools.set("triangle",new R(n,"triangle")),this.tools.set("hexagon",new R(n,"hexagon")),this.tools.set("parallelogram",new R(n,"parallelogram")),this.tools.set("trapezoid",new R(n,"trapezoid")),this.tools.set("pentagon",new R(n,"pentagon")),this.tools.set("octagon",new R(n,"octagon")),this.tools.set("star",new R(n,"star")),this.tools.set("uml-class",new R(n,"uml-class")),this.tools.set("uml-interface",new R(n,"uml-interface")),this.tools.set("line",new oe(n)),this.tools.set("arrow",new ae(n)),this.tools.set("text",new we(n)),this.tools.set("pen",new Q(n,"pen")),this.tools.set("highlighter",new Q(n,"highlighter")),this.tools.set("eraser",new Se(n)),this.tools.set("mind-map",new R(n,"mind-map")),this.setupEventListeners(),t.shapes?this.shapes=t.shapes.map(s=>({...s,style:{...s.style}})):this.persist&&this.loadFromStorage(),this.render();}setupEventListeners(){this.canvas.addEventListener("pointerdown",this.handlePointerDown),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerup",this.handlePointerUp),this.canvas.addEventListener("pointerleave",this.handlePointerUp),this.canvas.addEventListener("wheel",this.handleWheel,{passive:false}),window.addEventListener("keydown",this.handleKeyDown),window.addEventListener("keyup",this.handleKeyUp),window.addEventListener("resize",this.handleResize);}handlePointerDown=e=>{if(this.editingShapeId)return this.textInput&&e.target===this.textInput,void 0;if(this.pointerIsDown=true,e.button===1||e.button===0&&e.altKey){this.isPanning=true,this.panStart={x:e.clientX,y:e.clientY},this.canvas.setPointerCapture(e.pointerId),this.canvas.style.cursor="grabbing";return}let t=this.screenToPage({x:e.clientX,y:e.clientY}),i=this.activeTool==="select"?this.getMindMapCollapseHitAtPoint(t):null;if(i){this.toggleMindMapCollapse(i.shapeId,i.nodeId);return}if(this.activeTool==="select"){let s=Date.now(),r=this.getShapeAtPoint(t);if(s-this.lastClickTime<400&&this.lastClickShapeId&&r&&r.id===this.lastClickShapeId&&this.canEditShape(r)){this.enterEditing(r.id),this.lastClickTime=0,this.lastClickShapeId=null;return}if(this.lastClickTime=s,this.lastClickShapeId=r?.id||null,r&&r.type==="mind-map"&&this.mindMapEditingShapeId===r.id){let o=this.getMindMapNodeAtPoint(t);o&&(this.mindMapSelectedNode=o,this.notifyListeners(),this.render());return}r&&(this.dragStartPositions.clear(),this.selectedIds.forEach(o=>{let a=this.shapes.find(h=>h.id===o);a&&this.dragStartPositions.set(o,{x:a.x,y:a.y});}));}this.tools.get(this.activeTool)?.onPointerDown(t,e),this.updateCursor(t),this.render();};handlePointerMove=e=>{if(this.editingShapeId)return;if(this.isPanning){let n=e.clientX-this.panStart.x,s=e.clientY-this.panStart.y;this.camera.translate(n,s),this.panStart={x:e.clientX,y:e.clientY},this.scheduleRender(),this.notifyListeners();return}let t=this.screenToPage({x:e.clientX,y:e.clientY});this.tools.get(this.activeTool)?.onPointerMove(t,e),this.updateCursor(t),this.scheduleRender();};handlePointerUp=e=>{if(this.pointerIsDown=false,e.type==="pointerleave"&&(this.mindMapHoverNode=null),this.editingShapeId)return;if(this.isPanning){this.isPanning=false,this.updateCursor(this.screenToPage({x:e.clientX,y:e.clientY}));return}let t=this.screenToPage({x:e.clientX,y:e.clientY});this.tools.get(this.activeTool)?.onPointerUp(t,e),this.updateCursor(t),this.scheduleRender();};updateCursor(e){let i=this.tools.get(this.activeTool)?.getCursor(e)??"default";if(this.canvas.style.cursor!==i&&(this.canvas.style.cursor=i),!this.pointerIsDown){let n=this.getMindMapCursorHitAtPoint(e);(n?.shapeId!==this.mindMapHoverNode?.shapeId||n?.nodeId!==this.mindMapHoverNode?.nodeId)&&(this.mindMapHoverNode=n,this.scheduleRender());}}handleWheel=e=>{if(e.preventDefault(),e.ctrlKey||e.metaKey){let n=e.deltaY>0?.9:1.1;this.camera.zoomAt({x:e.clientX,y:e.clientY},n),this.scheduleRender(),this.notifyListeners();return}let t=e.deltaX||0,i=e.deltaY||0;e.deltaMode===1?(t*=40,i*=40):e.deltaMode===2&&(t*=120,i*=120),e.shiftKey&&(t=t||i,i=0),this.camera.translate(-t,-i),this.scheduleRender(),this.notifyListeners();};handleKeyDown=e=>{if(this.editingShapeId)return;if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==="z"){e.preventDefault(),e.shiftKey?this.redo():this.undo();return}if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==="y"){e.preventDefault(),this.redo();return}if((e.ctrlKey||e.metaKey)&&e.key.toLowerCase()==="s"){e.preventDefault(),this.saveToStorage();return}if(!e.ctrlKey&&!e.metaKey&&!e.altKey){if(e.key==="v"||e.key==="V"){this.setActiveTool("select"),e.preventDefault();return}if(e.key==="h"||e.key==="H"){this.setActiveTool("hand"),e.preventDefault();return}}this.tools.get(this.activeTool)?.onKeyDown(e),this.scheduleRender();};handleKeyUp=e=>{if(this.editingShapeId)return;this.tools.get(this.activeTool)?.onKeyUp(e),this.scheduleRender();};handleResize=()=>{this.renderer.resize(window.innerWidth,window.innerHeight),this.scheduleRender();};screenToPage(e){let t=this.canvas.getBoundingClientRect();return this.camera.screenToPage({x:e.x-t.left,y:e.y-t.top})}addShape(e){this.shapes.push(e),this.notifyListeners();}updateShape(e,t){let i=this.shapes.findIndex(n=>n.id===e);i!==-1&&(this.shapes[i]={...this.shapes[i],...t},(t.x!==void 0||t.y!==void 0)&&this.updateBoundArrows(e),this.notifyListeners());}updateBoundArrows(e){let t=this.shapes.find(i=>i.id===e);t&&this.shapes.forEach(i=>{if(i.type==="arrow"){let n=i,s={};if(n.startBinding?.toShapeId===e){let r=this.getBindingPosition(t,n.startBinding.handle||"top");s.points=n.points.map((o,a)=>a===0?r:o);}if(n.endBinding?.toShapeId===e){let r=this.getBindingPosition(t,n.endBinding.handle||"top"),o=s.points||[...n.points];s.points=o.map((a,h)=>h===o.length-1?r:a);}s.points&&(this.shapes[this.shapes.indexOf(i)]={...n,...s});}});}getBindingPosition(e,t){switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":switch(t){case "top":return {x:e.x,y:e.y-e.height/2};case "bottom":return {x:e.x,y:e.y+e.height/2};case "left":return {x:e.x-e.width/2,y:e.y};case "right":return {x:e.x+e.width/2,y:e.y}}case "circle":switch(t){case "top":return {x:e.x,y:e.y-e.radius};case "bottom":return {x:e.x,y:e.y+e.radius};case "left":return {x:e.x-e.radius,y:e.y};case "right":return {x:e.x+e.radius,y:e.y}}case "hexagon":switch(t){case "top":return {x:e.x,y:e.y-e.height/2};case "bottom":return {x:e.x,y:e.y+e.height/2};case "left":return {x:e.x-e.width/2,y:e.y};case "right":return {x:e.x+e.width/2,y:e.y}}default:return {x:e.x,y:e.y}}}deleteShape(e){this.shapes=this.shapes.filter(t=>t.id!==e),this.selectedIds=this.selectedIds.filter(t=>t!==e),this.shapes=this.shapes.map(t=>{if(t.type==="arrow"){let i=t;if(i.startBinding?.toShapeId===e)return {...i,startBinding:void 0};if(i.endBinding?.toShapeId===e)return {...i,endBinding:void 0}}return t}),this.notifyListeners(),this.scheduleRender();}selectShape(e,t){if(!e)this.selectedIds=[];else if(t){let i=this.selectedIds.indexOf(e);i===-1?this.selectedIds.push(e):this.selectedIds.splice(i,1);}else this.selectedIds=[e];this.notifyListeners(),this.scheduleRender();}selectShapes(e){this.selectedIds=[...e],this.notifyListeners(),this.scheduleRender();}setBrushRect(e){this.brushRect=e,this.scheduleRender();}setSnapGuides(e){this.snapGuides=e;}setConnectingTarget(e){this.connectingTargetId!==e&&(this.connectingTargetId=e,this.scheduleRender());}setGenerationPreview(e){this.genPreview?.from.x===e?.from.x&&this.genPreview?.from.y===e?.from.y&&this.genPreview?.to.x===e?.to.x&&this.genPreview?.to.y===e?.to.y&&this.genPreview?.type===e?.type||(this.genPreview=e,this.scheduleRender());}openGenerationMenu(e){let t=this.camera.getZoom(),i=(e.context.to.x+this.camera.x)*t,n=(e.context.to.y+this.camera.y)*t;this.emitUi({kind:"shapeTypeMenu",screenX:i,screenY:n,context:e.context,existingArrowId:e.existingArrowId,defaultShapeType:e.defaultShapeType});}lineStyle(){return {strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null}}computeSourceBinding(e){if(!e.sourceShapeId||!e.edge)return;let t=this.shapes.find(n=>n.id===e.sourceShapeId);if(!t)return;let i={n:"top",e:"right",s:"bottom",w:"left"};return {toShapeId:t.id,handle:i[e.edge]}}connectHandle(e,t){let i=t.x-e.x,n=t.y-e.y;return Math.abs(i)>=Math.abs(n)?i>=0?"left":"right":n>=0?"top":"bottom"}createFloatingLine(e){this.commitHistory();let t=e.from,i=e.to,n=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,s={id:n,type:"arrow",x:t.x,y:t.y,points:[{x:t.x,y:t.y},{x:i.x,y:i.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(e),connectionType:"polyline",arrowHead:"end",dashed:false};return this.addShape(s),this.selectedIds=[n],this.notifyListeners(),this.render(),n}createGeneratedConnection(e,t){this.commitHistory();let i=t.type,n;if(e.sourceShapeId){let a=this.shapes.find(h=>h.id===e.sourceShapeId);a&&fe(a.type)&&(n={...a.style});}let s=Ee(i,e.to,n);this.addShape(s);let r=e.from,o={toShapeId:s.id,handle:this.connectHandle(r,e.to)};if(t.existingArrowId)this.updateArrowBinding(t.existingArrowId,"end",s.id,{toShapeId:s.id,handle:this.connectHandle(r,e.to)});else {let h={id:`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:"arrow",x:r.x,y:r.y,points:[{x:r.x,y:r.y},{x:e.to.x,y:e.to.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(e),endBinding:o,connectionType:"polyline",arrowHead:"end",dashed:false};this.addShape(h);}this.selectedIds=[s.id],this.notifyListeners(),this.render();}connectToExisting(e,t,i){this.commitHistory();let n=this.shapes.find(l=>l.id===t);if(!n)return;let s=e.from,r=i?.handle??this.connectHandle(s,{x:n.x,y:n.y}),o=this.getBindingPosition(n,r),a=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,h={id:a,type:"arrow",x:s.x,y:s.y,points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(e),endBinding:{toShapeId:t,handle:r},connectionType:"polyline",arrowHead:"end",dashed:false};this.addShape(h),this.selectedIds=[a],this.notifyListeners(),this.render();}subscribeUi(e){return this.uiListeners.add(e),()=>this.uiListeners.delete(e)}emitUi(e){this.uiListeners.forEach(t=>t(e));}updateSelectedShapesStyle(e){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(t=>{let i=this.shapes.findIndex(n=>n.id===t);i!==-1&&(this.shapes[i]={...this.shapes[i],style:{...this.shapes[i].style,...e}});}),this.notifyListeners(),this.render());}updateSelectedShapesText(e){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(t=>{let i=this.shapes.findIndex(n=>n.id===t);i!==-1&&(this.shapes[i]={...this.shapes[i],...e});}),this.notifyListeners(),this.render());}updateConnectionType(e){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(t=>{let i=this.shapes.findIndex(n=>n.id===t);if(i!==-1){let n=this.shapes[i];(n.type==="line"||n.type==="arrow")&&(this.shapes[i]={...n,connectionType:e});}}),this.notifyListeners(),this.render());}updateArrowHeadType(e){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(t=>{let i=this.shapes.findIndex(n=>n.id===t);if(i!==-1){let n=this.shapes[i];n.type==="arrow"&&(this.shapes[i]={...n,arrowHead:e});}}),this.notifyListeners(),this.render());}updateArrowDashed(e){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(t=>{let i=this.shapes.findIndex(n=>n.id===t);if(i!==-1){let n=this.shapes[i];n.type==="arrow"&&(this.shapes[i]={...n,dashed:e});}}),this.notifyListeners(),this.render());}updateUmlClass(e,t){let i=this.shapes.findIndex(l=>l.id===e);if(i===-1)return;let n=this.shapes[i];if(n.type!=="uml-class")return;this.commitHistory();let s=t.className??n.className,r=t.attributes??n.attributes,o=t.methods??n.methods,{width:a,height:h}=xe(s,r,o);this.shapes[i]={...n,className:s,attributes:r,methods:o,width:a,height:h},this.notifyListeners(),this.render();}updateUmlInterface(e,t){let i=this.shapes.findIndex(g=>g.id===e);if(i===-1)return;let n=this.shapes[i];if(n.type!=="uml-interface")return;this.commitHistory();let s=n,r=t.className??s.className,o=t.methods??s.methods,a=W*.6,h=o.map(g=>`${g.visibility} ${g.name}(${g.params}): ${g.returnType}`),l=Math.max(r.length,...h.map(g=>g.length),0),u=Math.max(ne,l*a+$*2),c=o.length>0?o.length*V+L*2:L*2,p=X+c;this.shapes[i]={...n,className:r,methods:o,width:u,height:p},this.notifyListeners(),this.render();}getSelectedUml(){if(this.selectedIds.length!==1)return null;let e=this.shapes.find(t=>t.id===this.selectedIds[0]);return e&&(e.type==="uml-class"||e.type==="uml-interface")?e:null}getUmlById(e){let t=this.shapes.find(i=>i.id===e);return t&&(t.type==="uml-class"||t.type==="uml-interface")?t:null}getSelectedMindMap(){if(this.selectedIds.length!==1)return null;let e=this.shapes.find(t=>t.id===this.selectedIds[0]);return e&&e.type==="mind-map"?e:null}getMindMapNodeAtPoint(e){for(let t=this.shapes.length-1;t>=0;t--){let i=this.shapes[t];if(i.type!=="mind-map")continue;let n=i,s=e.x-n.x,r=e.y-n.y,o=Math.cos(n.rotation),a=Math.sin(n.rotation),h=s*o+r*a,l=-s*a+r*o;if(Math.abs(h)>n.width/2||Math.abs(l)>n.height/2)continue;let u=k(n.root);for(let[c,p]of u.positions)if(Math.abs(h-p.x)<=p.width/2&&Math.abs(l-p.y)<=p.height/2)return {shapeId:n.id,nodeId:c};return {shapeId:n.id,nodeId:n.root.id}}return null}getMindMapNodeAtScreenPoint(e){return this.getMindMapNodeAtPoint(this.screenToPage(e))}getMindMapCursorHitAtPoint(e){let t=this.getMindMapCollapseHitAtPoint(e);if(t)return t;for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(n.type!=="mind-map")continue;let s=n,r=e.x-s.x,o=e.y-s.y,a=Math.cos(s.rotation),h=Math.sin(s.rotation),l=r*a+o*h,u=-r*h+o*a,c=k(s.root);for(let[p,g]of c.positions)if(Math.abs(l-g.x)<=g.width/2&&Math.abs(u-g.y)<=g.height/2)return {shapeId:s.id,nodeId:p}}return null}selectMindMapNode(e,t){let i=this.shapes.find(n=>n.id===e);!i||i.type!=="mind-map"||(this.selectedIds=[e],this.mindMapSelectedNode={shapeId:e,nodeId:t},this.notifyListeners(),this.render());}getMindMapEditingShapeId(){return this.mindMapEditingShapeId}getMindMapSelectedNode(){return this.mindMapSelectedNode}getMindMapNode(e,t){let i=this.shapes.find(n=>n.id===e);return !i||i.type!=="mind-map"?null:F(i.root,t)}getMindMapNodeScreenRect(e,t){let i=this.shapes.find(w=>w.id===e);if(!i||i.type!=="mind-map")return null;let n=i,r=k(n.root).positions.get(t);if(!r)return null;let o=this.camera.getZoom(),a=r.x,h=r.y,l=Math.cos(n.rotation),u=Math.sin(n.rotation),c=a*l-h*u,p=a*u+h*l,g=this.camera.pageToScreen({x:n.x,y:n.y}),m=g.x+c*o,y=g.y+p*o;return {x:m-r.width*o/2,y:y-r.height*o/2,width:r.width*o,height:r.height*o}}getMindMapCollapseHitAtPoint(e){for(let t of this.shapes){if(t.type!=="mind-map")continue;let i=t,n=k(i.root),s=e.x-i.x,r=e.y-i.y,o=Math.cos(i.rotation),a=Math.sin(i.rotation),h=s*o+r*a,l=-s*a+r*o;for(let[u,c]of n.positions){let p=F(i.root,u);if(!p||!p.children||p.children.length===0)continue;let g=c.x+c.width/2+10,m=c.y,y=h-g,w=l-m;if(y*y+w*w<=121)return {shapeId:t.id,nodeId:u}}}return null}beginMindMapEdit(e,t){let i=this.shapes.find(s=>s.id===e);if(!i||i.type!=="mind-map")return;let n=i;this.mindMapEditingShapeId=e,this.mindMapSelectedNode={shapeId:e,nodeId:t&&F(n.root,t)?t:n.root.id},this.selectedIds=[e],this.notifyListeners(),this.render();}exitMindMapEdit(){this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null,this.notifyListeners(),this.render();}updateMindMapNode(e,t,i,n=true){let s=this.shapes.findIndex(p=>p.id===e);if(s===-1)return;let r=this.shapes[s];if(r.type!=="mind-map")return;let o=r,a=F(o.root,t);if(!a||!Object.keys(i).some(p=>a[p]!==i[p]))return;n&&this.commitHistory();let l=me(o.root,t,i),{width:u,height:c}=k(l);this.shapes[s]={...o,root:l,width:u,height:c},this.notifyListeners(),this.render();}addMindMapChild(e,t){let i=this.shapes.findIndex(l=>l.id===e);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let s=n,r={id:`mm_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,text:z("mindmap.defaultBranch")},o=Pe(s.root,t,r);this.commitHistory();let{width:a,height:h}=k(o);this.shapes[i]={...s,root:o,width:a,height:h},this.mindMapSelectedNode={shapeId:e,nodeId:r.id},this.notifyListeners(),this.render();}addMindMapSibling(e,t){let i=this.shapes.findIndex(l=>l.id===e);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let s=n;if(!te(s.root,t))return;let r={id:`mm_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,text:z("mindmap.defaultBranch")},o=Ie(s.root,t,r);this.commitHistory();let{width:a,height:h}=k(o);this.shapes[i]={...s,root:o,width:a,height:h},this.mindMapSelectedNode={shapeId:e,nodeId:r.id},this.notifyListeners(),this.render();}deleteMindMapNode(e,t){let i=this.shapes.findIndex(l=>l.id===e);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let s=n;if(s.root.id===t){this.commitHistory(),this.shapes=this.shapes.filter(l=>l.id!==e),this.selectedIds=this.selectedIds.filter(l=>l!==e),this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null,this.notifyListeners(),this.render();return}let r=Ce(s.root,t);if(!r)return;this.commitHistory();let{width:o,height:a}=k(r);this.shapes[i]={...s,root:r,width:o,height:a};let h=te(s.root,t);this.mindMapSelectedNode=h?{shapeId:e,nodeId:h.id}:{shapeId:e,nodeId:r.id},this.notifyListeners(),this.render();}toggleMindMapCollapse(e,t){let i=this.shapes.findIndex(l=>l.id===e);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let s=n,r=F(s.root,t);if(!r||!r.children||r.children.length===0)return;this.commitHistory();let o=me(s.root,t,{collapsed:!r.collapsed}),{width:a,height:h}=k(o);this.shapes[i]={...s,root:o,width:a,height:h},this.notifyListeners(),this.render();}addUmlAttribute(e){let t=this.shapes.find(n=>n.id===e);if(!t||t.type!=="uml-class")return;let i={id:`attr_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,visibility:"+",name:"newField",type:"string"};this.updateUmlClass(e,{attributes:[...t.attributes,i]});}addUmlMethod(e){let t=this.getUmlById(e);if(!t)return;let i={id:`meth_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,visibility:"+",name:"newMethod",params:"",returnType:"void"};t.type==="uml-class"?this.updateUmlClass(e,{methods:[...t.methods,i]}):this.updateUmlInterface(e,{methods:[...t.methods,i]});}removeUmlAttribute(e,t){let i=this.shapes.find(n=>n.id===e);!i||i.type!=="uml-class"||this.updateUmlClass(e,{attributes:i.attributes.filter(n=>n.id!==t)});}removeUmlMethod(e,t){let i=this.getUmlById(e);if(!i)return;let n=i.methods.filter(s=>s.id!==t);i.type==="uml-class"?this.updateUmlClass(e,{methods:n}):this.updateUmlInterface(e,{methods:n});}reorderUmlAttribute(e,t,i){let n=this.shapes.find(o=>o.id===e);if(!n||n.type!=="uml-class"||t===i)return;let s=[...n.attributes];if(t<0||t>=s.length||i<0||i>=s.length)return;let[r]=s.splice(t,1);s.splice(i,0,r),this.updateUmlClass(e,{attributes:s});}reorderUmlMethod(e,t,i){let n=this.getUmlById(e);if(!n||t===i)return;let s=[...n.methods];if(t<0||t>=s.length||i<0||i>=s.length)return;let[r]=s.splice(t,1);s.splice(i,0,r),n.type==="uml-class"?this.updateUmlClass(e,{methods:s}):this.updateUmlInterface(e,{methods:s});}updateUmlRowStyle(e,t,i,n){let s=this.getUmlById(e);if(s)if(t==="attribute"){if(s.type!=="uml-class")return;let r=s.attributes.map(o=>o.id===i?{...o,textColor:n.textColor===null?void 0:n.textColor??o.textColor,fontSize:n.fontSize===null?void 0:n.fontSize??o.fontSize,strikethrough:n.strikethrough===null?void 0:n.strikethrough??o.strikethrough}:o);this.updateUmlClass(e,{attributes:r});}else {let r=s.methods.map(o=>o.id===i?{...o,textColor:n.textColor===null?void 0:n.textColor??o.textColor,fontSize:n.fontSize===null?void 0:n.fontSize??o.fontSize,strikethrough:n.strikethrough===null?void 0:n.strikethrough??o.strikethrough}:o);s.type==="uml-class"?this.updateUmlClass(e,{methods:r}):this.updateUmlInterface(e,{methods:r});}}getUmlRowAtScreenPoint(e){let t=this.camera.screenToPage(e);for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(n.type!=="uml-class"&&n.type!=="uml-interface")continue;let s=n.width/2,r=n.height/2;if(t.x<n.x-s||t.x>n.x+s||t.y<n.y-r||t.y>n.y+r)continue;let o=X,a=t.y-n.y;if(a>=-r&&a<=-r+o)return {shape:n,section:"className",rowIndex:-1,text:n.className};if(n.type==="uml-interface"){let g=-r+o,m=r;if(n.methods.length>0&&a>=g&&a<=m){let y=Math.floor((a-g-L)/V);if(y>=0&&y<n.methods.length){let w=n.methods[y];return {shape:n,section:"method",rowIndex:y,text:`${w.visibility} ${w.name}(${w.params}): ${w.returnType}`}}return {shape:n,section:"method",rowIndex:-1,text:""}}return {shape:n,section:"className",rowIndex:-1,text:n.className}}let h=n.attributes.length>0?n.attributes.length*V+L*2:L*2,l=-r+o,u=l+h;if(n.attributes.length>0&&a>=l&&a<=u){let g=Math.floor((a-l-L)/V);if(g>=0&&g<n.attributes.length){let m=n.attributes[g];return {shape:n,section:"attribute",rowIndex:g,text:`${m.visibility} ${m.name}: ${m.type}`}}return {shape:n,section:"attribute",rowIndex:-1,text:""}}let c=u,p=r;if(n.methods.length>0&&a>=c&&a<=p){let g=Math.floor((a-c-L)/V);if(g>=0&&g<n.methods.length){let m=n.methods[g];return {shape:n,section:"method",rowIndex:g,text:`${m.visibility} ${m.name}(${m.params}): ${m.returnType}`}}return {shape:n,section:"method",rowIndex:-1,text:""}}return {shape:n,section:"className",rowIndex:-1,text:n.className}}return null}setActiveTool(e){this.tools.has(e)&&(this.activeTool=e,this.eraserPoint=null,this.notifyListeners());}getActiveTool(){return this.activeTool}getShapes(){return [...this.shapes]}getData(){return {shapes:this.getShapes(),camera:{x:this.camera.x,y:this.camera.y,zoom:this.camera.zoom}}}setShapes(e){return Array.isArray(e)?(this.shapes=e.map(t=>({...t,style:{...t.style}})),this.selectedIds=[],this.undoStack=[],this.redoStack=[],this.notifyListeners(),this.render(),true):false}setTheme(e){de(e),this.scheduleRender();}setLanguage(e){ue(e);}getSelectedIds(){return [...this.selectedIds]}getCamera(){return this.camera}isPointerDown(){return this.pointerIsDown}zoomIn(){this.camera.zoomAt({x:window.innerWidth/2,y:window.innerHeight/2},1.2),this.scheduleRender(),this.notifyListeners();}zoomOut(){this.camera.zoomAt({x:window.innerWidth/2,y:window.innerHeight/2},.8),this.scheduleRender(),this.notifyListeners();}resetZoom(){this.camera.reset(),this.scheduleRender(),this.notifyListeners();}panBy(e,t){this.camera.translate(e,t),this.scheduleRender(),this.notifyListeners();}setCameraPosition(e,t){this.camera.x=e,this.camera.y=t,this.scheduleRender(),this.notifyListeners();}requestRender(){this.scheduleRender(),this.notifyListeners();}setShowGrid(e){this.renderer.setShowGrid(e),this.scheduleRender();}render(){this.renderer.render(this.shapes,this.camera,new Set(this.selectedIds),this.brushRect,this.snapGuides,this.connectingTargetId,this.genPreview,this.eraserPoint,this.mindMapSelectedNode,this.mindMapHoverNode);}scheduleRender(){this.renderScheduled||(this.renderScheduled=true,requestAnimationFrame(()=>{this.renderScheduled=false,this.render();}));}subscribe(e){return this.listeners.add(e),()=>this.listeners.delete(e)}subscribeNotifications(e){return this.notificationListeners.add(e),()=>this.notificationListeners.delete(e)}notify(e){this.notificationListeners.forEach(t=>t(e));}notifyListeners(){this.notifyScheduled||(this.notifyScheduled=true,queueMicrotask(()=>{this.notifyScheduled=false,this.mindMapEditingShapeId&&!this.selectedIds.includes(this.mindMapEditingShapeId)&&(this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null),this.listeners.forEach(e=>e());}));}cloneShapes(e){return e.map(t=>{let i={...t,style:{...t.style}};return Array.isArray(t.points)&&(i.points=t.points.map(n=>({...n}))),t.startBinding&&(i.startBinding={...t.startBinding}),t.endBinding&&(i.endBinding={...t.endBinding}),t.root&&(i.root=ye(t.root)),i})}commitHistory(){if(this.isUndoing)return;let e={shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]};this.undoStack.push(e),this.undoStack.length>it&&this.undoStack.shift(),this.redoStack=[];}mark(){this.commitHistory();}undo(){if(this.undoStack.length!==0){this.isUndoing=true;try{this.redoStack.push({shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]});let e=this.undoStack.pop();this.shapes=this.cloneShapes(e.shapes),this.selectedIds=[...e.selectedIds];}finally{this.isUndoing=false;}this.notifyListeners(),this.render();}}redo(){if(this.redoStack.length!==0){this.isUndoing=true;try{this.undoStack.push({shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]});let e=this.redoStack.pop();this.shapes=this.cloneShapes(e.shapes),this.selectedIds=[...e.selectedIds];}finally{this.isUndoing=false;}this.notifyListeners(),this.render();}}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}saveToStorage(){if(!this.persist)return false;try{let e=JSON.stringify({version:1,shapes:this.shapes,savedAt:Date.now()});return localStorage.setItem(Ae,e),this.notifyListeners(),this.notify(z("save.success")),!0}catch(e){return console.error("\u4FDD\u5B58\u5931\u8D25:",e),this.notify(z("save.fail")),false}}loadFromStorage(){if(!this.persist)return false;try{let e=localStorage.getItem(Ae);if(!e)return !1;let t=JSON.parse(e);return t.shapes&&Array.isArray(t.shapes)?(this.shapes=t.shapes,this.selectedIds=[],this.undoStack=[],this.redoStack=[],this.notifyListeners(),this.scheduleRender(),!0):!1}catch(e){return console.error("\u52A0\u8F7D\u5931\u8D25:",e),false}}clearStorage(){localStorage.removeItem(Ae);}exportJSON(){return JSON.stringify({version:1,shapes:this.shapes,savedAt:Date.now()},null,2)}importJSON(e){try{let t=JSON.parse(e);return t.shapes&&Array.isArray(t.shapes)?(this.commitHistory(),this.shapes=t.shapes,this.selectedIds=[],this.notifyListeners(),this.render(),!0):!1}catch(t){return console.error("\u5BFC\u5165\u5931\u8D25:",t),false}}getEditingShapeId(){return this.editingShapeId}canEditShape(e){return !(e.type==="line"||e.type==="arrow"||e.type==="draw"||e.type==="uml-class"||e.type==="uml-interface"||e.type==="mind-map")}enterEditing(e){let t=this.shapes.find(i=>i.id===e);!t||!this.canEditShape(t)||(this.editingShapeId=e,this.selectedIds=[e],this.isNewTextShape=t.type==="text"&&!t.text,this.originalTextValue=t.text||"",this.notifyListeners(),this.scheduleRender(),requestAnimationFrame(()=>{this.createTextInput(t);}));}exitEditing(){if(!this.editingShapeId)return;let e=this.editingShapeId,t=this.shapes.find(n=>n.id===e),i=this.textInput?this.textInput.value:"";if(this.removeTextInput(),t)if(t.type==="text")if(this.commitHistory(),!i.trim()&&this.isNewTextShape)this.shapes=this.shapes.filter(n=>n.id!==e),this.selectedIds=this.selectedIds.filter(n=>n!==e);else {let n=t,s=n.fontSize||16,r=s*1.3,o=n.width||200,a=i.split(`
3
- `),h=0;for(let c of a){let p="";for(let g of c){let m=p+g;m.length*s*.6>o&&p?(h++,p=g):p=m;}p&&h++;}let l={...n,text:i,height:Math.max(h*r,r)},u=this.shapes.indexOf(t);u!==-1&&(this.shapes[u]=l),i.trim()||(this.shapes=this.shapes.filter(c=>c.id!==e),this.selectedIds=this.selectedIds.filter(c=>c!==e));}else this.commitHistory(),this.updateShape(e,{text:i,textColor:t.textColor||v.text,fontSize:t.fontSize||16});this.editingShapeId=null,this.isNewTextShape=false,this.originalTextValue="",this.setActiveTool("select"),this.notifyListeners(),this.render();}removeTextInput(){this.textOverlay&&(this.textOverlay.remove(),this.textOverlay=null),this.textInput&&(this.textInput.remove(),this.textInput=null);}createTextInput(e){this.removeTextInput();let t=this.canvas.parentElement;if(!t)return;let i=this.canvas.getBoundingClientRect(),n=t.getBoundingClientRect(),s=i.left-n.left,r=i.top-n.top;this.textOverlay=document.createElement("div"),this.textOverlay.style.position="absolute",this.textOverlay.style.left=`${s}px`,this.textOverlay.style.top=`${r}px`,this.textOverlay.style.width=`${i.width}px`,this.textOverlay.style.height=`${i.height}px`,this.textOverlay.style.background="transparent",this.textOverlay.style.zIndex="1000",this.textOverlay.style.cursor="text",this.textOverlay.addEventListener("pointerdown",u=>{this.textInput&&u.target!==this.textInput&&(u.preventDefault(),this.exitEditing());}),t.appendChild(this.textOverlay);let o=this.getShapeScreenBounds(e),a=this.camera.getZoom(),h=(e.fontSize||16)*a,l=document.createElement("textarea");l.style.position="absolute",l.style.left=`${s+o.x}px`,l.style.top=`${r+o.y}px`,l.style.width=`${Math.max(o.width,60)}px`,l.style.height=`${Math.max(o.height,24)}px`,l.style.fontSize=`${h}px`,l.style.color=e.textColor||"#1f2937",l.style.textAlign="center",l.style.border=`2px solid ${v.editBorder}`,l.style.borderRadius="4px",l.style.background="rgba(255, 255, 255, 0.95)",l.style.resize="none",l.style.padding="4px 8px",l.style.boxSizing="border-box",l.style.lineHeight="1.4",l.style.fontFamily="sans-serif",l.style.outline="none",l.style.whiteSpace="pre-wrap",l.style.wordBreak="break-word",l.style.overflow="hidden",l.style.zIndex="1001",l.value=e.text||"",l.dataset.shapeId=e.id,l.addEventListener("pointerdown",u=>{u.stopPropagation();}),l.addEventListener("mousedown",u=>{u.stopPropagation();}),l.addEventListener("keydown",u=>{if(u.stopPropagation(),u.key==="Escape"&&(u.preventDefault(),this.textInput&&(this.textInput.value=this.originalTextValue),this.exitEditing()),u.key==="Enter"&&!u.shiftKey&&(u.preventDefault(),this.exitEditing()),u.key==="Enter"&&u.shiftKey){u.preventDefault();let c=l.selectionStart,p=l.selectionEnd;l.value=l.value.substring(0,c)+`
4
- `+l.value.substring(p),l.selectionStart=l.selectionEnd=c+1;}}),t.appendChild(l),l.focus(),e.type==="text"&&!e.text&&(l.placeholder="\u8F93\u5165\u6587\u672C..."),this.textInput=l;}getShapeScreenBounds(e){let t=this.camera.getZoom(),i=this.camera.pageToScreen({x:e.x,y:e.y});switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":return {x:i.x-e.width*t/2,y:i.y-e.height*t/2,width:e.width*t,height:e.height*t};case "circle":return {x:i.x-e.radius*t,y:i.y-e.radius*t,width:e.radius*2*t,height:e.radius*2*t};case "text":{let n=e,s=n.width*t,r=n.height*t;return {x:i.x-s/2,y:i.y-r/2,width:s,height:r}}default:return {x:i.x-50*t,y:i.y-20*t,width:100*t,height:40*t}}}getShapeAtScreenPoint(e){let t=this.screenToPage(e);return this.getShapeAtPoint(t)}getShapeAtPoint(e,t){for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(!(t&&n.id===t)&&this.isPointInShape(e,n))return n}return null}getShapesInBrushRadius(e,t){let i=[];for(let n of this.shapes)this.shapeIntersectsBrush(n,e,t)&&i.push(n);return i}shapeIntersectsBrush(e,t,i){switch(e.type){case "line":case "arrow":case "draw":{let n=e.points,s=i+4;for(let r=1;r<n.length;r++)if(this.pointToSegmentDist(t,n[r-1],n[r])<=s)return true;return n.length>0&&Math.hypot(t.x-n[0].x,t.y-n[0].y)<=s}case "circle":return Math.hypot(t.x-e.x,t.y-e.y)<=e.radius+i;case "text":{let n=e;return Math.abs(t.x-e.x)<=n.width/2+i&&Math.abs(t.y-e.y)<=n.height/2+i}default:return Math.abs(t.x-e.x)<=e.width/2+i&&Math.abs(t.y-e.y)<=e.height/2+i}}pointToSegmentDist(e,t,i){let n=i.x-t.x,s=i.y-t.y,r=n*n+s*s,o=r===0?0:Math.max(0,Math.min(1,((e.x-t.x)*n+(e.y-t.y)*s)/r));return Math.hypot(e.x-(t.x+o*n),e.y-(t.y+o*s))}setEraserPoint(e){this.eraserPoint=e,this.scheduleRender();}isPointInShape(e,t){let i=e.x-t.x,n=e.y-t.y;switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return Math.abs(i)<=t.width/2&&Math.abs(n)<=t.height/2;case "circle":return i*i+n*n<=t.radius*t.radius;case "hexagon":{let s=t.width/2,r=t.height/2;return Math.abs(i)<=s&&Math.abs(n)<=r&&Math.abs(i)/s+Math.abs(n)/r<=1.5}case "mind-map":return Math.abs(i)<=t.width/2&&Math.abs(n)<=t.height/2;case "text":{let s=t;return Math.abs(i)<=s.width/2&&Math.abs(n)<=s.height/2}default:return false}}updateArrowBinding(e,t,i,n){let s=this.shapes.find(a=>a.id===e);if(!s||s.type!=="arrow")return;let r=s,o={};if(i){let a=this.shapes.find(c=>c.id===i);if(!a)return;let h=n?.handle||this.getClosestHandle(r,a),l=this.getBindingPosition(a,h),u=n?{...n,toShapeId:i}:{toShapeId:i,handle:h};t==="start"?(o.startBinding=u,o.points=r.points.map((c,p)=>p===0?l:c)):(o.endBinding=u,o.points=r.points.map((c,p)=>p===r.points.length-1?l:c));}else t==="start"?o.startBinding=void 0:o.endBinding=void 0;this.updateShape(e,o);}getClosestHandle(e,t){let i=e.points[0],n=e.points[e.points.length-1],s=e.endBinding?n:i,r=s.x-t.x,o=s.y-t.y;return Math.abs(r)>Math.abs(o)?r>0?"right":"left":o>0?"bottom":"top"}dispose(){this.canvas.removeEventListener("pointerdown",this.handlePointerDown),this.canvas.removeEventListener("pointermove",this.handlePointerMove),this.canvas.removeEventListener("pointerup",this.handlePointerUp),this.canvas.removeEventListener("pointerleave",this.handlePointerUp),this.canvas.removeEventListener("wheel",this.handleWheel),window.removeEventListener("keydown",this.handleKeyDown),window.removeEventListener("keyup",this.handleKeyUp),window.removeEventListener("resize",this.handleResize),this.removeTextInput(),this.tools.forEach(e=>e.dispose()),this.listeners.clear();}};exports.ArrowTool=ae;exports.Camera=ee;exports.Editor=Le;exports.FreehandTool=Q;exports.HandTool=re;exports.LineTool=oe;exports.MINDMAP_COLORS=Te;exports.MINDMAP_FONT_SIZE=pe;exports.MINDMAP_MAX_WIDTH=Xe;exports.MINDMAP_MIN_WIDTH=Ye;exports.MINDMAP_NODE_HEIGHT=We;exports.Mat2d=Y;exports.Renderer=ie;exports.SelectTool=se;exports.ShapeTool=R;exports.THEME=v;exports.UML_FONT_SIZE=W;exports.UML_HEADER_HEIGHT=X;exports.UML_LINE_HEIGHT=V;exports.UML_MIN_WIDTH=ne;exports.UML_PADDING_X=$;exports.UML_PADDING_Y=L;exports.Vec=j;exports.calcUmlClassSize=xe;exports.cloneMindMapNode=ye;exports.countMindMapNodes=Be;exports.findMindMapNode=F;exports.getLanguage=$e;exports.getMindMapNodeDepth=ke;exports.getMindMapParent=te;exports.getTheme=Oe;exports.hexToRgba=q;exports.layoutMindMap=k;exports.mindMapNodeColor=ge;exports.mindMapNodeSize=Ve;exports.setLanguage=ue;exports.setTheme=de;exports.shadeColor=ze;exports.subscribeLanguage=Ke;exports.subscribeTheme=Ge;exports.t=z;
1
+ 'use strict';var j={identity(){return {a:1,b:0,c:0,d:1,e:0,f:0}},translation(a,t){return {a:1,b:0,c:0,d:1,e:a,f:t}},rotation(a){let t=Math.cos(a),e=Math.sin(a);return {a:t,b:e,c:-e,d:t,e:0,f:0}},scale(a,t){return {a,b:0,c:0,d:t,e:0,f:0}},multiply(a,t){return {a:a.a*t.a+a.b*t.c,b:a.a*t.b+a.b*t.d,c:a.c*t.a+a.d*t.c,d:a.c*t.b+a.d*t.d,e:a.e*t.a+a.f*t.c+t.e,f:a.e*t.b+a.f*t.d+t.f}},apply(a,t){return {x:a.a*t.x+a.c*t.y+a.e,y:a.b*t.x+a.d*t.y+a.f}},invert(a){let t=a.a*a.d-a.b*a.c;if(Math.abs(t)<1e-10)return null;let e=1/t;return {a:a.d*e,b:-a.b*e,c:-a.c*e,d:a.a*e,e:(a.c*a.f-a.d*a.e)*e,f:(a.b*a.e-a.a*a.f)*e}},createCameraMatrix(a){let t=j.scale(a.zoom,a.zoom),e=j.translation(a.x,a.y);return j.multiply(e,t)}};var et=class{x=0;y=0;zoom=1;minZoom=.1;maxZoom=10;getMatrix(){return j.createCameraMatrix({x:this.x,y:this.y,zoom:this.zoom})}getInverseMatrix(){return j.invert(this.getMatrix())}screenToPage(t){let e=this.getInverseMatrix();return e?j.apply(e,t):t}pageToScreen(t){return j.apply(this.getMatrix(),t)}translate(t,e){this.x+=t,this.y+=e;}zoomAt(t,e){let i=this.screenToPage(t);this.zoom=Math.max(this.minZoom,Math.min(this.maxZoom,this.zoom*e));let n=this.pageToScreen(i);this.x+=t.x-n.x,this.y+=t.y-n.y;}reset(){this.x=0,this.y=0,this.zoom=1;}getZoom(){return this.zoom}fitBounds(t,e=50){let i=window.innerWidth,n=window.innerHeight,r=(i-e*2)/t.width,s=(n-e*2)/t.height,o=Math.min(r,s,this.maxZoom);this.zoom=Math.max(this.minZoom,o),this.x=(i-t.width*this.zoom)/2-t.x*this.zoom,this.y=(n-t.height*this.zoom)/2-t.y*this.zoom;}};var Wt={primary:"#3b82f6",selection:{outline:"#3b82f6",handleStroke:"#3b82f6",handleFill:"#ffffff",outlineFill:"rgba(59, 130, 246, 0.1)",shadow:"#3b82f6"},grid:"#e5e7eb",text:"#1f2937",editBorder:"#3b82f6",brushFill:"rgba(59, 130, 246, 0.08)",brushStroke:"rgba(59, 130, 246, 0.8)",guide:"rgba(59, 130, 246, 0.6)",lineHighlight:"rgba(59, 130, 246, 0.4)",genDot:"#3b82f6",genLine:"rgba(59, 130, 246, 0.55)"},I={...Wt,selection:{...Wt.selection}},At=new Set;function de(a){return At.add(a),()=>At.delete(a)}function bt(a){a.selection&&Object.assign(I.selection,a.selection);for(let t of Object.keys(a)){if(t==="selection")continue;let e=a[t];e!==void 0&&(I[t]=e);}At.forEach(t=>t());}function ce(){return I}function nt(a,t){let e=Kt(a);if(!e)return a;let i=parseInt(e,16),n=i>>16&255,r=i>>8&255,s=i&255;return `rgba(${n}, ${r}, ${s}, ${t})`}function ue(a,t){let e=Kt(a);if(!e)return a;let i=parseInt(e,16),n=t<0?0:255,r=Math.abs(t),s=o=>Math.round((n-o)*r+o).toString(16).padStart(2,"0");return `#${s(i>>16&255)}${s(i>>8&255)}${s(i&255)}`}function Kt(a){let t=a.replace("#","").trim();return /^[0-9a-fA-F]{3}$|^[0-9a-fA-F]{6}$/.test(t)?t.length===3?t.split("").map(e=>e+e).join(""):t:null}var H=class{context;constructor(t){this.context=t;}getCursor(t){return null}dispose(){}};var Ft={"zh-CN":{"save.success":"\u5DF2\u4FDD\u5B58","save.fail":"\u4FDD\u5B58\u5931\u8D25","tool.select":"\u9009\u62E9\u5DE5\u5177","tool.hand":"\u62D6\u62FD\u89C6\u53E3","tool.rectangle":"\u77E9\u5F62","tool.rounded-rectangle":"\u5706\u89D2\u77E9\u5F62","tool.circle":"\u5706\u5F62","tool.ellipse":"\u692D\u5706","tool.diamond":"\u83F1\u5F62","tool.triangle":"\u4E09\u89D2\u5F62","tool.hexagon":"\u516D\u8FB9\u5F62","tool.parallelogram":"\u5E73\u884C\u56DB\u8FB9\u5F62","tool.trapezoid":"\u68AF\u5F62","tool.pentagon":"\u4E94\u8FB9\u5F62","tool.octagon":"\u516B\u8FB9\u5F62","tool.star":"\u661F\u5F62","tool.uml-class":"UML \u7C7B\u56FE","tool.uml-interface":"UML \u63A5\u53E3","tool.line":"\u76F4\u7EBF","tool.arrow":"\u7EBF\u6761","tool.text":"\u6587\u672C","tool.draw":"\u753B\u7B14","tool.pen":"\u753B\u7B14","tool.highlighter":"\u8367\u5149\u7B14","tool.eraser":"\u6A61\u76AE\u64E6","status.none":"\u672A\u9009\u62E9","status.selected":"\u5DF2\u9009\u62E9 {n} \u4E2A\u56FE\u5F62","toolbar.select":"\u9009\u62E9 (V)","toolbar.hand":"\u62D6\u62FD\u89C6\u53E3 (H)","toolbar.shapes":"\u5F62\u72B6","toolbar.grid":"\u7F51\u683C","toolbar.undo":"\u64A4\u9500 (Ctrl+Z)","toolbar.redo":"\u91CD\u505A (Ctrl+Shift+Z)","toolbar.arrow":"\u7BAD\u5934","toolbar.text":"\u6587\u672C","toolbar.pen":"\u753B\u7B14","toolbar.highlighter":"\u8367\u5149\u7B14","toolbar.eraser":"\u6A61\u76AE\u64E6","toolbar.uml-class":"UML \u7C7B\u56FE","toolbar.uml-interface":"UML \u63A5\u53E3","zoom.in":"\u653E\u5927","zoom.out":"\u7F29\u5C0F","zoom.reset":"\u91CD\u7F6E","style.stroke":"\u8FB9\u6846","style.fill":"\u586B\u5145","style.text":"\u6587\u5B57","style.highlight":"\u9AD8\u4EAE","style.none":"\u65E0","style.connection":"\u8FDE\u7EBF","style.arrow":"\u7BAD\u5934","style.dashed":"\u865A\u7EBF","style.solid":"\u5B9E\u7EBF","style.connection.straight":"\u76F4\u7EBF","style.connection.polyline":"\u6298\u7EBF","style.connection.orthogonal":"\u76F4\u89D2\u6298\u7EBF","style.connection.curve":"\u66F2\u7EBF","style.arrowhead.none":"\u65E0\u7BAD\u5934","style.arrowhead.end":"\u7EC8\u70B9\u7BAD\u5934","style.arrowhead.start":"\u8D77\u70B9\u7BAD\u5934","style.arrowhead.both":"\u53CC\u7BAD\u5934","style.arrowhead.inheritance":"\u7EE7\u627F","style.arrowhead.composition":"\u7EC4\u5408","style.arrowhead.aggregation":"\u805A\u5408","menu.title":"\u9009\u62E9\u65B0\u56FE\u5F62","menu.cancel":"\u70B9\u51FB\u7A7A\u767D\u5904\u53D6\u6D88","shape.rectangle":"\u77E9\u5F62","shape.rounded-rectangle":"\u5706\u89D2","shape.circle":"\u5706\u5F62","shape.ellipse":"\u692D\u5706","shape.diamond":"\u83F1\u5F62","shape.triangle":"\u4E09\u89D2","shape.hexagon":"\u516D\u8FB9\u5F62","shape.parallelogram":"\u5E73\u884C","shape.trapezoid":"\u68AF\u5F62","shape.pentagon":"\u4E94\u8FB9\u5F62","shape.octagon":"\u516B\u8FB9\u5F62","shape.star":"\u661F\u5F62","shape.uml-class":"\u7C7B\u56FE","shape.uml-interface":"\u63A5\u53E3","uml.drag":"\u62D6\u62FD\u6392\u5E8F","uml.delete":"\u5220\u9664\u8BE5\u884C","uml.textColor":"\u6587\u5B57\u989C\u8272","uml.defaultColor":"\u9ED8\u8BA4\u989C\u8272","uml.fontSize":"\u5B57\u53F7","uml.strikethrough":"\u5220\u9664\u7EBF","uml.attribute":"\u5C5E\u6027","uml.method":"\u65B9\u6CD5","minimap.title":"\u5C0F\u5730\u56FE","minimap.expand":"\u5C55\u5F00\u5C0F\u5730\u56FE","minimap.collapse":"\u6536\u8D77\u5C0F\u5730\u56FE","tool.mind-map":"\u601D\u7EF4\u5BFC\u56FE","toolbar.mind-map":"\u601D\u7EF4\u5BFC\u56FE","toolbar.export":"\u5BFC\u51FA","toolbar.export.png":"PNG \u56FE\u7247","toolbar.export.svg":"SVG \u77E2\u91CF\u56FE","toolbar.export.pdf":"PDF \u6587\u6863","shape.mind-map":"\u601D\u7EF4\u5BFC\u56FE","mindmap.defaultRoot":"\u4E2D\u5FC3\u4E3B\u9898","mindmap.defaultBranch":"\u5206\u652F\u4E3B\u9898","mindmap.nodeText":"\u8282\u70B9\u6587\u672C","mindmap.addChild":"\u5B50\u8282\u70B9","mindmap.addSibling":"\u5144\u5F1F\u8282\u70B9","mindmap.deleteNode":"\u5220\u9664\u8282\u70B9","mindmap.color":"\u989C\u8272","mindmap.levelColor":"\u9ED8\u8BA4\u5C42\u7EA7\u8272","mindmap.icon":"\u56FE\u6807","mindmap.noIcon":"\u65E0\u56FE\u6807","mindmap.note":"\u5C5E\u6027\u8BF4\u660E","mindmap.notePlaceholder":"\u8BF4\u660E\u5185\u5BB9\uFF08\u53EF\u9009\uFF09","mindmap.noteColor":"\u8BF4\u660E\u989C\u8272","mindmap.noteColorDefault":"\u540C\u8282\u70B9\u8272","mindmap.collapse":"\u6298\u53E0","mindmap.expand":"\u5C55\u5F00","mindmap.close":"\u5173\u95ED\u7F16\u8F91","mindmap.more":"\u66F4\u591A\u8BBE\u7F6E"},"en-US":{"save.success":"Saved","save.fail":"Save failed","tool.select":"Select tool","tool.hand":"Pan view","tool.rectangle":"Rectangle","tool.rounded-rectangle":"Rounded rectangle","tool.circle":"Circle","tool.ellipse":"Ellipse","tool.diamond":"Diamond","tool.triangle":"Triangle","tool.hexagon":"Hexagon","tool.parallelogram":"Parallelogram","tool.trapezoid":"Trapezoid","tool.pentagon":"Pentagon","tool.octagon":"Octagon","tool.star":"Star","tool.uml-class":"UML class","tool.uml-interface":"UML interface","tool.line":"Line","tool.arrow":"Line","tool.text":"Text","tool.draw":"Pen","tool.pen":"Pen","tool.highlighter":"Highlighter","tool.eraser":"Eraser","status.none":"Nothing selected","status.selected":"{n} shapes selected","toolbar.select":"Select (V)","toolbar.hand":"Pan view (H)","toolbar.shapes":"Shapes","toolbar.grid":"Grid","toolbar.undo":"Undo (Ctrl+Z)","toolbar.redo":"Redo (Ctrl+Shift+Z)","toolbar.arrow":"Arrow","toolbar.text":"Text","toolbar.pen":"Pen","toolbar.highlighter":"Highlighter","toolbar.eraser":"Eraser","toolbar.uml-class":"UML class","toolbar.uml-interface":"UML interface","zoom.in":"Zoom in","zoom.out":"Zoom out","zoom.reset":"Reset","style.stroke":"Border","style.fill":"Fill","style.text":"Text","style.highlight":"Highlight","style.none":"None","style.connection":"Connection","style.arrow":"Arrow head","style.dashed":"Dashed","style.solid":"Solid","style.connection.straight":"Straight","style.connection.polyline":"Polyline","style.connection.orthogonal":"Orthogonal","style.connection.curve":"Curve","style.arrowhead.none":"None","style.arrowhead.end":"End","style.arrowhead.start":"Start","style.arrowhead.both":"Both","style.arrowhead.inheritance":"Inheritance","style.arrowhead.composition":"Composition","style.arrowhead.aggregation":"Aggregation","menu.title":"Create shape","menu.cancel":"Click empty space to cancel","shape.rectangle":"Rectangle","shape.rounded-rectangle":"Rounded","shape.circle":"Circle","shape.ellipse":"Ellipse","shape.diamond":"Diamond","shape.triangle":"Triangle","shape.hexagon":"Hexagon","shape.parallelogram":"Parallelogram","shape.trapezoid":"Trapezoid","shape.pentagon":"Pentagon","shape.octagon":"Octagon","shape.star":"Star","shape.uml-class":"Class","shape.uml-interface":"Interface","uml.drag":"Drag to reorder","uml.delete":"Delete row","uml.textColor":"Text color","uml.defaultColor":"Default color","uml.fontSize":"Font size","uml.strikethrough":"Strikethrough","uml.attribute":"Attributes","uml.method":"Methods","minimap.title":"Minimap","minimap.expand":"Expand minimap","minimap.collapse":"Collapse minimap","tool.mind-map":"Mind map","toolbar.mind-map":"Mind map","toolbar.export":"Export","toolbar.export.png":"PNG image","toolbar.export.svg":"SVG vector","toolbar.export.pdf":"PDF document","shape.mind-map":"Mind map","mindmap.defaultRoot":"Central topic","mindmap.defaultBranch":"Branch topic","mindmap.nodeText":"Node text","mindmap.addChild":"Child","mindmap.addSibling":"Sibling","mindmap.deleteNode":"Delete node","mindmap.color":"Color","mindmap.levelColor":"Default level color","mindmap.icon":"Icon","mindmap.noIcon":"No icon","mindmap.note":"Note","mindmap.notePlaceholder":"Note content (optional)","mindmap.noteColor":"Note color","mindmap.noteColorDefault":"Same as node","mindmap.collapse":"Collapse","mindmap.expand":"Expand","mindmap.close":"Close editor","mindmap.more":"More settings"}},Mt="zh-CN",Lt=new Set;function vt(a){Mt!==a&&(Mt=a,Lt.forEach(t=>t()));}function ge(){return Mt}function pe(a){return Lt.add(a),()=>Lt.delete(a)}function W(a,t){let i=Ft[Mt][a]??Ft["zh-CN"][a];if(t)for(let[n,r]of Object.entries(t))i=i.replace(new RegExp(`\\{${n}\\}`,"g"),String(r));return i}var Nt=["#ef4444","#f59e0b","#10b981","#3b82f6","#8b5cf6","#ec4899"],Z=14,ye=40,fe=80,me=240;function it(a,t){return a.color??Nt[t%Nt.length]}function jt(a){let t=a.text||"",e=0;for(let n of t)e+=/[\u2e80-\u9fff\uf900-\ufaff\uff00-\uffef\u3000-\u303f]/.test(n)?1:.6;let i=Math.max(80,Math.min(240,Math.ceil(e*14)+24));return a.icon&&(i+=26),{width:i,height:40}}function Pt(a){let t={...a};return a.children&&(t.children=a.children.map(e=>Pt(e))),t}function Tt(a,t,e){if(a.id===t)return {...a,...e};let i=a.children??[],n=i.map(r=>Tt(r,t,e));return n.some((r,s)=>r!==i[s])?{...a,children:n}:a}function Rt(a,t,e){if(a.id===t)return {...a,children:[...a.children??[],e],collapsed:false};let i=a.children??[],n=i.map(r=>Rt(r,t,e));return n.some((r,s)=>r!==i[s])?{...a,children:n}:a}function Vt(a,t,e){let i=a.children??[];for(let n=0;n<i.length;n++){if(i[n].id===t){let s=[...i];return s.splice(n+1,0,e),{...a,children:s}}let r=Vt(i[n],t,e);if(r!==i[n])return {...a,children:i.map(s=>s===i[n]?r:s)}}return a}function Ht(a,t){if(a.id===t)return null;let e=a.children??[],i=e.map(n=>Ht(n,t)).filter(n=>n!==null);return i.length!==e.length||i.some((n,r)=>n!==e[r])?{...a,children:i}:a}function q(a,t){if(a.id===t)return a;for(let e of a.children??[]){let i=q(e,t);if(i)return i}return null}function Zt(a,t){if(a.id===t)return 0;for(let e of a.children??[]){let i=Zt(e,t);if(i!==-1)return i+1}return -1}function lt(a,t){for(let e of a.children??[]){if(e.id===t)return a;let i=lt(e,t);if(i)return i}return null}function qt(a){let t=1;for(let e of a.children??[])t+=qt(e);return t}function Jt(a,t){t.set(a.id,jt(a));for(let e of a.children??[])Jt(e,t);}function k(a){let t=new Map;Jt(a,t);let e=new Map,i=c=>{let g=c.collapsed?[]:c.children??[];if(g.length===0)e.set(c.id,t.get(c.id).height);else {let p=0;for(let y of g)p+=i(y);p+=16*(g.length-1),e.set(c.id,Math.max(t.get(c.id).height,p));}return e.get(c.id)};i(a);let n=new Map,r=(c,g,p,y)=>{let f=e.get(c.id),M=t.get(c.id);if(n.set(c.id,{x:p,y:y+f/2,depth:g,width:M.width,height:M.height}),c.collapsed)return;let x=y;for(let v of c.children??[]){let b=t.get(v.id);r(v,g+1,p+M.width/2+48+b.width/2,x),x+=e.get(v.id)+16;}};r(a,0,0,-e.get(a.id)/2);let s=1/0,o=-1/0,h=1/0,l=-1/0;n.forEach(c=>{s=Math.min(s,c.x-c.width/2),o=Math.max(o,c.x+c.width/2),h=Math.min(h,c.y-c.height/2),l=Math.max(l,c.y+c.height/2);});let d=(s+o)/2,u=(h+l)/2;return n.forEach(c=>{c.x-=d,c.y-=u;}),{positions:n,width:o-s,height:l-h}}var xe={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},Se={rectangle:{width:120,height:60},"rounded-rectangle":{width:120,height:60,borderRadius:8},circle:{width:80,height:80},ellipse:{width:100,height:70},diamond:{width:100,height:80},triangle:{width:100,height:90},hexagon:{width:100,height:90},parallelogram:{width:120,height:60},trapezoid:{width:120,height:70},pentagon:{width:100,height:90},octagon:{width:100,height:90},star:{width:100,height:100}},_=14,L=22,K=36,B=14,D=8,dt=160,we=["rectangle","rounded-rectangle","circle","ellipse","diamond","triangle","hexagon","parallelogram","trapezoid","pentagon","octagon","star","uml-class","uml-interface","mind-map"];function It(a){return we.includes(a)}function kt(a,t,e){let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,n=Se[a]||{width:120,height:60},r=n.width,s=n.height,o=n.radius??r/2,h=n.borderRadius??8,l=e??{...xe};switch(a){case "rounded-rectangle":return {id:i,type:"rounded-rectangle",x:t.x,y:t.y,width:r,height:s,borderRadius:h,rotation:0,style:l};case "circle":return {id:i,type:"circle",x:t.x,y:t.y,radius:o,rotation:0,style:l};case "ellipse":return {id:i,type:"ellipse",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "diamond":return {id:i,type:"diamond",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "triangle":return {id:i,type:"triangle",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "hexagon":return {id:i,type:"hexagon",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "parallelogram":return {id:i,type:"parallelogram",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "trapezoid":return {id:i,type:"trapezoid",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "pentagon":return {id:i,type:"pentagon",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "octagon":return {id:i,type:"octagon",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "star":return {id:i,type:"star",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l};case "uml-class":{let d="ClassName",u=[{id:`attr_${Date.now()}_1`,visibility:"+",name:"field",type:"string"}],c=[{id:`meth_${Date.now()}_1`,visibility:"+",name:"method",params:"param",returnType:"void"}],{width:g,height:p}=Ct(d,u,c);return {id:i,type:"uml-class",x:t.x,y:t.y,width:g,height:p,className:d,attributes:u,methods:c,rotation:0,style:{...l,fillColor:"#ffffff"}}}case "uml-interface":{let d="Interface",u=[{id:`meth_${Date.now()}_1`,visibility:"+",name:"method",params:"type",returnType:"type"}],c=_*.6,g=u.map(x=>`${x.visibility} ${x.name}(${x.params}): ${x.returnType}`),p=Math.max(d.length,...g.map(x=>x.length),0),y=Math.max(dt,p*c+B*2),f=u.length>0?u.length*L+D*2:D*2,M=K+f;return {id:i,type:"uml-interface",x:t.x,y:t.y,width:y,height:M,className:d,methods:u,rotation:0,style:{...l,fillColor:"#ffffff"}}}case "mind-map":{let d=p=>`mm_${p}_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,u={id:d("root"),text:W("mindmap.defaultRoot"),children:[{id:d("b1"),text:W("mindmap.defaultBranch")},{id:d("b2"),text:W("mindmap.defaultBranch")},{id:d("b3"),text:W("mindmap.defaultBranch")}]},{width:c,height:g}=k(u);return {id:i,type:"mind-map",x:t.x,y:t.y,width:c,height:g,root:u,rotation:0,style:{...l,fillColor:"#ffffff"}}}default:return {id:i,type:"rectangle",x:t.x,y:t.y,width:r,height:s,rotation:0,style:l}}}function Ct(a,t,e){let i=_*.6,n=[a];for(let u of t)n.push(`${u.visibility} ${u.name}: ${u.type}`);for(let u of e)n.push(`${u.visibility} ${u.name}(${u.params}): ${u.returnType}`);let s=Math.max(...n.map(u=>u.length),0)*i+B*2,o=Math.max(dt,s),h=t.length>0?t.length*L+D*2:D*2,l=e.length>0?e.length*L+D*2:D*2,d=K+h+l;return {width:o,height:d}}var V=class extends H{type;constructor(t,e){super(t),this.type=e;}onPointerDown(t,e){let i=kt(this.type,t);this.context.commitHistory(),this.context.addShape(i),this.context.selectShape(i.id,false);}onPointerMove(t,e){}onPointerUp(t,e){this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(t){return this.context.getMindMapCursorHitAtPoint(t)?"pointer":"crosshair"}};var Bt=14,Et=class extends H{type="eraser";erasing=false;lastPoint=null;erasedIds=new Set;onPointerDown(t){this.erasing=true,this.lastPoint=t,this.erasedIds.clear(),this.context.commitHistory(),this.context.setEraserPoint(t),this.eraseAt(t);}onPointerMove(t){if(!this.erasing||!this.lastPoint)return;let e=this.lastPoint,i=Math.hypot(t.x-e.x,t.y-e.y),n=Math.max(1,Math.ceil(i/Math.max(this.brushRadius()*.5,1)));for(let r=1;r<=n;r++){let s=r/n;this.eraseAt({x:e.x+(t.x-e.x)*s,y:e.y+(t.y-e.y)*s});}this.lastPoint=t,this.context.setEraserPoint(t);}onPointerUp(){this.erasing=false,this.lastPoint=null,this.erasedIds.clear(),this.context.setEraserPoint(null);}onKeyDown(){}onKeyUp(){}getCursor(){return this.erasing?"grabbing":"crosshair"}dispose(){this.erasing=false,this.lastPoint=null,this.erasedIds.clear(),this.context.setEraserPoint(null);}brushRadius(){return Bt/this.context.getCamera().getZoom()}eraseAt(t){let e=this.context.getShapesInBrushRadius(t,this.brushRadius());for(let i of e)this.erasedIds.has(i.id)||(this.erasedIds.add(i.id),this.context.deleteShape(i.id));}};var st=class a{ctx;width=0;height=0;dpr=window.devicePixelRatio||1;showGrid=false;textLayoutCache=new Map;static TEXT_CACHE_LIMIT=500;constructor(t,e){let i=t.getContext("2d");if(!i)throw new Error("Failed to get Canvas 2D context");this.ctx=i,typeof e=="number"&&e>0&&(this.dpr=e);}resize(t,e){this.width=t,this.height=e;let i=Math.ceil(t*this.dpr),n=Math.ceil(e*this.dpr);(this.ctx.canvas.width!==i||this.ctx.canvas.height!==n)&&(this.ctx.canvas.width=i,this.ctx.canvas.height=n,this.ctx.canvas.style.width=`${t}px`,this.ctx.canvas.style.height=`${e}px`);}setShowGrid(t){this.showGrid=t;}render(t,e,i,n,r,s,o,h,l,d,u){let c=this.ctx,g=e.getZoom(),p=e.x,y=e.y;c.setTransform(1,0,0,1,0,0),c.clearRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height),u&&(c.fillStyle=u,c.fillRect(0,0,this.ctx.canvas.width,this.ctx.canvas.height));let f=this.dpr*g;c.setTransform(f,0,0,f,f*p,f*y),this.showGrid&&this.drawGrid(c,g,p,y);let M=null;for(let v of t)if(v.type==="arrow"&&(v.startBinding||v.endBinding)){M=new Map,t.forEach(b=>M.set(b.id,b));break}let x=M??new Map;t.forEach(v=>{c.save(),c.translate(v.x,v.y),c.rotate(v.rotation);let b=i.has(v.id);this.drawShape(c,v,b,g,x,l,d),c.restore();}),o&&this.drawGenerationPreview(c,o,g),n&&this.drawBrushRect(c,n,g),r&&r.length>0&&this.drawSnapGuides(c,r,g),s&&this.drawConnectingTargetHighlight(c,s,t,g),h&&this.drawEraserBrush(c,h,g),c.setTransform(1,0,0,1,0,0);}drawEraserBrush(t,e,i){let n=Bt/i;t.beginPath(),t.arc(e.x,e.y,n,0,Math.PI*2),t.fillStyle=nt(I.primary,.12),t.fill(),t.strokeStyle=nt(I.primary,.55),t.lineWidth=1.5/i,t.stroke();}drawConnectingTargetHighlight(t,e,i,n){let r=i.find(l=>l.id===e);if(!r||r.type==="line"||r.type==="arrow"||r.type==="draw")return;let s=this.getShapeWorldBounds(r),o=[{x:s.x+s.width/2,y:s.y},{x:s.x+s.width,y:s.y+s.height/2},{x:s.x+s.width/2,y:s.y+s.height},{x:s.x,y:s.y+s.height/2}],h=6/n;t.save(),o.forEach(l=>{t.beginPath(),t.arc(l.x,l.y,h,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=2/n,t.stroke();}),t.restore();}getShapeWorldBounds(t){let e=this.getShapeBounds(t);return {x:t.x+e.x,y:t.y+e.y,width:e.width,height:e.height}}drawBrushRect(t,e,i){t.save(),t.fillStyle=I.brushFill,t.strokeStyle=I.brushStroke,t.lineWidth=1.5/i,t.setLineDash([4/i,4/i]),t.beginPath(),t.rect(e.x,e.y,e.width,e.height),t.fill(),t.stroke(),t.restore();}drawGrid(t,e,i,n){let r=-i,s=-n,o=r+this.width/e,h=s+this.height/e,l=20;for(;l*e<10;)l*=2;t.strokeStyle=I.grid,t.lineWidth=1/e,t.beginPath();for(let d=Math.floor(r/l)*l;d<=o;d+=l)t.moveTo(d,s),t.lineTo(d,h);for(let d=Math.floor(s/l)*l;d<=h;d+=l)t.moveTo(r,d),t.lineTo(o,d);t.stroke();}drawShape(t,e,i,n,r,s,o){switch(this.applyStyle(t,e.style,n),e.type){case "rectangle":this.drawRectangle(t,e,i);break;case "rounded-rectangle":this.drawRoundedRectangle(t,e,i);break;case "circle":this.drawCircle(t,e,i);break;case "ellipse":this.drawEllipse(t,e,i);break;case "diamond":this.drawDiamond(t,e,i);break;case "triangle":this.drawTriangle(t,e,i);break;case "hexagon":this.drawHexagon(t,e,i);break;case "parallelogram":this.drawParallelogram(t,e,i);break;case "trapezoid":this.drawTrapezoid(t,e,i);break;case "pentagon":this.drawPentagon(t,e,i);break;case "octagon":this.drawOctagon(t,e,i);break;case "star":this.drawStar(t,e,i);break;case "uml-class":this.drawUmlClass(t,e,i);break;case "uml-interface":this.drawUmlInterface(t,e,i);break;case "mind-map":this.drawMindMap(t,e,i,s,o);break;case "line":this.drawLine(t,e,r,i,n);break;case "arrow":this.drawArrow(t,e,r,i,n);break;case "text":this.drawText(t,e);break;case "draw":this.drawFreehand(t,e);break}if(e.text&&e.type!=="text"&&e.type!=="line"&&e.type!=="arrow"&&e.type!=="draw"&&this.drawShapeText(t,e),i){let h=e.type==="line"||e.type==="arrow"||e.type==="draw";e.type==="mind-map"||(h?this.drawSelectionHandles(t,e,n):(this.drawSelectionOutline(t,e,n),this.drawSelectionHandles(t,e,n)));}}applyStyle(t,e,i){t.strokeStyle=e.strokeColor,t.fillStyle=e.fillColor,t.lineWidth=e.strokeWidth/i,t.lineCap="round",t.lineJoin="round",e.strokeDash?t.setLineDash(e.strokeDash):t.setLineDash([]);}drawRectangle(t,e,i){t.beginPath(),t.rect(-e.width/2,-e.height/2,e.width,e.height),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawRoundedRectangle(t,e,i){let{width:n,height:r,borderRadius:s}=e;t.beginPath(),t.roundRect(-n/2,-r/2,n,r,s),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawCircle(t,e,i){t.beginPath(),t.arc(0,0,e.radius,0,Math.PI*2),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawEllipse(t,e,i){t.beginPath(),t.ellipse(0,0,e.width/2,e.height/2,0,0,Math.PI*2),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawDiamond(t,e,i){t.beginPath(),t.moveTo(0,-e.height/2),t.lineTo(e.width/2,0),t.lineTo(0,e.height/2),t.lineTo(-e.width/2,0),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawTriangle(t,e,i){t.beginPath(),t.moveTo(0,-e.height/2),t.lineTo(e.width/2,e.height/2),t.lineTo(-e.width/2,e.height/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawHexagon(t,e,i){let n=e.width/2,r=e.height/2;t.beginPath();for(let s=0;s<6;s++){let o=s*Math.PI/3-Math.PI/2,h=n*Math.cos(o),l=r*Math.sin(o);s===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawParallelogram(t,e,i){let{width:n,height:r}=e,s=n*.2;t.beginPath(),t.moveTo(-n/2+s,-r/2),t.lineTo(n/2,-r/2),t.lineTo(n/2-s,r/2),t.lineTo(-n/2,r/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawTrapezoid(t,e,i){let{width:n,height:r}=e,s=n*.15;t.beginPath(),t.moveTo(-n/2+s,-r/2),t.lineTo(n/2-s,-r/2),t.lineTo(n/2,r/2),t.lineTo(-n/2,r/2),t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawPentagon(t,e,i){let n=e.width/2,r=e.height/2;t.beginPath();for(let s=0;s<5;s++){let o=s*2*Math.PI/5-Math.PI/2,h=n*Math.cos(o),l=r*Math.sin(o);s===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawOctagon(t,e,i){let n=e.width/2,r=e.height/2;t.beginPath();for(let s=0;s<8;s++){let o=s*Math.PI/4-Math.PI/8,h=n*Math.cos(o),l=r*Math.sin(o);s===0?t.moveTo(h,l):t.lineTo(h,l);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawStar(t,e,i){let n=e.width/2,r=e.height/2,s=5,o=.4;t.beginPath();for(let h=0;h<s*2;h++){let l=h*Math.PI/s-Math.PI/2,d=h%2===0?1:o,u=n*d*Math.cos(l),c=r*d*Math.sin(l);h===0?t.moveTo(u,c):t.lineTo(u,c);}t.closePath(),e.style.fillColor!=="transparent"&&t.fill(),t.stroke();}drawUmlClass(t,e,i){let{width:n,height:r,className:s,attributes:o,methods:h}=e,l=n/2,d=r/2,u=K,c=o.length>0?o.length*L+D*2:D*2;t.beginPath(),t.rect(-l,-d,n,r),e.style.fillColor!=="transparent"&&(t.fillStyle=e.style.fillColor,t.fill()),t.stroke(),t.beginPath(),t.moveTo(-l,-d+u),t.lineTo(l,-d+u),t.moveTo(-l,-d+u+c),t.lineTo(l,-d+u+c),t.stroke(),t.save(),t.textBaseline="middle";let g=n-B*2,p=x=>{if(t.measureText(x).width<=g)return x;let v="\u2026",b=0,P=x.length;for(;b<P;){let T=b+P+1>>1;t.measureText(x.slice(0,T)+v).width<=g?b=T:P=T-1;}return x.slice(0,b)+v},y=(x,v,b,P,T,E,U)=>{let Y=P||_,F=T||"#1f2937";t.font=`${Y}px sans-serif`,t.fillStyle=F,t.textAlign=U;let N=p(x);if(t.fillText(N,v,b),E){let R=t.measureText(N).width,St=v;t.strokeStyle=F,t.beginPath(),t.moveTo(St,b),t.lineTo(St+R,b),t.stroke();}};t.font=`bold ${e.fontSize||_}px sans-serif`,t.textAlign="center",t.fillStyle=e.textColor||"#1f2937",t.fillText(p(s),0,-d+u/2);let f=-d+u+D+L/2;o.forEach((x,v)=>{let b=`${x.visibility} ${x.name}: ${x.type}`;y(b,-l+B,f+v*L,x.fontSize||e.fontSize||0,x.textColor||e.textColor||"",!!x.strikethrough,"left");});let M=-d+u+c+D+L/2;h.forEach((x,v)=>{let b=`${x.visibility} ${x.name}(${x.params}): ${x.returnType}`;y(b,-l+B,M+v*L,x.fontSize||e.fontSize||0,x.textColor||e.textColor||"",!!x.strikethrough,"left");}),t.restore();}drawUmlInterface(t,e,i){let{width:n,height:r,className:s,methods:o}=e,h=n/2,l=r/2,d=K;t.beginPath(),t.rect(-h,-l,n,r),e.style.fillColor!=="transparent"&&(t.fillStyle=e.style.fillColor,t.fill()),t.stroke(),t.beginPath(),t.moveTo(-h,-l+d),t.lineTo(h,-l+d),t.stroke(),t.save(),t.textBaseline="middle";let u=n-B*2,c=f=>{if(t.measureText(f).width<=u)return f;let M="\u2026",x=0,v=f.length;for(;x<v;){let b=x+v+1>>1;t.measureText(f.slice(0,b)+M).width<=u?x=b:v=b-1;}return f.slice(0,x)+M},g=(f,M,x,v,b,P,T)=>{let E=v||_,U=b||"#1f2937";t.font=`${E}px sans-serif`,t.fillStyle=U,t.textAlign=T;let Y=c(f);if(t.fillText(Y,M,x),P){let F=t.measureText(Y).width,N=M;t.strokeStyle=U,t.beginPath(),t.moveTo(N,x),t.lineTo(N+F,x),t.stroke();}};t.font=`bold ${e.fontSize||_}px sans-serif`,t.textAlign="center",t.fillStyle=e.textColor||"#1f2937";let p=`<<${s||"Interface"}>>`;t.fillText(c(p),0,-l+d/2);let y=-l+d+D+L/2;o.forEach((f,M)=>{let x=`${f.visibility} ${f.name}(${f.params}): ${f.returnType}`;g(x,-h+B,y+M*L,f.fontSize||e.fontSize||0,f.textColor||e.textColor||"",!!f.strikethrough,"left");}),t.restore();}static DEFAULT_CORNER_RADIUS=10;static ROUTE_CLEARANCE=30;static CONNECTION_LEAD=24;static CONNECTED_PAD=8;drawMindMap(t,e,i,n,r){let o=k(e.root).positions;this.drawMindMapConnections(t,e.root,o),this.drawMindMapNodes(t,e,o,n,r);}drawMindMapConnections(t,e,i){let n=r=>{if(r.collapsed)return;let s=i.get(r.id);if(s)for(let o of r.children??[]){let h=i.get(o.id);if(!h)continue;let l=it(o,h.depth);t.strokeStyle=l,t.lineWidth=2,t.lineCap="round",t.beginPath(),t.moveTo(s.x+s.width/2,s.y);let d=(s.x+s.width/2+(h.x-h.width/2))/2;t.bezierCurveTo(d,s.y,d,h.y,h.x-h.width/2,h.y),t.stroke(),n(o);}};n(e);}drawMindMapNodes(t,e,i,n,r){let s=e.root,o=h=>{let l=i.get(h.id);if(!l)return;let d=it(h,l.depth),u=l.width/2,c=l.height/2;if(t.fillStyle="#ffffff",t.strokeStyle=d,t.lineWidth=2,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke(),r&&r.shapeId===e.id&&r.nodeId===h.id&&(t.fillStyle=nt(I.primary,.06),t.strokeStyle=nt(I.primary,.55),t.lineWidth=2,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke()),n&&n.shapeId===e.id&&n.nodeId===h.id&&(t.fillStyle=nt(I.primary,.12),t.strokeStyle=I.primary,t.lineWidth=2.5,t.beginPath(),t.roundRect(l.x-u,l.y-c,l.width,l.height,6),t.fill(),t.stroke()),h.children&&h.children.length>0&&(t.fillStyle="#ffffff",t.strokeStyle=d,t.lineWidth=2,t.beginPath(),t.arc(l.x+u+10,l.y,8,0,Math.PI*2),t.fill(),t.stroke(),t.fillStyle=d,t.font="bold 13px sans-serif",t.textAlign="center",t.textBaseline="middle",t.fillText(h.collapsed?"+":"\u2212",l.x+u+10,l.y+.5)),h.note){let T=h.noteColor??d;t.font="11px sans-serif";let E=Math.min(t.measureText(h.note).width+12,130),U=16;t.fillStyle=T,t.beginPath(),t.roundRect(l.x-u,l.y-c-U+2,E,U,4),t.fill(),t.fillStyle="#ffffff",t.font="11px sans-serif",t.textAlign="left",t.textBaseline="middle",t.fillText(t.measureText(h.note).width+12>130?h.note.slice(0,12)+"\u2026":h.note,l.x-u+6,l.y-c-U/2+2);}t.font=`${14}px sans-serif`;let f=h.icon?18:0,M=l.width-f-(h.icon?8:0)-16,x=this.ellipsizeText(t,h.text||"",M),v=t.measureText(x).width,b=f+(f?8:0)+v,P=l.x-b/2;if(t.textBaseline="middle",h.icon&&(t.font="16px sans-serif",t.textAlign="left",t.fillStyle="#1f2937",t.fillText(h.icon,P,l.y+1),P+=f+8),t.font=`${14}px sans-serif`,t.textAlign="left",t.fillStyle="#1f2937",t.fillText(x,P,l.y),!h.collapsed)for(let T of h.children??[])o(T);};o(s);}ellipsizeText(t,e,i){if(i<=0)return "";if(t.measureText(e).width<=i)return e;let n="\u2026",r=0,s=e.length;for(;r<s;){let o=r+s+1>>1;t.measureText(e.slice(0,o)+n).width<=i?r=o:s=o-1;}return e.slice(0,r)+n}drawLine(t,e,i,n,r){if(e.points.length<2)return;let s=e.points.map(d=>({x:d.x,y:d.y}));s.length>=2&&(s[0]=this.clampToShapeOutline(s[0],i,e.id,s[s.length-1]),s[s.length-1]=this.clampToShapeOutline(s[s.length-1],i,e.id,s[0]));let o=s.map(d=>({x:d.x-e.x,y:d.y-e.y})),h=e.connectionType||"straight",l=h==="straight"?this.getAlignedPoints(o):this.buildPathPoints(o,h,this.collectRoutingObstacles(e.id,o[0],o[o.length-1],i,{x:e.x,y:e.y}),{fromN:this.getDockNormal(s[0],i,e.id),toN:this.getDockNormal(s[s.length-1],i,e.id)});if(h==="straight"){t.beginPath(),t.moveTo(o[0].x,o[0].y);for(let d=1;d<o.length;d++)t.lineTo(o[d].x,o[d].y);t.stroke(),t.setLineDash([]);}else h==="orthogonal"?this.drawSharpPolyline(t,l):this.drawRoundedPolyline(t,l,a.DEFAULT_CORNER_RADIUS),t.stroke(),t.setLineDash([]);n&&this.drawLinearHighlight(t,l,r);}drawArrow(t,e,i,n,r){if(e.points.length<2)return;let s=e.points.map(c=>({x:c.x,y:c.y}));if(e.startBinding){let c=i.get(e.startBinding.toShapeId);c&&(s[0]=this.getBindingPoint(c,e.startBinding));}if(e.endBinding){let c=i.get(e.endBinding.toShapeId);c&&(s[s.length-1]=this.getBindingPoint(c,e.endBinding));}s[0]=this.clampToShapeOutline(s[0],i,e.id,s[s.length-1]),s[s.length-1]=this.clampToShapeOutline(s[s.length-1],i,e.id,s[0]);let o=s.map(c=>({x:c.x-e.x,y:c.y-e.y})),h=e.connectionType||"straight",l=e.arrowHead??"end";!!e.dashed?t.setLineDash([8,5]):t.setLineDash([]);let u;if(h==="straight"){let c=this.getAlignedPoints(o);u=c,t.beginPath(),t.moveTo(c[0].x,c[0].y);for(let g=1;g<c.length;g++)t.lineTo(c[g].x,c[g].y);t.stroke(),this.drawArrowHeads(t,c,l);}else u=this.buildPathPoints(o,h,this.collectRoutingObstacles(e.id,o[0],o[o.length-1],i,{x:e.x,y:e.y}),{fromN:this.getDockNormal(s[0],i,e.id),toN:this.getDockNormal(s[s.length-1],i,e.id)}),h==="orthogonal"?this.drawSharpPolyline(t,u):this.drawRoundedPolyline(t,u,a.DEFAULT_CORNER_RADIUS),t.stroke(),this.drawArrowHeads(t,u,l);t.setLineDash([]),n&&this.drawLinearHighlight(t,u,r);}drawLinearHighlight(t,e,i){if(!(!e||e.length<2)){t.save(),t.strokeStyle=I.lineHighlight,t.lineWidth=7/i,t.lineCap="round",t.lineJoin="round",t.setLineDash([]),t.beginPath(),t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length;n++)t.lineTo(e[n].x,e[n].y);t.stroke(),t.restore();}}drawGenerationPreview(t,e,i){let{from:n,to:r,type:s}=e;t.save(),t.beginPath(),t.arc(n.x,n.y,7/i,0,Math.PI*2),t.fillStyle=I.genDot,t.fill(),t.strokeStyle=I.genLine,t.lineWidth=2/i,t.setLineDash([5/i,4/i]),t.lineCap="round",t.beginPath(),t.moveTo(n.x,n.y),t.lineTo(r.x,r.y),t.stroke(),s&&this.drawPreviewShapeOutline(t,r,s,i),t.restore();}drawPreviewShapeOutline(t,e,i,n){let l=e.x,d=e.y;switch(t.strokeStyle=I.genLine,t.lineWidth=1.5/n,t.setLineDash([6/n,4/n]),t.beginPath(),i){case "circle":case "ellipse":t.ellipse(l,d,i==="circle"?40:120/2,i==="circle"?40:60/2,0,0,Math.PI*2);break;case "diamond":t.moveTo(l,d-30),t.lineTo(l+60,d),t.lineTo(l,d+30),t.lineTo(l-60,d),t.closePath();break;case "triangle":t.moveTo(l,d-30),t.lineTo(l+60,d+30),t.lineTo(l-60,d+30),t.closePath();break;case "hexagon":for(let u=0;u<6;u++){let c=u*Math.PI/3-Math.PI/2,g=l+60*Math.cos(c),p=d+30*Math.sin(c);u===0?t.moveTo(g,p):t.lineTo(g,p);}t.closePath();break;case "parallelogram":t.moveTo(l-60+18,d-30),t.lineTo(l+60,d-30),t.lineTo(l+60-18,d+30),t.lineTo(l-60,d+30),t.closePath();break;default:t.roundRect(l-60,d-30,120,60,i==="rounded-rectangle"?8:4);break}t.stroke();}static ALIGN_TOLERANCE=8;getAlignedPoints(t){if(t.length<2)return t;let e=t[0],i=t[t.length-1],n=i.x-e.x,r=i.y-e.y,s=a.ALIGN_TOLERANCE;if(Math.abs(r)<=s){let o=(e.y+i.y)/2;return t.map(h=>({x:h.x,y:o}))}if(Math.abs(n)<=s){let o=(e.x+i.x)/2;return t.map(h=>({x:o,y:h.y}))}return t}buildPathPoints(t,e,i=[],n={}){if(t.length<2||e==="straight")return t;switch(e){case "polyline":return this.generatePolylinePoints(t,i,n);case "orthogonal":return this.generateOrthogonalPoints(t,i,n);case "curve":return this.generateCurvePoints(t);default:return t}}drawRoundedPolyline(t,e,i){if(t.beginPath(),!(e.length<2)){if(e.length===2||i<=0){t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length;n++)t.lineTo(e[n].x,e[n].y);return}t.moveTo(e[0].x,e[0].y);for(let n=1;n<e.length-1;n++){let r=e[n-1],s=e[n],o=e[n+1],h=s.x-r.x,l=s.y-r.y,d=o.x-s.x,u=o.y-s.y,c=Math.hypot(h,l),g=Math.hypot(d,u);if(c<1e-6||g<1e-6){t.lineTo(s.x,s.y);continue}let p=Math.min(i,c*.5,g*.5),y=s.x-h/c*p,f=s.y-l/c*p,M=s.x+d/g*p,x=s.y+u/g*p;t.lineTo(y,f),t.arcTo(s.x,s.y,M,x,p);}t.lineTo(e[e.length-1].x,e[e.length-1].y);}}drawSharpPolyline(t,e){if(t.beginPath(),!(e.length<2)){t.moveTo(e[0].x,e[0].y);for(let i=1;i<e.length;i++)t.lineTo(e[i].x,e[i].y);}}drawSnapGuides(t,e,i){t.save(),t.strokeStyle=I.guide,t.lineWidth=1/i,t.setLineDash([6/i,4/i]),t.beginPath();for(let n of e)n.type==="horizontal"?(t.moveTo(n.start,n.position),t.lineTo(n.end,n.position)):(t.moveTo(n.position,n.start),t.lineTo(n.position,n.end));t.stroke(),t.restore();}generatePolylinePoints(t,e=[],i={}){if(t.length<2)return t;let n=[];n.push(t[0]);let r=t.length-1,s=a.CONNECTION_LEAD;for(let o=1;o<t.length;o++){let h=t[o-1],l=t[o],d=o===1,u=o===r,c=d&&i.fromN?{x:h.x+i.fromN.x*s,y:h.y+i.fromN.y*s}:h,g=u&&i.toN?{x:l.x+i.toN.x*s,y:l.y+i.toN.y*s}:l;d&&i.fromN&&n.push(c);let p=this.computeOrthogonalRoute(c,g,e);for(let y of p)n.push(y);u&&i.toN&&n.push(l);}return this.collapseLinePoints(n)}generateOrthogonalPoints(t,e=[],i={}){return this.generatePolylinePoints(t,e,i)}collapseLinePoints(t){let e=[];for(let i of t){let n=e.length;if(!(n>0&&Math.abs(e[n-1].x-i.x)<1e-6&&Math.abs(e[n-1].y-i.y)<1e-6)){if(n>=2){let r=e[n-2],s=e[n-1];if(Math.abs(r.y-s.y)<1e-6&&Math.abs(s.y-i.y)<1e-6||Math.abs(r.x-s.x)<1e-6&&Math.abs(s.x-i.x)<1e-6){e[n-1]=i;continue}}e.push(i);}}return e}computeOrthogonalRoute(t,e,i=[]){let n=e.x-t.x,r=e.y-t.y;if(Math.abs(n)<1||Math.abs(r)<1)return [e];let s=t.x+n/2,o=t.y+r/2,h=i.length>0,l=[[{x:s,y:t.y},{x:s,y:e.y},e],[{x:t.x,y:o},{x:e.x,y:o},e],[{x:e.x,y:t.y},e],[{x:t.x,y:e.y},e]];if(h){for(let u of l)if(!this.routeHitsObstacles(t,u,i))return u;let d=this.routeOrthogonalAvoidance(t,e,i);return d&&d.length>0?d:i.length>0&&!this.routeHitsObstacles(t,l[0],i)?l[0]:this.routeHitsObstacles(t,l[1],i)?[e]:l[1]}return Math.abs(n)>=Math.abs(r)?[{x:s,y:t.y},{x:s,y:e.y},e]:[{x:t.x,y:o},{x:e.x,y:o},e]}collectRoutingObstacles(t,e,i,n,r){if(!n||n.size===0)return [];let s=[];return n.forEach((o,h)=>{if(h===t)return;let l=this.getShapeBounds(o),d={x:o.x+l.x-r.x,y:o.y+l.y-r.y,width:l.width,height:l.height};d.pad=this.pointInRect(e,d)||this.pointInRect(i,d)?a.CONNECTED_PAD:a.ROUTE_CLEARANCE,s.push(d);}),s}pointInRect(t,e){return t.x>=e.x&&t.x<=e.x+e.width&&t.y>=e.y&&t.y<=e.y+e.height}routeHitsObstacles(t,e,i){let n=[t,...e];for(let r=1;r<n.length;r++)if(this.segmentHitsObstacle(n[r-1],n[r],i))return true;return false}segmentHitsObstacle(t,e,i){for(let n of i){let r=n.pad??a.ROUTE_CLEARANCE,s=n.y-r,o=n.y+n.height+r,h=n.x-r,l=n.x+n.width+r;if(Math.abs(t.y-e.y)<.5){if(t.y>=s&&t.y<=o){let d=Math.min(t.x,e.x);if(Math.max(t.x,e.x)>=h&&d<=l)return true}}else if(t.x>=h&&t.x<=l){let d=Math.min(t.y,e.y);if(Math.max(t.y,e.y)>=s&&d<=o)return true}}return false}routeOrthogonalAvoidance(t,e,i){let n=new Set([t.x,e.x]),r=new Set([t.y,e.y]);for(let S of i){let w=S.pad??a.ROUTE_CLEARANCE;n.add(S.x-w),n.add(S.x+S.width+w),r.add(S.y-w),r.add(S.y+S.height+w);}let s=[...n].sort((S,w)=>S-w),o=[...r].sort((S,w)=>S-w),h=s.length,l=o.length,d=S=>{for(let w=0;w<h;w++)if(Math.abs(s[w]-S)<1e-6)return w;return 0},u=S=>{for(let w=0;w<l;w++)if(Math.abs(o[w]-S)<1e-6)return w;return 0},c=d(t.x),g=u(t.y),p=d(e.x),y=u(e.y),f=[],M=[];for(let S=0;S<h;S++)f.push(new Array(l).fill(true)),M.push(new Array(l).fill(true));for(let S of i){let w=S.pad??a.ROUTE_CLEARANCE,C=S.x-w,$=S.x+S.width+w,G=S.y-w,z=S.y+S.height+w;for(let A=0;A<h-1;A++)if(!(s[A+1]<=C||s[A]>=$))for(let X=0;X<l;X++)o[X]>G&&o[X]<z&&(f[A][X]=false);for(let A=0;A<l-1;A++)if(!(o[A+1]<=G||o[A]>=z))for(let X=0;X<h;X++)s[X]>C&&s[X]<$&&(M[X][A]=false);}let x=h*l,v=1/0,b=new Float64Array(x).fill(v),P=new Int32Array(x).fill(-1),T=new Uint8Array(x),E=S=>{let w=S%h,C=S/h|0;return Math.abs(s[w]-e.x)+Math.abs(o[C]-e.y)},U=(S,w)=>S%h===w%h,Y=g*h+c,F=y*h+p;b[Y]=0;let N=[Y],R=[E(Y)],St=S=>{let w=b[S]+E(S);N.push(S),R.push(w);let C=N.length-1;for(;C>0;){let $=C-1>>1;if(R[$]<=R[C])break;[N[$],N[C]]=[N[C],N[$]],[R[$],R[C]]=[R[C],R[$]],C=$;}},le=()=>{let S=N[0],w=N.pop(),C=R.pop();if(N.length){N[0]=w,R[0]=C;let $=0;for(;;){let G=$*2+1,z=G+1,A=$;if(G<N.length&&R[G]<R[A]&&(A=G),z<N.length&&R[z]<R[A]&&(A=z),A===$)break;[N[A],N[$]]=[N[$],N[A]],[R[A],R[$]]=[R[$],R[A]],$=A;}}return S},wt=(S,w,C)=>{let $=S%h,G=w%h,z=b[S]+(Math.abs(G-$)===0?Math.abs(o[w/h|0]-o[S/h|0]):Math.abs(s[G]-s[$]))+C;z<b[w]&&(b[w]=z,P[w]=S,T[w]||St(w));};for(;N.length;){let S=le();if(S===F||T[S]){if(S===F)break;continue}T[S]=1;let w=S%h,C=S/h|0,$=P[S],G=$>=0?U($,S)?"v":"h":"",z=A=>{let X=U(S,A)?"v":"h";return G!==""&&G!==X?24:0};w+1<h&&f[w][C]&&wt(S,C*h+w+1,z(C*h+w+1)),w-1>=0&&f[w-1][C]&&wt(S,C*h+w-1,z(C*h+w-1)),C+1<l&&M[w][C]&&wt(S,(C+1)*h+w,z((C+1)*h+w)),C-1>=0&&M[w][C-1]&&wt(S,(C-1)*h+w,z((C-1)*h+w));}if(b[F]===v)return null;let Dt=[];for(let S=F;S!==-1;S=P[S])Dt.push({x:s[S%h],y:o[S/h|0]});Dt.reverse();let ot=[];for(let S of Dt){let w=ot.length;if(w>=2){let C=ot[w-2],$=ot[w-1];if(Math.abs(C.y-$.y)<1e-6&&Math.abs($.y-S.y)<1e-6||Math.abs(C.x-$.x)<1e-6&&Math.abs($.x-S.x)<1e-6){ot[w-1]=S;continue}}ot.push(S);}return ot.slice(1)}generateCurvePoints(t){if(t.length<2)return t;let e=[],i=20,n=t[0],r=n;e.push(n);for(let s=1;s<t.length;s++){let o=t[s],h=this.computeCurveControlPoint(r,o);for(let l=1;l<=i;l++){let d=l/i,u=(1-d)*(1-d)*r.x+2*(1-d)*d*h.x+d*d*o.x,c=(1-d)*(1-d)*r.y+2*(1-d)*d*h.y+d*d*o.y;e.push({x:u,y:c});}r=o;}return e}computeCurveControlPoint(t,e){let i=e.x-t.x,n=e.y-t.y,r=Math.sqrt(i*i+n*n);if(r<1)return {x:t.x,y:t.y};let s=(t.x+e.x)/2,o=(t.y+e.y)/2,h=-n/r,l=i/r,d=Math.min(r*.2,30);return {x:s+h*d,y:o+l*d}}getDisplayLines(t,e,i,n,r,s){let o=n*1.3,h=Math.max(1,Math.floor(s/o)),l=`${e.id}\0${i}\0${n}\0${r}x${s}\0${h}`,d=this.textLayoutCache.get(l);if(d)return d;let u=i.split(`
2
+ `),c=[];for(let p of u){let y=this.wrapLine(t,p,r);for(let f of y)c.push(f);}let g=c.slice(0,h);return c.length>h&&g.length>0&&(g[g.length-1]=this.truncateLine(t,g[g.length-1],r)),this.textLayoutCache.size>=a.TEXT_CACHE_LIMIT&&this.textLayoutCache.clear(),this.textLayoutCache.set(l,g),g}drawShapeText(t,e){let i=e.text||"";if(!i)return;let n=e.fontSize||16;t.font=`${n}px sans-serif`,t.fillStyle=e.textColor||"#1f2937";let r=this.getTextBounds(e),s=n*1.3,o=this.getDisplayLines(t,e,i,n,r.width,r.height),l=-(o.length*s)/2+s/2;t.textAlign="center",t.textBaseline="middle",o.forEach((d,u)=>{let c=l+u*s;t.fillText(d,0,c);});}getTextBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return {width:t.width*.85,height:t.height*.85};case "circle":return {width:t.radius*2*.85,height:t.radius*2*.85};default:return {width:100,height:40}}}wrapLine(t,e,i){if(!e)return [""];let n=[],r="";for(let s of e){let o=r+s;t.measureText(o).width>i&&r?(n.push(r),r=s):r=o;}return r&&n.push(r),n}truncateLine(t,e,i){if(!e)return "...";let n="...",r=e;for(;r.length>0&&t.measureText(r+n).width>i;)r=r.slice(0,-1);return r+n}getBindingPoint(t,e){if(e.isPrecise&&e.normalizedAnchor){let i=this.getShapePageBounds(t),n={x:i.x+i.width*e.normalizedAnchor.x,y:i.y+i.height*e.normalizedAnchor.y},r={x:t.x,y:t.y};return this.nearestPointOnShapeOutline(t,r,n)}if(e.handle){let i=this.getShapeBounds(t);switch(e.handle){case "top":return {x:t.x,y:t.y+i.y};case "bottom":return {x:t.x,y:t.y+i.y+i.height};case "left":return {x:t.x+i.x,y:t.y};case "right":return {x:t.x+i.x+i.width,y:t.y}}}return {x:t.x,y:t.y}}getDockNormal(t,e,i){if(!e||e.size===0)return;let n=null,r=1/0,s=.5;if(e.forEach((d,u)=>{if(u===i)return;let c=this.getShapePageBounds(d);if(t.x>=c.x-s&&t.x<=c.x+c.width+s&&t.y>=c.y-s&&t.y<=c.y+c.height+s){let g=(t.x-d.x)**2+(t.y-d.y)**2;g<r&&(r=g,n=d);}}),!n)return;let o=n,h=t.x-o.x,l=t.y-o.y;return Math.abs(l)>Math.abs(h)?{x:0,y:l<0?-1:1}:{x:h<0?-1:1,y:0}}getShapePageBounds(t){let e=this.getShapeBounds(t);return {x:t.x+e.x,y:t.y+e.y,width:e.width,height:e.height}}clampToShapeOutline(t,e,i,n){if(!e||e.size===0)return t;let r=null,s=1/0;if(e.forEach((h,l)=>{if(l===i)return;let d=this.getShapePageBounds(h);if(t.x>d.x&&t.x<d.x+d.width&&t.y>d.y&&t.y<d.y+d.height){let u=(h.x-n.x)**2+(h.y-n.y)**2;u<s&&(s=u,r=h);}}),!r)return t;let o=r;return this.nearestPointOnShapeOutline(o,{x:o.x,y:o.y},t)}nearestPointOnShapeOutline(t,e,i){let n=i.x-e.x,r=i.y-e.y,s=Math.hypot(n,r);if(s<1e-6)return {x:e.x,y:e.y};let o=n/s,h=r/s,l=Math.max(1e4,s*2),d={x:e.x+o*l,y:e.y+h*l},u=this.intersectShapeOutlineWithSegment(t,e,d);if(u.length===0)return i;let c=u[0],g=(c.x-e.x)**2+(c.y-e.y)**2;for(let p=1;p<u.length;p++){let y=(u[p].x-e.x)**2+(u[p].y-e.y)**2;y<g&&(g=y,c=u[p]);}return c}intersectShapeOutlineWithSegment(t,e,i){let n={x:e.x-t.x,y:e.y-t.y},r={x:i.x-t.x,y:i.y-t.y};return this.intersectLocalShapeOutlineWithSegment(t,n,r).map(o=>({x:o.x+t.x,y:o.y+t.y}))}intersectLocalShapeOutlineWithSegment(t,e,i){switch(t.type){case "rectangle":case "rounded-rectangle":{let n=t.width,r=t.height,s={x:-n/2,y:-r/2,width:n,height:r};return this.intersectSegmentRect(e,i,s)}case "ellipse":case "diamond":case "triangle":{let n=t.width,r=t.height,s={x:-n/2,y:-r/2,width:n,height:r};return this.intersectSegmentRect(e,i,s)}case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":{let n=t.width,r=t.height,s={x:-n/2,y:-r/2,width:n,height:r};return this.intersectSegmentRect(e,i,s)}case "circle":{let n=t.radius;return this.intersectSegmentCircle(e,i,{x:0,y:0},n)}default:return []}}intersectSegmentRect(t,e,i){let n=i.x,r=i.y,s=i.width,o=i.height,h=[[{x:n,y:r},{x:n+s,y:r}],[{x:n+s,y:r},{x:n+s,y:r+o}],[{x:n+s,y:r+o},{x:n,y:r+o}],[{x:n,y:r+o},{x:n,y:r}]],l=[];for(let[d,u]of h){let c=this.segmentIntersection(t,e,d,u);c&&l.push(c);}return l}segmentIntersection(t,e,i,n){let r=t.x,s=t.y,o=e.x,h=e.y,l=i.x,d=i.y,u=n.x,c=n.y,g=(r-o)*(d-c)-(s-h)*(l-u);if(Math.abs(g)<1e-9)return null;let p=((r-l)*(d-c)-(s-d)*(l-u))/g,y=-((r-o)*(s-d)-(s-h)*(r-l))/g;return p<0||p>1||y<0||y>1?null:{x:r+p*(o-r),y:s+p*(h-s)}}intersectSegmentCircle(t,e,i,n){let r=e.x-t.x,s=e.y-t.y,o=t.x-i.x,h=t.y-i.y,l=r*r+s*s,d=2*(o*r+h*s),u=o*o+h*h-n*n,c=d*d-4*l*u;if(c<0)return [];c=Math.sqrt(c);let g=(-d-c)/(2*l),p=(-d+c)/(2*l),y=[];return g>=0&&g<=1&&y.push({x:t.x+g*r,y:t.y+g*s}),p>=0&&p<=1&&Math.abs(p-g)>1e-6&&y.push({x:t.x+p*r,y:t.y+p*s}),y}drawArrowHead(t,e,i){let n=Math.atan2(i.y-e.y,i.x-e.x),r=12;t.beginPath(),t.moveTo(i.x,i.y),t.lineTo(i.x-r*Math.cos(n-Math.PI/6),i.y-r*Math.sin(n-Math.PI/6)),t.moveTo(i.x,i.y),t.lineTo(i.x-r*Math.cos(n+Math.PI/6),i.y-r*Math.sin(n+Math.PI/6)),t.stroke();}drawInheritanceHead(t,e,i){let n=Math.atan2(i.y-e.y,i.x-e.x),r=14,s=i.x,o=i.y,h=i.x-r*Math.cos(n),l=i.y-r*Math.sin(n),d=h+r*.5*Math.cos(n-Math.PI/2),u=l+r*.5*Math.sin(n-Math.PI/2),c=h+r*.5*Math.cos(n+Math.PI/2),g=l+r*.5*Math.sin(n+Math.PI/2);t.save(),t.fillStyle="#ffffff",t.beginPath(),t.moveTo(s,o),t.lineTo(d,u),t.lineTo(c,g),t.closePath(),t.fill(),t.stroke(),t.restore();}drawDiamondHead(t,e,i,n){let r=Math.atan2(i.y-e.y,i.x-e.x),s=14,o=i.x,h=i.y,l=i.x-s*.5*Math.cos(r),d=i.y-s*.5*Math.sin(r),u=i.x-s*Math.cos(r),c=i.y-s*Math.sin(r),g=l+s*.4*Math.cos(r-Math.PI/2),p=d+s*.4*Math.sin(r-Math.PI/2),y=l+s*.4*Math.cos(r+Math.PI/2),f=d+s*.4*Math.sin(r+Math.PI/2);t.save(),t.fillStyle=n?"#1f2937":"#ffffff",t.beginPath(),t.moveTo(o,h),t.lineTo(g,p),t.lineTo(u,c),t.lineTo(y,f),t.closePath(),t.fill(),t.stroke(),t.restore();}drawArrowHeads(t,e,i){if(i!=="none"){if(i==="start"||i==="both"){let n=e[0],r=e[1];this.drawArrowHead(t,r,n);}if(i==="end"||i==="both"){let n=e.length,r=e[n-2],s=e[n-1];this.drawArrowHead(t,r,s);}if(i==="inheritance"){let n=e.length,r=e[n-2],s=e[n-1];this.drawInheritanceHead(t,r,s);}if(i==="aggregation"){let n=e[0],r=e[1];this.drawDiamondHead(t,r,n,false);}if(i==="composition"){let n=e[0],r=e[1];this.drawDiamondHead(t,r,n,true);}}}drawText(t,e){if(!e.text)return;let i=e.fontSize;t.font=`${i}px sans-serif`,t.textAlign="center",t.textBaseline="middle";let n=e.width,r=e.height,s=i*1.3,o=this.getDisplayLines(t,e,e.text,i,n,r),h=o.length*s,l=-h/2+s/2;if(e.highlightColor&&e.highlightColor!=="transparent"){t.fillStyle=e.highlightColor;let d=i*.15;t.beginPath(),t.roundRect(-n/2-d,-h/2-d,n+d*2,h+d*2,4),t.fill();}t.fillStyle=e.textColor||"#1f2937",o.forEach((d,u)=>{let c=l+u*s;t.fillText(d,0,c);});}drawFreehand(t,e){if(e.points.length<2)return;let i=e.points.map(n=>({x:n.x-e.x,y:n.y-e.y}));t.beginPath(),t.moveTo(i[0].x,i[0].y);for(let n=1;n<i.length-1;n++){let r=(i[n].x+i[n+1].x)/2,s=(i[n].y+i[n+1].y)/2;t.quadraticCurveTo(i[n].x,i[n].y,r,s);}t.lineTo(i[i.length-1].x,i[i.length-1].y),t.stroke();}drawSelectionOutline(t,e,i){let n=this.getShapeBounds(e);t.strokeStyle=I.selection.outline,t.lineWidth=1/i,t.setLineDash([]),t.save(),t.shadowColor=I.selection.shadow,t.shadowBlur=8,t.shadowOffsetX=0,t.shadowOffsetY=0,t.beginPath(),t.roundRect(n.x-2,n.y-2,n.width+4,n.height+4,4),t.stroke(),t.restore(),t.fillStyle=I.selection.outlineFill,t.beginPath(),t.roundRect(n.x-2,n.y-2,n.width+4,n.height+4,4),t.fill();}drawSelectionHandles(t,e,i){let n=8/i;if((e.type==="line"||e.type==="arrow"||e.type==="draw")&&e.points&&e.points.length>=2){let s=e.points.map(u=>({x:u.x-e.x,y:u.y-e.y})),o=s[0],h=s[s.length-1];t.fillStyle=I.selection.handleFill,t.strokeStyle=I.selection.handleStroke,t.lineWidth=2/i,t.setLineDash([]),[o,h].forEach(u=>{t.beginPath(),t.arc(u.x,u.y,n/2,0,Math.PI*2),t.fill(),t.stroke();});let l=(o.x+h.x)/2,d=(o.y+h.y)/2;t.beginPath(),t.arc(l,d,7/i,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.5/i,t.stroke(),t.beginPath(),t.arc(l,d,3/i,0,Math.PI*2),t.fillStyle=I.genDot,t.fill();}else {let s=this.getShapeBounds(e),o=n,h=[{x:s.x,y:s.y},{x:s.x+s.width,y:s.y},{x:s.x+s.width,y:s.y+s.height},{x:s.x,y:s.y+s.height}];t.fillStyle=I.selection.handleFill,t.strokeStyle=I.selection.handleStroke,t.lineWidth=2/i,t.setLineDash([]),h.forEach(p=>{t.beginPath(),t.roundRect(p.x-o/2,p.y-o/2,o,o,2),t.fill(),t.stroke();});let l=9/i;[{x:s.x+s.width/2,y:s.y},{x:s.x+s.width,y:s.y+s.height/2},{x:s.x+s.width/2,y:s.y+s.height},{x:s.x,y:s.y+s.height/2}].forEach(p=>{t.beginPath(),t.arc(p.x,p.y,l,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.5/i,t.stroke(),t.beginPath(),t.arc(p.x,p.y,l*.45,0,Math.PI*2),t.fillStyle=I.primary,t.fill();});let u=26/i,c=s.x+s.width/2,g=s.y-u;t.strokeStyle="#94a3b8",t.lineWidth=1.5/i,t.setLineDash([]),t.beginPath(),t.moveTo(c,s.y),t.lineTo(c,g),t.stroke(),t.beginPath(),t.arc(c,g,8/i,0,Math.PI*2),t.fillStyle=I.selection.handleFill,t.fill(),t.strokeStyle=I.primary,t.lineWidth=1.6/i,t.stroke(),this.drawRotateIcon(t,c,g,i);}}drawRotateIcon(t,e,i,n){let r=8/n;t.save(),t.translate(e,i),t.strokeStyle=I.primary,t.lineWidth=1.8/n,t.lineCap="round",t.beginPath(),t.arc(0,0,r*.5,Math.PI*.18,Math.PI*1.6,false),t.stroke();let s=Math.PI*.18,o=Math.cos(s)*r*.5,h=Math.sin(s)*r*.5,l=1;t.beginPath(),t.moveTo(o,h),t.lineTo(o-Math.cos(s)*r*.26+l*Math.sin(s)*r*.16,h-Math.sin(s)*r*.26-l*Math.cos(s)*r*.16),t.moveTo(o,h),t.lineTo(o-Math.cos(s)*r*.26-l*Math.sin(s)*r*.16,h-Math.sin(s)*r*.26+l*Math.cos(s)*r*.16),t.stroke(),t.restore();}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:-t.width/2,y:-t.height/2,width:t.width,height:t.height};case "circle":return {x:-t.radius,y:-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":case "draw":if(t.points.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,r=-1/0;return t.points.forEach(s=>{e=Math.min(e,s.x-t.x),i=Math.min(i,s.y-t.y),n=Math.max(n,s.x-t.x),r=Math.max(r,s.y-t.y);}),{x:e,y:i,width:n-e,height:r-i};case "text":{let s=t;return {x:-s.width/2,y:-s.height/2,width:s.width,height:s.height}}default:return {x:0,y:0,width:0,height:0}}}};var rt={create(a=0,t=0){return {x:a,y:t}},add(a,t){return {x:a.x+t.x,y:a.y+t.y}},subtract(a,t){return {x:a.x-t.x,y:a.y-t.y}},multiply(a,t){return {x:a.x*t,y:a.y*t}},divide(a,t){return {x:a.x/t,y:a.y/t}},dot(a,t){return a.x*t.x+a.y*t.y},length(a){return Math.sqrt(a.x*a.x+a.y*a.y)},normalize(a){let t=rt.length(a);return t===0?{x:0,y:0}:{x:a.x/t,y:a.y/t}},distance(a,t){return rt.length(rt.subtract(a,t))},rotate(a,t){let e=Math.cos(t),i=Math.sin(t);return {x:a.x*e-a.y*i,y:a.x*i+a.y*e}},clone(a){return {x:a.x,y:a.y}},equals(a,t){return a.x===t.x&&a.y===t.y}};function J(a,t,e,i=8){let n=[];if(e==="horizontal"){let r=Math.min(a.x,t.x),s=Math.max(a.x+a.width,t.x+t.width),o=Math.abs(a.y-t.y)<=i,h=Math.abs(a.y+a.height-(t.y+t.height))<=i,l=Math.abs(a.y+a.height/2-(t.y+t.height/2))<=i;o&&n.push({type:"horizontal",position:(a.y+t.y)/2,start:r,end:s}),h&&n.push({type:"horizontal",position:(a.y+a.height+t.y+t.height)/2,start:r,end:s}),l&&!(o&&h)&&n.push({type:"horizontal",position:(a.y+a.height/2+t.y+t.height/2)/2,start:r,end:s});}else {let r=Math.min(a.y,t.y),s=Math.max(a.y+a.height,t.y+t.height),o=Math.abs(a.x-t.x)<=i,h=Math.abs(a.x+a.width-(t.x+t.width))<=i,l=Math.abs(a.x+a.width/2-(t.x+t.width/2))<=i;o&&n.push({type:"vertical",position:(a.x+t.x)/2,start:r,end:s}),h&&n.push({type:"vertical",position:(a.x+a.width+t.x+t.width)/2,start:r,end:s}),l&&!(o&&h)&&n.push({type:"vertical",position:(a.x+a.width/2+t.x+t.width/2)/2,start:r,end:s});}return n}var ct=class a extends H{type="select";state="idle";translatingState=null;resizingState=null;generatingState=null;hoverGenPoint=null;rotatingState=null;draggingArrowId=null;draggingTerminal=null;pendingHistoryCommit=false;brushStart={x:0,y:0};brushShiftKey=false;defaultGenType(t){if(t){let e=this.context.getShapes().find(i=>i.id===t);if(e&&It(e.type))return e.type}return "rectangle"}genPreviewOf(t,e){return {from:t.point,to:e,type:this.defaultGenType(t.sourceShapeId)}}genContext(t,e){return {from:t.point,to:e,sourceShapeId:t.sourceShapeId,edge:t.edge}}onPointerDown(t,e){let i=this.context.getShapes(),n=this.context.getSelectedIds(),r=this.hitTestArrowTerminal(t,i);if(r&&n.includes(r.shapeId)){this.state="dragging-terminal",this.draggingArrowId=r.shapeId,this.draggingTerminal=r.terminal,this.pendingHistoryCommit=true,this.context.updateArrowBinding(r.shapeId,r.terminal,null);return}let s=this.hitGenPoint(t,i,n);if(s){this.state="generating",this.generatingState={source:s,startPoint:t,hasMoved:false},this.pendingHistoryCommit=true,this.context.setGenerationPreview(this.genPreviewOf(s,this.genPreviewTarget(s,t,false)));return}let o=this.hitTest(t,i,n);if(o.handle==="rotation"){this.state="rotating",this.pendingHistoryCommit=true;let h=o.shape;this.rotatingState={shapeId:h.id,center:{x:h.x,y:h.y},startAngle:Math.atan2(t.y-h.y,t.x-h.x),startRotation:h.rotation};return}if(o.handle&&o.shape&&o.shape.type!=="mind-map"){this.state="resizing",this.resizingState={startPoint:t,startShape:o.shape,handle:o.handle},this.pendingHistoryCommit=true;return}if(o.shape){let h=o.shape,l=h.type==="line"||h.type==="arrow"||h.type==="draw",d=n.includes(h.id);if(l&&!d){this.context.selectShape(h.id,e.shiftKey);return}this.state="translating",this.pendingHistoryCommit=true,d||this.context.selectShape(h.id,e.shiftKey);let u=this.context.getSelectedIds(),c=new Map,g=new Map,p=new Map;u.forEach(y=>{let f=i.find(M=>M.id===y);f&&(c.set(y,{x:f.x,y:f.y}),g.set(y,f.rotation),p.set(y,this.getShapeWorldBounds(f)));}),this.translatingState={startPoint:t,startPositions:c,startRotation:g,startBounds:p};}else this.state="brushing",this.brushStart=t,this.brushShiftKey=e.shiftKey,e.shiftKey||this.context.selectShape("",false);}onPointerMove(t,e){let i=this.context.getShapes();if(this.state==="translating"&&this.translatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleTranslating(t,e);else if(this.state==="generating"&&this.generatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleGenerating(t,i);else if(this.state==="rotating"&&this.rotatingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleRotating(t,e);else if(this.state==="resizing"&&this.resizingState)this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false),this.handleResizing(t);else if(this.state==="dragging-terminal"&&this.draggingArrowId&&this.draggingTerminal){this.pendingHistoryCommit&&(this.context.commitHistory(),this.pendingHistoryCommit=false);let n=i.find(r=>r.id===this.draggingArrowId);if(n){let r=this.draggingTerminal==="start"?t:n.points[n.points.length-1],s=this.draggingTerminal==="start"?n.points[0]:t,o=this.computeSnapGuidesForArrow(r,s,t,n,i);this.context.setSnapGuides(o);let h=t;if(o.length>0){let u=o.filter(g=>g.type==="horizontal"),c=o.filter(g=>g.type==="vertical");if(u.length>0){let g=u[0].position,p=Math.abs(t.y-g);for(let y of u){let f=Math.abs(t.y-y.position);f<p&&(p=f,g=y.position);}h={...h,y:g};}else if(c.length>0){let g=c[0].position,p=Math.abs(t.x-g);for(let y of c){let f=Math.abs(t.x-y.position);f<p&&(p=f,g=y.position);}h={...h,x:g};}}let l=this.draggingTerminal==="start"?0:n.points.length-1,d=[...n.points];d[l]=h,this.context.updateShape(this.draggingArrowId,{points:d});}}else if(this.state==="brushing")this.handleBrushing(t);else {let n=this.context.getSelectedIds(),r=this.hitGenPoint(t,i,n);r?(this.hoverGenPoint=r,this.context.setGenerationPreview(this.genPreviewOf(r,this.genPreviewTarget(r,t,false)))):this.hoverGenPoint&&(this.hoverGenPoint=null,this.context.setGenerationPreview(null));}}onPointerUp(t,e){if(this.state==="dragging-terminal"&&this.draggingArrowId&&this.draggingTerminal){let i=this.context.getShapes(),n=this.findBindingNearPoint(t,i,this.draggingArrowId);n&&this.context.updateArrowBinding(this.draggingArrowId,this.draggingTerminal,n.toShapeId,n.binding);}if(this.state==="generating"&&this.generatingState){let i=this.generatingState,n=this.context.getShapes(),r=i.source,s=this.findBindingNearPoint(t,n,r.sourceShapeId);if(s)this.context.connectToExisting(this.genContext(r,t),s.toShapeId,s.binding);else if(!i.hasMoved)this.context.createGeneratedConnection(this.genContext(r,this.genPreviewTarget(r,r.point,false)),{type:this.defaultGenType(r.sourceShapeId)});else {let o=this.context.createFloatingLine(this.genContext(r,t));this.context.openGenerationMenu({context:this.genContext(r,t),existingArrowId:o,defaultShapeType:this.defaultGenType(r.sourceShapeId)});}this.generatingState=null,this.context.setGenerationPreview(null);}this.state==="brushing"&&this.context.setBrushRect(null),this.context.setConnectingTarget(null),this.hoverGenPoint=null,this.pendingHistoryCommit=false,this.state="idle",this.draggingArrowId=null,this.draggingTerminal=null,this.translatingState=null,this.resizingState=null,this.rotatingState=null,this.context.setSnapGuides([]);}onKeyDown(t){let e=t.target;if(!(e&&(e.tagName==="INPUT"||e.tagName==="TEXTAREA"||e.isContentEditable))){if(t.key==="Delete"||t.key==="Backspace"){let i=this.context.getSelectedIds();i.length>0&&(this.context.commitHistory(),i.forEach(n=>{this.context.deleteShape(n);}));}t.key==="Escape"&&(this.context.selectShape("",false),this.context.setSnapGuides([]),this.state="idle"),(t.key==="+"||t.key==="=")&&t.shiftKey&&(this.context.commitHistory(),this.handleRotation(15)),t.key==="-"&&t.shiftKey&&(this.context.commitHistory(),this.handleRotation(-15)),t.key==="ArrowUp"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(0,-5)),t.key==="ArrowDown"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(0,5)),t.key==="ArrowLeft"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(-5,0)),t.key==="ArrowRight"&&(t.preventDefault(),this.context.commitHistory(),this.handleNudge(5,0));}}onKeyUp(t){}getCursor(t){switch(this.state){case "translating":return "grabbing";case "generating":return "crosshair";case "rotating":return "grabbing";case "resizing":return this.resizingState?this.getHandleCursor(this.resizingState.handle,this.resizingState.startShape):"default";case "dragging-terminal":return "crosshair";case "brushing":return "crosshair"}let e=this.context.getShapes(),i=this.context.getSelectedIds();if(this.context.getMindMapCursorHitAtPoint(t))return "pointer";if(this.hitGenPoint(t,e,i))return "crosshair";if(this.hitTestArrowTerminal(t,e)&&i.includes(this.hitTestArrowTerminal(t,e).shapeId))return "move";let n=this.hitTest(t,e,i);return n.handle==="rotation"?"grab":n.handle?this.getHandleCursor(n.handle,n.shape):n.shape?"move":null}getHandleCursor(t,e){let n={e:0,se:45,s:90,sw:135,w:180,nw:225,n:270,ne:315}[t];if(n===void 0)return "grab";let r=((n+e.rotation*180/Math.PI)%360+360)%360,s=Math.round(r/45)%4;return ["ew-resize","nwse-resize","ns-resize","nesw-resize"][s]}static ALIGN_SNAP_THRESHOLD=8;handleTranslating(t,e){if(!this.translatingState)return;let i=rt.subtract(t,this.translatingState.startPoint),n={...i};e.shiftKey&&(Math.abs(i.x)>Math.abs(i.y)?n.y=0:n.x=0);let r=this.context.getShapes(),s=this.context.getSelectedIds(),o=new Set(s),h=[],l=[];if(this.translatingState.startBounds.forEach(d=>{l.push({x:d.x+n.x,y:d.y+n.y,width:d.width,height:d.height});}),!e.shiftKey&&l.length>0){let d=[];for(let g of r)o.has(g.id)||g.type==="line"||g.type==="arrow"||g.type==="draw"||d.push(this.getShapeWorldBounds(g));let u=[],c=[];for(let g of l){let p=[g.y,g.y+g.height/2,g.y+g.height],y=[g.x,g.x+g.width/2,g.x+g.width];for(let f of d){let M=[f.y,f.y+f.height/2,f.y+f.height];for(let v of p)for(let b of M){let P=b-v;Math.abs(P)<=a.ALIGN_SNAP_THRESHOLD&&u.push(P);}let x=[f.x,f.x+f.width/2,f.x+f.width];for(let v of y)for(let b of x){let P=b-v;Math.abs(P)<=a.ALIGN_SNAP_THRESHOLD&&c.push(P);}}}if(u.length>0){let g=u[0];for(let p of u)Math.abs(p)<Math.abs(g)&&(g=p);n.y+=g;}if(c.length>0){let g=c[0];for(let p of c)Math.abs(p)<Math.abs(g)&&(g=p);n.x+=g;}this.translatingState.startBounds.forEach(g=>{let p={x:g.x+n.x,y:g.y+n.y,width:g.width,height:g.height};for(let y of d)h.push(...J(p,y,"horizontal",1)),h.push(...J(p,y,"vertical",1));});}this.translatingState.startPositions.forEach((d,u)=>{this.context.updateShape(u,{x:d.x+n.x,y:d.y+n.y});}),this.context.setSnapGuides(this.mergeGuides(h));}handleResizing(t){if(!this.resizingState)return;let e=this.resizingState.startShape,i=this.resizingState.handle,n=this.resizingState.startPoint;if(!i||i==="rotation")return;let s={nw:[-1,-1],n:[0,-1],ne:[1,-1],w:[-1,0],e:[1,0],sw:[-1,1],s:[0,1],se:[1,1]}[i];if(!s)return;let[o,h]=s,l=rt.subtract(t,n),d=[];for(let P of this.context.getShapes())P.id!==e.id&&(P.type==="line"||P.type==="arrow"||P.type==="draw"||d.push(this.getShapeWorldBounds(P)));let u=20,c=this.getShapeWorldBounds(e),g=c.x,p=c.y,y=c.x+c.width,f=c.y+c.height;o===1?y=Math.max(g+u,y+l.x):o===-1&&(g=Math.min(y-u,g+l.x)),h===1?f=Math.max(p+u,f+l.y):h===-1&&(p=Math.min(f-u,p+l.y));let M=(P,T)=>{let E=null;for(let U of T){let Y=U-P;Math.abs(Y)<=a.ALIGN_SNAP_THRESHOLD&&(E===null||Math.abs(Y)<Math.abs(E))&&(E=Y);}return E};if(o!==0&&d.length>0){let P=[];for(let E of d)P.push(E.x,E.x+E.width/2,E.x+E.width);let T=M(o===1?y:g,P);T!==null&&(o===1?y+=T:g+=T);}if(h!==0&&d.length>0){let P=[];for(let E of d)P.push(E.y,E.y+E.height/2,E.y+E.height);let T=M(h===1?f:p,P);T!==null&&(h===1?f+=T:p+=T);}let x={x:g,y:p,width:y-g,height:f-p},v=[];for(let P of d)o!==0&&v.push(...J(x,P,"vertical",1)),h!==0&&v.push(...J(x,P,"horizontal",1));this.context.setSnapGuides(this.mergeGuides(v));let b={};if(e.type==="circle"){let P=Math.max(10,Math.max(o!==0?x.width/2:0,h!==0?x.height/2:0));if(b.radius=P,o!==0){let T=o===1?c.x:c.x+c.width;b.x=o===1?T+P:T-P;}if(h!==0){let T=h===1?c.y:c.y+c.height;b.y=h===1?T+P:T-P;}}else "width"in e&&o!==0&&(b.width=x.width,b.x=x.x+x.width/2),"height"in e&&h!==0&&(b.height=x.height,b.y=x.y+x.height/2);Object.keys(b).length>0&&this.context.updateShape(e.id,b);}mergeGuides(t){let e=new Map;for(let i of t){let n=`${i.type}\0${Math.round(i.position*2)/2}`,r=e.get(n);r?(r.start=Math.min(r.start,i.start),r.end=Math.max(r.end,i.end)):e.set(n,{...i});}return [...e.values()]}handleRotation(t){let e=this.context.getSelectedIds(),i=this.context.getShapes();e.forEach(n=>{let r=i.find(s=>s.id===n);r&&this.context.updateShape(n,{rotation:r.rotation+t*Math.PI/180});});}handleNudge(t,e){let i=this.context.getSelectedIds(),n=this.context.getShapes();i.forEach(r=>{let s=n.find(o=>o.id===r);s&&this.context.updateShape(r,{x:s.x+t,y:s.y+e});});}handleBrushing(t){let e=Math.min(this.brushStart.x,t.x),i=Math.min(this.brushStart.y,t.y),n=Math.abs(t.x-this.brushStart.x),r=Math.abs(t.y-this.brushStart.y);this.context.setBrushRect({x:e,y:i,width:n,height:r});let s=this.context.getShapes(),o=[];for(let h of s){let l=this.getShapeWorldBounds(h);this.rectsIntersect({x:e,y:i,width:n,height:r},l)&&o.push(h.id);}if(this.brushShiftKey){let h=this.context.getSelectedIds(),l=new Set([...h,...o]);this.context.selectShapes([...l]);}else this.context.selectShapes(o);}getShapeWorldBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":case "draw":{if(!t.points||t.points.length===0)return {x:t.x,y:t.y,width:0,height:0};let e=1/0,i=1/0,n=-1/0,r=-1/0;return t.points.forEach(s=>{e=Math.min(e,s.x),i=Math.min(i,s.y),n=Math.max(n,s.x),r=Math.max(r,s.y);}),{x:e,y:i,width:n-e,height:r-i}}case "text":{let e=t;return {x:t.x-e.width/2,y:t.y-e.height/2,width:e.width,height:e.height}}default:{let e=t;return {x:e.x,y:e.y,width:0,height:0}}}}rectsIntersect(t,e){return t.x<e.x+e.width&&t.x+t.width>e.x&&t.y<e.y+e.height&&t.y+t.height>e.y}hitTest(t,e,i){for(let n=e.length-1;n>=0;n--){let r=e[n];if(i.includes(r.id)){let s=this.getHitHandle(t,r);if(s)return {shape:r,handle:s}}if(this.isPointInShape(t,r))return {shape:r,handle:null}}return {shape:null,handle:null}}getHitHandle(t,e){if(e.type==="mind-map")return null;let i=14,n=this.getShapeBounds(e),r=Math.cos(-e.rotation),s=Math.sin(-e.rotation),o=t.x-e.x,h=t.y-e.y,l=o*r-h*s,d=o*s+h*r,u=[{type:"nw",x:n.x,y:n.y},{type:"ne",x:n.x+n.width,y:n.y},{type:"se",x:n.x+n.width,y:n.y+n.height},{type:"sw",x:n.x,y:n.y+n.height},{type:"rotation",x:n.x+n.width/2,y:n.y-26}];for(let c of u)if(Math.abs(l-c.x)<i&&Math.abs(d-c.y)<i)return c.type;return null}static GEN_HIT_THRESHOLD=14;static CLICK_MOVE_THRESHOLD=6;computeGenPoints(t,e){let i=[];for(let n of e){let r=t.find(s=>s.id===n);if(r){if(r.type==="line"||r.type==="arrow"||r.type==="draw"){if(r.points&&r.points.length>=2){let s=this.getShapeWorldBounds(r);i.push({point:{x:s.x+s.width/2,y:s.y+s.height/2},sourceShapeId:r.id});}}else if(r.type==="rectangle"||r.type==="rounded-rectangle"||r.type==="ellipse"||r.type==="diamond"||r.type==="triangle"||r.type==="hexagon"||r.type==="parallelogram"||r.type==="trapezoid"||r.type==="pentagon"||r.type==="octagon"||r.type==="star"||r.type==="uml-class"||r.type==="uml-interface"||r.type==="circle"){let s=this.getShapeBounds(r),o={x:r.x,y:r.y};i.push({point:{x:o.x+s.x+s.width/2,y:o.y+s.y},edge:"n",sourceShapeId:r.id}),i.push({point:{x:o.x+s.x+s.width,y:o.y+s.y+s.height/2},edge:"e",sourceShapeId:r.id}),i.push({point:{x:o.x+s.x+s.width/2,y:o.y+s.y+s.height},edge:"s",sourceShapeId:r.id}),i.push({point:{x:o.x+s.x,y:o.y+s.y+s.height/2},edge:"w",sourceShapeId:r.id});}}}return i}hitGenPoint(t,e,i){let n=a.GEN_HIT_THRESHOLD,r=null,s=n;for(let o of this.computeGenPoints(e,i)){let h=Math.hypot(o.point.x-t.x,o.point.y-t.y);h<=s&&(s=h,r=o);}return r}genPreviewTarget(t,e,i){if(i)return e;let n=96;if(t.edge)switch(t.edge){case "n":return {x:t.point.x,y:t.point.y-n};case "s":return {x:t.point.x,y:t.point.y+n};case "e":return {x:t.point.x+n,y:t.point.y};case "w":return {x:t.point.x-n,y:t.point.y}}return {x:t.point.x,y:t.point.y-n}}handleGenerating(t,e){if(!this.generatingState)return;let i=this.generatingState,n=i.source;Math.hypot(t.x-i.startPoint.x,t.y-i.startPoint.y)>a.CLICK_MOVE_THRESHOLD&&(i.hasMoved=true);let s=this.findBindingNearPoint(t,e,n.sourceShapeId),o=s?this.bindingPosition(s.toShapeId,s.binding,e):i.hasMoved?t:this.genPreviewTarget(n,t,false);this.context.setConnectingTarget(s?s.toShapeId:null),this.context.setGenerationPreview({from:n.point,to:o,type:s?void 0:this.defaultGenType(n.sourceShapeId)});}handleRotating(t,e){if(!this.rotatingState)return;let i=this.rotatingState,n=Math.atan2(t.y-i.center.y,t.x-i.center.x),r=i.startRotation+(n-i.startAngle);e.shiftKey&&(r=Math.round(r/(Math.PI/12))*(Math.PI/12)),this.context.updateShape(i.shapeId,{rotation:r});}bindingPosition(t,e,i){let n=i.find(s=>s.id===t);if(!n)return {x:0,y:0};let r=this.getShapeWorldBounds(n);if(e.handle)switch(e.handle){case "top":return {x:n.x,y:r.y};case "bottom":return {x:n.x,y:r.y+r.height};case "left":return {x:r.x,y:n.y};case "right":return {x:r.x+r.width,y:n.y}}return e.normalizedAnchor?{x:r.x+r.width*e.normalizedAnchor.x,y:r.y+r.height*e.normalizedAnchor.y}:{x:n.x,y:n.y}}isPointInShape(t,e){let i=t.x-e.x,n=t.y-e.y;switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return Math.abs(i)<=e.width/2&&Math.abs(n)<=e.height/2;case "circle":return i*i+n*n<=e.radius*e.radius;case "hexagon":return this.isPointInHexagon(i,n,e.width,e.height);case "line":case "arrow":case "draw":for(let r=0;r<e.points.length-1;r++){let s=e.points[r],o=e.points[r+1];if(this.pointToLineDistance(t,s,o)<10)return true}return false;case "text":return Math.abs(i)<=50&&Math.abs(n)<=e.fontSize/2;default:return false}}isPointInHexagon(t,e,i,n){let r=Math.abs(t),s=Math.abs(e),o=i/2,h=n/2;return r<=o&&s<=h&&r/o+s/h<=1.5}pointToLineDistance(t,e,i){let n=t.x-e.x,r=t.y-e.y,s=i.x-e.x,o=i.y-e.y,h=n*s+r*o,l=s*s+o*o,d=-1;l!==0&&(d=h/l);let u,c;d<0?(u=e.x,c=e.y):d>1?(u=i.x,c=i.y):(u=e.x+d*s,c=e.y+d*o);let g=t.x-u,p=t.y-c;return Math.sqrt(g*g+p*p)}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":return {x:-t.width/2,y:-t.height/2,width:t.width,height:t.height};case "circle":return {x:-t.radius,y:-t.radius,width:t.radius*2,height:t.radius*2};case "line":case "arrow":case "draw":if(t.points.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,r=-1/0;return t.points.forEach(s=>{e=Math.min(e,s.x-t.x),i=Math.min(i,s.y-t.y),n=Math.max(n,s.x-t.x),r=Math.max(r,s.y-t.y);}),{x:e,y:i,width:n-e,height:r-i};case "text":return {x:-50,y:-t.fontSize/2,width:100,height:t.fontSize};default:return {x:0,y:0,width:0,height:0}}}hitTestArrowTerminal(t,e){for(let n of e){if(n.type!=="arrow")continue;let r=n;if(r.points.length<2)continue;let s=r.points[0],o=r.points[r.points.length-1],h=Math.sqrt(Math.pow(t.x-s.x,2)+Math.pow(t.y-s.y,2)),l=Math.sqrt(Math.pow(t.x-o.x,2)+Math.pow(t.y-o.y,2));if(h<20)return {shapeId:r.id,terminal:"start"};if(l<20)return {shapeId:r.id,terminal:"end"}}return null}findShapeNearPoint(t,e,i){for(let r=e.length-1;r>=0;r--){let s=e[r];if(i&&s.id===i||s.type==="arrow"||s.type==="line"||s.type==="draw")continue;let o;switch(s.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":o=this.pointToRectDistance(t,{x:s.x-s.width/2,y:s.y-s.height/2,width:s.width,height:s.height});break;case "circle":o=Math.sqrt(Math.pow(t.x-s.x,2)+Math.pow(t.y-s.y,2))-s.radius;break;case "hexagon":{let h=s.width/2,l=s.height/2,d=Math.abs(t.x-s.x),u=Math.abs(t.y-s.y);o=d/h+u/l-1;break}default:continue}if(o<=30)return s}return null}pointToRectDistance(t,e){let i=Math.max(e.x,Math.min(t.x,e.x+e.width)),n=Math.max(e.y,Math.min(t.y,e.y+e.height));return Math.sqrt(Math.pow(t.x-i,2)+Math.pow(t.y-n,2))}static SNAP_THRESHOLD=32;static HANDLE_SNAP_DISTANCE=18;static ANCHOR_EPS=.001;computeSnapGuidesForArrow(t,e,i,n,r){let s=this.draggingTerminal==="start"?n.endBinding:n.startBinding,o=s?r.find(p=>p.id===s.toShapeId):null;if(!o)return [];let h=this.findShapeNearPoint(i,r,n.id);if(!h)return [];let l=this.getShapeWorldBounds(o),d=this.getShapeWorldBounds(h),u=e.x-t.x,c=e.y-t.y,g=Math.abs(u)>=Math.abs(c)?"horizontal":"vertical";return J(l,d,g)}findBindingNearPoint(t,e,i){let n;for(let r=e.length-1;r>=0;r--){let s=e[r];if(i&&s.id===i||s.type==="arrow"||s.type==="line"||s.type==="draw")continue;let o=this.getPageBounds(s),h=a.SNAP_THRESHOLD;if(t.x<o.x-h||t.x>o.x+o.width+h||t.y<o.y-h||t.y>o.y+o.height+h)continue;let l={x:s.x,y:s.y},d=[{handle:"top",pos:{x:l.x,y:o.y}},{handle:"bottom",pos:{x:l.x,y:o.y+o.height}},{handle:"left",pos:{x:o.x,y:l.y}},{handle:"right",pos:{x:o.x+o.width,y:l.y}}];for(let c of d){let g=Math.hypot(c.pos.x-t.x,c.pos.y-t.y);g<=a.HANDLE_SNAP_DISTANCE&&(!n||g<n.distance)&&(n={toShapeId:s.id,binding:{toShapeId:s.id,handle:c.handle,isPrecise:false},distance:g});}let u=this.nearestPointOnShapeOutline(s,t);if(u&&u.distance<=a.SNAP_THRESHOLD&&(!n||u.distance<n.distance)){let c=this.computeNormalizedAnchor(o,u.point);n={toShapeId:s.id,binding:{toShapeId:s.id,isPrecise:true,normalizedAnchor:c},distance:u.distance};}}if(n)return {toShapeId:n.toShapeId,binding:n.binding}}getPageBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};default:return {x:t.x-50,y:t.y-50,width:100,height:100}}}computeNormalizedAnchor(t,e){let i=a.ANCHOR_EPS,n=t.width>0?(e.x-t.x)/t.width:.5,r=t.height>0?(e.y-t.y)/t.height:.5;return n=Math.max(i,Math.min(1-i,n)),r=Math.max(i,Math.min(1-i,r)),{x:n,y:r}}nearestPointOnShapeOutline(t,e){let i={x:e.x-t.x,y:e.y-t.y},n=this.nearestLocalPointOnShapeOutline(t,i);if(!n)return null;let r={x:n.point.x+t.x,y:n.point.y+t.y};return {point:r,distance:Math.hypot(r.x-e.x,r.y-e.y)}}nearestLocalPointOnShapeOutline(t,e){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":{let i=t.width,n=t.height;return this.nearestPointOnRectOutlineLocal(e,{x:-i/2,y:-n/2,width:i,height:n})}case "circle":{let i=t.radius;return this.nearestPointOnCircleOutlineLocal(e,{x:0,y:0},i)}default:return null}}nearestPointOnRectOutlineLocal(t,e){let i=[[{x:e.x,y:e.y},{x:e.x+e.width,y:e.y}],[{x:e.x+e.width,y:e.y},{x:e.x+e.width,y:e.y+e.height}],[{x:e.x+e.width,y:e.y+e.height},{x:e.x,y:e.y+e.height}],[{x:e.x,y:e.y+e.height},{x:e.x,y:e.y}]],n=null;for(let[r,s]of i){let o=this.nearestPointOnSegment(t,r,s);(!n||o.distance<n.distance)&&(n=o);}return n}nearestPointOnCircleOutlineLocal(t,e,i){let n=t.x-e.x,r=t.y-e.y,s=Math.hypot(n,r);if(s<1e-9)return {point:{x:e.x+i,y:e.y},distance:i};let o=e.x+n/s*i,h=e.y+r/s*i,l={x:o,y:h};return {point:l,distance:Math.hypot(l.x-t.x,l.y-t.y)}}nearestPointOnSegment(t,e,i){let n=i.x-e.x,r=i.y-e.y,s=n*n+r*r,o=s>0?((t.x-e.x)*n+(t.y-e.y)*r)/s:0;o=Math.max(0,Math.min(1,o));let h=e.x+o*n,l=e.y+o*r,d={x:h,y:l};return {point:d,distance:Math.hypot(d.x-t.x,d.y-t.y)}}};var ut=class a extends H{type="hand";state="idle";startScreenPoint={x:0,y:0};initialCameraPos={x:0,y:0};static DRAG_THRESHOLD=4;onPointerDown(t,e){this.startScreenPoint={x:e.clientX,y:e.clientY};let i=this.context.getCamera();this.initialCameraPos={x:i.x,y:i.y},this.state="pointing";}onPointerMove(t,e){if(this.state!=="idle"){if(this.state==="pointing"){let i=e.clientX-this.startScreenPoint.x,n=e.clientY-this.startScreenPoint.y;if(Math.hypot(i,n)<a.DRAG_THRESHOLD)return;this.state="dragging",this.applyCameraDelta(i,n);return}if(this.state==="dragging"){let i=e.clientX-this.startScreenPoint.x,n=e.clientY-this.startScreenPoint.y;this.applyCameraDelta(i,n);}}}onPointerUp(t,e){if(this.state!=="idle"){if(this.state==="dragging"){let i=this.context.getCamera();this.initialCameraPos={x:i.x,y:i.y},this.startScreenPoint={x:e.clientX,y:e.clientY};}this.state="idle";}}onKeyDown(t){t.key==="Escape"&&this.state!=="idle"&&(this.context.setCameraPosition(this.initialCameraPos.x,this.initialCameraPos.y),this.state="idle");}onKeyUp(t){}getCursor(t){return this.state==="dragging"||this.state==="pointing"?"grabbing":"grab"}applyCameraDelta(t,e){this.context.setCameraPosition(this.initialCameraPos.x+t,this.initialCameraPos.y+e);}};var be={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},gt=class extends H{type="line";isDrawing=false;startPoint={x:0,y:0};currentShape=null;onPointerDown(t,e){this.isDrawing=true,this.startPoint=t,this.currentShape={id:`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:"line",x:t.x,y:t.y,points:[t],rotation:0,style:{...be}},this.context.commitHistory(),this.context.addShape(this.currentShape);}onPointerMove(t,e){!this.isDrawing||!this.currentShape||this.context.updateShape(this.currentShape.id,{points:[this.startPoint,t]});}onPointerUp(t,e){this.isDrawing=false,this.currentShape=null,this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}};var Me={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:4,strokeDash:null},ve={strokeColor:"rgba(255, 235, 59, 0.5)",fillColor:"transparent",strokeWidth:16,strokeDash:null},Pe=4e3,at=class extends H{type;mode;isDrawing=false;points=[];currentShapeId=null;committed=false;fadeTimer=null;constructor(t,e){super(t),this.mode=e,this.type=e==="pen"?"pen":"highlighter";}onPointerDown(t,e){this.isDrawing=true,this.committed=false,this.currentShapeId=null,this.points=[{...t}];}onPointerMove(t,e){if(this.isDrawing)if(this.points.push({...t}),!this.committed&&this.points.length>=2){this.context.commitHistory();let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;this.currentShapeId=i;let n=this.points[0],r=this.mode==="pen"?{...Me}:{...ve},s={id:i,type:"draw",x:n.x,y:n.y,points:this.points.map(o=>({...o})),rotation:0,style:r};this.context.addShape(s),this.committed=true;}else this.committed&&this.currentShapeId&&this.context.updateShape(this.currentShapeId,{points:this.points.map(i=>({...i}))});}onPointerUp(t,e){if(!this.isDrawing||(this.isDrawing=false,!this.committed||!this.currentShapeId))return;let i=this.currentShapeId;this.currentShapeId=null,this.mode==="highlighter"&&(this.fadeTimer=setTimeout(()=>{this.context.deleteShape(i);},Pe));}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}dispose(){this.fadeTimer&&(clearTimeout(this.fadeTimer),this.fadeTimer=null);}};var Te={strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null},pt=class extends H{type="arrow";isDrawing=false;startPoint={x:0,y:0};currentShapeId=null;startBindingInfo=null;onPointerDown(t,e){this.isDrawing=true,this.startPoint=t,this.startBindingInfo=null;let i=this.context.getShapes(),n=this.findShapeBinding(t,i),r=t;n&&(r=this.getBindingPosition(n.toShapeId,n.handle,i),this.startBindingInfo={...n,position:r});let s=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`;this.currentShapeId=s;let o={id:s,type:"arrow",x:r.x,y:r.y,points:[r],rotation:0,style:{...Te},startBinding:n?{toShapeId:n.toShapeId,handle:n.handle}:void 0,connectionType:"straight",arrowHead:"end",dashed:false};this.context.commitHistory(),this.context.addShape(o);}onPointerMove(t,e){if(!this.isDrawing||!this.currentShapeId)return;let i=this.context.getShapes(),n=this.findShapeBinding(t,i),r=t;n&&(r=this.getBindingPosition(n.toShapeId,n.handle,i));let s=this.startBindingInfo?.position||this.startPoint,o=this.computeSnapGuides(s,r,n,i);this.context.setSnapGuides(o),this.context.updateShape(this.currentShapeId,{points:[s,r],endBinding:n?{toShapeId:n.toShapeId,handle:n.handle}:void 0});}onPointerUp(t,e){this.isDrawing=false,this.currentShapeId=null,this.startBindingInfo=null,this.context.setSnapGuides([]),this.context.setActiveTool("select");}onKeyDown(t){}onKeyUp(t){}getCursor(){return "crosshair"}computeSnapGuides(t,e,i,n){let r=this.startBindingInfo?n.find(c=>c.id===this.startBindingInfo.toShapeId):null,s=i?n.find(c=>c.id===i.toShapeId):null;if(!r||!s)return [];let o=this.getShapeBounds(r),h=this.getShapeBounds(s),l=e.x-t.x,d=e.y-t.y,u=Math.abs(l)>=Math.abs(d)?"horizontal":"vertical";return J(o,h,u)}getShapeBounds(t){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};case "circle":return {x:t.x-t.radius,y:t.y-t.radius,width:t.radius*2,height:t.radius*2};case "text":return {x:t.x-t.width/2,y:t.y-t.height/2,width:t.width,height:t.height};default:return {x:t.x-50,y:t.y-20,width:100,height:40}}}findShapeBinding(t,e){for(let n=e.length-1;n>=0;n--){let r=e[n];if(r.type==="arrow"||r.type==="line"||r.type==="draw")continue;let s;switch(r.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "uml-class":case "uml-interface":s=this.pointToRectDistance(t,{x:r.x-r.width/2,y:r.y-r.height/2,width:r.width,height:r.height});break;case "circle":{let o=Math.sqrt(Math.pow(t.x-r.x,2)+Math.pow(t.y-r.y,2));s=Math.abs(o-r.radius);break}case "hexagon":{let o=r.width/2,h=r.height/2,l=Math.abs(t.x-r.x),d=Math.abs(t.y-r.y);s=l/o+d/h-1;break}default:continue}if(s<=40){let o=this.getClosestHandle(t,r);return {toShapeId:r.id,handle:o}}}}pointToRectDistance(t,e){let i=Math.max(e.x,Math.min(t.x,e.x+e.width)),n=Math.max(e.y,Math.min(t.y,e.y+e.height));return Math.sqrt(Math.pow(t.x-i,2)+Math.pow(t.y-n,2))}getClosestHandle(t,e){let i=t.x-e.x,n=t.y-e.y;if(e.type==="circle"||e.type==="hexagon"){let l=Math.atan2(n,i);return l>=-Math.PI/4&&l<Math.PI/4?"right":l>=Math.PI/4&&l<3*Math.PI/4?"bottom":l>=3*Math.PI/4||l<-(3*Math.PI)/4?"left":"top"}let r="width"in e?e.width:100,s="height"in e?e.height:100,o=Math.abs(i)/(r/2),h=Math.abs(n)/(s/2);return o>h?i>0?"right":"left":n>0?"bottom":"top"}getBindingPosition(t,e,i){let n=i.find(r=>r.id===t);if(!n)return {x:0,y:0};switch(n.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":return this.getRectBindingPosition(n,e);case "circle":return this.getCircleBindingPosition(n,e);case "hexagon":return this.getRectBindingPosition(n,e);default:return {x:n.x,y:n.y}}}getRectBindingPosition(t,e){switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}}getCircleBindingPosition(t,e){switch(e){case "top":return {x:t.x,y:t.y-t.radius};case "bottom":return {x:t.x,y:t.y+t.radius};case "left":return {x:t.x-t.radius,y:t.y};case "right":return {x:t.x+t.radius,y:t.y}}}};var Ie={strokeColor:"transparent",fillColor:"transparent",strokeWidth:0,strokeDash:null},$t=class extends H{type="text";onPointerDown(t,e){let i=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,n={id:i,type:"text",x:t.x,y:t.y,rotation:0,style:{...Ie},text:"",fontSize:16,textColor:"#1f2937",width:200,height:24};this.context.commitHistory(),this.context.addShape(n),this.context.enterEditing(i);}onPointerMove(t,e){}onPointerUp(t,e){}onKeyDown(t){}onKeyUp(t){}getCursor(){return "text"}};var mt="#1f2937";function Ut(a){switch(a.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":case "mind-map":case "text":return {x:-(a.width/2),y:-(a.height/2),width:a.width,height:a.height};case "circle":return {x:-a.radius,y:-a.radius,width:a.radius*2,height:a.radius*2};case "line":case "arrow":case "draw":{let t=a.points;if(!t||t.length===0)return {x:0,y:0,width:0,height:0};let e=1/0,i=1/0,n=-1/0,r=-1/0;for(let s of t){let o=s.x-a.x,h=s.y-a.y;e=Math.min(e,o),i=Math.min(i,h),n=Math.max(n,o),r=Math.max(r,h);}return {x:e,y:i,width:n-e,height:r-i}}default:return {x:0,y:0,width:0,height:0}}}function Ce(a){let t=Ut(a),e=Math.cos(a.rotation),i=Math.sin(a.rotation),n=1/0,r=1/0,s=-1/0,o=-1/0,h=[[t.x,t.y],[t.x+t.width,t.y],[t.x+t.width,t.y+t.height],[t.x,t.y+t.height]];for(let[l,d]of h){let u=l*e-d*i+a.x,c=l*i+d*e+a.y;n=Math.min(n,u),r=Math.min(r,c),s=Math.max(s,u),o=Math.max(o,c);}return {x:n,y:r,width:s-n,height:o-r}}function xt(a,t=24){if(!a||a.length===0)return {x:0,y:0,width:400,height:300};let e=1/0,i=1/0,n=-1/0,r=-1/0;for(let s of a){let o=Ce(s);e=Math.min(e,o.x),i=Math.min(i,o.y),n=Math.max(n,o.x+o.width),r=Math.max(r,o.y+o.height);}return {x:e-t,y:i-t,width:n-e+t*2,height:r-i+t*2}}function re(a,t={}){let e=t.padding??24,i=t.scale??2,n=t.background===void 0?"#ffffff":t.background??null,r=xt(a,e),s=Math.max(1,Math.ceil(r.width)),o=Math.max(1,Math.ceil(r.height)),h=document.createElement("canvas");h.width=Math.ceil(s*i),h.height=Math.ceil(o*i);let l=new st(h,i);l.resize(s*i,o*i);let d=new et;return d.zoom=1,d.x=-r.x,d.y=-r.y,l.render(a,d,new Set,void 0,void 0,void 0,void 0,void 0,void 0,void 0,n),h}function Ee(a,t,e){return new Promise((i,n)=>{a.toBlob(r=>{r?i(r):n(new Error("canvas.toBlob failed"));},t,e);})}function $e(a,t,e){return a.toDataURL(t,e)}var yt=null;function tt(a,t){return yt||(yt=document.createElement("canvas").getContext("2d")),yt?(yt.font=t,yt.measureText(a).width):a.length*8}function ht(a){return a.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&apos;")}function Qt(a,t,e,i){let n=t*1.3,r=Math.max(1,Math.floor(i/n)),s=`${t}px sans-serif`,o=a.split(`
3
+ `),h=[];for(let d of o){let u="";for(let c of d){let g=u+c;tt(g,s)>e&&u?(h.push(u),u=c):u=g;}u&&h.push(u);}let l=h.slice(0,r);if(h.length>r&&l.length>0){let d=l[l.length-1],u="...";for(;d.length>0&&tt(d+u,s)>e;)d=d.slice(0,-1);l[l.length-1]=d+u;}return l}function Gt(a,t,e){if(tt(a,e)<=t)return a;let i="\u2026",n=0,r=a.length;for(;n<r;){let s=n+r+1>>1;tt(a.slice(0,s)+i,e)<=t?n=s:r=s-1;}return a.slice(0,n)+i}function Q(a){return a.map(([t,e])=>`${m(t)},${m(e)}`).join(" ")}function m(a){return Math.round(a*100)/100}function oe(a){return a.strokeDash&&a.strokeDash.length?a.strokeDash.join(","):void 0}function ae(a,t){let e=t.x-a.x,i=t.y-a.y,n=Math.cos(a.rotation),r=Math.sin(a.rotation);return {x:e*n-i*r+a.x,y:e*r+i*n+a.y}}function te(a,t){if(t.isPrecise&&t.normalizedAnchor){let e=Ut(a),i=a.x+e.x+e.width*t.normalizedAnchor.x,n=a.y+e.y+e.height*t.normalizedAnchor.y;return {x:i,y:n}}if(t.handle){let e=Ut(a);switch(t.handle){case "top":return {x:a.x,y:a.y+e.y};case "bottom":return {x:a.x,y:a.y+e.y+e.height};case "left":return {x:a.x+e.x,y:a.y};case "right":return {x:a.x+e.x+e.width,y:a.y}}}return {x:a.x,y:a.y}}function De(a,t){let e=a.points.map(i=>({...i}));if(e.length===0)return e;if(a.startBinding){let i=t.get(a.startBinding.toShapeId);i&&(e[0]=te(i,a.startBinding));}if(a.endBinding){let i=t.get(a.endBinding.toShapeId);i&&(e[e.length-1]=te(i,a.endBinding));}return e.map(i=>ae(a,i))}function Ae(a){if(a.length<2)return a;let t=a[0],e=a[a.length-1],i=e.x-t.x,n=e.y-t.y,r=8;if(Math.abs(n)<=r){let s=(t.y+e.y)/2;return a.map(o=>({x:o.x,y:s}))}if(Math.abs(i)<=r){let s=(t.x+e.x)/2;return a.map(o=>({x:s,y:o.y}))}return a}function Le(a){if(a.length<2)return a;let t=[a[0]];for(let e=1;e<a.length;e++){let i=a[e-1],n=a[e],r=(i.x+n.x)/2,s=(i.y+n.y)/2;Math.abs(n.x-i.x)>=Math.abs(n.y-i.y)?(t.push({x:r,y:i.y}),t.push({x:r,y:n.y})):(t.push({x:i.x,y:s}),t.push({x:n.x,y:s})),t.push(n);}return t}function Ne(a){if(a.length<2)return "";let t=`M ${m(a[0].x)} ${m(a[0].y)}`,e=a[0];for(let i=1;i<a.length;i++){let n=a[i],r=n.x-e.x,s=n.y-e.y,o=Math.hypot(r,s),h={x:(e.x+n.x)/2,y:(e.y+n.y)/2};if(o>=1){let l=-s/o,d=r/o,u=Math.min(o*.2,30);h={x:h.x+l*u,y:h.y+d*u};}t+=` Q ${m(h.x)} ${m(h.y)} ${m(n.x)} ${m(n.y)}`,e=n;}return t}function Re(a,t){if(t==="curve")return Ne(a);let e=t==="straight"?Ae(a):Le(a);if(e.length<2)return "";let i=`M ${m(e[0].x)} ${m(e[0].y)}`;for(let n=1;n<e.length;n++)i+=` L ${m(e[n].x)} ${m(e[n].y)}`;return i}function ee(a,t,e,i){let n=Math.atan2(t.y-a.y,t.x-a.x),r=12,s={x:t.x-r*Math.cos(n-Math.PI/6),y:t.y-r*Math.sin(n-Math.PI/6)},o={x:t.x-r*Math.cos(n+Math.PI/6),y:t.y-r*Math.sin(n+Math.PI/6)};return `<path d="M ${m(t.x)} ${m(t.y)} L ${m(s.x)} ${m(s.y)} M ${m(t.x)} ${m(t.y)} L ${m(o.x)} ${m(o.y)}" stroke="${e}" stroke-width="${i}" stroke-linecap="round" fill="none" />`}function Ve(a,t,e,i){let n=Math.atan2(t.y-a.y,t.x-a.x),r=14,s=t.x,o=t.y,h=t.x-r*Math.cos(n),l=t.y-r*Math.sin(n),d=h+r*.5*Math.cos(n-Math.PI/2),u=l+r*.5*Math.sin(n-Math.PI/2),c=h+r*.5*Math.cos(n+Math.PI/2),g=l+r*.5*Math.sin(n+Math.PI/2);return `<polygon points="${m(s)},${m(o)} ${m(d)},${m(u)} ${m(c)},${m(g)}" fill="#ffffff" stroke="${e}" stroke-width="${i}" />`}function ne(a,t,e,i,n){let r=Math.atan2(t.y-a.y,t.x-a.x),s=14,o=t.x,h=t.y,l=t.x-s*.5*Math.cos(r),d=t.y-s*.5*Math.sin(r),u=t.x-s*Math.cos(r),c=t.y-s*Math.sin(r),g=l+s*.4*Math.cos(r-Math.PI/2),p=d+s*.4*Math.sin(r-Math.PI/2),y=l+s*.4*Math.cos(r+Math.PI/2),f=d+s*.4*Math.sin(r+Math.PI/2);return `<polygon points="${m(o)},${m(h)} ${m(g)},${m(p)} ${m(u)},${m(c)} ${m(y)},${m(f)}" fill="${n?e:"#ffffff"}" stroke="${e}" stroke-width="${i}" />`}function He(a,t,e,i){if(t==="none"||a.length<2)return "";let n="";return (t==="start"||t==="both")&&(n+=ee(a[1],a[0],e,i)),(t==="end"||t==="both")&&(n+=ee(a[a.length-2],a[a.length-1],e,i)),t==="inheritance"&&(n+=Ve(a[a.length-2],a[a.length-1],e,i)),t==="aggregation"&&(n+=ne(a[1],a[0],e,i,false)),t==="composition"&&(n+=ne(a[1],a[0],e,i,true)),n}function ie(a,t,e,i=0,n=0){if(a.length===0)return "";let r=t*1.3,o=-(a.length*r)/2+r/2,h=a.map((l,d)=>`<tspan x="${m(i)}" y="${m(n+o+d*r)}">${ht(l)}</tspan>`).join("");return `<text text-anchor="middle" dominant-baseline="central" font-family="sans-serif" font-size="${t}" fill="${e}">${h}</text>`}function O(a,t){let e=oe(a);return [a.fillColor!=="transparent"?`fill="${a.fillColor}"`:'fill="none"',`stroke="${a.strokeColor}"`,`stroke-width="${a.strokeWidth}"`,'stroke-linecap="round"','stroke-linejoin="round"',e?`stroke-dasharray="${e}"`:""].filter(Boolean).join(" ")}function se(a,t){let{width:e,height:i}=a,n=e/2,r=i/2,s=`${_}px sans-serif`,o=K,h=t?0:a.attributes.length>0?a.attributes.length*L+D*2:D*2,l=e-B*2,d=[];d.push(`<rect x="${m(-n)}" y="${m(-r)}" width="${e}" height="${i}" ${O(a.style)} />`),d.push(`<line x1="${m(-n)}" y1="${m(-r+o)}" x2="${m(n)}" y2="${m(-r+o)}" stroke="${a.style.strokeColor}" stroke-width="${a.style.strokeWidth}" />`),t||d.push(`<line x1="${m(-n)}" y1="${m(-r+o+h)}" x2="${m(n)}" y2="${m(-r+o+h)}" stroke="${a.style.strokeColor}" stroke-width="${a.style.strokeWidth}" />`);let u=t?`<<${a.className||"Interface"}>>`:a.className;d.push(`<text text-anchor="middle" dominant-baseline="central" font-family="sans-serif" font-weight="bold" font-size="${_}" fill="${a.textColor||mt}" x="0" y="${m(-r+o/2)}">${ht(Gt(u,l,s))}</text>`);let c=(p,y,f,M,x)=>{let v=`${f||_}px sans-serif`,b=Gt(p,l,v),P=`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="${f||_}" fill="${M||mt}" x="${m(-n+B)}" y="${m(y)}">${ht(b)}</text>`;if(x){let T=tt(b,v);P+=`<line x1="${m(-n+B)}" y1="${m(y)}" x2="${m(-n+B+T)}" y2="${m(y)}" stroke="${M||mt}" stroke-width="1" />`;}return P};if(!t){let p=-r+o+D+L/2;a.attributes.forEach((y,f)=>{d.push(c(`${y.visibility} ${y.name}: ${y.type}`,p+f*L,y.fontSize||a.fontSize||0,y.textColor||a.textColor||"",!!y.strikethrough));});}let g=-r+o+h+D+L/2;return a.methods.forEach((p,y)=>{d.push(c(`${p.visibility} ${p.name}(${p.params}): ${p.returnType}`,g+y*L,p.fontSize||a.fontSize||0,p.textColor||a.textColor||"",!!p.strikethrough));}),d.join("")}function ke(a){let e=k(a.root).positions,i=[],n=s=>{if(s.collapsed)return;let o=e.get(s.id);if(o)for(let h of s.children??[]){let l=e.get(h.id);if(!l)continue;let d=it(h,l.depth),u=a.x+o.x+o.width/2,c=a.y+o.y,g=a.x+l.x-l.width/2,p=a.y+l.y,y=(u+g)/2;i.push(`<path d="M ${m(u)} ${m(c)} C ${m(y)} ${m(c)} ${m(y)} ${m(p)} ${m(g)} ${m(p)}" stroke="${d}" stroke-width="2" fill="none" stroke-linecap="round" />`),n(h);}};n(a.root);let r=s=>{let o=e.get(s.id);if(!o)return;let h=it(s,o.depth),l=o.width/2,d=o.height/2,u=a.x+o.x,c=a.y+o.y;if(i.push(`<rect x="${m(u-l)}" y="${m(c-d)}" width="${o.width}" height="${o.height}" rx="6" ry="6" fill="#ffffff" stroke="${h}" stroke-width="2" />`),s.note){let v="11px sans-serif",b=s.noteColor??h,P=Math.min(tt(s.note,v)+12,130),T=16,E=tt(s.note,v)+12>130?s.note.slice(0,12)+"\u2026":s.note;i.push(`<rect x="${m(u-l)}" y="${m(c-d-T+2)}" width="${P}" height="${T}" rx="4" ry="4" fill="${b}" />`),i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="11" fill="#ffffff" x="${m(u-l+6)}" y="${m(c-d-T/2+2)}">${ht(E)}</text>`);}let g=s.icon?18:0,p=o.width-g-(s.icon?8:0)-16,y=Gt(s.text||"",p,`${14}px sans-serif`),f=tt(y,`${14}px sans-serif`),M=g+(g?8:0)+f,x=u-M/2;if(s.icon&&(i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="16" fill="#1f2937" x="${m(x)}" y="${m(c)}">${ht(s.icon)}</text>`),x+=g+8),i.push(`<text text-anchor="start" dominant-baseline="central" font-family="sans-serif" font-size="${14}" fill="#1f2937" x="${m(x)}" y="${m(c)}">${ht(y)}</text>`),s.children&&s.children.length>0&&!s.collapsed)for(let v of s.children)r(v);};return r(a.root),i.join("")}function Be(a,t){let e=a.rotation*180/Math.PI,i=`<g transform="translate(${m(a.x)} ${m(a.y)}) rotate(${m(e)})">`,n="</g>",r=a.style;switch(a.type){case "rectangle":{let s=a.width,o=a.height;return `${i}<rect x="${m(-s/2)}" y="${m(-o/2)}" width="${s}" height="${o}" ${O(r)} />${n}`}case "rounded-rectangle":{let s=a.width,o=a.height,h=a.borderRadius||8;return `${i}<rect x="${m(-s/2)}" y="${m(-o/2)}" width="${s}" height="${o}" rx="${h}" ry="${h}" ${O(r)} />${n}`}case "circle":{let s=a.radius;return `${i}<circle cx="0" cy="0" r="${s}" ${O(r)} />${n}`}case "ellipse":{let s=a.width,o=a.height;return `${i}<ellipse cx="0" cy="0" rx="${s/2}" ry="${o/2}" ${O(r)} />${n}`}case "diamond":{let s=a.width,o=a.height;return `${i}<polygon points="${Q([[0,-o/2],[s/2,0],[0,o/2],[-s/2,0]])}" ${O(r)} />${n}`}case "triangle":{let s=a.width,o=a.height;return `${i}<polygon points="${Q([[0,-o/2],[s/2,o/2],[-s/2,o/2]])}" ${O(r)} />${n}`}case "hexagon":{let s=a.width,o=a.height;return `${i}<polygon points="${Q(_t(s,o,6,-Math.PI/2))}" ${O(r)} />${n}`}case "pentagon":{let s=a.width,o=a.height;return `${i}<polygon points="${Q(_t(s,o,5,-Math.PI/2))}" ${O(r)} />${n}`}case "octagon":{let s=a.width,o=a.height;return `${i}<polygon points="${Q(_t(s,o,8,-Math.PI/8))}" ${O(r)} />${n}`}case "star":{let s=a.width,o=a.height;return `${i}<polygon points="${Q(_e(s,o))}" ${O(r)} />${n}`}case "parallelogram":{let s=a.width,o=a.height,h=s*.2;return `${i}<polygon points="${Q([[-s/2+h,-o/2],[s/2,-o/2],[s/2-h,o/2],[-s/2,o/2]])}" ${O(r)} />${n}`}case "trapezoid":{let s=a.width,o=a.height,h=s*.15;return `${i}<polygon points="${Q([[-s/2+h,-o/2],[s/2-h,-o/2],[s/2,o/2],[-s/2,o/2]])}" ${O(r)} />${n}`}case "uml-class":return `${i}${se(a,false)}${n}`;case "uml-interface":return `${i}${se(a,true)}${n}`;case "mind-map":return ke(a);case "line":case "arrow":{let s=a,o=s.connectionType||"straight",h=De(s,t);if(h.length<2)return "";let l=s.style.strokeColor,d=s.style.strokeWidth,u=oe(s.style),c=`<path d="${Re(h,o)}" fill="none" stroke="${l}" stroke-width="${d}" stroke-linecap="round" stroke-linejoin="round"${u?` stroke-dasharray="${u}"`:""} />`,g=He(h,s.arrowHead||"end",l,d);return `${c}${g}`}case "draw":{let s=a.points;if(!s||s.length<2)return "";let o=s.map(l=>ae(a,l));if(o.length<2)return "";let h=`M ${m(o[0].x)} ${m(o[0].y)}`;for(let l=1;l<o.length-1;l++){let d=(o[l].x+o[l+1].x)/2,u=(o[l].y+o[l+1].y)/2;h+=` Q ${m(o[l].x)} ${m(o[l].y)} ${m(d)} ${m(u)}`;}return h+=` L ${m(o[o.length-1].x)} ${m(o[o.length-1].y)}`,`<path d="${h}" fill="none" stroke="${r.strokeColor}" stroke-width="${r.strokeWidth}" stroke-linecap="round" stroke-linejoin="round" />`}case "text":{let s=a,o=s.fontSize||16,h=s.textColor||mt,l=Qt(s.text||"",o,s.width,s.height),d="";if(s.highlightColor&&s.highlightColor!=="transparent"){let u=o*.15;d+=`<rect x="${m(-s.width/2-u)}" y="${m(-(l.length*o*1.3)/2-u)}" width="${s.width+u*2}" height="${l.length*o*1.3+u*2}" rx="4" fill="${s.highlightColor}" />`;}return d+=ie(l,o,h),`${i}${d}${n}`}default:{let s=a,o=s.width||100,h=s.height||40,l="";if(s.text){let d=s.fontSize||16,u=Qt(s.text,d,o*.85,h*.85);l+=ie(u,d,s.textColor||mt);}return `${i}<rect x="${m(-o/2)}" y="${m(-h/2)}" width="${o}" height="${h}" ${O(r)} />${l}${n}`}}}function _t(a,t,e,i){let n=a/2,r=t/2,s=[];for(let o=0;o<e;o++){let h=o*2*Math.PI/e+i;s.push([n*Math.cos(h),r*Math.sin(h)]);}return s}function _e(a,t){let e=a/2,i=t/2,n=5,r=.4,s=[];for(let o=0;o<n*2;o++){let h=o*Math.PI/n-Math.PI/2,l=o%2===0?1:r;s.push([e*l*Math.cos(h),i*l*Math.sin(h)]);}return s}function he(a,t={}){let e=t.padding??24,i=t.background===void 0?"#ffffff":t.background??null,n=xt(a,e),r=Math.max(1,Math.ceil(n.width)),s=Math.max(1,Math.ceil(n.height)),o=new Map(a.map(d=>[d.id,d])),h=a.map(d=>Be(d,o)).filter(Boolean).join(`
4
+ `),l=i?`<rect x="${m(n.x)}" y="${m(n.y)}" width="${r}" height="${s}" fill="${i}" />`:"";return `<?xml version="1.0" encoding="UTF-8"?>
5
+ <svg xmlns="http://www.w3.org/2000/svg" width="${r}" height="${s}" viewBox="${m(n.x)} ${m(n.y)} ${r} ${s}" font-family="sans-serif">
6
+ ${l}
7
+ ${h}
8
+ </svg>`}function ft(a){return a.toString().padStart(10,"0")}function Ue(a,t,e){let i=a.split(",")[1]||"",n=atob(i),r=new Uint8Array(n.length);for(let E=0;E<n.length;E++)r[E]=n.charCodeAt(E);let s=Math.round(t),o=Math.round(e),h=`<< /Type /XObject /Subtype /Image /Width ${s} /Height ${o} /ColorSpace /DeviceRGB /BitsPerComponent 8 /Filter /DCTDecode /Length ${r.length} >>`,l=`q ${s} 0 0 ${o} 0 0 cm /Im0 Do Q`,d=`1 0 obj
9
+ << /Type /Catalog /Pages 2 0 R >>
10
+ endobj
11
+ `,u=`2 0 obj
12
+ << /Type /Pages /Kids [3 0 R] /Count 1 >>
13
+ endobj
14
+ `,c=`3 0 obj
15
+ << /Type /Page /Parent 2 0 R /MediaBox [0 0 ${s} ${o}] /Resources << /XObject << /Im0 4 0 R >> >> /Contents 5 0 R >>
16
+ endobj
17
+ `,g=`4 0 obj
18
+ ${h}
19
+ stream
20
+ `,p=`endstream
21
+ endobj
22
+ `,y=`5 0 obj
23
+ << /Length ${l.length} >>
24
+ stream
25
+ ${l}
26
+ endstream
27
+ endobj
28
+ `,f=`%PDF-1.4
29
+ `,M=f.length,x=M+d.length,v=x+u.length,b=v+c.length,P=b+g.length+r.length+p.length,T=`xref
30
+ 0 6
31
+ 0000000000 65535 f
32
+ `+ft(M)+` 00000 n
33
+ `+ft(x)+` 00000 n
34
+ `+ft(v)+` 00000 n
35
+ `+ft(b)+` 00000 n
36
+ `+ft(P)+` 00000 n
37
+ trailer
38
+ << /Size 6 /Root 1 0 R >>
39
+ startxref
40
+ ${P+y.length}
41
+ %%EOF`;return new Blob([f+d+u+c+g,r,p+y+T],{type:"application/pdf"})}async function zt(a,t,e={}){if(t==="svg"){let r=he(a,e);return new Blob([r],{type:"image/svg+xml;charset=utf-8"})}let i=re(a,e);if(t==="png")return Ee(i,"image/png");let n=$e(i,"image/jpeg",.92);return Ue(n,i.width,i.height)}function Ot(a,t){let e=URL.createObjectURL(a),i=document.createElement("a");i.href=e,i.download=t,document.body.appendChild(i),i.click(),document.body.removeChild(i),setTimeout(()=>URL.revokeObjectURL(e),1e3);}var Xt="drawui-canvas-data",Ge=50,Yt=class{canvas;renderer;camera;tools=new Map;activeTool="select";shapes=[];selectedIds=[];listeners=new Set;notificationListeners=new Set;uiListeners=new Set;isPanning=false;panStart={x:0,y:0};dragStartPositions=new Map;lastClickTime=0;lastClickShapeId=null;editingShapeId=null;textInput=null;textOverlay=null;isNewTextShape=false;originalTextValue="";undoStack=[];redoStack=[];isUndoing=false;brushRect=null;snapGuides=[];connectingTargetId=null;genPreview=null;eraserPoint=null;mindMapEditingShapeId=null;mindMapSelectedNode=null;mindMapHoverNode=null;renderScheduled=false;pointerIsDown=false;notifyScheduled=false;persist=true;constructor(t,e={}){this.canvas=t,this.persist=e.persist??!e.shapes,e.theme&&bt(e.theme),e.language&&vt(e.language);let i=t.getBoundingClientRect();this.renderer=new st(t),this.renderer.resize(i.width,i.height),this.camera=new et;let n={addShape:r=>this.addShape(r),updateShape:(r,s)=>this.updateShape(r,s),deleteShape:r=>this.deleteShape(r),selectShape:(r,s)=>this.selectShape(r,s),selectShapes:r=>this.selectShapes(r),getShapes:()=>[...this.shapes],getSelectedIds:()=>[...this.selectedIds],setActiveTool:r=>this.setActiveTool(r),screenToPage:r=>this.screenToPage(r),getCamera:()=>this.camera,panBy:(r,s)=>this.panBy(r,s),setCameraPosition:(r,s)=>this.setCameraPosition(r,s),getShapeAtPoint:(r,s)=>this.getShapeAtPoint(r,s),getShapesInBrushRadius:(r,s)=>this.getShapesInBrushRadius(r,s),setEraserPoint:r=>this.setEraserPoint(r),updateArrowBinding:(r,s,o,h)=>this.updateArrowBinding(r,s,o,h),enterEditing:r=>this.enterEditing(r),exitEditing:()=>this.exitEditing(),commitHistory:()=>this.commitHistory(),setBrushRect:r=>this.setBrushRect(r),setSnapGuides:r=>this.setSnapGuides(r),setConnectingTarget:r=>this.setConnectingTarget(r),setGenerationPreview:r=>this.setGenerationPreview(r),openGenerationMenu:r=>this.openGenerationMenu(r),createGeneratedConnection:(r,s)=>this.createGeneratedConnection(r,s),createFloatingLine:r=>this.createFloatingLine(r),connectToExisting:(r,s,o)=>this.connectToExisting(r,s,o),updateSelectedShapesStyle:r=>this.updateSelectedShapesStyle(r),updateSelectedShapesText:r=>this.updateSelectedShapesText(r),updateConnectionType:r=>this.updateConnectionType(r),getMindMapCursorHitAtPoint:r=>this.getMindMapCursorHitAtPoint(r),selectMindMapNode:(r,s)=>this.selectMindMapNode(r,s)};this.tools.set("select",new ct(n)),this.tools.set("hand",new ut(n)),this.tools.set("rectangle",new V(n,"rectangle")),this.tools.set("rounded-rectangle",new V(n,"rounded-rectangle")),this.tools.set("circle",new V(n,"circle")),this.tools.set("ellipse",new V(n,"ellipse")),this.tools.set("diamond",new V(n,"diamond")),this.tools.set("triangle",new V(n,"triangle")),this.tools.set("hexagon",new V(n,"hexagon")),this.tools.set("parallelogram",new V(n,"parallelogram")),this.tools.set("trapezoid",new V(n,"trapezoid")),this.tools.set("pentagon",new V(n,"pentagon")),this.tools.set("octagon",new V(n,"octagon")),this.tools.set("star",new V(n,"star")),this.tools.set("uml-class",new V(n,"uml-class")),this.tools.set("uml-interface",new V(n,"uml-interface")),this.tools.set("line",new gt(n)),this.tools.set("arrow",new pt(n)),this.tools.set("text",new $t(n)),this.tools.set("pen",new at(n,"pen")),this.tools.set("highlighter",new at(n,"highlighter")),this.tools.set("eraser",new Et(n)),this.tools.set("mind-map",new V(n,"mind-map")),this.setupEventListeners(),e.shapes?this.shapes=e.shapes.map(r=>({...r,style:{...r.style}})):this.persist&&this.loadFromStorage(),this.render();}setupEventListeners(){this.canvas.addEventListener("pointerdown",this.handlePointerDown),this.canvas.addEventListener("pointermove",this.handlePointerMove),this.canvas.addEventListener("pointerup",this.handlePointerUp),this.canvas.addEventListener("pointerleave",this.handlePointerUp),this.canvas.addEventListener("wheel",this.handleWheel,{passive:false}),window.addEventListener("keydown",this.handleKeyDown),window.addEventListener("keyup",this.handleKeyUp),window.addEventListener("resize",this.handleResize);}handlePointerDown=t=>{if(this.editingShapeId)return this.textInput&&t.target===this.textInput,void 0;if(this.pointerIsDown=true,t.button===1||t.button===0&&t.altKey){this.isPanning=true,this.panStart={x:t.clientX,y:t.clientY},this.canvas.setPointerCapture(t.pointerId),this.canvas.style.cursor="grabbing";return}let e=this.screenToPage({x:t.clientX,y:t.clientY}),i=this.activeTool==="select"?this.getMindMapCollapseHitAtPoint(e):null;if(i){this.toggleMindMapCollapse(i.shapeId,i.nodeId);return}if(this.activeTool==="select"){let r=Date.now(),s=this.getShapeAtPoint(e);if(r-this.lastClickTime<400&&this.lastClickShapeId&&s&&s.id===this.lastClickShapeId&&this.canEditShape(s)){this.enterEditing(s.id),this.lastClickTime=0,this.lastClickShapeId=null;return}if(this.lastClickTime=r,this.lastClickShapeId=s?.id||null,s&&s.type==="mind-map"&&this.mindMapEditingShapeId===s.id){let o=this.getMindMapNodeAtPoint(e);o&&(this.mindMapSelectedNode=o,this.notifyListeners(),this.render());return}s&&(this.dragStartPositions.clear(),this.selectedIds.forEach(o=>{let h=this.shapes.find(l=>l.id===o);h&&this.dragStartPositions.set(o,{x:h.x,y:h.y});}));}this.tools.get(this.activeTool)?.onPointerDown(e,t),this.updateCursor(e),this.render();};handlePointerMove=t=>{if(this.editingShapeId)return;if(this.isPanning){let n=t.clientX-this.panStart.x,r=t.clientY-this.panStart.y;this.camera.translate(n,r),this.panStart={x:t.clientX,y:t.clientY},this.scheduleRender(),this.notifyListeners();return}let e=this.screenToPage({x:t.clientX,y:t.clientY});this.tools.get(this.activeTool)?.onPointerMove(e,t),this.updateCursor(e),this.scheduleRender();};handlePointerUp=t=>{if(this.pointerIsDown=false,t.type==="pointerleave"&&(this.mindMapHoverNode=null),this.editingShapeId)return;if(this.isPanning){this.isPanning=false,this.updateCursor(this.screenToPage({x:t.clientX,y:t.clientY}));return}let e=this.screenToPage({x:t.clientX,y:t.clientY});this.tools.get(this.activeTool)?.onPointerUp(e,t),this.updateCursor(e),this.scheduleRender();};updateCursor(t){let i=this.tools.get(this.activeTool)?.getCursor(t)??"default";if(this.canvas.style.cursor!==i&&(this.canvas.style.cursor=i),!this.pointerIsDown){let n=this.getMindMapCursorHitAtPoint(t);(n?.shapeId!==this.mindMapHoverNode?.shapeId||n?.nodeId!==this.mindMapHoverNode?.nodeId)&&(this.mindMapHoverNode=n,this.scheduleRender());}}handleWheel=t=>{if(t.preventDefault(),t.ctrlKey||t.metaKey){let n=t.deltaY>0?.9:1.1;this.camera.zoomAt({x:t.clientX,y:t.clientY},n),this.scheduleRender(),this.notifyListeners();return}let e=t.deltaX||0,i=t.deltaY||0;t.deltaMode===1?(e*=40,i*=40):t.deltaMode===2&&(e*=120,i*=120),t.shiftKey&&(e=e||i,i=0),this.camera.translate(-e,-i),this.scheduleRender(),this.notifyListeners();};handleKeyDown=t=>{if(this.editingShapeId)return;if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="z"){t.preventDefault(),t.shiftKey?this.redo():this.undo();return}if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="y"){t.preventDefault(),this.redo();return}if((t.ctrlKey||t.metaKey)&&t.key.toLowerCase()==="s"){t.preventDefault(),this.saveToStorage();return}if(!t.ctrlKey&&!t.metaKey&&!t.altKey){if(t.key==="v"||t.key==="V"){this.setActiveTool("select"),t.preventDefault();return}if(t.key==="h"||t.key==="H"){this.setActiveTool("hand"),t.preventDefault();return}}this.tools.get(this.activeTool)?.onKeyDown(t),this.scheduleRender();};handleKeyUp=t=>{if(this.editingShapeId)return;this.tools.get(this.activeTool)?.onKeyUp(t),this.scheduleRender();};handleResize=()=>{this.renderer.resize(window.innerWidth,window.innerHeight),this.scheduleRender();};screenToPage(t){let e=this.canvas.getBoundingClientRect();return this.camera.screenToPage({x:t.x-e.left,y:t.y-e.top})}addShape(t){this.shapes.push(t),this.notifyListeners();}updateShape(t,e){let i=this.shapes.findIndex(n=>n.id===t);i!==-1&&(this.shapes[i]={...this.shapes[i],...e},(e.x!==void 0||e.y!==void 0)&&this.updateBoundArrows(t),this.notifyListeners());}updateBoundArrows(t){let e=this.shapes.find(i=>i.id===t);e&&this.shapes.forEach(i=>{if(i.type==="arrow"){let n=i,r={};if(n.startBinding?.toShapeId===t){let s=this.getBindingPosition(e,n.startBinding.handle||"top");r.points=n.points.map((o,h)=>h===0?s:o);}if(n.endBinding?.toShapeId===t){let s=this.getBindingPosition(e,n.endBinding.handle||"top"),o=r.points||[...n.points];r.points=o.map((h,l)=>l===o.length-1?s:h);}r.points&&(this.shapes[this.shapes.indexOf(i)]={...n,...r});}});}getBindingPosition(t,e){switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}case "circle":switch(e){case "top":return {x:t.x,y:t.y-t.radius};case "bottom":return {x:t.x,y:t.y+t.radius};case "left":return {x:t.x-t.radius,y:t.y};case "right":return {x:t.x+t.radius,y:t.y}}case "hexagon":switch(e){case "top":return {x:t.x,y:t.y-t.height/2};case "bottom":return {x:t.x,y:t.y+t.height/2};case "left":return {x:t.x-t.width/2,y:t.y};case "right":return {x:t.x+t.width/2,y:t.y}}default:return {x:t.x,y:t.y}}}deleteShape(t){this.shapes=this.shapes.filter(e=>e.id!==t),this.selectedIds=this.selectedIds.filter(e=>e!==t),this.shapes=this.shapes.map(e=>{if(e.type==="arrow"){let i=e;if(i.startBinding?.toShapeId===t)return {...i,startBinding:void 0};if(i.endBinding?.toShapeId===t)return {...i,endBinding:void 0}}return e}),this.notifyListeners(),this.scheduleRender();}selectShape(t,e){if(!t)this.selectedIds=[];else if(e){let i=this.selectedIds.indexOf(t);i===-1?this.selectedIds.push(t):this.selectedIds.splice(i,1);}else this.selectedIds=[t];this.notifyListeners(),this.scheduleRender();}selectShapes(t){this.selectedIds=[...t],this.notifyListeners(),this.scheduleRender();}setBrushRect(t){this.brushRect=t,this.scheduleRender();}setSnapGuides(t){this.snapGuides=t;}setConnectingTarget(t){this.connectingTargetId!==t&&(this.connectingTargetId=t,this.scheduleRender());}setGenerationPreview(t){this.genPreview?.from.x===t?.from.x&&this.genPreview?.from.y===t?.from.y&&this.genPreview?.to.x===t?.to.x&&this.genPreview?.to.y===t?.to.y&&this.genPreview?.type===t?.type||(this.genPreview=t,this.scheduleRender());}openGenerationMenu(t){let e=this.camera.getZoom(),i=(t.context.to.x+this.camera.x)*e,n=(t.context.to.y+this.camera.y)*e;this.emitUi({kind:"shapeTypeMenu",screenX:i,screenY:n,context:t.context,existingArrowId:t.existingArrowId,defaultShapeType:t.defaultShapeType});}lineStyle(){return {strokeColor:"#1f2937",fillColor:"transparent",strokeWidth:2,strokeDash:null}}computeSourceBinding(t){if(!t.sourceShapeId||!t.edge)return;let e=this.shapes.find(n=>n.id===t.sourceShapeId);if(!e)return;let i={n:"top",e:"right",s:"bottom",w:"left"};return {toShapeId:e.id,handle:i[t.edge]}}connectHandle(t,e){let i=e.x-t.x,n=e.y-t.y;return Math.abs(i)>=Math.abs(n)?i>=0?"left":"right":n>=0?"top":"bottom"}createFloatingLine(t){this.commitHistory();let e=t.from,i=t.to,n=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,r={id:n,type:"arrow",x:e.x,y:e.y,points:[{x:e.x,y:e.y},{x:i.x,y:i.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),connectionType:"polyline",arrowHead:"end",dashed:false};return this.addShape(r),this.selectedIds=[n],this.notifyListeners(),this.render(),n}createGeneratedConnection(t,e){this.commitHistory();let i=e.type,n;if(t.sourceShapeId){let h=this.shapes.find(l=>l.id===t.sourceShapeId);h&&It(h.type)&&(n={...h.style});}let r=kt(i,t.to,n);this.addShape(r);let s=t.from,o={toShapeId:r.id,handle:this.connectHandle(s,t.to)};if(e.existingArrowId)this.updateArrowBinding(e.existingArrowId,"end",r.id,{toShapeId:r.id,handle:this.connectHandle(s,t.to)});else {let l={id:`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:"arrow",x:s.x,y:s.y,points:[{x:s.x,y:s.y},{x:t.to.x,y:t.to.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),endBinding:o,connectionType:"polyline",arrowHead:"end",dashed:false};this.addShape(l);}this.selectedIds=[r.id],this.notifyListeners(),this.render();}connectToExisting(t,e,i){this.commitHistory();let n=this.shapes.find(d=>d.id===e);if(!n)return;let r=t.from,s=i?.handle??this.connectHandle(r,{x:n.x,y:n.y}),o=this.getBindingPosition(n,s),h=`shape_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,l={id:h,type:"arrow",x:r.x,y:r.y,points:[{x:r.x,y:r.y},{x:o.x,y:o.y}],rotation:0,style:this.lineStyle(),startBinding:this.computeSourceBinding(t),endBinding:{toShapeId:e,handle:s},connectionType:"polyline",arrowHead:"end",dashed:false};this.addShape(l),this.selectedIds=[h],this.notifyListeners(),this.render();}subscribeUi(t){return this.uiListeners.add(t),()=>this.uiListeners.delete(t)}emitUi(t){this.uiListeners.forEach(e=>e(t));}updateSelectedShapesStyle(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);i!==-1&&(this.shapes[i]={...this.shapes[i],style:{...this.shapes[i].style,...t}});}),this.notifyListeners(),this.render());}updateSelectedShapesText(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);i!==-1&&(this.shapes[i]={...this.shapes[i],...t});}),this.notifyListeners(),this.render());}updateConnectionType(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];(n.type==="line"||n.type==="arrow")&&(this.shapes[i]={...n,connectionType:t});}}),this.notifyListeners(),this.render());}updateArrowHeadType(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];n.type==="arrow"&&(this.shapes[i]={...n,arrowHead:t});}}),this.notifyListeners(),this.render());}updateArrowDashed(t){this.selectedIds.length!==0&&(this.commitHistory(),this.selectedIds.forEach(e=>{let i=this.shapes.findIndex(n=>n.id===e);if(i!==-1){let n=this.shapes[i];n.type==="arrow"&&(this.shapes[i]={...n,dashed:t});}}),this.notifyListeners(),this.render());}updateUmlClass(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="uml-class")return;this.commitHistory();let r=e.className??n.className,s=e.attributes??n.attributes,o=e.methods??n.methods,{width:h,height:l}=Ct(r,s,o);this.shapes[i]={...n,className:r,attributes:s,methods:o,width:h,height:l},this.notifyListeners(),this.render();}updateUmlInterface(t,e){let i=this.shapes.findIndex(p=>p.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="uml-interface")return;this.commitHistory();let r=n,s=e.className??r.className,o=e.methods??r.methods,h=_*.6,l=o.map(p=>`${p.visibility} ${p.name}(${p.params}): ${p.returnType}`),d=Math.max(s.length,...l.map(p=>p.length),0),u=Math.max(dt,d*h+B*2),c=o.length>0?o.length*L+D*2:D*2,g=K+c;this.shapes[i]={...n,className:s,methods:o,width:u,height:g},this.notifyListeners(),this.render();}getSelectedUml(){if(this.selectedIds.length!==1)return null;let t=this.shapes.find(e=>e.id===this.selectedIds[0]);return t&&(t.type==="uml-class"||t.type==="uml-interface")?t:null}getUmlById(t){let e=this.shapes.find(i=>i.id===t);return e&&(e.type==="uml-class"||e.type==="uml-interface")?e:null}getSelectedMindMap(){if(this.selectedIds.length!==1)return null;let t=this.shapes.find(e=>e.id===this.selectedIds[0]);return t&&t.type==="mind-map"?t:null}getMindMapNodeAtPoint(t){for(let e=this.shapes.length-1;e>=0;e--){let i=this.shapes[e];if(i.type!=="mind-map")continue;let n=i,r=t.x-n.x,s=t.y-n.y,o=Math.cos(n.rotation),h=Math.sin(n.rotation),l=r*o+s*h,d=-r*h+s*o;if(Math.abs(l)>n.width/2||Math.abs(d)>n.height/2)continue;let u=k(n.root);for(let[c,g]of u.positions)if(Math.abs(l-g.x)<=g.width/2&&Math.abs(d-g.y)<=g.height/2)return {shapeId:n.id,nodeId:c};return {shapeId:n.id,nodeId:n.root.id}}return null}getMindMapNodeAtScreenPoint(t){return this.getMindMapNodeAtPoint(this.screenToPage(t))}getMindMapCursorHitAtPoint(t){let e=this.getMindMapCollapseHitAtPoint(t);if(e)return e;for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(n.type!=="mind-map")continue;let r=n,s=t.x-r.x,o=t.y-r.y,h=Math.cos(r.rotation),l=Math.sin(r.rotation),d=s*h+o*l,u=-s*l+o*h,c=k(r.root);for(let[g,p]of c.positions)if(Math.abs(d-p.x)<=p.width/2&&Math.abs(u-p.y)<=p.height/2)return {shapeId:r.id,nodeId:g}}return null}selectMindMapNode(t,e){let i=this.shapes.find(n=>n.id===t);!i||i.type!=="mind-map"||(this.selectedIds=[t],this.mindMapSelectedNode={shapeId:t,nodeId:e},this.notifyListeners(),this.render());}getMindMapEditingShapeId(){return this.mindMapEditingShapeId}getMindMapSelectedNode(){return this.mindMapSelectedNode}getMindMapNode(t,e){let i=this.shapes.find(n=>n.id===t);return !i||i.type!=="mind-map"?null:q(i.root,e)}getMindMapNodeScreenRect(t,e){let i=this.shapes.find(M=>M.id===t);if(!i||i.type!=="mind-map")return null;let n=i,s=k(n.root).positions.get(e);if(!s)return null;let o=this.camera.getZoom(),h=s.x,l=s.y,d=Math.cos(n.rotation),u=Math.sin(n.rotation),c=h*d-l*u,g=h*u+l*d,p=this.camera.pageToScreen({x:n.x,y:n.y}),y=p.x+c*o,f=p.y+g*o;return {x:y-s.width*o/2,y:f-s.height*o/2,width:s.width*o,height:s.height*o}}getMindMapCollapseHitAtPoint(t){for(let e of this.shapes){if(e.type!=="mind-map")continue;let i=e,n=k(i.root),r=t.x-i.x,s=t.y-i.y,o=Math.cos(i.rotation),h=Math.sin(i.rotation),l=r*o+s*h,d=-r*h+s*o;for(let[u,c]of n.positions){let g=q(i.root,u);if(!g||!g.children||g.children.length===0)continue;let p=c.x+c.width/2+10,y=c.y,f=l-p,M=d-y;if(f*f+M*M<=121)return {shapeId:e.id,nodeId:u}}}return null}beginMindMapEdit(t,e){let i=this.shapes.find(r=>r.id===t);if(!i||i.type!=="mind-map")return;let n=i;this.mindMapEditingShapeId=t,this.mindMapSelectedNode={shapeId:t,nodeId:e&&q(n.root,e)?e:n.root.id},this.selectedIds=[t],this.notifyListeners(),this.render();}exitMindMapEdit(){this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null,this.notifyListeners(),this.render();}updateMindMapNode(t,e,i,n=true){let r=this.shapes.findIndex(g=>g.id===t);if(r===-1)return;let s=this.shapes[r];if(s.type!=="mind-map")return;let o=s,h=q(o.root,e);if(!h||!Object.keys(i).some(g=>h[g]!==i[g]))return;n&&this.commitHistory();let d=Tt(o.root,e,i),{width:u,height:c}=k(d);this.shapes[r]={...o,root:d,width:u,height:c},this.notifyListeners(),this.render();}addMindMapChild(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let r=n,s={id:`mm_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,text:W("mindmap.defaultBranch")},o=Rt(r.root,e,s);this.commitHistory();let{width:h,height:l}=k(o);this.shapes[i]={...r,root:o,width:h,height:l},this.mindMapSelectedNode={shapeId:t,nodeId:s.id},this.notifyListeners(),this.render();}addMindMapSibling(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let r=n;if(!lt(r.root,e))return;let s={id:`mm_${Date.now()}_${Math.random().toString(36).substr(2,6)}`,text:W("mindmap.defaultBranch")},o=Vt(r.root,e,s);this.commitHistory();let{width:h,height:l}=k(o);this.shapes[i]={...r,root:o,width:h,height:l},this.mindMapSelectedNode={shapeId:t,nodeId:s.id},this.notifyListeners(),this.render();}deleteMindMapNode(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let r=n;if(r.root.id===e){this.commitHistory(),this.shapes=this.shapes.filter(d=>d.id!==t),this.selectedIds=this.selectedIds.filter(d=>d!==t),this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null,this.notifyListeners(),this.render();return}let s=Ht(r.root,e);if(!s)return;this.commitHistory();let{width:o,height:h}=k(s);this.shapes[i]={...r,root:s,width:o,height:h};let l=lt(r.root,e);this.mindMapSelectedNode=l?{shapeId:t,nodeId:l.id}:{shapeId:t,nodeId:s.id},this.notifyListeners(),this.render();}toggleMindMapCollapse(t,e){let i=this.shapes.findIndex(d=>d.id===t);if(i===-1)return;let n=this.shapes[i];if(n.type!=="mind-map")return;let r=n,s=q(r.root,e);if(!s||!s.children||s.children.length===0)return;this.commitHistory();let o=Tt(r.root,e,{collapsed:!s.collapsed}),{width:h,height:l}=k(o);this.shapes[i]={...r,root:o,width:h,height:l},this.notifyListeners(),this.render();}addUmlAttribute(t){let e=this.shapes.find(n=>n.id===t);if(!e||e.type!=="uml-class")return;let i={id:`attr_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,visibility:"+",name:"newField",type:"string"};this.updateUmlClass(t,{attributes:[...e.attributes,i]});}addUmlMethod(t){let e=this.getUmlById(t);if(!e)return;let i={id:`meth_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,visibility:"+",name:"newMethod",params:"",returnType:"void"};e.type==="uml-class"?this.updateUmlClass(t,{methods:[...e.methods,i]}):this.updateUmlInterface(t,{methods:[...e.methods,i]});}removeUmlAttribute(t,e){let i=this.shapes.find(n=>n.id===t);!i||i.type!=="uml-class"||this.updateUmlClass(t,{attributes:i.attributes.filter(n=>n.id!==e)});}removeUmlMethod(t,e){let i=this.getUmlById(t);if(!i)return;let n=i.methods.filter(r=>r.id!==e);i.type==="uml-class"?this.updateUmlClass(t,{methods:n}):this.updateUmlInterface(t,{methods:n});}reorderUmlAttribute(t,e,i){let n=this.shapes.find(o=>o.id===t);if(!n||n.type!=="uml-class"||e===i)return;let r=[...n.attributes];if(e<0||e>=r.length||i<0||i>=r.length)return;let[s]=r.splice(e,1);r.splice(i,0,s),this.updateUmlClass(t,{attributes:r});}reorderUmlMethod(t,e,i){let n=this.getUmlById(t);if(!n||e===i)return;let r=[...n.methods];if(e<0||e>=r.length||i<0||i>=r.length)return;let[s]=r.splice(e,1);r.splice(i,0,s),n.type==="uml-class"?this.updateUmlClass(t,{methods:r}):this.updateUmlInterface(t,{methods:r});}updateUmlRowStyle(t,e,i,n){let r=this.getUmlById(t);if(r)if(e==="attribute"){if(r.type!=="uml-class")return;let s=r.attributes.map(o=>o.id===i?{...o,textColor:n.textColor===null?void 0:n.textColor??o.textColor,fontSize:n.fontSize===null?void 0:n.fontSize??o.fontSize,strikethrough:n.strikethrough===null?void 0:n.strikethrough??o.strikethrough}:o);this.updateUmlClass(t,{attributes:s});}else {let s=r.methods.map(o=>o.id===i?{...o,textColor:n.textColor===null?void 0:n.textColor??o.textColor,fontSize:n.fontSize===null?void 0:n.fontSize??o.fontSize,strikethrough:n.strikethrough===null?void 0:n.strikethrough??o.strikethrough}:o);r.type==="uml-class"?this.updateUmlClass(t,{methods:s}):this.updateUmlInterface(t,{methods:s});}}getUmlRowAtScreenPoint(t){let e=this.camera.screenToPage(t);for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(n.type!=="uml-class"&&n.type!=="uml-interface")continue;let r=n.width/2,s=n.height/2;if(e.x<n.x-r||e.x>n.x+r||e.y<n.y-s||e.y>n.y+s)continue;let o=K,h=e.y-n.y;if(h>=-s&&h<=-s+o)return {shape:n,section:"className",rowIndex:-1,text:n.className};if(n.type==="uml-interface"){let p=-s+o,y=s;if(n.methods.length>0&&h>=p&&h<=y){let f=Math.floor((h-p-D)/L);if(f>=0&&f<n.methods.length){let M=n.methods[f];return {shape:n,section:"method",rowIndex:f,text:`${M.visibility} ${M.name}(${M.params}): ${M.returnType}`}}return {shape:n,section:"method",rowIndex:-1,text:""}}return {shape:n,section:"className",rowIndex:-1,text:n.className}}let l=n.attributes.length>0?n.attributes.length*L+D*2:D*2,d=-s+o,u=d+l;if(n.attributes.length>0&&h>=d&&h<=u){let p=Math.floor((h-d-D)/L);if(p>=0&&p<n.attributes.length){let y=n.attributes[p];return {shape:n,section:"attribute",rowIndex:p,text:`${y.visibility} ${y.name}: ${y.type}`}}return {shape:n,section:"attribute",rowIndex:-1,text:""}}let c=u,g=s;if(n.methods.length>0&&h>=c&&h<=g){let p=Math.floor((h-c-D)/L);if(p>=0&&p<n.methods.length){let y=n.methods[p];return {shape:n,section:"method",rowIndex:p,text:`${y.visibility} ${y.name}(${y.params}): ${y.returnType}`}}return {shape:n,section:"method",rowIndex:-1,text:""}}return {shape:n,section:"className",rowIndex:-1,text:n.className}}return null}setActiveTool(t){this.tools.has(t)&&(this.activeTool=t,this.eraserPoint=null,this.notifyListeners());}getActiveTool(){return this.activeTool}getShapes(){return [...this.shapes]}getData(){return {shapes:this.getShapes(),camera:{x:this.camera.x,y:this.camera.y,zoom:this.camera.zoom}}}setShapes(t){return Array.isArray(t)?(this.shapes=t.map(e=>({...e,style:{...e.style}})),this.selectedIds=[],this.undoStack=[],this.redoStack=[],this.notifyListeners(),this.render(),true):false}setTheme(t){bt(t),this.scheduleRender();}setLanguage(t){vt(t);}getSelectedIds(){return [...this.selectedIds]}getCamera(){return this.camera}isPointerDown(){return this.pointerIsDown}getContentBounds(t=24){return xt(this.shapes,t)}async exportImage(t,e={}){return zt(this.getShapes(),t,e)}async downloadImage(t="drawui",e="png",i={}){let n=await this.exportImage(e,i);Ot(n,`${t}.${e}`);}zoomIn(){this.camera.zoomAt({x:window.innerWidth/2,y:window.innerHeight/2},1.2),this.scheduleRender(),this.notifyListeners();}zoomOut(){this.camera.zoomAt({x:window.innerWidth/2,y:window.innerHeight/2},.8),this.scheduleRender(),this.notifyListeners();}resetZoom(){this.camera.reset(),this.scheduleRender(),this.notifyListeners();}panBy(t,e){this.camera.translate(t,e),this.scheduleRender(),this.notifyListeners();}setCameraPosition(t,e){this.camera.x=t,this.camera.y=e,this.scheduleRender(),this.notifyListeners();}requestRender(){this.scheduleRender(),this.notifyListeners();}setShowGrid(t){this.renderer.setShowGrid(t),this.scheduleRender();}render(){this.renderer.render(this.shapes,this.camera,new Set(this.selectedIds),this.brushRect,this.snapGuides,this.connectingTargetId,this.genPreview,this.eraserPoint,this.mindMapSelectedNode,this.mindMapHoverNode);}scheduleRender(){this.renderScheduled||(this.renderScheduled=true,requestAnimationFrame(()=>{this.renderScheduled=false,this.render();}));}subscribe(t){return this.listeners.add(t),()=>this.listeners.delete(t)}subscribeNotifications(t){return this.notificationListeners.add(t),()=>this.notificationListeners.delete(t)}notify(t){this.notificationListeners.forEach(e=>e(t));}notifyListeners(){this.notifyScheduled||(this.notifyScheduled=true,queueMicrotask(()=>{this.notifyScheduled=false,this.mindMapEditingShapeId&&!this.selectedIds.includes(this.mindMapEditingShapeId)&&(this.mindMapEditingShapeId=null,this.mindMapSelectedNode=null),this.listeners.forEach(t=>t());}));}cloneShapes(t){return t.map(e=>{let i={...e,style:{...e.style}};return Array.isArray(e.points)&&(i.points=e.points.map(n=>({...n}))),e.startBinding&&(i.startBinding={...e.startBinding}),e.endBinding&&(i.endBinding={...e.endBinding}),e.root&&(i.root=Pt(e.root)),i})}commitHistory(){if(this.isUndoing)return;let t={shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]};this.undoStack.push(t),this.undoStack.length>Ge&&this.undoStack.shift(),this.redoStack=[];}mark(){this.commitHistory();}undo(){if(this.undoStack.length!==0){this.isUndoing=true;try{this.redoStack.push({shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]});let t=this.undoStack.pop();this.shapes=this.cloneShapes(t.shapes),this.selectedIds=[...t.selectedIds];}finally{this.isUndoing=false;}this.notifyListeners(),this.render();}}redo(){if(this.redoStack.length!==0){this.isUndoing=true;try{this.undoStack.push({shapes:this.cloneShapes(this.shapes),selectedIds:[...this.selectedIds]});let t=this.redoStack.pop();this.shapes=this.cloneShapes(t.shapes),this.selectedIds=[...t.selectedIds];}finally{this.isUndoing=false;}this.notifyListeners(),this.render();}}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}saveToStorage(){if(!this.persist)return false;try{let t=JSON.stringify({version:1,shapes:this.shapes,savedAt:Date.now()});return localStorage.setItem(Xt,t),this.notifyListeners(),this.notify(W("save.success")),!0}catch(t){return console.error("\u4FDD\u5B58\u5931\u8D25:",t),this.notify(W("save.fail")),false}}loadFromStorage(){if(!this.persist)return false;try{let t=localStorage.getItem(Xt);if(!t)return !1;let e=JSON.parse(t);return e.shapes&&Array.isArray(e.shapes)?(this.shapes=e.shapes,this.selectedIds=[],this.undoStack=[],this.redoStack=[],this.notifyListeners(),this.scheduleRender(),!0):!1}catch(t){return console.error("\u52A0\u8F7D\u5931\u8D25:",t),false}}clearStorage(){localStorage.removeItem(Xt);}exportJSON(){return JSON.stringify({version:1,shapes:this.shapes,savedAt:Date.now()},null,2)}importJSON(t){try{let e=JSON.parse(t);return e.shapes&&Array.isArray(e.shapes)?(this.commitHistory(),this.shapes=e.shapes,this.selectedIds=[],this.notifyListeners(),this.render(),!0):!1}catch(e){return console.error("\u5BFC\u5165\u5931\u8D25:",e),false}}getEditingShapeId(){return this.editingShapeId}canEditShape(t){return !(t.type==="line"||t.type==="arrow"||t.type==="draw"||t.type==="uml-class"||t.type==="uml-interface"||t.type==="mind-map")}enterEditing(t){let e=this.shapes.find(i=>i.id===t);!e||!this.canEditShape(e)||(this.editingShapeId=t,this.selectedIds=[t],this.isNewTextShape=e.type==="text"&&!e.text,this.originalTextValue=e.text||"",this.notifyListeners(),this.scheduleRender(),requestAnimationFrame(()=>{this.createTextInput(e);}));}exitEditing(){if(!this.editingShapeId)return;let t=this.editingShapeId,e=this.shapes.find(n=>n.id===t),i=this.textInput?this.textInput.value:"";if(this.removeTextInput(),e)if(e.type==="text")if(this.commitHistory(),!i.trim()&&this.isNewTextShape)this.shapes=this.shapes.filter(n=>n.id!==t),this.selectedIds=this.selectedIds.filter(n=>n!==t);else {let n=e,r=n.fontSize||16,s=r*1.3,o=n.width||200,h=i.split(`
42
+ `),l=0;for(let c of h){let g="";for(let p of c){let y=g+p;y.length*r*.6>o&&g?(l++,g=p):g=y;}g&&l++;}let d={...n,text:i,height:Math.max(l*s,s)},u=this.shapes.indexOf(e);u!==-1&&(this.shapes[u]=d),i.trim()||(this.shapes=this.shapes.filter(c=>c.id!==t),this.selectedIds=this.selectedIds.filter(c=>c!==t));}else this.commitHistory(),this.updateShape(t,{text:i,textColor:e.textColor||I.text,fontSize:e.fontSize||16});this.editingShapeId=null,this.isNewTextShape=false,this.originalTextValue="",this.setActiveTool("select"),this.notifyListeners(),this.render();}removeTextInput(){this.textOverlay&&(this.textOverlay.remove(),this.textOverlay=null),this.textInput&&(this.textInput.remove(),this.textInput=null);}createTextInput(t){this.removeTextInput();let e=this.canvas.parentElement;if(!e)return;let i=this.canvas.getBoundingClientRect(),n=e.getBoundingClientRect(),r=i.left-n.left,s=i.top-n.top;this.textOverlay=document.createElement("div"),this.textOverlay.style.position="absolute",this.textOverlay.style.left=`${r}px`,this.textOverlay.style.top=`${s}px`,this.textOverlay.style.width=`${i.width}px`,this.textOverlay.style.height=`${i.height}px`,this.textOverlay.style.background="transparent",this.textOverlay.style.zIndex="1000",this.textOverlay.style.cursor="text",this.textOverlay.addEventListener("pointerdown",u=>{this.textInput&&u.target!==this.textInput&&(u.preventDefault(),this.exitEditing());}),e.appendChild(this.textOverlay);let o=this.getShapeScreenBounds(t),h=this.camera.getZoom(),l=(t.fontSize||16)*h,d=document.createElement("textarea");d.style.position="absolute",d.style.left=`${r+o.x}px`,d.style.top=`${s+o.y}px`,d.style.width=`${Math.max(o.width,60)}px`,d.style.height=`${Math.max(o.height,24)}px`,d.style.fontSize=`${l}px`,d.style.color=t.textColor||"#1f2937",d.style.textAlign="center",d.style.border=`2px solid ${I.editBorder}`,d.style.borderRadius="4px",d.style.background="rgba(255, 255, 255, 0.95)",d.style.resize="none",d.style.padding="4px 8px",d.style.boxSizing="border-box",d.style.lineHeight="1.4",d.style.fontFamily="sans-serif",d.style.outline="none",d.style.whiteSpace="pre-wrap",d.style.wordBreak="break-word",d.style.overflow="hidden",d.style.zIndex="1001",d.value=t.text||"",d.dataset.shapeId=t.id,d.addEventListener("pointerdown",u=>{u.stopPropagation();}),d.addEventListener("mousedown",u=>{u.stopPropagation();}),d.addEventListener("keydown",u=>{if(u.stopPropagation(),u.key==="Escape"&&(u.preventDefault(),this.textInput&&(this.textInput.value=this.originalTextValue),this.exitEditing()),u.key==="Enter"&&!u.shiftKey&&(u.preventDefault(),this.exitEditing()),u.key==="Enter"&&u.shiftKey){u.preventDefault();let c=d.selectionStart,g=d.selectionEnd;d.value=d.value.substring(0,c)+`
43
+ `+d.value.substring(g),d.selectionStart=d.selectionEnd=c+1;}}),e.appendChild(d),d.focus(),t.type==="text"&&!t.text&&(d.placeholder="\u8F93\u5165\u6587\u672C..."),this.textInput=d;}getShapeScreenBounds(t){let e=this.camera.getZoom(),i=this.camera.pageToScreen({x:t.x,y:t.y});switch(t.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "hexagon":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":return {x:i.x-t.width*e/2,y:i.y-t.height*e/2,width:t.width*e,height:t.height*e};case "circle":return {x:i.x-t.radius*e,y:i.y-t.radius*e,width:t.radius*2*e,height:t.radius*2*e};case "text":{let n=t,r=n.width*e,s=n.height*e;return {x:i.x-r/2,y:i.y-s/2,width:r,height:s}}default:return {x:i.x-50*e,y:i.y-20*e,width:100*e,height:40*e}}}getShapeAtScreenPoint(t){let e=this.screenToPage(t);return this.getShapeAtPoint(e)}getShapeAtPoint(t,e){for(let i=this.shapes.length-1;i>=0;i--){let n=this.shapes[i];if(!(e&&n.id===e)&&this.isPointInShape(t,n))return n}return null}getShapesInBrushRadius(t,e){let i=[];for(let n of this.shapes)this.shapeIntersectsBrush(n,t,e)&&i.push(n);return i}shapeIntersectsBrush(t,e,i){switch(t.type){case "line":case "arrow":case "draw":{let n=t.points,r=i+4;for(let s=1;s<n.length;s++)if(this.pointToSegmentDist(e,n[s-1],n[s])<=r)return true;return n.length>0&&Math.hypot(e.x-n[0].x,e.y-n[0].y)<=r}case "circle":return Math.hypot(e.x-t.x,e.y-t.y)<=t.radius+i;case "text":{let n=t;return Math.abs(e.x-t.x)<=n.width/2+i&&Math.abs(e.y-t.y)<=n.height/2+i}default:return Math.abs(e.x-t.x)<=t.width/2+i&&Math.abs(e.y-t.y)<=t.height/2+i}}pointToSegmentDist(t,e,i){let n=i.x-e.x,r=i.y-e.y,s=n*n+r*r,o=s===0?0:Math.max(0,Math.min(1,((t.x-e.x)*n+(t.y-e.y)*r)/s));return Math.hypot(t.x-(e.x+o*n),t.y-(e.y+o*r))}setEraserPoint(t){this.eraserPoint=t,this.scheduleRender();}isPointInShape(t,e){let i=t.x-e.x,n=t.y-e.y;switch(e.type){case "rectangle":case "rounded-rectangle":case "ellipse":case "diamond":case "triangle":case "parallelogram":case "trapezoid":case "pentagon":case "octagon":case "star":case "uml-class":case "uml-interface":return Math.abs(i)<=e.width/2&&Math.abs(n)<=e.height/2;case "circle":return i*i+n*n<=e.radius*e.radius;case "hexagon":{let r=e.width/2,s=e.height/2;return Math.abs(i)<=r&&Math.abs(n)<=s&&Math.abs(i)/r+Math.abs(n)/s<=1.5}case "mind-map":return Math.abs(i)<=e.width/2&&Math.abs(n)<=e.height/2;case "text":{let r=e;return Math.abs(i)<=r.width/2&&Math.abs(n)<=r.height/2}default:return false}}updateArrowBinding(t,e,i,n){let r=this.shapes.find(h=>h.id===t);if(!r||r.type!=="arrow")return;let s=r,o={};if(i){let h=this.shapes.find(c=>c.id===i);if(!h)return;let l=n?.handle||this.getClosestHandle(s,h),d=this.getBindingPosition(h,l),u=n?{...n,toShapeId:i}:{toShapeId:i,handle:l};e==="start"?(o.startBinding=u,o.points=s.points.map((c,g)=>g===0?d:c)):(o.endBinding=u,o.points=s.points.map((c,g)=>g===s.points.length-1?d:c));}else e==="start"?o.startBinding=void 0:o.endBinding=void 0;this.updateShape(t,o);}getClosestHandle(t,e){let i=t.points[0],n=t.points[t.points.length-1],r=t.endBinding?n:i,s=r.x-e.x,o=r.y-e.y;return Math.abs(s)>Math.abs(o)?s>0?"right":"left":o>0?"bottom":"top"}dispose(){this.canvas.removeEventListener("pointerdown",this.handlePointerDown),this.canvas.removeEventListener("pointermove",this.handlePointerMove),this.canvas.removeEventListener("pointerup",this.handlePointerUp),this.canvas.removeEventListener("pointerleave",this.handlePointerUp),this.canvas.removeEventListener("wheel",this.handleWheel),window.removeEventListener("keydown",this.handleKeyDown),window.removeEventListener("keyup",this.handleKeyUp),window.removeEventListener("resize",this.handleResize),this.removeTextInput(),this.tools.forEach(t=>t.dispose()),this.listeners.clear();}};exports.ArrowTool=pt;exports.Camera=et;exports.Editor=Yt;exports.FreehandTool=at;exports.HandTool=ut;exports.LineTool=gt;exports.MINDMAP_COLORS=Nt;exports.MINDMAP_FONT_SIZE=Z;exports.MINDMAP_MAX_WIDTH=me;exports.MINDMAP_MIN_WIDTH=fe;exports.MINDMAP_NODE_HEIGHT=ye;exports.Mat2d=j;exports.Renderer=st;exports.SelectTool=ct;exports.ShapeTool=V;exports.THEME=I;exports.UML_FONT_SIZE=_;exports.UML_HEADER_HEIGHT=K;exports.UML_LINE_HEIGHT=L;exports.UML_MIN_WIDTH=dt;exports.UML_PADDING_X=B;exports.UML_PADDING_Y=D;exports.Vec=rt;exports.calcUmlClassSize=Ct;exports.cloneMindMapNode=Pt;exports.countMindMapNodes=qt;exports.downloadBlob=Ot;exports.exportToBlob=zt;exports.findMindMapNode=q;exports.getContentBounds=xt;exports.getLanguage=ge;exports.getMindMapNodeDepth=Zt;exports.getMindMapParent=lt;exports.getTheme=ce;exports.hexToRgba=nt;exports.layoutMindMap=k;exports.mindMapNodeColor=it;exports.mindMapNodeSize=jt;exports.renderSVGString=he;exports.renderToCanvas=re;exports.setLanguage=vt;exports.setTheme=bt;exports.shadeColor=ue;exports.subscribeLanguage=pe;exports.subscribeTheme=de;exports.t=W;