kritzel-stencil 0.1.78 → 0.1.80

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 (163) hide show
  1. package/dist/cjs/{index-BRZ6e6oa.js → index-CFnj_FXt.js} +36 -9
  2. package/dist/cjs/index.cjs.js +1 -1
  3. package/dist/cjs/kritzel-active-users_42.cjs.entry.js +333 -177
  4. package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
  5. package/dist/cjs/loader.cjs.js +2 -2
  6. package/dist/cjs/stencil.cjs.js +3 -3
  7. package/dist/cjs/{workspace.migrations-sUPrO23c.js → workspace.migrations-DUXtSb7C.js} +244 -197
  8. package/dist/collection/classes/core/core.class.js +39 -31
  9. package/dist/collection/classes/core/store.class.js +57 -16
  10. package/dist/collection/classes/core/viewport.class.js +12 -12
  11. package/dist/collection/classes/handlers/context-menu.handler.js +1 -1
  12. package/dist/collection/classes/handlers/line-handle.handler.js +7 -4
  13. package/dist/collection/classes/handlers/move.handler.js +11 -8
  14. package/dist/collection/classes/handlers/resize.handler.js +12 -3
  15. package/dist/collection/classes/handlers/rotation.handler.js +12 -3
  16. package/dist/collection/classes/handlers/selection.handler.js +20 -15
  17. package/dist/collection/classes/managers/anchor.manager.js +4 -4
  18. package/dist/collection/classes/objects/base-object.class.js +6 -6
  19. package/dist/collection/classes/objects/custom-element.class.js +2 -2
  20. package/dist/collection/classes/objects/group.class.js +10 -10
  21. package/dist/collection/classes/objects/image.class.js +2 -2
  22. package/dist/collection/classes/objects/line.class.js +7 -7
  23. package/dist/collection/classes/objects/path.class.js +5 -5
  24. package/dist/collection/classes/objects/selection-box.class.js +1 -1
  25. package/dist/collection/classes/objects/selection-group.class.js +16 -16
  26. package/dist/collection/classes/objects/shape.class.js +37 -31
  27. package/dist/collection/classes/objects/text.class.js +40 -32
  28. package/dist/collection/classes/structures/app-state-map.structure.js +18 -16
  29. package/dist/collection/classes/structures/object-map.structure.js +30 -27
  30. package/dist/collection/classes/tools/brush-tool.class.js +14 -14
  31. package/dist/collection/classes/tools/image-tool.class.js +1 -1
  32. package/dist/collection/classes/tools/line-tool.class.js +14 -14
  33. package/dist/collection/classes/tools/selection-tool.class.js +2 -2
  34. package/dist/collection/classes/tools/shape-tool.class.js +6 -6
  35. package/dist/collection/classes/tools/text-tool.class.js +2 -2
  36. package/dist/collection/collection-manifest.json +1 -1
  37. package/dist/collection/components/core/kritzel-awareness-cursors/kritzel-awareness-cursors.js +6 -6
  38. package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +2 -2
  39. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +70 -11
  40. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +21 -1
  41. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +159 -60
  42. package/dist/collection/configs/default-engine-config.js +2 -2
  43. package/dist/collection/constants/version.js +1 -1
  44. package/dist/collection/helpers/keyboard.helper.js +15 -11
  45. package/dist/components/index.js +1 -1
  46. package/dist/components/kritzel-active-users.js +1 -1
  47. package/dist/components/kritzel-avatar.js +1 -1
  48. package/dist/components/kritzel-awareness-cursors.js +1 -1
  49. package/dist/components/kritzel-back-to-content.js +1 -1
  50. package/dist/components/kritzel-brush-style.js +1 -1
  51. package/dist/components/kritzel-button.js +1 -1
  52. package/dist/components/kritzel-color-palette.js +1 -1
  53. package/dist/components/kritzel-color.js +1 -1
  54. package/dist/components/kritzel-context-menu.js +1 -1
  55. package/dist/components/kritzel-controls.js +1 -1
  56. package/dist/components/kritzel-current-user-dialog.js +1 -1
  57. package/dist/components/kritzel-current-user.js +1 -1
  58. package/dist/components/kritzel-cursor-trail.js +1 -1
  59. package/dist/components/kritzel-dialog.js +1 -1
  60. package/dist/components/kritzel-dropdown.js +1 -1
  61. package/dist/components/kritzel-editor.js +1 -1
  62. package/dist/components/kritzel-engine.js +1 -1
  63. package/dist/components/kritzel-export.js +1 -1
  64. package/dist/components/kritzel-font-family.js +1 -1
  65. package/dist/components/kritzel-font-size.js +1 -1
  66. package/dist/components/kritzel-font.js +1 -1
  67. package/dist/components/kritzel-icon.js +1 -1
  68. package/dist/components/kritzel-input.js +1 -1
  69. package/dist/components/kritzel-line-endings.js +1 -1
  70. package/dist/components/kritzel-login-dialog.js +1 -1
  71. package/dist/components/kritzel-master-detail.js +1 -1
  72. package/dist/components/kritzel-menu-item.js +1 -1
  73. package/dist/components/kritzel-menu.js +1 -1
  74. package/dist/components/kritzel-more-menu.js +1 -1
  75. package/dist/components/kritzel-numeric-input.js +1 -1
  76. package/dist/components/kritzel-opacity-slider.js +1 -1
  77. package/dist/components/kritzel-pill-tabs.js +1 -1
  78. package/dist/components/kritzel-portal.js +1 -1
  79. package/dist/components/kritzel-settings.js +1 -1
  80. package/dist/components/kritzel-shape-fill.js +1 -1
  81. package/dist/components/kritzel-share-dialog.js +1 -1
  82. package/dist/components/kritzel-slide-toggle.js +1 -1
  83. package/dist/components/kritzel-split-button.js +1 -1
  84. package/dist/components/kritzel-stroke-size.js +1 -1
  85. package/dist/components/kritzel-tool-config.js +1 -1
  86. package/dist/components/kritzel-tooltip.js +1 -1
  87. package/dist/components/kritzel-utility-panel.js +1 -1
  88. package/dist/components/kritzel-workspace-manager.js +1 -1
  89. package/dist/components/{p-Md9Y-b3d.js → p-1ppb4M65.js} +1 -1
  90. package/dist/components/{p-KJ4dHzrS.js → p-7yR-sKH8.js} +1 -1
  91. package/dist/components/{p-CN8IxBlU.js → p-B-Gej_Ak.js} +1 -1
  92. package/dist/components/{p-76W5pG2O.js → p-B4F19Aqj.js} +1 -1
  93. package/dist/components/{p-BuI6Gkzg.js → p-B5WII1Lk.js} +1 -1
  94. package/dist/components/p-BWj1eE2b.js +1 -0
  95. package/dist/components/{p-ZC5YELQJ.js → p-BZ8bK8qT.js} +1 -1
  96. package/dist/components/{p-DkWWzVg8.js → p-BaaFG0p-.js} +1 -1
  97. package/dist/components/{p-6NFl6EB2.js → p-Bat829Bg.js} +1 -1
  98. package/dist/components/p-BcwZ36sO.js +1 -0
  99. package/dist/components/{p-53di1Zko.js → p-BjPmEs5A.js} +1 -1
  100. package/dist/components/{p-D5IhryUR.js → p-Brwz_Dpb.js} +1 -1
  101. package/dist/components/p-BzQmBVwr.js +9 -0
  102. package/dist/components/{p-C2l9mZ1P.js → p-C-MtTi6x.js} +1 -1
  103. package/dist/components/p-C8WnYSHi.js +1 -0
  104. package/dist/components/{p-BLsH_Oi0.js → p-C9zsWWH2.js} +1 -1
  105. package/dist/components/{p-ZQ2bKafG.js → p-CJKsuQun.js} +1 -1
  106. package/dist/components/{p-m1nVDC3G.js → p-CJzg_ejc.js} +1 -1
  107. package/dist/components/{p-Dte67BWd.js → p-CM7rYf9A.js} +1 -1
  108. package/dist/components/{p-Dr3-pKVg.js → p-CMGHx71q.js} +1 -1
  109. package/dist/components/{p-CI9Nbh-x.js → p-CNMpVlot.js} +1 -1
  110. package/dist/components/{p-DDKjsXCe.js → p-CS7r-zhx.js} +1 -1
  111. package/dist/components/{p-DaGZEV0R.js → p-C_fSm7T4.js} +1 -1
  112. package/dist/components/{p-Ck1dhpUQ.js → p-CfEGaTaV.js} +1 -1
  113. package/dist/components/{p-CWMFGEe0.js → p-CvyE2Wg-.js} +1 -1
  114. package/dist/components/{p-D3pNw-SV.js → p-D5BXoK9m.js} +1 -1
  115. package/dist/components/{p-DV7Z_qfa.js → p-D7pwbRUy.js} +1 -1
  116. package/dist/components/{p-CBslLN3-.js → p-DCH4Rlqx.js} +1 -1
  117. package/dist/components/{p-CYh7yV-K.js → p-DEOUiiyI.js} +1 -1
  118. package/dist/components/{p-pCC6t6BH.js → p-DKeBfe_l.js} +1 -1
  119. package/dist/components/{p-DWsCbu01.js → p-DUQmBcTy.js} +1 -1
  120. package/dist/components/{p-D14QNK3X.js → p-DUnKjQN7.js} +1 -1
  121. package/dist/components/{p-BrZ_gL8Q.js → p-DYcsC2zO.js} +1 -1
  122. package/dist/components/{p-D7yzmu1l.js → p-DkT0KZCm.js} +1 -1
  123. package/dist/components/{p-Cns7qSKS.js → p-DrsORMoT.js} +1 -1
  124. package/dist/components/{p-BueaqfA2.js → p-Dw0Obsn5.js} +1 -1
  125. package/dist/components/{p-DxzDda_J.js → p-Gm5hSQ-e.js} +1 -1
  126. package/dist/components/{p-C4fKLlrd.js → p-HK-6khHo.js} +1 -1
  127. package/dist/components/{p-_QEHfsIk.js → p-V3VW2JKl.js} +1 -1
  128. package/dist/components/{p-Lhyh6KeB.js → p-VxgCvVox.js} +1 -1
  129. package/dist/components/{p-l_YGO7RB.js → p-cjeDomsc.js} +1 -1
  130. package/dist/components/{p-gtQlsorg.js → p-rNu5JVNH.js} +1 -1
  131. package/dist/components/p-xYCbKFih.js +1 -0
  132. package/dist/esm/{index-BbOHefEf.js → index-D9HaikfQ.js} +36 -9
  133. package/dist/esm/index.js +1 -1
  134. package/dist/esm/kritzel-active-users_42.entry.js +333 -177
  135. package/dist/esm/kritzel-brush-style.entry.js +1 -1
  136. package/dist/esm/loader.js +3 -3
  137. package/dist/esm/stencil.js +4 -4
  138. package/dist/esm/{workspace.migrations-NhRgr2_H.js → workspace.migrations-OzSSw5kt.js} +244 -197
  139. package/dist/stencil/index.esm.js +1 -1
  140. package/dist/stencil/p-D9HaikfQ.js +2 -0
  141. package/dist/stencil/p-OzSSw5kt.js +1 -0
  142. package/dist/stencil/{p-98238bf9.entry.js → p-b0be4da1.entry.js} +1 -1
  143. package/dist/stencil/p-f7be06a8.entry.js +9 -0
  144. package/dist/stencil/stencil.esm.js +1 -1
  145. package/dist/types/classes/core/store.class.d.ts +23 -0
  146. package/dist/types/classes/objects/shape.class.d.ts +1 -0
  147. package/dist/types/classes/objects/text.class.d.ts +1 -0
  148. package/dist/types/classes/providers/hocuspocus-sync-provider.class.d.ts +1 -1
  149. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +7 -5
  150. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +10 -4
  151. package/dist/types/components.d.ts +35 -13
  152. package/dist/types/constants/version.d.ts +1 -1
  153. package/dist/types/helpers/tool-config.helper.d.ts +1 -1
  154. package/dist/types/interfaces/engine-state.interface.d.ts +10 -10
  155. package/package.json +1 -1
  156. package/dist/components/p-Ban3OlgZ.js +0 -9
  157. package/dist/components/p-CGGiwvWZ.js +0 -1
  158. package/dist/components/p-CHY71o5B.js +0 -1
  159. package/dist/components/p-DXpYcAnT.js +0 -1
  160. package/dist/components/p-pGzF7PUB.js +0 -1
  161. package/dist/stencil/p-4a4b38e4.entry.js +0 -9
  162. package/dist/stencil/p-BbOHefEf.js +0 -2
  163. package/dist/stencil/p-NhRgr2_H.js +0 -1
@@ -424,7 +424,7 @@ class KritzelBaseObject {
424
424
  const object = new KritzelBaseObject();
425
425
  object._core = core;
426
426
  object.zIndex = core.store.currentZIndex;
427
- object.workspaceId = core.store.state.activeWorkspace.id;
427
+ object.workspaceId = core.store.activeWorkspace.id;
428
428
  object.userId = core.user?.id;
429
429
  return object;
430
430
  }
@@ -491,7 +491,7 @@ class KritzelBaseObject {
491
491
  * Triggers a re-render of the object in the canvas.
492
492
  */
493
493
  update() {
494
- this._core.store.state.objects.update(this);
494
+ this._core.store.objects.update(this);
495
495
  }
496
496
  /**
497
497
  * Moves the object based on the delta between start and end coordinates.
@@ -506,7 +506,7 @@ class KritzelBaseObject {
506
506
  const deltaY = (startY - endY) / this._core.store.state.scale;
507
507
  this.translateX += deltaX;
508
508
  this.translateY += deltaY;
509
- this._core.store.state.objects.update(this);
509
+ this._core.store.objects.update(this);
510
510
  }
511
511
  /**
512
512
  * Resizes the object to new dimensions and position.
@@ -525,7 +525,7 @@ class KritzelBaseObject {
525
525
  this.height = height;
526
526
  this.translateX = x;
527
527
  this.translateY = y;
528
- this._core.store.state.objects.update(this);
528
+ this._core.store.objects.update(this);
529
529
  // Update any lines that are anchored to this object (after position is updated)
530
530
  this._core.anchorManager.updateAnchorsForObject(this.id);
531
531
  }
@@ -535,7 +535,7 @@ class KritzelBaseObject {
535
535
  */
536
536
  rotate(value) {
537
537
  this.rotation = value;
538
- this._core.store.state.objects.update(this);
538
+ this._core.store.objects.update(this);
539
539
  }
540
540
  /**
541
541
  * Creates a shallow clone of this object with the same ID.
@@ -640,7 +640,7 @@ class KritzelBaseObject {
640
640
  updatePosition(x, y) {
641
641
  this.translateX = x;
642
642
  this.translateY = y;
643
- this._core.store.state.objects.update(this);
643
+ this._core.store.objects.update(this);
644
644
  }
645
645
  }
646
646
 
@@ -683,23 +683,27 @@ class KritzelKeyboardHelper {
683
683
  const meta = document.querySelector('meta[name="viewport"][content*="interactive-widget=resizes-content"]');
684
684
  if (meta) {
685
685
  let currentContent = meta.getAttribute('content');
686
- if (!currentContent.includes('interactive-widget=resizes-content')) {
686
+ if (!currentContent?.includes('interactive-widget=resizes-content')) {
687
687
  currentContent += ', interactive-widget=resizes-content';
688
688
  }
689
- meta.setAttribute('content', currentContent);
689
+ if (currentContent) {
690
+ meta.setAttribute('content', currentContent);
691
+ }
690
692
  }
691
693
  }
692
694
  static disableInteractiveWidget() {
693
695
  const meta = document.querySelector('meta[name="viewport"][content*="interactive-widget=resizes-content"]');
694
696
  if (meta) {
695
697
  let currentContent = meta.getAttribute('content');
696
- let newContent = currentContent.replace(/\s*interactive-widget=resizes-content\s*[,;]?/g, '');
697
- newContent = newContent
698
- .replace(/,(\s*,)+/g, ',')
699
- .replace(/^,/, '')
700
- .replace(/,$/, '')
701
- .trim();
702
- meta.setAttribute('content', newContent);
698
+ let newContent = currentContent?.replace(/\s*interactive-widget=resizes-content\s*[,;]?/g, '');
699
+ if (newContent !== undefined) {
700
+ newContent = newContent
701
+ .replace(/,(\s*,)+/g, ',')
702
+ .replace(/^,/, '')
703
+ .replace(/,$/, '')
704
+ .trim();
705
+ meta.setAttribute('content', newContent);
706
+ }
703
707
  }
704
708
  }
705
709
  static onKeyboardVisibleChanged(callback) {
@@ -712,8 +716,8 @@ class KritzelKeyboardHelper {
712
716
  const isOpen = isMobileDevice && isViewportReduced;
713
717
  callback(isOpen);
714
718
  };
715
- window.visualViewport.addEventListener('resize', onResize);
716
- return () => window.visualViewport.removeEventListener('resize', onResize);
719
+ window.visualViewport?.addEventListener('resize', onResize);
720
+ return () => window.visualViewport?.removeEventListener('resize', onResize);
717
721
  }
718
722
  else {
719
723
  // Fallback for older browsers does not provide a reliable event-based mechanism.
@@ -15224,6 +15228,12 @@ class KritzelText extends KritzelBaseObject {
15224
15228
  isEditing = false;
15225
15229
  editor = null;
15226
15230
  content = null;
15231
+ get _editor() {
15232
+ if (!this._editor) {
15233
+ throw new Error('KritzelShape: editor is not initialized');
15234
+ }
15235
+ return this._editor;
15236
+ }
15227
15237
  _schema = new Schema({
15228
15238
  nodes: addListNodes(schema.spec.nodes, 'paragraph block*', 'block'),
15229
15239
  marks: schema.spec.marks,
@@ -15235,10 +15245,10 @@ class KritzelText extends KritzelBaseObject {
15235
15245
  * @returns `true` if the editor is empty or contains only whitespace, `false` otherwise.
15236
15246
  */
15237
15247
  get isEmpty() {
15238
- if (!this.editor) {
15248
+ if (!this._editor) {
15239
15249
  return true;
15240
15250
  }
15241
- const doc = this.editor.state.doc;
15251
+ const doc = this._editor.state.doc;
15242
15252
  if (doc.content.size === 0) {
15243
15253
  return true;
15244
15254
  }
@@ -15311,10 +15321,10 @@ class KritzelText extends KritzelBaseObject {
15311
15321
  const object = new KritzelText();
15312
15322
  object._core = core;
15313
15323
  object.id = object.generateId();
15314
- object.workspaceId = core.store.state.activeWorkspace.id;
15324
+ object.workspaceId = core.store.activeWorkspace.id;
15315
15325
  object.userId = core.user?.id;
15316
- object.fontSize = fontSize;
15317
- object.fontFamily = fontFamily;
15326
+ object.fontSize = fontSize || 8;
15327
+ object.fontFamily = fontFamily || 'Arial';
15318
15328
  object.translateX = 0;
15319
15329
  object.translateY = 0;
15320
15330
  const coreScale = core.store.state.scale;
@@ -15342,7 +15352,7 @@ class KritzelText extends KritzelBaseObject {
15342
15352
  element.style.fontFamily = this.fontFamily;
15343
15353
  element.style.fontSize = `${this.fontSize}pt`;
15344
15354
  element.style.color = KritzelColorHelper.resolveThemeColor(this.fontColor);
15345
- if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
15355
+ if (this.isMounted && this.elementRef === element && this._editor.dom.parentElement === element) {
15346
15356
  if (!this._core.store.state.isScaling && !this._core.store.state.isPanning) {
15347
15357
  requestAnimationFrame(() => this.adjustSizeOnInput());
15348
15358
  }
@@ -15352,7 +15362,7 @@ class KritzelText extends KritzelBaseObject {
15352
15362
  this.elementRef.style.whiteSpace = 'pre-wrap';
15353
15363
  this.elementRef.style.wordWrap = 'break-word';
15354
15364
  this.elementRef.innerHTML = '';
15355
- this.elementRef.appendChild(this.editor.dom);
15365
+ this.elementRef.appendChild(this._editor.dom);
15356
15366
  this.isMounted = true;
15357
15367
  requestAnimationFrame(() => this.adjustSizeOnInput());
15358
15368
  }
@@ -15370,13 +15380,13 @@ class KritzelText extends KritzelBaseObject {
15370
15380
  }),
15371
15381
  editable: () => false,
15372
15382
  dispatchTransaction: transaction => {
15373
- const newState = this.editor.state.apply(transaction);
15374
- this.editor.updateState(newState);
15383
+ const newState = this._editor.state.apply(transaction);
15384
+ this._editor.updateState(newState);
15375
15385
  if (transaction.docChanged) {
15376
15386
  this.content = newState.doc.toJSON();
15377
15387
  this.adjustSizeOnInput();
15378
15388
  if (!transaction.getMeta('fromRemote')) {
15379
- this._core.store.state.objects.update(this, { temporary: true });
15389
+ this._core.store.objects.update(this, { temporary: true });
15380
15390
  }
15381
15391
  }
15382
15392
  },
@@ -15389,11 +15399,11 @@ class KritzelText extends KritzelBaseObject {
15389
15399
  */
15390
15400
  setContent(content) {
15391
15401
  this.content = content;
15392
- if (this.editor && content) {
15393
- const newDoc = this.editor.state.schema.nodeFromJSON(content);
15394
- const tr = this.editor.state.tr.replaceWith(0, this.editor.state.doc.content.size, newDoc.content);
15402
+ if (this._editor && content) {
15403
+ const newDoc = this._editor.state.schema.nodeFromJSON(content);
15404
+ const tr = this._editor.state.tr.replaceWith(0, this._editor.state.doc.content.size, newDoc.content);
15395
15405
  tr.setMeta('fromRemote', true);
15396
- this.editor.dispatch(tr);
15406
+ this._editor.dispatch(tr);
15397
15407
  }
15398
15408
  }
15399
15409
  /**
@@ -15447,7 +15457,7 @@ class KritzelText extends KritzelBaseObject {
15447
15457
  this.height = originalHeight * this.scaleFactor;
15448
15458
  this.translateX = x;
15449
15459
  this.translateY = y;
15450
- this._core.store.state.objects.update(this);
15460
+ this._core.store.objects.update(this);
15451
15461
  }
15452
15462
  /**
15453
15463
  * Focuses the text editor and optionally positions the cursor at specific coordinates.
@@ -15458,13 +15468,13 @@ class KritzelText extends KritzelBaseObject {
15458
15468
  * @param coords.y - Y coordinate for cursor placement.
15459
15469
  */
15460
15470
  focus(coords) {
15461
- if (this.editor) {
15462
- const doc = this.editor.state.doc;
15471
+ if (this._editor) {
15472
+ const doc = this._editor.state.doc;
15463
15473
  if (coords.x && coords.y && !this.isEmpty) {
15464
- const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
15474
+ const pos = this._editor.posAtCoords({ left: coords.x, top: coords.y });
15465
15475
  if (pos) {
15466
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
15467
- this.editor.focus();
15476
+ this._editor.dispatch(this._editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
15477
+ this._editor.focus();
15468
15478
  if (KritzelDevicesHelper.isIOS()) {
15469
15479
  this.scrollIntoViewOnIOS();
15470
15480
  }
@@ -15472,8 +15482,8 @@ class KritzelText extends KritzelBaseObject {
15472
15482
  }
15473
15483
  }
15474
15484
  const end = Math.max(1, doc.content.size - 1);
15475
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, end)));
15476
- this.editor.focus();
15485
+ this._editor.dispatch(this._editor.state.tr.setSelection(TextSelection.create(doc, end)));
15486
+ this._editor.focus();
15477
15487
  if (KritzelDevicesHelper.isIOS()) {
15478
15488
  this.scrollIntoViewOnIOS();
15479
15489
  }
@@ -15485,11 +15495,11 @@ class KritzelText extends KritzelBaseObject {
15485
15495
  */
15486
15496
  scrollIntoViewOnIOS() {
15487
15497
  setTimeout(() => {
15488
- if (this.editor && this.editor.dom) {
15489
- this.editor.dom.scrollIntoView({
15498
+ if (this._editor && this._editor.dom) {
15499
+ this._editor.dom.scrollIntoView({
15490
15500
  behavior: 'smooth',
15491
15501
  block: 'center',
15492
- inline: 'nearest'
15502
+ inline: 'nearest',
15493
15503
  });
15494
15504
  }
15495
15505
  }, 300);
@@ -15504,11 +15514,13 @@ class KritzelText extends KritzelBaseObject {
15504
15514
  KritzelKeyboardHelper.disableInteractiveWidget();
15505
15515
  this.uneditedObject = this.clone();
15506
15516
  this._core.store.setState('activeTool', KritzelToolRegistry.getTool('text'));
15507
- this.editor.setProps({ editable: () => true });
15517
+ this._editor.setProps({ editable: () => true });
15508
15518
  this.isEditing = true;
15509
15519
  this._core.rerender();
15510
15520
  this.adjustSizeOnInput();
15511
- this.focus({ x: event?.clientX, y: event?.clientY });
15521
+ if (event?.clientX && event?.clientY) {
15522
+ this.focus({ x: event?.clientX, y: event?.clientY });
15523
+ }
15512
15524
  KritzelKeyboardHelper.enableInteractiveWidget();
15513
15525
  }
15514
15526
  /**
@@ -15518,12 +15530,12 @@ class KritzelText extends KritzelBaseObject {
15518
15530
  */
15519
15531
  save() {
15520
15532
  requestAnimationFrame(() => this.adjustSizeOnInput());
15521
- this.content = this.editor.state.doc.toJSON();
15522
- this.editor.setProps({ editable: () => false });
15523
- this.editor.dom.blur();
15533
+ this.content = this._editor.state.doc.toJSON();
15534
+ this._editor.setProps({ editable: () => false });
15535
+ this._editor.dom.blur();
15524
15536
  this.isEditing = false;
15525
- this._core.store.state.objects.consolidateTemporaryItems();
15526
- this._core.store.state.objects.update(this);
15537
+ this._core.store.objects.consolidateTemporaryItems();
15538
+ this._core.store.objects.update(this);
15527
15539
  this._core.engine.emitObjectsChange();
15528
15540
  }
15529
15541
  /**
@@ -15701,7 +15713,7 @@ class KritzelPath extends KritzelBaseObject {
15701
15713
  const object = new KritzelPath();
15702
15714
  object._core = core;
15703
15715
  object.id = object.generateId();
15704
- object.workspaceId = core.store.state.activeWorkspace.id;
15716
+ object.workspaceId = core.store.activeWorkspace.id;
15705
15717
  object.userId = core.user?.id;
15706
15718
  object.options = options;
15707
15719
  object.points = options?.points ?? [];
@@ -15759,7 +15771,7 @@ class KritzelPath extends KritzelBaseObject {
15759
15771
  this.translateX = x;
15760
15772
  this.translateY = y;
15761
15773
  this._adjustedPoints = null;
15762
- this._core.store.state.objects.update(this);
15774
+ this._core.store.objects.update(this);
15763
15775
  }
15764
15776
  /**
15765
15777
  * Rotates the path by the specified angle.
@@ -15769,7 +15781,7 @@ class KritzelPath extends KritzelBaseObject {
15769
15781
  rotate(value) {
15770
15782
  this.rotation = value;
15771
15783
  this._adjustedPoints = null;
15772
- this._core.store.state.objects.update(this);
15784
+ this._core.store.objects.update(this);
15773
15785
  }
15774
15786
  /**
15775
15787
  * Moves the path by calculating the delta between start and end positions.
@@ -15785,7 +15797,7 @@ class KritzelPath extends KritzelBaseObject {
15785
15797
  this.translateX += deltaX;
15786
15798
  this.translateY += deltaY;
15787
15799
  this._adjustedPoints = null;
15788
- this._core.store.state.objects.update(this);
15800
+ this._core.store.objects.update(this);
15789
15801
  }
15790
15802
  /**
15791
15803
  * Tests whether a point intersects with the path's stroke.
@@ -15880,7 +15892,7 @@ class KritzelPath extends KritzelBaseObject {
15880
15892
  this.translateX = x;
15881
15893
  this.translateY = y;
15882
15894
  this._adjustedPoints = null;
15883
- this._core.store.state.objects.update(this);
15895
+ this._core.store.objects.update(this);
15884
15896
  }
15885
15897
  /**
15886
15898
  * Lifecycle hook called after properties have been updated.
@@ -16203,7 +16215,7 @@ class KritzelImage extends KritzelBaseObject {
16203
16215
  const object = new KritzelImage();
16204
16216
  object._core = core;
16205
16217
  object.id = object.generateId();
16206
- object.workspaceId = core.store.state.activeWorkspace.id;
16218
+ object.workspaceId = core.store.activeWorkspace.id;
16207
16219
  object.userId = core.user?.id;
16208
16220
  object.x = 0;
16209
16221
  object.y = 0;
@@ -16232,7 +16244,7 @@ class KritzelImage extends KritzelBaseObject {
16232
16244
  this.translateX = x;
16233
16245
  this.translateY = y;
16234
16246
  // Update to sync changes to y.js and propagate to other tabs
16235
- this._core.store.state.objects.update(this);
16247
+ this._core.store.objects.update(this);
16236
16248
  }
16237
16249
  /**
16238
16250
  * Creates a KritzelImage from a URL, handling image loading and dimension calculation.
@@ -16354,7 +16366,7 @@ class KritzelLine extends KritzelBaseObject {
16354
16366
  const object = new KritzelLine();
16355
16367
  object._core = core;
16356
16368
  object.id = object.generateId();
16357
- object.workspaceId = core.store.state.activeWorkspace.id;
16369
+ object.workspaceId = core.store.activeWorkspace.id;
16358
16370
  object.userId = core.user?.id;
16359
16371
  object.options = options;
16360
16372
  object.startX = options?.startX ?? 0;
@@ -16410,7 +16422,7 @@ class KritzelLine extends KritzelBaseObject {
16410
16422
  this.translateY = y;
16411
16423
  this._adjustedPoints = null;
16412
16424
  this._clipInfo = null;
16413
- this._core.store.state.objects.update(this);
16425
+ this._core.store.objects.update(this);
16414
16426
  // Update anchors after the line is updated
16415
16427
  this._core.anchorManager.updateAnchorsForObject(this.id);
16416
16428
  if (this.startAnchor) {
@@ -16429,7 +16441,7 @@ class KritzelLine extends KritzelBaseObject {
16429
16441
  this.rotation = value;
16430
16442
  this._adjustedPoints = null;
16431
16443
  this._clipInfo = null;
16432
- this._core.store.state.objects.update(this);
16444
+ this._core.store.objects.update(this);
16433
16445
  }
16434
16446
  /**
16435
16447
  * Moves the line by calculating the delta between start and end positions.
@@ -16453,7 +16465,7 @@ class KritzelLine extends KritzelBaseObject {
16453
16465
  }
16454
16466
  this._adjustedPoints = null;
16455
16467
  this._clipInfo = null;
16456
- this._core.store.state.objects.update(this);
16468
+ this._core.store.objects.update(this);
16457
16469
  }
16458
16470
  /**
16459
16471
  * Tests if a point intersects with the line within the stroke tolerance.
@@ -16580,7 +16592,7 @@ class KritzelLine extends KritzelBaseObject {
16580
16592
  this.translateY = y;
16581
16593
  this._adjustedPoints = null;
16582
16594
  this._clipInfo = null;
16583
- this._core.store.state.objects.update(this);
16595
+ this._core.store.objects.update(this);
16584
16596
  }
16585
16597
  /**
16586
16598
  * Updates a specific endpoint of the line (start or end).
@@ -16638,7 +16650,7 @@ class KritzelLine extends KritzelBaseObject {
16638
16650
  // Clear cached adjusted points
16639
16651
  this._adjustedPoints = null;
16640
16652
  this._clipInfo = null;
16641
- this._core.store.state.objects.update(this);
16653
+ this._core.store.objects.update(this);
16642
16654
  }
16643
16655
  /**
16644
16656
  * Updates the control point for a quadratic Bezier curve.
@@ -16688,7 +16700,7 @@ class KritzelLine extends KritzelBaseObject {
16688
16700
  // Clear cached adjusted points
16689
16701
  this._adjustedPoints = null;
16690
16702
  this._clipInfo = null;
16691
- this._core.store.state.objects.update(this);
16703
+ this._core.store.objects.update(this);
16692
16704
  }
16693
16705
  /**
16694
16706
  * Computes the line endpoints in world coordinates, accounting for rotation,
@@ -17092,7 +17104,7 @@ class KritzelGroup extends KritzelBaseObject {
17092
17104
  }
17093
17105
  return this.childIds
17094
17106
  .map(id => {
17095
- const found = this._core.store.state.objects.filter(obj => obj.id === id);
17107
+ const found = this._core.store.objects.filter(obj => obj.id === id);
17096
17108
  return found.length > 0 ? found[0] : null;
17097
17109
  })
17098
17110
  .filter((obj) => obj !== null);
@@ -17114,7 +17126,7 @@ class KritzelGroup extends KritzelBaseObject {
17114
17126
  const group = new KritzelGroup();
17115
17127
  group._core = core;
17116
17128
  group.id = group.generateId();
17117
- group.workspaceId = core.store.state.activeWorkspace.id;
17129
+ group.workspaceId = core.store.activeWorkspace.id;
17118
17130
  group.userId = core.user?.id;
17119
17131
  group.scale = core.store.state.scale;
17120
17132
  group.zIndex = core.store.currentZIndex;
@@ -17147,7 +17159,7 @@ class KritzelGroup extends KritzelBaseObject {
17147
17159
  * @returns The parent KritzelGroup if found, or null if the object is not a child of any group.
17148
17160
  */
17149
17161
  static findParentGroup(core, objectId) {
17150
- const allGroups = core.store.state.objects
17162
+ const allGroups = core.store.objects
17151
17163
  .filter(obj => obj.__class__ === 'KritzelGroup');
17152
17164
  for (const group of allGroups) {
17153
17165
  if (group.childIds.includes(objectId)) {
@@ -17333,8 +17345,8 @@ class KritzelGroup extends KritzelBaseObject {
17333
17345
  const deltaY = (startY - endY) / this._core.store.state.scale;
17334
17346
  this.translateX += deltaX;
17335
17347
  this.translateY += deltaY;
17336
- this._core.store.state.objects.transaction(() => {
17337
- this._core.store.state.objects.update(this);
17348
+ this._core.store.objects.transaction(() => {
17349
+ this._core.store.objects.update(this);
17338
17350
  this.children.forEach(child => {
17339
17351
  child.move(startX, startY, endX, endY);
17340
17352
  // Update any lines anchored to this child
@@ -17372,7 +17384,7 @@ class KritzelGroup extends KritzelBaseObject {
17372
17384
  const sin = Math.sin(-rotation);
17373
17385
  const cosR = Math.cos(rotation);
17374
17386
  const sinR = Math.sin(rotation);
17375
- this._core.store.state.objects.transaction(() => {
17387
+ this._core.store.objects.transaction(() => {
17376
17388
  this.children.forEach(child => {
17377
17389
  // Calculate child center
17378
17390
  const childCenterX = child.translateX + child.totalWidth / 2 / child.scale;
@@ -17410,7 +17422,7 @@ class KritzelGroup extends KritzelBaseObject {
17410
17422
  });
17411
17423
  this.refreshBoundingBox();
17412
17424
  this.captureChildSnapshots();
17413
- this._core.store.state.objects.update(this);
17425
+ this._core.store.objects.update(this);
17414
17426
  });
17415
17427
  }
17416
17428
  /**
@@ -17426,8 +17438,8 @@ class KritzelGroup extends KritzelBaseObject {
17426
17438
  const angle = value - this.snapshotRotation;
17427
17439
  const cos = Math.cos(angle);
17428
17440
  const sin = Math.sin(angle);
17429
- this._core.store.state.objects.transaction(() => {
17430
- this._core.store.state.objects.update(this);
17441
+ this._core.store.objects.transaction(() => {
17442
+ this._core.store.objects.update(this);
17431
17443
  this.children.forEach(child => {
17432
17444
  const unchangedSnapshot = this.unchangedChildSnapshots.get(child.id);
17433
17445
  if (!unchangedSnapshot)
@@ -17553,7 +17565,7 @@ class KritzelGroup extends KritzelBaseObject {
17553
17565
  * Triggers synchronization with y.js for collaborative editing.
17554
17566
  */
17555
17567
  update() {
17556
- this._core.store.state.objects.update(this);
17568
+ this._core.store.objects.update(this);
17557
17569
  }
17558
17570
  /**
17559
17571
  * Updates the workspace ID for this group and all its children recursively.
@@ -17611,6 +17623,12 @@ class KritzelShape extends KritzelBaseObject {
17611
17623
  get viewBox() {
17612
17624
  return `${this.x} ${this.y} ${this.width} ${this.height}`;
17613
17625
  }
17626
+ get _editor() {
17627
+ if (!this.editor) {
17628
+ throw new Error('KritzelShape: editor is not initialized');
17629
+ }
17630
+ return this.editor;
17631
+ }
17614
17632
  /**
17615
17633
  * Creates a new KritzelShape instance with optional configuration.
17616
17634
  * This constructor initializes the shape with default values that can be
@@ -17666,7 +17684,7 @@ class KritzelShape extends KritzelBaseObject {
17666
17684
  const object = new KritzelShape();
17667
17685
  object._core = core;
17668
17686
  object.id = object.generateId();
17669
- object.workspaceId = core.store.state.activeWorkspace.id;
17687
+ object.workspaceId = core.store.activeWorkspace.id;
17670
17688
  object.userId = core.user?.id;
17671
17689
  object.x = config?.x ?? 0;
17672
17690
  object.y = config?.y ?? 0;
@@ -17718,7 +17736,7 @@ class KritzelShape extends KritzelBaseObject {
17718
17736
  if (element === null || this.isInViewport() === false) {
17719
17737
  return;
17720
17738
  }
17721
- if (this.isMounted && this.elementRef === element && this.editor.dom.parentElement === element) {
17739
+ if (this.isMounted && this.elementRef === element && this._editor.dom.parentElement === element) {
17722
17740
  return;
17723
17741
  }
17724
17742
  this.elementRef = element;
@@ -17734,7 +17752,7 @@ class KritzelShape extends KritzelBaseObject {
17734
17752
  * @returns void
17735
17753
  */
17736
17754
  mountTextEditor(element) {
17737
- if (element === null) {
17755
+ if (element === null || !this.editor) {
17738
17756
  return;
17739
17757
  }
17740
17758
  element.style.fontFamily = this.fontFamily;
@@ -17765,12 +17783,12 @@ class KritzelShape extends KritzelBaseObject {
17765
17783
  }),
17766
17784
  editable: () => false,
17767
17785
  dispatchTransaction: transaction => {
17768
- const newState = this.editor.state.apply(transaction);
17769
- this.editor.updateState(newState);
17786
+ const newState = this._editor.state.apply(transaction);
17787
+ this._editor.updateState(newState);
17770
17788
  if (transaction.docChanged) {
17771
17789
  this.content = newState.doc.toJSON();
17772
17790
  if (!transaction.getMeta('fromRemote')) {
17773
- this._core.store.state.objects.update(this, { temporary: true });
17791
+ this._core.store.objects.update(this, { temporary: true });
17774
17792
  }
17775
17793
  }
17776
17794
  },
@@ -17814,7 +17832,7 @@ class KritzelShape extends KritzelBaseObject {
17814
17832
  this.height = height;
17815
17833
  this.translateX = x;
17816
17834
  this.translateY = y;
17817
- this._core.store.state.objects.update(this);
17835
+ this._core.store.objects.update(this);
17818
17836
  }
17819
17837
  /**
17820
17838
  * Focuses the text editor and optionally positions the cursor at specific coordinates.
@@ -17828,25 +17846,23 @@ class KritzelShape extends KritzelBaseObject {
17828
17846
  * @returns void
17829
17847
  */
17830
17848
  focus(coords) {
17831
- if (this.editor) {
17832
- const doc = this.editor.state.doc;
17833
- if (coords?.x && coords?.y) {
17834
- const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
17835
- if (pos) {
17836
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
17837
- this.editor.focus();
17838
- if (KritzelDevicesHelper.isIOS()) {
17839
- this.scrollIntoViewOnIOS();
17840
- }
17841
- return;
17849
+ const doc = this._editor.state.doc;
17850
+ if (coords?.x && coords?.y) {
17851
+ const pos = this._editor.posAtCoords({ left: coords.x, top: coords.y });
17852
+ if (pos) {
17853
+ this._editor.dispatch(this._editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
17854
+ this._editor.focus();
17855
+ if (KritzelDevicesHelper.isIOS()) {
17856
+ this.scrollIntoViewOnIOS();
17842
17857
  }
17858
+ return;
17843
17859
  }
17844
- const end = Math.max(1, doc.content.size - 1);
17845
- this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, end)));
17846
- this.editor.focus();
17847
- if (KritzelDevicesHelper.isIOS()) {
17848
- this.scrollIntoViewOnIOS();
17849
- }
17860
+ }
17861
+ const end = Math.max(1, doc.content.size - 1);
17862
+ this._editor.dispatch(this._editor.state.tr.setSelection(TextSelection.create(doc, end)));
17863
+ this._editor.focus();
17864
+ if (KritzelDevicesHelper.isIOS()) {
17865
+ this.scrollIntoViewOnIOS();
17850
17866
  }
17851
17867
  }
17852
17868
  /**
@@ -17882,10 +17898,12 @@ class KritzelShape extends KritzelBaseObject {
17882
17898
  KritzelKeyboardHelper.disableInteractiveWidget();
17883
17899
  this.uneditedObject = this.clone();
17884
17900
  this._core.store.setState('activeTool', KritzelToolRegistry.getTool('shape'));
17885
- this.editor.setProps({ editable: () => true });
17901
+ this._editor.setProps({ editable: () => true });
17886
17902
  this.isEditing = true;
17887
17903
  this._core.rerender();
17888
- this.focus({ x: event?.clientX, y: event?.clientY });
17904
+ if (event?.clientX && event?.clientY) {
17905
+ this.focus({ x: event.clientX, y: event.clientY });
17906
+ }
17889
17907
  KritzelKeyboardHelper.enableInteractiveWidget();
17890
17908
  }
17891
17909
  /**
@@ -17897,12 +17915,12 @@ class KritzelShape extends KritzelBaseObject {
17897
17915
  * @returns void
17898
17916
  */
17899
17917
  save() {
17900
- this.content = this.editor.state.doc.toJSON();
17901
- this.editor.setProps({ editable: () => false });
17902
- this.editor.dom.blur();
17918
+ this.content = this._editor.state.doc.toJSON();
17919
+ this._editor.setProps({ editable: () => false });
17920
+ this._editor.dom.blur();
17903
17921
  this.isEditing = false;
17904
- this._core.store.state.objects.consolidateTemporaryItems();
17905
- this._core.store.state.objects.update(this);
17922
+ this._core.store.objects.consolidateTemporaryItems();
17923
+ this._core.store.objects.update(this);
17906
17924
  this._core.engine.emitObjectsChange();
17907
17925
  }
17908
17926
  /**
@@ -18347,8 +18365,8 @@ class KritzelBrushTool extends KritzelBaseTool {
18347
18365
  });
18348
18366
  path.isCompleted = false;
18349
18367
  this._currentPathId = path.id;
18350
- this._core.store.state.objects.insert(path);
18351
- this._core.store.state.objects?.setActiveDrawingObject(path.id);
18368
+ this._core.store.objects.insert(path);
18369
+ this._core.store.objects?.setActiveDrawingObject(path.id);
18352
18370
  }
18353
18371
  }
18354
18372
  if (event.pointerType === 'touch' || event.pointerType === 'pen') {
@@ -18371,8 +18389,8 @@ class KritzelBrushTool extends KritzelBaseTool {
18371
18389
  });
18372
18390
  path.isCompleted = false;
18373
18391
  this._currentPathId = path.id;
18374
- this._core.store.state.objects.insert(path);
18375
- this._core.store.state.objects?.setActiveDrawingObject(path.id);
18392
+ this._core.store.objects.insert(path);
18393
+ this._core.store.objects?.setActiveDrawingObject(path.id);
18376
18394
  }
18377
18395
  }
18378
18396
  }
@@ -18388,7 +18406,7 @@ class KritzelBrushTool extends KritzelBaseTool {
18388
18406
  }
18389
18407
  if (event.pointerType === 'mouse') {
18390
18408
  if (this._core.store.state.isDrawing && this._currentPathId) {
18391
- const currentPath = this._core.store.state.objects.findById(this._currentPathId);
18409
+ const currentPath = this._core.store.objects.findById(this._currentPathId);
18392
18410
  if (currentPath) {
18393
18411
  const viewportScale = this._core.store.state.scale;
18394
18412
  const lockScale = this._core.store.state.lockDrawingScale;
@@ -18408,7 +18426,7 @@ class KritzelBrushTool extends KritzelBaseTool {
18408
18426
  updatedPath.workspaceId = currentPath.workspaceId;
18409
18427
  updatedPath.zIndex = currentPath.zIndex;
18410
18428
  updatedPath.isCompleted = false;
18411
- this._core.store.state.objects.update(updatedPath);
18429
+ this._core.store.objects.update(updatedPath);
18412
18430
  }
18413
18431
  }
18414
18432
  }
@@ -18416,7 +18434,7 @@ class KritzelBrushTool extends KritzelBaseTool {
18416
18434
  const activePointers = Array.from(this._core.store.state.pointers.values());
18417
18435
  if (activePointers.length === 1) {
18418
18436
  if (this._currentPathId) {
18419
- const currentPath = this._core.store.state.objects.findById(this._currentPathId);
18437
+ const currentPath = this._core.store.objects.findById(this._currentPathId);
18420
18438
  if (currentPath) {
18421
18439
  const viewportScale = this._core.store.state.scale;
18422
18440
  const lockScale = this._core.store.state.lockDrawingScale;
@@ -18436,7 +18454,7 @@ class KritzelBrushTool extends KritzelBaseTool {
18436
18454
  updatedPath.workspaceId = currentPath.workspaceId;
18437
18455
  updatedPath.zIndex = currentPath.zIndex;
18438
18456
  updatedPath.isCompleted = false;
18439
- this._core.store.state.objects.update(updatedPath);
18457
+ this._core.store.objects.update(updatedPath);
18440
18458
  }
18441
18459
  }
18442
18460
  }
@@ -18456,14 +18474,14 @@ class KritzelBrushTool extends KritzelBaseTool {
18456
18474
  if (this._core.store.state.isDrawing) {
18457
18475
  this._core.store.state.isDrawing = false;
18458
18476
  if (this._currentPathId) {
18459
- const currentPath = this._core.store.state.objects.findById(this._currentPathId);
18477
+ const currentPath = this._core.store.objects.findById(this._currentPathId);
18460
18478
  if (currentPath) {
18461
18479
  currentPath.isCompleted = true;
18462
- this._core.store.state.objects.update(currentPath);
18480
+ this._core.store.objects.update(currentPath);
18463
18481
  this._core.engine.emitObjectsChange();
18464
18482
  this._core.engine.emitObjectsAdded([currentPath]);
18465
18483
  }
18466
- this._core.store.state.objects?.setActiveDrawingObject(null);
18484
+ this._core.store.objects?.setActiveDrawingObject(null);
18467
18485
  this._currentPathId = null;
18468
18486
  }
18469
18487
  }
@@ -18472,14 +18490,14 @@ class KritzelBrushTool extends KritzelBaseTool {
18472
18490
  if (this._core.store.state.isDrawing) {
18473
18491
  this._core.store.state.isDrawing = false;
18474
18492
  if (this._currentPathId) {
18475
- const currentPath = this._core.store.state.objects.findById(this._currentPathId);
18493
+ const currentPath = this._core.store.objects.findById(this._currentPathId);
18476
18494
  if (currentPath) {
18477
18495
  currentPath.isCompleted = true;
18478
- this._core.store.state.objects.update(currentPath);
18496
+ this._core.store.objects.update(currentPath);
18479
18497
  this._core.engine.emitObjectsChange();
18480
18498
  this._core.engine.emitObjectsAdded([currentPath]);
18481
18499
  }
18482
- this._core.store.state.objects?.setActiveDrawingObject(null);
18500
+ this._core.store.objects?.setActiveDrawingObject(null);
18483
18501
  this._currentPathId = null;
18484
18502
  }
18485
18503
  }
@@ -18507,10 +18525,10 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18507
18525
  snapshotTranslateX = 0;
18508
18526
  snapshotTranslateY = 0;
18509
18527
  clientId;
18510
- minX;
18511
- maxX;
18512
- minY;
18513
- maxY;
18528
+ minX = 0;
18529
+ maxX = 0;
18530
+ minY = 0;
18531
+ maxY = 0;
18514
18532
  // Selection styling properties
18515
18533
  handleColor;
18516
18534
  handleStrokeColor;
@@ -18550,7 +18568,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18550
18568
  return this._cachedObjects;
18551
18569
  }
18552
18570
  const idSet = new Set(this._objectIds);
18553
- const foundObjects = this._core.store.state.objects.filter(obj => idSet.has(obj.id));
18571
+ const foundObjects = this._core.store.objects.filter(obj => idSet.has(obj.id));
18554
18572
  // Preserve the original order from objectIds
18555
18573
  const objectMap = new Map(foundObjects.map(obj => [obj.id, obj]));
18556
18574
  this._cachedObjects = this._objectIds
@@ -18577,9 +18595,9 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18577
18595
  const object = new KritzelSelectionGroup();
18578
18596
  object._core = core;
18579
18597
  object.id = object.generateId();
18580
- object.workspaceId = core.store.state.activeWorkspace.id;
18598
+ object.workspaceId = core.store.activeWorkspace.id;
18581
18599
  object.userId = core.user?.id;
18582
- object.clientId = core.store.state.objects?.localClientId ?? undefined;
18600
+ object.clientId = core.store.objects?.localClientId ?? undefined;
18583
18601
  object.scale = core.store.state.scale;
18584
18602
  object.zIndex = 99999;
18585
18603
  // Initialize styling with theme-aware defaults
@@ -18718,7 +18736,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18718
18736
  });
18719
18737
  this.translateX = x;
18720
18738
  this.translateY = y;
18721
- this._core.store.state.objects.update(this);
18739
+ this._core.store.objects.update(this);
18722
18740
  }
18723
18741
  /**
18724
18742
  * Capture snapshots of current object states for undo/redo operations
@@ -18795,7 +18813,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18795
18813
  // Only update the selection group itself
18796
18814
  // Child objects are already updated during move/resize/rotate operations
18797
18815
  // Updating them again here would create redundant y.js updates
18798
- this._core.store.state.objects.update(this);
18816
+ this._core.store.objects.update(this);
18799
18817
  }
18800
18818
  /**
18801
18819
  * Moves the selection group and all its contained objects by calculating the delta from drag coordinates.
@@ -18811,8 +18829,8 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18811
18829
  const deltaY = (startY - endY) / this._core.store.state.scale;
18812
18830
  this.translateX += deltaX;
18813
18831
  this.translateY += deltaY;
18814
- this._core.store.state.objects.transaction(() => {
18815
- this._core.store.state.objects.update(this);
18832
+ this._core.store.objects.transaction(() => {
18833
+ this._core.store.objects.update(this);
18816
18834
  const children = this.objects;
18817
18835
  for (const obj of children) {
18818
18836
  obj.move(startX, startY, endX, endY);
@@ -18855,7 +18873,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18855
18873
  const sin = Math.sin(-rotation);
18856
18874
  const cosR = Math.cos(rotation);
18857
18875
  const sinR = Math.sin(rotation);
18858
- this._core.store.state.objects.transaction(() => {
18876
+ this._core.store.objects.transaction(() => {
18859
18877
  // Cache objects once to avoid repeated getter calls during resize
18860
18878
  const children = this.objects;
18861
18879
  children.forEach(child => {
@@ -18907,7 +18925,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18907
18925
  // Note: Don't capture new snapshots here - we need to preserve the original snapshots
18908
18926
  // until the transform operation is complete to avoid compounding errors during drag
18909
18927
  this.refreshObjectDimensions(children);
18910
- this._core.store.state.objects.update(this);
18928
+ this._core.store.objects.update(this);
18911
18929
  });
18912
18930
  }
18913
18931
  /**
@@ -18925,9 +18943,9 @@ class KritzelSelectionGroup extends KritzelBaseObject {
18925
18943
  const sin = Math.sin(angle);
18926
18944
  // Cache objects once to avoid repeated getter calls during rotation
18927
18945
  const children = this.objects;
18928
- this._core.store.state.objects.transaction(() => {
18946
+ this._core.store.objects.transaction(() => {
18929
18947
  // Update the SelectionGroup itself to propagate rotation to other tabs
18930
- this._core.store.state.objects.update(this);
18948
+ this._core.store.objects.update(this);
18931
18949
  const childCount = children.length;
18932
18950
  for (const child of children) {
18933
18951
  const unchangedSnapshot = this.unchangedObjectSnapshots.get(child.id);
@@ -19024,7 +19042,7 @@ class KritzelSelectionGroup extends KritzelBaseObject {
19024
19042
  this.translateY = cy - (this.height / this.scale + 2 * this.padding) / 2;
19025
19043
  }
19026
19044
  if (!skipPersist) {
19027
- this._core.store.state.objects.update(this);
19045
+ this._core.store.objects.update(this);
19028
19046
  }
19029
19047
  }
19030
19048
  /**
@@ -19142,8 +19160,8 @@ class KritzelLineTool extends KritzelBaseTool {
19142
19160
  });
19143
19161
  line.isCompleted = false;
19144
19162
  this._currentLineId = line.id;
19145
- this._core.store.state.objects.insert(line);
19146
- this._core.store.state.objects?.setActiveDrawingObject(line.id);
19163
+ this._core.store.objects.insert(line);
19164
+ this._core.store.objects?.setActiveDrawingObject(line.id);
19147
19165
  }
19148
19166
  }
19149
19167
  if (event.pointerType === 'touch' || event.pointerType === 'pen') {
@@ -19172,8 +19190,8 @@ class KritzelLineTool extends KritzelBaseTool {
19172
19190
  });
19173
19191
  line.isCompleted = false;
19174
19192
  this._currentLineId = line.id;
19175
- this._core.store.state.objects.insert(line);
19176
- this._core.store.state.objects?.setActiveDrawingObject(line.id);
19193
+ this._core.store.objects.insert(line);
19194
+ this._core.store.objects?.setActiveDrawingObject(line.id);
19177
19195
  }
19178
19196
  }
19179
19197
  }
@@ -19189,7 +19207,7 @@ class KritzelLineTool extends KritzelBaseTool {
19189
19207
  }
19190
19208
  if (event.pointerType === 'mouse') {
19191
19209
  if (this._core.store.state.isDrawing && this._currentLineId) {
19192
- const currentLine = this._core.store.state.objects.findById(this._currentLineId);
19210
+ const currentLine = this._core.store.objects.findById(this._currentLineId);
19193
19211
  if (currentLine) {
19194
19212
  const viewportScale = this._core.store.state.scale;
19195
19213
  const lockScale = this._core.store.state.lockDrawingScale;
@@ -19213,14 +19231,14 @@ class KritzelLineTool extends KritzelBaseTool {
19213
19231
  updatedLine.workspaceId = currentLine.workspaceId;
19214
19232
  updatedLine.zIndex = currentLine.zIndex;
19215
19233
  updatedLine.isCompleted = false;
19216
- this._core.store.state.objects.update(updatedLine);
19234
+ this._core.store.objects.update(updatedLine);
19217
19235
  }
19218
19236
  }
19219
19237
  }
19220
19238
  if (event.pointerType === 'touch' || event.pointerType === 'pen') {
19221
19239
  const activePointers = Array.from(this._core.store.state.pointers.values());
19222
19240
  if (activePointers.length === 1 && this._currentLineId) {
19223
- const currentLine = this._core.store.state.objects.findById(this._currentLineId);
19241
+ const currentLine = this._core.store.objects.findById(this._currentLineId);
19224
19242
  if (currentLine) {
19225
19243
  const viewportScale = this._core.store.state.scale;
19226
19244
  const lockScale = this._core.store.state.lockDrawingScale;
@@ -19244,7 +19262,7 @@ class KritzelLineTool extends KritzelBaseTool {
19244
19262
  updatedLine.workspaceId = currentLine.workspaceId;
19245
19263
  updatedLine.zIndex = currentLine.zIndex;
19246
19264
  updatedLine.isCompleted = false;
19247
- this._core.store.state.objects.update(updatedLine);
19265
+ this._core.store.objects.update(updatedLine);
19248
19266
  }
19249
19267
  }
19250
19268
  }
@@ -19263,16 +19281,16 @@ class KritzelLineTool extends KritzelBaseTool {
19263
19281
  if (this._core.store.state.isDrawing) {
19264
19282
  this._core.store.state.isDrawing = false;
19265
19283
  if (this._currentLineId) {
19266
- const currentLine = this._core.store.state.objects.findById(this._currentLineId);
19284
+ const currentLine = this._core.store.objects.findById(this._currentLineId);
19267
19285
  if (currentLine) {
19268
19286
  currentLine.isCompleted = true;
19269
- this._core.store.state.objects.update(currentLine);
19287
+ this._core.store.objects.update(currentLine);
19270
19288
  this._core.engine.emitObjectsChange();
19271
19289
  this._core.engine.emitObjectsAdded([currentLine]);
19272
19290
  // Switch to selection tool and select the drawn line
19273
19291
  this.selectLineAndSwitchTool(currentLine);
19274
19292
  }
19275
- this._core.store.state.objects?.setActiveDrawingObject(null);
19293
+ this._core.store.objects?.setActiveDrawingObject(null);
19276
19294
  this._currentLineId = null;
19277
19295
  }
19278
19296
  }
@@ -19281,16 +19299,16 @@ class KritzelLineTool extends KritzelBaseTool {
19281
19299
  if (this._core.store.state.isDrawing) {
19282
19300
  this._core.store.state.isDrawing = false;
19283
19301
  if (this._currentLineId) {
19284
- const currentLine = this._core.store.state.objects.findById(this._currentLineId);
19302
+ const currentLine = this._core.store.objects.findById(this._currentLineId);
19285
19303
  if (currentLine) {
19286
19304
  currentLine.isCompleted = true;
19287
- this._core.store.state.objects.update(currentLine);
19305
+ this._core.store.objects.update(currentLine);
19288
19306
  this._core.engine.emitObjectsChange();
19289
19307
  this._core.engine.emitObjectsAdded([currentLine]);
19290
19308
  // Switch to selection tool and select the drawn line
19291
19309
  this.selectLineAndSwitchTool(currentLine);
19292
19310
  }
19293
- this._core.store.state.objects?.setActiveDrawingObject(null);
19311
+ this._core.store.objects?.setActiveDrawingObject(null);
19294
19312
  this._currentLineId = null;
19295
19313
  }
19296
19314
  }
@@ -19477,7 +19495,7 @@ class KritzelImageTool extends KritzelBaseTool {
19477
19495
  if (this._core.store.isDisabled) {
19478
19496
  return;
19479
19497
  }
19480
- this.fileInput.click();
19498
+ this.fileInput?.click();
19481
19499
  }
19482
19500
  /**
19483
19501
  * Creates and configures the hidden file input element.
@@ -19641,7 +19659,7 @@ class KritzelTextTool extends KritzelBaseTool {
19641
19659
  text.translateX = (clientX - this._core.store.state.translateX) / viewportScale;
19642
19660
  text.translateY = (clientY - this._core.store.state.translateY) / viewportScale;
19643
19661
  text.zIndex = this._core.store.currentZIndex;
19644
- this._core.store.state.objects.insert(text);
19662
+ this._core.store.objects.insert(text);
19645
19663
  this._core.rerender();
19646
19664
  text.edit(event);
19647
19665
  }
@@ -19678,7 +19696,7 @@ class KritzelTextTool extends KritzelBaseTool {
19678
19696
  text.translateX = (clientX - this._core.store.state.translateX) / viewportScale;
19679
19697
  text.translateY = (clientY - this._core.store.state.translateY) / viewportScale;
19680
19698
  text.zIndex = this._core.store.currentZIndex;
19681
- this._core.store.state.objects.insert(text);
19699
+ this._core.store.objects.insert(text);
19682
19700
  this._core.rerender();
19683
19701
  text.edit(event);
19684
19702
  }
@@ -19871,8 +19889,8 @@ class KritzelShapeTool extends KritzelBaseTool {
19871
19889
  fontFamily: this.fontFamily,
19872
19890
  scale: lockScale ? 1 : viewportScale,
19873
19891
  });
19874
- this._core.store.state.objects.insert(this.currentShape);
19875
- this._core.store.state.objects?.setActiveDrawingObject(this.currentShape.id);
19892
+ this._core.store.objects.insert(this.currentShape);
19893
+ this._core.store.objects?.setActiveDrawingObject(this.currentShape.id);
19876
19894
  this._core.rerender();
19877
19895
  }
19878
19896
  /**
@@ -19906,7 +19924,7 @@ class KritzelShapeTool extends KritzelBaseTool {
19906
19924
  this.currentShape.translateX = -this._core.store.state.translateX / divider;
19907
19925
  this.currentShape.translateY = -this._core.store.state.translateY / divider;
19908
19926
  this.currentShape.updateDimensions();
19909
- this._core.store.state.objects.update(this.currentShape);
19927
+ this._core.store.objects.update(this.currentShape);
19910
19928
  }
19911
19929
  /**
19912
19930
  * Completes the shape drawing process.
@@ -19922,18 +19940,18 @@ class KritzelShapeTool extends KritzelBaseTool {
19922
19940
  // Compare in screen space
19923
19941
  if (this.currentShape.width < 10 && this.currentShape.height < 10) {
19924
19942
  const shapeId = this.currentShape.id;
19925
- this._core.store.state.objects.remove(o => o.id === shapeId);
19943
+ this._core.store.objects.remove(o => o.id === shapeId);
19926
19944
  }
19927
19945
  else {
19928
19946
  this.currentShape.zIndex = this._core.store.currentZIndex;
19929
- this._core.store.state.objects.update(this.currentShape);
19947
+ this._core.store.objects.update(this.currentShape);
19930
19948
  this._core.engine.emitObjectsChange();
19931
19949
  this._core.engine.emitObjectsAdded([this.currentShape]);
19932
19950
  this._core.selectObjects([this.currentShape]);
19933
19951
  this._core.store.setState('activeTool', KritzelToolRegistry.getTool('selection'));
19934
19952
  }
19935
19953
  this.isDrawing = false;
19936
- this._core.store.state.objects?.setActiveDrawingObject(null);
19954
+ this._core.store.objects?.setActiveDrawingObject(null);
19937
19955
  this.currentShape = null;
19938
19956
  this._core.rerender();
19939
19957
  }
@@ -20140,17 +20158,17 @@ const ANCHOR_DISCONNECT_THRESHOLD = 30;
20140
20158
  */
20141
20159
  class KritzelMoveHandler extends KritzelBaseHandler {
20142
20160
  /** X coordinate where the drag started (updates during drag for incremental movement) */
20143
- dragStartX;
20161
+ dragStartX = 0;
20144
20162
  /** Y coordinate where the drag started (updates during drag for incremental movement) */
20145
- dragStartY;
20163
+ dragStartY = 0;
20146
20164
  /** Initial X coordinate when starting interaction (remains constant during drag) */
20147
- startX;
20165
+ startX = 0;
20148
20166
  /** Initial Y coordinate when starting interaction (remains constant during drag) */
20149
- startY;
20167
+ startY = 0;
20150
20168
  /** Current X coordinate during move operation */
20151
- endX;
20169
+ endX = 0;
20152
20170
  /** Current Y coordinate during move operation */
20153
- endY;
20171
+ endY = 0;
20154
20172
  /** Initial position when drag started (for calculating total accumulated distance) */
20155
20173
  initialDragX = 0;
20156
20174
  initialDragY = 0;
@@ -20308,7 +20326,10 @@ class KritzelMoveHandler extends KritzelBaseHandler {
20308
20326
  const moveDeltaY = Math.abs(y - this.startY);
20309
20327
  const moveThreshold = 5;
20310
20328
  if (this.hasMoved || moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) {
20311
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20329
+ const timeout = this._core.store.state.longTouchTimeout;
20330
+ if (timeout) {
20331
+ globalThis.clearTimeout?.(timeout);
20332
+ }
20312
20333
  // Check for anchor disconnect threshold on lines
20313
20334
  this.checkAndDisconnectAnchors(x, y);
20314
20335
  selectionGroup.move(x, y, this.dragStartX, this.dragStartY);
@@ -20407,7 +20428,7 @@ class KritzelMoveHandler extends KritzelBaseHandler {
20407
20428
  // Mark as disconnected so we don't try again
20408
20429
  this.disconnectedLineIds.add(line.id);
20409
20430
  // Update the line to persist the change
20410
- this._core.store.state.objects.update(line);
20431
+ this._core.store.objects.update(line);
20411
20432
  }
20412
20433
  }
20413
20434
  }
@@ -20504,7 +20525,10 @@ class KritzelResizeHandler extends KritzelBaseHandler {
20504
20525
  this.initialSize.height = selectionGroup.height;
20505
20526
  this.initialSize.x = selectionGroup.translateX;
20506
20527
  this.initialSize.y = selectionGroup.translateY;
20507
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20528
+ const timeout = this._core.store.state.longTouchTimeout;
20529
+ if (timeout) {
20530
+ globalThis.clearTimeout?.(timeout);
20531
+ }
20508
20532
  }
20509
20533
  }
20510
20534
  }
@@ -20599,7 +20623,10 @@ class KritzelResizeHandler extends KritzelBaseHandler {
20599
20623
  const resizeDeltaY = Math.abs(dy);
20600
20624
  const resizeThreshold = 5;
20601
20625
  if (resizeDeltaX > resizeThreshold || resizeDeltaY > resizeThreshold) {
20602
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20626
+ const timeout = this._core.store.state.longTouchTimeout;
20627
+ if (timeout) {
20628
+ globalThis.clearTimeout?.(timeout);
20629
+ }
20603
20630
  this.hasResized = true;
20604
20631
  }
20605
20632
  if (!this.hasResized) {
@@ -20708,7 +20735,10 @@ class KritzelResizeHandler extends KritzelBaseHandler {
20708
20735
  this._core.store.state.hasObjectsChanged = true;
20709
20736
  }
20710
20737
  this.reset();
20711
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20738
+ const timeout = this._core.store.state.longTouchTimeout;
20739
+ if (timeout) {
20740
+ globalThis.clearTimeout?.(timeout);
20741
+ }
20712
20742
  }
20713
20743
  }
20714
20744
  }
@@ -20786,7 +20816,10 @@ class KritzelRotationHandler extends KritzelBaseHandler {
20786
20816
  const cursorY = (clientY - this._core.store.state.translateY) / this._core.store.state.scale;
20787
20817
  this.initialSelectionGroupRotation = selectionGroup.rotation;
20788
20818
  this.initialRotation = Math.atan2(centerY - cursorY, centerX - cursorX) - selectionGroup.rotation;
20789
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20819
+ const timeout = this._core.store.state.longTouchTimeout;
20820
+ if (timeout) {
20821
+ globalThis.clearTimeout?.(timeout);
20822
+ }
20790
20823
  }
20791
20824
  }
20792
20825
  }
@@ -20831,7 +20864,10 @@ class KritzelRotationHandler extends KritzelBaseHandler {
20831
20864
  const currentRotation = Math.atan2(groupCenterY - cursorY, groupCenterX - cursorX);
20832
20865
  this.rotation = currentRotation - this.initialRotation;
20833
20866
  selectionGroup.rotate(this.rotation);
20834
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20867
+ const timeout = this._core.store.state.longTouchTimeout;
20868
+ if (timeout) {
20869
+ globalThis.clearTimeout?.(timeout);
20870
+ }
20835
20871
  }
20836
20872
  }
20837
20873
  }
@@ -20858,7 +20894,10 @@ class KritzelRotationHandler extends KritzelBaseHandler {
20858
20894
  this._core.store.state.isRotating = false;
20859
20895
  this._core.store.state.hasObjectsChanged = true;
20860
20896
  this.reset();
20861
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
20897
+ const timeout = this._core.store.state.longTouchTimeout;
20898
+ if (timeout) {
20899
+ globalThis.clearTimeout?.(timeout);
20900
+ }
20862
20901
  }
20863
20902
  }
20864
20903
  }
@@ -20883,7 +20922,7 @@ class KritzelSelectionBox extends KritzelBaseObject {
20883
20922
  const object = new KritzelSelectionBox();
20884
20923
  object._core = core;
20885
20924
  object.id = object.generateId();
20886
- object.workspaceId = core.store.state.activeWorkspace.id;
20925
+ object.workspaceId = core.store.activeWorkspace.id;
20887
20926
  object.userId = core.user?.id;
20888
20927
  object.scale = core.store.state.scale;
20889
20928
  object.zIndex = 99999;
@@ -20903,8 +20942,8 @@ class KritzelSelectionBox extends KritzelBaseObject {
20903
20942
  * via shift/ctrl modifiers.
20904
20943
  */
20905
20944
  class KritzelSelectionHandler extends KritzelBaseHandler {
20906
- startX;
20907
- startY;
20945
+ startX = 0;
20946
+ startY = 0;
20908
20947
  touchStartX = 0;
20909
20948
  touchStartY = 0;
20910
20949
  touchStartTimeout = null;
@@ -20982,7 +21021,10 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
20982
21021
  const moveThreshold = 5;
20983
21022
  if ((moveDeltaX > moveThreshold || moveDeltaY > moveThreshold) && this._core.store.state.isSelecting) {
20984
21023
  this.updateTouchSelection();
20985
- clearTimeout(this._core.store.state.longTouchTimeout);
21024
+ const timeout = this._core.store.state.longTouchTimeout;
21025
+ if (timeout) {
21026
+ globalThis.clearTimeout?.(timeout);
21027
+ }
20986
21028
  }
20987
21029
  }
20988
21030
  }
@@ -21047,9 +21089,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21047
21089
  */
21048
21090
  removeSelectionBox() {
21049
21091
  this._core.store.state.isSelecting = false;
21050
- this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox);
21092
+ this._core.store.objects.remove(o => o instanceof KritzelSelectionBox);
21051
21093
  this._core.store.setSelectionBox(null);
21052
- this._core.store.state.objects.clearLocalSelectionBox();
21094
+ this._core.store.objects.clearLocalSelectionBox();
21053
21095
  }
21054
21096
  /**
21055
21097
  * Initiates a mouse-based selection by creating a selection box at the click position.
@@ -21068,12 +21110,12 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21068
21110
  selectionBox.translateX = this.startX;
21069
21111
  selectionBox.translateY = this.startY;
21070
21112
  this._core.store.state.isSelecting = true;
21071
- this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup && (o.userId == null || o.userId === this._core.user?.id)));
21113
+ this._core.store.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup && (o.userId == null || o.userId === this._core.user?.id)));
21072
21114
  this._core.store.setSelectionBox(null);
21073
21115
  if (!isAdditive) {
21074
21116
  this._core.store.setSelectionGroup(null);
21075
21117
  }
21076
- this._core.store.state.objects.insert(selectionBox);
21118
+ this._core.store.objects.insert(selectionBox);
21077
21119
  this._core.store.setSelectionBox(selectionBox);
21078
21120
  }
21079
21121
  /**
@@ -21100,12 +21142,12 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21100
21142
  selectionBox.translateX = this.startX;
21101
21143
  selectionBox.translateY = this.startY;
21102
21144
  this._core.store.state.isSelecting = true;
21103
- this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup && (o.userId == null || o.userId === this._core.user?.id)));
21145
+ this._core.store.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup && (o.userId == null || o.userId === this._core.user?.id)));
21104
21146
  this._core.store.setSelectionBox(null);
21105
21147
  if (!isAdditive) {
21106
21148
  this._core.store.setSelectionGroup(null);
21107
21149
  }
21108
- this._core.store.state.objects.insert(selectionBox);
21150
+ this._core.store.objects.insert(selectionBox);
21109
21151
  this._core.store.setSelectionBox(selectionBox);
21110
21152
  }
21111
21153
  /**
@@ -21128,7 +21170,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21128
21170
  selectionBox.height = height;
21129
21171
  selectionBox.translateX = Math.min(currentX, this.startX);
21130
21172
  selectionBox.translateY = Math.min(currentY, this.startY);
21131
- this._core.store.state.objects.setLocalSelectionBox({
21173
+ this._core.store.objects.setLocalSelectionBox({
21132
21174
  x: selectionBox.translateX,
21133
21175
  y: selectionBox.translateY,
21134
21176
  width: width / selectionBox.scale,
@@ -21167,7 +21209,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21167
21209
  selectionBox.height = height;
21168
21210
  selectionBox.translateX = Math.min(currentX, this.startX);
21169
21211
  selectionBox.translateY = Math.min(currentY, this.startY);
21170
- this._core.store.state.objects.setLocalSelectionBox({
21212
+ this._core.store.objects.setLocalSelectionBox({
21171
21213
  x: selectionBox.translateX,
21172
21214
  y: selectionBox.translateY,
21173
21215
  width: width / selectionBox.scale,
@@ -21207,9 +21249,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21207
21249
  y: minY,
21208
21250
  z: selectionBox.scale,
21209
21251
  width: maxX - minX,
21210
- height: maxY - minY
21252
+ height: maxY - minY,
21211
21253
  };
21212
- const candidates = this._core.store.state.objects.query(selectionBounds);
21254
+ const candidates = this._core.store.objects.query(selectionBounds);
21213
21255
  // Track newly selected objects for efficient comparison
21214
21256
  const newlySelectedObjects = new Set();
21215
21257
  // Only test candidates that overlap the bounding box
@@ -21241,7 +21283,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21241
21283
  const selectedObject = this.getTopmostHitObject(event);
21242
21284
  const isAdditive = event.shiftKey || event.ctrlKey;
21243
21285
  this.clearSelectionPreview();
21244
- this.addObjectToSelectionGroup(selectedObject, isAdditive);
21286
+ if (selectedObject) {
21287
+ this.addObjectToSelectionGroup(selectedObject, isAdditive);
21288
+ }
21245
21289
  this.removeSelectionBox();
21246
21290
  }
21247
21291
  /**
@@ -21324,7 +21368,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
21324
21368
  return;
21325
21369
  }
21326
21370
  // Build parent group lookup map ONCE - O(g * c) instead of O(n * g * c)
21327
- const allGroups = this._core.store.state.objects.filter(obj => obj.__class__ === 'KritzelGroup');
21371
+ const allGroups = this._core.store.objects.filter(obj => obj.__class__ === 'KritzelGroup');
21328
21372
  const childToParentMap = new Map();
21329
21373
  for (const group of allGroups) {
21330
21374
  for (const childId of group.childIds) {
@@ -21491,7 +21535,10 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
21491
21535
  if (handleType === 'start' || handleType === 'end') {
21492
21536
  this._core.anchorManager.removeAnchor(line.id, handleType);
21493
21537
  }
21494
- globalThis.clearTimeout?.(this._core.store.state.longTouchTimeout);
21538
+ const timeout = this._core.store.state.longTouchTimeout;
21539
+ if (timeout) {
21540
+ globalThis.clearTimeout?.(timeout);
21541
+ }
21495
21542
  }
21496
21543
  /**
21497
21544
  * Handles pointer move events during a line handle drag operation.
@@ -21786,8 +21833,8 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
21786
21833
  const rotatedDeltaCx = deltaCx * cos - deltaCy * sin;
21787
21834
  const rotatedDeltaCy = deltaCx * sin + deltaCy * cos;
21788
21835
  // Calculate new translate
21789
- const newTranslateX = this.initialTranslateX + scale * (oldWidth - newWidth) / 2 + scale * rotatedDeltaCx;
21790
- const newTranslateY = this.initialTranslateY + scale * (oldHeight - newHeight) / 2 + scale * rotatedDeltaCy;
21836
+ const newTranslateX = this.initialTranslateX + (scale * (oldWidth - newWidth)) / 2 + scale * rotatedDeltaCx;
21837
+ const newTranslateY = this.initialTranslateY + (scale * (oldHeight - newHeight)) / 2 + scale * rotatedDeltaCy;
21791
21838
  // Update the line properties
21792
21839
  line.startX = startX;
21793
21840
  line.startY = startY;
@@ -21802,7 +21849,7 @@ class KritzelLineHandleHandler extends KritzelBaseHandler {
21802
21849
  line.translateY = newTranslateY;
21803
21850
  // Clear cached adjusted points
21804
21851
  line._adjustedPoints = null;
21805
- this._core.store.state.objects.update(line);
21852
+ this._core.store.objects.update(line);
21806
21853
  }
21807
21854
  /**
21808
21855
  * Handles pointer up events to complete a line handle drag operation.
@@ -22073,7 +22120,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
22073
22120
  const objects = this.flattenObjects(this.getSelectedObjects());
22074
22121
  for (const obj of objects) {
22075
22122
  if (obj instanceof KritzelLine)
22076
- return obj.arrows;
22123
+ return obj.arrows ?? { start: { enabled: false }, end: { enabled: false } };
22077
22124
  }
22078
22125
  return { start: { enabled: false }, end: { enabled: false } };
22079
22126
  }
@@ -22315,7 +22362,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
22315
22362
  getSelectedObject(event) {
22316
22363
  const path = event.composedPath().slice(1);
22317
22364
  const objectElement = path.find(element => element.classList && element.classList.contains('object'));
22318
- const object = this._core.findObjectById(objectElement?.id);
22365
+ const object = objectElement?.id ? this._core.findObjectById(objectElement.id) : null;
22319
22366
  if (!object) {
22320
22367
  return null;
22321
22368
  }
@@ -25726,7 +25773,7 @@ class KritzelAnchorManager {
25726
25773
  // Snap the endpoint to the target's center
25727
25774
  this.snapEndpointToObject(line, endpoint, targetObjectId);
25728
25775
  // Persist the change
25729
- this._core.store.state.objects.update(line);
25776
+ this._core.store.objects.update(line);
25730
25777
  }
25731
25778
  /**
25732
25779
  * Removes an anchor from a line endpoint.
@@ -26105,7 +26152,7 @@ class KritzelAnchorManager {
26105
26152
  // Update the line to persist the change
26106
26153
  const line = this.getLineById(entry.lineId);
26107
26154
  if (line) {
26108
- this._core.store.state.objects.update(line);
26155
+ this._core.store.objects.update(line);
26109
26156
  }
26110
26157
  }
26111
26158
  // Remove the object from the index
@@ -26207,7 +26254,7 @@ class KritzelAnchorManager {
26207
26254
  * @returns The KritzelLine object if found and is a line, null otherwise.
26208
26255
  */
26209
26256
  getLineById(lineId) {
26210
- const objects = this._core.store.state.objects.filter(o => o.id === lineId);
26257
+ const objects = this._core.store.objects.filter(o => o.id === lineId);
26211
26258
  if (objects.length === 0) {
26212
26259
  return null;
26213
26260
  }
@@ -26221,7 +26268,7 @@ class KritzelAnchorManager {
26221
26268
  * @returns The KritzelBaseObject if found, null otherwise.
26222
26269
  */
26223
26270
  getObjectById(objectId) {
26224
- const objects = this._core.store.state.objects.filter(o => o.id === objectId);
26271
+ const objects = this._core.store.objects.filter(o => o.id === objectId);
26225
26272
  return objects.length > 0 ? objects[0] : null;
26226
26273
  }
26227
26274
  /**