kritzel-stencil 0.1.21 → 0.1.22

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 (32) hide show
  1. package/dist/cjs/{default-line-tool.config-Bva9deYM.js → default-line-tool.config-DSutud0N.js} +22 -6
  2. package/dist/cjs/index.cjs.js +1 -1
  3. package/dist/cjs/kritzel-back-to-content_32.cjs.entry.js +39 -49
  4. package/dist/collection/classes/objects/text.class.js +19 -3
  5. package/dist/collection/classes/tools/text-tool.class.js +3 -3
  6. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +20 -34
  7. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +17 -13
  8. package/dist/collection/constants/version.js +1 -1
  9. package/dist/components/index.js +1 -1
  10. package/dist/components/kritzel-controls.js +1 -1
  11. package/dist/components/kritzel-editor.js +1 -1
  12. package/dist/components/kritzel-engine.js +1 -1
  13. package/dist/components/kritzel-settings.js +1 -1
  14. package/dist/components/kritzel-tool-config.js +1 -1
  15. package/dist/components/p-B6WmB4Lk.js +1 -0
  16. package/dist/components/{p-CYX7RMRZ.js → p-BAVx6TLg.js} +1 -1
  17. package/dist/components/{p-Dmy0R-7y.js → p-BP6ggkYA.js} +1 -1
  18. package/dist/components/{p-BbHELXEC.js → p-CEHVU-Ri.js} +2 -2
  19. package/dist/components/{p-BsvZ2juR.js → p-DBUd8DTC.js} +1 -1
  20. package/dist/esm/{default-line-tool.config-DDIFE6oX.js → default-line-tool.config-_PqPRv7q.js} +22 -6
  21. package/dist/esm/index.js +2 -2
  22. package/dist/esm/kritzel-back-to-content_32.entry.js +39 -49
  23. package/dist/stencil/index.esm.js +1 -1
  24. package/dist/stencil/p-0472bdc3.entry.js +9 -0
  25. package/dist/stencil/p-_PqPRv7q.js +1 -0
  26. package/dist/stencil/stencil.esm.js +1 -1
  27. package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +1 -0
  28. package/dist/types/constants/version.d.ts +1 -1
  29. package/package.json +1 -1
  30. package/dist/components/p-DqtvAhfs.js +0 -1
  31. package/dist/stencil/p-3fc743ee.entry.js +0 -9
  32. package/dist/stencil/p-DDIFE6oX.js +0 -1
@@ -1 +1 @@
1
- import{p as e,H as t,c as s,h as i,d as l,t as n}from"./p-Cj-I2_Og.js";import{d as a}from"./p-CTQmvTXG.js";import{d as o}from"./p-Cpb-fnoO.js";import{d as r}from"./p-DKNtjoqf.js";import{d as c}from"./p-n0XDtwWP.js";import{d as g}from"./p-RU06uu0S.js";const d="kritzel-settings",h=[{id:"general",label:"General",icon:"settings"},{id:"about",label:"About",icon:"info"}],m=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.settingsChange=s(this,"settingsChange")}get host(){return this}isDialogOpen=!1;selectedCategoryId=h[0].id;scaleMin=1e-4;scaleMax=1e3;lockDrawingScale=!0;currentTheme="light";settingsChange;componentWillLoad(){this.loadSettings()}loadSettings(){const e=localStorage.getItem(d);if(e)try{const t=JSON.parse(e);"number"==typeof t.scaleMin&&(this.scaleMin=t.scaleMin),"number"==typeof t.scaleMax&&(this.scaleMax=t.scaleMax),"boolean"==typeof t.lockDrawingScale&&(this.lockDrawingScale=t.lockDrawingScale),"light"!==t.theme&&"dark"!==t.theme||(this.currentTheme=t.theme)}catch{}}saveSettings(){const e={scaleMin:this.scaleMin,scaleMax:this.scaleMax,lockDrawingScale:this.lockDrawingScale,theme:this.currentTheme};localStorage.setItem(d,JSON.stringify(e)),this.settingsChange.emit(e)}handleScaleMinChange=e=>{this.scaleMin=e.detail,this.saveSettings()};handleScaleMaxChange=e=>{this.scaleMax=e.detail,this.saveSettings()};handleLockDrawingScaleChange=e=>{this.lockDrawingScale=e.detail,this.saveSettings()};handleThemeChange=e=>{this.currentTheme=e.detail?"dark":"light",this.saveSettings()};async open(){this.isDialogOpen=!0}closeDialog=()=>{this.isDialogOpen=!1};handleCategorySelect=e=>{this.selectedCategoryId=e.detail.item.id};renderCategoryContent(){switch(this.selectedCategoryId){case"general":return i("div",{class:"settings-content"},i("h3",null,"General Settings"),i("div",{class:"settings-group"},i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Dark Mode"),i("p",{class:"settings-description"},"Toggle between light and dark color themes for the editor interface."),i("kritzel-slide-toggle",{checked:"dark"===this.currentTheme,label:"Dark Mode",onCheckedChange:this.handleThemeChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Lock Drawing Scale"),i("p",{class:"settings-description"},"When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level."),i("kritzel-slide-toggle",{checked:this.lockDrawingScale,label:"Lock Drawing Scale",onCheckedChange:this.handleLockDrawingScaleChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Minimum Zoom Level"),i("p",{class:"settings-description"},"Sets the minimum zoom level. Lower values allow zooming out further to see more of the canvas."),i("kritzel-numeric-input",{value:this.scaleMin,min:1e-4,max:1,step:1e-4,onValueChange:this.handleScaleMinChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Maximum Zoom Level"),i("p",{class:"settings-description"},"Sets the maximum zoom level. Higher values allow zooming in closer for detailed work."),i("kritzel-numeric-input",{value:this.scaleMax,min:1,max:1e3,step:1,onValueChange:this.handleScaleMaxChange}))));case"about":return i("div",{class:"settings-content"},i("h3",null,"About"),i("p",null,"Kritzel - A drawing application"),i("p",{class:"version-info"},"Version ","0.1.21"));default:return null}}render(){return i(l,{key:"6e43b90b2c3031811856bda112df13d2e2bf5904"},i("kritzel-dialog",{key:"d84df729050fbf12033441cd8373cbea3068958a",isOpen:this.isDialogOpen,dialogTitle:"Settings",size:"large",onDialogClose:this.closeDialog},i("kritzel-master-detail",{key:"6c9ff2fab8a1d071b0f22bc04576780ed80ecc30",items:h,selectedItemId:this.selectedCategoryId,onItemSelect:this.handleCategorySelect},this.renderCategoryContent())))}static get style(){return":host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:500;color:var(--kritzel-settings-label-color, #333333);margin:0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}"}},[513,"kritzel-settings",{isDialogOpen:[32],selectedCategoryId:[32],scaleMin:[32],scaleMax:[32],lockDrawingScale:[32],currentTheme:[32],open:[64]}]);function p(){"undefined"!=typeof customElements&&["kritzel-settings","kritzel-dialog","kritzel-icon","kritzel-master-detail","kritzel-numeric-input","kritzel-slide-toggle"].forEach((e=>{switch(e){case"kritzel-settings":customElements.get(n(e))||customElements.define(n(e),m);break;case"kritzel-dialog":customElements.get(n(e))||a();break;case"kritzel-icon":customElements.get(n(e))||o();break;case"kritzel-master-detail":customElements.get(n(e))||r();break;case"kritzel-numeric-input":customElements.get(n(e))||c();break;case"kritzel-slide-toggle":customElements.get(n(e))||g()}}))}export{m as K,p as d}
1
+ import{p as e,H as t,c as s,h as i,d as l,t as n}from"./p-Cj-I2_Og.js";import{d as a}from"./p-CTQmvTXG.js";import{d as o}from"./p-Cpb-fnoO.js";import{d as r}from"./p-DKNtjoqf.js";import{d as c}from"./p-n0XDtwWP.js";import{d as g}from"./p-RU06uu0S.js";const d="kritzel-settings",h=[{id:"general",label:"General",icon:"settings"},{id:"about",label:"About",icon:"info"}],m=e(class extends t{constructor(e){super(),!1!==e&&this.__registerHost(),this.__attachShadow(),this.settingsChange=s(this,"settingsChange")}get host(){return this}isDialogOpen=!1;selectedCategoryId=h[0].id;scaleMin=1e-4;scaleMax=1e3;lockDrawingScale=!0;currentTheme="light";settingsChange;componentWillLoad(){this.loadSettings()}loadSettings(){const e=localStorage.getItem(d);if(e)try{const t=JSON.parse(e);"number"==typeof t.scaleMin&&(this.scaleMin=t.scaleMin),"number"==typeof t.scaleMax&&(this.scaleMax=t.scaleMax),"boolean"==typeof t.lockDrawingScale&&(this.lockDrawingScale=t.lockDrawingScale),"light"!==t.theme&&"dark"!==t.theme||(this.currentTheme=t.theme)}catch{}}saveSettings(){const e={scaleMin:this.scaleMin,scaleMax:this.scaleMax,lockDrawingScale:this.lockDrawingScale,theme:this.currentTheme};localStorage.setItem(d,JSON.stringify(e)),this.settingsChange.emit(e)}handleScaleMinChange=e=>{this.scaleMin=e.detail,this.saveSettings()};handleScaleMaxChange=e=>{this.scaleMax=e.detail,this.saveSettings()};handleLockDrawingScaleChange=e=>{this.lockDrawingScale=e.detail,this.saveSettings()};handleThemeChange=e=>{this.currentTheme=e.detail?"dark":"light",this.saveSettings()};async open(){this.isDialogOpen=!0}closeDialog=()=>{this.isDialogOpen=!1};handleCategorySelect=e=>{this.selectedCategoryId=e.detail.item.id};renderCategoryContent(){switch(this.selectedCategoryId){case"general":return i("div",{class:"settings-content"},i("h3",null,"General Settings"),i("div",{class:"settings-group"},i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Dark Mode"),i("p",{class:"settings-description"},"Toggle between light and dark color themes for the editor interface."),i("kritzel-slide-toggle",{checked:"dark"===this.currentTheme,label:"Dark Mode",onCheckedChange:this.handleThemeChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Lock Drawing Scale"),i("p",{class:"settings-description"},"When enabled, drawn objects maintain a fixed visual size regardless of the current zoom level."),i("kritzel-slide-toggle",{checked:this.lockDrawingScale,label:"Lock Drawing Scale",onCheckedChange:this.handleLockDrawingScaleChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Minimum Zoom Level"),i("p",{class:"settings-description"},"Sets the minimum zoom level. Lower values allow zooming out further to see more of the canvas."),i("kritzel-numeric-input",{value:this.scaleMin,min:1e-4,max:1,step:1e-4,onValueChange:this.handleScaleMinChange})),i("div",{class:"settings-item"},i("label",{class:"settings-label"},"Maximum Zoom Level"),i("p",{class:"settings-description"},"Sets the maximum zoom level. Higher values allow zooming in closer for detailed work."),i("kritzel-numeric-input",{value:this.scaleMax,min:1,max:1e3,step:1,onValueChange:this.handleScaleMaxChange}))));case"about":return i("div",{class:"settings-content"},i("h3",null,"About"),i("p",null,"Kritzel - A drawing application"),i("p",{class:"version-info"},"Version ","0.1.22"));default:return null}}render(){return i(l,{key:"6e43b90b2c3031811856bda112df13d2e2bf5904"},i("kritzel-dialog",{key:"d84df729050fbf12033441cd8373cbea3068958a",isOpen:this.isDialogOpen,dialogTitle:"Settings",size:"large",onDialogClose:this.closeDialog},i("kritzel-master-detail",{key:"6c9ff2fab8a1d071b0f22bc04576780ed80ecc30",items:h,selectedItemId:this.selectedCategoryId,onItemSelect:this.handleCategorySelect},this.renderCategoryContent())))}static get style(){return":host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:500;color:var(--kritzel-settings-label-color, #333333);margin:0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}"}},[513,"kritzel-settings",{isDialogOpen:[32],selectedCategoryId:[32],scaleMin:[32],scaleMax:[32],lockDrawingScale:[32],currentTheme:[32],open:[64]}]);function p(){"undefined"!=typeof customElements&&["kritzel-settings","kritzel-dialog","kritzel-icon","kritzel-master-detail","kritzel-numeric-input","kritzel-slide-toggle"].forEach((e=>{switch(e){case"kritzel-settings":customElements.get(n(e))||customElements.define(n(e),m);break;case"kritzel-dialog":customElements.get(n(e))||a();break;case"kritzel-icon":customElements.get(n(e))||o();break;case"kritzel-master-detail":customElements.get(n(e))||r();break;case"kritzel-numeric-input":customElements.get(n(e))||c();break;case"kritzel-slide-toggle":customElements.get(n(e))||g()}}))}export{m as K,p as d}
@@ -14967,7 +14967,7 @@ class KritzelText extends KritzelBaseObject {
14967
14967
  focus(coords) {
14968
14968
  if (this.editor) {
14969
14969
  const doc = this.editor.state.doc;
14970
- if (coords.x && coords.y) {
14970
+ if (coords.x && coords.y && !this.isEmpty) {
14971
14971
  const pos = this.editor.posAtCoords({ left: coords.x, top: coords.y });
14972
14972
  if (pos) {
14973
14973
  this.editor.dispatch(this.editor.state.tr.setSelection(TextSelection.create(doc, pos.pos)));
@@ -15028,13 +15028,29 @@ class KritzelText extends KritzelBaseObject {
15028
15028
  if (!this.isEditing) {
15029
15029
  return;
15030
15030
  }
15031
- event.stopPropagation();
15031
+ // Only stop propagation if the engine is not tracking this pointer.
15032
+ // During text creation, the engine adds the pointer before the text element
15033
+ // is in the DOM. We must let move events propagate so the engine can
15034
+ // update its pointer state.
15035
+ if (!this._core.store.state.pointers.has(event.pointerId)) {
15036
+ event.stopPropagation();
15037
+ }
15032
15038
  }
15033
15039
  handlePointerUp(event) {
15034
15040
  if (!this.isEditing) {
15035
15041
  return;
15036
15042
  }
15037
- event.stopPropagation();
15043
+ // Only stop propagation if the engine is not tracking this pointer.
15044
+ // When a text is created during pointerdown, the engine adds the pointer
15045
+ // to its map before the text element exists in the DOM. By the time
15046
+ // pointerup fires, the text element may intercept the event (especially
15047
+ // on iOS where pointer capture may not redirect events in shadow DOM).
15048
+ // We must let the event propagate so the engine can clean up the pointer.
15049
+ // Without this, stale pointers accumulate and single-finger touches
15050
+ // get misinterpreted as two-finger zoom gestures.
15051
+ if (!this._core.store.state.pointers.has(event.pointerId)) {
15052
+ event.stopPropagation();
15053
+ }
15038
15054
  }
15039
15055
  copy() {
15040
15056
  const copiedObject = super.copy();
@@ -17571,10 +17587,10 @@ class KritzelTextTool extends KritzelBaseTool {
17571
17587
  }
17572
17588
  }
17573
17589
  handlePointerUp(event) {
17574
- if (event.cancelable) {
17575
- event.preventDefault();
17590
+ const activeText = this._core.store.activeText;
17591
+ if (activeText && activeText.isMounted && !activeText.editor?.hasFocus()) {
17592
+ activeText.focus({ x: event.clientX, y: event.clientY });
17576
17593
  }
17577
- this._core.store.activeText?.edit(event);
17578
17594
  }
17579
17595
  }
17580
17596
 
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { w as writeVarUint, a as writeVarUint8Array, t as toUint8Array, r as readVarUint, b as readVarUint8Array, e as encodeStateAsUpdate, c as applyUpdate, d as encodeStateVector, f as createEncoder, g as createDecoder, s as setIfUndefined, h as create, i as fromBase64, v as varStorage, j as toBase64, o as onChange, k as createUint8ArrayFromArrayBuffer, l as offChange, m as readVarString, O as Observable, n as floor, p as getUnixTime, q as equalityDeep, u as writeVarString, x as map, y as ObservableV2, z as length, A as isNode, B as min, C as pow, H as HocuspocusProvider, D as HocuspocusProviderWebsocket } from './default-line-tool.config-DDIFE6oX.js';
2
- export { W as DEFAULT_BRUSH_CONFIG, Y as DEFAULT_LINE_TOOL_CONFIG, X as DEFAULT_TEXT_CONFIG, S as IndexedDBSyncProvider, V as KritzelAnchorManager, T as KritzelAppStateMap, J as KritzelBrushTool, Q as KritzelCursorHelper, M as KritzelEraserTool, I as KritzelGroup, F as KritzelImage, N as KritzelImageTool, G as KritzelLine, L as KritzelLineTool, E as KritzelPath, R as KritzelSelectionTool, K as KritzelText, P as KritzelTextTool, $ as KritzelThemeManager, U as KritzelWorkspace, _ as darkTheme, Z as lightTheme } from './default-line-tool.config-DDIFE6oX.js';
1
+ import { w as writeVarUint, a as writeVarUint8Array, t as toUint8Array, r as readVarUint, b as readVarUint8Array, e as encodeStateAsUpdate, c as applyUpdate, d as encodeStateVector, f as createEncoder, g as createDecoder, s as setIfUndefined, h as create, i as fromBase64, v as varStorage, j as toBase64, o as onChange, k as createUint8ArrayFromArrayBuffer, l as offChange, m as readVarString, O as Observable, n as floor, p as getUnixTime, q as equalityDeep, u as writeVarString, x as map, y as ObservableV2, z as length, A as isNode, B as min, C as pow, H as HocuspocusProvider, D as HocuspocusProviderWebsocket } from './default-line-tool.config-_PqPRv7q.js';
2
+ export { W as DEFAULT_BRUSH_CONFIG, Y as DEFAULT_LINE_TOOL_CONFIG, X as DEFAULT_TEXT_CONFIG, S as IndexedDBSyncProvider, V as KritzelAnchorManager, T as KritzelAppStateMap, J as KritzelBrushTool, Q as KritzelCursorHelper, M as KritzelEraserTool, I as KritzelGroup, F as KritzelImage, N as KritzelImageTool, G as KritzelLine, L as KritzelLineTool, E as KritzelPath, R as KritzelSelectionTool, K as KritzelText, P as KritzelTextTool, $ as KritzelThemeManager, U as KritzelWorkspace, _ as darkTheme, Z as lightTheme } from './default-line-tool.config-_PqPRv7q.js';
3
3
 
4
4
  /**
5
5
  * BroadcastChannel sync provider for cross-tab synchronization
@@ -1,5 +1,5 @@
1
1
  import { r as registerInstance, c as createEvent, h, H as Host, g as getElement } from './index-k35gVcuU.js';
2
- import { a0 as KritzelColorHelper, a1 as KritzelBaseTool, a2 as ShapeType, a3 as DEFAULT_COLOR_PALETTE, a4 as KritzelShape, a5 as KritzelToolRegistry, a6 as KritzelEventHelper, R as KritzelSelectionTool, J as KritzelBrushTool, L as KritzelLineTool, P as KritzelTextTool, a7 as KritzelDevicesHelper, a8 as KritzelMouseButton, W as DEFAULT_BRUSH_CONFIG, Y as DEFAULT_LINE_TOOL_CONFIG, M as KritzelEraserTool, X as DEFAULT_TEXT_CONFIG, N as KritzelImageTool, U as KritzelWorkspace, a9 as KritzelIconRegistry, aa as KritzelKeyboardHelper, ab as KritzelSelectionBox, ac as KritzelBaseHandler, ad as KritzelSelectionGroup, ae as KritzelBaseObject, I as KritzelGroup, F as KritzelImage, K as KritzelText, G as KritzelLine, E as KritzelPath, af as Doc, ag as DEFAULT_SYNC_CONFIG, ah as UndoManager, Q as KritzelCursorHelper, T as KritzelAppStateMap, V as KritzelAnchorManager, $ as KritzelThemeManager, ai as ObjectHelper, aj as KritzelClassHelper } from './default-line-tool.config-DDIFE6oX.js';
2
+ import { a0 as KritzelColorHelper, a1 as KritzelBaseTool, a2 as ShapeType, a3 as DEFAULT_COLOR_PALETTE, a4 as KritzelShape, a5 as KritzelToolRegistry, a6 as KritzelEventHelper, R as KritzelSelectionTool, J as KritzelBrushTool, L as KritzelLineTool, P as KritzelTextTool, a7 as KritzelDevicesHelper, a8 as KritzelMouseButton, W as DEFAULT_BRUSH_CONFIG, Y as DEFAULT_LINE_TOOL_CONFIG, M as KritzelEraserTool, X as DEFAULT_TEXT_CONFIG, N as KritzelImageTool, U as KritzelWorkspace, a9 as KritzelIconRegistry, aa as KritzelKeyboardHelper, ab as KritzelSelectionBox, ac as KritzelBaseHandler, ad as KritzelSelectionGroup, ae as KritzelBaseObject, I as KritzelGroup, F as KritzelImage, K as KritzelText, G as KritzelLine, E as KritzelPath, af as Doc, ag as DEFAULT_SYNC_CONFIG, ah as UndoManager, Q as KritzelCursorHelper, T as KritzelAppStateMap, V as KritzelAnchorManager, $ as KritzelThemeManager, ai as ObjectHelper, aj as KritzelClassHelper } from './default-line-tool.config-_PqPRv7q.js';
3
3
 
4
4
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5
5
 
@@ -630,14 +630,23 @@ const KritzelControls = class {
630
630
  componentDidLoad() {
631
631
  this.updateScrollIndicators();
632
632
  }
633
+ componentDidRender() {
634
+ this.updateScrollIndicators();
635
+ }
633
636
  updateScrollIndicators() {
634
637
  if (!this.toolsScrollRef)
635
638
  return;
636
639
  const { scrollLeft, scrollWidth, clientWidth } = this.toolsScrollRef;
637
640
  const threshold = 2; // Small threshold to account for rounding
638
- this.canScrollLeft = scrollLeft > threshold;
639
- this.canScrollRight = scrollLeft + clientWidth < scrollWidth - threshold;
640
- this.needsScrolling = scrollWidth > clientWidth;
641
+ const canScrollLeft = scrollLeft > threshold;
642
+ const canScrollRight = scrollLeft + clientWidth < scrollWidth - threshold;
643
+ const needsScrolling = scrollWidth > clientWidth;
644
+ if (this.canScrollLeft !== canScrollLeft)
645
+ this.canScrollLeft = canScrollLeft;
646
+ if (this.canScrollRight !== canScrollRight)
647
+ this.canScrollRight = canScrollRight;
648
+ if (this.needsScrolling !== needsScrolling)
649
+ this.needsScrolling = needsScrolling;
641
650
  }
642
651
  handleToolsScroll = () => {
643
652
  this.updateScrollIndicators();
@@ -737,18 +746,13 @@ const KritzelControls = class {
737
746
  // Separate tool controls from config control
738
747
  const toolControls = this.controls.filter(c => c.type === 'tool');
739
748
  const configControl = this.controls.find(c => c.type === 'config' && c.name === this.firstConfig?.name);
740
- return (h(Host, { key: 'cb713bc59241300837519145031c1d15109e28c3', class: {
749
+ return (h(Host, { key: '7e6687a1c3aa5da1a3f70f93fbc31ff27071a5d8', class: {
741
750
  mobile: this.isTouchDevice,
742
- } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '62cb00da2676739aa472d69e8e453501bd78e408', style: {
751
+ } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: 'ba600940a33609b8150aacf5a63a781c06d9d9fe', style: {
743
752
  position: 'absolute',
744
753
  bottom: '56px',
745
754
  left: '12px',
746
- }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '0376615eb976d961cb17ba02aab36f4127343899', class: "kritzel-controls" }, h("div", { key: 'c72373afc1eb04fb39868d107cb0a35c846097fe', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), h("div", { key: '1aa1ece36dda200a4c62529c08f1787d8bd4b534', class: "kritzel-tools-scroll", ref: el => {
747
- this.toolsScrollRef = el;
748
- // Update indicators when ref is set
749
- if (el)
750
- this.updateScrollIndicators();
751
- }, onScroll: this.handleToolsScroll }, toolControls.map(control => {
755
+ }, undoState: this.undoState, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '6c31fb4ccf4c1022426847d0b3684f6dd54c6cbf', class: "kritzel-controls" }, h("div", { key: 'aad8c170278b0d46bef5a9e94546dec502b179db', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), h("div", { key: '7652a3ed5536f845899481ef98540ed6c09a31d5', class: "kritzel-tools-scroll", ref: el => this.toolsScrollRef = el, onScroll: this.handleToolsScroll }, toolControls.map(control => {
752
756
  // Check if this control has sub-options (split-button)
753
757
  if (control.subOptions?.length) {
754
758
  const selectedSubOption = this.getSelectedSubOption(control);
@@ -773,10 +777,10 @@ const KritzelControls = class {
773
777
  'kritzel-control': true,
774
778
  'selected': this.activeControl?.name === control?.name,
775
779
  }, key: control.name, onClick: _event => this.handleControlClick?.(control) }, h("kritzel-icon", { name: control.icon })));
776
- })), h("div", { key: 'a3129881a9c992b6fbd94b66a6325d46072dba60', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (h("div", { class: {
780
+ })), h("div", { key: 'f1dd9f702185a32004fecf48798f5767e20c99e7', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (h("div", { class: {
777
781
  'kritzel-config-container': true,
778
782
  'visible': hasConfigUI,
779
- }, key: configControl.name }, h("div", { key: '57de6641291894b0e507e90987ea94a9103c25ca', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), h("kritzel-tooltip", { key: '182317753d162abe9c804a4757ed19505bb3b487', ref: el => (this.tooltipRef = el), isVisible: this.isTooltipVisible, anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), onTooltipClosed: () => this.handleTooltipClosed() }, h("kritzel-tool-config", { key: '13ecc34147d44b2bb12eb0008eec179db55f5840', tool: this.activeControl.tool, theme: this.theme, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), h("div", { key: 'bc4053cf9feb69c2962fe5a86cd7cf811b03e971', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", onClick: event => this.handleConfigClick?.(event), onKeyDown: event => {
783
+ }, key: configControl.name }, h("div", { key: 'ad44b915f2ebe292fa8f17de771e637b22089396', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), h("kritzel-tooltip", { key: '9e750ed1f0e37f4a07bb99446effdc1fe7d2d7ce', ref: el => (this.tooltipRef = el), isVisible: this.isTooltipVisible, anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), onTooltipClosed: () => this.handleTooltipClosed() }, h("kritzel-tool-config", { key: '4f87a184a3b395368c94752e5fedcf66164f0baa', tool: this.activeControl.tool, theme: this.theme, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), h("div", { key: '37cb99e360419fe35820e9de8ac042f44b71e496', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", onClick: event => this.handleConfigClick?.(event), onKeyDown: event => {
780
784
  if (event.key === 'Enter') {
781
785
  this.handleConfigClick?.(event);
782
786
  }
@@ -22031,7 +22035,9 @@ const KritzelEngine = class {
22031
22035
  return;
22032
22036
  }
22033
22037
  this.core.store.state.pointers.delete(ev.pointerId);
22034
- this.host.releasePointerCapture(ev.pointerId);
22038
+ if (this.host.hasPointerCapture(ev.pointerId)) {
22039
+ this.host.releasePointerCapture(ev.pointerId);
22040
+ }
22035
22041
  // Reset cursor to default when all pointers are released
22036
22042
  if (this.core.store.state.pointers.size === 0) {
22037
22043
  this.core.cursorManager.resetToDefault();
@@ -22043,7 +22049,9 @@ const KritzelEngine = class {
22043
22049
  if (this.core.store.isDisabled) {
22044
22050
  return;
22045
22051
  }
22046
- this.host.releasePointerCapture(ev.pointerId);
22052
+ if (this.host.hasPointerCapture(ev.pointerId)) {
22053
+ this.host.releasePointerCapture(ev.pointerId);
22054
+ }
22047
22055
  this.core.store.state.pointers.delete(ev.pointerId);
22048
22056
  // Reset cursor to default when all pointers are released
22049
22057
  if (this.core.store.state.pointers.size === 0) {
@@ -22421,7 +22429,7 @@ const KritzelEngine = class {
22421
22429
  if (this.core.store.totalObjectCount > 0) {
22422
22430
  this.objectsInViewportChange.emit(visibleObjects);
22423
22431
  }
22424
- return (h(Host, { key: '26d2ef50f28fb809d046b60dff6e977dec53fc8c' }, this.core.store.state.debugInfo.showViewportInfo && (h("div", { key: 'bbacc63967672c6934d1c90913139f1f96e532cb', class: "debug-panel" }, h("div", { key: '59d46ef1a1a8dffe7b1bd97b0df3c77fdd095d97' }, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", { key: 'd6bc9b3c6076540ccfec4fd2ef3b3e2edf08d524' }, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", { key: '12e229d893933a01bbfdd038e1bd14eee198b34e' }, "TranslateX: ", this.core.store.state?.translateX), h("div", { key: '9caf69c342d545a478bb4945aa7b2c37ea77561f' }, "TranslateY: ", this.core.store.state?.translateY), h("div", { key: '123f6b17777475f4de32872b940abd3b7ffe6d78' }, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", { key: '463c70e208dad8572317bbde0df0f4b149674a7d' }, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", { key: '82deb6d97ae66c86431b32582114f81bcd83e5ae' }, "PointerCount: ", this.core.store.state.pointers.size), h("div", { key: 'be32ffe65da2fc92f556ac037afa5b50c27cedd2' }, "Scale: ", this.core.store.state?.scale), h("div", { key: '53029e75a8972f670ef0fa427549415fd8be7986' }, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", { key: '27517882d278f0df7df59858a9219d356e5bbd8d' }, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", { key: '616611f9ad570741c9be3eabd0c78dc978c16c4f' }, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", { key: '318a17d0b0d7eb2a58233c76063cc72e87782f1b' }, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", { key: '45c92f5cc524338b5c0cab5f5123faf0296e7484' }, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", { key: '4b295ddaf8eb9e49547430c839a9ba50daacd42e' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: 'eef9039260d0f1ffa23102aee0f18ebd90111738' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: '1a22a4a93ddab249532fe40640f1fa7bbb485d76' }, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: '094daef63fffab66051e1c65392baac58d8f3eca' }, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: 'dae17ba3dec0ededdfb873eda4081fb51cea0c52' }, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", { key: '11b4c3fb7fef201e6a98a58f586e1c717f255af4' }, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", { key: 'ac7b98f441747b90f047069b9e7eac2ac5194eec' }, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", { key: 'eb2285428d88835319c68ff26cb99e1e631cba82' }, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", { key: 'd32cb23e569a84b16a50b98d2e3d778c6462c88c' }, "PointerX: ", this.core.store.state?.pointerX), h("div", { key: '0b4fafde05bb83d4046b103015a4f008c5b268d8' }, "PointerY: ", this.core.store.state?.pointerY), h("div", { key: '0083eb1e81cd1d0552e0fa2d6cca147e14e0bd86' }, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", { key: '232f452fd89d22db9e4aaf8e6d3b672f934422a5' }, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { key: '66a0d3a6ac62153acf6ed1b7c57b3ae77daa3c5e', id: "origin", class: "origin", style: {
22432
+ return (h(Host, { key: '6cc974d4e3fdcfe1b185a014fa9eb6b1243dde91' }, this.core.store.state.debugInfo.showViewportInfo && (h("div", { key: '8f8ac08f2d643b664e2b39fbaf50e0c474c5255d', class: "debug-panel" }, h("div", { key: '79ad4f3db958d8b17b2efdb3a1a6ab24d81bb436' }, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", { key: '0cdaa6abeebc865eec1c3026d5fd38e00bd388a7' }, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", { key: '125ca4bb69ca2fcc647bd55e9cb8c4072fbaa600' }, "TranslateX: ", this.core.store.state?.translateX), h("div", { key: '02aee9b8359b9cdefa2f54afc26d328dab984ea3' }, "TranslateY: ", this.core.store.state?.translateY), h("div", { key: '8398e28a5c70318dace386182633088e5e3267d5' }, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", { key: '0e17a7fbf96acbe1cbf2769b0fa853eaf7fb6f3b' }, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", { key: 'd214e66618d2c38ca94154e7b06f681d815ffadc' }, "PointerCount: ", this.core.store.state.pointers.size), h("div", { key: '35695f7f82605bf6ba0fd512f814a7da723f623c' }, "Scale: ", this.core.store.state?.scale), h("div", { key: '6935c9e5cedb8f7bd6d81a5d02b383fbb0e4d3a2' }, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", { key: '6a7490a07ca3019157d6a4b10b9164d3a504c4c0' }, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", { key: 'ba70d5d01cad9e0fb6e80a4955e3361723af3531' }, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", { key: 'be3a408762c8bada64224c4da92baf987ae62f6d' }, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", { key: '9cf44848dbcb7e8b1a40618db1ee6cf019e01720' }, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", { key: 'b53633b5c099b338089294c897cfbc32973d360d' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", { key: '0cab012a88532c69ba0aeb1daa7646e91c4f029d' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", { key: '1c47bfd56352b70a8eafb771470d9912240e9885' }, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", { key: '1147a866a58f3d50c8751fc02f6614e899b13bc0' }, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", { key: 'a308df3601fd5ba49741f2efbc3d262059daed2d' }, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", { key: 'af5ceafa9bb39c2e2085815c691198f7a0b48017' }, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", { key: '8abffd4f1e3e7b174ee5e5e9070fc0ca0703d1aa' }, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", { key: 'e127318f52e25d65b323d3325b02a0125864c3be' }, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", { key: 'b8f21b1a1bd674f7403e3096e7cb52e629b2df89' }, "PointerX: ", this.core.store.state?.pointerX), h("div", { key: '892abdc68df061495f88ceea2037766b537f82ab' }, "PointerY: ", this.core.store.state?.pointerY), h("div", { key: '04f08e11cb67cedf31900d01803960caaa0a5a0b' }, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", { key: '6a6efb9f05cb70eaff83cea1a22e1151a08e2ec9' }, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { key: 'c9e2392f43cf54b57f0fb49a361d47a2c4156ca3', id: "origin", class: "origin", style: {
22425
22433
  transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
22426
22434
  } }, visibleObjects?.map(object => {
22427
22435
  return (h("div", { key: object.id, id: object.id, class: "object", style: {
@@ -22430,7 +22438,7 @@ const KritzelEngine = class {
22430
22438
  position: 'absolute',
22431
22439
  zIndex: object.zIndex.toString(),
22432
22440
  pointerEvents: this.core.store.state.isScaling ? 'none' : 'auto',
22433
- } }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (h("svg", { xmlns: "http://www.w3.org/2000/svg", style: {
22441
+ } }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (h("svg", { ref: el => object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: {
22434
22442
  height: object?.totalHeight + 'px',
22435
22443
  width: object?.totalWidth + 'px',
22436
22444
  left: '0',
@@ -22440,7 +22448,8 @@ const KritzelEngine = class {
22440
22448
  transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
22441
22449
  opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
22442
22450
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
22443
- } }, h("svg", { ref: el => object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: { overflow: 'visible' }, viewBox: object?.viewBox }, h("path", { d: object?.d, fill: KritzelColorHelper.resolveThemeColor(object.fill, currentTheme), stroke: KritzelColorHelper.resolveThemeColor(object?.stroke, currentTheme), "shape-rendering": object.isLowRes() ? 'optimizeSpeed' : 'auto' })))), KritzelClassHelper.isInstanceOf(object, 'KritzelLine') && (h("svg", { xmlns: "http://www.w3.org/2000/svg", style: {
22451
+ overflow: 'visible',
22452
+ }, viewBox: object?.viewBox }, h("path", { d: object?.d, fill: KritzelColorHelper.resolveThemeColor(object.fill, currentTheme), stroke: KritzelColorHelper.resolveThemeColor(object?.stroke, currentTheme), "shape-rendering": object.isLowRes() ? 'optimizeSpeed' : 'auto' }))), KritzelClassHelper.isInstanceOf(object, 'KritzelLine') && (h("svg", { ref: el => object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: {
22444
22453
  height: object?.totalHeight + 'px',
22445
22454
  width: object?.totalWidth + 'px',
22446
22455
  left: '0',
@@ -22450,7 +22459,8 @@ const KritzelEngine = class {
22450
22459
  transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
22451
22460
  opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
22452
22461
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
22453
- } }, h("svg", { ref: el => object.mount(el), xmlns: "http://www.w3.org/2000/svg", style: { overflow: 'visible' }, viewBox: object?.viewBox }, (object.hasStartArrow || object.hasEndArrow) && (h("defs", null, object.hasStartArrow && (h("marker", { id: object.startMarkerId, markerWidth: object.getArrowSize('start'), markerHeight: object.getArrowSize('start'), refX: 0, refY: object.getArrowSize('start') / 2, orient: "auto-start-reverse", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.start?.style), fill: object.getArrowFill('start'), transform: `scale(${object.getArrowSize('start') / 10})` }))), object.hasEndArrow && (h("marker", { id: object.endMarkerId, markerWidth: object.getArrowSize('end'), markerHeight: object.getArrowSize('end'), refX: 0, refY: object.getArrowSize('end') / 2, orient: "auto", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.end?.style), fill: object.getArrowFill('end'), transform: `scale(${object.getArrowSize('end') / 10})` }))))), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: "transparent", "stroke-width": Math.max(object?.strokeWidth || 0, 10), "stroke-linecap": "round" }), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: KritzelColorHelper.resolveThemeColor(object?.stroke, currentTheme), "stroke-width": object?.strokeWidth, "stroke-linecap": "round", "marker-start": object.hasStartArrow ? `url(#${object.startMarkerId})` : undefined, "marker-end": object.hasEndArrow ? `url(#${object.endMarkerId})` : undefined })))), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (h("div", { style: {
22462
+ overflow: 'visible',
22463
+ }, viewBox: object?.viewBox }, (object.hasStartArrow || object.hasEndArrow) && (h("defs", null, object.hasStartArrow && (h("marker", { id: object.startMarkerId, markerWidth: object.getArrowSize('start'), markerHeight: object.getArrowSize('start'), refX: 0, refY: object.getArrowSize('start') / 2, orient: "auto-start-reverse", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.start?.style), fill: object.getArrowFill('start'), transform: `scale(${object.getArrowSize('start') / 10})` }))), object.hasEndArrow && (h("marker", { id: object.endMarkerId, markerWidth: object.getArrowSize('end'), markerHeight: object.getArrowSize('end'), refX: 0, refY: object.getArrowSize('end') / 2, orient: "auto", markerUnits: "userSpaceOnUse" }, h("path", { d: object.getArrowPath(object.arrows?.end?.style), fill: object.getArrowFill('end'), transform: `scale(${object.getArrowSize('end') / 10})` }))))), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: "transparent", "stroke-width": Math.max(object?.strokeWidth || 0, 10), "stroke-linecap": "round" }), h("path", { d: this.core.anchorManager.computeClippedLinePath(object), fill: "none", stroke: KritzelColorHelper.resolveThemeColor(object?.stroke, currentTheme), "stroke-width": object?.strokeWidth, "stroke-linecap": "round", "marker-start": object.hasStartArrow ? `url(#${object.startMarkerId})` : undefined, "marker-end": object.hasEndArrow ? `url(#${object.endMarkerId})` : undefined }))), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (h("img", { ref: el => object.mount(el), src: object.src, style: {
22454
22464
  position: 'absolute',
22455
22465
  left: '0',
22456
22466
  top: '0',
@@ -22466,13 +22476,9 @@ const KritzelEngine = class {
22466
22476
  borderStyle: 'solid',
22467
22477
  padding: object.padding + 'px',
22468
22478
  overflow: 'visible',
22469
- } }, h("img", { ref: el => object.mount(el), src: object.src, style: {
22470
- width: '100%',
22471
- height: '100%',
22472
22479
  userSelect: 'none',
22473
- pointerEvents: 'none',
22474
22480
  imageRendering: this.core.store.state.isScaling || this.core.store.state.isPanning ? 'pixelated' : 'auto',
22475
- }, draggable: false, onDragStart: e => e.preventDefault() }))), KritzelClassHelper.isInstanceOf(object, 'KritzelCustomElement') && (h("div", { style: {
22481
+ }, draggable: false, onDragStart: e => e.preventDefault() })), KritzelClassHelper.isInstanceOf(object, 'KritzelCustomElement') && (h("div", { ref: el => object.mount(el), style: {
22476
22482
  position: 'absolute',
22477
22483
  left: '0',
22478
22484
  top: '0',
@@ -22487,14 +22493,9 @@ const KritzelEngine = class {
22487
22493
  borderWidth: object.borderWidth + 'px',
22488
22494
  borderStyle: 'solid',
22489
22495
  padding: object.padding + 'px',
22490
- overflow: 'visible',
22491
- } }, h("div", { ref: el => object.mount(el), style: {
22492
- width: '100%',
22493
- height: '100%',
22494
- pointerEvents: 'auto',
22495
22496
  overflow: 'hidden',
22496
22497
  display: 'block',
22497
- } }))), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') && !this.core.displaySelectionLineUI(object) && (h("div", { style: {
22498
+ } })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') && !this.core.displaySelectionLineUI(object) && (h("div", { ref: el => object.mount(el), style: {
22498
22499
  position: 'absolute',
22499
22500
  left: '0',
22500
22501
  top: '0',
@@ -22504,10 +22505,7 @@ const KritzelEngine = class {
22504
22505
  transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
22505
22506
  opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
22506
22507
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
22507
- } }, h("div", { ref: el => object.mount(el), style: {
22508
- width: '100%',
22509
- height: '100%',
22510
- } }))), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionBox') && (h("div", { style: {
22508
+ } })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionBox') && (h("div", { ref: el => object.mount(el), style: {
22511
22509
  position: 'absolute',
22512
22510
  left: '0',
22513
22511
  top: '0',
@@ -22521,10 +22519,7 @@ const KritzelEngine = class {
22521
22519
  borderColor: KritzelColorHelper.resolveThemeColor(object.borderColor, currentTheme),
22522
22520
  borderWidth: object.borderWidth + 'px',
22523
22521
  borderStyle: 'solid',
22524
- } }, h("div", { ref: el => object.mount(el), style: {
22525
- width: '100%',
22526
- height: '100%',
22527
- } }))), KritzelClassHelper.isInstanceOf(object, 'KritzelText') && (h("div", { style: {
22522
+ } })), KritzelClassHelper.isInstanceOf(object, 'KritzelText') && (h("div", { style: {
22528
22523
  position: 'absolute',
22529
22524
  left: '0',
22530
22525
  top: '0',
@@ -22544,8 +22539,7 @@ const KritzelEngine = class {
22544
22539
  transform: `scale(${object.scaleFactor})`,
22545
22540
  backgroundColor: KritzelColorHelper.resolveThemeColor(object.backgroundColor, currentTheme),
22546
22541
  overflow: 'visible',
22547
- textRendering: this.core.store.state.isScaling || this.core.store.state.isPanning ? 'optimizeSpeed' : 'auto',
22548
- } }))), KritzelClassHelper.isInstanceOf(object, 'KritzelShape') && (h("div", { style: {
22542
+ } }))), KritzelClassHelper.isInstanceOf(object, 'KritzelShape') && (h("div", { ref: el => object.mount(el), onPointerDown: e => object.handlePointerDown(e), onPointerMove: e => object.handlePointerMove(e), onPointerUp: e => object.handlePointerUp(e), style: {
22549
22543
  position: 'absolute',
22550
22544
  left: '0',
22551
22545
  top: '0',
@@ -22555,10 +22549,6 @@ const KritzelEngine = class {
22555
22549
  transformOrigin: object.rotationDegrees !== 0 ? `${object.totalWidth / 2}px ${object.totalHeight / 2}px` : undefined,
22556
22550
  opacity: object.markedForRemoval ? '0.5' : object.opacity.toString(),
22557
22551
  pointerEvents: object.markedForRemoval ? 'none' : 'auto',
22558
- } }, h("div", { ref: el => object.mount(el), onPointerDown: e => object.handlePointerDown(e), onPointerMove: e => object.handlePointerMove(e), onPointerUp: e => object.handlePointerUp(e), style: {
22559
- width: '100%',
22560
- height: '100%',
22561
- position: 'relative',
22562
22552
  overflow: 'visible',
22563
22553
  } }, h("svg", { xmlns: "http://www.w3.org/2000/svg", style: {
22564
22554
  position: 'absolute',
@@ -22580,7 +22570,7 @@ const KritzelEngine = class {
22580
22570
  textAlign: 'center',
22581
22571
  overflow: 'hidden',
22582
22572
  pointerEvents: object.isEditing ? 'auto' : 'none',
22583
- } })))), this.core.store.state.debugInfo.showObjectInfo && object.isDebugInfoVisible && (h("div", { style: {
22573
+ } }))), this.core.store.state.debugInfo.showObjectInfo && object.isDebugInfoVisible && (h("div", { style: {
22584
22574
  pointerEvents: 'none',
22585
22575
  position: 'absolute',
22586
22576
  left: `${object.totalWidth}px`,
@@ -22767,7 +22757,7 @@ const KritzelEngine = class {
22767
22757
  stroke: 'var(--kritzel-snap-indicator-stroke, #007bff)',
22768
22758
  strokeWidth: data.indicatorStrokeWidth,
22769
22759
  } }))));
22770
- })()), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: 'b9171dfffeb4a88bc4ad9a7b0196a18f5427183f', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.core.store.state.contextMenuItems, objects: this.core.store.selectionGroup?.objects || [], style: {
22760
+ })()), this.core.store.state.isContextMenuVisible && (h("kritzel-context-menu", { key: '307012661cd1021e7e3c3db48f1671700f5de91b', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.core.store.state.contextMenuItems, objects: this.core.store.selectionGroup?.objects || [], style: {
22771
22761
  position: 'fixed',
22772
22762
  left: `${this.core.store.state.contextMenuX}px`,
22773
22763
  top: `${this.core.store.state.contextMenuY}px`,
@@ -22778,7 +22768,7 @@ const KritzelEngine = class {
22778
22768
  y: (-this.core.store.state.translateY + this.core.store.state.contextMenuY) / this.core.store.state.scale,
22779
22769
  }, this.core.store.selectionGroup?.objects);
22780
22770
  this.hideContextMenu();
22781
- }, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: 'd3ce01397575891a78449128020a212345332d06', core: this.core })));
22771
+ }, onClose: () => this.hideContextMenu() })), this.core.store.state?.activeTool instanceof KritzelEraserTool && !this.core.store.state.isScaling && h("kritzel-cursor-trail", { key: 'bd48d2a8e7c83e2c5d80c92548b00720650391ab', core: this.core })));
22782
22772
  }
22783
22773
  static get watchers() { return {
22784
22774
  "workspace": [{
@@ -23789,7 +23779,7 @@ const KritzelPortal = class {
23789
23779
  * This file is auto-generated by the version bump scripts.
23790
23780
  * Do not modify manually.
23791
23781
  */
23792
- const KRITZEL_VERSION = '0.1.21';
23782
+ const KRITZEL_VERSION = '0.1.22';
23793
23783
 
23794
23784
  const kritzelSettingsCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-body-padding:0;--kritzel-dialog-width-large:800px;--kritzel-dialog-height-large:500px}.footer-button{padding:8px 16px;border-radius:6px;cursor:pointer;font-size:14px}.cancel-button{border:1px solid #ebebeb;background:#fff;color:inherit}.cancel-button:hover{background:#f5f5f5}.settings-content{padding:0}.settings-content h3{margin:0 0 16px 0;font-size:18px;font-weight:600;color:var(--kritzel-settings-content-heading-color, #333333)}.settings-content p{margin:0;font-size:14px;color:var(--kritzel-settings-content-text-color, #666666);line-height:1.5}.settings-group{display:flex;flex-direction:column;gap:24px}.settings-item{display:flex;flex-direction:column;gap:8px}.settings-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.settings-label{font-size:14px;font-weight:500;color:var(--kritzel-settings-label-color, #333333);margin:0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}`;
23795
23785
 
@@ -1 +1 @@
1
- import{w as t,a as s,t as e,r as i,b as n,e as o,c,d as h,f as a,g as r,s as l,h as d,i as u,v as p,j as m,o as y,k as f,l as w,m as k,O as v,n as b,p as g,q as z,u as C,x,y as B,z as H,A as D,B as A,C as O,H as j,D as q}from"./p-DDIFE6oX.js";export{W as DEFAULT_BRUSH_CONFIG,Y as DEFAULT_LINE_TOOL_CONFIG,X as DEFAULT_TEXT_CONFIG,S as IndexedDBSyncProvider,V as KritzelAnchorManager,T as KritzelAppStateMap,J as KritzelBrushTool,Q as KritzelCursorHelper,M as KritzelEraserTool,I as KritzelGroup,F as KritzelImage,N as KritzelImageTool,G as KritzelLine,L as KritzelLineTool,E as KritzelPath,R as KritzelSelectionTool,K as KritzelText,P as KritzelTextTool,$ as KritzelThemeManager,U as KritzelWorkspace,_ as darkTheme,Z as lightTheme}from"./p-DDIFE6oX.js";class tt{doc;channel;_synced=!1;constructor(t,s,e){this.doc=s,this.channel=new BroadcastChannel(t),this.channel.onmessage=t=>{this.handleMessage(t.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),console.info(`BroadcastChannel Provider initialized: ${t}`)}handleDocUpdate=(i,n)=>{if(n!==this){const n=a();t(n,0),s(n,i),this.channel.postMessage(e(n))}};handleMessage(h){const l=r(new Uint8Array(h));switch(i(l)){case 0:const i=n(l);c(this.doc,i,this);break;case 1:this.broadcastSync();break;case 2:const h=n(l),r=o(this.doc,h);if(r.length>0){const i=a();t(i,0),s(i,r),this.channel.postMessage(e(i))}}}broadcastSync(){const i=a();t(i,2),s(i,h(this.doc)),this.channel.postMessage(e(i))}async connect(){if(!this._synced)return new Promise((t=>{const s=()=>{this._synced?t():setTimeout(s,50)};s()}))}disconnect(){}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}const st=new Map,et="undefined"==typeof BroadcastChannel?class{constructor(t){this.room=t,this.onmessage=null,this._onChange=s=>s.key===t&&null!==this.onmessage&&this.onmessage({data:u(s.newValue||"")}),y(this._onChange)}postMessage(t){p.setItem(this.room,m(f(t)))}close(){w(this._onChange)}}:BroadcastChannel,it=t=>l(st,t,(()=>{const s=d(),e=new et(t);return e.onmessage=t=>s.forEach((s=>s(t.data,"broadcastchannel"))),{bc:e,subs:s}})),nt=(t,s,e=null)=>{const i=it(t);i.bc.postMessage(s),i.subs.forEach((t=>t(s,e)))},ot=(e,i)=>{t(e,0);const n=h(i);s(e,n)},ct=(e,i,n)=>{t(e,1),s(e,o(i,n))},ht=(t,s,e,i)=>{try{c(s,n(t),e)}catch(t){null!=i&&i(t),console.error("Caught error while handling a Yjs update",t)}},at=ht;class rt extends v{constructor(t){super(),this.doc=t,this.clientID=t.clientID,this.states=new Map,this.meta=new Map,this._checkInterval=setInterval((()=>{const t=g();null!==this.getLocalState()&&15e3<=t-this.meta.get(this.clientID).lastUpdated&&this.setLocalState(this.getLocalState());const s=[];this.meta.forEach(((e,i)=>{i!==this.clientID&&3e4<=t-e.lastUpdated&&this.states.has(i)&&s.push(i)})),s.length>0&&lt(this,s,"timeout")}),b(3e3)),t.on("destroy",(()=>{this.destroy()})),this.setLocalState({})}destroy(){this.emit("destroy",[this]),this.setLocalState(null),super.destroy(),clearInterval(this._checkInterval)}getLocalState(){return this.states.get(this.clientID)||null}setLocalState(t){const s=this.clientID,e=this.meta.get(s),i=void 0===e?0:e.clock+1,n=this.states.get(s);null===t?this.states.delete(s):this.states.set(s,t),this.meta.set(s,{clock:i,lastUpdated:g()});const o=[],c=[],h=[],a=[];null===t?a.push(s):null==n?null!=t&&o.push(s):(c.push(s),z(n,t)||h.push(s)),(o.length>0||h.length>0||a.length>0)&&this.emit("change",[{added:o,updated:h,removed:a},"local"]),this.emit("update",[{added:o,updated:c,removed:a},"local"])}setLocalStateField(t,s){const e=this.getLocalState();null!==e&&this.setLocalState({...e,[t]:s})}getStates(){return this.states}}const lt=(t,s,e)=>{const i=[];for(let e=0;e<s.length;e++){const n=s[e];if(t.states.has(n)){if(t.states.delete(n),n===t.clientID){const s=t.meta.get(n);t.meta.set(n,{clock:s.clock+1,lastUpdated:g()})}i.push(n)}}i.length>0&&(t.emit("change",[{added:[],updated:[],removed:i},e]),t.emit("update",[{added:[],updated:[],removed:i},e]))},dt=(s,i,n=s.states)=>{const o=i.length,c=a();t(c,o);for(let e=0;e<o;e++){const o=i[e],h=n.get(o)||null,a=s.meta.get(o).clock;t(c,o),t(c,a),C(c,JSON.stringify(h))}return e(c)},ut=[];ut[0]=(s,e,o,c)=>{t(s,0);const h=((t,s,e,o,c)=>{const h=i(t);switch(h){case 0:((t,s,e)=>{ct(s,e,n(t))})(t,s,e);break;case 1:ht(t,e,o,c);break;case 2:at(t,e,o,c);break;default:throw new Error("Unknown message type")}return h})(e,s,o.doc,o);c&&1===h&&!o.synced&&(o.synced=!0)},ut[3]=(e,i,n)=>{t(e,1),s(e,dt(n.awareness,Array.from(n.awareness.getStates().keys())))},ut[1]=(t,s,e)=>{((t,s,e)=>{const n=r(s),o=g(),c=[],h=[],a=[],l=[],d=i(n);for(let s=0;s<d;s++){const s=i(n);let e=i(n);const r=JSON.parse(k(n)),d=t.meta.get(s),u=t.states.get(s),p=void 0===d?0:d.clock;(p<e||p===e&&null===r&&t.states.has(s))&&(null===r?s===t.clientID&&null!=t.getLocalState()?e++:t.states.delete(s):t.states.set(s,r),t.meta.set(s,{clock:e,lastUpdated:o}),void 0===d&&null!==r?c.push(s):void 0!==d&&null===r?l.push(s):null!==r&&(z(r,u)||a.push(s),h.push(s)))}(c.length>0||a.length>0||l.length>0)&&t.emit("change",[{added:c,updated:a,removed:l},e]),(c.length>0||h.length>0||l.length>0)&&t.emit("update",[{added:c,updated:h,removed:l},e])})(e.awareness,n(s),e)},ut[2]=(t,s,e)=>{((t,s,e)=>{0===i(t)&&e(0,k(t))})(s,0,((t,s)=>pt(e,s)))};const pt=(t,s)=>console.warn(`Permission denied to access ${t.url}.\n${s}`),mt=(t,s,e)=>{const n=r(s),o=a(),c=i(n),h=t.messageHandlers[c];return h?h(o,n,t,e,c):console.error("Unable to compute message"),o},yt=(t,s,e)=>{s===t.ws&&(t.emit("connection-close",[e,t]),t.ws=null,s.close(),t.wsconnecting=!1,t.wsconnected?(t.wsconnected=!1,t.synced=!1,lt(t.awareness,Array.from(t.awareness.getStates().keys()).filter((s=>s!==t.doc.clientID)),t),t.emit("status",[{status:"disconnected"}])):t.wsUnsuccessfulReconnects++,setTimeout(St,A(100*O(2,t.wsUnsuccessfulReconnects),t.maxBackoffTime),t))},St=i=>{if(i.shouldConnect&&null===i.ws){const n=new i._WS(i.url,i.protocols);n.binaryType="arraybuffer",i.ws=n,i.wsconnecting=!0,i.wsconnected=!1,i.synced=!1,n.onmessage=t=>{i.wsLastMessageReceived=g();const s=mt(i,new Uint8Array(t.data),!0);H(s)>1&&n.send(e(s))},n.onerror=t=>{i.emit("connection-error",[t,i])},n.onclose=t=>{yt(i,n,t)},n.onopen=()=>{i.wsLastMessageReceived=g(),i.wsconnecting=!1,i.wsconnected=!0,i.wsUnsuccessfulReconnects=0,i.emit("status",[{status:"connected"}]);const o=a();if(t(o,0),ot(o,i.doc),n.send(e(o)),null!==i.awareness.getLocalState()){const o=a();t(o,1),s(o,dt(i.awareness,[i.doc.clientID])),n.send(e(o))}},i.emit("status",[{status:"connecting"}])}},ft=(t,s)=>{const e=t.ws;t.wsconnected&&e&&e.readyState===e.OPEN&&e.send(s),t.bcconnected&&nt(t.bcChannel,s,t)};class wt extends B{constructor(i,n,o,{connect:c=!0,awareness:h=new rt(o),params:r={},protocols:l=[],WebSocketPolyfill:d=WebSocket,resyncInterval:u=-1,maxBackoffTime:p=2500,disableBc:m=!1}={}){for(super();"/"===i[i.length-1];)i=i.slice(0,i.length-1);this.serverUrl=i,this.bcChannel=i+"/"+n,this.maxBackoffTime=p,this.params=r,this.protocols=l,this.roomname=n,this.doc=o,this._WS=d,this.awareness=h,this.wsconnected=!1,this.wsconnecting=!1,this.bcconnected=!1,this.disableBc=m,this.wsUnsuccessfulReconnects=0,this.messageHandlers=ut.slice(),this._synced=!1,this.ws=null,this.wsLastMessageReceived=0,this.shouldConnect=c,this._resyncInterval=0,u>0&&(this._resyncInterval=setInterval((()=>{if(this.ws&&this.ws.readyState===WebSocket.OPEN){const s=a();t(s,0),ot(s,o),this.ws.send(e(s))}}),u)),this._bcSubscriber=(t,s)=>{if(s!==this){const s=mt(this,new Uint8Array(t),!1);H(s)>1&&nt(this.bcChannel,e(s),this)}},this._updateHandler=(i,n)=>{if(n!==this){const n=a();t(n,0),((e,i)=>{t(e,2),s(e,i)})(n,i),ft(this,e(n))}},this.doc.on("update",this._updateHandler),this._awarenessUpdateHandler=({added:i,updated:n,removed:o})=>{const c=i.concat(n).concat(o),r=a();t(r,1),s(r,dt(h,c)),ft(this,e(r))},this._exitHandler=()=>{lt(this.awareness,[o.clientID],"app closed")},D&&"undefined"!=typeof process&&process.on("exit",this._exitHandler),h.on("update",this._awarenessUpdateHandler),this._checkInterval=setInterval((()=>{this.wsconnected&&3e4<g()-this.wsLastMessageReceived&&yt(this,this.ws,null)}),3e3),c&&this.connect()}get url(){const t=x(this.params,((t,s)=>`${encodeURIComponent(s)}=${encodeURIComponent(t)}`)).join("&");return this.serverUrl+"/"+this.roomname+(0===t.length?"":"?"+t)}get synced(){return this._synced}set synced(t){this._synced!==t&&(this._synced=t,this.emit("synced",[t]),this.emit("sync",[t]))}destroy(){0!==this._resyncInterval&&clearInterval(this._resyncInterval),clearInterval(this._checkInterval),this.disconnect(),D&&"undefined"!=typeof process&&process.off("exit",this._exitHandler),this.awareness.off("update",this._awarenessUpdateHandler),this.doc.off("update",this._updateHandler),super.destroy()}connectBc(){if(this.disableBc)return;var i;this.bcconnected||(i=this._bcSubscriber,it(this.bcChannel).subs.add(i),this.bcconnected=!0);const n=a();t(n,0),ot(n,this.doc),nt(this.bcChannel,e(n),this);const o=a();t(o,0),ct(o,this.doc),nt(this.bcChannel,e(o),this);const c=a();t(c,3),nt(this.bcChannel,e(c),this);const h=a();t(h,1),s(h,dt(this.awareness,[this.doc.clientID])),nt(this.bcChannel,e(h),this)}disconnectBc(){const i=a();t(i,1),s(i,dt(this.awareness,[this.doc.clientID],new Map)),ft(this,e(i)),this.bcconnected&&(((t,s)=>{const e=it(t);e.subs.delete(s)&&0===e.subs.size&&(e.bc.close(),st.delete(t))})(this.bcChannel,this._bcSubscriber),this.bcconnected=!1)}disconnect(){this.shouldConnect=!1,this.disconnectBc(),null!==this.ws&&yt(this,this.ws,null)}connect(){this.shouldConnect=!0,this.wsconnected||null!==this.ws||(St(this),this.connectBc())}}class kt{provider;isConnected=!1;constructor(t,s,e){const i=e?.url||"ws://localhost:1234",n=e?.roomName||t;this.provider=new wt(i,n,s,{params:e?.params,protocols:e?.protocols,WebSocketPolyfill:e?.WebSocketPolyfill,awareness:e?.awareness,maxBackoffTime:e?.maxBackoffTime,disableBc:!0}),this.setupEventListeners(),console.info(`WebSocket Provider initialized: ${i}/${n}`)}static with(t){return{create:(s,e)=>new kt(s,e,t)}}setupEventListeners(){this.provider.on("status",(({status:t})=>{"connected"===t?(this.isConnected=!0,console.info("WebSocket connected")):"disconnected"===t&&(this.isConnected=!1,console.info("WebSocket disconnected"))})),this.provider.on("sync",(t=>{t&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((t,s)=>{const e=setTimeout((()=>{s(new Error("WebSocket connection timeout"))}),1e4),i=({status:s})=>{"connected"===s&&(clearTimeout(e),this.provider.off("status",i),this.isConnected=!0,t())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(e),this.provider.off("status",i),this.isConnected=!0,t())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class vt{provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;static sharedWebSocketProvider=null;constructor(t,s,e){const i=e?.name||t,n=e?.url||"ws://localhost:1234",o=e?.websocketProvider||vt.sharedWebSocketProvider;if(o){this.usesSharedSocket=!0;const t={websocketProvider:o,name:i,document:s,token:e?.token||null,onConnect:()=>{this.isConnected=!0,e?.quiet||console.info(`Hocuspocus connected: ${i}`),e?.onConnect&&e.onConnect()},onDisconnect:()=>{this.isConnected=!1,this.isSynced=!1,e?.quiet||console.info(`Hocuspocus disconnected: ${i}`),e?.onDisconnect&&e.onDisconnect()},onSynced:()=>{this.isSynced=!0,e?.quiet||console.info(`Hocuspocus synced: ${i}`),e?.onSynced&&e.onSynced()}};void 0!==e?.forceSyncInterval&&(t.forceSyncInterval=e.forceSyncInterval),e?.onAuthenticationFailed&&(t.onAuthenticationFailed=e.onAuthenticationFailed),e?.onStatus&&(t.onStatus=e.onStatus),this.provider=new j(t),this.provider.attach(),e?.quiet||console.info(`Hocuspocus Provider initialized (multiplexed): ${i}`)}else{this.usesSharedSocket=!1;const t={url:n,name:i,document:s,token:e?.token||null,onConnect:()=>{this.isConnected=!0,e?.quiet||console.info(`Hocuspocus connected: ${i}`),e?.onConnect&&e.onConnect()},onDisconnect:()=>{this.isConnected=!1,this.isSynced=!1,e?.quiet||console.info(`Hocuspocus disconnected: ${i}`),e?.onDisconnect&&e.onDisconnect()},onSynced:()=>{this.isSynced=!0,e?.quiet||console.info(`Hocuspocus synced: ${i}`),e?.onSynced&&e.onSynced()}};void 0!==e?.forceSyncInterval&&(t.forceSyncInterval=e.forceSyncInterval),e?.onAuthenticationFailed&&(t.onAuthenticationFailed=e.onAuthenticationFailed),e?.onStatus&&(t.onStatus=e.onStatus),e?.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),this.provider=new j(t),e?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}}static createSharedWebSocket(t){if(vt.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),vt.sharedWebSocketProvider;const s={url:t.url};return t.WebSocketPolyfill&&(s.WebSocketPolyfill=t.WebSocketPolyfill),t.onConnect&&(s.onConnect=t.onConnect),t.onDisconnect&&(s.onDisconnect=t.onDisconnect),t.onStatus&&(s.onStatus=t.onStatus),vt.sharedWebSocketProvider=new q(s),console.info(`Shared Hocuspocus WebSocket created: ${t.url}`),vt.sharedWebSocketProvider}static destroySharedWebSocket(){vt.sharedWebSocketProvider&&(vt.sharedWebSocketProvider.destroy(),vt.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return vt.sharedWebSocketProvider}static with(t){return{create:(s,e)=>new vt(s,e,t)}}async connect(){if(!this.isSynced)return new Promise(((t,s)=>{const e=setTimeout((()=>{s(new Error("Hocuspocus connection timeout"))}),1e4),i=()=>{clearTimeout(e),this.provider.off("synced",i),t()};if(this.provider.on("synced",i),this.provider.isSynced)return clearTimeout(e),this.provider.off("synced",i),void t();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}disconnect(){this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1}}export{tt as BroadcastSyncProvider,vt as HocuspocusSyncProvider,kt as WebSocketSyncProvider}
1
+ import{w as t,a as s,t as e,r as i,b as n,e as o,c,d as h,f as a,g as r,s as l,h as d,i as u,v as p,j as m,o as y,k as f,l as w,m as v,O as k,n as b,p as g,q as z,u as C,x,y as B,z as H,A,B as D,C as O,H as q,D as j}from"./p-_PqPRv7q.js";export{W as DEFAULT_BRUSH_CONFIG,Y as DEFAULT_LINE_TOOL_CONFIG,X as DEFAULT_TEXT_CONFIG,S as IndexedDBSyncProvider,V as KritzelAnchorManager,T as KritzelAppStateMap,J as KritzelBrushTool,Q as KritzelCursorHelper,M as KritzelEraserTool,I as KritzelGroup,F as KritzelImage,N as KritzelImageTool,G as KritzelLine,L as KritzelLineTool,E as KritzelPath,R as KritzelSelectionTool,K as KritzelText,P as KritzelTextTool,$ as KritzelThemeManager,U as KritzelWorkspace,_ as darkTheme,Z as lightTheme}from"./p-_PqPRv7q.js";class tt{doc;channel;_synced=!1;constructor(t,s,e){this.doc=s,this.channel=new BroadcastChannel(t),this.channel.onmessage=t=>{this.handleMessage(t.data)},this.doc.on("update",this.handleDocUpdate),this.broadcastSync(),setTimeout((()=>{this._synced=!0}),100),console.info(`BroadcastChannel Provider initialized: ${t}`)}handleDocUpdate=(i,n)=>{if(n!==this){const n=a();t(n,0),s(n,i),this.channel.postMessage(e(n))}};handleMessage(h){const l=r(new Uint8Array(h));switch(i(l)){case 0:const i=n(l);c(this.doc,i,this);break;case 1:this.broadcastSync();break;case 2:const h=n(l),r=o(this.doc,h);if(r.length>0){const i=a();t(i,0),s(i,r),this.channel.postMessage(e(i))}}}broadcastSync(){const i=a();t(i,2),s(i,h(this.doc)),this.channel.postMessage(e(i))}async connect(){if(!this._synced)return new Promise((t=>{const s=()=>{this._synced?t():setTimeout(s,50)};s()}))}disconnect(){}destroy(){this.doc.off("update",this.handleDocUpdate),this.channel.close()}}const st=new Map,et="undefined"==typeof BroadcastChannel?class{constructor(t){this.room=t,this.onmessage=null,this._onChange=s=>s.key===t&&null!==this.onmessage&&this.onmessage({data:u(s.newValue||"")}),y(this._onChange)}postMessage(t){p.setItem(this.room,m(f(t)))}close(){w(this._onChange)}}:BroadcastChannel,it=t=>l(st,t,(()=>{const s=d(),e=new et(t);return e.onmessage=t=>s.forEach((s=>s(t.data,"broadcastchannel"))),{bc:e,subs:s}})),nt=(t,s,e=null)=>{const i=it(t);i.bc.postMessage(s),i.subs.forEach((t=>t(s,e)))},ot=(e,i)=>{t(e,0);const n=h(i);s(e,n)},ct=(e,i,n)=>{t(e,1),s(e,o(i,n))},ht=(t,s,e,i)=>{try{c(s,n(t),e)}catch(t){null!=i&&i(t),console.error("Caught error while handling a Yjs update",t)}},at=ht;class rt extends k{constructor(t){super(),this.doc=t,this.clientID=t.clientID,this.states=new Map,this.meta=new Map,this._checkInterval=setInterval((()=>{const t=g();null!==this.getLocalState()&&15e3<=t-this.meta.get(this.clientID).lastUpdated&&this.setLocalState(this.getLocalState());const s=[];this.meta.forEach(((e,i)=>{i!==this.clientID&&3e4<=t-e.lastUpdated&&this.states.has(i)&&s.push(i)})),s.length>0&&lt(this,s,"timeout")}),b(3e3)),t.on("destroy",(()=>{this.destroy()})),this.setLocalState({})}destroy(){this.emit("destroy",[this]),this.setLocalState(null),super.destroy(),clearInterval(this._checkInterval)}getLocalState(){return this.states.get(this.clientID)||null}setLocalState(t){const s=this.clientID,e=this.meta.get(s),i=void 0===e?0:e.clock+1,n=this.states.get(s);null===t?this.states.delete(s):this.states.set(s,t),this.meta.set(s,{clock:i,lastUpdated:g()});const o=[],c=[],h=[],a=[];null===t?a.push(s):null==n?null!=t&&o.push(s):(c.push(s),z(n,t)||h.push(s)),(o.length>0||h.length>0||a.length>0)&&this.emit("change",[{added:o,updated:h,removed:a},"local"]),this.emit("update",[{added:o,updated:c,removed:a},"local"])}setLocalStateField(t,s){const e=this.getLocalState();null!==e&&this.setLocalState({...e,[t]:s})}getStates(){return this.states}}const lt=(t,s,e)=>{const i=[];for(let e=0;e<s.length;e++){const n=s[e];if(t.states.has(n)){if(t.states.delete(n),n===t.clientID){const s=t.meta.get(n);t.meta.set(n,{clock:s.clock+1,lastUpdated:g()})}i.push(n)}}i.length>0&&(t.emit("change",[{added:[],updated:[],removed:i},e]),t.emit("update",[{added:[],updated:[],removed:i},e]))},dt=(s,i,n=s.states)=>{const o=i.length,c=a();t(c,o);for(let e=0;e<o;e++){const o=i[e],h=n.get(o)||null,a=s.meta.get(o).clock;t(c,o),t(c,a),C(c,JSON.stringify(h))}return e(c)},ut=[];ut[0]=(s,e,o,c)=>{t(s,0);const h=((t,s,e,o,c)=>{const h=i(t);switch(h){case 0:((t,s,e)=>{ct(s,e,n(t))})(t,s,e);break;case 1:ht(t,e,o,c);break;case 2:at(t,e,o,c);break;default:throw new Error("Unknown message type")}return h})(e,s,o.doc,o);c&&1===h&&!o.synced&&(o.synced=!0)},ut[3]=(e,i,n)=>{t(e,1),s(e,dt(n.awareness,Array.from(n.awareness.getStates().keys())))},ut[1]=(t,s,e)=>{((t,s,e)=>{const n=r(s),o=g(),c=[],h=[],a=[],l=[],d=i(n);for(let s=0;s<d;s++){const s=i(n);let e=i(n);const r=JSON.parse(v(n)),d=t.meta.get(s),u=t.states.get(s),p=void 0===d?0:d.clock;(p<e||p===e&&null===r&&t.states.has(s))&&(null===r?s===t.clientID&&null!=t.getLocalState()?e++:t.states.delete(s):t.states.set(s,r),t.meta.set(s,{clock:e,lastUpdated:o}),void 0===d&&null!==r?c.push(s):void 0!==d&&null===r?l.push(s):null!==r&&(z(r,u)||a.push(s),h.push(s)))}(c.length>0||a.length>0||l.length>0)&&t.emit("change",[{added:c,updated:a,removed:l},e]),(c.length>0||h.length>0||l.length>0)&&t.emit("update",[{added:c,updated:h,removed:l},e])})(e.awareness,n(s),e)},ut[2]=(t,s,e)=>{((t,s,e)=>{0===i(t)&&e(0,v(t))})(s,0,((t,s)=>pt(e,s)))};const pt=(t,s)=>console.warn(`Permission denied to access ${t.url}.\n${s}`),mt=(t,s,e)=>{const n=r(s),o=a(),c=i(n),h=t.messageHandlers[c];return h?h(o,n,t,e,c):console.error("Unable to compute message"),o},yt=(t,s,e)=>{s===t.ws&&(t.emit("connection-close",[e,t]),t.ws=null,s.close(),t.wsconnecting=!1,t.wsconnected?(t.wsconnected=!1,t.synced=!1,lt(t.awareness,Array.from(t.awareness.getStates().keys()).filter((s=>s!==t.doc.clientID)),t),t.emit("status",[{status:"disconnected"}])):t.wsUnsuccessfulReconnects++,setTimeout(St,D(100*O(2,t.wsUnsuccessfulReconnects),t.maxBackoffTime),t))},St=i=>{if(i.shouldConnect&&null===i.ws){const n=new i._WS(i.url,i.protocols);n.binaryType="arraybuffer",i.ws=n,i.wsconnecting=!0,i.wsconnected=!1,i.synced=!1,n.onmessage=t=>{i.wsLastMessageReceived=g();const s=mt(i,new Uint8Array(t.data),!0);H(s)>1&&n.send(e(s))},n.onerror=t=>{i.emit("connection-error",[t,i])},n.onclose=t=>{yt(i,n,t)},n.onopen=()=>{i.wsLastMessageReceived=g(),i.wsconnecting=!1,i.wsconnected=!0,i.wsUnsuccessfulReconnects=0,i.emit("status",[{status:"connected"}]);const o=a();if(t(o,0),ot(o,i.doc),n.send(e(o)),null!==i.awareness.getLocalState()){const o=a();t(o,1),s(o,dt(i.awareness,[i.doc.clientID])),n.send(e(o))}},i.emit("status",[{status:"connecting"}])}},ft=(t,s)=>{const e=t.ws;t.wsconnected&&e&&e.readyState===e.OPEN&&e.send(s),t.bcconnected&&nt(t.bcChannel,s,t)};class wt extends B{constructor(i,n,o,{connect:c=!0,awareness:h=new rt(o),params:r={},protocols:l=[],WebSocketPolyfill:d=WebSocket,resyncInterval:u=-1,maxBackoffTime:p=2500,disableBc:m=!1}={}){for(super();"/"===i[i.length-1];)i=i.slice(0,i.length-1);this.serverUrl=i,this.bcChannel=i+"/"+n,this.maxBackoffTime=p,this.params=r,this.protocols=l,this.roomname=n,this.doc=o,this._WS=d,this.awareness=h,this.wsconnected=!1,this.wsconnecting=!1,this.bcconnected=!1,this.disableBc=m,this.wsUnsuccessfulReconnects=0,this.messageHandlers=ut.slice(),this._synced=!1,this.ws=null,this.wsLastMessageReceived=0,this.shouldConnect=c,this._resyncInterval=0,u>0&&(this._resyncInterval=setInterval((()=>{if(this.ws&&this.ws.readyState===WebSocket.OPEN){const s=a();t(s,0),ot(s,o),this.ws.send(e(s))}}),u)),this._bcSubscriber=(t,s)=>{if(s!==this){const s=mt(this,new Uint8Array(t),!1);H(s)>1&&nt(this.bcChannel,e(s),this)}},this._updateHandler=(i,n)=>{if(n!==this){const n=a();t(n,0),((e,i)=>{t(e,2),s(e,i)})(n,i),ft(this,e(n))}},this.doc.on("update",this._updateHandler),this._awarenessUpdateHandler=({added:i,updated:n,removed:o})=>{const c=i.concat(n).concat(o),r=a();t(r,1),s(r,dt(h,c)),ft(this,e(r))},this._exitHandler=()=>{lt(this.awareness,[o.clientID],"app closed")},A&&"undefined"!=typeof process&&process.on("exit",this._exitHandler),h.on("update",this._awarenessUpdateHandler),this._checkInterval=setInterval((()=>{this.wsconnected&&3e4<g()-this.wsLastMessageReceived&&yt(this,this.ws,null)}),3e3),c&&this.connect()}get url(){const t=x(this.params,((t,s)=>`${encodeURIComponent(s)}=${encodeURIComponent(t)}`)).join("&");return this.serverUrl+"/"+this.roomname+(0===t.length?"":"?"+t)}get synced(){return this._synced}set synced(t){this._synced!==t&&(this._synced=t,this.emit("synced",[t]),this.emit("sync",[t]))}destroy(){0!==this._resyncInterval&&clearInterval(this._resyncInterval),clearInterval(this._checkInterval),this.disconnect(),A&&"undefined"!=typeof process&&process.off("exit",this._exitHandler),this.awareness.off("update",this._awarenessUpdateHandler),this.doc.off("update",this._updateHandler),super.destroy()}connectBc(){if(this.disableBc)return;var i;this.bcconnected||(i=this._bcSubscriber,it(this.bcChannel).subs.add(i),this.bcconnected=!0);const n=a();t(n,0),ot(n,this.doc),nt(this.bcChannel,e(n),this);const o=a();t(o,0),ct(o,this.doc),nt(this.bcChannel,e(o),this);const c=a();t(c,3),nt(this.bcChannel,e(c),this);const h=a();t(h,1),s(h,dt(this.awareness,[this.doc.clientID])),nt(this.bcChannel,e(h),this)}disconnectBc(){const i=a();t(i,1),s(i,dt(this.awareness,[this.doc.clientID],new Map)),ft(this,e(i)),this.bcconnected&&(((t,s)=>{const e=it(t);e.subs.delete(s)&&0===e.subs.size&&(e.bc.close(),st.delete(t))})(this.bcChannel,this._bcSubscriber),this.bcconnected=!1)}disconnect(){this.shouldConnect=!1,this.disconnectBc(),null!==this.ws&&yt(this,this.ws,null)}connect(){this.shouldConnect=!0,this.wsconnected||null!==this.ws||(St(this),this.connectBc())}}class vt{provider;isConnected=!1;constructor(t,s,e){const i=e?.url||"ws://localhost:1234",n=e?.roomName||t;this.provider=new wt(i,n,s,{params:e?.params,protocols:e?.protocols,WebSocketPolyfill:e?.WebSocketPolyfill,awareness:e?.awareness,maxBackoffTime:e?.maxBackoffTime,disableBc:!0}),this.setupEventListeners(),console.info(`WebSocket Provider initialized: ${i}/${n}`)}static with(t){return{create:(s,e)=>new vt(s,e,t)}}setupEventListeners(){this.provider.on("status",(({status:t})=>{"connected"===t?(this.isConnected=!0,console.info("WebSocket connected")):"disconnected"===t&&(this.isConnected=!1,console.info("WebSocket disconnected"))})),this.provider.on("sync",(t=>{t&&console.info("WebSocket synced")}))}async connect(){if(!this.isConnected)return new Promise(((t,s)=>{const e=setTimeout((()=>{s(new Error("WebSocket connection timeout"))}),1e4),i=({status:s})=>{"connected"===s&&(clearTimeout(e),this.provider.off("status",i),this.isConnected=!0,t())};this.provider.on("status",i),this.provider.wsconnected&&(clearTimeout(e),this.provider.off("status",i),this.isConnected=!0,t())}))}disconnect(){this.provider&&this.provider.disconnect(),this.isConnected=!1}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1}}class kt{provider;isConnected=!1;isSynced=!1;usesSharedSocket=!1;static sharedWebSocketProvider=null;constructor(t,s,e){const i=e?.name||t,n=e?.url||"ws://localhost:1234",o=e?.websocketProvider||kt.sharedWebSocketProvider;if(o){this.usesSharedSocket=!0;const t={websocketProvider:o,name:i,document:s,token:e?.token||null,onConnect:()=>{this.isConnected=!0,e?.quiet||console.info(`Hocuspocus connected: ${i}`),e?.onConnect&&e.onConnect()},onDisconnect:()=>{this.isConnected=!1,this.isSynced=!1,e?.quiet||console.info(`Hocuspocus disconnected: ${i}`),e?.onDisconnect&&e.onDisconnect()},onSynced:()=>{this.isSynced=!0,e?.quiet||console.info(`Hocuspocus synced: ${i}`),e?.onSynced&&e.onSynced()}};void 0!==e?.forceSyncInterval&&(t.forceSyncInterval=e.forceSyncInterval),e?.onAuthenticationFailed&&(t.onAuthenticationFailed=e.onAuthenticationFailed),e?.onStatus&&(t.onStatus=e.onStatus),this.provider=new q(t),this.provider.attach(),e?.quiet||console.info(`Hocuspocus Provider initialized (multiplexed): ${i}`)}else{this.usesSharedSocket=!1;const t={url:n,name:i,document:s,token:e?.token||null,onConnect:()=>{this.isConnected=!0,e?.quiet||console.info(`Hocuspocus connected: ${i}`),e?.onConnect&&e.onConnect()},onDisconnect:()=>{this.isConnected=!1,this.isSynced=!1,e?.quiet||console.info(`Hocuspocus disconnected: ${i}`),e?.onDisconnect&&e.onDisconnect()},onSynced:()=>{this.isSynced=!0,e?.quiet||console.info(`Hocuspocus synced: ${i}`),e?.onSynced&&e.onSynced()}};void 0!==e?.forceSyncInterval&&(t.forceSyncInterval=e.forceSyncInterval),e?.onAuthenticationFailed&&(t.onAuthenticationFailed=e.onAuthenticationFailed),e?.onStatus&&(t.onStatus=e.onStatus),e?.WebSocketPolyfill&&(t.WebSocketPolyfill=e.WebSocketPolyfill),this.provider=new q(t),e?.quiet||console.info(`Hocuspocus Provider initialized: ${n}/${i}`)}}static createSharedWebSocket(t){if(kt.sharedWebSocketProvider)return console.warn("Shared WebSocket already exists. Returning existing instance."),kt.sharedWebSocketProvider;const s={url:t.url};return t.WebSocketPolyfill&&(s.WebSocketPolyfill=t.WebSocketPolyfill),t.onConnect&&(s.onConnect=t.onConnect),t.onDisconnect&&(s.onDisconnect=t.onDisconnect),t.onStatus&&(s.onStatus=t.onStatus),kt.sharedWebSocketProvider=new j(s),console.info(`Shared Hocuspocus WebSocket created: ${t.url}`),kt.sharedWebSocketProvider}static destroySharedWebSocket(){kt.sharedWebSocketProvider&&(kt.sharedWebSocketProvider.destroy(),kt.sharedWebSocketProvider=null,console.info("Shared Hocuspocus WebSocket destroyed"))}static getSharedWebSocket(){return kt.sharedWebSocketProvider}static with(t){return{create:(s,e)=>new kt(s,e,t)}}async connect(){if(!this.isSynced)return new Promise(((t,s)=>{const e=setTimeout((()=>{s(new Error("Hocuspocus connection timeout"))}),1e4),i=()=>{clearTimeout(e),this.provider.off("synced",i),t()};if(this.provider.on("synced",i),this.provider.isSynced)return clearTimeout(e),this.provider.off("synced",i),void t();this.isConnected||this.usesSharedSocket||this.provider.connect()}))}disconnect(){this.provider&&(this.usesSharedSocket?this.provider.detach():this.provider.disconnect()),this.isConnected=!1,this.isSynced=!1}destroy(){this.provider&&this.provider.destroy(),this.isConnected=!1,this.isSynced=!1}}export{tt as BroadcastSyncProvider,kt as HocuspocusSyncProvider,vt as WebSocketSyncProvider}