@elixpo/lixsketch 5.6.10 → 5.6.11

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 (156) hide show
  1. package/dist/react/{AIRenderer-R5M2CIDO.js → AIRenderer-JNEZYDYQ.js} +4 -4
  2. package/dist/react/Arrow-QMR77LGQ.js +9 -0
  3. package/dist/react/Circle-5WL5HZA5.js +11 -0
  4. package/dist/react/{CopyPaste-N4U2NTQT.js → CopyPaste-V7AY56H3.js} +74 -30
  5. package/dist/react/CopyPaste-V7AY56H3.js.map +7 -0
  6. package/dist/react/{EventDispatcher-J657SDW4.js → EventDispatcher-E4OJCMY6.js} +153 -56
  7. package/dist/react/{EventDispatcher-J657SDW4.js.map → EventDispatcher-E4OJCMY6.js.map} +3 -3
  8. package/dist/react/Frame-OZCDVPMI.js +11 -0
  9. package/dist/react/FreehandStroke-QSSYWBFK.js +9 -0
  10. package/dist/react/IconShape-HXUV4VRT.js +10 -0
  11. package/dist/react/ImageShape-JGLT2UGG.js +10 -0
  12. package/dist/react/Line-YONPLUYT.js +11 -0
  13. package/dist/react/{MermaidFlowchartRenderer-EL3Q2MNW.js → MermaidFlowchartRenderer-FSH43RUP.js} +26 -7
  14. package/dist/react/{MermaidFlowchartRenderer-EL3Q2MNW.js.map → MermaidFlowchartRenderer-FSH43RUP.js.map} +2 -2
  15. package/dist/react/{MermaidSequenceRenderer-K4KHHEVC.js → MermaidSequenceRenderer-FRPNOF2V.js} +11 -9
  16. package/dist/react/{MermaidSequenceRenderer-K4KHHEVC.js.map → MermaidSequenceRenderer-FRPNOF2V.js.map} +2 -2
  17. package/dist/react/{MermaidStructuredRenderer-6LN3WISP.js → MermaidStructuredRenderer-BZGQLRIH.js} +13 -6
  18. package/dist/react/{MermaidStructuredRenderer-6LN3WISP.js.map → MermaidStructuredRenderer-BZGQLRIH.js.map} +2 -2
  19. package/dist/react/Rectangle-7KMA3SC6.js +11 -0
  20. package/dist/react/{SceneSerializer-Y6QABGZY.js → SceneSerializer-7O72LEZP.js} +13 -12
  21. package/dist/react/{SceneSerializer-Y6QABGZY.js.map → SceneSerializer-7O72LEZP.js.map} +1 -1
  22. package/dist/react/{Selection-GCZWCNAR.js → Selection-S4FYSZIF.js} +5 -5
  23. package/dist/react/{SketchEngine-PCMCE63L.js → SketchEngine-VTWURP2K.js} +26 -26
  24. package/dist/react/{UndoRedo-RXO7YHA2.js → UndoRedo-YLQJ6DXW.js} +8 -2
  25. package/dist/react/{ZoomPan-RR7KUYZT.js → ZoomPan-AEKWKUCH.js} +2 -2
  26. package/dist/react/{arrowTool-UN3TNJFP.js → arrowTool-C4RDWQEX.js} +3 -3
  27. package/dist/react/{chunk-KXLNEFN5.js → chunk-2U47AU6Y.js} +2 -2
  28. package/dist/react/{chunk-YHQ4ZAJQ.js → chunk-75OPJOWN.js} +6 -6
  29. package/dist/react/chunk-75OPJOWN.js.map +7 -0
  30. package/dist/react/{chunk-P5476S5I.js → chunk-CWE5IFG7.js} +4 -4
  31. package/dist/react/{chunk-3FCIBY54.js → chunk-IS2MKWGH.js} +8 -7
  32. package/dist/react/chunk-IS2MKWGH.js.map +7 -0
  33. package/dist/react/{chunk-ZNZAICWY.js → chunk-JEHOEQ6Z.js} +13 -5
  34. package/dist/react/chunk-JEHOEQ6Z.js.map +7 -0
  35. package/dist/react/{chunk-TAJ5E6KI.js → chunk-JYBJXTLM.js} +39 -14
  36. package/dist/react/chunk-JYBJXTLM.js.map +7 -0
  37. package/dist/react/{chunk-3PFVMNDJ.js → chunk-LXEHYCKH.js} +3 -3
  38. package/dist/react/chunk-M7OYYJC6.js +17 -0
  39. package/dist/react/chunk-M7OYYJC6.js.map +7 -0
  40. package/dist/react/chunk-MS4TIQ6Z.js +131 -0
  41. package/dist/react/chunk-MS4TIQ6Z.js.map +7 -0
  42. package/dist/react/{chunk-5XGQ3CMT.js → chunk-OCJN32IL.js} +2 -2
  43. package/dist/react/{chunk-7NHZYKYB.js → chunk-P7VIYR6R.js} +7 -4
  44. package/dist/react/chunk-P7VIYR6R.js.map +7 -0
  45. package/dist/react/{chunk-UERV53R7.js → chunk-PX2635H5.js} +32 -10
  46. package/dist/react/chunk-PX2635H5.js.map +7 -0
  47. package/dist/react/{chunk-KACRJ6AJ.js → chunk-SDG4U7TP.js} +7 -6
  48. package/dist/react/chunk-SDG4U7TP.js.map +7 -0
  49. package/dist/react/{chunk-JVHZVV5U.js → chunk-STJERZ25.js} +7 -3
  50. package/dist/react/chunk-STJERZ25.js.map +7 -0
  51. package/dist/react/{chunk-VZPH7OAM.js → chunk-TCWCC4Z4.js} +7 -3
  52. package/dist/react/chunk-TCWCC4Z4.js.map +7 -0
  53. package/dist/react/{chunk-VZX55VQL.js → chunk-TFCBCWL5.js} +90 -33
  54. package/dist/react/chunk-TFCBCWL5.js.map +7 -0
  55. package/dist/react/{chunk-GQLXUZHQ.js → chunk-TWHJ6PJK.js} +5 -3
  56. package/dist/react/chunk-TWHJ6PJK.js.map +7 -0
  57. package/dist/react/{chunk-NH3NVSWT.js → chunk-UCOK4V5Z.js} +4 -3
  58. package/dist/react/{chunk-NH3NVSWT.js.map → chunk-UCOK4V5Z.js.map} +2 -2
  59. package/dist/react/{chunk-W7XUY4GR.js → chunk-VJDNKJBX.js} +56 -4
  60. package/dist/react/chunk-VJDNKJBX.js.map +7 -0
  61. package/dist/react/{chunk-BT2EIJD4.js → chunk-WCA3FGWE.js} +6 -3
  62. package/dist/react/chunk-WCA3FGWE.js.map +7 -0
  63. package/dist/react/{chunk-7WXEWDRL.js → chunk-Y3FJMYPX.js} +3 -3
  64. package/dist/react/{chunk-ULZW5PXM.js → chunk-YCGLGY4C.js} +2 -2
  65. package/dist/react/{circleTool-YDTQDGYX.js → circleTool-QQV2QEVF.js} +4 -4
  66. package/dist/react/{codeTool-U6SYKHHD.js → codeTool-PTCPSZ4L.js} +5 -5
  67. package/dist/react/{frameTool-VRI7OODN.js → frameTool-7GQPLU4Y.js} +4 -4
  68. package/dist/react/{freehandTool-2ICCQHVY.js → freehandTool-3RJXTVAK.js} +4 -4
  69. package/dist/react/{iconTool-32D5NJ4I.js → iconTool-DW5YJX7P.js} +5 -5
  70. package/dist/react/{imageTool-Z6Y4OXBG.js → imageTool-7GZQKWYT.js} +5 -5
  71. package/dist/react/index.js +49 -56
  72. package/dist/react/index.js.map +2 -2
  73. package/dist/react/{lineTool-BUWVQ666.js → lineTool-5CY7BHND.js} +4 -4
  74. package/dist/react/{rectangleTool-NJYG6Y6L.js → rectangleTool-DK4QL4QW.js} +4 -4
  75. package/dist/react/{textTool-CIJCF4Z3.js → textTool-GP5QQYF3.js} +6 -6
  76. package/package.json +1 -1
  77. package/src/core/CopyPaste.js +66 -18
  78. package/src/core/EventDispatcher.js +71 -47
  79. package/src/core/MermaidFlowchartRenderer.js +34 -8
  80. package/src/core/MermaidSequenceRenderer.js +10 -8
  81. package/src/core/MermaidStructuredRenderer.js +12 -5
  82. package/src/core/ScreenSpaceControls.js +102 -13
  83. package/src/core/Selection.js +26 -7
  84. package/src/core/SelectionGesture.js +50 -0
  85. package/src/core/UndoRedo.js +108 -35
  86. package/src/react/components/sidebars/CircleSidebar.jsx +11 -5
  87. package/src/react/components/sidebars/IconSidebar.jsx +10 -4
  88. package/src/react/components/sidebars/RectangleSidebar.jsx +11 -5
  89. package/src/react/components/sidebars/ShapeSidebar.jsx +29 -37
  90. package/src/react/store/useUIStore.js +7 -0
  91. package/src/shapes/Arrow.js +4 -3
  92. package/src/shapes/Circle.js +58 -2
  93. package/src/shapes/Frame.js +11 -4
  94. package/src/shapes/FreehandStroke.js +2 -1
  95. package/src/shapes/Line.js +45 -18
  96. package/src/shapes/Rectangle.js +3 -1
  97. package/src/tools/circleTool.js +4 -1
  98. package/src/tools/frameTool.js +3 -2
  99. package/src/tools/iconTool.js +4 -3
  100. package/src/tools/imageTool.js +3 -2
  101. package/src/tools/lineTool.js +4 -0
  102. package/src/tools/textTool.js +1 -1
  103. package/src/utils/themeColors.js +13 -0
  104. package/dist/react/Arrow-EF7ALH2Y.js +0 -8
  105. package/dist/react/Circle-HMM5PKJ2.js +0 -10
  106. package/dist/react/CopyPaste-N4U2NTQT.js.map +0 -7
  107. package/dist/react/Frame-NHPESH4Y.js +0 -11
  108. package/dist/react/FreehandStroke-WXIJKD5I.js +0 -9
  109. package/dist/react/IconShape-RN5HJDUF.js +0 -10
  110. package/dist/react/ImageShape-L7U64AVP.js +0 -10
  111. package/dist/react/Line-LPRTGPUQ.js +0 -10
  112. package/dist/react/Rectangle-4U4CD2ER.js +0 -10
  113. package/dist/react/chunk-3FCIBY54.js.map +0 -7
  114. package/dist/react/chunk-7NHZYKYB.js.map +0 -7
  115. package/dist/react/chunk-BT2EIJD4.js.map +0 -7
  116. package/dist/react/chunk-GQLXUZHQ.js.map +0 -7
  117. package/dist/react/chunk-JVHZVV5U.js.map +0 -7
  118. package/dist/react/chunk-KACRJ6AJ.js.map +0 -7
  119. package/dist/react/chunk-PAKA6HUX.js +0 -59
  120. package/dist/react/chunk-PAKA6HUX.js.map +0 -7
  121. package/dist/react/chunk-TAJ5E6KI.js.map +0 -7
  122. package/dist/react/chunk-UERV53R7.js.map +0 -7
  123. package/dist/react/chunk-VZPH7OAM.js.map +0 -7
  124. package/dist/react/chunk-VZX55VQL.js.map +0 -7
  125. package/dist/react/chunk-W7XUY4GR.js.map +0 -7
  126. package/dist/react/chunk-YHQ4ZAJQ.js.map +0 -7
  127. package/dist/react/chunk-ZNZAICWY.js.map +0 -7
  128. /package/dist/react/{AIRenderer-R5M2CIDO.js.map → AIRenderer-JNEZYDYQ.js.map} +0 -0
  129. /package/dist/react/{Arrow-EF7ALH2Y.js.map → Arrow-QMR77LGQ.js.map} +0 -0
  130. /package/dist/react/{Circle-HMM5PKJ2.js.map → Circle-5WL5HZA5.js.map} +0 -0
  131. /package/dist/react/{Frame-NHPESH4Y.js.map → Frame-OZCDVPMI.js.map} +0 -0
  132. /package/dist/react/{FreehandStroke-WXIJKD5I.js.map → FreehandStroke-QSSYWBFK.js.map} +0 -0
  133. /package/dist/react/{IconShape-RN5HJDUF.js.map → IconShape-HXUV4VRT.js.map} +0 -0
  134. /package/dist/react/{ImageShape-L7U64AVP.js.map → ImageShape-JGLT2UGG.js.map} +0 -0
  135. /package/dist/react/{Line-LPRTGPUQ.js.map → Line-YONPLUYT.js.map} +0 -0
  136. /package/dist/react/{Rectangle-4U4CD2ER.js.map → Rectangle-7KMA3SC6.js.map} +0 -0
  137. /package/dist/react/{Selection-GCZWCNAR.js.map → Selection-S4FYSZIF.js.map} +0 -0
  138. /package/dist/react/{SketchEngine-PCMCE63L.js.map → SketchEngine-VTWURP2K.js.map} +0 -0
  139. /package/dist/react/{UndoRedo-RXO7YHA2.js.map → UndoRedo-YLQJ6DXW.js.map} +0 -0
  140. /package/dist/react/{ZoomPan-RR7KUYZT.js.map → ZoomPan-AEKWKUCH.js.map} +0 -0
  141. /package/dist/react/{arrowTool-UN3TNJFP.js.map → arrowTool-C4RDWQEX.js.map} +0 -0
  142. /package/dist/react/{chunk-KXLNEFN5.js.map → chunk-2U47AU6Y.js.map} +0 -0
  143. /package/dist/react/{chunk-P5476S5I.js.map → chunk-CWE5IFG7.js.map} +0 -0
  144. /package/dist/react/{chunk-3PFVMNDJ.js.map → chunk-LXEHYCKH.js.map} +0 -0
  145. /package/dist/react/{chunk-5XGQ3CMT.js.map → chunk-OCJN32IL.js.map} +0 -0
  146. /package/dist/react/{chunk-7WXEWDRL.js.map → chunk-Y3FJMYPX.js.map} +0 -0
  147. /package/dist/react/{chunk-ULZW5PXM.js.map → chunk-YCGLGY4C.js.map} +0 -0
  148. /package/dist/react/{circleTool-YDTQDGYX.js.map → circleTool-QQV2QEVF.js.map} +0 -0
  149. /package/dist/react/{codeTool-U6SYKHHD.js.map → codeTool-PTCPSZ4L.js.map} +0 -0
  150. /package/dist/react/{frameTool-VRI7OODN.js.map → frameTool-7GQPLU4Y.js.map} +0 -0
  151. /package/dist/react/{freehandTool-2ICCQHVY.js.map → freehandTool-3RJXTVAK.js.map} +0 -0
  152. /package/dist/react/{iconTool-32D5NJ4I.js.map → iconTool-DW5YJX7P.js.map} +0 -0
  153. /package/dist/react/{imageTool-Z6Y4OXBG.js.map → imageTool-7GZQKWYT.js.map} +0 -0
  154. /package/dist/react/{lineTool-BUWVQ666.js.map → lineTool-5CY7BHND.js.map} +0 -0
  155. /package/dist/react/{rectangleTool-NJYG6Y6L.js.map → rectangleTool-DK4QL4QW.js.map} +0 -0
  156. /package/dist/react/{textTool-CIJCF4Z3.js.map → textTool-GP5QQYF3.js.map} +0 -0
@@ -1159,20 +1159,20 @@ function initAIRenderer() {
1159
1159
  async function loadSequenceRenderer() {
1160
1160
  if (_seqParser) return;
1161
1161
  const mod = await import("./MermaidSequenceParser-DBYXW23P.js");
1162
- const rend = await import("./MermaidSequenceRenderer-K4KHHEVC.js");
1162
+ const rend = await import("./MermaidSequenceRenderer-FRPNOF2V.js");
1163
1163
  _seqParser = mod.parseSequenceDiagram;
1164
1164
  _seqPreview = rend.renderSequencePreviewSVG;
1165
1165
  _seqCanvas = rend.renderSequenceOnCanvas;
1166
1166
  }
1167
1167
  async function loadFlowchartRenderer() {
1168
1168
  if (_fcPreview) return;
1169
- const mod = await import("./MermaidFlowchartRenderer-EL3Q2MNW.js");
1169
+ const mod = await import("./MermaidFlowchartRenderer-FSH43RUP.js");
1170
1170
  _fcPreview = mod.renderFlowchartPreviewSVG;
1171
1171
  _fcCanvas = mod.renderFlowchartOnCanvas;
1172
1172
  }
1173
1173
  async function loadStructuredRenderer() {
1174
1174
  if (_structured) return;
1175
- _structured = await import("./MermaidStructuredRenderer-6LN3WISP.js");
1175
+ _structured = await import("./MermaidStructuredRenderer-BZGQLRIH.js");
1176
1176
  }
1177
1177
  function mermaidHeader(src) {
1178
1178
  return src.split("\n").map((line) => line.trim()).find((line) => line && !line.startsWith("%%"))?.toLowerCase() || "";
@@ -1268,4 +1268,4 @@ export {
1268
1268
  parseMermaid,
1269
1269
  renderAIDiagram
1270
1270
  };
1271
- //# sourceMappingURL=AIRenderer-R5M2CIDO.js.map
1271
+ //# sourceMappingURL=AIRenderer-JNEZYDYQ.js.map
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ import {
3
+ Arrow
4
+ } from "./chunk-WCA3FGWE.js";
5
+ import "./chunk-M7OYYJC6.js";
6
+ export {
7
+ Arrow
8
+ };
9
+ //# sourceMappingURL=Arrow-QMR77LGQ.js.map
@@ -0,0 +1,11 @@
1
+ "use client";
2
+ import {
3
+ Circle
4
+ } from "./chunk-VJDNKJBX.js";
5
+ import "./chunk-6AIFXYV6.js";
6
+ import "./chunk-MS4TIQ6Z.js";
7
+ import "./chunk-M7OYYJC6.js";
8
+ export {
9
+ Circle
10
+ };
11
+ //# sourceMappingURL=Circle-5WL5HZA5.js.map
@@ -4,38 +4,41 @@ import {
4
4
  } from "./chunk-MB7VS6MK.js";
5
5
  import {
6
6
  ImageShape
7
- } from "./chunk-ULZW5PXM.js";
7
+ } from "./chunk-YCGLGY4C.js";
8
8
  import {
9
9
  IconShape
10
- } from "./chunk-5XGQ3CMT.js";
10
+ } from "./chunk-OCJN32IL.js";
11
11
  import {
12
12
  Frame
13
- } from "./chunk-ZNZAICWY.js";
13
+ } from "./chunk-JEHOEQ6Z.js";
14
14
  import {
15
15
  FreehandStroke
16
- } from "./chunk-NH3NVSWT.js";
16
+ } from "./chunk-UCOK4V5Z.js";
17
17
  import {
18
18
  compressImage,
19
19
  isAllowedImage
20
20
  } from "./chunk-DNAG7ML6.js";
21
21
  import {
22
22
  Rectangle
23
- } from "./chunk-VZPH7OAM.js";
23
+ } from "./chunk-TCWCC4Z4.js";
24
24
  import {
25
25
  Circle
26
- } from "./chunk-W7XUY4GR.js";
26
+ } from "./chunk-VJDNKJBX.js";
27
27
  import "./chunk-6AIFXYV6.js";
28
- import "./chunk-PAKA6HUX.js";
28
+ import "./chunk-MS4TIQ6Z.js";
29
29
  import {
30
30
  Arrow
31
- } from "./chunk-BT2EIJD4.js";
31
+ } from "./chunk-WCA3FGWE.js";
32
32
  import {
33
33
  Line
34
- } from "./chunk-TAJ5E6KI.js";
35
- import "./chunk-KXLNEFN5.js";
34
+ } from "./chunk-JYBJXTLM.js";
35
+ import "./chunk-M7OYYJC6.js";
36
+ import "./chunk-2U47AU6Y.js";
36
37
  import {
38
+ beginUndoBatch,
39
+ endUndoBatch,
37
40
  pushCreateAction
38
- } from "./chunk-VZX55VQL.js";
41
+ } from "./chunk-TFCBCWL5.js";
39
42
  import {
40
43
  TextShape
41
44
  } from "./chunk-PGT3TJOW.js";
@@ -48,9 +51,11 @@ function getSVGElement() {
48
51
  return document.getElementById("freehand-canvas");
49
52
  }
50
53
  function cloneOptions(options) {
51
- return JSON.parse(JSON.stringify(options));
54
+ return options ? JSON.parse(JSON.stringify(options)) : {};
52
55
  }
53
- function serializeShape(shape) {
56
+ function serializeShape(shape, visited = /* @__PURE__ */ new Set()) {
57
+ if (!shape || visited.has(shape)) return null;
58
+ visited.add(shape);
54
59
  switch (shape.shapeName) {
55
60
  case "rectangle":
56
61
  return {
@@ -110,7 +115,15 @@ function serializeShape(shape) {
110
115
  height: shape.height,
111
116
  rotation: shape.rotation,
112
117
  frameName: shape.frameName,
113
- options: cloneOptions(shape.options)
118
+ frameType: shape._frameType || null,
119
+ webEmbedURL: shape._webEmbedURL || null,
120
+ diagramType: shape._diagramType || null,
121
+ fillStyle: shape.fillStyle,
122
+ fillColor: shape.fillColor,
123
+ gridSize: shape.gridSize,
124
+ gridColor: shape.gridColor,
125
+ options: cloneOptions(shape.options),
126
+ children: (shape.containedShapes || []).map((child) => serializeShape(child, visited)).filter(Boolean)
114
127
  };
115
128
  case "text": {
116
129
  const group = shape.group;
@@ -170,6 +183,17 @@ function serializeShape(shape) {
170
183
  return null;
171
184
  }
172
185
  }
186
+ function getCopyRoots(selectedShapes) {
187
+ const selectedSet = new Set(selectedShapes);
188
+ return selectedShapes.filter((shape) => {
189
+ let parent = shape?.parentFrame;
190
+ while (parent) {
191
+ if (selectedSet.has(parent)) return false;
192
+ parent = parent.parentFrame;
193
+ }
194
+ return true;
195
+ });
196
+ }
173
197
  function getShapeCenter(data) {
174
198
  switch (data.type) {
175
199
  case "rectangle":
@@ -283,9 +307,20 @@ function createShapeFromData(data, offsetX, offsetY) {
283
307
  data.y + offsetY,
284
308
  data.width,
285
309
  data.height,
286
- { ...cloneOptions(data.options), frameName: data.frameName, rotation: data.rotation }
310
+ {
311
+ ...cloneOptions(data.options),
312
+ frameName: data.frameName,
313
+ rotation: data.rotation,
314
+ frameType: data.frameType,
315
+ webEmbedURL: data.webEmbedURL,
316
+ fillStyle: data.fillStyle,
317
+ fillColor: data.fillColor,
318
+ gridSize: data.gridSize,
319
+ gridColor: data.gridColor
320
+ }
287
321
  );
288
322
  newFrame.rotation = data.rotation;
323
+ if (data.diagramType) newFrame._diagramType = data.diagramType;
289
324
  return newFrame;
290
325
  }
291
326
  case "text": {
@@ -407,16 +442,14 @@ function createShapeFromData(data, offsetX, offsetY) {
407
442
  }
408
443
  }
409
444
  function copySelected() {
410
- const shapesToCopy = [];
445
+ let selectedShapes = [];
411
446
  if (window.multiSelection && window.multiSelection.selectedShapes && window.multiSelection.selectedShapes.size > 0) {
412
- window.multiSelection.selectedShapes.forEach((shape) => {
413
- const data = serializeShape(shape);
414
- if (data) shapesToCopy.push(data);
415
- });
447
+ selectedShapes = [...window.multiSelection.selectedShapes];
416
448
  } else if (typeof currentShape !== "undefined" && currentShape && currentShape.isSelected) {
417
- const data = serializeShape(currentShape);
418
- if (data) shapesToCopy.push(data);
449
+ selectedShapes = [currentShape];
419
450
  }
451
+ const copyRoots = getCopyRoots(selectedShapes);
452
+ const shapesToCopy = copyRoots.map((shape) => serializeShape(shape)).filter(Boolean);
420
453
  if (shapesToCopy.length === 0) return false;
421
454
  let totalX = 0, totalY = 0;
422
455
  shapesToCopy.forEach((d) => {
@@ -460,16 +493,25 @@ function pasteClipboard() {
460
493
  disableAllSideBars();
461
494
  }
462
495
  const pastedShapes = [];
463
- clipboard.shapes.forEach((data) => {
496
+ const undoBatch = beginUndoBatch();
497
+ const pasteShapeTree = (data, parentFrame = null) => {
464
498
  const newShape = createShapeFromData(data, groupOffsetX, groupOffsetY);
465
- if (newShape) {
466
- if (typeof shapes !== "undefined" && Array.isArray(shapes)) {
467
- shapes.push(newShape);
468
- }
499
+ if (!newShape) return null;
500
+ if (typeof shapes !== "undefined" && Array.isArray(shapes)) shapes.push(newShape);
501
+ if (parentFrame?.addShapeToFrame) parentFrame.addShapeToFrame(newShape);
502
+ if (data.type === "frame") {
503
+ pushCreateAction(newShape, { frameCreation: true, containedShapes: [] });
504
+ for (const childData of data.children || []) pasteShapeTree(childData, newShape);
505
+ } else {
469
506
  pushCreateAction(newShape);
470
- pastedShapes.push(newShape);
471
507
  }
508
+ return newShape;
509
+ };
510
+ clipboard.shapes.forEach((data) => {
511
+ const newShape = pasteShapeTree(data);
512
+ if (newShape) pastedShapes.push(newShape);
472
513
  });
514
+ endUndoBatch(undoBatch, "clipboard-paste");
473
515
  if (pastedShapes.length === 1) {
474
516
  const s = pastedShapes[0];
475
517
  s.isSelected = true;
@@ -601,7 +643,9 @@ function initCopyPaste() {
601
643
  }
602
644
  export {
603
645
  copySelected,
646
+ getCopyRoots,
604
647
  initCopyPaste,
605
- pasteClipboard
648
+ pasteClipboard,
649
+ serializeShape
606
650
  };
607
- //# sourceMappingURL=CopyPaste-N4U2NTQT.js.map
651
+ //# sourceMappingURL=CopyPaste-V7AY56H3.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/CopyPaste.js"],
4
+ "sourcesContent": ["/* eslint-disable */\n// Centralized Copy/Paste system for ALL shape types\n// Supports single and multi-selection copy/paste\n// Pastes at mouse pointer position with offset to prevent stacking\n\nimport { beginUndoBatch, endUndoBatch, pushCreateAction } from './UndoRedo.js';\nimport { Rectangle } from '../shapes/Rectangle.js';\nimport { Circle } from '../shapes/Circle.js';\nimport { Line } from '../shapes/Line.js';\nimport { Arrow } from '../shapes/Arrow.js';\nimport { FreehandStroke } from '../shapes/FreehandStroke.js';\nimport { Frame } from '../shapes/Frame.js';\nimport { TextShape } from '../shapes/TextShape.js';\nimport { CodeShape } from '../shapes/CodeShape.js';\nimport { ImageShape } from '../shapes/ImageShape.js';\nimport { isAllowedImage, isAllowedImageDataUrl } from '../utils/allowedImageTypes.js';\nimport { compressImage } from '../utils/imageCompressor.js';\nimport { IconShape } from '../shapes/IconShape.js';\n\n// Clipboard storage\nlet clipboard = null; // { shapes: [...clonedData], centerX, centerY }\nlet pasteCount = 0; // Increments per paste to offset repeated pastes\n\n// Last known mouse position in SVG coordinates\nlet lastMouseSVG = { x: 0, y: 0 };\n\nfunction getSVGElement() {\n return document.getElementById('freehand-canvas');\n}\n\nfunction getSVGCoordsFromMouse(e) {\n const svgEl = getSVGElement();\n if (!svgEl) return { x: 0, y: 0 };\n const viewBox = svgEl.viewBox.baseVal;\n const rect = svgEl.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\nfunction cloneOptions(options) {\n return options ? JSON.parse(JSON.stringify(options)) : {};\n}\n\n// ============================================================\n// SERIALIZE: Extract copyable data from a shape\n// ============================================================\nexport function serializeShape(shape, visited = new Set()) {\n if (!shape || visited.has(shape)) return null;\n visited.add(shape);\n switch (shape.shapeName) {\n case 'rectangle':\n return {\n type: 'rectangle',\n x: shape.x,\n y: shape.y,\n width: shape.width,\n height: shape.height,\n rotation: shape.rotation,\n options: cloneOptions(shape.options)\n };\n\n case 'circle':\n return {\n type: 'circle',\n x: shape.x,\n y: shape.y,\n rx: shape.rx,\n ry: shape.ry,\n rotation: shape.rotation,\n options: cloneOptions(shape.options)\n };\n\n case 'line':\n return {\n type: 'line',\n startPoint: { x: shape.startPoint.x, y: shape.startPoint.y },\n endPoint: { x: shape.endPoint.x, y: shape.endPoint.y },\n controlPoint: shape.controlPoint ? { x: shape.controlPoint.x, y: shape.controlPoint.y } : null,\n isCurved: shape.isCurved || false,\n options: cloneOptions(shape.options)\n };\n\n case 'arrow':\n return {\n type: 'arrow',\n startPoint: { x: shape.startPoint.x, y: shape.startPoint.y },\n endPoint: { x: shape.endPoint.x, y: shape.endPoint.y },\n controlPoint1: shape.controlPoint1 ? { x: shape.controlPoint1.x, y: shape.controlPoint1.y } : null,\n controlPoint2: shape.controlPoint2 ? { x: shape.controlPoint2.x, y: shape.controlPoint2.y } : null,\n options: cloneOptions(shape.options),\n arrowOutlineStyle: shape.arrowOutlineStyle,\n arrowHeadStyle: shape.arrowHeadStyle,\n arrowCurved: shape.arrowCurved,\n arrowCurveAmount: shape.arrowCurveAmount\n };\n\n case 'freehandStroke':\n return {\n type: 'freehandStroke',\n points: JSON.parse(JSON.stringify(shape.points)),\n rotation: shape.rotation,\n options: cloneOptions(shape.options)\n };\n\n case 'frame':\n return {\n type: 'frame',\n x: shape.x,\n y: shape.y,\n width: shape.width,\n height: shape.height,\n rotation: shape.rotation,\n frameName: shape.frameName,\n frameType: shape._frameType || null,\n webEmbedURL: shape._webEmbedURL || null,\n diagramType: shape._diagramType || null,\n fillStyle: shape.fillStyle,\n fillColor: shape.fillColor,\n gridSize: shape.gridSize,\n gridColor: shape.gridColor,\n options: cloneOptions(shape.options),\n children: (shape.containedShapes || [])\n .map(child => serializeShape(child, visited))\n .filter(Boolean),\n };\n\n case 'text': {\n const group = shape.group;\n const textEl = group.querySelector('text');\n return {\n type: 'text',\n x: shape.x,\n y: shape.y,\n rotation: shape.rotation,\n groupHTML: group.cloneNode(true).outerHTML\n };\n }\n\n case 'code': {\n const group = shape.group;\n return {\n type: 'code',\n x: shape.x,\n y: shape.y,\n rotation: shape.rotation,\n groupHTML: group.cloneNode(true).outerHTML\n };\n }\n\n case 'image': {\n const el = shape.element;\n return {\n type: 'image',\n x: shape.x,\n y: shape.y,\n width: shape.width,\n height: shape.height,\n rotation: shape.rotation,\n href: el.getAttribute('href') || el.getAttributeNS('http://www.w3.org/1999/xlink', 'href') || '',\n storageProvider: el.getAttribute('data-storage-provider') || null,\n storageCloudName: el.getAttribute('data-storage-cloud-name') || null,\n aiGenerated: el.getAttribute('data-ai-generated') === 'true',\n aiModel: el.getAttribute('data-ai-model') || null,\n frameType: shape._frameType || null,\n graphData: shape._frameType === 'graph' && shape._graphData\n ? cloneOptions(shape._graphData)\n : null\n };\n }\n\n case 'icon': {\n const el = shape.element;\n return {\n type: 'icon',\n x: shape.x,\n y: shape.y,\n width: shape.width,\n height: shape.height,\n rotation: shape.rotation,\n elementHTML: el.cloneNode(true).outerHTML,\n viewboxWidth: parseFloat(el.getAttribute('data-viewbox-width')) || 24,\n viewboxHeight: parseFloat(el.getAttribute('data-viewbox-height')) || 24\n };\n }\n\n default:\n console.warn('Copy not supported for shape type:', shape.shapeName);\n return null;\n }\n}\n\nexport function getCopyRoots(selectedShapes) {\n const selectedSet = new Set(selectedShapes);\n return selectedShapes.filter(shape => {\n let parent = shape?.parentFrame;\n while (parent) {\n if (selectedSet.has(parent)) return false;\n parent = parent.parentFrame;\n }\n return true;\n });\n}\n\n// ============================================================\n// Get bounding center of a serialized shape\n// ============================================================\nfunction getShapeCenter(data) {\n switch (data.type) {\n case 'rectangle':\n case 'frame':\n return { x: data.x + data.width / 2, y: data.y + data.height / 2 };\n case 'circle':\n return { x: data.x, y: data.y };\n case 'line':\n return {\n x: (data.startPoint.x + data.endPoint.x) / 2,\n y: (data.startPoint.y + data.endPoint.y) / 2\n };\n case 'arrow':\n return {\n x: (data.startPoint.x + data.endPoint.x) / 2,\n y: (data.startPoint.y + data.endPoint.y) / 2\n };\n case 'freehandStroke': {\n if (!data.points.length) return { x: 0, y: 0 };\n let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;\n data.points.forEach(p => {\n if (p[0] < minX) minX = p[0];\n if (p[1] < minY) minY = p[1];\n if (p[0] > maxX) maxX = p[0];\n if (p[1] > maxY) maxY = p[1];\n });\n return { x: (minX + maxX) / 2, y: (minY + maxY) / 2 };\n }\n case 'text':\n case 'code':\n return { x: data.x, y: data.y };\n case 'image':\n case 'icon':\n return { x: data.x + data.width / 2, y: data.y + data.height / 2 };\n default:\n return { x: 0, y: 0 };\n }\n}\n\n// ============================================================\n// DESERIALIZE: Create a new shape from copied data at offset\n// ============================================================\nfunction createShapeFromData(data, offsetX, offsetY) {\n const svgEl = getSVGElement();\n if (!svgEl) return null;\n\n switch (data.type) {\n case 'rectangle': {\n const newRect = new Rectangle(\n data.x + offsetX,\n data.y + offsetY,\n data.width,\n data.height,\n cloneOptions(data.options)\n );\n newRect.rotation = data.rotation;\n newRect.draw();\n return newRect;\n }\n\n case 'circle': {\n const newCircle = new Circle(\n data.x + offsetX,\n data.y + offsetY,\n data.rx,\n data.ry,\n cloneOptions(data.options)\n );\n newCircle.rotation = data.rotation;\n newCircle.draw();\n return newCircle;\n }\n\n case 'line': {\n const newLine = new Line(\n { x: data.startPoint.x + offsetX, y: data.startPoint.y + offsetY },\n { x: data.endPoint.x + offsetX, y: data.endPoint.y + offsetY },\n cloneOptions(data.options)\n );\n if (data.isCurved && data.controlPoint) {\n newLine.isCurved = true;\n newLine.controlPoint = { x: data.controlPoint.x + offsetX, y: data.controlPoint.y + offsetY };\n }\n newLine.draw();\n return newLine;\n }\n\n case 'arrow': {\n const opts = {\n ...cloneOptions(data.options),\n arrowOutlineStyle: data.arrowOutlineStyle,\n arrowHeadStyle: data.arrowHeadStyle,\n arrowCurved: data.arrowCurved,\n arrowCurveAmount: data.arrowCurveAmount,\n controlPoint1: data.controlPoint1 ? { x: data.controlPoint1.x + offsetX, y: data.controlPoint1.y + offsetY } : null,\n controlPoint2: data.controlPoint2 ? { x: data.controlPoint2.x + offsetX, y: data.controlPoint2.y + offsetY } : null\n };\n const newArrow = new Arrow(\n { x: data.startPoint.x + offsetX, y: data.startPoint.y + offsetY },\n { x: data.endPoint.x + offsetX, y: data.endPoint.y + offsetY },\n opts\n );\n return newArrow;\n }\n\n case 'freehandStroke': {\n const offsetPoints = data.points.map(p => [\n p[0] + offsetX,\n p[1] + offsetY,\n p[2] || 0.5\n ]);\n const newStroke = new FreehandStroke(offsetPoints, cloneOptions(data.options));\n newStroke.rotation = data.rotation;\n newStroke.draw();\n return newStroke;\n }\n\n case 'frame': {\n const newFrame = new Frame(\n data.x + offsetX,\n data.y + offsetY,\n data.width,\n data.height,\n {\n ...cloneOptions(data.options),\n frameName: data.frameName,\n rotation: data.rotation,\n frameType: data.frameType,\n webEmbedURL: data.webEmbedURL,\n fillStyle: data.fillStyle,\n fillColor: data.fillColor,\n gridSize: data.gridSize,\n gridColor: data.gridColor,\n }\n );\n newFrame.rotation = data.rotation;\n if (data.diagramType) newFrame._diagramType = data.diagramType;\n return newFrame;\n }\n\n case 'text': {\n // Parse the cloned HTML and insert into SVG\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = data.groupHTML;\n const clonedGroup = tempDiv.firstElementChild;\n if (!clonedGroup) return null;\n\n // Generate new unique ID\n const newID = `text-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n clonedGroup.setAttribute('id', newID);\n const textChild = clonedGroup.querySelector('text');\n if (textChild) textChild.setAttribute('id', `${newID}-text`);\n\n // Update position\n const newX = data.x + offsetX;\n const newY = data.y + offsetY;\n const rotation = data.rotation || 0;\n if (textChild && rotation) {\n try {\n const bbox = { x: 0, y: 0, width: 100, height: 30 }; // approximate until appended\n clonedGroup.setAttribute('transform', `translate(${newX}, ${newY}) rotate(${rotation}, ${bbox.width / 2}, ${bbox.height / 2})`);\n } catch (e) {\n clonedGroup.setAttribute('transform', `translate(${newX}, ${newY})`);\n }\n } else {\n clonedGroup.setAttribute('transform', `translate(${newX}, ${newY})`);\n }\n clonedGroup.setAttribute('data-x', newX);\n clonedGroup.setAttribute('data-y', newY);\n\n svgEl.appendChild(clonedGroup);\n\n const textShape = new TextShape(clonedGroup);\n return textShape;\n }\n\n case 'code': {\n const tempDiv = document.createElement('div');\n tempDiv.innerHTML = data.groupHTML;\n const clonedGroup = tempDiv.firstElementChild;\n if (!clonedGroup) return null;\n\n const newID = `code-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n clonedGroup.setAttribute('id', newID);\n const codeChild = clonedGroup.querySelector('text');\n if (codeChild) codeChild.setAttribute('id', `${newID}-code`);\n\n const newX = data.x + offsetX;\n const newY = data.y + offsetY;\n const rotation = data.rotation || 0;\n if (rotation) {\n clonedGroup.setAttribute('transform', `translate(${newX}, ${newY}) rotate(${rotation}, 0, 0)`);\n } else {\n clonedGroup.setAttribute('transform', `translate(${newX}, ${newY})`);\n }\n clonedGroup.setAttribute('data-x', newX);\n clonedGroup.setAttribute('data-y', newY);\n\n svgEl.appendChild(clonedGroup);\n\n const codeShape = new CodeShape(clonedGroup);\n return codeShape;\n }\n\n case 'image': {\n const imgEl = document.createElementNS('http://www.w3.org/2000/svg', 'image');\n const newX = data.x + offsetX;\n const newY = data.y + offsetY;\n imgEl.setAttribute('x', newX);\n imgEl.setAttribute('y', newY);\n imgEl.setAttribute('width', data.width);\n imgEl.setAttribute('height', data.height);\n imgEl.setAttribute('href', data.href);\n imgEl.setAttribute('data-shape-x', newX);\n imgEl.setAttribute('data-shape-y', newY);\n imgEl.setAttribute('data-shape-width', data.width);\n imgEl.setAttribute('data-shape-height', data.height);\n imgEl.setAttribute('preserveAspectRatio', 'none');\n imgEl.setAttribute('style', 'cursor: pointer;');\n if (data.storageProvider) imgEl.setAttribute('data-storage-provider', data.storageProvider);\n if (data.storageCloudName) imgEl.setAttribute('data-storage-cloud-name', data.storageCloudName);\n if (data.aiGenerated) imgEl.setAttribute('data-ai-generated', 'true');\n if (data.aiModel) imgEl.setAttribute('data-ai-model', data.aiModel);\n\n // ImageShape constructor moves element into a group and appends to svg\n svgEl.appendChild(imgEl);\n const imageShape = new ImageShape(imgEl);\n imageShape.rotation = data.rotation;\n if (data.frameType === 'graph' && data.graphData) {\n if (typeof window.__hydrateGraphShape === 'function') {\n window.__hydrateGraphShape(imageShape, data.graphData);\n } else {\n imageShape._frameType = 'graph';\n imageShape._graphData = cloneOptions(data.graphData);\n imageShape.element.setAttribute('data-graph-shape', 'true');\n }\n }\n return imageShape;\n }\n\n case 'icon': {\n // Parse inside an SVG document. Parsing a copied <g> through an\n // HTML <div> creates it in the HTML namespace, so it can be added\n // to shapes[] but the SVG renderer will not paint it.\n const parser = new DOMParser();\n const parsed = parser.parseFromString(\n `<svg xmlns=\"http://www.w3.org/2000/svg\">${data.elementHTML}</svg>`,\n 'image/svg+xml'\n );\n const parsedGroup = parsed.querySelector('g');\n if (!parsedGroup || parsed.querySelector('parsererror')) return null;\n const clonedEl = svgEl.ownerDocument.importNode(parsedGroup, true);\n\n const newX = data.x + offsetX;\n const newY = data.y + offsetY;\n const newID = `icon-${String(Date.now()).slice(0, 8)}-${Math.floor(Math.random() * 10000)}`;\n clonedEl.setAttribute('id', newID);\n clonedEl.setAttribute('x', newX);\n clonedEl.setAttribute('y', newY);\n clonedEl.setAttribute('data-shape-x', newX);\n clonedEl.setAttribute('data-shape-y', newY);\n clonedEl.setAttribute('data-shape-width', data.width);\n clonedEl.setAttribute('data-shape-height', data.height);\n clonedEl.setAttribute('data-shape-rotation', data.rotation);\n clonedEl.setAttribute('data-viewbox-width', data.viewboxWidth);\n clonedEl.setAttribute('data-viewbox-height', data.viewboxHeight);\n\n // Recalculate transform\n const scale = data.width / Math.max(data.viewboxWidth, data.viewboxHeight);\n const localCenterX = data.width / 2 / scale;\n const localCenterY = data.height / 2 / scale;\n clonedEl.setAttribute('transform', `translate(${newX}, ${newY}) scale(${scale}) rotate(${data.rotation}, ${localCenterX}, ${localCenterY})`);\n\n svgEl.appendChild(clonedEl);\n\n const iconShape = new IconShape(clonedEl);\n return iconShape;\n }\n\n default:\n return null;\n }\n}\n\n// ============================================================\n// COPY: Serialize currently selected shapes\n// ============================================================\nfunction copySelected() {\n let selectedShapes = [];\n\n // Check multi-selection first\n if (window.multiSelection && window.multiSelection.selectedShapes && window.multiSelection.selectedShapes.size > 0) {\n selectedShapes = [...window.multiSelection.selectedShapes];\n }\n // Fall back to single currentShape\n else if (typeof currentShape !== 'undefined' && currentShape && currentShape.isSelected) {\n selectedShapes = [currentShape];\n }\n\n // If both a frame and one of its children are selected, serialize the\n // child only through the frame. This preserves ownership without creating\n // a second loose duplicate beside the pasted frame.\n const copyRoots = getCopyRoots(selectedShapes);\n const shapesToCopy = copyRoots.map(shape => serializeShape(shape)).filter(Boolean);\n\n if (shapesToCopy.length === 0) return false;\n\n // Calculate center of all copied shapes\n let totalX = 0, totalY = 0;\n shapesToCopy.forEach(d => {\n const c = getShapeCenter(d);\n totalX += c.x;\n totalY += c.y;\n });\n const centerX = totalX / shapesToCopy.length;\n const centerY = totalY / shapesToCopy.length;\n\n clipboard = {\n shapes: shapesToCopy,\n centerX,\n centerY\n };\n pasteCount = 0;\n\n return true;\n}\n\n// ============================================================\n// PASTE: Create new shapes from clipboard at mouse position\n// ============================================================\nfunction pasteClipboard() {\n if (!clipboard || clipboard.shapes.length === 0) return false;\n\n pasteCount++;\n const baseOffset = 20 * pasteCount;\n\n // Calculate paste position: center the group on the mouse pointer\n const targetX = lastMouseSVG.x;\n const targetY = lastMouseSVG.y;\n const groupOffsetX = targetX - clipboard.centerX + baseOffset;\n const groupOffsetY = targetY - clipboard.centerY + baseOffset;\n\n // Deselect all currently selected shapes\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) {\n shapes.forEach(s => {\n if (s.isSelected && typeof s.removeSelection === 'function') {\n s.removeSelection();\n s.isSelected = false;\n }\n });\n }\n if (window.multiSelection) {\n window.multiSelection.clearSelection();\n }\n if (typeof currentShape !== 'undefined') {\n currentShape = null;\n }\n if (typeof disableAllSideBars === 'function') {\n disableAllSideBars();\n }\n\n const pastedShapes = [];\n const undoBatch = beginUndoBatch();\n\n const pasteShapeTree = (data, parentFrame = null) => {\n const newShape = createShapeFromData(data, groupOffsetX, groupOffsetY);\n if (!newShape) return null;\n if (typeof shapes !== 'undefined' && Array.isArray(shapes)) shapes.push(newShape);\n if (parentFrame?.addShapeToFrame) parentFrame.addShapeToFrame(newShape);\n\n if (data.type === 'frame') {\n pushCreateAction(newShape, { frameCreation: true, containedShapes: [] });\n for (const childData of data.children || []) pasteShapeTree(childData, newShape);\n } else {\n pushCreateAction(newShape);\n }\n return newShape;\n };\n\n clipboard.shapes.forEach(data => {\n const newShape = pasteShapeTree(data);\n if (newShape) pastedShapes.push(newShape);\n });\n endUndoBatch(undoBatch, 'clipboard-paste');\n\n // Select the pasted shapes\n if (pastedShapes.length === 1) {\n const s = pastedShapes[0];\n s.isSelected = true;\n currentShape = s;\n if (typeof s.addAnchors === 'function') {\n s.addAnchors();\n } else if (typeof s.selectShape === 'function') {\n s.selectShape();\n }\n } else if (pastedShapes.length > 1 && window.multiSelection) {\n pastedShapes.forEach(s => {\n window.multiSelection.addShape(s);\n });\n window.multiSelection.updateControls();\n }\n\n return true;\n}\n\n// ============================================================\n// KEYBOARD HANDLER: Ctrl+C / Ctrl+V\n// ============================================================\nfunction handleCopyPasteKeydown(e) {\n // Don't intercept if user is typing in an input/textarea/contenteditable\n const tag = (e.target.tagName || '').toLowerCase();\n if (tag === 'input' || tag === 'textarea' || e.target.isContentEditable) return;\n\n if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'c') {\n if (copySelected()) {\n e.preventDefault();\n }\n }\n\n if ((e.ctrlKey || e.metaKey) && e.key.toLowerCase() === 'v') {\n if (pasteClipboard()) {\n e.preventDefault();\n }\n }\n}\n\n// Track mouse position for paste placement\nfunction handleMouseMoveForPaste(e) {\n const svgEl = getSVGElement();\n if (!svgEl) return;\n const viewBox = svgEl.viewBox.baseVal;\n const rect = svgEl.getBoundingClientRect();\n const mouseX = e.clientX - rect.left;\n const mouseY = e.clientY - rect.top;\n lastMouseSVG.x = viewBox.x + (mouseX / rect.width) * viewBox.width;\n lastMouseSVG.y = viewBox.y + (mouseY / rect.height) * viewBox.height;\n}\n\n// ============================================================\n// PASTE IMAGE FROM CLIPBOARD (external images, screenshots)\n// ============================================================\nfunction handlePasteEvent(e) {\n // Don't intercept if user is typing\n const tag = (e.target.tagName || '').toLowerCase();\n if (tag === 'input' || tag === 'textarea' || e.target.isContentEditable) return;\n\n const items = e.clipboardData?.items;\n if (!items) return;\n\n for (const item of items) {\n if (item.type.startsWith('image/')) {\n e.preventDefault();\n const blob = item.getAsFile();\n if (!blob) return;\n\n // Validate against the canonical allowlist \u2014 clipboard sources\n // can include animated GIFs / HEIC / TIFF / arbitrary mime types.\n if (!isAllowedImage(blob)) {\n console.warn('[CopyPaste] Rejected pasted image type:', blob.type);\n return;\n }\n\n const reader = new FileReader();\n reader.onload = async (ev) => {\n const rawDataUrl = ev.target.result;\n const isSvg = (blob.type || '').toLowerCase() === 'image/svg+xml';\n let placedDataUrl = rawDataUrl;\n let placedSize = blob.size;\n if (!isSvg) {\n try {\n const compressed = await compressImage(rawDataUrl);\n if (compressed?.dataUrl) {\n placedDataUrl = compressed.dataUrl;\n placedSize = compressed.compressedSize || placedSize;\n }\n } catch (err) {\n console.warn('[CopyPaste] Pre-placement compression failed, using raw:', err);\n }\n }\n const limit = Number(window.__roomImageLimitBytes) || 2 * 1024 * 1024;\n const personalStorage = window.__personalCloudinary?.connected && window.__personalCloudinary?.useForUploads;\n if (!personalStorage && (window.__roomImageBytesUsed || 0) + placedSize > limit) {\n alert(`Workspace image limit reached (${Math.round(limit / (1024 * 1024))} MB).`);\n return;\n }\n placeImageFromDataUrl(placedDataUrl, placedSize);\n };\n reader.readAsDataURL(blob);\n return; // only handle first image\n }\n }\n}\n\nfunction placeImageFromDataUrl(dataUrl, sizeBytes = 0) {\n const svgEl = getSVGElement();\n if (!svgEl || !window.ImageShape) return;\n\n const img = new Image();\n img.onload = () => {\n const aspectRatio = img.height / img.width;\n const displayW = Math.min(400, img.width);\n const displayH = displayW * aspectRatio;\n\n // Place at center of current viewport\n const vb = svgEl.viewBox.baseVal;\n const cx = vb.x + vb.width / 2;\n const cy = vb.y + vb.height / 2;\n\n const imgEl = document.createElementNS('http://www.w3.org/2000/svg', 'image');\n imgEl.setAttribute('href', dataUrl);\n imgEl.setAttribute('x', cx - displayW / 2);\n imgEl.setAttribute('y', cy - displayH / 2);\n imgEl.setAttribute('width', displayW);\n imgEl.setAttribute('height', displayH);\n imgEl.setAttribute('data-shape-x', cx - displayW / 2);\n imgEl.setAttribute('data-shape-y', cy - displayH / 2);\n imgEl.setAttribute('data-shape-width', displayW);\n imgEl.setAttribute('data-shape-height', displayH);\n imgEl.setAttribute('type', 'image');\n imgEl.setAttribute('preserveAspectRatio', 'none');\n imgEl.__fileSize = sizeBytes;\n imgEl.setAttribute('data-file-size', String(sizeBytes));\n window.__roomImageBytesUsed = (window.__roomImageBytesUsed || 0) + sizeBytes;\n\n svgEl.appendChild(imgEl);\n const imageShape = new ImageShape(imgEl);\n if (window.shapes) window.shapes.push(imageShape);\n if (window.pushCreateAction) window.pushCreateAction(imageShape);\n\n // Compress and upload to Cloudinary\n if (window.uploadImageToCloudinary) {\n window.uploadImageToCloudinary(imageShape);\n }\n\n console.log('[CopyPaste] Pasted image from clipboard');\n };\n img.src = dataUrl;\n}\n\n// ============================================================\n// INIT: Set up event listeners\n// ============================================================\nfunction initCopyPaste() {\n document.addEventListener('keydown', handleCopyPasteKeydown);\n document.addEventListener('pointermove', handleMouseMoveForPaste);\n document.addEventListener('paste', handlePasteEvent);\n\n // Expose for context menu\n window.copySelected = copySelected;\n window.pasteClipboard = pasteClipboard;\n}\n\nexport { initCopyPaste, copySelected, pasteClipboard };\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }