kritzel-stencil 0.0.161 → 0.0.162

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 (126) hide show
  1. package/dist/cjs/{default-text-tool.config-zB3FPuXq.js → default-line-tool.config-D1Ns0NmM.js} +3156 -1052
  2. package/dist/cjs/default-line-tool.config-D1Ns0NmM.js.map +1 -0
  3. package/dist/cjs/index.cjs.js +131 -127
  4. package/dist/cjs/index.cjs.js.map +1 -1
  5. package/dist/cjs/kritzel-color_22.cjs.entry.js +480 -147
  6. package/dist/collection/classes/core/core.class.js +140 -3
  7. package/dist/collection/classes/core/core.class.js.map +1 -1
  8. package/dist/collection/classes/core/reviver.class.js +8 -0
  9. package/dist/collection/classes/core/reviver.class.js.map +1 -1
  10. package/dist/collection/classes/core/store.class.js +5 -0
  11. package/dist/collection/classes/core/store.class.js.map +1 -1
  12. package/dist/collection/classes/handlers/line-handle.handler.js +383 -0
  13. package/dist/collection/classes/handlers/line-handle.handler.js.map +1 -0
  14. package/dist/collection/classes/handlers/move.handler.js +2 -2
  15. package/dist/collection/classes/handlers/move.handler.js.map +1 -1
  16. package/dist/collection/classes/managers/anchor.manager.js +874 -0
  17. package/dist/collection/classes/managers/anchor.manager.js.map +1 -0
  18. package/dist/collection/classes/managers/cursor.manager.js +117 -0
  19. package/dist/collection/classes/managers/cursor.manager.js.map +1 -0
  20. package/dist/collection/classes/objects/base-object.class.js +4 -2
  21. package/dist/collection/classes/objects/base-object.class.js.map +1 -1
  22. package/dist/collection/classes/objects/line.class.js +564 -0
  23. package/dist/collection/classes/objects/line.class.js.map +1 -0
  24. package/dist/collection/classes/objects/selection-group.class.js +4 -0
  25. package/dist/collection/classes/objects/selection-group.class.js.map +1 -1
  26. package/dist/collection/classes/registries/icon-registry.class.js +1 -0
  27. package/dist/collection/classes/registries/icon-registry.class.js.map +1 -1
  28. package/dist/collection/classes/tools/line-tool.class.js +172 -0
  29. package/dist/collection/classes/tools/line-tool.class.js.map +1 -0
  30. package/dist/collection/classes/tools/selection-tool.class.js +41 -8
  31. package/dist/collection/classes/tools/selection-tool.class.js.map +1 -1
  32. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +11 -2
  33. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
  34. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +130 -58
  35. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
  36. package/dist/collection/configs/default-engine-config.js +4 -0
  37. package/dist/collection/configs/default-engine-config.js.map +1 -1
  38. package/dist/collection/configs/default-line-tool.config.js +34 -0
  39. package/dist/collection/configs/default-line-tool.config.js.map +1 -0
  40. package/dist/collection/helpers/geometry.helper.js +42 -0
  41. package/dist/collection/helpers/geometry.helper.js.map +1 -1
  42. package/dist/collection/index.js +5 -0
  43. package/dist/collection/index.js.map +1 -1
  44. package/dist/collection/interfaces/anchor.interface.js +2 -0
  45. package/dist/collection/interfaces/anchor.interface.js.map +1 -0
  46. package/dist/collection/interfaces/arrow-head.interface.js +2 -0
  47. package/dist/collection/interfaces/arrow-head.interface.js.map +1 -0
  48. package/dist/collection/interfaces/engine-state.interface.js.map +1 -1
  49. package/dist/collection/interfaces/line-options.interface.js +2 -0
  50. package/dist/collection/interfaces/line-options.interface.js.map +1 -0
  51. package/dist/collection/interfaces/toolbar-control.interface.js.map +1 -1
  52. package/dist/components/index.js +4 -4
  53. package/dist/components/kritzel-brush-style.js +1 -1
  54. package/dist/components/kritzel-context-menu.js +1 -1
  55. package/dist/components/kritzel-control-brush-config.js +1 -1
  56. package/dist/components/kritzel-control-text-config.js +1 -1
  57. package/dist/components/kritzel-controls.js +1 -1
  58. package/dist/components/kritzel-editor.js +54 -13
  59. package/dist/components/kritzel-editor.js.map +1 -1
  60. package/dist/components/kritzel-engine.js +1 -1
  61. package/dist/components/kritzel-icon.js +1 -1
  62. package/dist/components/kritzel-menu-item.js +1 -1
  63. package/dist/components/kritzel-menu.js +1 -1
  64. package/dist/components/kritzel-split-button.js +1 -1
  65. package/dist/components/kritzel-utility-panel.js +1 -1
  66. package/dist/components/kritzel-workspace-manager.js +1 -1
  67. package/dist/components/{p-BdZKPKnx.js → p-7_lwv0zQ.js} +4 -4
  68. package/dist/components/{p-BdZKPKnx.js.map → p-7_lwv0zQ.js.map} +1 -1
  69. package/dist/components/{p-DbKKCHKd.js → p-BixlbUD7.js} +3 -2
  70. package/dist/components/p-BixlbUD7.js.map +1 -0
  71. package/dist/components/{p-Doixm8-N.js → p-CDteBYm9.js} +3 -3
  72. package/dist/components/{p-Doixm8-N.js.map → p-CDteBYm9.js.map} +1 -1
  73. package/dist/components/{p-58y59Acb.js → p-CkD1PQQX.js} +5 -5
  74. package/dist/components/{p-58y59Acb.js.map → p-CkD1PQQX.js.map} +1 -1
  75. package/dist/components/{p-DxNbcUzt.js → p-Cqr0Bah5.js} +3 -3
  76. package/dist/components/{p-DxNbcUzt.js.map → p-Cqr0Bah5.js.map} +1 -1
  77. package/dist/components/{p-D7BLVRXX.js → p-CuhOrcET.js} +2726 -380
  78. package/dist/components/p-CuhOrcET.js.map +1 -0
  79. package/dist/components/{p-i0IlGLv2.js → p-CvLFRlQU.js} +3 -3
  80. package/dist/components/{p-i0IlGLv2.js.map → p-CvLFRlQU.js.map} +1 -1
  81. package/dist/components/{p-BpXgwgnV.js → p-DKwJJuFb.js} +7 -7
  82. package/dist/components/{p-BpXgwgnV.js.map → p-DKwJJuFb.js.map} +1 -1
  83. package/dist/components/{p-CC8KFHSe.js → p-DZ7kxJUx.js} +3 -3
  84. package/dist/components/{p-CC8KFHSe.js.map → p-DZ7kxJUx.js.map} +1 -1
  85. package/dist/components/{p-D_ygcWSz.js → p-dMCB4tJA.js} +3 -3
  86. package/dist/components/{p-D_ygcWSz.js.map → p-dMCB4tJA.js.map} +1 -1
  87. package/dist/components/{p-CBYBurdY.js → p-sokRZ7Vn.js} +49 -5
  88. package/dist/components/p-sokRZ7Vn.js.map +1 -0
  89. package/dist/esm/{default-text-tool.config-BvCgOiKA.js → default-line-tool.config-C35m-d1Y.js} +3152 -1053
  90. package/dist/esm/default-line-tool.config-C35m-d1Y.js.map +1 -0
  91. package/dist/esm/index.js +2 -2
  92. package/dist/esm/kritzel-color_22.entry.js +399 -66
  93. package/dist/stencil/index.esm.js +1 -1
  94. package/dist/stencil/p-C35m-d1Y.js +2 -0
  95. package/dist/stencil/p-C35m-d1Y.js.map +1 -0
  96. package/dist/stencil/p-d142ef46.entry.js +10 -0
  97. package/dist/stencil/p-d142ef46.entry.js.map +1 -0
  98. package/dist/stencil/stencil.esm.js +1 -1
  99. package/dist/types/classes/core/core.class.d.ts +18 -0
  100. package/dist/types/classes/core/store.class.d.ts +2 -0
  101. package/dist/types/classes/handlers/line-handle.handler.d.ts +34 -0
  102. package/dist/types/classes/managers/anchor.manager.d.ts +160 -0
  103. package/dist/types/classes/managers/cursor.manager.d.ts +43 -0
  104. package/dist/types/classes/objects/line.class.d.ts +98 -0
  105. package/dist/types/classes/tools/line-tool.class.d.ts +17 -0
  106. package/dist/types/classes/tools/selection-tool.class.d.ts +4 -0
  107. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +2 -4
  108. package/dist/types/components.d.ts +5 -5
  109. package/dist/types/configs/default-line-tool.config.d.ts +2 -0
  110. package/dist/types/helpers/geometry.helper.d.ts +10 -0
  111. package/dist/types/index.d.ts +5 -0
  112. package/dist/types/interfaces/anchor.interface.d.ts +137 -0
  113. package/dist/types/interfaces/arrow-head.interface.d.ts +26 -0
  114. package/dist/types/interfaces/engine-state.interface.d.ts +8 -0
  115. package/dist/types/interfaces/line-options.interface.d.ts +21 -0
  116. package/dist/types/interfaces/toolbar-control.interface.d.ts +17 -1
  117. package/package.json +1 -1
  118. package/dist/cjs/default-text-tool.config-zB3FPuXq.js.map +0 -1
  119. package/dist/components/p-CBYBurdY.js.map +0 -1
  120. package/dist/components/p-D7BLVRXX.js.map +0 -1
  121. package/dist/components/p-DbKKCHKd.js.map +0 -1
  122. package/dist/esm/default-text-tool.config-BvCgOiKA.js.map +0 -1
  123. package/dist/stencil/p-6d9756d9.entry.js +0 -10
  124. package/dist/stencil/p-6d9756d9.entry.js.map +0 -1
  125. package/dist/stencil/p-BvCgOiKA.js +0 -2
  126. package/dist/stencil/p-BvCgOiKA.js.map +0 -1
@@ -1,5 +1,5 @@
1
1
  import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-SGde3HXB.js';
2
- import { U as KritzelDevicesHelper, G as KritzelBrushTool, L as KritzelTextTool, V as KritzelMouseButton, N as KritzelSelectionTool, S as DEFAULT_BRUSH_CONFIG, I as KritzelEraserTool, T as DEFAULT_TEXT_CONFIG, J as KritzelImageTool, R as KritzelWorkspace, W as KritzelIconRegistry, X as KritzelKeyboardHelper, Y as KritzelBaseHandler, Z as KritzelToolRegistry, _ as KritzelSelectionBox, $ as KritzelSelectionGroup, a0 as KritzelBaseObject, F as KritzelImage, K as KritzelText, E as KritzelPath, a1 as Doc, a2 as DEFAULT_SYNC_CONFIG, a3 as UndoManager, Q as KritzelAppStateMap, a4 as ObjectHelper, a5 as KritzelEventHelper, a6 as KritzelBaseTool, M as KritzelCursorHelper } from './default-text-tool.config-BvCgOiKA.js';
2
+ import { Y as KritzelDevicesHelper, I as KritzelBrushTool, N as KritzelTextTool, Z as KritzelMouseButton, Q as KritzelSelectionTool, V as DEFAULT_BRUSH_CONFIG, X as DEFAULT_LINE_TOOL_CONFIG, J as KritzelLineTool, L as KritzelEraserTool, W as DEFAULT_TEXT_CONFIG, M as KritzelImageTool, T as KritzelWorkspace, _ as KritzelIconRegistry, $ as KritzelKeyboardHelper, a0 as KritzelBaseHandler, a1 as KritzelToolRegistry, a2 as KritzelSelectionBox, a3 as KritzelSelectionGroup, a4 as KritzelBaseObject, F as KritzelImage, K as KritzelText, G as KritzelLine, E as KritzelPath, a5 as Doc, a6 as DEFAULT_SYNC_CONFIG, a7 as UndoManager, P as KritzelCursorHelper, S as KritzelAppStateMap, U as KritzelAnchorManager, a8 as ObjectHelper, a9 as KritzelEventHelper, aa as KritzelBaseTool, ab as KritzelClassHelper } from './default-line-tool.config-C35m-d1Y.js';
3
3
 
4
4
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5
5
 
@@ -603,6 +603,13 @@ const KritzelEditor = class {
603
603
  icon: 'pen',
604
604
  config: DEFAULT_BRUSH_CONFIG,
605
605
  },
606
+ {
607
+ name: 'line',
608
+ type: 'tool',
609
+ tool: KritzelLineTool,
610
+ icon: 'arrow',
611
+ config: DEFAULT_LINE_TOOL_CONFIG,
612
+ },
606
613
  {
607
614
  name: 'eraser',
608
615
  type: 'tool',
@@ -802,7 +809,7 @@ const KritzelEditor = class {
802
809
  }
803
810
  }
804
811
  render() {
805
- return (h(Host, { key: 'c824014ce85ef5c94436211df5241d23f11caed4' }, h("kritzel-workspace-manager", { key: '8ce43afa37896897674b5df943bef3fe1ffba32b', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-engine", { key: '12f80313bb145d9065a6222d5a8b503f0eca177a', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, syncConfig: this.syncConfig, scaleMax: this.scaleMax, scaleMin: this.scaleMin, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onObjectsChange: event => this.handleObjectsChange(event), onUndoStateChange: event => this.handleUndoStateChange(event) }), h("kritzel-controls", { key: '0a1e63580afcbe65e5cf42833d86c3b34bb686c7', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, onIsControlsReady: () => (this.isControlsReady = true) })));
812
+ return (h(Host, { key: 'f107cce23625f36978736ef948a51cd91d84c3f1' }, h("kritzel-workspace-manager", { key: 'a924de174ac5226c3ac5507c35e162b35490a5dd', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-engine", { key: '48b6c14ca2c1e1a2c745ec81294a331a463219a1', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, syncConfig: this.syncConfig, scaleMax: this.scaleMax, scaleMin: this.scaleMin, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onObjectsChange: event => this.handleObjectsChange(event), onUndoStateChange: event => this.handleUndoStateChange(event) }), h("kritzel-controls", { key: '2ec26e1444f4ba642c4fdc4ef2da1a62dc0256a6', class: { 'keyboard-open': this.isVirtualKeyboardOpen }, style: { display: this.isControlsVisible ? 'flex' : 'none' }, ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState, onIsControlsReady: () => (this.isControlsReady = true) })));
806
813
  }
807
814
  static get watchers() { return {
808
815
  "isEngineReady": ["onIsEngineReady"],
@@ -18325,18 +18332,14 @@ class KritzelContextMenuHandler extends KritzelBaseHandler {
18325
18332
  }
18326
18333
  }
18327
18334
 
18328
- class KritzelClassHelper {
18329
- static isInstanceOf(object, className) {
18330
- return !!object && object.__class__ === className;
18331
- }
18332
- }
18333
-
18334
18335
  const DEFAULT_ENGINE_CONFIG = {
18335
18336
  activeWorkspace: null,
18336
18337
  activeTool: null,
18337
18338
  copiedObjects: null,
18338
18339
  objects: null,
18340
+ snapCandidate: null,
18339
18341
  resizeHandleType: null,
18342
+ lineHandleType: null,
18340
18343
  hasViewportChanged: false,
18341
18344
  hasObjectsChanged: false,
18342
18345
  isReady: false,
@@ -18350,6 +18353,8 @@ const DEFAULT_ENGINE_CONFIG = {
18350
18353
  isRotating: false,
18351
18354
  isRotationHandleHovered: false,
18352
18355
  isRotationHandleSelected: false,
18356
+ isLineHandleSelected: false,
18357
+ isLineHandleDragging: false,
18353
18358
  isDragging: false,
18354
18359
  isDrawing: false,
18355
18360
  isErasing: false,
@@ -18464,6 +18469,9 @@ class KritzelReviver {
18464
18469
  case 'KritzelPath':
18465
18470
  revivedObj = KritzelPath.create(this._core).deserialize(obj);
18466
18471
  break;
18472
+ case 'KritzelLine':
18473
+ revivedObj = KritzelLine.create(this._core).deserialize(obj);
18474
+ break;
18467
18475
  case 'KritzelText':
18468
18476
  revivedObj = KritzelText.create(this._core, obj.fontSize, obj.fontFamily).deserialize(obj);
18469
18477
  break;
@@ -18494,6 +18502,9 @@ class KritzelReviver {
18494
18502
  case 'KritzelTextTool':
18495
18503
  revivedObj = new KritzelTextTool(this._core);
18496
18504
  break;
18505
+ case 'KritzelLineTool':
18506
+ revivedObj = new KritzelLineTool(this._core);
18507
+ break;
18497
18508
  default:
18498
18509
  revivedObj = obj;
18499
18510
  }
@@ -18973,6 +18984,10 @@ class KritzelStore {
18973
18984
  const drawingPaths = this._state.objects.filter(o => o instanceof KritzelPath && o.isCompleted === false);
18974
18985
  return drawingPaths.length > 0 ? drawingPaths[0] : null;
18975
18986
  }
18987
+ get currentLine() {
18988
+ const drawingLines = this._state.objects.filter(o => o instanceof KritzelLine && o.isCompleted === false);
18989
+ return drawingLines.length > 0 ? drawingLines[0] : null;
18990
+ }
18976
18991
  get offsetX() {
18977
18992
  return this._state.host.getBoundingClientRect().left;
18978
18993
  }
@@ -19009,11 +19024,129 @@ class KritzelStore {
19009
19024
  }
19010
19025
  }
19011
19026
 
19027
+ /**
19028
+ * Manages cursor state and updates across the application.
19029
+ * Handles cursor changes based on handle hovers, tool states, and interactions.
19030
+ */
19031
+ class KritzelCursorManager {
19032
+ _core;
19033
+ _targetElement = null;
19034
+ _shadowRoot = null;
19035
+ constructor(core) {
19036
+ this._core = core;
19037
+ }
19038
+ /**
19039
+ * Sets the target element where cursor styles will be applied.
19040
+ * Also sets the pointer cursor CSS variable for child components.
19041
+ */
19042
+ setTargetElement(element) {
19043
+ // Reset cursor on old target
19044
+ if (this._targetElement) {
19045
+ this._targetElement.style.cursor = '';
19046
+ this._targetElement.style.removeProperty('--kritzel-pointer-cursor');
19047
+ }
19048
+ this._targetElement = element;
19049
+ // Set the pointer cursor CSS variable for child components to use
19050
+ if (this._targetElement) {
19051
+ this._targetElement.style.setProperty('--kritzel-pointer-cursor', KritzelCursorHelper.getPointerCursor());
19052
+ }
19053
+ }
19054
+ /**
19055
+ * Gets the current cursor target element.
19056
+ */
19057
+ getTargetElement() {
19058
+ return this._targetElement;
19059
+ }
19060
+ /**
19061
+ * Sets the shadow root for element detection.
19062
+ */
19063
+ setShadowRoot(shadowRoot) {
19064
+ this._shadowRoot = shadowRoot;
19065
+ }
19066
+ /**
19067
+ * Resets cursor to default state.
19068
+ * Should be called when all pointers are released.
19069
+ */
19070
+ resetToDefault() {
19071
+ this._core.store.state.cursor = { icon: 'default', iconActive: 'default' };
19072
+ }
19073
+ /**
19074
+ * Detects handle hover states using elementsFromPoint() to work with overlapped elements.
19075
+ * This approach finds all elements at the pointer position instead of relying on pointerenter/pointerleave.
19076
+ */
19077
+ updateHoverState(ev) {
19078
+ if (this._core.store.isPointerDown)
19079
+ return;
19080
+ if (!this._shadowRoot)
19081
+ return;
19082
+ const elementsAtPoint = this._shadowRoot.elementsFromPoint(ev.clientX, ev.clientY);
19083
+ if (!elementsAtPoint || elementsAtPoint.length === 0)
19084
+ return;
19085
+ // Check for resize handle overlays (selection group)
19086
+ const resizeHandleOverlay = elementsAtPoint.find(el => el.classList.contains('resize-handle-overlay'));
19087
+ if (resizeHandleOverlay) {
19088
+ const selectionGroup = this._core.store.selectionGroup;
19089
+ const rotationDegrees = selectionGroup?.rotationDegrees ?? 0;
19090
+ // Determine rotation offset based on handle position
19091
+ const isTopLeft = resizeHandleOverlay.classList.contains('top-left');
19092
+ const isBottomRight = resizeHandleOverlay.classList.contains('bottom-right');
19093
+ const rotationOffset = (isTopLeft || isBottomRight) ? -45 : 45;
19094
+ this._core.store.state.cursor = { icon: 'move-vertical', rotation: rotationDegrees + rotationOffset };
19095
+ return;
19096
+ }
19097
+ // Check for rotation handle overlay
19098
+ const rotationHandleOverlay = elementsAtPoint.find(el => el.classList.contains('rotation-handle-overlay'));
19099
+ if (rotationHandleOverlay) {
19100
+ this._core.store.state.cursor = { icon: 'hand', iconActive: 'hand-grab' };
19101
+ return;
19102
+ }
19103
+ // Check for line handle overlays (selection line)
19104
+ const lineHandleOverlay = elementsAtPoint.find(el => el.classList.contains('selection-line-handle-overlay'));
19105
+ if (lineHandleOverlay) {
19106
+ this._core.store.state.cursor = { icon: 'hand', iconActive: 'hand-grab' };
19107
+ return;
19108
+ }
19109
+ // Reset cursor if not hovering any handle
19110
+ this._core.store.state.cursor = { icon: 'default', iconActive: 'default' };
19111
+ }
19112
+ /**
19113
+ * Applies the current cursor state to the target element.
19114
+ * Should be called in the render loop.
19115
+ */
19116
+ applyCursor() {
19117
+ const state = this._core.store.state;
19118
+ const isPointerDown = this._core.store.isPointerDown;
19119
+ const icon = state.cursor?.icon;
19120
+ const iconActive = state.cursor?.iconActive ?? icon;
19121
+ const rotation = state.cursor?.rotation;
19122
+ const cursor = KritzelCursorHelper.getCursor({
19123
+ iconName: isPointerDown ? iconActive : icon,
19124
+ rotation: rotation,
19125
+ });
19126
+ if (this._targetElement) {
19127
+ this._targetElement.style.cursor = cursor;
19128
+ }
19129
+ }
19130
+ /**
19131
+ * Cleans up cursor state when the component is disconnected.
19132
+ */
19133
+ cleanup() {
19134
+ if (this._targetElement) {
19135
+ this._targetElement.style.cursor = '';
19136
+ this._targetElement.style.removeProperty('--kritzel-pointer-cursor');
19137
+ }
19138
+ this._targetElement = null;
19139
+ this._shadowRoot = null;
19140
+ }
19141
+ }
19142
+
19012
19143
  class KritzelCore {
19013
19144
  _kritzelEngine;
19014
19145
  _store;
19015
19146
  _syncConfig;
19016
19147
  _appStateMap;
19148
+ _anchorManager;
19149
+ _cursorManager;
19017
19150
  get engine() {
19018
19151
  return this._kritzelEngine;
19019
19152
  }
@@ -19023,10 +19156,18 @@ class KritzelCore {
19023
19156
  get appStateMap() {
19024
19157
  return this._appStateMap;
19025
19158
  }
19159
+ get anchorManager() {
19160
+ return this._anchorManager;
19161
+ }
19162
+ get cursorManager() {
19163
+ return this._cursorManager;
19164
+ }
19026
19165
  constructor(kritzelEngine) {
19027
19166
  this._kritzelEngine = kritzelEngine;
19028
19167
  this._store = new KritzelStore(DEFAULT_ENGINE_CONFIG);
19029
19168
  this._appStateMap = new KritzelAppStateMap();
19169
+ this._anchorManager = new KritzelAnchorManager(this);
19170
+ this._cursorManager = new KritzelCursorManager(this);
19030
19171
  }
19031
19172
  setSyncConfig(config) {
19032
19173
  this._syncConfig = config;
@@ -19099,6 +19240,8 @@ class KritzelCore {
19099
19240
  const objectsMap = new KritzelObjectMap();
19100
19241
  await objectsMap.initialize(this, activeWorkspace.id, this._syncConfig);
19101
19242
  this._store.state.objects = objectsMap;
19243
+ // Rebuild anchor index after loading objects
19244
+ this._anchorManager.rebuildIndex();
19102
19245
  this.engine.emitObjectsChange();
19103
19246
  this.rerender();
19104
19247
  }
@@ -19159,6 +19302,15 @@ class KritzelCore {
19159
19302
  this._store.state.objects.insert(object);
19160
19303
  }
19161
19304
  removeObject(object) {
19305
+ // Handle anchor cleanup
19306
+ if (object instanceof KritzelLine) {
19307
+ // If removing a line, clean up its anchor index entries
19308
+ this._anchorManager.handleLineDeleted(object.id);
19309
+ }
19310
+ else {
19311
+ // If removing a non-line object, detach any lines anchored to it
19312
+ this._anchorManager.handleObjectDeleted(object.id);
19313
+ }
19162
19314
  object.isMounted = false;
19163
19315
  this._store.state.objects.remove(o => o.id === object.id);
19164
19316
  }
@@ -19216,8 +19368,18 @@ class KritzelCore {
19216
19368
  copy() {
19217
19369
  const selectionGroup = this._store.selectionGroup;
19218
19370
  if (selectionGroup) {
19219
- // Copy each object and store them in an array
19220
- this._store.state.copiedObjects = selectionGroup.objects.sort((a, b) => a.zIndex - b.zIndex).map(obj => obj.copy());
19371
+ // Copy each object and store them in an array, also track the ID mapping
19372
+ const idMapping = new Map();
19373
+ const copiedObjects = selectionGroup.objects
19374
+ .sort((a, b) => a.zIndex - b.zIndex)
19375
+ .map(obj => {
19376
+ const copiedObj = obj.copy();
19377
+ // Map: newId -> originalId
19378
+ idMapping.set(copiedObj.id, obj.id);
19379
+ return copiedObj;
19380
+ });
19381
+ this._store.state.copiedObjects = copiedObjects;
19382
+ this._store.state.copiedObjectIdMapping = idMapping;
19221
19383
  }
19222
19384
  }
19223
19385
  paste(x, y) {
@@ -19226,6 +19388,7 @@ class KritzelCore {
19226
19388
  return;
19227
19389
  }
19228
19390
  const activeWorkspace = this._store.state.activeWorkspace;
19391
+ const originalIdMapping = this._store.state.copiedObjectIdMapping;
19229
19392
  // Check if we're pasting from a different workspace
19230
19393
  const isDifferentWorkspace = copiedObjects.some(obj => obj.workspaceId !== activeWorkspace.id);
19231
19394
  // Calculate the bounding box of all copied objects
@@ -19257,6 +19420,14 @@ class KritzelCore {
19257
19420
  this.removeSelectionBox();
19258
19421
  // Create a new selection group for the pasted objects
19259
19422
  const selectionGroup = KritzelSelectionGroup.create(this);
19423
+ // Build a reverse mapping: originalId -> newCopiedObjectId
19424
+ // This is used to remap anchor references from original IDs to the copied object IDs
19425
+ const originalToNewIdMap = new Map();
19426
+ if (originalIdMapping) {
19427
+ originalIdMapping.forEach((originalId, copiedId) => {
19428
+ originalToNewIdMap.set(originalId, copiedId);
19429
+ });
19430
+ }
19260
19431
  // First add all copied objects to the objectsMap with updated positions
19261
19432
  copiedObjects.forEach((obj, i) => {
19262
19433
  // Update workspace if pasting to a different workspace
@@ -19272,6 +19443,27 @@ class KritzelCore {
19272
19443
  // Add to selection group
19273
19444
  selectionGroup.addOrRemove(obj);
19274
19445
  });
19446
+ // Update line anchors to point to the newly pasted objects
19447
+ // Only remap if the anchor target was also part of the copied selection
19448
+ copiedObjects.forEach(obj => {
19449
+ if (obj instanceof KritzelLine) {
19450
+ let updated = false;
19451
+ if (obj.startAnchor && originalToNewIdMap.has(obj.startAnchor.objectId)) {
19452
+ obj.startAnchor = { objectId: originalToNewIdMap.get(obj.startAnchor.objectId) };
19453
+ updated = true;
19454
+ }
19455
+ if (obj.endAnchor && originalToNewIdMap.has(obj.endAnchor.objectId)) {
19456
+ obj.endAnchor = { objectId: originalToNewIdMap.get(obj.endAnchor.objectId) };
19457
+ updated = true;
19458
+ }
19459
+ // If anchors were updated, rebuild the anchor index and persist the change
19460
+ if (updated) {
19461
+ this._store.state.objects.update(obj);
19462
+ }
19463
+ }
19464
+ });
19465
+ // Rebuild anchor index after all anchor updates
19466
+ this._anchorManager.rebuildIndex();
19275
19467
  // Mark selection group as selected
19276
19468
  selectionGroup.isSelected = true;
19277
19469
  // Set rotation for single object
@@ -19297,7 +19489,17 @@ class KritzelCore {
19297
19489
  // Update copiedObjects to the newly created objects for potential future pastes
19298
19490
  const newSelectionGroup = this._store.selectionGroup;
19299
19491
  if (newSelectionGroup) {
19300
- this._store.state.copiedObjects = newSelectionGroup.objects.sort((a, b) => a.zIndex - b.zIndex).map(obj => obj.copy());
19492
+ // Create new copies and track the ID mapping for future pastes
19493
+ const newIdMapping = new Map();
19494
+ const newCopiedObjects = newSelectionGroup.objects
19495
+ .sort((a, b) => a.zIndex - b.zIndex)
19496
+ .map(obj => {
19497
+ const copiedObj = obj.copy();
19498
+ newIdMapping.set(copiedObj.id, obj.id);
19499
+ return copiedObj;
19500
+ });
19501
+ this._store.state.copiedObjects = newCopiedObjects;
19502
+ this._store.state.copiedObjectIdMapping = newIdMapping;
19301
19503
  }
19302
19504
  this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
19303
19505
  this.engine.emitObjectsChange();
@@ -19398,6 +19600,9 @@ class KritzelCore {
19398
19600
  this._store.state.isSelecting = false;
19399
19601
  this._store.state.isResizeHandleSelected = false;
19400
19602
  this._store.state.isRotationHandleSelected = false;
19603
+ this._store.state.isLineHandleSelected = false;
19604
+ this._store.state.isLineHandleDragging = false;
19605
+ this._store.state.lineHandleType = null;
19401
19606
  this.rerender();
19402
19607
  }
19403
19608
  resetActiveText() {
@@ -19449,6 +19654,26 @@ class KritzelCore {
19449
19654
  }
19450
19655
  return [];
19451
19656
  }
19657
+ /**
19658
+ * Get all elements at a pointer position that match a given selector.
19659
+ * Uses elementsFromPoint to find overlapped elements.
19660
+ */
19661
+ getElementsAtPoint(event, selector) {
19662
+ const shadowRoot = this._store.state.host?.shadowRoot;
19663
+ if (!shadowRoot)
19664
+ return [];
19665
+ const elementsAtPoint = shadowRoot.elementsFromPoint(event.clientX, event.clientY);
19666
+ if (!elementsAtPoint || elementsAtPoint.length === 0)
19667
+ return [];
19668
+ return elementsAtPoint.filter(el => el.matches(selector));
19669
+ }
19670
+ /**
19671
+ * Check if any element at the pointer position matches the given selector.
19672
+ * Useful for detecting hover states on overlapped elements.
19673
+ */
19674
+ isPointerOverElement(event, selector) {
19675
+ return this.getElementsAtPoint(event, selector).length > 0;
19676
+ }
19452
19677
  getCanvasPoint(event) {
19453
19678
  if (!this._store.state.host) {
19454
19679
  return { x: 0, y: 0 };
@@ -19467,6 +19692,46 @@ class KritzelCore {
19467
19692
  this.clearSelection();
19468
19693
  this._store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
19469
19694
  }
19695
+ displaySelectionGroupUI(object) {
19696
+ if (!object.isSelected) {
19697
+ return false;
19698
+ }
19699
+ const selectionGroup = this._store.selectionGroup;
19700
+ if (!selectionGroup) {
19701
+ // During selection phase (no group yet), hide UI for KritzelLine objects
19702
+ return !(object instanceof KritzelLine);
19703
+ }
19704
+ // Show UI if selection contains more than one object
19705
+ if (selectionGroup.objects.length > 1) {
19706
+ return true;
19707
+ }
19708
+ // Hide UI if selection contains a single KritzelLine
19709
+ if (selectionGroup.objects.length === 1) {
19710
+ const selectedObject = selectionGroup.objects[0];
19711
+ return !(selectedObject instanceof KritzelLine);
19712
+ }
19713
+ return true;
19714
+ }
19715
+ displaySelectionLineUI(object) {
19716
+ // Only show line UI on KritzelLine objects, not on selection groups
19717
+ if (!(object instanceof KritzelLine)) {
19718
+ return false;
19719
+ }
19720
+ // During selection phase (no group yet), show line UI if line is selected
19721
+ const selectionGroup = this._store.selectionGroup;
19722
+ if (!selectionGroup) {
19723
+ return object.isSelected;
19724
+ }
19725
+ if (!selectionGroup.isSelected) {
19726
+ return false;
19727
+ }
19728
+ // Show UI only if selection contains exactly one KritzelLine and it's this object
19729
+ if (selectionGroup.objects.length === 1) {
19730
+ const selectedObject = selectionGroup.objects[0];
19731
+ return selectedObject instanceof KritzelLine && selectedObject.id === object.id;
19732
+ }
19733
+ return false;
19734
+ }
19470
19735
  }
19471
19736
 
19472
19737
  const kritzelEngineCss = ":host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.ProseMirror{outline:none}p,h1,h2,h3,h4,h5,h6,blockquote,pre{margin:0;padding:0}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}.PlaygroundEditorTheme__quote{margin:0;margin-left:20px;margin-bottom:10px;font-size:15px;color:rgb(101, 103, 107);border-left-color:rgb(206, 208, 212);border-left-width:4px;border-left-style:solid;padding-left:16px}";
@@ -19510,12 +19775,7 @@ const KritzelEngine = class {
19510
19775
  }
19511
19776
  cursorTarget;
19512
19777
  onCursorTargetChange(newValue) {
19513
- // Reset cursor on old target
19514
- if (this.cursorTargetElement) {
19515
- this.cursorTargetElement.style.cursor = '';
19516
- }
19517
- // Set new target (defaults to document.body)
19518
- this.cursorTargetElement = newValue || document.body;
19778
+ this.core.cursorManager.setTargetElement(newValue || document.body);
19519
19779
  }
19520
19780
  isEngineReady;
19521
19781
  activeToolChange;
@@ -19563,6 +19823,8 @@ const KritzelEngine = class {
19563
19823
  if (this.core.store.state.pointers.size > 1) {
19564
19824
  this.throttledPointerMoveMulti(ev);
19565
19825
  }
19826
+ // Update cursor for handle hover states using elementsFromPoint
19827
+ this.core.cursorManager.updateHoverState(ev);
19566
19828
  this.viewport.handlePointerMove(ev);
19567
19829
  this.core.store.state?.activeTool?.handlePointerMove(ev);
19568
19830
  }
@@ -19574,7 +19836,7 @@ const KritzelEngine = class {
19574
19836
  this.host.releasePointerCapture(ev.pointerId);
19575
19837
  // Reset cursor to default when all pointers are released
19576
19838
  if (this.core.store.state.pointers.size === 0) {
19577
- this.core.store.state.cursor = { icon: 'default', iconActive: 'default' };
19839
+ this.core.cursorManager.resetToDefault();
19578
19840
  }
19579
19841
  this.viewport.handlePointerUp(ev);
19580
19842
  this.core.store.state?.activeTool?.handlePointerUp(ev);
@@ -19587,7 +19849,7 @@ const KritzelEngine = class {
19587
19849
  this.core.store.state.pointers.delete(ev.pointerId);
19588
19850
  // Reset cursor to default when all pointers are released
19589
19851
  if (this.core.store.state.pointers.size === 0) {
19590
- this.core.store.state.cursor = { icon: 'default', iconActive: 'default' };
19852
+ this.core.cursorManager.resetToDefault();
19591
19853
  }
19592
19854
  this.viewport.handlePointerUp(ev);
19593
19855
  this.core.store.state?.activeTool?.handlePointerUp(ev);
@@ -19763,7 +20025,6 @@ const KritzelEngine = class {
19763
20025
  contextMenuHandler;
19764
20026
  keyHandler;
19765
20027
  contextMenuElement = null;
19766
- cursorTargetElement = null;
19767
20028
  get isSelecting() {
19768
20029
  return this.core.store.state.activeTool instanceof KritzelSelectionTool && this.core.store.state.isSelecting;
19769
20030
  }
@@ -19783,12 +20044,7 @@ const KritzelEngine = class {
19783
20044
  disconnectedCallback() {
19784
20045
  this.throttledWheel.cancel();
19785
20046
  this.throttledPointerMoveMulti.cancel();
19786
- // Reset cursor on target element
19787
- if (this.cursorTargetElement) {
19788
- this.cursorTargetElement.style.cursor = '';
19789
- this.cursorTargetElement.style.removeProperty('--kritzel-pointer-cursor');
19790
- this.cursorTargetElement = null;
19791
- }
20047
+ this.core.cursorManager.cleanup();
19792
20048
  }
19793
20049
  componentWillLoad() {
19794
20050
  this.validateScaleMax(this.scaleMax);
@@ -19798,10 +20054,9 @@ const KritzelEngine = class {
19798
20054
  this.contextMenuHandler = new KritzelContextMenuHandler(this.core, this.globalContextMenuItems, this.objectContextMenuItems);
19799
20055
  this.keyHandler = new KritzelKeyHandler(this.core);
19800
20056
  this.viewport = new KritzelViewport(this.core, this.host);
19801
- // Set cursor target element (use prop value or default to document.body)
19802
- this.cursorTargetElement = this.cursorTarget || document.body;
19803
- // Set the pointer cursor CSS variable for child components to use
19804
- this.cursorTargetElement.style.setProperty('--kritzel-pointer-cursor', KritzelCursorHelper.getPointerCursor());
20057
+ // Initialize cursor manager with target element and shadow root
20058
+ this.core.cursorManager.setTargetElement(this.cursorTarget || document.body);
20059
+ this.core.cursorManager.setShadowRoot(this.host.shadowRoot);
19805
20060
  // Set sync configuration if provided
19806
20061
  if (this.syncConfig) {
19807
20062
  this.core.setSyncConfig(this.syncConfig);
@@ -19843,20 +20098,6 @@ const KritzelEngine = class {
19843
20098
  KritzelKeyboardHelper.forceHideKeyboard();
19844
20099
  this.core.rerender();
19845
20100
  }
19846
- updateCursor() {
19847
- const state = this.core.store.state;
19848
- const isPointerDown = this.core.store.isPointerDown;
19849
- const icon = state.cursor?.icon;
19850
- const iconActive = state.cursor?.iconActive ?? icon;
19851
- const rotation = state.cursor?.rotation;
19852
- const cursor = KritzelCursorHelper.getCursor({
19853
- iconName: isPointerDown ? iconActive : icon,
19854
- rotation: rotation,
19855
- });
19856
- if (this.cursorTargetElement) {
19857
- this.cursorTargetElement.style.cursor = cursor;
19858
- }
19859
- }
19860
20101
  render() {
19861
20102
  const computedStyle = window.getComputedStyle(this.host);
19862
20103
  const baseHandleSizePx = computedStyle.getPropertyValue('--kritzel-selection-handle-size').trim() || '6px';
@@ -19873,17 +20114,17 @@ const KritzelEngine = class {
19873
20114
  depth: 100,
19874
20115
  };
19875
20116
  const visibleObjects = this.core.store.state.objects.query(viewportBounds);
19876
- this.updateCursor();
19877
- return (h(Host, { key: '192c356c5476b2b3cf370b05efd5742776423200' }, this.core.store.state.debugInfo.showViewportInfo && (h("div", { key: 'fae1b053c1eda01726f6b583a8dd167bb1c34aa1', class: "debug-panel" }, h("div", { key: '0e0fab7c39c1c8116831cf7b228914b0c40fb338' }, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", { key: '770d284f5104919c5c6a36e653971d3662e9428b' }, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", { key: '4937256ccf074a0a2fffb9c8c32a8c6ba41d3fb4' }, "TranslateX: ", this.core.store.state?.translateX), h("div", { key: '447d95aed0dda6e212e7c67ff4bc0a2e574131fd' }, "TranslateY: ", this.core.store.state?.translateY), h("div", { key: '548a04b16f68873e5fc0a2767146b52e83b9f0f8' }, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", { key: '16a92abf89f1b438f14f311dd248ae82e1ac1982' }, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", { key: '92a2abc5a757c64d764f3e1ee525556eb6a88852' }, "PointerCount: ", this.core.store.state.pointers.size), h("div", { key: '7677d4fd149ef2507626e50502d7c2b74fb294af' }, "Scale: ", this.core.store.state?.scale), h("div", { key: '3120c7ff85fd9f8ef14fb313b9aae6f2fc817f75' }, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", { key: '100cd8a8c221d66046d9ff869b23809ca2568d12' }, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", { key: '2efec039f635eec81d172113d55284eb9002f339' }, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", { key: 'f1df2fbf86a1944831c26a23e8c0baadd5ba1c56' }, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", { key: '10098cd2ffd07200fc8a12941ffd91fc1fac4de8' }, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", { key: '75043ccdac3ef3b02dae17b758813132174c2034' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: '59217b67d572cc60fc8381bcc930a952fea2faaa' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: 'c4a7d64031d3b430673adb6adcb7f525f7a47ddc' }, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: 'd62bef9cab424e77781a3d5639552b8122e92238' }, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: 'ab5dbbc947b335a1396a945328a5939d690d8cd0' }, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", { key: 'fb2c19a0cdc070ecbf28e51b08112a73ffcf2817' }, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", { key: '2d5519541aeb9a6423524463a03d1626f5eaf6ca' }, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", { key: 'f86b578263c68ac194d6b3d606a1cb31717b1792' }, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", { key: '52ed5379ef3e9a18cbabe14be8106055a8f71ede' }, "PointerX: ", this.core.store.state?.pointerX), h("div", { key: '6b97e5f6c90666283fb5cfed0cf0e3b7bc0fffe3' }, "PointerY: ", this.core.store.state?.pointerY), h("div", { key: '5f80b9d4121974ee1e8afe89925b6b38b840e90f' }, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", { key: '8a280b4454677f5dc29e4a2a39fd4f7cfc8c26df' }, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { key: '660dd95852906f5c049b9527b26ea0af3fa04274', id: "origin", class: "origin", style: {
20117
+ this.core.cursorManager.applyCursor();
20118
+ return (h(Host, { key: '4a7e8c72ad1f80c3c31aa37eff33e78634cb37d1' }, this.core.store.state.debugInfo.showViewportInfo && (h("div", { key: '3c8981ce6cafbc49f4f04189d27809c511bf45c4', class: "debug-panel" }, h("div", { key: '428d483a87b98cde24446a0a26ba790ec2a6358b' }, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", { key: '3ec597c219109c026f78e5018a885e88e51aa5c4' }, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", { key: '803c0d009b19fdc7c465ef14f3b5f278a954a912' }, "TranslateX: ", this.core.store.state?.translateX), h("div", { key: '8b1aef0ae845cdf4b93afe59d8c78c84dd181a2d' }, "TranslateY: ", this.core.store.state?.translateY), h("div", { key: '137ead0c39a2fba55b4c4dde53fb09d0832439e1' }, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", { key: 'b19f710385e4306620176551853eb2645b96ca7a' }, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", { key: '943b55daada95aa37b759e45a15ffcfca76fba72' }, "PointerCount: ", this.core.store.state.pointers.size), h("div", { key: 'd001782dd4bc48c84c08477b26e5f3fce8df0b47' }, "Scale: ", this.core.store.state?.scale), h("div", { key: 'ed640d3905b39a995ba40a1cbf38f10a4aa1b400' }, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", { key: '154888aabbb56365aaf4584b0b991be848629e3e' }, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", { key: 'c0c39e988940baf20137de8a0eeda2c085da2810' }, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", { key: 'abd5a79b27bc75e898877d33097597c057dc3f2b' }, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", { key: '9c49bf3246525c9a755bb293bec8a143ade97158' }, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", { key: '88ff8ab48af31bf036719f72a5a3726780ab9720' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: '9650075f855fcf91b7303d3ace14242075fc523d' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: '911acb1f90f9812d30dc0aebceb207aecf9b4248' }, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: 'b65db638d3cefbd74e2d03b639ee5fe86a2a858b' }, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: 'c53ca259dadc656762733119b4086c1f82235a7e' }, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", { key: 'ae2d7a8917af450eb3bfd8e171a87530f337c0c2' }, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", { key: '5633cd9901ec028e4f5433c84b07321932beea66' }, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", { key: '82232a8eec470562e5658dee9713c855e78ca6a3' }, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", { key: '5b6b04b323a21ef37ddb144721ea01dccc7aec8b' }, "PointerX: ", this.core.store.state?.pointerX), h("div", { key: '3287f804515cfa31eaa755332e2043fce4feb7a9' }, "PointerY: ", this.core.store.state?.pointerY), h("div", { key: '3a59fd4db60f6f05d419de39149ea10e482875d4' }, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", { key: 'f91a8ea9dfc50e5f1ae89d66c7609a103e3263a4' }, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { key: '40ba8fb5530243c18e0b0c3ad68dadb2cbc615a1', id: "origin", class: "origin", style: {
19878
20119
  transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
19879
20120
  } }, visibleObjects?.map(object => {
19880
20121
  return (h("div", { key: object.id, style: {
19881
20122
  transform: object?.transformationMatrix,
19882
20123
  transformOrigin: 'top left',
19883
- zIndex: object.zIndex.toString(),
19884
20124
  position: 'absolute',
19885
20125
  pointerEvents: this.core.store.state.isScaling ? 'none' : 'auto',
19886
20126
  } }, h("svg", { xmlns: "http://www.w3.org/2000/svg", id: object.id, class: "object", style: {
20127
+ zIndex: object.zIndex.toString(),
19887
20128
  height: object?.totalHeight.toString(),
19888
20129
  width: object?.totalWidth.toString(),
19889
20130
  left: '0',
@@ -19893,7 +20134,7 @@ const KritzelEngine = class {
19893
20134
  transformOrigin: `${object.totalWidth / 2}px ${object.totalHeight / 2}px`,
19894
20135
  opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
19895
20136
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
19896
- } }, h("foreignObject", { x: "0", y: "0", width: object.totalWidth.toString(), height: object.totalHeight.toString(), style: {
20137
+ } }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (h("svg", { ref: el => object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: { overflow: 'visible' }, viewBox: object?.viewBox }, h("path", { d: object?.d, fill: object.fill, stroke: object?.stroke, "shape-rendering": object.isLowRes() ? 'optimizeSpeed' : 'auto' }))), KritzelClassHelper.isInstanceOf(object, 'KritzelLine') && (h("svg", { ref: el => object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: { overflow: 'visible' }, viewBox: object?.viewBox }, h("defs", null, object.hasStartArrow && (h("marker", { id: object.startMarkerId, markerWidth: object.getArrowSize('start'), markerHeight: object.getArrowSize('start'), refX: 0, refY: object.getArrowSize('start') / 2, orient: "auto-start-reverse", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.start?.style), fill: object.getArrowFill('start'), transform: `scale(${object.getArrowSize('start') / 10})` }))), object.hasEndArrow && (h("marker", { id: object.endMarkerId, markerWidth: object.getArrowSize('end'), markerHeight: object.getArrowSize('end'), refX: 0, refY: object.getArrowSize('end') / 2, orient: "auto", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.end?.style), fill: object.getArrowFill('end'), transform: `scale(${object.getArrowSize('end') / 10})` })))), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: object?.stroke, "stroke-width": object?.strokeWidth, "stroke-linecap": "round", "marker-start": object.hasStartArrow ? `url(#${object.startMarkerId})` : undefined, "marker-end": object.hasEndArrow ? `url(#${object.endMarkerId})` : undefined }))), h("foreignObject", { x: "0", y: "0", width: object.totalWidth.toString(), height: object.totalHeight.toString(), style: {
19897
20138
  minHeight: '0',
19898
20139
  minWidth: '0',
19899
20140
  backgroundColor: object.backgroundColor,
@@ -19902,18 +20143,14 @@ const KritzelEngine = class {
19902
20143
  borderStyle: 'solid',
19903
20144
  padding: object.padding + 'px',
19904
20145
  overflow: 'visible',
19905
- } }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (h("svg", { ref: el => object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: {
19906
- height: object?.height.toString(),
19907
- width: object?.width.toString(),
19908
- position: 'absolute',
19909
- overflow: 'visible',
19910
- }, viewBox: object?.viewBox }, h("path", { d: object?.d, fill: object.fill, stroke: object?.stroke, "shape-rendering": object.isLowRes() ? 'optimizeSpeed' : 'auto' }))), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (h("img", { ref: el => object.mount(el), src: object.src, style: {
20146
+ display: KritzelClassHelper.isInstanceOf(object, 'KritzelLine') || KritzelClassHelper.isInstanceOf(object, 'KritzelPath') ? 'none' : 'block'
20147
+ } }, KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (h("img", { ref: el => object.mount(el), src: object.src, style: {
19911
20148
  width: '100%',
19912
20149
  height: '100%',
19913
20150
  userSelect: 'none',
19914
20151
  pointerEvents: 'none',
19915
20152
  imageRendering: this.core.store.state.isScaling || this.core.store.state.isPanning ? 'pixelated' : 'auto',
19916
- }, draggable: false, onDragStart: e => e.preventDefault() })), KritzelClassHelper.isInstanceOf(object, 'KritzelText') && (h("div", { ref: el => object.mount(el), onPointerDown: e => object.handlePointerDown(e), onPointerMove: e => object.handlePointerMove(e), onPointerUp: e => object.handlePointerUp(e), style: {
20153
+ }, draggable: false, onDragStart: e => e.preventDefault() })), KritzelClassHelper.isInstanceOf(object, 'KritzelText') && (h("div", { id: "text-object", ref: el => object.mount(el), onPointerDown: e => object.handlePointerDown(e), onPointerMove: e => object.handlePointerMove(e), onPointerUp: e => object.handlePointerUp(e), style: {
19917
20154
  minWidth: object.initialWidth + 'px',
19918
20155
  minHeight: object.initialHeight + 'px',
19919
20156
  maxWidth: '500px',
@@ -19930,7 +20167,7 @@ const KritzelEngine = class {
19930
20167
  pointerEvents: 'auto',
19931
20168
  overflow: 'hidden',
19932
20169
  display: 'block',
19933
- } })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') && (h("div", { ref: el => object.mount(el), style: {
20170
+ } })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') && !this.core.displaySelectionLineUI(object) && (h("div", { ref: el => object.mount(el), style: {
19934
20171
  width: '100%',
19935
20172
  height: '100%',
19936
20173
  } })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionBox') && (h("div", { ref: el => object.mount(el), style: {
@@ -19940,7 +20177,8 @@ const KritzelEngine = class {
19940
20177
  borderWidth: KritzelDevicesHelper.isFirefox() ? object.borderWidth + 'px' : '0',
19941
20178
  borderStyle: KritzelDevicesHelper.isFirefox() ? 'solid' : 'none',
19942
20179
  borderColor: KritzelDevicesHelper.isFirefox() ? object.borderColor : 'transparent',
19943
- } }))), this.core.store.state.debugInfo.showObjectInfo && object.isDebugInfoVisible && (h("g", { style: { pointerEvents: 'none' } }, h("foreignObject", { x: object.totalWidth.toString(), y: "0", width: "400px", height: "160px", style: { minHeight: '0', minWidth: '0' } }, h("div", { style: { width: '100%', height: '100%' } }, h("div", { style: { whiteSpace: 'nowrap' } }, "Id: ", object.id), h("div", { style: { whiteSpace: 'nowrap' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap' } }, "translateY: ", object.translateY)))))), h("svg", { xmlns: "http://www.w3.org/2000/svg", style: {
20180
+ } }))), this.core.store.state.debugInfo.showObjectInfo && object.isDebugInfoVisible && (h("g", { style: { pointerEvents: 'none' } }, h("foreignObject", { x: object.totalWidth.toString(), y: "0", width: "400px", height: "160px", style: { minHeight: '0', minWidth: '0' } }, h("div", { style: { width: '100%', height: '100%' } }, h("div", { style: { whiteSpace: 'nowrap' } }, "Id: ", object.id), h("div", { style: { whiteSpace: 'nowrap' } }, "width: ", object.width), h("div", { style: { whiteSpace: 'nowrap' } }, "height: ", object.height), h("div", { style: { whiteSpace: 'nowrap' } }, "translateX: ", object.translateX), h("div", { style: { whiteSpace: 'nowrap' } }, "translateY: ", object.translateY), h("div", { style: { whiteSpace: 'nowrap' } }, "rotationDegrees: ", object.rotationDegrees)))))), h("svg", { xmlns: "http://www.w3.org/2000/svg", style: {
20181
+ zIndex: (object.zIndex + 1).toString(),
19944
20182
  height: object?.totalHeight.toString(),
19945
20183
  width: object?.totalWidth.toString(),
19946
20184
  left: '0',
@@ -19950,7 +20188,7 @@ const KritzelEngine = class {
19950
20188
  transformOrigin: `${object.totalWidth / 2}px ${object.totalHeight / 2}px`,
19951
20189
  overflow: 'visible',
19952
20190
  pointerEvents: 'none',
19953
- } }, object.isSelected && (h("g", { class: "selection-borders", style: { pointerEvents: 'none' } }, h("line", { x1: "0", y1: "0", x2: object.totalWidth, y2: "0", style: {
20191
+ } }, this.core.displaySelectionGroupUI(object) && (h("g", { class: "selection-group-ui", style: { pointerEvents: 'none' } }, h("g", { class: "selection-group-borders" }, h("line", { x1: "0", y1: "0", x2: object.totalWidth, y2: "0", style: {
19954
20192
  stroke: 'var(--kritzel-selection-border-color, #007AFF)',
19955
20193
  strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
19956
20194
  strokeLinecap: 'square',
@@ -19966,31 +20204,31 @@ const KritzelEngine = class {
19966
20204
  stroke: 'var(--kritzel-selection-border-color, #007AFF)',
19967
20205
  strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
19968
20206
  strokeLinecap: 'square',
19969
- } }))), object.isSelected && !this.isSelecting && (h("g", { class: "selection-handles", style: { pointerEvents: 'auto' } }, h("circle", { class: "resize-handle top-left", cx: "0", cy: "0", r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
20207
+ } })), !this.isSelecting && (h("g", { class: "selection-group-handles", style: { pointerEvents: 'auto' } }, h("circle", { class: "resize-handle top-left", cx: "0", cy: "0", r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
19970
20208
  fill: 'var(--kritzel-selection-handle-color, #000000)',
19971
20209
  paintOrder: 'fill',
19972
20210
  } }), h("circle", { class: "resize-handle-overlay top-left", cx: "0", cy: "0", r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
19973
20211
  fill: 'transparent',
19974
20212
  paintOrder: 'fill',
19975
- }, onPointerEnter: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'move-vertical', rotation: object.rotationDegrees - 45 }), onPointerLeave: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'default', iconActive: 'default' }) }), h("circle", { class: "resize-handle top-right", cx: object.totalWidth, cy: "0", r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
20213
+ } }), h("circle", { class: "resize-handle top-right", cx: object.totalWidth, cy: "0", r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
19976
20214
  fill: 'var(--kritzel-selection-handle-color, #000000)',
19977
20215
  paintOrder: 'fill',
19978
20216
  } }), h("circle", { class: "resize-handle-overlay top-right", cx: object.totalWidth, cy: "0", r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
19979
20217
  fill: 'transparent',
19980
20218
  paintOrder: 'fill',
19981
- }, onPointerEnter: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'move-vertical', rotation: object.rotationDegrees + 45 }), onPointerLeave: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'default', iconActive: 'default' }) }), h("circle", { class: "resize-handle bottom-left", cx: "0", cy: object.totalHeight, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
20219
+ } }), h("circle", { class: "resize-handle bottom-left", cx: "0", cy: object.totalHeight, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
19982
20220
  fill: 'var(--kritzel-selection-handle-color, #000000)',
19983
20221
  paintOrder: 'fill',
19984
20222
  } }), h("circle", { class: "resize-handle-overlay bottom-left", cx: "0", cy: object.totalHeight, r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
19985
20223
  fill: 'transparent',
19986
20224
  paintOrder: 'fill',
19987
- }, onPointerEnter: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'move-vertical', rotation: object.rotationDegrees + 45 }), onPointerLeave: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'default', iconActive: 'default' }) }), h("circle", { class: "resize-handle bottom-right", cx: object.totalWidth, cy: object.totalHeight, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
20225
+ } }), h("circle", { class: "resize-handle bottom-right", cx: object.totalWidth, cy: object.totalHeight, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
19988
20226
  fill: 'var(--kritzel-selection-handle-color, #000000)',
19989
20227
  paintOrder: 'fill',
19990
20228
  } }), h("circle", { class: "resize-handle-overlay bottom-right", cx: object.totalWidth, cy: object.totalHeight, r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
19991
20229
  fill: 'transparent',
19992
20230
  paintOrder: 'fill',
19993
- }, onPointerEnter: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'move-vertical', rotation: object.rotationDegrees - 45 }), onPointerLeave: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'default', iconActive: 'default' }) }), h("line", { x1: object.totalWidth / 2, y1: "0", x2: object.totalWidth / 2, y2: -((15 * object.scale) / this.core.store.state?.scale), style: {
20231
+ } }), h("line", { x1: object.totalWidth / 2, y1: "0", x2: object.totalWidth / 2, y2: -((15 * object.scale) / this.core.store.state?.scale), style: {
19994
20232
  stroke: 'var(--kritzel-selection-border-color, #007AFF)',
19995
20233
  strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
19996
20234
  } }), h("circle", { class: "rotation-handle", cx: object.totalWidth / 2, cy: -((15 * object.scale) / this.core.store.state?.scale), r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
@@ -19999,8 +20237,103 @@ const KritzelEngine = class {
19999
20237
  } }), h("circle", { class: "rotation-handle-overlay", cx: object.totalWidth / 2, cy: -((15 * object.scale) / this.core.store.state?.scale), r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
20000
20238
  fill: 'transparent',
20001
20239
  paintOrder: 'fill',
20002
- }, onPointerEnter: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'hand', iconActive: 'hand-grab' }), onPointerLeave: () => !this.core.store.isPointerDown && (this.core.store.state.cursor = { icon: 'default', iconActive: 'default' }) }))))));
20003
- })), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: '0da13416f8f2cf2f0eb6fcbb8eacb942dda0efb5', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.core.store.state.contextMenuItems, objects: this.core.store.selectionGroup?.objects || [], style: {
20240
+ } }))))), this.core.displaySelectionLineUI(object) && KritzelClassHelper.isInstanceOf(object, 'KritzelLine') && (h("g", { class: "selection-line-ui", style: { pointerEvents: 'none' } }, h("g", { class: "selection-line-borders" }, h("path", { class: "selection-line-border", d: this.core.anchorManager.computeClippedLinePath(object, true), style: {
20241
+ stroke: 'var(--kritzel-selection-border-color, #007AFF)',
20242
+ strokeWidth: `calc(var(--kritzel-selection-border-width, 2px) * ${object.scale} / ${this.core.store.state?.scale})`,
20243
+ strokeLinecap: 'round',
20244
+ fill: 'none',
20245
+ } })), !this.isSelecting && (h("g", { class: "selection-line-handles", style: { pointerEvents: 'auto' } }, h("circle", { class: "selection-line-handle start", cx: object.startX - object.x, cy: object.startY - object.y, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
20246
+ fill: 'var(--kritzel-selection-handle-color, #000000)',
20247
+ paintOrder: 'fill',
20248
+ } }), h("circle", { class: "selection-line-handle-overlay start", cx: object.startX - object.x, cy: object.startY - object.y, r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
20249
+ fill: 'transparent',
20250
+ paintOrder: 'fill',
20251
+ } }), h("circle", { class: "selection-line-handle center", cx: object.controlX !== undefined ? (object.startX + 2 * object.controlX + object.endX) / 4 - object.x : (object.startX - object.x + object.endX - object.x) / 2, cy: object.controlY !== undefined ? (object.startY + 2 * object.controlY + object.endY) / 4 - object.y : (object.startY - object.y + object.endY - object.y) / 2, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
20252
+ fill: 'var(--kritzel-selection-handle-color, #000000)',
20253
+ paintOrder: 'fill',
20254
+ } }), h("circle", { class: "selection-line-handle-overlay center", cx: object.controlX !== undefined ? (object.startX + 2 * object.controlX + object.endX) / 4 - object.x : (object.startX - object.x + object.endX - object.x) / 2, cy: object.controlY !== undefined ? (object.startY + 2 * object.controlY + object.endY) / 4 - object.y : (object.startY - object.y + object.endY - object.y) / 2, r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
20255
+ fill: 'transparent',
20256
+ paintOrder: 'fill',
20257
+ } }), h("circle", { class: "selection-line-handle end", cx: object.endX - object.x, cy: object.endY - object.y, r: `${(baseHandleSize * object.scale) / this.core.store.state?.scale}`, style: {
20258
+ fill: 'var(--kritzel-selection-handle-color, #000000)',
20259
+ paintOrder: 'fill',
20260
+ } }), h("circle", { class: "selection-line-handle-overlay end", cx: object.endX - object.x, cy: object.endY - object.y, r: `${(baseHandleTouchSize * object.scale) / this.core.store.state?.scale}`, style: {
20261
+ fill: 'transparent',
20262
+ paintOrder: 'fill',
20263
+ } }))))))));
20264
+ }), (() => {
20265
+ const data = this.core.anchorManager.getAnchorLinesRenderData();
20266
+ if (!data)
20267
+ return null;
20268
+ return (h("svg", { xmlns: "http://www.w3.org/2000/svg", class: "anchor-lines", style: {
20269
+ position: 'absolute',
20270
+ left: '0',
20271
+ top: '0',
20272
+ width: '1px',
20273
+ height: '1px',
20274
+ pointerEvents: 'none',
20275
+ zIndex: '9998',
20276
+ overflow: 'visible',
20277
+ } }, data.startAnchorViz && (h("g", { class: "anchor-line-start" }, data.startAnchorViz.pathD ? (h("path", { d: data.startAnchorViz.pathD, style: {
20278
+ stroke: 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.3))',
20279
+ strokeWidth: `${data.lineStrokeWidth}`,
20280
+ strokeDasharray: data.dashArray,
20281
+ strokeLinecap: 'round',
20282
+ fill: 'none',
20283
+ } })) : (h("line", { x1: data.startAnchorViz.edgeX, y1: data.startAnchorViz.edgeY, x2: data.startAnchorViz.centerX, y2: data.startAnchorViz.centerY, style: {
20284
+ stroke: 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.3))',
20285
+ strokeWidth: `${data.lineStrokeWidth}`,
20286
+ strokeDasharray: data.dashArray,
20287
+ strokeLinecap: 'round',
20288
+ } })), h("circle", { cx: data.startAnchorViz.centerX, cy: data.startAnchorViz.centerY, r: data.indicatorRadius, style: {
20289
+ fill: 'var(--kritzel-snap-indicator-fill, rgba(0, 0, 0))',
20290
+ stroke: 'var(--kritzel-snap-indicator-stroke, #3b82f6)',
20291
+ strokeWidth: data.indicatorStrokeWidth,
20292
+ } }))), data.endAnchorViz && (h("g", { class: "anchor-line-end" }, data.endAnchorViz.pathD ? (h("path", { d: data.endAnchorViz.pathD, style: {
20293
+ stroke: 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.2))',
20294
+ strokeWidth: `${data.lineStrokeWidth}`,
20295
+ strokeDasharray: data.dashArray,
20296
+ strokeLinecap: 'round',
20297
+ fill: 'none',
20298
+ } })) : (h("line", { x1: data.endAnchorViz.edgeX, y1: data.endAnchorViz.edgeY, x2: data.endAnchorViz.centerX, y2: data.endAnchorViz.centerY, style: {
20299
+ stroke: 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.2))',
20300
+ strokeWidth: `${data.lineStrokeWidth}`,
20301
+ strokeDasharray: data.dashArray,
20302
+ strokeLinecap: 'round',
20303
+ } })), h("circle", { cx: data.endAnchorViz.centerX, cy: data.endAnchorViz.centerY, r: data.indicatorRadius, style: {
20304
+ fill: 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))',
20305
+ stroke: 'var(--kritzel-snap-indicator-stroke, #3b82f6)',
20306
+ strokeWidth: data.indicatorStrokeWidth,
20307
+ } })))));
20308
+ })(), (() => {
20309
+ const data = this.core.anchorManager.getSnapIndicatorRenderData();
20310
+ if (!data)
20311
+ return null;
20312
+ return (h("svg", { xmlns: "http://www.w3.org/2000/svg", class: "snap-indicator", style: {
20313
+ position: 'absolute',
20314
+ left: '0',
20315
+ top: '0',
20316
+ width: '1px',
20317
+ height: '1px',
20318
+ pointerEvents: 'none',
20319
+ zIndex: '9999',
20320
+ overflow: 'visible',
20321
+ } }, h("g", null, data.snapLinePath ? (h("path", { d: data.snapLinePath, fill: "none", style: {
20322
+ stroke: 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.2))',
20323
+ strokeWidth: data.lineStrokeWidth,
20324
+ strokeDasharray: data.dashArray,
20325
+ strokeLinecap: 'round',
20326
+ } })) : (data.edgeX !== undefined && data.edgeY !== undefined && (h("line", { x1: data.edgeX, y1: data.edgeY, x2: data.centerX, y2: data.centerY, style: {
20327
+ stroke: 'var(--kritzel-snap-line-stroke, rgba(0, 0, 0, 0.2))',
20328
+ strokeWidth: data.lineStrokeWidth,
20329
+ strokeDasharray: data.dashArray,
20330
+ strokeLinecap: 'round',
20331
+ } }))), h("circle", { cx: data.centerX, cy: data.centerY, r: data.indicatorRadius, style: {
20332
+ fill: 'var(--kritzel-snap-indicator-fill, rgba(59, 130, 246, 0.3))',
20333
+ stroke: 'var(--kritzel-snap-indicator-stroke, #3b82f6)',
20334
+ strokeWidth: data.indicatorStrokeWidth,
20335
+ } }))));
20336
+ })()), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: '7e350c48da76c54a223f23ead9dea8018b0bc36c', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.core.store.state.contextMenuItems, objects: this.core.store.selectionGroup?.objects || [], style: {
20004
20337
  position: 'fixed',
20005
20338
  left: `${this.core.store.state.contextMenuX}px`,
20006
20339
  top: `${this.core.store.state.contextMenuY}px`,
@@ -20011,7 +20344,7 @@ const KritzelEngine = class {
20011
20344
  y: (-this.core.store.state.translateY + this.core.store.state.contextMenuY) / this.core.store.state.scale,
20012
20345
  }, this.core.store.selectionGroup?.objects);
20013
20346
  this.hideContextMenu();
20014
- }, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: '609dd8438a2678eaa3ce0a73858d9236c9371f96', core: this.core })));
20347
+ }, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: '7923a3f6a92fa71911c971166171317b5bc421bf', core: this.core })));
20015
20348
  }
20016
20349
  static get watchers() { return {
20017
20350
  "workspace": ["onWorkspaceChange"],