kritzel-stencil 0.1.31 → 0.1.33

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 (145) hide show
  1. package/dist/cjs/{default-line-tool.config-qD8Chdg7.js → alignment.enum-B6ffXMOy.js} +169 -124
  2. package/dist/cjs/{index-NMqsANCI.js → index-DIJLnoqQ.js} +2 -2
  3. package/dist/cjs/index.cjs.js +139 -135
  4. package/dist/cjs/kritzel-back-to-content_32.cjs.entry.js +768 -242
  5. package/dist/cjs/kritzel-brush-style.cjs.entry.js +1 -1
  6. package/dist/cjs/loader.cjs.js +2 -2
  7. package/dist/cjs/stencil.cjs.js +3 -3
  8. package/dist/collection/classes/core/core.class.js +56 -0
  9. package/dist/collection/classes/core/viewport.class.js +107 -19
  10. package/dist/collection/classes/handlers/key.handler.js +48 -25
  11. package/dist/collection/classes/handlers/move.handler.js +4 -2
  12. package/dist/collection/classes/handlers/selection.handler.js +61 -34
  13. package/dist/collection/classes/objects/selection-group.class.js +27 -0
  14. package/dist/collection/classes/registries/icon-registry.class.js +13 -1
  15. package/dist/collection/classes/registries/tool.registry.js +3 -0
  16. package/dist/collection/classes/tools/selection-tool.class.js +6 -2
  17. package/dist/collection/collection-manifest.json +1 -1
  18. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +162 -19
  19. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +213 -3
  20. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.css +53 -2
  21. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +112 -7
  22. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.css +52 -2
  23. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +114 -3
  24. package/dist/collection/configs/default-engine-config.js +5 -1
  25. package/dist/collection/constants/version.js +1 -1
  26. package/dist/collection/enums/alignment.enum.js +9 -0
  27. package/dist/collection/helpers/alignment.helper.js +73 -0
  28. package/dist/collection/helpers/devices.helper.js +3 -0
  29. package/dist/collection/helpers/keyboard.helper.js +12 -69
  30. package/dist/collection/index.js +2 -0
  31. package/dist/collection/themes/dark-theme.js +7 -0
  32. package/dist/collection/themes/light-theme.js +7 -0
  33. package/dist/components/index.js +1 -1
  34. package/dist/components/kritzel-back-to-content.js +1 -1
  35. package/dist/components/kritzel-brush-style.js +1 -1
  36. package/dist/components/kritzel-color-palette.js +1 -1
  37. package/dist/components/kritzel-color.js +1 -1
  38. package/dist/components/kritzel-context-menu.js +1 -1
  39. package/dist/components/kritzel-controls.js +1 -1
  40. package/dist/components/kritzel-cursor-trail.js +1 -1
  41. package/dist/components/kritzel-dialog.js +1 -1
  42. package/dist/components/kritzel-dropdown.js +1 -1
  43. package/dist/components/kritzel-editor.js +1 -1
  44. package/dist/components/kritzel-engine.js +1 -1
  45. package/dist/components/kritzel-export.js +1 -1
  46. package/dist/components/kritzel-font-family.js +1 -1
  47. package/dist/components/kritzel-font-size.js +1 -1
  48. package/dist/components/kritzel-font.js +1 -1
  49. package/dist/components/kritzel-icon.js +1 -1
  50. package/dist/components/kritzel-line-endings.js +1 -1
  51. package/dist/components/kritzel-master-detail.js +1 -1
  52. package/dist/components/kritzel-menu-item.js +1 -1
  53. package/dist/components/kritzel-menu.js +1 -1
  54. package/dist/components/kritzel-more-menu.js +1 -1
  55. package/dist/components/kritzel-numeric-input.js +1 -1
  56. package/dist/components/kritzel-opacity-slider.js +1 -1
  57. package/dist/components/kritzel-portal.js +1 -1
  58. package/dist/components/kritzel-settings.js +1 -1
  59. package/dist/components/kritzel-shape-fill.js +1 -1
  60. package/dist/components/kritzel-slide-toggle.js +1 -1
  61. package/dist/components/kritzel-split-button.js +1 -1
  62. package/dist/components/kritzel-stroke-size.js +1 -1
  63. package/dist/components/kritzel-tool-config.js +1 -1
  64. package/dist/components/kritzel-tooltip.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-D6cey6Hr.js → p--XTEcyn_.js} +1 -1
  68. package/dist/components/p-B8CWwdfi.js +1 -0
  69. package/dist/components/{p-Dz5ub8ld.js → p-BGPuQkm0.js} +1 -1
  70. package/dist/components/{p-BpgX0LEG.js → p-BNwjQiPh.js} +1 -1
  71. package/dist/components/{p-CIslK7aK.js → p-BSeT3m6s.js} +1 -1
  72. package/dist/components/{p-CuWxY3KC.js → p-BYI5ehMO.js} +1 -1
  73. package/dist/components/{p-B-tzBj-f.js → p-BaKE7XPi.js} +1 -1
  74. package/dist/components/{p-D3ynGLzV.js → p-BjDOFcMX.js} +1 -1
  75. package/dist/components/p-BnHOylv8.js +1 -0
  76. package/dist/components/{p-CSxODmkF.js → p-C4N8AZ9B.js} +1 -1
  77. package/dist/components/{p-D80DeXmM.js → p-CC1BHPhB.js} +1 -1
  78. package/dist/components/p-CES4oQNA.js +1 -0
  79. package/dist/components/p-CVzm666U.js +1 -0
  80. package/dist/components/{p-Cb3hilN-.js → p-CYnXapmr.js} +1 -1
  81. package/dist/components/{p-BwZ_0A7g.js → p-CeKkAN2i.js} +1 -1
  82. package/dist/components/{p-BiibSoAl.js → p-CmaPYM4B.js} +1 -1
  83. package/dist/components/{p-TQCB-ocH.js → p-Cp2tbPv4.js} +1 -1
  84. package/dist/components/{p-CS2-FWGh.js → p-Cr8tKxRj.js} +1 -1
  85. package/dist/components/{p-B22gBahO.js → p-CrGrZ8uk.js} +1 -1
  86. package/dist/components/p-D0CbTHkO.js +9 -0
  87. package/dist/components/{p-Dt85tAlJ.js → p-D0RL1-Ei.js} +1 -1
  88. package/dist/components/{p-D84uGsE3.js → p-D6-IoJEY.js} +1 -1
  89. package/dist/components/p-DFX-ZavX.js +1 -0
  90. package/dist/components/{p-BUW_CzVu.js → p-DID_uArU.js} +1 -1
  91. package/dist/components/{p-Cu2JOs99.js → p-DbXV7qn9.js} +1 -1
  92. package/dist/components/{p-DTd44r1v.js → p-DhvIA1iT.js} +1 -1
  93. package/dist/components/{p-eE5FpwD4.js → p-DqsfSW0F.js} +1 -1
  94. package/dist/components/{p-K1VNFj7L.js → p-FdIFe1Pu.js} +1 -1
  95. package/dist/components/{p-DB2KHpaa.js → p-GMJthlFK.js} +1 -1
  96. package/dist/components/p-LJx8eUhH.js +1 -0
  97. package/dist/components/{p-CioyMx_2.js → p-VreWTrJ9.js} +1 -1
  98. package/dist/components/{p-CJAFwG4C.js → p-hzWexKmP.js} +1 -1
  99. package/dist/components/{p-l10It7Nm.js → p-jGOpkGDl.js} +1 -1
  100. package/dist/esm/{default-line-tool.config-CjlaN1S5.js → alignment.enum-CU8gYEtU.js} +170 -125
  101. package/dist/esm/{index-DeSOzavr.js → index-CS1qgEOS.js} +2 -2
  102. package/dist/esm/index.js +2 -2
  103. package/dist/esm/kritzel-back-to-content_32.entry.js +608 -82
  104. package/dist/esm/kritzel-brush-style.entry.js +1 -1
  105. package/dist/esm/loader.js +3 -3
  106. package/dist/esm/stencil.js +4 -4
  107. package/dist/stencil/index.esm.js +1 -1
  108. package/dist/stencil/p-22e7d6ed.entry.js +9 -0
  109. package/dist/stencil/p-CU8gYEtU.js +1 -0
  110. package/dist/stencil/{p-e2bb9026.entry.js → p-a7fb4dc6.entry.js} +1 -1
  111. package/dist/stencil/stencil.esm.js +1 -1
  112. package/dist/types/classes/core/core.class.d.ts +9 -0
  113. package/dist/types/classes/core/viewport.class.d.ts +15 -0
  114. package/dist/types/classes/handlers/key.handler.d.ts +3 -1
  115. package/dist/types/classes/objects/selection-group.class.d.ts +1 -0
  116. package/dist/types/classes/registries/tool.registry.d.ts +1 -0
  117. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +7 -0
  118. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +17 -0
  119. package/dist/types/components/ui/kritzel-context-menu/kritzel-context-menu.d.ts +12 -0
  120. package/dist/types/components/ui/kritzel-settings/kritzel-settings.d.ts +14 -0
  121. package/dist/types/components.d.ts +101 -4
  122. package/dist/types/constants/version.d.ts +1 -1
  123. package/dist/types/enums/alignment.enum.d.ts +8 -0
  124. package/dist/types/helpers/alignment.helper.d.ts +21 -0
  125. package/dist/types/helpers/devices.helper.d.ts +1 -0
  126. package/dist/types/helpers/keyboard.helper.d.ts +0 -1
  127. package/dist/types/index.d.ts +2 -0
  128. package/dist/types/interfaces/context-menu-item.interface.d.ts +3 -1
  129. package/dist/types/interfaces/engine-state.interface.d.ts +8 -0
  130. package/dist/types/interfaces/settings.interface.d.ts +8 -0
  131. package/dist/types/interfaces/shortcut.interface.d.ts +2 -0
  132. package/dist/types/interfaces/theme.interface.d.ts +7 -0
  133. package/dist/types/stencil-public-runtime.d.ts +3 -1
  134. package/package.json +1 -1
  135. package/dist/components/p-BPSr4bMw.js +0 -1
  136. package/dist/components/p-C5-i16ck.js +0 -1
  137. package/dist/components/p-Cg6bE3bx.js +0 -1
  138. package/dist/components/p-CihUAfk9.js +0 -9
  139. package/dist/components/p-CnoVf56N.js +0 -1
  140. package/dist/components/p-DUSygVl-.js +0 -1
  141. package/dist/components/p-opmUuRlE.js +0 -1
  142. package/dist/stencil/p-9bce6f4f.entry.js +0 -9
  143. package/dist/stencil/p-CjlaN1S5.js +0 -1
  144. /package/dist/components/{p-BjwppWz9.js → p-CwrXe_ca.js} +0 -0
  145. /package/dist/stencil/{p-DeSOzavr.js → p-CS1qgEOS.js} +0 -0
@@ -16,6 +16,9 @@ class KritzelToolRegistry {
16
16
  }
17
17
  return toolInstance;
18
18
  }
19
+ static getToolByIndex(index) {
20
+ return Object.values(this.registry)[index] ?? null;
21
+ }
19
22
  }
20
23
 
21
24
  class ObjectHelper {
@@ -450,6 +453,9 @@ class KritzelDevicesHelper {
450
453
  return 'Other';
451
454
  }
452
455
  }
456
+ static isMobile() {
457
+ return this.isIOS() || this.isAndroid();
458
+ }
453
459
  static isFirefox() {
454
460
  return /firefox/i.test(navigator.userAgent);
455
461
  }
@@ -484,82 +490,25 @@ class KritzelKeyboardHelper {
484
490
  meta.setAttribute('content', newContent);
485
491
  }
486
492
  }
487
- static isTextInputFocused() {
488
- const activeElement = document.activeElement;
489
- if (!activeElement)
490
- return false;
491
- // Check for standard text input elements
492
- if (activeElement instanceof HTMLInputElement) {
493
- const textTypes = ['text', 'password', 'email', 'number', 'search', 'tel', 'url'];
494
- return textTypes.includes(activeElement.type);
495
- }
496
- if (activeElement instanceof HTMLTextAreaElement) {
497
- return true;
498
- }
499
- // Check for contenteditable elements
500
- if (activeElement instanceof HTMLElement && activeElement.isContentEditable) {
501
- return true;
502
- }
503
- return false;
504
- }
505
493
  static onKeyboardVisibleChanged(callback) {
506
- const os = KritzelDevicesHelper.detectOS();
507
- if (os !== 'iOS' && os !== 'Android') {
508
- return () => { };
509
- }
510
- // Use VirtualKeyboard API if available (modern browsers)
511
- if ('virtualKeyboard' in navigator) {
512
- const vk = navigator.virtualKeyboard;
513
- const onGeometryChange = () => {
514
- const isOpen = vk.boundingRect.height > 0;
515
- callback(isOpen);
516
- };
517
- vk.addEventListener('geometrychange', onGeometryChange);
518
- return () => vk.removeEventListener('geometrychange', onGeometryChange);
519
- }
520
- // Fallback: combine focus detection with viewport changes
521
494
  if ('visualViewport' in window) {
522
495
  const VIEWPORT_VS_CLIENT_HEIGHT_RATIO = 0.75;
523
- let initialHeight = window.visualViewport.height;
524
- const checkKeyboardState = () => {
525
- const viewportRatio = (window.visualViewport.height * window.visualViewport.scale) / initialHeight;
526
- const viewportShrunk = viewportRatio < VIEWPORT_VS_CLIENT_HEIGHT_RATIO;
527
- const isOpen = viewportShrunk && this.isTextInputFocused();
496
+ const onResize = (event) => {
497
+ const target = event.target;
498
+ const isMobileDevice = KritzelDevicesHelper.isMobile();
499
+ const isViewportReduced = (target.height * target.scale) / window.screen.height < VIEWPORT_VS_CLIENT_HEIGHT_RATIO;
500
+ const isOpen = isMobileDevice && isViewportReduced;
528
501
  callback(isOpen);
529
502
  };
530
- const onResize = () => {
531
- checkKeyboardState();
532
- };
533
- const onFocusIn = () => {
534
- // Update initial height when focus changes to capture pre-keyboard state
535
- if (!this.isTextInputFocused()) {
536
- initialHeight = window.visualViewport.height;
537
- }
538
- // Small delay to allow viewport to adjust
539
- setTimeout(checkKeyboardState, 100);
540
- };
541
- const onFocusOut = () => {
542
- // Keyboard closes when focus leaves text inputs
543
- setTimeout(() => {
544
- if (!this.isTextInputFocused()) {
545
- callback(false);
546
- // Reset initial height after keyboard closes
547
- setTimeout(() => {
548
- initialHeight = window.visualViewport.height;
549
- }, 300);
550
- }
551
- }, 100);
552
- };
553
503
  window.visualViewport.addEventListener('resize', onResize);
554
- document.addEventListener('focusin', onFocusIn);
555
- document.addEventListener('focusout', onFocusOut);
556
- return () => {
557
- window.visualViewport.removeEventListener('resize', onResize);
558
- document.removeEventListener('focusin', onFocusIn);
559
- document.removeEventListener('focusout', onFocusOut);
560
- };
504
+ return () => window.visualViewport.removeEventListener('resize', onResize);
505
+ }
506
+ else {
507
+ // Fallback for older browsers does not provide a reliable event-based mechanism.
508
+ console.warn('Listening for keyboard visibility changes is not reliably supported in this browser.');
509
+ // Return a no-op cleanup function.
510
+ return () => { };
561
511
  }
562
- return () => { };
563
512
  }
564
513
  }
565
514
 
@@ -3396,7 +3345,7 @@ function wsOptionsFor(type, preserveWhitespace, base) {
3396
3345
  if (preserveWhitespace != null)
3397
3346
  return (preserveWhitespace ? OPT_PRESERVE_WS : 0) |
3398
3347
  (preserveWhitespace === "full" ? OPT_PRESERVE_WS_FULL : 0);
3399
- return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & -5;
3348
+ return type && type.whitespace == "pre" ? OPT_PRESERVE_WS | OPT_PRESERVE_WS_FULL : base & ~OPT_OPEN_LEFT;
3400
3349
  }
3401
3350
  class NodeContext {
3402
3351
  constructor(type, attrs, marks, solid, match, options) {
@@ -6801,7 +6750,7 @@ let Transaction$1 = class Transaction extends Transform {
6801
6750
  throw new RangeError("Selection passed to setSelection must point at the current document");
6802
6751
  this.curSelection = selection;
6803
6752
  this.curSelectionFor = this.steps.length;
6804
- this.updated = (this.updated | UPDATED_SEL) & -3;
6753
+ this.updated = (this.updated | UPDATED_SEL) & ~UPDATED_MARKS;
6805
6754
  this.storedMarks = null;
6806
6755
  return this;
6807
6756
  }
@@ -6852,7 +6801,7 @@ let Transaction$1 = class Transaction extends Transform {
6852
6801
  */
6853
6802
  addStep(step, doc) {
6854
6803
  super.addStep(step, doc);
6855
- this.updated = this.updated & -3;
6804
+ this.updated = this.updated & ~UPDATED_MARKS;
6856
6805
  this.storedMarks = null;
6857
6806
  }
6858
6807
  /**
@@ -11966,7 +11915,17 @@ class DOMObserver {
11966
11915
  }
11967
11916
  }
11968
11917
  }
11969
- if (gecko && added.length) {
11918
+ if (added.some(n => n.nodeName == "BR") && (view.input.lastKeyCode == 8 || view.input.lastKeyCode == 46)) {
11919
+ // Browsers sometimes insert a bogus break node if you
11920
+ // backspace out the last bit of text before an inline-flex node (#1552)
11921
+ for (let node of added)
11922
+ if (node.nodeName == "BR" && node.parentNode) {
11923
+ let after = node.nextSibling;
11924
+ if (after && after.nodeType == 1 && after.contentEditable == "false")
11925
+ node.parentNode.removeChild(node);
11926
+ }
11927
+ }
11928
+ else if (gecko && added.length) {
11970
11929
  let brs = added.filter(n => n.nodeName == "BR");
11971
11930
  if (brs.length == 2) {
11972
11931
  let [a, b] = brs;
@@ -11984,17 +11943,6 @@ class DOMObserver {
11984
11943
  }
11985
11944
  }
11986
11945
  }
11987
- else if ((chrome || safari) && added.some(n => n.nodeName == "BR") &&
11988
- (view.input.lastKeyCode == 8 || view.input.lastKeyCode == 46)) {
11989
- // Chrome/Safari sometimes insert a bogus break node if you
11990
- // backspace out the last bit of text before an inline-flex node (#1552)
11991
- for (let node of added)
11992
- if (node.nodeName == "BR" && node.parentNode) {
11993
- let after = node.nextSibling;
11994
- if (after && after.nodeType == 1 && after.contentEditable == "false")
11995
- node.parentNode.removeChild(node);
11996
- }
11997
- }
11998
11946
  let readSel = null;
11999
11947
  // If it looks like the browser has reset the selection to the
12000
11948
  // start of the document after focus, restore the selection from
@@ -14197,6 +14145,7 @@ const lightTheme = {
14197
14145
  backgroundColor: '#ffffff',
14198
14146
  border: '1px solid #ebebeb',
14199
14147
  boxShadow: '0 1px 6px rgba(0, 0, 0, 0.12)',
14148
+ dividerColor: 'rgba(0, 0, 0, 0.1)',
14200
14149
  itemActiveBackgroundColor: 'hsl(0, 0%, 0%, 8.6%)',
14201
14150
  itemColor: '#333333',
14202
14151
  itemDisabledColor: '#aaaaaa',
@@ -14318,6 +14267,12 @@ const lightTheme = {
14318
14267
  contentTextColor: '#333333',
14319
14268
  descriptionColor: '#666666',
14320
14269
  labelColor: '#333333',
14270
+ shortcutsCategoryColor: '#666666',
14271
+ shortcutItemBg: '#f8f8f8',
14272
+ shortcutLabelColor: '#333333',
14273
+ shortcutKeyBg: '#ffffff',
14274
+ shortcutKeyBorder: '#e0e0e0',
14275
+ shortcutKeyColor: '#555555',
14321
14276
  },
14322
14277
  shapeFill: {
14323
14278
  hoverBackgroundColor: '#ebebeb',
@@ -14397,6 +14352,7 @@ const darkTheme = {
14397
14352
  backgroundColor: '#2a2a2a',
14398
14353
  border: '1px solid #3a3a3a',
14399
14354
  boxShadow: '0 1px 8px rgba(0, 0, 0, 0.4)',
14355
+ dividerColor: 'rgba(255, 255, 255, 0.1)',
14400
14356
  itemActiveBackgroundColor: 'hsl(0, 0%, 100%, 12%)',
14401
14357
  itemColor: '#e0e0e0',
14402
14358
  itemDisabledColor: '#666666',
@@ -14517,6 +14473,12 @@ const darkTheme = {
14517
14473
  contentTextColor: '#e0e0e0',
14518
14474
  descriptionColor: '#999999',
14519
14475
  labelColor: '#e0e0e0',
14476
+ shortcutsCategoryColor: '#999999',
14477
+ shortcutItemBg: '#3a3a3a',
14478
+ shortcutLabelColor: '#e0e0e0',
14479
+ shortcutKeyBg: '#2a2a2a',
14480
+ shortcutKeyBorder: '#4a4a4a',
14481
+ shortcutKeyColor: '#e0e0e0',
14520
14482
  },
14521
14483
  shapeFill: {
14522
14484
  hoverBackgroundColor: '#3a3a3a',
@@ -15108,7 +15070,8 @@ function requireCjs () {
15108
15070
  if (hasRequiredCjs) return cjs;
15109
15071
  hasRequiredCjs = 1;
15110
15072
  (function (exports) {
15111
- var pe=Object.defineProperty;var ge=e=>pe(e,"__esModule",{value:true});var de=(e,t)=>{ge(e);for(var s in t)pe(e,s,{get:t[s],enumerable:true});};de(exports,{default:()=>ve,getStroke:()=>ne,getStrokeOutlinePoints:()=>te,getStrokePoints:()=>re});function $(e,t,s,x=h=>h){return e*x(.5-t*(.5-s))}function ce(e){return [-e[0],-e[1]]}function l(e,t){return [e[0]+t[0],e[1]+t[1]]}function a(e,t){return [e[0]-t[0],e[1]-t[1]]}function b(e,t){return [e[0]*t,e[1]*t]}function xe(e,t){return [e[0]/t,e[1]/t]}function R(e){return [e[1],-e[0]]}function B(e,t){return e[0]*t[0]+e[1]*t[1]}function me(e,t){return e[0]===t[0]&&e[1]===t[1]}function Se(e){return Math.hypot(e[0],e[1])}function Pe(e){return e[0]*e[0]+e[1]*e[1]}function A(e,t){return Pe(a(e,t))}function G(e){return xe(e,Se(e))}function ae(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function L(e,t,s){let x=Math.sin(s),h=Math.cos(s),y=e[0]-t[0],n=e[1]-t[1],f=y*h-n*x,d=y*x+n*h;return [f+t[0],d+t[1]]}function K(e,t,s){return l(e,b(a(t,e),s))}function ee(e,t,s){return l(e,b(t,s))}var{min:C,PI:ke}=Math,le=.275,V=ke+1e-4;function te(e,t={}){let{size:s=16,smoothing:x=.5,thinning:h=.5,simulatePressure:y=true,easing:n=r=>r,start:f={},end:d={},last:D=false}=t,{cap:S=true,easing:j=r=>r*(2-r)}=f,{cap:q=true,easing:c=r=>--r*r*r+1}=d;if(e.length===0||s<=0)return [];let p=e[e.length-1].runningLength,g=f.taper===false?0:f.taper===true?Math.max(s,p):f.taper,T=d.taper===false?0:d.taper===true?Math.max(s,p):d.taper,oe=Math.pow(s*x,2),_=[],M=[],H=e.slice(0,10).reduce((r,i)=>{let o=i.pressure;if(y){let u=C(1,i.distance/s),W=C(1,1-u);o=C(1,r+(W-r)*(u*le));}return (r+o)/2},e[0].pressure),m=$(s,h,e[e.length-1].pressure,n),U,X=e[0].vector,z=e[0].point,F=z,O=z,E=F,J=false;for(let r=0;r<e.length;r++){let{pressure:i}=e[r],{point:o,vector:u,distance:W,runningLength:I}=e[r];if(r<e.length-1&&p-I<3)continue;if(h){if(y){let v=C(1,W/s),Z=C(1,1-v);i=C(1,H+(Z-H)*(v*le));}m=$(s,h,i,n);}else m=s/2;U===void 0&&(U=m);let fe=I<g?j(I/g):1,be=p-I<T?c((p-I)/T):1;m=Math.max(.01,m*Math.min(fe,be));let se=(r<e.length-1?e[r+1]:e[r]).vector,Y=r<e.length-1?B(u,se):1,he=B(u,X)<0&&!J,ue=Y!==null&&Y<0;if(he||ue){let v=b(R(X),m);for(let Z=1/13,w=0;w<=1;w+=Z)O=L(a(o,v),o,V*w),_.push(O),E=L(l(o,v),o,V*-w),M.push(E);z=O,F=E,ue&&(J=true);continue}if(J=false,r===e.length-1){let v=b(R(u),m);_.push(a(o,v)),M.push(l(o,v));continue}let ie=b(R(K(se,u,Y)),m);O=a(o,ie),(r<=1||A(z,O)>oe)&&(_.push(O),z=O),E=l(o,ie),(r<=1||A(F,E)>oe)&&(M.push(E),F=E),H=i,X=u;}let P=e[0].point.slice(0,2),k=e.length>1?e[e.length-1].point.slice(0,2):l(e[0].point,[1,1]),Q=[],N=[];if(e.length===1){if(!(g||T)||D){let r=ee(P,G(R(a(P,k))),-(U||m)),i=[];for(let o=1/13,u=o;u<=1;u+=o)i.push(L(r,P,V*2*u));return i}}else {if(!(g||T&&e.length===1))if(S)for(let i=1/13,o=i;o<=1;o+=i){let u=L(M[0],P,V*o);Q.push(u);}else {let i=a(_[0],M[0]),o=b(i,.5),u=b(i,.51);Q.push(a(P,o),a(P,u),l(P,u),l(P,o));}let r=R(ce(e[e.length-1].vector));if(T||g&&e.length===1)N.push(k);else if(q){let i=ee(k,r,m);for(let o=1/29,u=o;u<1;u+=o)N.push(L(i,k,V*3*u));}else N.push(l(k,b(r,m)),l(k,b(r,m*.99)),a(k,b(r,m*.99)),a(k,b(r,m)));}return _.concat(N,M.reverse(),Q)}function re(e,t={}){var q;let{streamline:s=.5,size:x=16,last:h=false}=t;if(e.length===0)return [];let y=.15+(1-s)*.85,n=Array.isArray(e[0])?e:e.map(({x:c,y:p,pressure:g=.5})=>[c,p,g]);if(n.length===2){let c=n[1];n=n.slice(0,-1);for(let p=1;p<5;p++)n.push(K(n[0],c,p/4));}n.length===1&&(n=[...n,[...l(n[0],[1,1]),...n[0].slice(2)]]);let f=[{point:[n[0][0],n[0][1]],pressure:n[0][2]>=0?n[0][2]:.25,vector:[1,1],distance:0,runningLength:0}],d=false,D=0,S=f[0],j=n.length-1;for(let c=1;c<n.length;c++){let p=h&&c===j?n[c].slice(0,2):K(S.point,n[c],y);if(me(S.point,p))continue;let g=ae(p,S.point);if(D+=g,c<j&&!d){if(D<x)continue;d=true;}S={point:p,pressure:n[c][2]>=0?n[c][2]:.5,vector:G(a(S.point,p)),distance:g,runningLength:D},f.push(S);}return f[0].vector=((q=f[1])==null?void 0:q.vector)||[0,0],f}function ne(e,t={}){return te(re(e,t),t)}var ve=ne;
15073
+ Object.defineProperties(exports,{__esModule:{value:true},[Symbol.toStringTag]:{value:`Module`}});const{PI:e}=Math,t=e+1e-4,n=.5,r=[1,1];function i(e,t,n,r=e=>e){return e*r(.5-t*(.5-n))}const{min:a}=Math;function o(e,t,n){let r=a(1,t/n);return a(1,e+(a(1,1-r)-e)*(r*.275))}function s(e){return [-e[0],-e[1]]}function c(e,t){return [e[0]+t[0],e[1]+t[1]]}function l(e,t,n){return e[0]=t[0]+n[0],e[1]=t[1]+n[1],e}function u(e,t){return [e[0]-t[0],e[1]-t[1]]}function d(e,t,n){return e[0]=t[0]-n[0],e[1]=t[1]-n[1],e}function f(e,t){return [e[0]*t,e[1]*t]}function p(e,t,n){return e[0]=t[0]*n,e[1]=t[1]*n,e}function m(e,t){return [e[0]/t,e[1]/t]}function h(e){return [e[1],-e[0]]}function g(e,t){let n=t[0];return e[0]=t[1],e[1]=-n,e}function ee(e,t){return e[0]*t[0]+e[1]*t[1]}function _(e,t){return e[0]===t[0]&&e[1]===t[1]}function v(e){return Math.hypot(e[0],e[1])}function y(e,t){let n=e[0]-t[0],r=e[1]-t[1];return n*n+r*r}function b(e){return m(e,v(e))}function x(e,t){return Math.hypot(e[1]-t[1],e[0]-t[0])}function S(e,t,n){let r=Math.sin(n),i=Math.cos(n),a=e[0]-t[0],o=e[1]-t[1],s=a*i-o*r,c=a*r+o*i;return [s+t[0],c+t[1]]}function C(e,t,n,r){let i=Math.sin(r),a=Math.cos(r),o=t[0]-n[0],s=t[1]-n[1],c=o*a-s*i,l=o*i+s*a;return e[0]=c+n[0],e[1]=l+n[1],e}function w(e,t,n){return c(e,f(u(t,e),n))}function te(e,t,n,r){let i=n[0]-t[0],a=n[1]-t[1];return e[0]=t[0]+i*r,e[1]=t[1]+a*r,e}function T(e,t,n){return c(e,f(t,n))}const E=[0,0],D=[0,0],O=[0,0];function k(e,n){let r=T(e,b(h(u(e,c(e,[1,1])))),-n),i=[],a=1/13;for(let n=a;n<=1;n+=a)i.push(S(r,e,t*2*n));return i}function A(e,n,r){let i=[],a=1/r;for(let r=a;r<=1;r+=a)i.push(S(n,e,t*r));return i}function j(e,t,n){let r=u(t,n),i=f(r,.5),a=f(r,.51);return [u(e,i),u(e,a),c(e,a),c(e,i)]}function M(e,n,r,i){let a=[],o=T(e,n,r),s=1/i;for(let n=s;n<1;n+=s)a.push(S(o,e,t*3*n));return a}function ne(e,t,n){return [c(e,f(t,n)),c(e,f(t,n*.99)),u(e,f(t,n*.99)),u(e,f(t,n))]}function N(e,t,n){return e===false||e===void 0?0:e===true?Math.max(t,n):e}function re(e,t,n){return e.slice(0,10).reduce((e,r)=>{let i=r.pressure;return t&&(i=o(e,r.distance,n)),(e+i)/2},e[0].pressure)}function P(e,n={}){let{size:r=16,smoothing:a=.5,thinning:f=.5,simulatePressure:m=true,easing:_=e=>e,start:v={},end:b={},last:x=false}=n,{cap:S=true,easing:w=e=>e*(2-e)}=v,{cap:T=true,easing:P=e=>--e*e*e+1}=b;if(e.length===0||r<=0)return [];let F=e[e.length-1].runningLength,I=N(v.taper,r,F),L=N(b.taper,r,F),R=(r*a)**2,z=[],B=[],V=re(e,m,r),H=i(r,f,e[e.length-1].pressure,_),U,W=e[0].vector,G=e[0].point,K=G,q=G,J=K,Y=false;for(let n=0;n<e.length;n++){let{pressure:a}=e[n],{point:s,vector:h,distance:v,runningLength:b}=e[n],x=n===e.length-1;if(!x&&F-b<3)continue;f?(m&&(a=o(V,v,r)),H=i(r,f,a,_)):H=r/2,U===void 0&&(U=H);let S=b<I?w(b/I):1,T=F-b<L?P((F-b)/L):1;H=Math.max(.01,H*Math.min(S,T));let k=(x?e[n]:e[n+1]).vector,A=x?1:ee(h,k),j=ee(h,W)<0&&!Y,M=A!==null&&A<0;if(j||M){g(E,W),p(E,E,H);for(let e=0;e<=1;e+=.07692307692307693)d(D,s,E),C(D,D,s,t*e),q=[D[0],D[1]],z.push(q),l(O,s,E),C(O,O,s,t*-e),J=[O[0],O[1]],B.push(J);G=q,K=J,M&&(Y=true);continue}if(Y=false,x){g(E,h),p(E,E,H),z.push(u(s,E)),B.push(c(s,E));continue}te(E,k,h,A),g(E,E),p(E,E,H),d(D,s,E),q=[D[0],D[1]],(n<=1||y(G,q)>R)&&(z.push(q),G=q),l(O,s,E),J=[O[0],O[1]],(n<=1||y(K,J)>R)&&(B.push(J),K=J),V=a,W=h;}let X=[e[0].point[0],e[0].point[1]],Z=e.length>1?[e[e.length-1].point[0],e[e.length-1].point[1]]:c(e[0].point,[1,1]),Q=[],$=[];if(e.length===1){if(!(I||L)||x)return k(X,U||H)}else {I||L&&e.length===1||(S?Q.push(...A(X,B[0],13)):Q.push(...j(X,z[0],B[0])));let t=h(s(e[e.length-1].vector));L||I&&e.length===1?$.push(Z):T?$.push(...M(Z,t,H,29)):$.push(...ne(Z,t,H));}return z.concat($,B.reverse(),Q)}const F=[0,0];function I(e){return e!=null&&e>=0}function L(e,t={}){let{streamline:i=.5,size:a=16,last:o=false}=t;if(e.length===0)return [];let s=.15+(1-i)*.85,l=Array.isArray(e[0])?e:e.map(({x:e,y:t,pressure:r=n})=>[e,t,r]);if(l.length===2){let e=l[1];l=l.slice(0,-1);for(let t=1;t<5;t++)l.push(w(l[0],e,t/4));}l.length===1&&(l=[...l,[...c(l[0],r),...l[0].slice(2)]]);let u=[{point:[l[0][0],l[0][1]],pressure:I(l[0][2])?l[0][2]:.25,vector:[...r],distance:0,runningLength:0}],f=false,p=0,m=u[0],h=l.length-1;for(let e=1;e<l.length;e++){let t=o&&e===h?[l[e][0],l[e][1]]:w(m.point,l[e],s);if(_(m.point,t))continue;let r=x(t,m.point);if(p+=r,e<h&&!f){if(p<a)continue;f=true;}d(F,m.point,t),m={point:t,pressure:I(l[e][2])?l[e][2]:n,vector:b(F),distance:r,runningLength:p},u.push(m);}return u[0].vector=u[1]?.vector||[0,0],u}function R(e,t={}){return P(L(e,t),t)}var z=R;exports.default=z,exports.getStroke=R,exports.getStrokeOutlinePoints=P,exports.getStrokePoints=L;
15074
+
15112
15075
  } (cjs));
15113
15076
  return cjs;
15114
15077
  }
@@ -16899,6 +16862,27 @@ class KritzelSelectionGroup extends KritzelBaseObject {
16899
16862
  object.zIndex = 99999;
16900
16863
  return object;
16901
16864
  }
16865
+ addObjects(objects) {
16866
+ let changed = false;
16867
+ for (const object of objects) {
16868
+ if (!this._objectIds.includes(object.id)) {
16869
+ this._objectIds.push(object.id);
16870
+ changed = true;
16871
+ }
16872
+ }
16873
+ if (changed) {
16874
+ this._cachedObjects = null;
16875
+ const children = this.objects;
16876
+ if (children.length === 1) {
16877
+ this.rotation = children[0].rotation;
16878
+ }
16879
+ else if (children.length > 1) {
16880
+ this.rotation = 0;
16881
+ }
16882
+ this.captureUnchangedSnapshots(children);
16883
+ this.refreshObjectDimensions(children);
16884
+ }
16885
+ }
16902
16886
  addOrRemove(object) {
16903
16887
  const index = this._objectIds.findIndex(id => id === object.id);
16904
16888
  if (index === -1) {
@@ -16909,6 +16893,12 @@ class KritzelSelectionGroup extends KritzelBaseObject {
16909
16893
  }
16910
16894
  this._cachedObjects = null; // Invalidate cache
16911
16895
  const children = this.objects; // Get cached objects once
16896
+ if (children.length === 1) {
16897
+ this.rotation = children[0].rotation;
16898
+ }
16899
+ else if (children.length > 1) {
16900
+ this.rotation = 0;
16901
+ }
16912
16902
  this.captureUnchangedSnapshots(children);
16913
16903
  this.refreshObjectDimensions(children);
16914
16904
  }
@@ -17715,6 +17705,8 @@ KritzelIconRegistry.registerIcons({
17715
17705
  'cursor': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M4.037 4.688a.495.495 0 0 1 .651-.651l16 6.5a.5.5 0 0 1-.063.947l-6.124 1.58a2 2 0 0 0-1.438 1.435l-1.579 6.126a.5.5 0 0 1-.947.063z"/></svg>',
17716
17706
  'pen': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/></svg>',
17717
17707
  'arrow': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="5" y1="19" x2="19" y2="5"/><path d="M15 5h4v4"/></svg>',
17708
+ 'arrow-up-from-dot': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-up-from-dot-icon lucide-arrow-up-from-dot"><path d="m5 9 7-7 7 7"/><path d="M12 16V2"/><circle cx="12" cy="21" r="1"/></svg>',
17709
+ 'arrow-down-from-dot': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-arrow-down-from-dot-icon lucide-arrow-down-from-dot" transform="rotate(180)"><path d="m5 9 7-7 7 7"/><path d="M12 16V2"/><circle cx="12" cy="21" r="1"/></svg>',
17718
17710
  'highlighter': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-highlighter-icon lucide-highlighter"><path d="m9 11-6 6v3h9l3-3"/><path d="m22 12-4.6 4.6a2 2 0 0 1-2.8 0l-5.2-5.2a2 2 0 0 1 0-2.8L14 4"/></svg>',
17719
17711
  'eraser': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><path d="m7 21-4.3-4.3c-1-1-1-2.5 0-3.4l9.6-9.6c1-1 2.5-1 3.4 0l5.6 5.6c1 1 1 2.5 0 3.4L13 21"/><path d="M22 21H7"/><path d="m5 11 9 9"/></svg>',
17720
17712
  'type': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><polyline points="4 7 4 4 20 4 20 7"/><line x1="9" x2="15" y1="20" y2="20"/><line x1="12" x2="12" y1="4" y2="20"/></svg>',
@@ -17753,7 +17745,17 @@ KritzelIconRegistry.registerIcons({
17753
17745
  'share': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-share2-icon lucide-share-2"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"/><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"/></svg>',
17754
17746
  'palette': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-palette-icon lucide-palette"><path d="M12 22a1 1 0 0 1 0-20 10 9 0 0 1 10 9 5 5 0 0 1-5 5h-2.25a1.75 1.75 0 0 0-1.4 2.8l.3.4a1.75 1.75 0 0 1-1.4 2.8z"/><circle cx="13.5" cy="6.5" r=".5" fill="currentColor"/><circle cx="17.5" cy="10.5" r=".5" fill="currentColor"/><circle cx="6.5" cy="12.5" r=".5" fill="currentColor"/><circle cx="8.5" cy="7.5" r=".5" fill="currentColor"/></svg>',
17755
17747
  'command': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-command-icon lucide-command"><path d="M15 6v12a3 3 0 1 0 3-3H6a3 3 0 1 0 3 3V6a3 3 0 1 0-3 3h12a3 3 0 1 0-3-3"/></svg>',
17756
- 'info': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info-icon lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>'
17748
+ 'info': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-info-icon lucide-info"><circle cx="12" cy="12" r="10"/><path d="M12 16v-4"/><path d="M12 8h.01"/></svg>',
17749
+ 'ordering': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bring-to-front-icon lucide-bring-to-front"><rect x="8" y="8" width="8" height="8" rx="2"/><path d="M4 10a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2"/><path d="M14 20a2 2 0 0 0 2 2h4a2 2 0 0 0 2-2v-4a2 2 0 0 0-2-2"/></svg>',
17750
+ 'layout-template': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-layout-template-icon lucide-layout-template"><rect width="18" height="7" x="3" y="3" rx="1"/><rect width="9" height="7" x="3" y="14" rx="1"/><rect width="5" height="7" x="16" y="14" rx="1"/></svg>',
17751
+ 'align': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round"><line x1="21" x2="3" y1="10" y2="10"/><line x1="21" x2="3" y1="6" y2="6"/><line x1="21" x2="3" y1="14" y2="14"/><line x1="21" x2="3" y1="18" y2="18"/></svg>',
17752
+ 'align-start-horizontal': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-start-horizontal-icon lucide-align-start-horizontal"><rect width="6" height="16" x="4" y="6" rx="2"/><rect width="6" height="9" x="14" y="6" rx="2"/><path d="M22 2H2"/></svg>',
17753
+ 'align-center-horizontal': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-center-horizontal-icon lucide-align-center-horizontal"><path d="M2 12h20"/><path d="M10 16v4a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-4"/><path d="M10 8V4a2 2 0 0 0-2-2H6a2 2 0 0 0-2 2v4"/><path d="M20 16v1a2 2 0 0 1-2 2h-2a2 2 0 0 1-2-2v-1"/><path d="M14 8V7c0-1.1.9-2 2-2h2a2 2 0 0 1 2 2v1"/></svg>',
17754
+ 'align-end-horizontal': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-end-horizontal-icon lucide-align-end-horizontal"><rect width="6" height="16" x="4" y="2" rx="2"/><rect width="6" height="9" x="14" y="9" rx="2"/><path d="M22 22H2"/></svg>',
17755
+ 'align-start-vertical': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-start-vertical-icon lucide-align-start-vertical"><rect width="9" height="6" x="6" y="14" rx="2"/><rect width="16" height="6" x="6" y="4" rx="2"/><path d="M2 2v20"/></svg>',
17756
+ 'align-center-vertical': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-center-vertical-icon lucide-align-center-vertical"><path d="M12 2v20"/><path d="M8 10H4a2 2 0 0 1-2-2V6c0-1.1.9-2 2-2h4"/><path d="M16 10h4a2 2 0 0 0 2-2V6a2 2 0 0 0-2-2h-4"/><path d="M8 20H7a2 2 0 0 1-2-2v-2c0-1.1.9-2 2-2h1"/><path d="M16 14h1a2 2 0 0 1 2 2v2a2 2 0 0 1-2 2h-1"/></svg>',
17757
+ 'align-end-vertical': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-align-end-vertical-icon lucide-align-end-vertical"><rect width="16" height="6" x="2" y="4" rx="2"/><rect width="9" height="6" x="9" y="14" rx="2"/><path d="M22 22V2"/></svg>',
17758
+ 'viewport': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-maximize-icon lucide-maximize"><path d="M8 3H5a2 2 0 0 0-2 2v3"/><path d="M21 8V5a2 2 0 0 0-2-2h-3"/><path d="M3 16v3a2 2 0 0 0 2 2h3"/><path d="M16 21h3a2 2 0 0 0 2-2v-3"/></svg>'
17757
17759
  });
17758
17760
 
17759
17761
  class KritzelCursorHelper {
@@ -17860,7 +17862,8 @@ class KritzelMoveHandler extends KritzelBaseHandler {
17860
17862
  if (event.pointerType === 'mouse') {
17861
17863
  if (KritzelEventHelper.isLeftClick(event)) {
17862
17864
  const selectionGroup = this._core.store.selectionGroup;
17863
- if (selectionGroup?.isSelected && !this._core.store.state.isResizeHandleSelected && !this._core.store.state.isRotationHandleSelected && !this._core.store.state.isLineHandleSelected) {
17865
+ const isAdditive = event.shiftKey || event.ctrlKey;
17866
+ if (selectionGroup?.isSelected && !this._core.store.state.isResizeHandleSelected && !this._core.store.state.isRotationHandleSelected && !this._core.store.state.isLineHandleSelected && !isAdditive) {
17864
17867
  const clientX = event.clientX - this._core.store.offsetX;
17865
17868
  const clientY = event.clientY - this._core.store.offsetY;
17866
17869
  this._core.store.state.isDragging = true;
@@ -17889,7 +17892,8 @@ class KritzelMoveHandler extends KritzelBaseHandler {
17889
17892
  return;
17890
17893
  }
17891
17894
  const selectionGroup = this._core.store.selectionGroup;
17892
- if (selectionGroup?.isSelected && !this._core.store.state.isResizeHandleSelected && !this._core.store.state.isRotationHandleSelected && !this._core.store.state.isLineHandleSelected) {
17895
+ const isAdditive = event.shiftKey || event.ctrlKey;
17896
+ if (selectionGroup?.isSelected && !this._core.store.state.isResizeHandleSelected && !this._core.store.state.isRotationHandleSelected && !this._core.store.state.isLineHandleSelected && !isAdditive) {
17893
17897
  const x = Math.round(activePointers[0].clientX - this._core.store.offsetX);
17894
17898
  const y = Math.round(activePointers[0].clientY - this._core.store.offsetY);
17895
17899
  this.dragStartX = x;
@@ -18402,15 +18406,16 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18402
18406
  super(core);
18403
18407
  }
18404
18408
  handlePointerDown(event) {
18409
+ const isAdditive = event.shiftKey || event.ctrlKey;
18405
18410
  if (event.pointerType === 'mouse') {
18406
- if (KritzelEventHelper.isLeftClick(event) && !this._core.store.selectionGroup) {
18407
- this.startMouseSelection(event);
18411
+ if (KritzelEventHelper.isLeftClick(event) && (!this._core.store.selectionGroup || isAdditive)) {
18412
+ this.startMouseSelection(event, isAdditive);
18408
18413
  }
18409
18414
  }
18410
18415
  if (event.pointerType === 'touch' || event.pointerType === 'pen') {
18411
18416
  this.touchStartTimeout = setTimeout(() => {
18412
- if (this._core.store.state.pointers.size === 1 && !this._core.store.state.isScaling && !this._core.store.selectionGroup) {
18413
- this.startTouchSelection();
18417
+ if (this._core.store.state.pointers.size === 1 && !this._core.store.state.isScaling && (!this._core.store.selectionGroup || isAdditive)) {
18418
+ this.startTouchSelection(event, isAdditive);
18414
18419
  this.updateTouchSelection();
18415
18420
  }
18416
18421
  }, 80);
@@ -18449,8 +18454,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18449
18454
  this.handleSelectionClick(event);
18450
18455
  }
18451
18456
  if (this.isSelectionDrag) {
18457
+ const isAdditive = event.shiftKey || event.ctrlKey;
18452
18458
  this.updateMouseSelection(event);
18453
- this.addSelectedObjectsToSelectionGroup();
18459
+ this.addSelectedObjectsToSelectionGroup(isAdditive);
18454
18460
  this.removeSelectionBox();
18455
18461
  }
18456
18462
  this._core.engine.emitObjectsChange();
@@ -18470,8 +18476,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18470
18476
  this.handleSelectionClick(event);
18471
18477
  }
18472
18478
  if (this.isSelectionDrag) {
18479
+ const isAdditive = event.shiftKey || event.ctrlKey;
18473
18480
  this.updateTouchSelection();
18474
- this.addSelectedObjectsToSelectionGroup();
18481
+ this.addSelectedObjectsToSelectionGroup(isAdditive);
18475
18482
  this.removeSelectionBox();
18476
18483
  }
18477
18484
  this._core.engine.emitObjectsChange();
@@ -18484,7 +18491,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18484
18491
  this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox);
18485
18492
  this._core.store.setSelectionBox(null);
18486
18493
  }
18487
- startMouseSelection(event) {
18494
+ startMouseSelection(event, isAdditive = false) {
18488
18495
  let clientX, clientY;
18489
18496
  clientX = event.clientX - this._core.store.offsetX;
18490
18497
  clientY = event.clientY - this._core.store.offsetY;
@@ -18494,13 +18501,15 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18494
18501
  selectionBox.translateX = this.startX;
18495
18502
  selectionBox.translateY = this.startY;
18496
18503
  this._core.store.state.isSelecting = true;
18497
- this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);
18504
+ this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup));
18498
18505
  this._core.store.setSelectionBox(null);
18499
- this._core.store.setSelectionGroup(null);
18506
+ if (!isAdditive) {
18507
+ this._core.store.setSelectionGroup(null);
18508
+ }
18500
18509
  this._core.store.state.objects.insert(selectionBox);
18501
18510
  this._core.store.setSelectionBox(selectionBox);
18502
18511
  }
18503
- startTouchSelection() {
18512
+ startTouchSelection(_event, isAdditive = false) {
18504
18513
  const activePointers = Array.from(this._core.store.state.pointers.values());
18505
18514
  const firstTouch = activePointers[0];
18506
18515
  if (!firstTouch) {
@@ -18517,9 +18526,11 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18517
18526
  selectionBox.translateX = this.startX;
18518
18527
  selectionBox.translateY = this.startY;
18519
18528
  this._core.store.state.isSelecting = true;
18520
- this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || o instanceof KritzelSelectionGroup);
18529
+ this._core.store.state.objects.remove(o => o instanceof KritzelSelectionBox || (!isAdditive && o instanceof KritzelSelectionGroup));
18521
18530
  this._core.store.setSelectionBox(null);
18522
- this._core.store.setSelectionGroup(null);
18531
+ if (!isAdditive) {
18532
+ this._core.store.setSelectionGroup(null);
18533
+ }
18523
18534
  this._core.store.state.objects.insert(selectionBox);
18524
18535
  this._core.store.setSelectionBox(selectionBox);
18525
18536
  }
@@ -18599,7 +18610,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18599
18610
  const newlySelectedObjects = new Set();
18600
18611
  // Only test candidates that overlap the bounding box
18601
18612
  for (const object of candidates) {
18602
- if (object instanceof KritzelSelectionBox)
18613
+ if (object instanceof KritzelSelectionBox || object instanceof KritzelSelectionGroup)
18603
18614
  continue;
18604
18615
  const isHit = object.hitTestPolygon(selectionPolygon);
18605
18616
  object.isSelected = isHit;
@@ -18618,8 +18629,9 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18618
18629
  }
18619
18630
  handleSelectionClick(event) {
18620
18631
  const selectedObject = this.getTopmostHitObject(event);
18632
+ const isAdditive = event.shiftKey || event.ctrlKey;
18621
18633
  this.clearSelectionPreview();
18622
- this.addObjectToSelectionGroup(selectedObject);
18634
+ this.addObjectToSelectionGroup(selectedObject, isAdditive);
18623
18635
  this.removeSelectionBox();
18624
18636
  }
18625
18637
  getTopmostHitObject(event) {
@@ -18627,7 +18639,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18627
18639
  const pointerY = this._core.store.state.pointerY;
18628
18640
  const overlappingObjects = this._core.getObjectsFromPointerEvent(event, '.object');
18629
18641
  for (const object of overlappingObjects) {
18630
- if (object instanceof KritzelSelectionBox)
18642
+ if (object instanceof KritzelSelectionBox || object instanceof KritzelSelectionGroup)
18631
18643
  continue;
18632
18644
  if (object.hitTest(pointerX, pointerY)) {
18633
18645
  return object;
@@ -18642,7 +18654,7 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18642
18654
  }
18643
18655
  this._previouslySelectedObjects.clear();
18644
18656
  }
18645
- addObjectToSelectionGroup(object) {
18657
+ addObjectToSelectionGroup(object, shiftKey = false) {
18646
18658
  if (!object) {
18647
18659
  return;
18648
18660
  }
@@ -18650,14 +18662,25 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18650
18662
  const parentGroup = KritzelGroup.findParentGroup(this._core, object.id);
18651
18663
  const objectToSelect = parentGroup || object;
18652
18664
  objectToSelect.isSelected = false;
18653
- const selectionGroup = KritzelSelectionGroup.create(this._core);
18654
- selectionGroup.addOrRemove(objectToSelect);
18655
- selectionGroup.isSelected = true;
18656
- selectionGroup.rotation = objectToSelect.rotation;
18657
- this._core.addSelectionGroup(selectionGroup);
18658
- this._core.rerender();
18665
+ const existingGroup = this._core.store.selectionGroup;
18666
+ if (shiftKey && existingGroup) {
18667
+ existingGroup.addOrRemove(objectToSelect);
18668
+ if (existingGroup.objects.length === 0) {
18669
+ this._core.removeSelectionGroup();
18670
+ }
18671
+ else {
18672
+ this._core.rerender();
18673
+ }
18674
+ }
18675
+ else {
18676
+ const selectionGroup = KritzelSelectionGroup.create(this._core);
18677
+ selectionGroup.addOrRemove(objectToSelect);
18678
+ selectionGroup.isSelected = true;
18679
+ this._core.addSelectionGroup(selectionGroup);
18680
+ this._core.rerender();
18681
+ }
18659
18682
  }
18660
- addSelectedObjectsToSelectionGroup() {
18683
+ addSelectedObjectsToSelectionGroup(shiftKey = false) {
18661
18684
  const selectedObjects = this._core.store.selectedObjects;
18662
18685
  if (selectedObjects.length === 0) {
18663
18686
  return;
@@ -18678,18 +18701,26 @@ class KritzelSelectionHandler extends KritzelBaseHandler {
18678
18701
  resolvedObjects.set(toSelect.id, toSelect);
18679
18702
  obj.isSelected = false;
18680
18703
  }
18681
- // Create selection group and set all IDs at once (no per-item refresh)
18682
- const selectionGroup = KritzelSelectionGroup.create(this._core);
18683
- selectionGroup.objectIds = Array.from(resolvedObjects.keys());
18684
- // Only refresh dimensions and capture snapshots ONCE at the end - O(n) instead of O(n²)
18685
- selectionGroup.captureUnchangedSnapshots();
18686
- selectionGroup.refreshObjectDimensions();
18687
- selectionGroup.isSelected = true;
18688
- if (selectionGroup.length === 1) {
18689
- selectionGroup.rotation = selectionGroup.objects[0].rotation;
18704
+ const unrolledObjects = Array.from(resolvedObjects.values());
18705
+ const existingGroup = this._core.store.selectionGroup;
18706
+ if (shiftKey && existingGroup) {
18707
+ existingGroup.addObjects(unrolledObjects);
18708
+ this._core.rerender();
18709
+ }
18710
+ else {
18711
+ // Create selection group and set all IDs at once (no per-item refresh)
18712
+ const selectionGroup = KritzelSelectionGroup.create(this._core);
18713
+ selectionGroup.objectIds = Array.from(resolvedObjects.keys());
18714
+ // Only refresh dimensions and capture snapshots ONCE at the end - O(n) instead of O(n²)
18715
+ if (selectionGroup.length === 1) {
18716
+ selectionGroup.rotation = selectionGroup.objects[0].rotation;
18717
+ }
18718
+ selectionGroup.captureUnchangedSnapshots();
18719
+ selectionGroup.refreshObjectDimensions();
18720
+ selectionGroup.isSelected = true;
18721
+ this._core.addSelectionGroup(selectionGroup);
18722
+ this._core.rerender();
18690
18723
  }
18691
- this._core.addSelectionGroup(selectionGroup);
18692
- this._core.rerender();
18693
18724
  }
18694
18725
  }
18695
18726
 
@@ -19732,11 +19763,13 @@ class KritzelSelectionTool extends KritzelBaseTool {
19732
19763
  const selectedObject = this.getSelectedObject(event);
19733
19764
  const selectionGroup = this._core.store.selectionGroup;
19734
19765
  const isDifferentObject = selectedObject && selectionGroup && selectedObject.id !== selectionGroup.id;
19766
+ const isAdditive = event.shiftKey || event.ctrlKey;
19735
19767
  if ((selectedObject === null || isDifferentObject) &&
19736
19768
  selectionGroup &&
19737
19769
  !this._core.store.state.isResizeHandleSelected &&
19738
19770
  !this._core.store.state.isRotationHandleSelected &&
19739
- !this._core.store.state.isLineHandleSelected) {
19771
+ !this._core.store.state.isLineHandleSelected &&
19772
+ !isAdditive) {
19740
19773
  this._core.removeSelectionGroup();
19741
19774
  this._core.rerender();
19742
19775
  }
@@ -19764,6 +19797,7 @@ class KritzelSelectionTool extends KritzelBaseTool {
19764
19797
  const selectedObject = this.getSelectedObject(event);
19765
19798
  const selectionGroup = this._core.store.selectionGroup;
19766
19799
  const isDifferentObject = selectedObject && selectionGroup && selectedObject.id !== selectionGroup.id;
19800
+ const isAdditive = event.shiftKey || event.ctrlKey;
19767
19801
  if (!selectionGroup && selectedObject) {
19768
19802
  this._core.store.state.skipContextMenu = true;
19769
19803
  }
@@ -19771,7 +19805,8 @@ class KritzelSelectionTool extends KritzelBaseTool {
19771
19805
  selectionGroup &&
19772
19806
  !this._core.store.state.isResizeHandleSelected &&
19773
19807
  !this._core.store.state.isRotationHandleSelected &&
19774
- !this._core.store.state.isLineHandleSelected) {
19808
+ !this._core.store.state.isLineHandleSelected &&
19809
+ !isAdditive) {
19775
19810
  this._core.removeSelectionGroup();
19776
19811
  this._core.rerender();
19777
19812
  }
@@ -37321,6 +37356,16 @@ const DEFAULT_LINE_TOOL_CONFIG = {
37321
37356
  },
37322
37357
  };
37323
37358
 
37359
+ exports.KritzelAlignment = void 0;
37360
+ (function (KritzelAlignment) {
37361
+ KritzelAlignment["StartHorizontal"] = "start-horizontal";
37362
+ KritzelAlignment["CenterHorizontal"] = "center-horizontal";
37363
+ KritzelAlignment["EndHorizontal"] = "end-horizontal";
37364
+ KritzelAlignment["StartVertical"] = "start-vertical";
37365
+ KritzelAlignment["CenterVertical"] = "center-vertical";
37366
+ KritzelAlignment["EndVertical"] = "end-vertical";
37367
+ })(exports.KritzelAlignment || (exports.KritzelAlignment = {}));
37368
+
37324
37369
  exports.DEFAULT_BRUSH_CONFIG = DEFAULT_BRUSH_CONFIG;
37325
37370
  exports.DEFAULT_COLOR_PALETTE = DEFAULT_COLOR_PALETTE;
37326
37371
  exports.DEFAULT_LINE_TOOL_CONFIG = DEFAULT_LINE_TOOL_CONFIG;
@@ -22,7 +22,7 @@ const NAMESPACE = 'stencil';
22
22
  const BUILD = /* stencil */ { hotModuleReplacement: false, hydratedSelectorName: "hydrated", lazyLoad: true, propChangeCallback: true, state: true, updatable: true};
23
23
 
24
24
  /*
25
- Stencil Client Platform v4.43.0 | MIT Licensed | https://stenciljs.com
25
+ Stencil Client Platform v4.43.1 | MIT Licensed | https://stenciljs.com
26
26
  */
27
27
 
28
28
 
@@ -332,7 +332,7 @@ var addStyle = (styleContainerNode, cmpMeta, mode) => {
332
332
  }
333
333
  } else {
334
334
  const existingStyleContainer = styleContainerNode.querySelector("style");
335
- if (existingStyleContainer) {
335
+ if (existingStyleContainer && true) {
336
336
  existingStyleContainer.textContent = style + existingStyleContainer.textContent;
337
337
  } else {
338
338
  styleContainerNode.prepend(styleElm);