@elixpo/lixsketch 5.5.14 → 5.5.16

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.
Files changed (32) hide show
  1. package/dist/react/{AIRenderer-ATIKGFB4.js → AIRenderer-HI7TYROT.js} +2 -2
  2. package/dist/react/Arrow-EF7ALH2Y.js +8 -0
  3. package/dist/react/{CopyPaste-UTU5MPKY.js → CopyPaste-AAHQTNVL.js} +4 -4
  4. package/dist/react/{Frame-6UR5XPAX.js → Frame-WPQZQLNT.js} +2 -2
  5. package/dist/react/{MermaidStructuredRenderer-26WGA6YD.js → MermaidStructuredRenderer-H42SKKN2.js} +28 -9
  6. package/dist/react/{MermaidStructuredRenderer-26WGA6YD.js.map → MermaidStructuredRenderer-H42SKKN2.js.map} +2 -2
  7. package/dist/react/Rectangle-2LNCIQDZ.js +8 -0
  8. package/dist/react/{SceneSerializer-34VQFJN7.js → SceneSerializer-YK44QZ6B.js} +4 -4
  9. package/dist/react/{SketchEngine-P3XNZA56.js → SketchEngine-B7XCB3BS.js} +7 -7
  10. package/dist/react/{chunk-Z4YVT54E.js → chunk-24TW3M7X.js} +11 -1
  11. package/dist/react/chunk-24TW3M7X.js.map +7 -0
  12. package/dist/react/{chunk-BU4D2WYQ.js → chunk-2AYTBFV5.js} +19 -1
  13. package/dist/react/{chunk-BU4D2WYQ.js.map → chunk-2AYTBFV5.js.map} +2 -2
  14. package/dist/react/{chunk-XISEAGBV.js → chunk-BT2EIJD4.js} +24 -5
  15. package/dist/react/chunk-BT2EIJD4.js.map +7 -0
  16. package/dist/react/index.js +2 -2
  17. package/package.json +1 -1
  18. package/src/core/MermaidStructuredRenderer.js +33 -9
  19. package/src/shapes/Arrow.js +27 -5
  20. package/src/shapes/Frame.js +22 -0
  21. package/src/shapes/Rectangle.js +14 -1
  22. package/dist/react/Arrow-BJDAXPMH.js +0 -8
  23. package/dist/react/Rectangle-2F7BAXG4.js +0 -8
  24. package/dist/react/chunk-XISEAGBV.js.map +0 -7
  25. package/dist/react/chunk-Z4YVT54E.js.map +0 -7
  26. /package/dist/react/{AIRenderer-ATIKGFB4.js.map → AIRenderer-HI7TYROT.js.map} +0 -0
  27. /package/dist/react/{Arrow-BJDAXPMH.js.map → Arrow-EF7ALH2Y.js.map} +0 -0
  28. /package/dist/react/{CopyPaste-UTU5MPKY.js.map → CopyPaste-AAHQTNVL.js.map} +0 -0
  29. /package/dist/react/{Frame-6UR5XPAX.js.map → Frame-WPQZQLNT.js.map} +0 -0
  30. /package/dist/react/{Rectangle-2F7BAXG4.js.map → Rectangle-2LNCIQDZ.js.map} +0 -0
  31. /package/dist/react/{SceneSerializer-34VQFJN7.js.map → SceneSerializer-YK44QZ6B.js.map} +0 -0
  32. /package/dist/react/{SketchEngine-P3XNZA56.js.map → SketchEngine-B7XCB3BS.js.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shapes/Arrow.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n// Arrow shape class - extracted from drawArrow.js\n// Depends on globals: svg, shapes, rough, currentShape, currentZoom\n\nlet isDragging = false;\nlet hoveredFrameArrow = null;\nlet dragOldPosArrow = null;\n\nfunction getSVGCoordsFromMouse(e) {\n const viewBox = svg.viewBox.baseVal;\n const rect = svg.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n const svgX = viewBox.x + (mouseX / rect.width) * viewBox.width;\n const svgY = viewBox.y + (mouseY / rect.height) * viewBox.height;\n return { x: svgX, y: svgY };\n}\n\nclass Arrow {\n constructor(startPoint, endPoint, options = {}) {\n this.startPoint = startPoint;\n this.endPoint = endPoint;\n this.options = {\n stroke: options.stroke || \"#fff\",\n strokeWidth: options.strokeWidth || 2,\n strokeDasharray: options.arrowOutlineStyle === \"dashed\" ? \"10,10\" : (options.arrowOutlineStyle === \"dotted\" ? \"2,8\" : \"\"),\n fill: 'none',\n ...options\n };\n this.arrowOutlineStyle = options.arrowOutlineStyle || \"solid\";\n this.arrowHeadStyle = options.arrowHeadStyle || \"default\";\n this.arrowHeadLength = parseFloat(options.arrowHeadLength || 15);\n this.arrowHeadAngleDeg = parseFloat(options.arrowHeadAngleDeg || 30);\n this.arrowCurved = options.arrowCurved !== undefined ? options.arrowCurved : \"straight\";\n this.arrowCurveAmount = options.arrowCurveAmount || 50;\n\n // Control points for curved arrows\n this.controlPoint1 = options.controlPoint1 || null;\n this.controlPoint2 = options.controlPoint2 || null;\n\n\n this.attachedToStart = null;\n this.attachedToEnd = null;\n this.parentFrame = null;\n this.element = null;\n this.elbowX = options.elbowX !== undefined ? options.elbowX : null;\n this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.isSelected = false;\n this.anchors = [];\n this.shapeName = \"arrow\";\n this.shapeID = `arrow-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n this.group.setAttribute('id', this.shapeID);\n\n // Embedded label support\n this.label = options.label || '';\n this.labelElement = null;\n this.labelColor = options.labelColor || '#e0e0e0';\n this.labelFontSize = options.labelFontSize || 12;\n this.labelBg = options.labelBg !== false; // labelBg:false \u2192 no knockout rect behind label\n this.labelOffsetY = options.labelOffsetY || 0; // shift label along the perpendicular of the line, e.g. lift it clear of the stroke\n this._isEditingLabel = false;\n this._hitArea = null;\n this._labelBg = null;\n\n // Initialize control points if curved\n if (this.arrowCurved === \"curved\" && !this.controlPoint1 && !this.controlPoint2) {\n this.initializeCurveControlPoints();\n }\n\n svg.appendChild(this.group);\n this._setupLabelDblClick();\n this.draw();\n }\n\n get x() {\n return Math.min(this.startPoint.x, this.endPoint.x);\n }\n\n set x(value) {\n const currentX = this.x;\n const dx = value - currentX;\n this.startPoint.x += dx;\n this.endPoint.x += dx;\n if (this.controlPoint1) this.controlPoint1.x += dx;\n if (this.controlPoint2) this.controlPoint2.x += dx;\n }\n\n get y() {\n return Math.min(this.startPoint.y, this.endPoint.y);\n }\n\n set y(value) {\n const currentY = this.y;\n const dy = value - currentY;\n this.startPoint.y += dy;\n this.endPoint.y += dy;\n if (this.controlPoint1) this.controlPoint1.y += dy;\n if (this.controlPoint2) this.controlPoint2.y += dy;\n }\n\n get width() {\n return Math.abs(this.endPoint.x - this.startPoint.x);\n }\n\n set width(value) {\n const centerX = (this.startPoint.x + this.endPoint.x) / 2;\n const halfWidth = value / 2;\n this.startPoint.x = centerX - halfWidth;\n this.endPoint.x = centerX + halfWidth;\n }\n\n get height() {\n return Math.abs(this.endPoint.y - this.startPoint.y);\n }\n\n set height(value) {\n const centerY = (this.startPoint.y + this.endPoint.y) / 2;\n const halfHeight = value / 2;\n this.startPoint.y = centerY - halfHeight;\n this.endPoint.y = centerY + halfHeight;\n }\n\n initializeCurveControlPoints() {\n const dx = this.endPoint.x - this.startPoint.x;\n const dy = this.endPoint.y - this.startPoint.y;\n const distance = Math.sqrt(dx * dx + dy * dy);\n\n if (distance === 0 || isNaN(distance)) {\n this.controlPoint1 = { x: this.startPoint.x + 20, y: this.startPoint.y };\n this.controlPoint2 = { x: this.endPoint.x - 20, y: this.endPoint.y };\n return;\n }\n\n const perpX = -dy / distance;\n const perpY = dx / distance;\n const curveOffset = this.arrowCurveAmount;\n\n const t1 = 0.33;\n const point1X = this.startPoint.x + t1 * dx;\n const point1Y = this.startPoint.y + t1 * dy;\n this.controlPoint1 = {\n x: point1X + perpX * curveOffset,\n y: point1Y + perpY * curveOffset\n };\n\n const t2 = 0.67;\n const point2X = this.startPoint.x + t2 * dx;\n const point2Y = this.startPoint.y + t2 * dy;\n this.controlPoint2 = {\n x: point2X - perpX * curveOffset,\n y: point2Y - perpY * curveOffset\n };\n }\n\n _buildElbowPath(elbowX, shortenEnd) {\n const x1 = this.startPoint.x, y1 = this.startPoint.y;\n const x2 = this.endPoint.x, y2 = this.endPoint.y;\n const r = Math.min(\n Math.abs(this.arrowCurveAmount),\n Math.abs(elbowX - x1) / 2,\n Math.abs(x2 - elbowX) / 2,\n Math.abs(y2 - y1) / 2\n );\n const dx = elbowX >= x1 ? 1 : -1;\n const ex = x2 >= elbowX ? 1 : -1;\n const dy = y2 >= y1 ? 1 : -1;\n let endX = x2;\n if (shortenEnd) {\n endX = x2 - ex * (this.arrowHeadLength * 0.3);\n }\n if (r > 2 && Math.abs(elbowX - x1) > r * 2 && Math.abs(x2 - elbowX) > r * 2 && Math.abs(y2 - y1) > r * 2) {\n return `M ${x1} ${y1}` +\n ` H ${elbowX - dx * r}` +\n ` Q ${elbowX} ${y1} ${elbowX} ${y1 + dy * r}` +\n ` V ${y2 - dy * r}` +\n ` Q ${elbowX} ${y2} ${elbowX + ex * r} ${y2}` +\n ` H ${endX}`;\n }\n return `M ${x1} ${y1} H ${elbowX} V ${y2} H ${endX}`;\n }\n\n selectArrow() {\n this.isSelected = true;\n disableAllSideBars();\n arrowSideBar.classList.remove(\"hidden\");\n if (window.__showSidebarForShape) window.__showSidebarForShape('arrow');\n this.updateSidebar();\n this.draw();\n }\n\n removeSelection() {\n this.anchors.forEach(anchor => {\n if (anchor.parentNode === this.group) {\n this.group.removeChild(anchor);\n }\n });\n this.anchors = [];\n this.isSelected = false;\n }\n\n attachToShape(isStartPoint, shape, attachment) {\n if (isStartPoint) {\n this.attachedToStart = {\n shape: shape,\n side: attachment.side,\n offset: attachment.offset\n };\n this.startPoint = attachment.point;\n } else {\n this.attachedToEnd = {\n shape: shape,\n side: attachment.side,\n offset: attachment.offset\n };\n this.endPoint = attachment.point;\n }\n\n // Update control points if curved\n if (this.arrowCurved === \"curved\") {\n this.initializeCurveControlPoints();\n }\n\n this.draw();\n }\n\n draw() {\n // Clean up existing arrowhead element before redraw\n if (this._arrowHeadEl) {\n this._arrowHeadEl.remove();\n this._arrowHeadEl = null;\n }\n\n const childrenToRemove = [];\n const anchorSet = this._skipAnchors ? new Set(this.anchors) : null;\n for (let i = 0; i < this.group.children.length; i++) {\n const child = this.group.children[i];\n if (child !== this.labelElement && child !== this._hitArea && child !== this._labelBg) {\n if (anchorSet && anchorSet.has(child)) continue;\n childrenToRemove.push(child);\n }\n }\n childrenToRemove.forEach(child => this.group.removeChild(child));\n if (!this._skipAnchors) this.anchors = [];\n\n let pathData;\n let arrowEndPoint = this.endPoint;\n\n const elbowX = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n if (isNaN(this.controlPoint1.x) || isNaN(this.controlPoint1.y) ||\n isNaN(this.controlPoint2.x) || isNaN(this.controlPoint2.y)) {\n this.initializeCurveControlPoints();\n }\n\n pathData = `M ${this.startPoint.x} ${this.startPoint.y} ` +\n `C ${this.controlPoint1.x} ${this.controlPoint1.y}, ` +\n `${this.controlPoint2.x} ${this.controlPoint2.y}, ` +\n `${this.endPoint.x} ${this.endPoint.y}`;\n\n // Shorten curve endpoint so arrowhead sits cleanly at the tip\n const t = 0.95;\n const tangent = this.getCubicBezierTangent(t);\n const curveAngle = Math.atan2(tangent.y, tangent.x);\n\n if (this.arrowHeadStyle && this.arrowHeadStyle !== 'none') {\n arrowEndPoint = {\n x: this.endPoint.x - (this.arrowHeadLength * 0.3) * Math.cos(curveAngle),\n y: this.endPoint.y - (this.arrowHeadLength * 0.3) * Math.sin(curveAngle)\n };\n\n pathData = `M ${this.startPoint.x} ${this.startPoint.y} ` +\n `C ${this.controlPoint1.x} ${this.controlPoint1.y}, ` +\n `${this.controlPoint2.x} ${this.controlPoint2.y}, ` +\n `${arrowEndPoint.x} ${arrowEndPoint.y}`;\n }\n } else if (this.arrowCurved === \"elbow\") {\n pathData = this._buildElbowPath(elbowX, false);\n } else {\n pathData = `M ${this.startPoint.x} ${this.startPoint.y} L ${this.endPoint.x} ${this.endPoint.y}`;\n }\n\n // Render arrowhead\n const headAngle = this._getArrowAngle(elbowX);\n if (this.arrowHeadStyle === \"default\") {\n const pts = this._getArrowHeadPoints(headAngle);\n pathData += ` M ${pts.x3} ${pts.y3} L ${this.endPoint.x} ${this.endPoint.y} L ${pts.x4} ${pts.y4}`;\n } else {\n this._renderArrowHead(headAngle);\n }\n\n const arrowPath = document.createElementNS(\"http://www.w3.org/2000/svg\", \"path\");\n arrowPath.setAttribute(\"d\", pathData);\n arrowPath.setAttribute(\"stroke\", this.options.stroke);\n arrowPath.setAttribute(\"stroke-width\", this.options.strokeWidth);\n arrowPath.setAttribute(\"fill\", this.options.fill);\n\n if (this.options.strokeDasharray) {\n arrowPath.setAttribute(\"stroke-dasharray\", this.options.strokeDasharray);\n } else {\n arrowPath.removeAttribute(\"stroke-dasharray\");\n }\n\n arrowPath.setAttribute(\"stroke-linecap\", \"round\");\n arrowPath.setAttribute(\"stroke-linejoin\", \"round\");\n arrowPath.classList.add(\"arrow-path\");\n\n this.element = arrowPath;\n this.group.appendChild(this.element);\n\n // Hit area - thicker invisible path for dblclick detection\n {\n let hitPathData;\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n hitPathData = `M ${this.startPoint.x} ${this.startPoint.y} C ${this.controlPoint1.x} ${this.controlPoint1.y}, ${this.controlPoint2.x} ${this.controlPoint2.y}, ${this.endPoint.x} ${this.endPoint.y}`;\n } else if (this.arrowCurved === \"elbow\") {\n const ex = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n hitPathData = `M ${this.startPoint.x} ${this.startPoint.y} L ${ex} ${this.startPoint.y} L ${ex} ${this.endPoint.y} L ${this.endPoint.x} ${this.endPoint.y}`;\n } else {\n hitPathData = `M ${this.startPoint.x} ${this.startPoint.y} L ${this.endPoint.x} ${this.endPoint.y}`;\n }\n if (!this._hitArea) {\n this._hitArea = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n this._hitArea.setAttribute('fill', 'none');\n this._hitArea.setAttribute('stroke', 'transparent');\n this._hitArea.setAttribute('stroke-width', '20');\n this._hitArea.setAttribute('style', 'pointer-events: stroke;');\n this.group.appendChild(this._hitArea);\n }\n this._hitArea.setAttribute('d', hitPathData);\n }\n\n // Update embedded label at midpoint\n this._updateLabelElement();\n\n if (this.isSelected) {\n if (this._skipAnchors) {\n this.updateSelectionControls();\n } else {\n this.addAnchors();\n this.addAttachmentIndicators();\n }\n }\n }\n\n _buildFullPathData() {\n let pathData;\n const elbowX = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n if (isNaN(this.controlPoint1.x) || isNaN(this.controlPoint1.y) ||\n isNaN(this.controlPoint2.x) || isNaN(this.controlPoint2.y)) {\n this.initializeCurveControlPoints();\n }\n pathData = `M ${this.startPoint.x} ${this.startPoint.y} ` +\n `C ${this.controlPoint1.x} ${this.controlPoint1.y}, ` +\n `${this.controlPoint2.x} ${this.controlPoint2.y}, ` +\n `${this.endPoint.x} ${this.endPoint.y}`;\n\n if (this.arrowHeadStyle && this.arrowHeadStyle !== 'none') {\n const t = 0.95;\n const tangent = this.getCubicBezierTangent(t);\n const angle = Math.atan2(tangent.y, tangent.x);\n const arrowEndPoint = {\n x: this.endPoint.x - (this.arrowHeadLength * 0.3) * Math.cos(angle),\n y: this.endPoint.y - (this.arrowHeadLength * 0.3) * Math.sin(angle)\n };\n pathData = `M ${this.startPoint.x} ${this.startPoint.y} ` +\n `C ${this.controlPoint1.x} ${this.controlPoint1.y}, ` +\n `${this.controlPoint2.x} ${this.controlPoint2.y}, ` +\n `${arrowEndPoint.x} ${arrowEndPoint.y}`;\n }\n } else if (this.arrowCurved === \"elbow\") {\n pathData = this._buildElbowPath(elbowX, false);\n } else {\n pathData = `M ${this.startPoint.x} ${this.startPoint.y} L ${this.endPoint.x} ${this.endPoint.y}`;\n }\n\n // Only include arrowhead in path string for default style\n if (this.arrowHeadStyle === \"default\") {\n const angle = this._getArrowAngle(elbowX);\n const pts = this._getArrowHeadPoints(angle);\n pathData += ` M ${pts.x3} ${pts.y3} L ${this.endPoint.x} ${this.endPoint.y} L ${pts.x4} ${pts.y4}`;\n }\n return pathData;\n }\n\n _updatePathElement() {\n if (!this.element) return;\n this.element.setAttribute(\"d\", this._buildFullPathData());\n this._updateArrowHead();\n }\n\n _updateHitArea() {\n if (!this._hitArea) return;\n let hitPathData;\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n hitPathData = `M ${this.startPoint.x} ${this.startPoint.y} C ${this.controlPoint1.x} ${this.controlPoint1.y}, ${this.controlPoint2.x} ${this.controlPoint2.y}, ${this.endPoint.x} ${this.endPoint.y}`;\n } else if (this.arrowCurved === \"elbow\") {\n const ex = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n hitPathData = `M ${this.startPoint.x} ${this.startPoint.y} L ${ex} ${this.startPoint.y} L ${ex} ${this.endPoint.y} L ${this.endPoint.x} ${this.endPoint.y}`;\n } else {\n hitPathData = `M ${this.startPoint.x} ${this.startPoint.y} L ${this.endPoint.x} ${this.endPoint.y}`;\n }\n this._hitArea.setAttribute('d', hitPathData);\n }\n\n _getMidpoint() {\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n const p = this.getCubicBezierPoint(0.5);\n return { x: p.x, y: p.y };\n }\n if (this.arrowCurved === \"elbow\") {\n const ex = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n return { x: ex, y: (this.startPoint.y + this.endPoint.y) / 2 };\n }\n return {\n x: (this.startPoint.x + this.endPoint.x) / 2,\n y: (this.startPoint.y + this.endPoint.y) / 2\n };\n }\n\n _updateAnchorPositions() {\n if (!this.anchors || this.anchors.length === 0) return;\n\n const anchorSize = 5 / currentZoom;\n let anchorPositions = [this.startPoint, this.endPoint];\n\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n const midOnCurve = this.getCubicBezierPoint(0.5);\n anchorPositions.push(midOnCurve);\n } else if (this.arrowCurved === \"elbow\") {\n const elbowXVal = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n const midY = (this.startPoint.y + this.endPoint.y) / 2;\n anchorPositions.push({ x: elbowXVal, y: midY });\n } else {\n // straight \u2014 offset end anchor past arrowhead\n const arrowAngle = Math.atan2(this.endPoint.y - this.startPoint.y, this.endPoint.x - this.startPoint.x);\n const arrowHeadClearance = this.arrowHeadLength + anchorSize - 10;\n anchorPositions[1] = {\n x: this.endPoint.x + arrowHeadClearance * Math.cos(arrowAngle),\n y: this.endPoint.y + arrowHeadClearance * Math.sin(arrowAngle)\n };\n }\n\n anchorPositions.forEach((point, index) => {\n if (this.anchors[index]) {\n this.anchors[index].setAttribute('cx', point.x);\n this.anchors[index].setAttribute('cy', point.y);\n }\n });\n }\n\n _updateLabelElement() {\n if (!this.label) {\n if (this.labelElement && this.labelElement.parentNode === this.group) {\n this.group.removeChild(this.labelElement);\n this.labelElement = null;\n }\n if (this._labelBg && this._labelBg.parentNode === this.group) {\n this.group.removeChild(this._labelBg);\n this._labelBg = null;\n }\n return;\n }\n\n if (!this.labelElement) {\n this.labelElement = document.createElementNS('http://www.w3.org/2000/svg', 'text');\n this.labelElement.setAttribute('class', 'shape-label');\n this.labelElement.setAttribute('pointer-events', 'none');\n }\n\n const mid = this._getMidpoint();\n let lx = mid.x, ly = mid.y;\n if (this.labelOffsetY) {\n // Offset perpendicular to the line direction so the label lifts\n // clear of the stroke instead of sitting centered on top of it.\n const dx = this.endPoint.x - this.startPoint.x;\n const dy = this.endPoint.y - this.startPoint.y;\n const len = Math.sqrt(dx * dx + dy * dy) || 1;\n lx += (-dy / len) * this.labelOffsetY;\n ly += (dx / len) * this.labelOffsetY;\n }\n this.labelElement.setAttribute('x', lx);\n this.labelElement.setAttribute('y', ly);\n this.labelElement.setAttribute('text-anchor', 'middle');\n this.labelElement.setAttribute('dominant-baseline', 'central');\n this.labelElement.setAttribute('fill', this.labelColor);\n this.labelElement.setAttribute('font-size', this.labelFontSize);\n this.labelElement.setAttribute('font-family', 'lixFont, sans-serif');\n this.labelElement.textContent = this.label;\n\n if (!this.labelBg) {\n if (this._labelBg && this._labelBg.parentNode === this.group) {\n this.group.removeChild(this._labelBg);\n this._labelBg = null;\n }\n if (this.labelElement.parentNode === this.group) this.group.removeChild(this.labelElement);\n this.group.appendChild(this.labelElement);\n return;\n }\n\n // Background knockout rect - hides the arrow behind the text\n const canvasBg = window.getComputedStyle(svg).backgroundColor || '#000';\n if (!this._labelBg) {\n this._labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');\n this._labelBg.setAttribute('pointer-events', 'none');\n }\n this._labelBg.setAttribute('fill', canvasBg);\n const hPadding = 4;\n const vPadding = 1;\n const charWidth = this.labelFontSize * 0.6;\n const bgW = this.label.length * charWidth + hPadding * 2;\n const bgH = this.labelFontSize + vPadding * 2;\n this._labelBg.setAttribute('x', lx - bgW / 2);\n this._labelBg.setAttribute('y', ly - bgH / 2);\n this._labelBg.setAttribute('width', bgW);\n this._labelBg.setAttribute('height', bgH);\n this._labelBg.setAttribute('rx', 2);\n\n // Re-append bg then text at end so they render ON TOP of the arrow path\n if (this._labelBg.parentNode === this.group) this.group.removeChild(this._labelBg);\n if (this.labelElement.parentNode === this.group) this.group.removeChild(this.labelElement);\n this.group.appendChild(this._labelBg);\n this.group.appendChild(this.labelElement);\n }\n\n _setupLabelDblClick() {\n this.group.addEventListener('dblclick', (e) => {\n e.stopPropagation();\n e.preventDefault();\n this.startLabelEdit();\n });\n }\n\n startLabelEdit() {\n if (this._isEditingLabel) return;\n this._isEditingLabel = true;\n\n if (this.labelElement) {\n this.labelElement.setAttribute('visibility', 'hidden');\n }\n if (this._labelBg) {\n this._labelBg.setAttribute('visibility', 'hidden');\n }\n\n // Get midpoint in screen coords via CTM\n const mid = this._getMidpoint();\n const ctm = this.group.getScreenCTM();\n if (!ctm) { this._isEditingLabel = false; return; }\n\n const pt = svg.createSVGPoint();\n pt.x = mid.x; pt.y = mid.y;\n const screenMid = pt.matrixTransform(ctm);\n\n const editW = 160;\n const editH = 28;\n\n // Create HTML overlay centered on the midpoint\n const overlay = document.createElement('div');\n overlay.className = 'shape-label-editor';\n overlay.style.cssText = `\n position: fixed; z-index: 10000;\n left: ${screenMid.x - editW / 2}px; top: ${screenMid.y - editH / 2}px;\n width: ${editW}px; height: ${editH}px;\n display: flex; align-items: center; justify-content: center;\n pointer-events: auto;\n `;\n\n const canvasBg = window.getComputedStyle(svg).backgroundColor || '#000';\n const input = document.createElement('div');\n input.setAttribute('contenteditable', 'true');\n input.style.cssText = `\n width: 100%; height: 100%;\n background: ${canvasBg}; border: none;\n outline: none; padding: 2px 6px;\n color: ${this.labelColor}; font-size: ${this.labelFontSize}px;\n font-family: lixFont, sans-serif; text-align: center;\n display: flex; align-items: center; justify-content: center;\n white-space: pre-wrap; word-break: break-word;\n cursor: text;\n `;\n if (this.label) {\n input.textContent = this.label;\n } else {\n input.innerHTML = '&nbsp;';\n }\n\n overlay.appendChild(input);\n document.body.appendChild(overlay);\n\n setTimeout(() => {\n input.focus();\n const sel = window.getSelection();\n const range = document.createRange();\n range.selectNodeContents(input);\n sel.removeAllRanges();\n sel.addRange(range);\n }, 10);\n\n const finishEdit = () => {\n const newText = input.textContent.trim().replace(/\\u00A0/g, '');\n this.label = newText;\n this._isEditingLabel = false;\n if (overlay.parentNode) overlay.parentNode.removeChild(overlay);\n if (this.labelElement) this.labelElement.removeAttribute('visibility');\n if (this._labelBg) this._labelBg.removeAttribute('visibility');\n this.draw();\n };\n\n input.addEventListener('blur', finishEdit);\n input.addEventListener('keydown', (e) => {\n e.stopPropagation();\n if (e.key === 'Enter' && !e.shiftKey) { e.preventDefault(); input.blur(); }\n if (e.key === 'Escape') { input.textContent = this.label; input.blur(); }\n });\n input.addEventListener('pointerdown', (e) => e.stopPropagation());\n input.addEventListener('pointermove', (e) => e.stopPropagation());\n input.addEventListener('pointerup', (e) => e.stopPropagation());\n }\n\n setLabel(text, color, fontSize) {\n this.label = text || '';\n if (color) this.labelColor = color;\n if (fontSize) this.labelFontSize = fontSize;\n this.draw();\n }\n\n getCubicBezierPoint(t) {\n if (!this.controlPoint1 || !this.controlPoint2) return this.startPoint;\n\n const mt = 1 - t;\n const mt2 = mt * mt;\n const mt3 = mt2 * mt;\n const t2 = t * t;\n const t3 = t2 * t;\n\n return {\n x: mt3 * this.startPoint.x + 3 * mt2 * t * this.controlPoint1.x +\n 3 * mt * t2 * this.controlPoint2.x + t3 * this.endPoint.x,\n y: mt3 * this.startPoint.y + 3 * mt2 * t * this.controlPoint1.y +\n 3 * mt * t2 * this.controlPoint2.y + t3 * this.endPoint.y\n };\n }\n\n getCubicBezierTangent(t) {\n if (!this.controlPoint1 || !this.controlPoint2) {\n return { x: this.endPoint.x - this.startPoint.x, y: this.endPoint.y - this.startPoint.y };\n }\n\n const mt = 1 - t;\n const mt2 = mt * mt;\n const t2 = t * t;\n\n return {\n x: 3 * mt2 * (this.controlPoint1.x - this.startPoint.x) +\n 6 * mt * t * (this.controlPoint2.x - this.controlPoint1.x) +\n 3 * t2 * (this.endPoint.x - this.controlPoint2.x),\n y: 3 * mt2 * (this.controlPoint1.y - this.startPoint.y) +\n 6 * mt * t * (this.controlPoint2.y - this.controlPoint1.y) +\n 3 * t2 * (this.endPoint.y - this.controlPoint2.y)\n };\n }\n\n _getArrowAngle(elbowX) {\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n const tangent = this.getCubicBezierTangent(1.0);\n return Math.atan2(tangent.y, tangent.x);\n } else if (this.arrowCurved === \"elbow\") {\n const ex = elbowX !== undefined ? elbowX : (this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2);\n return Math.atan2(0, this.endPoint.x - ex);\n } else {\n const dx = this.endPoint.x - this.startPoint.x;\n const dy = this.endPoint.y - this.startPoint.y;\n return Math.atan2(dy, dx);\n }\n }\n\n _getArrowHeadPoints(angle) {\n const rad = (this.arrowHeadAngleDeg * Math.PI) / 180;\n return {\n x3: this.endPoint.x - this.arrowHeadLength * Math.cos(angle - rad),\n y3: this.endPoint.y - this.arrowHeadLength * Math.sin(angle - rad),\n x4: this.endPoint.x - this.arrowHeadLength * Math.cos(angle + rad),\n y4: this.endPoint.y - this.arrowHeadLength * Math.sin(angle + rad)\n };\n }\n\n _renderArrowHead(angle) {\n if (this._arrowHeadEl) {\n this._arrowHeadEl.remove();\n this._arrowHeadEl = null;\n }\n\n const style = this.arrowHeadStyle;\n if (!style || style === 'default') return; // default is handled inline in pathData\n\n const pts = this._getArrowHeadPoints(angle);\n const tip = this.endPoint;\n let el;\n\n if (style === 'square') {\n const size = this.arrowHeadLength * 0.7;\n const perpX = -Math.sin(angle), perpY = Math.cos(angle);\n const backX = -Math.cos(angle), backY = -Math.sin(angle);\n const p1x = tip.x + perpX * size / 2, p1y = tip.y + perpY * size / 2;\n const p2x = tip.x - perpX * size / 2, p2y = tip.y - perpY * size / 2;\n const p3x = p2x + backX * size, p3y = p2y + backY * size;\n const p4x = p1x + backX * size, p4y = p1y + backY * size;\n el = document.createElementNS(\"http://www.w3.org/2000/svg\", \"polygon\");\n el.setAttribute(\"points\", `${p1x},${p1y} ${p2x},${p2y} ${p3x},${p3y} ${p4x},${p4y}`);\n el.setAttribute(\"fill\", \"none\");\n } else {\n // outline or solid - triangle\n el = document.createElementNS(\"http://www.w3.org/2000/svg\", \"polygon\");\n el.setAttribute(\"points\", `${pts.x3},${pts.y3} ${tip.x},${tip.y} ${pts.x4},${pts.y4}`);\n el.setAttribute(\"fill\", style === 'solid' ? this.options.stroke : \"none\");\n }\n\n el.setAttribute(\"stroke\", this.options.stroke);\n el.setAttribute(\"stroke-width\", this.options.strokeWidth);\n el.setAttribute(\"stroke-linejoin\", \"round\");\n el.classList.add(\"arrow-head\");\n this._arrowHeadEl = el;\n this.group.appendChild(el);\n }\n\n _updateArrowHead() {\n if (!this._arrowHeadEl) return;\n const style = this.arrowHeadStyle;\n if (style === 'default' || !style) return;\n\n const elbowX = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n const angle = this._getArrowAngle(elbowX);\n const pts = this._getArrowHeadPoints(angle);\n const tip = this.endPoint;\n\n if (style === 'square') {\n const size = this.arrowHeadLength * 0.7;\n const perpX = -Math.sin(angle), perpY = Math.cos(angle);\n const backX = -Math.cos(angle), backY = -Math.sin(angle);\n const p1x = tip.x + perpX * size / 2, p1y = tip.y + perpY * size / 2;\n const p2x = tip.x - perpX * size / 2, p2y = tip.y - perpY * size / 2;\n const p3x = p2x + backX * size, p3y = p2y + backY * size;\n const p4x = p1x + backX * size, p4y = p1y + backY * size;\n this._arrowHeadEl.setAttribute(\"points\", `${p1x},${p1y} ${p2x},${p2y} ${p3x},${p3y} ${p4x},${p4y}`);\n } else {\n this._arrowHeadEl.setAttribute(\"points\", `${pts.x3},${pts.y3} ${tip.x},${tip.y} ${pts.x4},${pts.y4}`);\n }\n }\n\n updateSelectionControls() {\n if (!this.anchors || this.anchors.length === 0) return;\n\n const anchorSize = 5 / currentZoom;\n\n let anchorPositions = [this.startPoint, this.endPoint];\n\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n const midOnCurve = this.getCubicBezierPoint(0.5);\n anchorPositions.push(midOnCurve);\n } else if (this.arrowCurved === \"elbow\") {\n const elbowXVal = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n const midY = (this.startPoint.y + this.endPoint.y) / 2;\n anchorPositions.push({ x: elbowXVal, y: midY });\n } else {\n // straight \u2014 offset end anchor past arrowhead\n const arrowAngle = Math.atan2(this.endPoint.y - this.startPoint.y, this.endPoint.x - this.startPoint.x);\n const arrowHeadClearance = this.arrowHeadLength + anchorSize - 10;\n anchorPositions[1] = {\n x: this.endPoint.x + arrowHeadClearance * Math.cos(arrowAngle),\n y: this.endPoint.y + arrowHeadClearance * Math.sin(arrowAngle)\n };\n }\n\n anchorPositions.forEach((point, index) => {\n if (this.anchors[index]) {\n this.anchors[index].setAttribute(\"cx\", point.x);\n this.anchors[index].setAttribute(\"cy\", point.y);\n this.anchors[index].setAttribute(\"r\", anchorSize);\n }\n });\n }\n\n addAnchors() {\n const anchorSize = 5 / currentZoom;\n const anchorStrokeWidth = 2 / currentZoom;\n\n let anchorPositions = [this.startPoint, this.endPoint];\n\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n // Show a single on-curve anchor at t=0.5 for intuitive dragging\n const midOnCurve = this.getCubicBezierPoint(0.5);\n anchorPositions.push(midOnCurve);\n } else if (this.arrowCurved === \"elbow\") {\n const elbowXVal = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n const midY = (this.startPoint.y + this.endPoint.y) / 2;\n anchorPositions.push({ x: elbowXVal, y: midY });\n } else {\n // straight \u2014 offset end anchor past arrowhead\n const arrowAngle = Math.atan2(this.endPoint.y - this.startPoint.y, this.endPoint.x - this.startPoint.x);\n const arrowHeadClearance = this.arrowHeadLength + anchorSize - 10;\n anchorPositions[1] = {\n x: this.endPoint.x + arrowHeadClearance * Math.cos(arrowAngle),\n y: this.endPoint.y + arrowHeadClearance * Math.sin(arrowAngle)\n };\n }\n\n // Show sidebar\n disableAllSideBars();\n arrowSideBar.classList.remove(\"hidden\");\n if (window.__showSidebarForShape) window.__showSidebarForShape('arrow');\n this.updateSidebar();\n\n anchorPositions.forEach((point, index) => {\n const anchor = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n anchor.setAttribute(\"cx\", point.x);\n anchor.setAttribute(\"cy\", point.y);\n anchor.setAttribute(\"r\", anchorSize);\n\n if (this.arrowCurved && index >= 2) {\n anchor.setAttribute(\"fill\", \"#121212\");\n anchor.setAttribute(\"stroke\", \"#5B57D1\");\n } else {\n anchor.setAttribute(\"fill\", \"#121212\");\n anchor.setAttribute(\"stroke\", \"#5B57D1\");\n }\n\n anchor.setAttribute(\"stroke-width\", anchorStrokeWidth);\n anchor.setAttribute(\"vector-effect\", \"non-scaling-stroke\");\n anchor.setAttribute(\"class\", \"anchor arrow-anchor\");\n anchor.setAttribute(\"data-index\", index);\n anchor.style.cursor = \"grab\";\n anchor.style.pointerEvents = \"all\";\n anchor.addEventListener('pointerdown', (e) => this.startAnchorDrag(e, index));\n\n this.group.appendChild(anchor);\n this.anchors[index] = anchor;\n });\n }\n\n addAttachmentIndicators() {\n if (this.attachedToStart) {\n const attachPoint = this.calculateAttachedPoint(this.attachedToStart);\n const indicator = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n indicator.setAttribute(\"cx\", attachPoint.x);\n indicator.setAttribute(\"cy\", attachPoint.y);\n indicator.setAttribute(\"r\", 4);\n indicator.setAttribute(\"fill\", \"#5B57D1\");\n indicator.setAttribute(\"stroke\", \"#121212\");\n indicator.setAttribute(\"stroke-width\", 1);\n indicator.setAttribute(\"class\", \"attachment-indicator\");\n this.group.appendChild(indicator);\n }\n\n if (this.attachedToEnd) {\n const attachPoint = this.calculateAttachedPoint(this.attachedToEnd);\n const indicator = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n indicator.setAttribute(\"cx\", attachPoint.x);\n indicator.setAttribute(\"cy\", attachPoint.y);\n indicator.setAttribute(\"r\", 4);\n indicator.setAttribute(\"fill\", \"#5B57D1\");\n indicator.setAttribute(\"stroke\", \"#121212\");\n indicator.setAttribute(\"stroke-width\", 1);\n indicator.setAttribute(\"class\", \"attachment-indicator\");\n this.group.appendChild(indicator);\n }\n }\n\n getAttachmentState() {\n return {\n attachedToStart: this.attachedToStart ? {\n shapeId: this.attachedToStart.shape.shapeID,\n side: this.attachedToStart.side,\n offset: { ...this.attachedToStart.offset }\n } : null,\n attachedToEnd: this.attachedToEnd ? {\n shapeId: this.attachedToEnd.shape.shapeID,\n side: this.attachedToEnd.side,\n offset: { ...this.attachedToEnd.offset }\n } : null\n };\n }\n\n restoreAttachmentState(attachmentState) {\n this.attachedToStart = null;\n this.attachedToEnd = null;\n\n if (attachmentState.attachedToStart) {\n const shape = shapes.find(s => s.shapeID === attachmentState.attachedToStart.shapeId);\n if (shape) {\n this.attachedToStart = {\n shape: shape,\n side: attachmentState.attachedToStart.side,\n offset: { ...attachmentState.attachedToStart.offset }\n };\n this.startPoint = this.calculateAttachedPoint(this.attachedToStart);\n }\n }\n\n if (attachmentState.attachedToEnd) {\n const shape = shapes.find(s => s.shapeID === attachmentState.attachedToEnd.shapeId);\n if (shape) {\n this.attachedToEnd = {\n shape: shape,\n side: attachmentState.attachedToEnd.side,\n offset: { ...attachmentState.attachedToEnd.offset }\n };\n this.endPoint = this.calculateAttachedPoint(this.attachedToEnd);\n }\n }\n\n if (this.arrowCurved === \"curved\") {\n this.initializeCurveControlPoints();\n }\n\n this.draw();\n }\n\n static getEllipsePerimeterPoint(circle, angle) {\n // Calculate point on ellipse perimeter at given angle\n const cosAngle = Math.cos(angle);\n const sinAngle = Math.sin(angle);\n\n const a = circle.rx;\n const b = circle.ry;\n\n const t = Math.atan2(a * sinAngle, b * cosAngle);\n\n return {\n x: circle.x + a * Math.cos(t),\n y: circle.y + b * Math.sin(t)\n };\n }\n\n\n static findNearbyShape(point, tolerance = 20) {\n for (let shape of shapes) {\n // Can't attach to other arrows or lines\n if (shape.shapeName === 'arrow' || shape.shapeName === 'line') continue;\n\n let attachment = null;\n\n switch (shape.shapeName) {\n case 'rectangle':\n attachment = Arrow.getRectangleAttachmentPoint(point, shape, tolerance);\n break;\n case 'circle':\n attachment = Arrow.getCircleAttachmentPoint(point, shape, tolerance);\n break;\n case 'frame':\n attachment = Arrow.getFrameAttachmentPoint(point, shape, tolerance);\n break;\n case 'text':\n case 'code':\n // Text and code shapes wrap a group element\n if (shape.group) {\n attachment = Arrow.getTextAttachmentPoint(point, shape.group, tolerance);\n }\n break;\n case 'image':\n // Image shapes wrap an element\n if (shape.element) {\n attachment = Arrow.getImageAttachmentPoint(point, shape.element, tolerance);\n }\n break;\n case 'icon':\n if (shape.element) {\n attachment = Arrow.getIconAttachmentPoint(point, shape.element, tolerance);\n }\n break;\n case 'freehandStroke':\n attachment = Arrow.getBoundingBoxAttachmentPoint(point, shape, tolerance);\n break;\n case 'line':\n attachment = Arrow.getLineAttachmentPoint(point, shape, tolerance);\n break;\n }\n\n if (attachment) {\n return { shape, attachment };\n }\n }\n return null;\n}\n\n static getBoundingBoxAttachmentPoint(point, shape, tolerance = 20) {\n const bounds = shape.boundingBox || { x: shape.x, y: shape.y, width: shape.width, height: shape.height };\n if (!bounds || bounds.width === 0 || bounds.height === 0) return null;\n\n const sides = [\n { name: 'top', start: { x: bounds.x, y: bounds.y }, end: { x: bounds.x + bounds.width, y: bounds.y } },\n { name: 'right', start: { x: bounds.x + bounds.width, y: bounds.y }, end: { x: bounds.x + bounds.width, y: bounds.y + bounds.height } },\n { name: 'bottom', start: { x: bounds.x + bounds.width, y: bounds.y + bounds.height }, end: { x: bounds.x, y: bounds.y + bounds.height } },\n { name: 'left', start: { x: bounds.x, y: bounds.y + bounds.height }, end: { x: bounds.x, y: bounds.y } }\n ];\n\n let closestSide = null;\n let minDistance = tolerance;\n let attachPoint = null;\n\n sides.forEach(side => {\n const distance = Arrow.pointToLineSegmentDistance(point, side.start, side.end);\n if (distance < minDistance) {\n minDistance = distance;\n closestSide = side.name;\n attachPoint = Arrow.closestPointOnLineSegment(point, side.start, side.end);\n }\n });\n\n if (closestSide && attachPoint) {\n const offset = {\n x: attachPoint.x - bounds.x,\n y: attachPoint.y - bounds.y,\n side: closestSide\n };\n return { side: closestSide, point: attachPoint, offset };\n }\n return null;\n }\n\n static getLineAttachmentPoint(point, line, tolerance = 20) {\n const start = line.startPoint;\n const end = line.endPoint;\n if (!start || !end) return null;\n\n const distance = Arrow.pointToLineSegmentDistance(point, start, end);\n if (distance >= tolerance) return null;\n\n const attachPoint = Arrow.closestPointOnLineSegment(point, start, end);\n // Store as a parametric t value along the line\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const lenSq = dx * dx + dy * dy;\n const t = lenSq > 0 ? ((attachPoint.x - start.x) * dx + (attachPoint.y - start.y) * dy) / lenSq : 0;\n\n return {\n side: 'line',\n point: attachPoint,\n offset: { t: Math.max(0, Math.min(1, t)), side: 'line' }\n };\n }\n\nstatic getIconAttachmentPoint(point, iconElement, tolerance = 20) {\n // Check if it's an SVG icon element (group)\n if (!iconElement || (iconElement.tagName !== 'g' && (!iconElement.getAttribute || iconElement.getAttribute('type') !== 'icon'))) {\n console.warn('Invalid icon element for attachment:', iconElement);\n return null;\n }\n\n // Get icon position and dimensions from data attributes\n const iconX = parseFloat(iconElement.getAttribute('data-shape-x') || iconElement.getAttribute('x'));\n const iconY = parseFloat(iconElement.getAttribute('data-shape-y') || iconElement.getAttribute('y'));\n const iconWidth = parseFloat(iconElement.getAttribute('data-shape-width') || iconElement.getAttribute('width'));\n const iconHeight = parseFloat(iconElement.getAttribute('data-shape-height') || iconElement.getAttribute('height'));\n\n // Get rotation from data attribute or transform attribute\n let rotation = 0;\n const dataRotation = iconElement.getAttribute('data-shape-rotation');\n if (dataRotation) {\n rotation = parseFloat(dataRotation) * Math.PI / 180; // Convert to radians\n } else {\n const transform = iconElement.getAttribute('transform');\n if (transform) {\n const rotateMatch = transform.match(/rotate\\(([^,]+)/);\n if (rotateMatch) {\n rotation = parseFloat(rotateMatch[1]) * Math.PI / 180; // Convert to radians\n }\n }\n }\n\n const centerX = iconX + iconWidth / 2;\n const centerY = iconY + iconHeight / 2;\n\n // Transform the bounding box corners to world coordinates\n const corners = [\n { x: iconX, y: iconY }, // top-left\n { x: iconX + iconWidth, y: iconY }, // top-right\n { x: iconX + iconWidth, y: iconY + iconHeight }, // bottom-right\n { x: iconX, y: iconY + iconHeight } // bottom-left\n ];\n\n // Apply rotation to corners\n const transformedCorners = corners.map(corner => {\n if (rotation === 0) return corner;\n\n const dx = corner.x - centerX;\n const dy = corner.y - centerY;\n\n return {\n x: centerX + dx * Math.cos(rotation) - dy * Math.sin(rotation),\n y: centerY + dx * Math.sin(rotation) + dy * Math.cos(rotation)\n };\n });\n\n // Calculate sides of the transformed rectangle\n const sides = [\n { name: 'top', start: transformedCorners[0], end: transformedCorners[1] },\n { name: 'right', start: transformedCorners[1], end: transformedCorners[2] },\n { name: 'bottom', start: transformedCorners[2], end: transformedCorners[3] },\n { name: 'left', start: transformedCorners[3], end: transformedCorners[0] }\n ];\n\n let closestSide = null;\n let minDistance = tolerance;\n let attachPoint = null;\n\n sides.forEach(side => {\n const distance = Arrow.pointToLineSegmentDistance(point, side.start, side.end);\n if (distance < minDistance) {\n minDistance = distance;\n closestSide = side.name;\n\n // Calculate the closest point on the line segment\n attachPoint = Arrow.closestPointOnLineSegment(point, side.start, side.end);\n }\n });\n\n if (closestSide && attachPoint) {\n // Calculate offset relative to the original icon rectangle\n // Transform the attach point back to local coordinates\n let localPoint = attachPoint;\n if (rotation !== 0) {\n const dx = attachPoint.x - centerX;\n const dy = attachPoint.y - centerY;\n\n localPoint = {\n x: centerX + dx * Math.cos(-rotation) - dy * Math.sin(-rotation),\n y: centerY + dx * Math.sin(-rotation) + dy * Math.cos(-rotation)\n };\n }\n\n // Calculate offset relative to the icon rectangle\n const offset = {\n x: localPoint.x - iconX,\n y: localPoint.y - iconY,\n side: closestSide\n };\n\n return { side: closestSide, point: attachPoint, offset };\n }\n\n return null;\n}\n\n\n static getImageAttachmentPoint(point, imageElement, tolerance = 20) {\n // Check if it's an SVG image element\n if (!imageElement || (imageElement.tagName !== 'image' && (!imageElement.getAttribute || imageElement.getAttribute('type') !== 'image'))) {\n console.warn('Invalid image element for attachment:', imageElement);\n return null;\n }\n\n // Get image position and dimensions from data attributes\n const imgX = parseFloat(imageElement.getAttribute('data-shape-x') || imageElement.getAttribute('x'));\n const imgY = parseFloat(imageElement.getAttribute('data-shape-y') || imageElement.getAttribute('y'));\n const imgWidth = parseFloat(imageElement.getAttribute('data-shape-width') || imageElement.getAttribute('width'));\n const imgHeight = parseFloat(imageElement.getAttribute('data-shape-height') || imageElement.getAttribute('height'));\n\n // Get rotation from data attribute or transform attribute\n let rotation = 0;\n const dataRotation = imageElement.getAttribute('data-shape-rotation');\n if (dataRotation) {\n rotation = parseFloat(dataRotation) * Math.PI / 180; // Convert to radians\n } else {\n const transform = imageElement.getAttribute('transform');\n if (transform) {\n const rotateMatch = transform.match(/rotate\\(([^,]+)/);\n if (rotateMatch) {\n rotation = parseFloat(rotateMatch[1]) * Math.PI / 180; // Convert to radians\n }\n }\n }\n\n const centerX = imgX + imgWidth / 2;\n const centerY = imgY + imgHeight / 2;\n\n // Transform the bounding box corners to world coordinates\n const corners = [\n { x: imgX, y: imgY }, // top-left\n { x: imgX + imgWidth, y: imgY }, // top-right\n { x: imgX + imgWidth, y: imgY + imgHeight }, // bottom-right\n { x: imgX, y: imgY + imgHeight } // bottom-left\n ];\n\n // Apply rotation to corners\n const transformedCorners = corners.map(corner => {\n if (rotation === 0) return corner;\n\n const dx = corner.x - centerX;\n const dy = corner.y - centerY;\n\n return {\n x: centerX + dx * Math.cos(rotation) - dy * Math.sin(rotation),\n y: centerY + dx * Math.sin(rotation) + dy * Math.cos(rotation)\n };\n });\n\n // Calculate sides of the transformed rectangle\n const sides = [\n { name: 'top', start: transformedCorners[0], end: transformedCorners[1] },\n { name: 'right', start: transformedCorners[1], end: transformedCorners[2] },\n { name: 'bottom', start: transformedCorners[2], end: transformedCorners[3] },\n { name: 'left', start: transformedCorners[3], end: transformedCorners[0] }\n ];\n\n let closestSide = null;\n let minDistance = tolerance;\n let attachPoint = null;\n\n sides.forEach(side => {\n const distance = Arrow.pointToLineSegmentDistance(point, side.start, side.end);\n if (distance < minDistance) {\n minDistance = distance;\n closestSide = side.name;\n\n // Calculate the closest point on the line segment\n attachPoint = Arrow.closestPointOnLineSegment(point, side.start, side.end);\n }\n });\n\n if (closestSide && attachPoint) {\n // Calculate offset relative to the original image rectangle\n // Transform the attach point back to local coordinates\n let localPoint = attachPoint;\n if (rotation !== 0) {\n const dx = attachPoint.x - centerX;\n const dy = attachPoint.y - centerY;\n\n localPoint = {\n x: centerX + dx * Math.cos(-rotation) - dy * Math.sin(-rotation),\n y: centerY + dx * Math.sin(-rotation) + dy * Math.cos(-rotation)\n };\n }\n\n // Calculate offset relative to the image rectangle\n const offset = {\n x: localPoint.x - imgX,\n y: localPoint.y - imgY,\n side: closestSide\n };\n\n return { side: closestSide, point: attachPoint, offset };\n }\n\n return null;\n}\n\nstatic getFrameAttachmentPoint(point, frame, tolerance = 20) {\n const rect = {\n left: frame.x,\n right: frame.x + frame.width,\n top: frame.y,\n bottom: frame.y + frame.height\n };\n\n const distances = {\n top: Math.abs(point.y - rect.top),\n bottom: Math.abs(point.y - rect.bottom),\n left: Math.abs(point.x - rect.left),\n right: Math.abs(point.x - rect.right)\n };\n\n let closestSide = null;\n let minDistance = tolerance;\n\n for (let side in distances) {\n if (distances[side] < minDistance) {\n if ((side === 'top' || side === 'bottom') &&\n point.x >= rect.left - tolerance && point.x <= rect.right + tolerance) {\n closestSide = side;\n minDistance = distances[side];\n } else if ((side === 'left' || side === 'right') &&\n point.y >= rect.top - tolerance && point.y <= rect.bottom + tolerance) {\n closestSide = side;\n minDistance = distances[side];\n }\n }\n }\n\n if (closestSide) {\n let attachPoint, offset;\n\n switch (closestSide) {\n case 'top':\n attachPoint = { x: Math.max(rect.left, Math.min(rect.right, point.x)), y: rect.top };\n offset = { x: attachPoint.x - frame.x, y: 0 };\n break;\n case 'bottom':\n attachPoint = { x: Math.max(rect.left, Math.min(rect.right, point.x)), y: rect.bottom };\n offset = { x: attachPoint.x - frame.x, y: frame.height };\n break;\n case 'left':\n attachPoint = { x: rect.left, y: Math.max(rect.top, Math.min(rect.bottom, point.y)) };\n offset = { x: 0, y: attachPoint.y - frame.y };\n break;\n case 'right':\n attachPoint = { x: rect.right, y: Math.max(rect.top, Math.min(rect.bottom, point.y)) };\n offset = { x: frame.width, y: attachPoint.y - frame.y };\n break;\n }\n\n return { side: closestSide, point: attachPoint, offset };\n }\n\n return null;\n}\n\n static getRectangleAttachmentPoint(point, rectangle, tolerance = 20) {\n const rect = {\n left: rectangle.x,\n right: rectangle.x + rectangle.width,\n top: rectangle.y,\n bottom: rectangle.y + rectangle.height\n };\n\n const distances = {\n top: Math.abs(point.y - rect.top),\n bottom: Math.abs(point.y - rect.bottom),\n left: Math.abs(point.x - rect.left),\n right: Math.abs(point.x - rect.right)\n };\n\n let closestSide = null;\n let minDistance = tolerance;\n\n for (let side in distances) {\n if (distances[side] < minDistance) {\n if ((side === 'top' || side === 'bottom') &&\n point.x >= rect.left - tolerance && point.x <= rect.right + tolerance) {\n closestSide = side;\n minDistance = distances[side];\n } else if ((side === 'left' || side === 'right') &&\n point.y >= rect.top - tolerance && point.y <= rect.bottom + tolerance) {\n closestSide = side;\n minDistance = distances[side];\n }\n }\n }\n\n if (closestSide) {\n let attachPoint, offset;\n\n switch (closestSide) {\n case 'top':\n attachPoint = { x: Math.max(rect.left, Math.min(rect.right, point.x)), y: rect.top };\n offset = { x: attachPoint.x - rectangle.x, y: 0 };\n break;\n case 'bottom':\n attachPoint = { x: Math.max(rect.left, Math.min(rect.right, point.x)), y: rect.bottom };\n offset = { x: attachPoint.x - rectangle.x, y: rectangle.height };\n break;\n case 'left':\n attachPoint = { x: rect.left, y: Math.max(rect.top, Math.min(rect.bottom, point.y)) };\n offset = { x: 0, y: attachPoint.y - rectangle.y };\n break;\n case 'right':\n attachPoint = { x: rect.right, y: Math.max(rect.top, Math.min(rect.bottom, point.y)) };\n offset = { x: rectangle.width, y: attachPoint.y - rectangle.y };\n break;\n }\n\n return { side: closestSide, point: attachPoint, offset };\n }\n\n return null;\n }\n\n static getCircleAttachmentPoint(point, circle, tolerance = 20) {\n // Calculate distance from point to circle center\n const dx = point.x - circle.x;\n const dy = point.y - circle.y;\n const distanceToCenter = Math.sqrt(dx * dx + dy * dy);\n\n const averageRadius = (circle.rx + circle.ry) / 2;\n const distanceToPerimeter = Math.abs(distanceToCenter - averageRadius);\n\n if (distanceToPerimeter <= tolerance) {\n\n const angle = Math.atan2(dy, dx);\n\n\n const attachPoint = this.getEllipsePerimeterPoint(circle, angle);\n\n\n const offset = {\n angle: angle,\n radiusRatioX: (attachPoint.x - circle.x) / circle.rx,\n radiusRatioY: (attachPoint.y - circle.y) / circle.ry\n };\n\n return {\n side: 'perimeter',\n point: attachPoint,\n offset: offset\n };\n }\n\n return null;\n }\n\n static getTextAttachmentPoint(point, textGroup, tolerance = 20) {\n if (!textGroup) return null;\n // Accept groups with type='text' or type='code'\n const groupType = textGroup.getAttribute ? textGroup.getAttribute('type') : textGroup.type;\n if (groupType !== 'text' && groupType !== 'code') return null;\n\n const textElement = textGroup.querySelector('text');\n if (!textElement) return null;\n\n // Get the text bounding box\n const bbox = textElement.getBBox();\n\n // Get the group's transform\n const groupTransform = textGroup.transform.baseVal.consolidate();\n const matrix = groupTransform ? groupTransform.matrix : { e: 0, f: 0, a: 1, b: 0, c: 0, d: 1 };\n\n // Transform the bounding box corners to world coordinates\n const corners = [\n { x: bbox.x, y: bbox.y }, // top-left\n { x: bbox.x + bbox.width, y: bbox.y }, // top-right\n { x: bbox.x + bbox.width, y: bbox.y + bbox.height }, // bottom-right\n { x: bbox.x, y: bbox.y + bbox.height } // bottom-left\n ];\n\n // Transform corners using the group's transform matrix\n const transformedCorners = corners.map(corner => ({\n x: corner.x * matrix.a + corner.y * matrix.c + matrix.e,\n y: corner.x * matrix.b + corner.y * matrix.d + matrix.f\n }));\n\n // Calculate sides of the transformed rectangle\n const sides = [\n { name: 'top', start: transformedCorners[0], end: transformedCorners[1] },\n { name: 'right', start: transformedCorners[1], end: transformedCorners[2] },\n { name: 'bottom', start: transformedCorners[2], end: transformedCorners[3] },\n { name: 'left', start: transformedCorners[3], end: transformedCorners[0] }\n ];\n\n let closestSide = null;\n let minDistance = tolerance;\n let attachPoint = null;\n\n sides.forEach(side => {\n const distance = Arrow.pointToLineSegmentDistance(point, side.start, side.end);\n if (distance < minDistance) {\n minDistance = distance;\n closestSide = side.name;\n\n // Calculate the closest point on the line segment\n attachPoint = Arrow.closestPointOnLineSegment(point, side.start, side.end);\n }\n });\n\n if (closestSide && attachPoint) {\n // Calculate offset relative to the original bounding box\n // Transform the attach point back to local coordinates\n const det = matrix.a * matrix.d - matrix.b * matrix.c;\n if (det === 0) return null;\n\n const invMatrix = {\n a: matrix.d / det,\n b: -matrix.b / det,\n c: -matrix.c / det,\n d: matrix.a / det,\n e: (matrix.c * matrix.f - matrix.d * matrix.e) / det,\n f: (matrix.b * matrix.e - matrix.a * matrix.f) / det\n };\n\n const localPoint = {\n x: attachPoint.x * invMatrix.a + attachPoint.y * invMatrix.c + invMatrix.e,\n y: attachPoint.x * invMatrix.b + attachPoint.y * invMatrix.d + invMatrix.f\n };\n\n // Calculate offset relative to the bounding box\n const offset = {\n x: localPoint.x - bbox.x,\n y: localPoint.y - bbox.y,\n side: closestSide\n };\n\n return { side: closestSide, point: attachPoint, offset };\n }\n\n return null;\n }\n\n static pointToLineSegmentDistance(point, lineStart, lineEnd) {\n const A = point.x - lineStart.x;\n const B = point.y - lineStart.y;\n const C = lineEnd.x - lineStart.x;\n const D = lineEnd.y - lineStart.y;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n\n if (lenSq === 0) {\n // Line segment is a point\n return Math.sqrt(A * A + B * B);\n }\n\n let param = dot / lenSq;\n param = Math.max(0, Math.min(1, param)); // Clamp to [0,1]\n\n const xx = lineStart.x + param * C;\n const yy = lineStart.y + param * D;\n\n const dx = point.x - xx;\n const dy = point.y - yy;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n static closestPointOnLineSegment(point, lineStart, lineEnd) {\n const A = point.x - lineStart.x;\n const B = point.y - lineStart.y;\n const C = lineEnd.x - lineStart.x;\n const D = lineEnd.y - lineStart.y;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n\n if (lenSq === 0) {\n return { x: lineStart.x, y: lineStart.y };\n }\n\n let param = dot / lenSq;\n param = Math.max(0, Math.min(1, param));\n\n return {\n x: lineStart.x + param * C,\n y: lineStart.y + param * D\n };\n }\n\n calculateAttachedPoint(attachment) {\n const shape = attachment.shape;\n const side = attachment.side;\n const offset = attachment.offset;\n\n if (shape.shapeName === 'rectangle') {\n return Arrow._calcRectAttachedPoint(shape.x, shape.y, shape.width, shape.height, shape.rotation, side, offset);\n }\n\n if (shape.shapeName === 'circle') {\n if (side === 'perimeter') {\n return Arrow.getEllipsePerimeterPoint(shape, offset.angle);\n }\n }\n\n if (shape.shapeName === 'text' || shape.shapeName === 'code') {\n // Text/code shapes use their group's transform\n const groupEl = shape.group;\n if (!groupEl) return { x: shape.x || 0, y: shape.y || 0 };\n const textElement = groupEl.querySelector('text') || groupEl.querySelector('foreignObject');\n if (!textElement) return { x: shape.x || 0, y: shape.y || 0 };\n\n const bbox = textElement.getBBox();\n const groupTransform = groupEl.transform.baseVal.consolidate();\n const matrix = groupTransform ? groupTransform.matrix : { e: 0, f: 0, a: 1, b: 0, c: 0, d: 1 };\n\n let localPoint = { x: bbox.x + offset.x, y: bbox.y + offset.y };\n return {\n x: localPoint.x * matrix.a + localPoint.y * matrix.c + matrix.e,\n y: localPoint.x * matrix.b + localPoint.y * matrix.d + matrix.f\n };\n }\n\n if (shape.shapeName === 'image') {\n return Arrow._calcRectAttachedPoint(shape.x, shape.y, shape.width, shape.height, shape.rotation, side, offset);\n }\n\n if (shape.shapeName === 'icon') {\n return Arrow._calcRectAttachedPoint(shape.x, shape.y, shape.width, shape.height, shape.rotation, side, offset);\n }\n\n if (shape.shapeName === 'frame') {\n return Arrow._calcRectAttachedPoint(shape.x, shape.y, shape.width, shape.height, 0, side, offset);\n }\n\n if (shape.shapeName === 'freehandStroke') {\n const bounds = shape.boundingBox || { x: shape.x, y: shape.y, width: shape.width, height: shape.height };\n return Arrow._calcRectAttachedPoint(bounds.x, bounds.y, bounds.width, bounds.height, 0, side, offset);\n }\n\n if (shape.shapeName === 'line') {\n if (side === 'line' && offset.t !== undefined) {\n const t = offset.t;\n return {\n x: shape.startPoint.x + t * (shape.endPoint.x - shape.startPoint.x),\n y: shape.startPoint.y + t * (shape.endPoint.y - shape.startPoint.y)\n };\n }\n }\n\n return { x: shape.x || 0, y: shape.y || 0 };\n}\n\n static _calcRectAttachedPoint(rx, ry, rw, rh, rotation, side, offset) {\n let localPoint;\n switch (side) {\n case 'top':\n localPoint = { x: rx + offset.x, y: ry };\n break;\n case 'bottom':\n localPoint = { x: rx + offset.x, y: ry + rh };\n break;\n case 'left':\n localPoint = { x: rx, y: ry + offset.y };\n break;\n case 'right':\n localPoint = { x: rx + rw, y: ry + offset.y };\n break;\n default:\n localPoint = { x: rx + offset.x, y: ry + offset.y };\n }\n\n if (rotation) {\n const rad = rotation * Math.PI / 180;\n const cx = rx + rw / 2;\n const cy = ry + rh / 2;\n const dx = localPoint.x - cx;\n const dy = localPoint.y - cy;\n return {\n x: cx + dx * Math.cos(rad) - dy * Math.sin(rad),\n y: cy + dx * Math.sin(rad) + dy * Math.cos(rad)\n };\n }\n return localPoint;\n }\n\n detachFromShape(isStartPoint) {\n if (isStartPoint) {\n this.attachedToStart = null;\n } else {\n this.attachedToEnd = null;\n }\n }\n\n updateAttachments() {\n let needsRedraw = false;\n\n if (this.attachedToStart && this.attachedToStart.shape) {\n const newPoint = this.calculateAttachedPoint(this.attachedToStart);\n if (newPoint.x !== this.startPoint.x || newPoint.y !== this.startPoint.y) {\n this.startPoint = newPoint;\n needsRedraw = true;\n }\n }\n\n if (this.attachedToEnd && this.attachedToEnd.shape) {\n const newPoint = this.calculateAttachedPoint(this.attachedToEnd);\n if (newPoint.x !== this.endPoint.x || newPoint.y !== this.endPoint.y) {\n this.endPoint = newPoint;\n needsRedraw = true;\n }\n }\n\n if (needsRedraw) {\n if (this.arrowCurved) {\n this.initializeCurveControlPoints();\n }\n this.draw();\n }\n }\n\n move(dx, dy) {\n if (!this.attachedToStart) {\n this.startPoint.x += dx;\n this.startPoint.y += dy;\n }\n if (!this.attachedToEnd) {\n this.endPoint.x += dx;\n this.endPoint.y += dy;\n }\n\n if (this.controlPoint1 && (!this.attachedToStart && !this.attachedToEnd)) {\n this.controlPoint1.x += dx;\n this.controlPoint1.y += dy;\n }\n if (this.controlPoint2 && (!this.attachedToStart && !this.attachedToEnd)) {\n this.controlPoint2.x += dx;\n this.controlPoint2.y += dy;\n }\n\n // Lightweight update \u2014 rebuild the path element without full draw/anchor rebuild\n this._updatePathElement();\n this._updateHitArea();\n this._updateLabelElement();\n this._updateAnchorPositions();\n\n // Only update frame containment if we're actively dragging the shape itself\n // and not being moved by a parent frame\n if (isDragging && !this.isBeingMovedByFrame) {\n this.updateFrameContainment();\n }\n}\n\nupdateFrameContainment() {\n // Don't update if we're being moved by a frame\n if (this.isBeingMovedByFrame) return;\n \n let targetFrame = null;\n \n // Find which frame this shape is over\n shapes.forEach(shape => {\n if (shape.shapeName === 'frame' && shape.isShapeInFrame(this)) {\n targetFrame = shape;\n }\n });\n \n // If we have a parent frame and we're being dragged, temporarily remove clipping\n if (this.parentFrame && isDragging) {\n this.parentFrame.temporarilyRemoveFromFrame(this);\n }\n \n // Update frame highlighting\n if (hoveredFrameArrow && hoveredFrameArrow !== targetFrame) {\n hoveredFrameArrow.removeHighlight();\n }\n \n if (targetFrame && targetFrame !== hoveredFrameArrow) {\n targetFrame.highlightFrame();\n }\n \n hoveredFrameArrow = targetFrame;\n}\n\n isNearAnchor(x, y) {\n const anchorSize = 10 / currentZoom;\n\n for (let i = 0; i < this.anchors.length; i++) {\n const anchor = this.anchors[i];\n if (anchor) {\n const anchorX = parseFloat(anchor.getAttribute('cx'));\n const anchorY = parseFloat(anchor.getAttribute('cy'));\n const distance = Math.sqrt(Math.pow(x - anchorX, 2) + Math.pow(y - anchorY, 2));\n if (distance <= anchorSize) {\n return { type: 'anchor', index: i };\n }\n }\n }\n\n return null;\n }\n\n startAnchorDrag(e, index) {\n e.stopPropagation();\n e.preventDefault();\n\n // Store initial state including attachments\n dragOldPosArrow = {\n startPoint: { x: this.startPoint.x, y: this.startPoint.y },\n endPoint: { x: this.endPoint.x, y: this.endPoint.y },\n controlPoint1: this.controlPoint1 ? { x: this.controlPoint1.x, y: this.controlPoint1.y } : null,\n controlPoint2: this.controlPoint2 ? { x: this.controlPoint2.x, y: this.controlPoint2.y } : null,\n attachments: this.getAttachmentState()\n };\n\n const onPointerMove = (event) => {\n const { x, y } = getSVGCoordsFromMouse(event);\n\n // Check for potential attachment when dragging start or end anchors\n if (index === 0 || index === 1) {\n const nearbyShape = Arrow.findNearbyShape({ x, y });\n if (nearbyShape) {\n // Show preview while dragging\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n\n const preview = document.createElementNS(\"http://www.w3.org/2000/svg\", \"circle\");\n preview.setAttribute(\"cx\", nearbyShape.attachment.point.x);\n preview.setAttribute(\"cy\", nearbyShape.attachment.point.y);\n preview.setAttribute(\"r\", 6);\n preview.setAttribute(\"fill\", \"none\");\n preview.setAttribute(\"stroke\", \"#5B57D1\");\n preview.setAttribute(\"stroke-width\", 2);\n preview.setAttribute(\"class\", \"attachment-preview\");\n preview.setAttribute(\"opacity\", \"0.7\");\n svg.appendChild(preview);\n\n // Snap to attachment point\n this.updatePosition(index, nearbyShape.attachment.point.x, nearbyShape.attachment.point.y);\n } else {\n\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n\n this.updatePosition(index, x, y);\n }\n } else {\n this.updatePosition(index, x, y);\n }\n };\n\n const onPointerUp = () => {\n\n const existingPreview = svg.querySelector('.attachment-preview');\n if (existingPreview) existingPreview.remove();\n\n if (index === 0) {\n // Check for start point attachment\n const startAttachment = Arrow.findNearbyShape(this.startPoint);\n if (startAttachment) {\n\n if (this.attachedToStart && this.attachedToStart.shape !== startAttachment.shape) {\n this.detachFromShape(true);\n }\n this.attachToShape(true, startAttachment.shape, startAttachment.attachment);\n } else {\n // Detach if moved away from shape\n if (this.attachedToStart) {\n this.detachFromShape(true);\n }\n }\n } else if (index === 1) {\n // Check for end point attachment\n const endAttachment = Arrow.findNearbyShape(this.endPoint);\n if (endAttachment) {\n // Detach if previously attached to different shape\n if (this.attachedToEnd && this.attachedToEnd.shape !== endAttachment.shape) {\n this.detachFromShape(false);\n }\n this.attachToShape(false, endAttachment.shape, endAttachment.attachment);\n } else {\n // Detach if moved away from shape\n if (this.attachedToEnd) {\n this.detachFromShape(false);\n }\n }\n }\n\n if (dragOldPosArrow) {\n const newPos = {\n startPoint: { x: this.startPoint.x, y: this.startPoint.y },\n endPoint: { x: this.endPoint.x, y: this.endPoint.y },\n controlPoint1: this.controlPoint1 ? { x: this.controlPoint1.x, y: this.controlPoint1.y } : null,\n controlPoint2: this.controlPoint2 ? { x: this.controlPoint2.x, y: this.controlPoint2.y } : null,\n attachments: this.getAttachmentState()\n };\n\n // Check if anything actually changed (position or attachments)\n const stateChanged =\n dragOldPosArrow.startPoint.x !== newPos.startPoint.x ||\n dragOldPosArrow.startPoint.y !== newPos.startPoint.y ||\n dragOldPosArrow.endPoint.x !== newPos.endPoint.x ||\n dragOldPosArrow.endPoint.y !== newPos.endPoint.y ||\n JSON.stringify(dragOldPosArrow.attachments) !== JSON.stringify(newPos.attachments);\n\n if (stateChanged) {\n pushTransformAction(this, dragOldPosArrow, newPos);\n }\n dragOldPosArrow = null;\n }\n\n svg.removeEventListener('pointermove', onPointerMove);\n svg.removeEventListener('pointerup', onPointerUp);\n };\n\n svg.addEventListener('pointermove', onPointerMove);\n svg.addEventListener('pointerup', onPointerUp);\n }\n\n updatePosition(anchorIndex, newViewBoxX, newViewBoxY) {\n if (anchorIndex === 0) {\n this.startPoint.x = newViewBoxX;\n this.startPoint.y = newViewBoxY;\n } else if (anchorIndex === 1) {\n this.endPoint.x = newViewBoxX;\n this.endPoint.y = newViewBoxY;\n } else if (anchorIndex === 2 && this.arrowCurved === \"elbow\") {\n this.elbowX = newViewBoxX;\n } else if (anchorIndex === 2 && this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n // On-curve midpoint anchor dragged \u2014 inversely compute control points\n // B(0.5) = 0.125*P0 + 0.375*CP1 + 0.375*CP2 + 0.125*P3\n // Keep curve symmetric: offset both control points equally from the line\n const dx = this.endPoint.x - this.startPoint.x;\n const dy = this.endPoint.y - this.startPoint.y;\n const dist = Math.sqrt(dx * dx + dy * dy) || 1;\n const perpX = -dy / dist;\n const perpY = dx / dist;\n\n // Desired midpoint offset from line midpoint\n const lineMidX = (this.startPoint.x + this.endPoint.x) / 2;\n const lineMidY = (this.startPoint.y + this.endPoint.y) / 2;\n const offsetX = newViewBoxX - lineMidX;\n const offsetY = newViewBoxY - lineMidY;\n // Project offset onto perpendicular to get curve amount\n const curveAmount = offsetX * perpX + offsetY * perpY;\n\n // Recompute control points with this curve amount\n const t1 = 0.33, t2 = 0.67;\n this.controlPoint1 = {\n x: this.startPoint.x + t1 * dx + perpX * curveAmount * (4 / 3),\n y: this.startPoint.y + t1 * dy + perpY * curveAmount * (4 / 3)\n };\n this.controlPoint2 = {\n x: this.startPoint.x + t2 * dx + perpX * curveAmount * (4 / 3),\n y: this.startPoint.y + t2 * dy + perpY * curveAmount * (4 / 3)\n };\n }\n this.draw();\n }\n\n contains(viewBoxX, viewBoxY) {\n const tolerance = Math.max(5, this.options.strokeWidth * 2) / currentZoom;\n\n if (this.arrowCurved === \"curved\" && this.controlPoint1 && this.controlPoint2) {\n return this.pointToCubicBezierDistance(viewBoxX, viewBoxY) <= tolerance;\n } else if (this.arrowCurved === \"elbow\") {\n const ex = this.elbowX !== null ? this.elbowX : (this.startPoint.x + this.endPoint.x) / 2;\n const d1 = this.pointToLineDistance(viewBoxX, viewBoxY, this.startPoint.x, this.startPoint.y, ex, this.startPoint.y);\n const d2 = this.pointToLineDistance(viewBoxX, viewBoxY, ex, this.startPoint.y, ex, this.endPoint.y);\n const d3 = this.pointToLineDistance(viewBoxX, viewBoxY, ex, this.endPoint.y, this.endPoint.x, this.endPoint.y);\n return Math.min(d1, d2, d3) <= tolerance;\n } else {\n return this.pointToLineDistance(viewBoxX, viewBoxY, this.startPoint.x, this.startPoint.y, this.endPoint.x, this.endPoint.y) <= tolerance;\n }\n }\n\n pointToCubicBezierDistance(x, y) {\n let minDistance = Infinity;\n const steps = 100;\n\n for (let i = 0; i <= steps; i++) {\n const t = i / steps;\n const point = this.getCubicBezierPoint(t);\n const distance = Math.sqrt(Math.pow(x - point.x, 2) + Math.pow(y - point.y, 2));\n minDistance = Math.min(minDistance, distance);\n }\n\n return minDistance;\n }\n\n pointToLineDistance(x, y, x1, y1, x2, y2) {\n const A = x - x1;\n const B = y - y1;\n const C = x2 - x1;\n const D = y2 - y1;\n\n const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n let param = -1;\n\n if (lenSq !== 0) {\n param = dot / lenSq;\n }\n\n let xx, yy;\n\n if (param < 0) {\n xx = x1;\n yy = y1;\n } else if (param > 1) {\n xx = x2;\n yy = y2;\n } else {\n xx = x1 + param * C;\n yy = y1 + param * D;\n }\n\n const dx = x - xx;\n const dy = y - yy;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n updateStyle(newOptions) {\n if (newOptions.arrowOutlineStyle !== undefined) {\n this.arrowOutlineStyle = newOptions.arrowOutlineStyle;\n const style = this.arrowOutlineStyle;\n this.options.strokeDasharray = style === \"dashed\" ? \"10,10\" : (style === \"dotted\" ? \"2,8\" : \"\");\n }\n if (newOptions.arrowHeadStyle !== undefined) {\n this.arrowHeadStyle = newOptions.arrowHeadStyle;\n }\n if (newOptions.arrowCurved !== undefined) {\n const wasCurved = this.arrowCurved;\n this.arrowCurved = newOptions.arrowCurved;\n\n if (this.arrowCurved === \"curved\" && wasCurved !== \"curved\") {\n this.initializeCurveControlPoints();\n } else if (this.arrowCurved !== \"curved\") {\n this.controlPoint1 = null;\n this.controlPoint2 = null;\n }\n if (this.arrowCurved !== \"elbow\") {\n this.elbowX = null;\n }\n }\n if (newOptions.elbowX !== undefined) {\n this.elbowX = newOptions.elbowX;\n }\n if (newOptions.stroke !== undefined) {\n this.options.stroke = newOptions.stroke;\n }\n if (newOptions.strokeWidth !== undefined) {\n this.options.strokeWidth = parseFloat(newOptions.strokeWidth);\n }\n if (newOptions.arrowCurveAmount !== undefined) {\n this.arrowCurveAmount = newOptions.arrowCurveAmount;\n if (this.arrowCurved) {\n this.initializeCurveControlPoints();\n }\n }\n\n Object.keys(newOptions).forEach(key => newOptions[key] === undefined && delete newOptions[key]);\n this.options = { ...this.options, ...newOptions };\n\n if (this.arrowOutlineStyle === 'solid' && this.options.strokeDasharray) {\n delete this.options.strokeDasharray;\n }\n\n this.draw();\n }\n\n updateSidebar() {\n // No-op: React sidebar handles UI updates via Zustand store\n }\n\n destroy() {\n if (this.group && this.group.parentNode) {\n this.group.parentNode.removeChild(this.group);\n }\n const index = shapes.indexOf(this);\n if (index > -1) {\n shapes.splice(index, 1);\n }\n if (currentShape === this) {\n currentShape = null;\n }\n }\n}\n\nexport { Arrow };"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -431,7 +431,7 @@ function useSketchEngine(svgRef, ready = true) {
431
431
  setZoom: (zoom) => useSketchStore_default.setState({ zoom }),
432
432
  getState: () => useSketchStore_default.getState()
433
433
  };
434
- const { SketchEngine } = await import("./SketchEngine-P3XNZA56.js");
434
+ const { SketchEngine } = await import("./SketchEngine-B7XCB3BS.js");
435
435
  if (cancelled) return;
436
436
  const engine = new SketchEngine(svgRef.current);
437
437
  await engine.init();
@@ -4741,7 +4741,7 @@ var _saveScene = null;
4741
4741
  var _loadScene = null;
4742
4742
  async function ensureSceneSerializer() {
4743
4743
  if (_saveScene && _loadScene) return;
4744
- const m = await import("./SceneSerializer-34VQFJN7.js");
4744
+ const m = await import("./SceneSerializer-YK44QZ6B.js");
4745
4745
  _saveScene = m.saveScene;
4746
4746
  _loadScene = m.loadScene;
4747
4747
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@elixpo/lixsketch",
3
- "version": "5.5.14",
3
+ "version": "5.5.16",
4
4
  "description": "Open-source SVG whiteboard engine + React canvas component with hand-drawn aesthetics — the core of LixSketch",
5
5
  "type": "module",
6
6
  "main": "src/index.js",
@@ -354,16 +354,16 @@ export function renderEROnCanvas(diagram) {
354
354
  const x = origin.x + entity.x;
355
355
  const y = origin.y + entity.y;
356
356
  const header = push(new window.Rectangle(x, y, entity.width, entity.headerHeight, {
357
- stroke: entity.color.stroke, strokeWidth: 1.5, fill: entity.color.fill, fillStyle: 'solid', roughness: 1,
358
- label: entity.name, labelColor: contrastText(entity.color.fill), labelFontSize: 15,
357
+ stroke: entity.color.stroke, strokeWidth: 1.5, fill: entity.color.fill, fillStyle: 'solid', roughness: 0, fillWeight: 0.5,
358
+ label: entity.name, labelColor: contrastText(entity.color.fill), labelFontSize: 15, labelBg: false,
359
359
  }), frame);
360
360
  if (!first) first = header;
361
361
  entityShapes.set(entity.name, { shape: header, x, y, width: entity.width, height: entity.headerHeight });
362
362
  const attributes = entity.attributes.length ? entity.attributes : [{ type: '', name: 'No attributes', key: '' }];
363
363
  attributes.forEach((attribute, row) => push(new window.Rectangle(
364
364
  x, y + entity.headerHeight + row * entity.rowHeight, entity.width, entity.rowHeight,
365
- { stroke: TK.frame, strokeWidth: 1, fill: TK.panel, fillStyle: 'solid', roughness: .4,
366
- label: [attribute.type, attribute.name, attribute.key].filter(Boolean).join(' '), labelColor: TK.text, labelFontSize: 11 }
365
+ { stroke: TK.frame, strokeWidth: 1, fill: TK.panel, fillStyle: 'solid', roughness: 0, fillWeight: 0.5,
366
+ label: [attribute.type, attribute.name, attribute.key].filter(Boolean).join(' '), labelColor: TK.text, labelFontSize: 11, labelBg: false }
367
367
  ), frame));
368
368
  }
369
369
 
@@ -371,11 +371,20 @@ export function renderEROnCanvas(diagram) {
371
371
  const from = entityShapes.get(relation.from);
372
372
  const to = entityShapes.get(relation.to);
373
373
  if (!from || !to) continue;
374
- const start = { x: from.x + from.width / 2, y: from.y + from.height / 2 };
375
- const end = { x: to.x + to.width / 2, y: to.y + to.height / 2 };
374
+ const fromCenter = { x: from.x + from.width / 2, y: from.y + from.height / 2 };
375
+ const toCenter = { x: to.x + to.width / 2, y: to.y + to.height / 2 };
376
+ // Anchor the arrow at the actual box boundary (not the box center) so
377
+ // it terminates at the entity edge instead of drawing through — and
378
+ // over — the header label, and so autoAttach's nearest-side check
379
+ // (which compares against this point) resolves to the side actually
380
+ // facing the other entity rather than whichever side happens to be
381
+ // closest to the geometric center on a short, wide header box.
382
+ const start = rectBoundaryPoint(from, toCenter);
383
+ const end = rectBoundaryPoint(to, fromCenter);
376
384
  const arrow = push(new window.Arrow(start, end, {
377
- stroke: TK.line, strokeWidth: 1.5, roughness: 1,
378
- label: `${relation.fromCardinality} ${relation.label} ${relation.toCardinality}`, labelColor: TK.text,
385
+ stroke: TK.line, strokeWidth: 1.5, roughness: 0,
386
+ label: `${relation.fromCardinality} ${relation.label} ${relation.toCardinality}`,
387
+ labelColor: TK.text, labelBg: false, labelOffsetY: -12,
379
388
  }), frame);
380
389
  if (arrow && window.__autoAttach) {
381
390
  window.__autoAttach(arrow, from.shape, true, start);
@@ -386,6 +395,21 @@ export function renderEROnCanvas(diagram) {
386
395
  return true;
387
396
  }
388
397
 
398
+ // Intersection of the line from `box`'s center toward `target` with box's
399
+ // own rectangular boundary. Used to anchor ER relationship arrows exactly
400
+ // at the entity edge instead of the entity center.
401
+ function rectBoundaryPoint(box, target) {
402
+ const cx = box.x + box.width / 2;
403
+ const cy = box.y + box.height / 2;
404
+ const dx = target.x - cx;
405
+ const dy = target.y - cy;
406
+ const hw = box.width / 2;
407
+ const hh = box.height / 2;
408
+ if (dx === 0 && dy === 0) return { x: cx, y: cy };
409
+ const scale = 1 / Math.max(Math.abs(dx) / hw, Math.abs(dy) / hh);
410
+ return { x: cx + dx * scale, y: cy + dy * scale };
411
+ }
412
+
389
413
  export function renderChartOnCanvas(chart) {
390
414
  if (!chart?.series?.length || !window.Rectangle || !window.Circle || !window.Line || !window.FreehandStroke || !window.Frame) return false;
391
415
  if (chart.kind === 'pie') return renderPieOnCanvas(chart);
@@ -500,4 +524,4 @@ function renderPieOnCanvas(chart) {
500
524
 
501
525
  selectOnlyFrame(frame);
502
526
  return true;
503
- }
527
+ }
@@ -56,6 +56,8 @@ class Arrow {
56
56
  this.labelElement = null;
57
57
  this.labelColor = options.labelColor || '#e0e0e0';
58
58
  this.labelFontSize = options.labelFontSize || 12;
59
+ this.labelBg = options.labelBg !== false; // labelBg:false → no knockout rect behind label
60
+ this.labelOffsetY = options.labelOffsetY || 0; // shift label along the perpendicular of the line, e.g. lift it clear of the stroke
59
61
  this._isEditingLabel = false;
60
62
  this._hitArea = null;
61
63
  this._labelBg = null;
@@ -469,8 +471,18 @@ class Arrow {
469
471
  }
470
472
 
471
473
  const mid = this._getMidpoint();
472
- this.labelElement.setAttribute('x', mid.x);
473
- this.labelElement.setAttribute('y', mid.y);
474
+ let lx = mid.x, ly = mid.y;
475
+ if (this.labelOffsetY) {
476
+ // Offset perpendicular to the line direction so the label lifts
477
+ // clear of the stroke instead of sitting centered on top of it.
478
+ const dx = this.endPoint.x - this.startPoint.x;
479
+ const dy = this.endPoint.y - this.startPoint.y;
480
+ const len = Math.sqrt(dx * dx + dy * dy) || 1;
481
+ lx += (-dy / len) * this.labelOffsetY;
482
+ ly += (dx / len) * this.labelOffsetY;
483
+ }
484
+ this.labelElement.setAttribute('x', lx);
485
+ this.labelElement.setAttribute('y', ly);
474
486
  this.labelElement.setAttribute('text-anchor', 'middle');
475
487
  this.labelElement.setAttribute('dominant-baseline', 'central');
476
488
  this.labelElement.setAttribute('fill', this.labelColor);
@@ -478,6 +490,16 @@ class Arrow {
478
490
  this.labelElement.setAttribute('font-family', 'lixFont, sans-serif');
479
491
  this.labelElement.textContent = this.label;
480
492
 
493
+ if (!this.labelBg) {
494
+ if (this._labelBg && this._labelBg.parentNode === this.group) {
495
+ this.group.removeChild(this._labelBg);
496
+ this._labelBg = null;
497
+ }
498
+ if (this.labelElement.parentNode === this.group) this.group.removeChild(this.labelElement);
499
+ this.group.appendChild(this.labelElement);
500
+ return;
501
+ }
502
+
481
503
  // Background knockout rect - hides the arrow behind the text
482
504
  const canvasBg = window.getComputedStyle(svg).backgroundColor || '#000';
483
505
  if (!this._labelBg) {
@@ -490,8 +512,8 @@ class Arrow {
490
512
  const charWidth = this.labelFontSize * 0.6;
491
513
  const bgW = this.label.length * charWidth + hPadding * 2;
492
514
  const bgH = this.labelFontSize + vPadding * 2;
493
- this._labelBg.setAttribute('x', mid.x - bgW / 2);
494
- this._labelBg.setAttribute('y', mid.y - bgH / 2);
515
+ this._labelBg.setAttribute('x', lx - bgW / 2);
516
+ this._labelBg.setAttribute('y', ly - bgH / 2);
495
517
  this._labelBg.setAttribute('width', bgW);
496
518
  this._labelBg.setAttribute('height', bgH);
497
519
  this._labelBg.setAttribute('rx', 2);
@@ -2008,4 +2030,4 @@ updateFrameContainment() {
2008
2030
  }
2009
2031
  }
2010
2032
 
2011
- export { Arrow };
2033
+ export { Arrow };
@@ -1211,6 +1211,28 @@ startLabelEdit(labelElement) {
1211
1211
  shape.y = this.y + relTY * this.height;
1212
1212
  break;
1213
1213
  }
1214
+ case 'freehandStroke': {
1215
+ // Pie sectors are editable closed freehand polygons.
1216
+ // Scale their source points with the frame so their
1217
+ // geometry stays attached instead of being clipped
1218
+ // at its previous canvas coordinates.
1219
+ if (Array.isArray(shape.points)) {
1220
+ shape.points = shape.points.map(point => {
1221
+ if (!Array.isArray(point) || point.length < 2) return point;
1222
+ const relPX = (point[0] - oldX) / oldW;
1223
+ const relPY = (point[1] - oldY) / oldH;
1224
+ return [
1225
+ this.x + relPX * this.width,
1226
+ this.y + relPY * this.height,
1227
+ point[2] || 0.5
1228
+ ];
1229
+ });
1230
+ shape._moveOffsetX = 0;
1231
+ shape._moveOffsetY = 0;
1232
+ if (typeof shape.draw === 'function') shape.draw();
1233
+ }
1234
+ break;
1235
+ }
1214
1236
  }
1215
1237
 
1216
1238
  if (typeof shape.updateAttachedArrows === 'function') {
@@ -50,6 +50,7 @@ class Rectangle {
50
50
  this.labelElement = null;
51
51
  this.labelColor = options.labelColor || '#e0e0e0';
52
52
  this.labelFontSize = options.labelFontSize || 14;
53
+ this.labelBg = options.labelBg !== false; // set labelBg:false to render plain text with no pill backdrop
53
54
  this._isEditingLabel = false;
54
55
  this._hitArea = null;
55
56
  this._labelBg = null;
@@ -245,7 +246,19 @@ class Rectangle {
245
246
  this.labelElement.setAttribute('font-family', 'lixFont, sans-serif');
246
247
  this.labelElement.textContent = this.label;
247
248
 
248
- // Background padding rect behind text (like arrows have)
249
+ // Background padding rect behind text (like arrows have) — skippable
250
+ // via labelBg:false for dense multi-row content (e.g. mermaid ER
251
+ // attribute rows) where a pill backdrop looks out of place and
252
+ // doesn't match the SVG preview.
253
+ if (!this.labelBg) {
254
+ if (this._labelBg && this._labelBg.parentNode === this.group) {
255
+ this.group.removeChild(this._labelBg);
256
+ this._labelBg = null;
257
+ }
258
+ if (this.labelElement.parentNode === this.group) this.group.removeChild(this.labelElement);
259
+ this.group.appendChild(this.labelElement);
260
+ return;
261
+ }
249
262
  const canvasBg = window.getComputedStyle(svg).backgroundColor || '#000';
250
263
  if (!this._labelBg) {
251
264
  this._labelBg = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
@@ -1,8 +0,0 @@
1
- "use client";
2
- import {
3
- Arrow
4
- } from "./chunk-XISEAGBV.js";
5
- export {
6
- Arrow
7
- };
8
- //# sourceMappingURL=Arrow-BJDAXPMH.js.map
@@ -1,8 +0,0 @@
1
- "use client";
2
- import {
3
- Rectangle
4
- } from "./chunk-Z4YVT54E.js";
5
- export {
6
- Rectangle
7
- };
8
- //# sourceMappingURL=Rectangle-2F7BAXG4.js.map