@elixpo/lixsketch 5.4.7 → 5.5.0

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 (218) hide show
  1. package/dist/react/AIRenderer-M4LMJ66J.js +1105 -0
  2. package/dist/react/AIRenderer-M4LMJ66J.js.map +7 -0
  3. package/dist/react/Arrow-BJDAXPMH.js +8 -0
  4. package/dist/react/Arrow-BJDAXPMH.js.map +7 -0
  5. package/dist/react/Circle-KPG7TKIX.js +8 -0
  6. package/dist/react/Circle-KPG7TKIX.js.map +7 -0
  7. package/dist/react/CodeShape-K4DIZAIV.js +8 -0
  8. package/dist/react/CodeShape-K4DIZAIV.js.map +7 -0
  9. package/dist/react/CopyPaste-4CKJRHJ3.js +569 -0
  10. package/dist/react/CopyPaste-4CKJRHJ3.js.map +7 -0
  11. package/dist/react/EraserTrail-PA6IQLQN.js +20 -0
  12. package/dist/react/EraserTrail-PA6IQLQN.js.map +7 -0
  13. package/dist/react/EventDispatcher-SRFH6LQZ.js +463 -0
  14. package/dist/react/EventDispatcher-SRFH6LQZ.js.map +7 -0
  15. package/dist/react/Frame-6UR5XPAX.js +10 -0
  16. package/dist/react/Frame-6UR5XPAX.js.map +7 -0
  17. package/dist/react/FreehandStroke-CK24NUT3.js +8 -0
  18. package/dist/react/FreehandStroke-CK24NUT3.js.map +7 -0
  19. package/dist/react/GraphEngine-QE5B2PMR.js +340 -0
  20. package/dist/react/GraphEngine-QE5B2PMR.js.map +7 -0
  21. package/dist/react/GraphMathParser-2WMTY4IE.js +10 -0
  22. package/dist/react/GraphMathParser-2WMTY4IE.js.map +7 -0
  23. package/dist/react/IconShape-KMIA6T2H.js +10 -0
  24. package/dist/react/IconShape-KMIA6T2H.js.map +7 -0
  25. package/dist/react/ImageShape-CHHGBXUQ.js +10 -0
  26. package/dist/react/ImageShape-CHHGBXUQ.js.map +7 -0
  27. package/dist/react/LayerOrder-XCHF4MSS.js +66 -0
  28. package/dist/react/LayerOrder-XCHF4MSS.js.map +7 -0
  29. package/dist/react/Line-2KOQEEGA.js +10 -0
  30. package/dist/react/Line-2KOQEEGA.js.map +7 -0
  31. package/dist/react/LixScriptParser-JYWJX375.js +1033 -0
  32. package/dist/react/LixScriptParser-JYWJX375.js.map +7 -0
  33. package/dist/react/MermaidFlowchartRenderer-4QBAZ5MB.js +412 -0
  34. package/dist/react/MermaidFlowchartRenderer-4QBAZ5MB.js.map +7 -0
  35. package/dist/react/MermaidSequenceParser-UKG2NSZY.js +8 -0
  36. package/dist/react/MermaidSequenceParser-UKG2NSZY.js.map +7 -0
  37. package/dist/react/MermaidSequenceRenderer-HPLHY5II.js +387 -0
  38. package/dist/react/MermaidSequenceRenderer-HPLHY5II.js.map +7 -0
  39. package/dist/react/Rectangle-6FE7RN6W.js +8 -0
  40. package/dist/react/Rectangle-6FE7RN6W.js.map +7 -0
  41. package/dist/react/ResizeCode-WAMDTKSW.js +2 -0
  42. package/dist/react/ResizeCode-WAMDTKSW.js.map +7 -0
  43. package/dist/react/ResizeShapes-LKEQTITP.js +250 -0
  44. package/dist/react/ResizeShapes-LKEQTITP.js.map +7 -0
  45. package/dist/react/SceneSerializer-4U4B24JM.js +739 -0
  46. package/dist/react/SceneSerializer-4U4B24JM.js.map +7 -0
  47. package/dist/react/Selection-VVUHY5YJ.js +34 -0
  48. package/dist/react/Selection-VVUHY5YJ.js.map +7 -0
  49. package/dist/react/SketchEngine-YA4RG3KX.js +413 -0
  50. package/dist/react/SketchEngine-YA4RG3KX.js.map +7 -0
  51. package/dist/react/TextShape-54ZJ66E3.js +8 -0
  52. package/dist/react/TextShape-54ZJ66E3.js.map +7 -0
  53. package/dist/react/UndoRedo-M2JZUBKN.js +30 -0
  54. package/dist/react/UndoRedo-M2JZUBKN.js.map +7 -0
  55. package/dist/react/ZoomPan-U3TXC5AJ.js +186 -0
  56. package/dist/react/ZoomPan-U3TXC5AJ.js.map +7 -0
  57. package/dist/react/arrowTool-CWEMIRXK.js +17 -0
  58. package/dist/react/arrowTool-CWEMIRXK.js.map +7 -0
  59. package/dist/react/boxicons-5JNJQPUP.woff +0 -0
  60. package/dist/react/boxicons-6NVWQSCQ.eot +0 -0
  61. package/dist/react/boxicons-AQ5N6WP7.woff2 +0 -0
  62. package/dist/react/boxicons-GDR4JU3X.ttf +0 -0
  63. package/dist/react/boxicons-NNFHLMOR.svg +1660 -0
  64. package/dist/react/chunk-2OQXI7QB.js +564 -0
  65. package/dist/react/chunk-2OQXI7QB.js.map +7 -0
  66. package/dist/react/chunk-5OUBTHHO.js +187 -0
  67. package/dist/react/chunk-5OUBTHHO.js.map +7 -0
  68. package/dist/react/chunk-6PFXZKL2.js +628 -0
  69. package/dist/react/chunk-6PFXZKL2.js.map +7 -0
  70. package/dist/react/chunk-6SFNWGGZ.js +453 -0
  71. package/dist/react/chunk-6SFNWGGZ.js.map +7 -0
  72. package/dist/react/chunk-7TZSIR6V.js +210 -0
  73. package/dist/react/chunk-7TZSIR6V.js.map +7 -0
  74. package/dist/react/chunk-AJAZC37E.js +662 -0
  75. package/dist/react/chunk-AJAZC37E.js.map +7 -0
  76. package/dist/react/chunk-BU4D2WYQ.js +1213 -0
  77. package/dist/react/chunk-BU4D2WYQ.js.map +7 -0
  78. package/dist/react/chunk-BZE4CEBG.js +747 -0
  79. package/dist/react/chunk-BZE4CEBG.js.map +7 -0
  80. package/dist/react/chunk-CB2RANCB.js +212 -0
  81. package/dist/react/chunk-CB2RANCB.js.map +7 -0
  82. package/dist/react/chunk-DNAG7ML6.js +128 -0
  83. package/dist/react/chunk-DNAG7ML6.js.map +7 -0
  84. package/dist/react/chunk-HZWLPXFN.js +198 -0
  85. package/dist/react/chunk-HZWLPXFN.js.map +7 -0
  86. package/dist/react/chunk-I6HCCIXB.js +572 -0
  87. package/dist/react/chunk-I6HCCIXB.js.map +7 -0
  88. package/dist/react/chunk-IZ5OGWGW.js +235 -0
  89. package/dist/react/chunk-IZ5OGWGW.js.map +7 -0
  90. package/dist/react/chunk-JJCJNLNN.js +1490 -0
  91. package/dist/react/chunk-JJCJNLNN.js.map +7 -0
  92. package/dist/react/chunk-JQ3IRFDP.js +222 -0
  93. package/dist/react/chunk-JQ3IRFDP.js.map +7 -0
  94. package/dist/react/chunk-L5OARZJ7.js +1134 -0
  95. package/dist/react/chunk-L5OARZJ7.js.map +7 -0
  96. package/dist/react/chunk-LHRTXNVE.js +1600 -0
  97. package/dist/react/chunk-LHRTXNVE.js.map +7 -0
  98. package/dist/react/chunk-Q2GA4MBZ.js +1653 -0
  99. package/dist/react/chunk-Q2GA4MBZ.js.map +7 -0
  100. package/dist/react/chunk-QNSE5BAY.js +519 -0
  101. package/dist/react/chunk-QNSE5BAY.js.map +7 -0
  102. package/dist/react/chunk-QXFBG7OM.js +191 -0
  103. package/dist/react/chunk-QXFBG7OM.js.map +7 -0
  104. package/dist/react/chunk-T6ZVV5ZO.js +714 -0
  105. package/dist/react/chunk-T6ZVV5ZO.js.map +7 -0
  106. package/dist/react/chunk-URB6MY46.js +974 -0
  107. package/dist/react/chunk-URB6MY46.js.map +7 -0
  108. package/dist/react/chunk-VN62KLOC.js +931 -0
  109. package/dist/react/chunk-VN62KLOC.js.map +7 -0
  110. package/dist/react/chunk-VQVEPJSA.js +158 -0
  111. package/dist/react/chunk-VQVEPJSA.js.map +7 -0
  112. package/dist/react/chunk-XISEAGBV.js +1632 -0
  113. package/dist/react/chunk-XISEAGBV.js.map +7 -0
  114. package/dist/react/chunk-YKJUBFHE.js +575 -0
  115. package/dist/react/chunk-YKJUBFHE.js.map +7 -0
  116. package/dist/react/circleTool-NUATSEI2.js +14 -0
  117. package/dist/react/circleTool-NUATSEI2.js.map +7 -0
  118. package/dist/react/codeTool-MHCB2FNB.js +38 -0
  119. package/dist/react/codeTool-MHCB2FNB.js.map +7 -0
  120. package/dist/react/eraserTool-2GS2LQCS.js +103 -0
  121. package/dist/react/eraserTool-2GS2LQCS.js.map +7 -0
  122. package/dist/react/frameTool-PWVKKXSP.js +14 -0
  123. package/dist/react/frameTool-PWVKKXSP.js.map +7 -0
  124. package/dist/react/freehandTool-SLYGASVP.js +14 -0
  125. package/dist/react/freehandTool-SLYGASVP.js.map +7 -0
  126. package/dist/react/iconTool-GPZ7O7NH.js +18 -0
  127. package/dist/react/iconTool-GPZ7O7NH.js.map +7 -0
  128. package/dist/react/imageTool-D5R4XGEU.js +15 -0
  129. package/dist/react/imageTool-D5R4XGEU.js.map +7 -0
  130. package/dist/react/index.js +5342 -0
  131. package/dist/react/index.js.map +7 -0
  132. package/dist/react/laserTool-XVMV63AV.js +239 -0
  133. package/dist/react/laserTool-XVMV63AV.js.map +7 -0
  134. package/dist/react/lineTool-WNI5EMZ5.js +14 -0
  135. package/dist/react/lineTool-WNI5EMZ5.js.map +7 -0
  136. package/dist/react/lixCode-OJMVUXXI.ttf +0 -0
  137. package/dist/react/lixDefault-JEAPAUJL.ttf +0 -0
  138. package/dist/react/lixFancy-BPXYM5CQ.ttf +0 -0
  139. package/dist/react/lixFont-CPKEUDVM.woff2 +0 -0
  140. package/dist/react/rectangleTool-U7DZ6ZTA.js +14 -0
  141. package/dist/react/rectangleTool-U7DZ6ZTA.js.map +7 -0
  142. package/dist/react/styles.css +6627 -0
  143. package/dist/react/textTool-M7S6F3VC.js +21 -0
  144. package/dist/react/textTool-M7S6F3VC.js.map +7 -0
  145. package/package.json +39 -5
  146. package/src/EngineShortcuts.js +83 -27
  147. package/src/core/AIRenderer.js +30 -18
  148. package/src/core/GraphEngine.js +64 -41
  149. package/src/core/MermaidFlowchartRenderer.js +153 -88
  150. package/src/core/MermaidSequenceRenderer.js +168 -93
  151. package/src/core/SceneSerializer.js +86 -2
  152. package/src/core/Selection.js +119 -19
  153. package/src/core/UndoRedo.js +82 -15
  154. package/src/core/ZoomPan.js +15 -5
  155. package/src/index.js +14 -1
  156. package/src/react/LixSketchCanvas.jsx +347 -0
  157. package/src/react/components/AppMenu.jsx +475 -0
  158. package/src/react/components/Footer.jsx +85 -0
  159. package/src/react/components/Toolbar.jsx +140 -0
  160. package/src/react/components/canvas/CanvasLoadingOverlay.jsx +76 -0
  161. package/src/react/components/canvas/ContextMenu.jsx +466 -0
  162. package/src/react/components/canvas/FindBar.jsx +177 -0
  163. package/src/react/components/canvas/ImageSourcePicker.jsx +133 -0
  164. package/src/react/components/canvas/MultiSelectActions.jsx +120 -0
  165. package/src/react/components/canvas/SVGCanvas.jsx +145 -0
  166. package/src/react/components/canvas/SaveStatusIndicator.jsx +29 -0
  167. package/src/react/components/modals/CanvasPropertiesModal.jsx +358 -0
  168. package/src/react/components/modals/CommandPalette.jsx +307 -0
  169. package/src/react/components/modals/ExportImageModal.jsx +287 -0
  170. package/src/react/components/modals/GraphModal.jsx +174 -0
  171. package/src/react/components/modals/HelpModal.jsx +208 -0
  172. package/src/react/components/modals/LixScriptModal.jsx +130 -0
  173. package/src/react/components/modals/ShortcutsModal.jsx +125 -0
  174. package/src/react/components/sidebars/ArrowSidebar.jsx +173 -0
  175. package/src/react/components/sidebars/CircleSidebar.jsx +134 -0
  176. package/src/react/components/sidebars/FrameSidebar.jsx +263 -0
  177. package/src/react/components/sidebars/IconSidebar.jsx +279 -0
  178. package/src/react/components/sidebars/ImageSidebar.jsx +69 -0
  179. package/src/react/components/sidebars/LineSidebar.jsx +109 -0
  180. package/src/react/components/sidebars/PaintbrushSidebar.jsx +119 -0
  181. package/src/react/components/sidebars/RectangleSidebar.jsx +165 -0
  182. package/src/react/components/sidebars/ShapeSidebar.jsx +130 -0
  183. package/src/react/components/sidebars/TextSidebar.jsx +174 -0
  184. package/src/react/hooks/inertStores.js +58 -0
  185. package/src/react/hooks/useSketchEngine.js +76 -0
  186. package/src/react/hooks/useTranslation.js +92 -0
  187. package/src/react/index.js +41 -0
  188. package/src/react/store/useSketchStore.js +234 -0
  189. package/src/react/store/useUIStore.js +196 -0
  190. package/src/react/styles/arrowSidebar.css +263 -0
  191. package/src/react/styles/canvasStroke.css +47 -0
  192. package/src/react/styles/canvasTools.css +769 -0
  193. package/src/react/styles/circleSidebar.css +206 -0
  194. package/src/react/styles/fonts/fonts.css +29 -0
  195. package/src/react/styles/fonts/lixCode.ttf +0 -0
  196. package/src/react/styles/fonts/lixDefault.ttf +0 -0
  197. package/src/react/styles/fonts/lixDocs.ttf +0 -0
  198. package/src/react/styles/fonts/lixFancy.ttf +0 -0
  199. package/src/react/styles/fonts/lixFont.woff2 +0 -0
  200. package/src/react/styles/lineSidebar.css +207 -0
  201. package/src/react/styles/paintbrushSidebar.css +247 -0
  202. package/src/react/styles/squareSidebar.css +206 -0
  203. package/src/react/styles/writeText.css +149 -0
  204. package/src/react/styles.css +175 -0
  205. package/src/react/toolsEnum.js +20 -0
  206. package/src/react/utils/toast.js +18 -0
  207. package/src/shapes/Frame.js +7 -1
  208. package/src/shapes/Line.js +11 -5
  209. package/src/tools/arrowTool.js +30 -4
  210. package/src/tools/circleTool.js +33 -9
  211. package/src/tools/codeTool.js +5 -3
  212. package/src/tools/frameTool.js +47 -7
  213. package/src/tools/freehandTool.js +12 -4
  214. package/src/tools/iconTool.js +7 -1
  215. package/src/tools/imageTool.js +7 -1
  216. package/src/tools/lineTool.js +27 -3
  217. package/src/tools/rectangleTool.js +45 -8
  218. package/src/tools/textTool.js +23 -6
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/shapes/Line.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n// Line shape class - extracted from lineTool.js\n// Depends on globals: svg, shapes, rough, currentShape, currentZoom\nimport { updateAttachedArrows as updateArrowsForShape } from '../tools/arrowTool.js';\n\nconst rc = rough.svg(svg);\n// Issue #38 follow-up: read the default stroke from the active theme\n// instead of pinning to a single colour. White was invisible on the new\n// light canvas, near-black is invisible if the user toggles dark.\nfunction getThemeStroke() {\n if (typeof document === 'undefined') return '#fff';\n return document.body && document.body.classList.contains('theme-dark') ? '#fff' : '#1a1a2e';\n}\nconst lineStrokeWidth = 2;\nlet hoveredFrameLine = null;\n\nclass Line {\n constructor(startPoint, endPoint, options = {}) {\n this.startPoint = startPoint;\n this.endPoint = endPoint;\n this.options = { ...options };\n this.group = document.createElementNS('http://www.w3.org/2000/svg', 'g');\n this.isSelected = false;\n this.anchors = [];\n this.selectionOutline = null;\n this.shapeName = \"line\"; \n this.shapeID = `line-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`; \n this.group.setAttribute('id', this.shapeID);\n \n // Curve properties\n this.isCurved = false;\n this.controlPoint = null;\n \n // Frame attachment properties\n this.parentFrame = null;\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._isEditingLabel = false;\n this._hitArea = null;\n this._labelBg = null;\n\n svg.appendChild(this.group);\n this._setupLabelDblClick();\n this.draw();\n }\n\n // Add position and dimension properties for frame compatibility\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.controlPoint) {\n this.controlPoint.x += dx;\n }\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.controlPoint) {\n this.controlPoint.y += dy;\n }\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 this.startPoint.x = centerX - value / 2;\n this.endPoint.x = centerX + value / 2;\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 this.startPoint.y = centerY - value / 2;\n this.endPoint.y = centerY + value / 2;\n }\n\n initializeCurveControlPoint() {\n const midX = (this.startPoint.x + this.endPoint.x) / 2;\n const midY = (this.startPoint.y + this.endPoint.y) / 2;\n \n // Calculate perpendicular offset for curve\n const dx = this.endPoint.x - this.startPoint.x;\n const dy = this.endPoint.y - this.startPoint.y;\n const length = Math.sqrt(dx * dx + dy * dy);\n \n if (length === 0) {\n this.controlPoint = { x: midX, y: midY - 20 };\n return;\n }\n \n // Perpendicular vector\n const perpX = -dy / length;\n const perpY = dx / length;\n const curveOffset = 30; // Default curve amount\n \n this.controlPoint = {\n x: midX + perpX * curveOffset,\n y: midY + perpY * curveOffset\n };\n }\n\n draw() {\n // Clear existing elements but preserve label, hit area, and anchors during active resize\n const childrenToRemove = [];\n const preserveSet = this._skipAnchors ? new Set([...this.anchors, this.selectionOutline].filter(Boolean)) : 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 (preserveSet && preserveSet.has(child)) continue;\n childrenToRemove.push(child);\n }\n }\n childrenToRemove.forEach(child => this.group.removeChild(child));\n\n const rc = rough.svg(svg);\n let lineElement;\n\n if (this.isCurved && this.controlPoint) {\n const pathData = `M ${this.startPoint.x} ${this.startPoint.y} Q ${this.controlPoint.x} ${this.controlPoint.y} ${this.endPoint.x} ${this.endPoint.y}`;\n lineElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n lineElement.setAttribute('d', pathData);\n lineElement.setAttribute('stroke', this.options.stroke || getThemeStroke());\n lineElement.setAttribute('stroke-width', this.options.strokeWidth || lineStrokeWidth);\n lineElement.setAttribute('fill', 'none');\n lineElement.setAttribute('stroke-linecap', 'round');\n if (this.options.strokeDasharray) {\n lineElement.setAttribute('stroke-dasharray', this.options.strokeDasharray);\n }\n } else if (this.isBeingDrawn || this.options.strokeDasharray) {\n // Use plain SVG for lines being drawn OR dashed/dotted lines\n // (RoughJS ignores strokeDasharray, so dashed styles must bypass it)\n lineElement = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n lineElement.setAttribute('x1', this.startPoint.x);\n lineElement.setAttribute('y1', this.startPoint.y);\n lineElement.setAttribute('x2', this.endPoint.x);\n lineElement.setAttribute('y2', this.endPoint.y);\n lineElement.setAttribute('stroke', this.options.stroke || getThemeStroke());\n lineElement.setAttribute('stroke-width', this.options.strokeWidth || lineStrokeWidth);\n lineElement.setAttribute('stroke-linecap', 'round');\n if (this.options.strokeDasharray) {\n lineElement.setAttribute('stroke-dasharray', this.options.strokeDasharray);\n }\n } else {\n lineElement = rc.line(\n this.startPoint.x, this.startPoint.y,\n this.endPoint.x, this.endPoint.y,\n this.options\n );\n }\n\n this.element = lineElement;\n this.group.appendChild(lineElement);\n\n // Hit area - thicker invisible path for dblclick detection\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 if (this.isCurved && this.controlPoint) {\n this._hitArea.setAttribute('d', `M ${this.startPoint.x} ${this.startPoint.y} Q ${this.controlPoint.x} ${this.controlPoint.y} ${this.endPoint.x} ${this.endPoint.y}`);\n } else {\n this._hitArea.setAttribute('d', `M ${this.startPoint.x} ${this.startPoint.y} L ${this.endPoint.x} ${this.endPoint.y}`);\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 }\n }\n }\n\n _getMidpoint() {\n if (this.isCurved && this.controlPoint) {\n // Quadratic bezier midpoint at t=0.5\n const t = 0.5;\n const mx = (1 - t) * (1 - t) * this.startPoint.x + 2 * (1 - t) * t * this.controlPoint.x + t * t * this.endPoint.x;\n const my = (1 - t) * (1 - t) * this.startPoint.y + 2 * (1 - t) * t * this.controlPoint.y + t * t * this.endPoint.y;\n return { x: mx, y: my };\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 _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 this.labelElement.setAttribute('x', mid.x);\n this.labelElement.setAttribute('y', mid.y);\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 // Background knockout rect - hides the line 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', mid.x - bgW / 2);\n this._labelBg.setAttribute('y', mid.y - 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 line 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 updateSelectionControls() {\n if (this.anchors.length === 0) return;\n\n // Update start anchor\n if (this.anchors[0]) {\n this.anchors[0].setAttribute('cx', this.startPoint.x);\n this.anchors[0].setAttribute('cy', this.startPoint.y);\n }\n\n // Update end anchor\n if (this.anchors[1]) {\n this.anchors[1].setAttribute('cx', this.endPoint.x);\n this.anchors[1].setAttribute('cy', this.endPoint.y);\n }\n\n // Update middle anchor\n if (this.anchors[2]) {\n const midX = (this.startPoint.x + this.endPoint.x) / 2;\n const midY = (this.startPoint.y + this.endPoint.y) / 2;\n let anchorMidX = midX, anchorMidY = midY;\n if (this.isCurved && this.controlPoint) {\n anchorMidX = 0.25 * this.startPoint.x + 0.5 * this.controlPoint.x + 0.25 * this.endPoint.x;\n anchorMidY = 0.25 * this.startPoint.y + 0.5 * this.controlPoint.y + 0.25 * this.endPoint.y;\n }\n this.anchors[2].setAttribute('cx', anchorMidX);\n this.anchors[2].setAttribute('cy', anchorMidY);\n }\n }\n\n selectLine() {\n this.isSelected = true;\n this.addAnchors();\n}\n\ndeselectLine() {\n this.isSelected = false;\n this.removeSelection();\n}\n\n// Update the complete removeSelection method\nremoveSelection() {\n // Remove anchors\n this.anchors.forEach(anchor => {\n if (anchor && anchor.parentNode === this.group) {\n this.group.removeChild(anchor);\n }\n });\n this.anchors = [];\n this.isSelected = false; // Only set to false when actually deselecting\n}\n\n addAnchors() {\n // Only remove existing anchors if they exist, don't call full removeSelection\n this.anchors.forEach(anchor => {\n if (anchor && anchor.parentNode === this.group) {\n this.group.removeChild(anchor);\n }\n });\n this.anchors = [];\n \n const anchorSize = 10 / (currentZoom || 1);\n const anchorStrokeWidth = 2 / (currentZoom || 1);\n \n // Start point anchor\n const startAnchor = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n startAnchor.setAttribute('cx', this.startPoint.x);\n startAnchor.setAttribute('cy', this.startPoint.y);\n startAnchor.setAttribute('r', anchorSize / 2);\n startAnchor.setAttribute('fill', '#121212');\n startAnchor.setAttribute('stroke', '#5B57D1');\n startAnchor.setAttribute('stroke-width', anchorStrokeWidth);\n startAnchor.setAttribute('vector-effect', 'non-scaling-stroke');\n startAnchor.setAttribute('class', 'anchor line-anchor');\n startAnchor.style.cursor = 'grab';\n startAnchor.style.pointerEvents = 'all';\n startAnchor.dataset.index = 0;\n this.group.appendChild(startAnchor);\n this.anchors[0] = startAnchor;\n\n // End point anchor\n const endAnchor = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n endAnchor.setAttribute('cx', this.endPoint.x);\n endAnchor.setAttribute('cy', this.endPoint.y);\n endAnchor.setAttribute('r', anchorSize / 2);\n endAnchor.setAttribute('fill', '#121212');\n endAnchor.setAttribute('stroke', '#5B57D1');\n endAnchor.setAttribute('stroke-width', anchorStrokeWidth);\n endAnchor.setAttribute('vector-effect', 'non-scaling-stroke');\n endAnchor.setAttribute('class', 'anchor line-anchor');\n endAnchor.style.cursor = 'grab';\n endAnchor.style.pointerEvents = 'all';\n endAnchor.dataset.index = 1;\n this.group.appendChild(endAnchor);\n this.anchors[1] = endAnchor;\n\n // Middle anchor for curving - positioned ON the bezier curve at t=0.5\n const midX = (this.startPoint.x + this.endPoint.x) / 2;\n const midY = (this.startPoint.y + this.endPoint.y) / 2;\n let anchorMidX = midX, anchorMidY = midY;\n if (this.isCurved && this.controlPoint) {\n // Bezier point at t=0.5: 0.25*P0 + 0.5*CP + 0.25*P1\n anchorMidX = 0.25 * this.startPoint.x + 0.5 * this.controlPoint.x + 0.25 * this.endPoint.x;\n anchorMidY = 0.25 * this.startPoint.y + 0.5 * this.controlPoint.y + 0.25 * this.endPoint.y;\n }\n\n const middleAnchor = document.createElementNS('http://www.w3.org/2000/svg', 'circle');\n middleAnchor.setAttribute('cx', anchorMidX);\n middleAnchor.setAttribute('cy', anchorMidY);\n middleAnchor.setAttribute('r', anchorSize / 2);\n middleAnchor.setAttribute('fill', this.isCurved ? '#5B57D1' : '#121212');\n middleAnchor.setAttribute('stroke', '#5B57D1');\n middleAnchor.setAttribute('stroke-width', anchorStrokeWidth);\n middleAnchor.setAttribute('vector-effect', 'non-scaling-stroke');\n middleAnchor.setAttribute('class', 'anchor line-middle-anchor');\n middleAnchor.style.cursor = 'grab';\n middleAnchor.style.pointerEvents = 'all';\n middleAnchor.dataset.index = 2;\n this.group.appendChild(middleAnchor);\n this.anchors[2] = middleAnchor;\n\n // Show line sidebar\n disableAllSideBars();\n lineSideBar.classList.remove(\"hidden\");\n if (window.__showSidebarForShape) window.__showSidebarForShape('line');\n this.updateSidebar();\n }\n\n isNearAnchor(x, y) {\n if (!this.isSelected) return null;\n const buffer = 15; // Increased buffer for easier selection\n const anchorSize = 10 / (currentZoom || 1);\n\n // Check anchors\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 / 2 + buffer) {\n return { type: 'anchor', index: i };\n }\n }\n }\n \n return null;\n }\n\n updatePosition(anchorIndex, newX, newY) {\n if (anchorIndex === 0) {\n this.startPoint.x = newX;\n this.startPoint.y = newY;\n } else if (anchorIndex === 1) {\n this.endPoint.x = newX;\n this.endPoint.y = newY;\n } else if (anchorIndex === 2) {\n // Middle anchor - dragged position is ON the curve (bezier t=0.5)\n if (!this.isCurved) {\n this.isCurved = true;\n }\n // Invert bezier formula: CP = 2*M - 0.5*(P0+P1)\n this.controlPoint = {\n x: 2 * newX - 0.5 * (this.startPoint.x + this.endPoint.x),\n y: 2 * newY - 0.5 * (this.startPoint.y + this.endPoint.y)\n };\n }\n\n // Full redraw to keep anchors, hit area, and label in sync\n this.draw();\n }\n\n updateLineElement() {\n // Update just the line element without rebuilding entire structure\n if (this.element && this.element.parentNode) {\n this.element.parentNode.removeChild(this.element);\n }\n\n const rc = rough.svg(svg);\n let lineElement;\n\n if (this.isCurved && this.controlPoint) {\n const pathData = `M ${this.startPoint.x} ${this.startPoint.y} Q ${this.controlPoint.x} ${this.controlPoint.y} ${this.endPoint.x} ${this.endPoint.y}`;\n lineElement = document.createElementNS('http://www.w3.org/2000/svg', 'path');\n lineElement.setAttribute('d', pathData);\n lineElement.setAttribute('stroke', this.options.stroke || getThemeStroke());\n lineElement.setAttribute('stroke-width', this.options.strokeWidth || lineStrokeWidth);\n lineElement.setAttribute('fill', 'none');\n lineElement.setAttribute('stroke-linecap', 'round');\n if (this.options.strokeDasharray) {\n lineElement.setAttribute('stroke-dasharray', this.options.strokeDasharray);\n }\n } else if (this.options.strokeDasharray) {\n // Dashed/dotted lines must use plain SVG (RoughJS ignores strokeDasharray)\n lineElement = document.createElementNS('http://www.w3.org/2000/svg', 'line');\n lineElement.setAttribute('x1', this.startPoint.x);\n lineElement.setAttribute('y1', this.startPoint.y);\n lineElement.setAttribute('x2', this.endPoint.x);\n lineElement.setAttribute('y2', this.endPoint.y);\n lineElement.setAttribute('stroke', this.options.stroke || getThemeStroke());\n lineElement.setAttribute('stroke-width', this.options.strokeWidth || lineStrokeWidth);\n lineElement.setAttribute('stroke-linecap', 'round');\n lineElement.setAttribute('stroke-dasharray', this.options.strokeDasharray);\n } else {\n lineElement = rc.line(\n this.startPoint.x, this.startPoint.y,\n this.endPoint.x, this.endPoint.y,\n this.options\n );\n }\n\n this.element = lineElement;\n this.group.insertBefore(lineElement, this.group.firstChild);\n }\n\n updateAnchorPositions() {\n // Update anchor positions without rebuilding them\n if (this.anchors[0]) {\n this.anchors[0].setAttribute('cx', this.startPoint.x);\n this.anchors[0].setAttribute('cy', this.startPoint.y);\n }\n if (this.anchors[1]) {\n this.anchors[1].setAttribute('cx', this.endPoint.x);\n this.anchors[1].setAttribute('cy', this.endPoint.y);\n }\n if (this.anchors[2]) {\n const midX = (this.startPoint.x + this.endPoint.x) / 2;\n const midY = (this.startPoint.y + this.endPoint.y) / 2;\n let anchorMidX = midX, anchorMidY = midY;\n if (this.isCurved && this.controlPoint) {\n // Bezier point at t=0.5: 0.25*P0 + 0.5*CP + 0.25*P1\n anchorMidX = 0.25 * this.startPoint.x + 0.5 * this.controlPoint.x + 0.25 * this.endPoint.x;\n anchorMidY = 0.25 * this.startPoint.y + 0.5 * this.controlPoint.y + 0.25 * this.endPoint.y;\n }\n this.anchors[2].setAttribute('cx', anchorMidX);\n this.anchors[2].setAttribute('cy', anchorMidY);\n this.anchors[2].setAttribute('fill', this.isCurved ? '#5B57D1' : '#121212');\n }\n }\n\n // Add move method for dragging the entire line\n move(dx, dy) {\n this.startPoint.x += dx;\n this.startPoint.y += dy;\n this.endPoint.x += dx;\n this.endPoint.y += dy;\n if (this.controlPoint) {\n this.controlPoint.x += dx;\n this.controlPoint.y += dy;\n }\n\n // Update without full redraw to prevent jitter\n this.updateLineElement();\n this.updateAnchorPositions();\n\n // Update hit area path\n if (this._hitArea) {\n if (this.isCurved && this.controlPoint) {\n this._hitArea.setAttribute('d', `M ${this.startPoint.x} ${this.startPoint.y} Q ${this.controlPoint.x} ${this.controlPoint.y} ${this.endPoint.x} ${this.endPoint.y}`);\n } else {\n this._hitArea.setAttribute('d', `M ${this.startPoint.x} ${this.startPoint.y} L ${this.endPoint.x} ${this.endPoint.y}`);\n }\n }\n\n // Update label position\n this._updateLabelElement();\n\n // Only update frame containment if not being moved by a parent frame\n if (!this.isBeingMovedByFrame) {\n this.updateFrameContainment();\n }\n\n this.updateAttachedArrows();\n }\n\n updateAttachedArrows() {\n updateArrowsForShape(this);\n }\n\n updateFrameContainment() {\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) {\n this.parentFrame.temporarilyRemoveFromFrame(this);\n }\n \n // Update frame highlighting\n if (hoveredFrameLine && hoveredFrameLine !== targetFrame) {\n hoveredFrameLine.removeHighlight();\n }\n \n if (targetFrame && targetFrame !== hoveredFrameLine) {\n targetFrame.highlightFrame();\n }\n \n hoveredFrameLine = targetFrame;\n }\n\n contains(x, y) {\n const tolerance = 8 / (currentZoom || 1); // Slightly larger tolerance for easier selection\n \n if (this.isCurved && this.controlPoint) {\n return this.pointToQuadraticBezierDistance(x, y) <= tolerance;\n } else {\n return this.pointToLineDistance(x, y, this.startPoint.x, this.startPoint.y, this.endPoint.x, this.endPoint.y) <= tolerance;\n }\n }\n\n pointToQuadraticBezierDistance(x, y) {\n let minDistance = Infinity;\n const steps = 50; // Reduced steps for better performance\n\n for (let i = 0; i <= steps; i++) {\n const t = i / steps;\n const point = this.getQuadraticBezierPoint(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 getQuadraticBezierPoint(t) {\n if (!this.controlPoint) return this.startPoint;\n \n const mt = 1 - t;\n return {\n x: mt * mt * this.startPoint.x + 2 * mt * t * this.controlPoint.x + t * t * this.endPoint.x,\n y: mt * mt * this.startPoint.y + 2 * mt * t * this.controlPoint.y + t * t * this.endPoint.y\n };\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 const dot = A * C + B * D;\n const lenSq = C * C + D * D;\n let param = -1;\n if (lenSq !== 0) param = dot / lenSq;\n let xx, yy;\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 const dx = x - xx;\n const dy = y - yy;\n return Math.sqrt(dx * dx + dy * dy);\n }\n\n // No-op: React sidebar handles UI updates via Zustand store\n updateSidebar() {}\n}\n\nexport { Line };\n"],
5
+ "mappings": "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",
6
+ "names": ["rc"]
7
+ }
@@ -0,0 +1,453 @@
1
+ "use client";
2
+ import {
3
+ calculateSnap,
4
+ clearSnapGuides
5
+ } from "./chunk-BZE4CEBG.js";
6
+ import {
7
+ pushCreateAction,
8
+ pushDeleteAction,
9
+ pushFrameAttachmentAction,
10
+ pushOptionsChangeAction,
11
+ pushTransformAction
12
+ } from "./chunk-L5OARZJ7.js";
13
+
14
+ // src/tools/lineTool.js
15
+ function getThemeStroke() {
16
+ if (typeof document === "undefined") return "#fff";
17
+ return document.body && document.body.classList.contains("theme-dark") ? "#fff" : "#1a1a2e";
18
+ }
19
+ var isDrawingLine = false;
20
+ var currentLine = null;
21
+ var lineColor = null;
22
+ var lineStrokeWidth = 3;
23
+ var lineStrokeStyle = "solid";
24
+ var lineEdgeType = 1;
25
+ var lineSktetchRate = 3;
26
+ var isDraggingLine = false;
27
+ var dragOldPosLine = null;
28
+ var draggedShapeInitialFrameLine = null;
29
+ var hoveredFrameLine = null;
30
+ var startX;
31
+ var startY;
32
+ var lineColorOptions = document.querySelectorAll(".lineColor > span");
33
+ var lineThicknessOptions = document.querySelectorAll(".lineThicknessSpan");
34
+ var lineOutlineOptions = document.querySelectorAll(".lineStyleSpan");
35
+ var lineSlopeOptions = document.querySelectorAll(".lineSlopeSpan");
36
+ var lineEdgeOptions = document.querySelectorAll(".lineEdgeSpan");
37
+ function getSVGCoordsFromMouse(e) {
38
+ const viewBox = svg.viewBox.baseVal;
39
+ const rect = svg.getBoundingClientRect();
40
+ const mouseX = e.clientX - rect.left;
41
+ const mouseY = e.clientY - rect.top;
42
+ const svgX = viewBox.x + mouseX / rect.width * viewBox.width;
43
+ const svgY = viewBox.y + mouseY / rect.height * viewBox.height;
44
+ return { x: svgX, y: svgY };
45
+ }
46
+ function deleteCurrentShape() {
47
+ if (currentShape && currentShape.shapeName === "line") {
48
+ const idx = shapes.indexOf(currentShape);
49
+ if (idx !== -1) shapes.splice(idx, 1);
50
+ if (currentShape.group.parentNode) {
51
+ currentShape.group.parentNode.removeChild(currentShape.group);
52
+ }
53
+ pushDeleteAction(currentShape);
54
+ currentShape = null;
55
+ disableAllSideBars();
56
+ }
57
+ }
58
+ document.addEventListener("keydown", (e) => {
59
+ if (e.key === "Delete" && currentShape && currentShape.shapeName === "line") {
60
+ deleteCurrentShape();
61
+ }
62
+ });
63
+ var handleMouseDown = (e) => {
64
+ if (!isLineToolActive && !isSelectionToolActive) return;
65
+ const { x, y } = getSVGCoordsFromMouse(e);
66
+ if (isLineToolActive) {
67
+ isDrawingLine = true;
68
+ currentLine = new Line(
69
+ { x, y },
70
+ { x, y },
71
+ {
72
+ stroke: lineColor ?? getThemeStroke(),
73
+ strokeWidth: lineStrokeWidth,
74
+ roughness: lineSktetchRate,
75
+ bowing: lineEdgeType,
76
+ strokeDasharray: lineStrokeStyle === "dashed" ? "5,5" : lineStrokeStyle === "dotted" ? "2,12" : ""
77
+ }
78
+ );
79
+ currentLine.isBeingDrawn = true;
80
+ shapes.push(currentLine);
81
+ currentShape = currentLine;
82
+ } else if (isSelectionToolActive) {
83
+ let clickedOnShape = false;
84
+ if (currentShape && currentShape.shapeName === "line" && currentShape.isSelected) {
85
+ const anchorInfo = currentShape.isNearAnchor(x, y);
86
+ if (anchorInfo && anchorInfo.type === "anchor") {
87
+ clickedOnShape = true;
88
+ dragOldPosLine = {
89
+ startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },
90
+ endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },
91
+ controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,
92
+ isCurved: currentShape.isCurved,
93
+ parentFrame: currentShape.parentFrame
94
+ };
95
+ const anchorIndex = anchorInfo.index;
96
+ const onPointerMove = (event) => {
97
+ const { x: newX, y: newY } = getSVGCoordsFromMouse(event);
98
+ currentShape.updatePosition(anchorIndex, newX, newY);
99
+ };
100
+ const onPointerUp = () => {
101
+ if (dragOldPosLine) {
102
+ const newPos = {
103
+ startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },
104
+ endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },
105
+ controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,
106
+ isCurved: currentShape.isCurved,
107
+ parentFrame: currentShape.parentFrame
108
+ };
109
+ pushTransformAction(currentShape, dragOldPosLine, newPos);
110
+ dragOldPosLine = null;
111
+ }
112
+ svg.removeEventListener("pointermove", onPointerMove);
113
+ svg.removeEventListener("pointerup", onPointerUp);
114
+ };
115
+ svg.addEventListener("pointermove", onPointerMove);
116
+ svg.addEventListener("pointerup", onPointerUp);
117
+ e.preventDefault();
118
+ e.stopPropagation();
119
+ } else if (currentShape.contains(x, y)) {
120
+ isDraggingLine = true;
121
+ dragOldPosLine = {
122
+ startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },
123
+ endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },
124
+ controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,
125
+ isCurved: currentShape.isCurved,
126
+ parentFrame: currentShape.parentFrame
127
+ };
128
+ draggedShapeInitialFrameLine = currentShape.parentFrame || null;
129
+ if (currentShape.parentFrame) {
130
+ currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);
131
+ }
132
+ startX = x;
133
+ startY = y;
134
+ clickedOnShape = true;
135
+ }
136
+ }
137
+ if (!clickedOnShape) {
138
+ let shapeToSelect = null;
139
+ for (let i = shapes.length - 1; i >= 0; i--) {
140
+ const shape = shapes[i];
141
+ if (shape instanceof Line && shape.contains(x, y)) {
142
+ shapeToSelect = shape;
143
+ break;
144
+ }
145
+ }
146
+ if (currentShape && currentShape !== shapeToSelect) {
147
+ currentShape.removeSelection();
148
+ currentShape = null;
149
+ }
150
+ if (shapeToSelect) {
151
+ currentShape = shapeToSelect;
152
+ currentShape.selectLine();
153
+ clickedOnShape = true;
154
+ }
155
+ }
156
+ if (!clickedOnShape && currentShape) {
157
+ currentShape.removeSelection();
158
+ currentShape = null;
159
+ }
160
+ }
161
+ };
162
+ var handleMouseMove = (e) => {
163
+ const { x, y } = getSVGCoordsFromMouse(e);
164
+ const svgRect = svg.getBoundingClientRect();
165
+ lastMousePos = {
166
+ x: e.clientX - svgRect.left,
167
+ y: e.clientY - svgRect.top
168
+ };
169
+ if (isDrawingLine && currentLine) {
170
+ let endX = x, endY = y;
171
+ if (e.shiftKey) {
172
+ const dx = x - currentLine.startPoint.x;
173
+ const dy = y - currentLine.startPoint.y;
174
+ const angle = Math.atan2(dy, dx);
175
+ const snapAngle = Math.round(angle / (Math.PI / 4)) * (Math.PI / 4);
176
+ const dist = Math.sqrt(dx * dx + dy * dy);
177
+ endX = currentLine.startPoint.x + dist * Math.cos(snapAngle);
178
+ endY = currentLine.startPoint.y + dist * Math.sin(snapAngle);
179
+ }
180
+ currentLine.endPoint = { x: endX, y: endY };
181
+ currentLine.draw();
182
+ shapes.forEach((frame) => {
183
+ if (frame.shapeName === "frame") {
184
+ if (frame.isShapeInFrame(currentLine)) {
185
+ frame.highlightFrame();
186
+ hoveredFrameLine = frame;
187
+ } else if (hoveredFrameLine === frame) {
188
+ frame.removeHighlight();
189
+ hoveredFrameLine = null;
190
+ }
191
+ }
192
+ });
193
+ } else if (isDraggingLine && currentShape && currentShape.isSelected) {
194
+ const dx = x - startX;
195
+ const dy = y - startY;
196
+ currentShape.move(dx, dy);
197
+ startX = x;
198
+ startY = y;
199
+ let newHover = null;
200
+ for (const f of shapes) {
201
+ if (f.shapeName !== "frame") continue;
202
+ if (f === currentShape) continue;
203
+ if (typeof f.isShapeInFrame === "function" && f.isShapeInFrame(currentShape)) {
204
+ newHover = f;
205
+ break;
206
+ }
207
+ }
208
+ if (hoveredFrameLine && hoveredFrameLine !== newHover && typeof hoveredFrameLine.removeHighlight === "function") {
209
+ hoveredFrameLine.removeHighlight();
210
+ }
211
+ if (newHover && newHover !== hoveredFrameLine && typeof newHover.highlightFrame === "function") {
212
+ newHover.highlightFrame();
213
+ }
214
+ hoveredFrameLine = newHover;
215
+ if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {
216
+ const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);
217
+ if (snap.dx || snap.dy) {
218
+ currentShape.move(snap.dx, snap.dy);
219
+ }
220
+ } else {
221
+ clearSnapGuides();
222
+ }
223
+ }
224
+ };
225
+ var handleMouseUp = (e) => {
226
+ if (isDrawingLine) {
227
+ isDrawingLine = false;
228
+ const dx = currentLine.endPoint.x - currentLine.startPoint.x;
229
+ const dy = currentLine.endPoint.y - currentLine.startPoint.y;
230
+ const lengthSq = dx * dx + dy * dy;
231
+ if (lengthSq < (5 / currentZoom) ** 2) {
232
+ shapes.pop();
233
+ if (currentLine.group.parentNode) {
234
+ currentLine.group.parentNode.removeChild(currentLine.group);
235
+ }
236
+ currentLine = null;
237
+ currentShape = null;
238
+ } else {
239
+ currentLine.isBeingDrawn = false;
240
+ currentLine.draw();
241
+ pushCreateAction(currentLine);
242
+ const finalFrame = hoveredFrameLine;
243
+ if (finalFrame) {
244
+ finalFrame.addShapeToFrame(currentLine);
245
+ pushFrameAttachmentAction(finalFrame, currentLine, "attach", null);
246
+ }
247
+ const drawnLine = currentLine;
248
+ if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool("select", { afterDraw: true });
249
+ currentShape = drawnLine;
250
+ drawnLine.selectLine();
251
+ }
252
+ if (hoveredFrameLine) {
253
+ hoveredFrameLine.removeHighlight();
254
+ hoveredFrameLine = null;
255
+ }
256
+ currentLine = null;
257
+ }
258
+ if (isDraggingLine && dragOldPosLine && currentShape) {
259
+ const newPos = {
260
+ startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },
261
+ endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },
262
+ controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,
263
+ parentFrame: hoveredFrameLine || null
264
+ };
265
+ const oldPos = {
266
+ ...dragOldPosLine,
267
+ parentFrame: draggedShapeInitialFrameLine
268
+ };
269
+ const stateChanged = dragOldPosLine.startPoint.x !== newPos.startPoint.x || dragOldPosLine.startPoint.y !== newPos.startPoint.y || dragOldPosLine.endPoint.x !== newPos.endPoint.x || dragOldPosLine.endPoint.y !== newPos.endPoint.y;
270
+ const frameChanged = oldPos.parentFrame !== newPos.parentFrame;
271
+ if (stateChanged || frameChanged) {
272
+ pushTransformAction(currentShape, oldPos, newPos);
273
+ }
274
+ if (isDraggingLine) {
275
+ const finalFrame = hoveredFrameLine;
276
+ if (draggedShapeInitialFrameLine !== finalFrame) {
277
+ if (draggedShapeInitialFrameLine) {
278
+ draggedShapeInitialFrameLine.removeShapeFromFrame(currentShape);
279
+ }
280
+ if (finalFrame) {
281
+ finalFrame.addShapeToFrame(currentShape);
282
+ }
283
+ if (frameChanged) {
284
+ pushFrameAttachmentAction(
285
+ finalFrame || draggedShapeInitialFrameLine,
286
+ currentShape,
287
+ finalFrame ? "attach" : "detach",
288
+ draggedShapeInitialFrameLine
289
+ );
290
+ }
291
+ } else if (draggedShapeInitialFrameLine) {
292
+ draggedShapeInitialFrameLine.restoreToFrame(currentShape);
293
+ }
294
+ }
295
+ dragOldPosLine = null;
296
+ draggedShapeInitialFrameLine = null;
297
+ }
298
+ if (hoveredFrameLine) {
299
+ hoveredFrameLine.removeHighlight();
300
+ hoveredFrameLine = null;
301
+ }
302
+ clearSnapGuides();
303
+ isDraggingLine = false;
304
+ };
305
+ lineColorOptions.forEach((span) => {
306
+ span.addEventListener("click", (event) => {
307
+ event.stopPropagation();
308
+ lineColorOptions.forEach((el) => el.classList.remove("selected"));
309
+ span.classList.add("selected");
310
+ if (currentShape instanceof Line && currentShape.isSelected) {
311
+ const oldOptions = { ...currentShape.options };
312
+ currentShape.options.stroke = span.getAttribute("data-id");
313
+ currentShape.draw();
314
+ pushOptionsChangeAction(currentShape, oldOptions);
315
+ } else {
316
+ lineColor = span.getAttribute("data-id");
317
+ }
318
+ });
319
+ });
320
+ lineThicknessOptions.forEach((span) => {
321
+ span.addEventListener("click", (event) => {
322
+ event.stopPropagation();
323
+ lineThicknessOptions.forEach((el) => el.classList.remove("selected"));
324
+ span.classList.add("selected");
325
+ if (currentShape instanceof Line && currentShape.isSelected) {
326
+ const oldOptions = { ...currentShape.options };
327
+ currentShape.options.strokeWidth = parseInt(span.getAttribute("data-id"));
328
+ currentShape.draw();
329
+ pushOptionsChangeAction(currentShape, oldOptions);
330
+ } else {
331
+ lineStrokeWidth = parseInt(span.getAttribute("data-id"));
332
+ }
333
+ });
334
+ });
335
+ lineOutlineOptions.forEach((span) => {
336
+ span.addEventListener("click", (event) => {
337
+ event.stopPropagation();
338
+ lineOutlineOptions.forEach((el) => el.classList.remove("selected"));
339
+ span.classList.add("selected");
340
+ if (currentShape instanceof Line && currentShape.isSelected) {
341
+ const oldOptions = { ...currentShape.options };
342
+ const style = span.getAttribute("data-id");
343
+ currentShape.options.strokeDasharray = style === "dashed" ? "5,5" : style === "dotted" ? "2,12" : "";
344
+ currentShape.draw();
345
+ pushOptionsChangeAction(currentShape, oldOptions);
346
+ } else {
347
+ lineStrokeStyle = span.getAttribute("data-id");
348
+ }
349
+ });
350
+ });
351
+ lineSlopeOptions.forEach((span) => {
352
+ span.addEventListener("click", (event) => {
353
+ event.stopPropagation();
354
+ lineSlopeOptions.forEach((el) => el.classList.remove("selected"));
355
+ span.classList.add("selected");
356
+ if (currentShape instanceof Line && currentShape.isSelected) {
357
+ const oldOptions = { ...currentShape.options };
358
+ currentShape.options.roughness = parseFloat(span.getAttribute("data-id"));
359
+ currentShape.draw();
360
+ pushOptionsChangeAction(currentShape, oldOptions);
361
+ } else {
362
+ lineSktetchRate = parseFloat(span.getAttribute("data-id"));
363
+ }
364
+ });
365
+ });
366
+ lineEdgeOptions.forEach((span) => {
367
+ span.addEventListener("click", (event) => {
368
+ event.stopPropagation();
369
+ lineEdgeOptions.forEach((el) => el.classList.remove("selected"));
370
+ span.classList.add("selected");
371
+ if (currentShape instanceof Line && currentShape.isSelected) {
372
+ const oldOptions = { ...currentShape.options };
373
+ currentShape.options.bowing = parseFloat(span.getAttribute("data-id"));
374
+ currentShape.draw();
375
+ pushOptionsChangeAction(currentShape, oldOptions);
376
+ } else {
377
+ lineEdgeType = parseFloat(span.getAttribute("data-id"));
378
+ }
379
+ });
380
+ });
381
+ window.Line = Line;
382
+ window.lineToolSettings = {
383
+ get strokeColor() {
384
+ return lineColor;
385
+ },
386
+ set strokeColor(v) {
387
+ lineColor = v;
388
+ },
389
+ get strokeWidth() {
390
+ return lineStrokeWidth;
391
+ },
392
+ set strokeWidth(v) {
393
+ lineStrokeWidth = v;
394
+ },
395
+ get strokeStyle() {
396
+ return lineStrokeStyle;
397
+ },
398
+ set strokeStyle(v) {
399
+ lineStrokeStyle = v;
400
+ },
401
+ get sloppiness() {
402
+ return lineSktetchRate;
403
+ },
404
+ set sloppiness(v) {
405
+ lineSktetchRate = v;
406
+ },
407
+ get edge() {
408
+ return lineEdgeType;
409
+ },
410
+ set edge(v) {
411
+ lineEdgeType = v;
412
+ }
413
+ };
414
+ window.updateSelectedLineStyle = function(changes) {
415
+ if (currentShape instanceof Line && currentShape.isSelected) {
416
+ const oldOptions = { ...currentShape.options };
417
+ if (changes.stroke !== void 0) {
418
+ lineColor = changes.stroke;
419
+ currentShape.options.stroke = changes.stroke;
420
+ }
421
+ if (changes.strokeWidth !== void 0) {
422
+ lineStrokeWidth = changes.strokeWidth;
423
+ currentShape.options.strokeWidth = changes.strokeWidth;
424
+ }
425
+ if (changes.strokeStyle !== void 0) {
426
+ lineStrokeStyle = changes.strokeStyle;
427
+ currentShape.options.strokeDasharray = changes.strokeStyle === "dashed" ? "5,5" : changes.strokeStyle === "dotted" ? "2,12" : "";
428
+ }
429
+ if (changes.sloppiness !== void 0) {
430
+ lineSktetchRate = changes.sloppiness;
431
+ currentShape.options.roughness = changes.sloppiness;
432
+ }
433
+ if (changes.edge !== void 0) {
434
+ lineEdgeType = changes.edge;
435
+ currentShape.options.bowing = changes.edge;
436
+ }
437
+ currentShape.draw();
438
+ pushOptionsChangeAction(currentShape, oldOptions);
439
+ } else {
440
+ if (changes.stroke !== void 0) lineColor = changes.stroke;
441
+ if (changes.strokeWidth !== void 0) lineStrokeWidth = changes.strokeWidth;
442
+ if (changes.strokeStyle !== void 0) lineStrokeStyle = changes.strokeStyle;
443
+ if (changes.sloppiness !== void 0) lineSktetchRate = changes.sloppiness;
444
+ if (changes.edge !== void 0) lineEdgeType = changes.edge;
445
+ }
446
+ };
447
+
448
+ export {
449
+ handleMouseDown,
450
+ handleMouseMove,
451
+ handleMouseUp
452
+ };
453
+ //# sourceMappingURL=chunk-6SFNWGGZ.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/tools/lineTool.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n// Line tool event handlers - extracted from lineTool.js\nimport { pushCreateAction, pushDeleteAction, pushOptionsChangeAction, pushTransformAction, pushFrameAttachmentAction } from '../core/UndoRedo.js';\nimport { updateAttachedArrows as updateArrowsForShape, cleanupAttachments } from './arrowTool.js';\nimport { calculateSnap, clearSnapGuides } from '../core/SnapGuides.js';\n\nfunction getThemeStroke() { if (typeof document === \"undefined\") return \"#fff\"; return document.body && document.body.classList.contains(\"theme-dark\") ? \"#fff\" : \"#1a1a2e\"; }\n\nlet isDrawingLine = false;\nlet currentLine = null;\nlet lineStartX = 0; \nlet lineStartY = 0; \nlet currentLineGroup = null; \nlet lineColor = null;\nlet lineStrokeWidth = 3;\nlet lineStrokeStyle = \"solid\";\nlet lineEdgeType = 1;\nlet lineSktetchRate = 3;\n\nlet isDraggingLine = false;\nlet dragOldPosLine = null;\nlet copiedShapeData = null;\nlet draggedShapeInitialFrameLine = null;\nlet hoveredFrameLine = null;\n\nlet startX, startY;\n\nlet lineColorOptions = document.querySelectorAll(\".lineColor > span\");\nlet lineThicknessOptions = document.querySelectorAll(\".lineThicknessSpan\");\nlet lineOutlineOptions = document.querySelectorAll(\".lineStyleSpan\");\nlet lineSlopeOptions = document.querySelectorAll(\".lineSlopeSpan\");\nlet lineEdgeOptions = document.querySelectorAll(\".lineEdgeSpan\");\n\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\n// Add delete functionality\nfunction deleteCurrentShape() {\n if (currentShape && currentShape.shapeName === 'line') {\n const idx = shapes.indexOf(currentShape);\n if (idx !== -1) shapes.splice(idx, 1);\n if (currentShape.group.parentNode) {\n currentShape.group.parentNode.removeChild(currentShape.group);\n }\n pushDeleteAction(currentShape);\n currentShape = null;\n disableAllSideBars();\n }\n}\n\ndocument.addEventListener('keydown', (e) => {\n if (e.key === 'Delete' && currentShape && currentShape.shapeName === 'line') {\n deleteCurrentShape();\n }\n});\n\nconst handleMouseDown = (e) => {\n if (!isLineToolActive && !isSelectionToolActive) return;\n\n const { x, y } = getSVGCoordsFromMouse(e);\n\n if (isLineToolActive) {\n isDrawingLine = true;\n currentLine = new Line(\n { x, y },\n { x, y },\n {\n stroke: lineColor ?? getThemeStroke(),\n strokeWidth: lineStrokeWidth,\n roughness: lineSktetchRate,\n bowing: lineEdgeType,\n strokeDasharray: lineStrokeStyle === \"dashed\" ? \"5,5\" : (lineStrokeStyle === \"dotted\" ? \"2,12\" : \"\")\n }\n );\n currentLine.isBeingDrawn = true;\n shapes.push(currentLine);\n currentShape = currentLine;\n } else if (isSelectionToolActive) {\n let clickedOnShape = false;\n \n // Check if clicking on current selected line\n if (currentShape && currentShape.shapeName === 'line' && currentShape.isSelected) {\n const anchorInfo = currentShape.isNearAnchor(x, y);\n \n if (anchorInfo && anchorInfo.type === 'anchor') {\n clickedOnShape = true;\n // Start anchor drag\n dragOldPosLine = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,\n isCurved: currentShape.isCurved,\n parentFrame: currentShape.parentFrame\n };\n \n const anchorIndex = anchorInfo.index;\n \n const onPointerMove = (event) => {\n const { x: newX, y: newY } = getSVGCoordsFromMouse(event);\n currentShape.updatePosition(anchorIndex, newX, newY);\n };\n \n const onPointerUp = () => {\n if (dragOldPosLine) {\n const newPos = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,\n isCurved: currentShape.isCurved,\n parentFrame: currentShape.parentFrame\n };\n pushTransformAction(currentShape, dragOldPosLine, newPos);\n dragOldPosLine = null;\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 // Prevent default to stop any other drag behavior\n e.preventDefault();\n e.stopPropagation();\n \n } else if (currentShape.contains(x, y)) {\n // Dragging the line itself (not anchors)\n isDraggingLine = true;\n dragOldPosLine = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,\n isCurved: currentShape.isCurved,\n parentFrame: currentShape.parentFrame\n };\n \n // Store initial frame state\n draggedShapeInitialFrameLine = currentShape.parentFrame || null;\n \n // Temporarily remove from frame clipping if dragging\n if (currentShape.parentFrame) {\n currentShape.parentFrame.temporarilyRemoveFromFrame(currentShape);\n }\n \n startX = x;\n startY = y;\n clickedOnShape = true;\n }\n }\n\n // If not clicking on selected shape, check for other shapes\n if (!clickedOnShape) {\n let shapeToSelect = null;\n for (let i = shapes.length - 1; i >= 0; i--) {\n const shape = shapes[i];\n if (shape instanceof Line && shape.contains(x, y)) {\n shapeToSelect = shape;\n break;\n }\n }\n\n if (currentShape && currentShape !== shapeToSelect) {\n currentShape.removeSelection();\n currentShape = null;\n }\n\n if (shapeToSelect) {\n currentShape = shapeToSelect;\n currentShape.selectLine();\n clickedOnShape = true;\n }\n }\n\n if (!clickedOnShape && currentShape) {\n currentShape.removeSelection();\n currentShape = null;\n }\n }\n};\n// Update clone function to remove rotation property\nfunction cloneLineData(line) {\n return {\n startPoint: { x: line.startPoint.x, y: line.startPoint.y },\n endPoint: { x: line.endPoint.x, y: line.endPoint.y },\n controlPoint: line.controlPoint ? { x: line.controlPoint.x, y: line.controlPoint.y } : null,\n isCurved: line.isCurved || false,\n parentFrame: line.parentFrame,\n options: cloneOptions(line.options)\n };\n}\n\nconst handleMouseMove = (e) => {\n const { x, y } = getSVGCoordsFromMouse(e);\n \n // Keep lastMousePos in screen coordinates for other functions\n const svgRect = svg.getBoundingClientRect();\n lastMousePos = {\n x: e.clientX - svgRect.left, \n y: e.clientY - svgRect.top\n };\n \n if (isDrawingLine && currentLine) {\n let endX = x, endY = y;\n if (e.shiftKey) {\n const dx = x - currentLine.startPoint.x;\n const dy = y - currentLine.startPoint.y;\n const angle = Math.atan2(dy, dx);\n const snapAngle = Math.round(angle / (Math.PI / 4)) * (Math.PI / 4);\n const dist = Math.sqrt(dx * dx + dy * dy);\n endX = currentLine.startPoint.x + dist * Math.cos(snapAngle);\n endY = currentLine.startPoint.y + dist * Math.sin(snapAngle);\n }\n currentLine.endPoint = { x: endX, y: endY };\n currentLine.draw();\n \n // Check for frame containment while drawing (but don't apply clipping yet)\n shapes.forEach(frame => {\n if (frame.shapeName === 'frame') {\n if (frame.isShapeInFrame(currentLine)) {\n frame.highlightFrame();\n hoveredFrameLine = frame;\n } else if (hoveredFrameLine === frame) {\n frame.removeHighlight();\n hoveredFrameLine = null;\n }\n }\n });\n } else if (isDraggingLine && currentShape && currentShape.isSelected) {\n const dx = x - startX;\n const dy = y - startY;\n currentShape.move(dx, dy);\n startX = x;\n startY = y;\n\n // Issue #24 bug #4: track containing frame during existing-line\n // drag so mouseUp re-parents from current geometry, not from a\n // stale hoveredFrameLine.\n let newHover = null;\n for (const f of shapes) {\n if (f.shapeName !== 'frame') continue;\n if (f === currentShape) continue;\n if (typeof f.isShapeInFrame === 'function' && f.isShapeInFrame(currentShape)) {\n newHover = f;\n break;\n }\n }\n if (hoveredFrameLine && hoveredFrameLine !== newHover && typeof hoveredFrameLine.removeHighlight === 'function') {\n hoveredFrameLine.removeHighlight();\n }\n if (newHover && newHover !== hoveredFrameLine && typeof newHover.highlightFrame === 'function') {\n newHover.highlightFrame();\n }\n hoveredFrameLine = newHover;\n\n // Snap guides\n if (window.__sketchStoreApi && window.__sketchStoreApi.getState().snapToObjects) {\n const snap = calculateSnap(currentShape, e.shiftKey, e.clientX, e.clientY);\n if (snap.dx || snap.dy) {\n currentShape.move(snap.dx, snap.dy);\n }\n } else {\n clearSnapGuides();\n }\n }\n};\n\nconst handleMouseUp = (e) => {\n if (isDrawingLine) {\n isDrawingLine = false;\n \n // Check if line is too small\n const dx = currentLine.endPoint.x - currentLine.startPoint.x;\n const dy = currentLine.endPoint.y - currentLine.startPoint.y;\n const lengthSq = dx * dx + dy * dy;\n \n if (lengthSq < (5 / currentZoom) ** 2) {\n shapes.pop();\n if (currentLine.group.parentNode) {\n currentLine.group.parentNode.removeChild(currentLine.group);\n }\n currentLine = null;\n currentShape = null;\n } else {\n // Finalize: apply roughness now that drawing is done\n currentLine.isBeingDrawn = false;\n currentLine.draw();\n\n // Push create action for undo/redo\n pushCreateAction(currentLine);\n\n // Check for frame containment and track attachment\n const finalFrame = hoveredFrameLine;\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentLine);\n // Track the attachment for undo\n pushFrameAttachmentAction(finalFrame, currentLine, 'attach', null);\n }\n\n // Auto-select the drawn line and switch to selection tool\n const drawnLine = currentLine;\n if (window.__sketchStoreApi) window.__sketchStoreApi.setActiveTool('select', { afterDraw: true });\n currentShape = drawnLine;\n drawnLine.selectLine();\n }\n \n // Clear frame highlighting\n if (hoveredFrameLine) {\n hoveredFrameLine.removeHighlight();\n hoveredFrameLine = null;\n }\n \n currentLine = null;\n }\n \n if (isDraggingLine && dragOldPosLine && currentShape) {\n // Issue #34 bug #2: use hoveredFrameLine (actual destination) instead\n // of the stale parentFrame \u2014 containment transfer hasn't happened yet.\n const newPos = {\n startPoint: { x: currentShape.startPoint.x, y: currentShape.startPoint.y },\n endPoint: { x: currentShape.endPoint.x, y: currentShape.endPoint.y },\n controlPoint: currentShape.controlPoint ? { x: currentShape.controlPoint.x, y: currentShape.controlPoint.y } : null,\n parentFrame: hoveredFrameLine || null,\n };\n const oldPos = {\n ...dragOldPosLine,\n parentFrame: draggedShapeInitialFrameLine\n };\n \n const stateChanged = dragOldPosLine.startPoint.x !== newPos.startPoint.x || \n dragOldPosLine.startPoint.y !== newPos.startPoint.y ||\n dragOldPosLine.endPoint.x !== newPos.endPoint.x || \n dragOldPosLine.endPoint.y !== newPos.endPoint.y;\n\n const frameChanged = oldPos.parentFrame !== newPos.parentFrame;\n \n if (stateChanged || frameChanged) {\n pushTransformAction(currentShape, oldPos, newPos);\n }\n \n // Handle frame containment changes after drag\n if (isDraggingLine) {\n const finalFrame = hoveredFrameLine;\n \n // If shape moved to a different frame\n if (draggedShapeInitialFrameLine !== finalFrame) {\n // Remove from initial frame\n if (draggedShapeInitialFrameLine) {\n draggedShapeInitialFrameLine.removeShapeFromFrame(currentShape);\n }\n \n // Add to new frame\n if (finalFrame) {\n finalFrame.addShapeToFrame(currentShape);\n }\n \n // Track the frame change for undo\n if (frameChanged) {\n pushFrameAttachmentAction(finalFrame || draggedShapeInitialFrameLine, currentShape, \n finalFrame ? 'attach' : 'detach', draggedShapeInitialFrameLine);\n }\n } else if (draggedShapeInitialFrameLine) {\n // Shape stayed in same frame, restore clipping\n draggedShapeInitialFrameLine.restoreToFrame(currentShape);\n }\n }\n \n dragOldPosLine = null;\n draggedShapeInitialFrameLine = null;\n }\n \n // Clear frame highlighting\n if (hoveredFrameLine) {\n hoveredFrameLine.removeHighlight();\n hoveredFrameLine = null;\n }\n \n clearSnapGuides();\n isDraggingLine = false;\n};\n\n// --- Event Handlers ---\n\n// --- Style Option Event Listeners ---\nlineColorOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n lineColorOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof Line && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.stroke = span.getAttribute(\"data-id\");\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n lineColor = span.getAttribute(\"data-id\");\n }\n });\n});\n\nlineThicknessOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n lineThicknessOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof Line && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.strokeWidth = parseInt(span.getAttribute(\"data-id\"));\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n lineStrokeWidth = parseInt(span.getAttribute(\"data-id\"));\n }\n });\n});\n\nlineOutlineOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n lineOutlineOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof Line && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n const style = span.getAttribute(\"data-id\");\n currentShape.options.strokeDasharray = \n style === \"dashed\" ? \"5,5\" : \n (style === \"dotted\" ? \"2,12\" : \"\");\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n lineStrokeStyle = span.getAttribute(\"data-id\");\n }\n });\n});\n\nlineSlopeOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n lineSlopeOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof Line && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.roughness = parseFloat(span.getAttribute(\"data-id\"));\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n lineSktetchRate = parseFloat(span.getAttribute(\"data-id\"));\n }\n });\n});\n\nlineEdgeOptions.forEach((span) => {\n span.addEventListener(\"click\", (event) => {\n event.stopPropagation();\n lineEdgeOptions.forEach((el) => el.classList.remove(\"selected\"));\n span.classList.add(\"selected\");\n \n if (currentShape instanceof Line && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n currentShape.options.bowing = parseFloat(span.getAttribute(\"data-id\"));\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n lineEdgeType = parseFloat(span.getAttribute(\"data-id\"));\n }\n });\n});\n\n// Add copy/paste functionality\nfunction cloneOptions(options) {\n return JSON.parse(JSON.stringify(options));\n}\n\nwindow.Line = Line;\n\n// Bridge line tool settings to React sidebar\nwindow.lineToolSettings = {\n get strokeColor() { return lineColor; },\n set strokeColor(v) { lineColor = v; },\n get strokeWidth() { return lineStrokeWidth; },\n set strokeWidth(v) { lineStrokeWidth = v; },\n get strokeStyle() { return lineStrokeStyle; },\n set strokeStyle(v) { lineStrokeStyle = v; },\n get sloppiness() { return lineSktetchRate; },\n set sloppiness(v) { lineSktetchRate = v; },\n get edge() { return lineEdgeType; },\n set edge(v) { lineEdgeType = v; },\n};\nwindow.updateSelectedLineStyle = function(changes) {\n if (currentShape instanceof Line && currentShape.isSelected) {\n const oldOptions = {...currentShape.options};\n if (changes.stroke !== undefined) { lineColor = changes.stroke; currentShape.options.stroke = changes.stroke; }\n if (changes.strokeWidth !== undefined) { lineStrokeWidth = changes.strokeWidth; currentShape.options.strokeWidth = changes.strokeWidth; }\n if (changes.strokeStyle !== undefined) {\n lineStrokeStyle = changes.strokeStyle;\n currentShape.options.strokeDasharray = changes.strokeStyle === \"dashed\" ? \"5,5\" : (changes.strokeStyle === \"dotted\" ? \"2,12\" : \"\");\n }\n if (changes.sloppiness !== undefined) { lineSktetchRate = changes.sloppiness; currentShape.options.roughness = changes.sloppiness; }\n if (changes.edge !== undefined) { lineEdgeType = changes.edge; currentShape.options.bowing = changes.edge; }\n currentShape.draw();\n pushOptionsChangeAction(currentShape, oldOptions);\n } else {\n if (changes.stroke !== undefined) lineColor = changes.stroke;\n if (changes.strokeWidth !== undefined) lineStrokeWidth = changes.strokeWidth;\n if (changes.strokeStyle !== undefined) lineStrokeStyle = changes.strokeStyle;\n if (changes.sloppiness !== undefined) lineSktetchRate = changes.sloppiness;\n if (changes.edge !== undefined) lineEdgeType = changes.edge;\n }\n};\n\nexport {\n handleMouseDown as handleMouseDownLine,\n handleMouseMove as handleMouseMoveLine,\n handleMouseUp as handleMouseUpLine,\n};\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }