kritzel-stencil 0.4.23 → 0.4.25

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 (34) hide show
  1. package/dist/cjs/index.cjs.js +3 -46
  2. package/dist/cjs/kritzel-active-users_47.cjs.entry.js +93 -138
  3. package/dist/cjs/loader.cjs.js +1 -1
  4. package/dist/cjs/stencil.cjs.js +1 -1
  5. package/dist/collection/classes/core/core.class.js +4 -0
  6. package/dist/collection/classes/providers/sync/hocuspocus-sync-provider.class.js +1 -19
  7. package/dist/collection/classes/providers/sync/websocket-sync-provider.class.js +2 -27
  8. package/dist/collection/classes/structures/app-state-map.structure.js +1 -4
  9. package/dist/collection/classes/structures/object-map.structure.js +64 -61
  10. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +20 -32
  11. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +21 -73
  12. package/dist/collection/constants/version.js +1 -1
  13. package/dist/components/index.js +4 -47
  14. package/dist/components/kritzel-editor.js +20 -18
  15. package/dist/components/kritzel-engine.js +1 -1
  16. package/dist/components/kritzel-settings.js +1 -1
  17. package/dist/components/{p-Cb-xlpsJ.js → p-0fhjWRmT.js} +1 -1
  18. package/dist/components/{p-EijwLEZx.js → p-gJcH-huF.js} +75 -123
  19. package/dist/esm/index.js +3 -46
  20. package/dist/esm/kritzel-active-users_47.entry.js +93 -138
  21. package/dist/esm/loader.js +1 -1
  22. package/dist/esm/stencil.js +1 -1
  23. package/dist/stencil/index.esm.js +3 -46
  24. package/dist/stencil/{p-9e38407e.entry.js → p-dc5783ee.entry.js} +93 -138
  25. package/dist/stencil/stencil.esm.js +1 -1
  26. package/dist/types/classes/providers/sync/hocuspocus-sync-provider.class.d.ts +1 -5
  27. package/dist/types/classes/providers/sync/websocket-sync-provider.class.d.ts +1 -6
  28. package/dist/types/classes/structures/object-map.structure.d.ts +16 -26
  29. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +3 -4
  30. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +3 -12
  31. package/dist/types/components.d.ts +7 -12
  32. package/dist/types/constants/version.d.ts +1 -1
  33. package/dist/types/interfaces/sync-provider.interface.d.ts +5 -11
  34. package/package.json +1 -1
@@ -266,9 +266,7 @@ export class KritzelEditor {
266
266
  login;
267
267
  isPublicChange;
268
268
  awarenessChange;
269
- /** Emitted while remote changes are being applied to the active workspace. Stays silent when the remote holds nothing new. */
270
- syncingChange;
271
- loadingChange;
269
+ isSyncing;
272
270
  isEngineReady = false;
273
271
  isControlsReady = false;
274
272
  isWorkspaceManagerReady = false;
@@ -290,8 +288,8 @@ export class KritzelEditor {
290
288
  contextMenuState;
291
289
  normalizedControls = [];
292
290
  resolvedMoreMenuItems = [];
293
- isSyncing = false;
294
291
  isLoadingOverlayVisible = false;
292
+ isSyncingIndicatorVisible = false;
295
293
  notificationDismissTimeout;
296
294
  notificationDismissAnimationTimeout;
297
295
  notificationDisplayDurationMs = 5000;
@@ -774,6 +772,11 @@ export class KritzelEditor {
774
772
  event.stopPropagation();
775
773
  this.awarenessChange.emit(event.detail);
776
774
  }
775
+ handleIsSyncingChange(event) {
776
+ event.stopPropagation();
777
+ this.isSyncingIndicatorVisible = event.detail;
778
+ this.isSyncing.emit(event.detail);
779
+ }
777
780
  handleNotificationsChange(event) {
778
781
  event.stopPropagation();
779
782
  this.clearNotificationDismissAnimationTimer();
@@ -1087,40 +1090,40 @@ export class KritzelEditor {
1087
1090
  const isLoggedIn = this.isLoggedIn;
1088
1091
  const shouldShowCurrentUser = isLoggedIn;
1089
1092
  const shouldShowLoginButton = this.isReady && !!this.loginConfig && !isLoggedIn;
1090
- return (h(Host, { key: 'ff7d505697bd4c4bd840dadcb04a934b7e243a01' }, h("div", { key: 'b40076c3c79ad3f879e80c58b412b79266de2ea8', class: "editor-content", style: {
1093
+ return (h(Host, { key: 'a24350a0c12d99ccb0d0ec3ab5975d0f1bf7f861' }, h("div", { key: 'bd7029567aeef8cba5290c2bf9937db1af113475', class: "editor-content", style: {
1091
1094
  opacity: this.isEditorVisible ? '1' : '0',
1092
1095
  visibility: this.isEditorVisible ? 'visible' : 'hidden',
1093
1096
  transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out',
1094
- } }, h("div", { key: '1b1171eea60a36ad06da55a3da564bc356526266', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '48b59f3f57ace57debc19a295d4fb642e8c3b23d', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, terms: this.resolvedTerms, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'c66a6faae8bf7115dcce47630ad820af9ba76eb0', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), this.activeNotification && (h("div", { key: '834baedc5f20328deb4ee586f693313306895a71', class: "top-center-notification-layer", role: "presentation" }, h("div", { key: 'f800508a2e076ee3e89820ffff4df81842b175b3', class: { 'top-center-notification-container': true, 'is-dismissing': this.isNotificationDismissing }, role: "presentation" }, h("kritzel-notification-card", { key: '2835ea84e8fa92c41637adaa29d9005f209b2da9', notification: this.activeNotification, locale: this.locale, onDismiss: this.dismissNotification, onHoverChange: event => this.handleNotificationHoverChange(event) })))), this.contextMenuState && this.contextMenuState.items.length > 0 && (h("kritzel-context-menu", { key: '6c49e899b7f933d3f06cd1f8696a590d542214a7', class: "context-menu", items: this.contextMenuState.items, objects: this.contextMenuState.objects, style: {
1097
+ } }, h("div", { key: 'f628dbd94d88c9bdb313a59d73ce86302c90e375', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '5a82d054da31e47d3f8b5c6c403949a5fb97b9dd', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, terms: this.resolvedTerms, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'a5bccef36c8a49ef2cb7ec029def1c7ba71d1c31', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), this.activeNotification && (h("div", { key: 'c5c359b199528dd7b1b64a6a32ef349037357c5a', class: "top-center-notification-layer", role: "presentation" }, h("div", { key: 'a41cd6c67c56626c2b6f0eb12193af1f80d6a254', class: { 'top-center-notification-container': true, 'is-dismissing': this.isNotificationDismissing }, role: "presentation" }, h("kritzel-notification-card", { key: 'fb49769368ddf0fc74998a96dd26dc446ff2b386', notification: this.activeNotification, locale: this.locale, onDismiss: this.dismissNotification, onHoverChange: event => this.handleNotificationHoverChange(event) })))), this.contextMenuState && this.contextMenuState.items.length > 0 && (h("kritzel-context-menu", { key: '56f38790f477d08761d7542ed3794c52f1f73815', class: "context-menu", items: this.contextMenuState.items, objects: this.contextMenuState.objects, style: {
1095
1098
  position: 'absolute',
1096
1099
  left: `${this.contextMenuState.position.x}px`,
1097
1100
  top: `${this.contextMenuState.position.y}px`,
1098
1101
  zIndex: '10002',
1099
- }, onActionSelected: event => this.handleContextMenuActionSelected(event), onClose: () => this.hideContextMenu() })), h("kritzel-sync-indicator", { key: '9622af1634a939d6689d5a133496d536f5d7865f', visible: this.isSyncing, text: "Syncing..." }), h("kritzel-loading-overlay", { key: '00f142a3eb8b23fbd0bdb6ec53ae95855434516c', visible: this.isLoadingOverlayVisible, text: this.resolvedTerms['editor.loading'] ?? 'Loading...' }), h("kritzel-engine", { key: '39b1d7bfce0a5347fec60cd135d6db8fb4250bfa', ref: el => {
1102
+ }, onActionSelected: event => this.handleContextMenuActionSelected(event), onClose: () => this.hideContextMenu() })), h("kritzel-sync-indicator", { key: '4957b8bae0d7087d586c9d0c6da82cae905d7d08', visible: this.isSyncingIndicatorVisible, text: "Syncing..." }), h("kritzel-loading-overlay", { key: 'e2e99dc452245a2edf7a575ea5fb60aa91be20df', visible: this.isLoadingOverlayVisible, text: this.resolvedTerms['editor.loading'] ?? 'Loading...' }), h("kritzel-engine", { key: 'fcebe1cc1237c8649461f03679f9c76c05dde9c4', ref: el => {
1100
1103
  if (el) {
1101
1104
  this.engineRef = el;
1102
1105
  }
1103
- }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, isObjectDistanceFadingActive: this.isObjectDistanceFadingActive, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, isPanningEnabled: this.isPanningEnabled, isZoomingEnabled: this.isZoomingEnabled, theme: this.theme, themes: this.themes, licenseKey: this.licenseKey, locale: this.locale, locales: this.locales, fallbackLocale: this.fallbackLocale, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event), onNotificationsChange: event => this.handleNotificationsChange(event), onContextMenuStateChange: event => this.handleContextMenuStateChange(event), onSyncingChange: event => (this.isSyncing = event.detail), onLoadingChange: event => (this.isLoadingOverlayVisible = event.detail) }), h("kritzel-controls", { key: '9a708f21ab92ecc6953a35f5db8001b2403f330e', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
1106
+ }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, isObjectDistanceFadingActive: this.isObjectDistanceFadingActive, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, isPanningEnabled: this.isPanningEnabled, isZoomingEnabled: this.isZoomingEnabled, theme: this.theme, themes: this.themes, licenseKey: this.licenseKey, locale: this.locale, locales: this.locales, fallbackLocale: this.fallbackLocale, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event), onIsSyncing: event => this.handleIsSyncingChange(event), onNotificationsChange: event => this.handleNotificationsChange(event), onContextMenuStateChange: event => this.handleContextMenuStateChange(event), onLoadingChange: event => (this.isLoadingOverlayVisible = event.detail) }), h("kritzel-controls", { key: '72b1a3f80bfedb3843d0d54159ad47793db69977', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
1104
1107
  if (el) {
1105
1108
  this.controlsRef = el;
1106
1109
  }
1107
- }, controls: this.normalizedControls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: '6a2b1cd72099db86952ac31aad9655693d0a6a0d', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: 'b3756514bf8de6de8ac7586c626f9759da7f231d', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: 'd5e118bc4d60b867006bac287c5516baf3aa890e', class: "top-right-buttons" }, h("kritzel-settings", { key: 'e4065d36beb9283cdbbf3ae9800f4f8011c0b4f0', ref: el => {
1110
+ }, controls: this.normalizedControls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: '1684a320f1806ae9fdfcfcff115d01f5788737e7', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: '8e85652ded70df043d79c9cd73b226aaefa5d6d4', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: 'a836056bdae11324f4ce79da4b991281c1985358', class: "top-right-buttons" }, h("kritzel-settings", { key: 'e68f4e79bc053e03dc37c18ee153758d284b0d34', ref: el => {
1108
1111
  if (el) {
1109
1112
  this.settingsRef = el;
1110
1113
  }
1111
- }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], availableLocales: this.availableLocaleOptions, settings: this.currentSettingsConfig, terms: this.resolvedTerms, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '4e18d9b42c9e7fef9433577b983c508559461da2', ref: el => {
1114
+ }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], availableLocales: this.availableLocaleOptions, settings: this.currentSettingsConfig, terms: this.resolvedTerms, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: 'f1e9ea467d11b55dbe75d8b0252fd7f5ed37a1a2', ref: el => {
1112
1115
  if (el) {
1113
1116
  this.exportRef = el;
1114
1117
  }
1115
- }, workspaceName: this.activeWorkspace?.name || 'workspace', terms: this.resolvedTerms, onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '56e6b29c9c3dcd7b68af4a1ef7d34224d592ce34', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '3b90bcc7e583fcf3c6845d222ad181ccf234a423', user: this.user, terms: this.resolvedTerms, onClick: () => this.currentUserDialogRef?.open() }), shouldShowCurrentUser && (h("kritzel-current-user-dialog", { key: 'f87702c5a708b6afdb2bc3760895e3e3650a4cb5', ref: el => {
1118
+ }, workspaceName: this.activeWorkspace?.name || 'workspace', terms: this.resolvedTerms, onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '01bb56bd37bc22e82be5a1175f597cdf724c4834', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '5470ef356a4d6332b380e8c75f02f0fccbe861cc', user: this.user, terms: this.resolvedTerms, onClick: () => this.currentUserDialogRef?.open() }), shouldShowCurrentUser && (h("kritzel-current-user-dialog", { key: '229551b18f0443944a96f7b8e833ff1aefb001f4', ref: el => {
1116
1119
  if (el) {
1117
1120
  this.currentUserDialogRef = el;
1118
1121
  }
1119
- }, user: this.user, terms: this.resolvedTerms, onLogoutRequest: this.handleCurrentUserLogout })), shouldShowLoginButton && h("kritzel-button", { key: '015bc0f4c66352136de66d35d28c20070366933f', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in'), h("kritzel-more-menu", { key: 'b3fdf9fdb2a34508002e82dfdef9e9bdbbe57ecc', items: this.resolvedMoreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: 'bac4fbbfa04c261e2b128e766cc43c1062aec2ff', ref: el => {
1122
+ }, user: this.user, terms: this.resolvedTerms, onLogoutRequest: this.handleCurrentUserLogout })), shouldShowLoginButton && h("kritzel-button", { key: '3d9a8ebbe62084e94348265f1f883bc80e625d9c', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in'), h("kritzel-more-menu", { key: '9f7f763c330b27068bc371d98eb22a80adbf359e', items: this.resolvedMoreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: 'c60b860e22394a44270285dea45f02305a05c545', ref: el => {
1120
1123
  if (el) {
1121
1124
  this.shareDialogRef = el;
1122
1125
  }
1123
- }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: 'a7d52bad9e752ad546adf80d257c6a46de031e76', ref: el => {
1126
+ }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '84d0fab11722a7be1d5824b3284f000502277dfc', ref: el => {
1124
1127
  if (el) {
1125
1128
  this.loginDialogRef = el;
1126
1129
  }
@@ -1985,8 +1988,8 @@ export class KritzelEditor {
1985
1988
  "contextMenuState": {},
1986
1989
  "normalizedControls": {},
1987
1990
  "resolvedMoreMenuItems": {},
1988
- "isSyncing": {},
1989
- "isLoadingOverlayVisible": {}
1991
+ "isLoadingOverlayVisible": {},
1992
+ "isSyncingIndicatorVisible": {}
1990
1993
  };
1991
1994
  }
1992
1995
  static get events() {
@@ -2294,23 +2297,8 @@ export class KritzelEditor {
2294
2297
  }
2295
2298
  }
2296
2299
  }, {
2297
- "method": "syncingChange",
2298
- "name": "syncingChange",
2299
- "bubbles": true,
2300
- "cancelable": true,
2301
- "composed": true,
2302
- "docs": {
2303
- "tags": [],
2304
- "text": "Emitted while remote changes are being applied to the active workspace. Stays silent when the remote holds nothing new."
2305
- },
2306
- "complexType": {
2307
- "original": "boolean",
2308
- "resolved": "boolean",
2309
- "references": {}
2310
- }
2311
- }, {
2312
- "method": "loadingChange",
2313
- "name": "loadingChange",
2300
+ "method": "isSyncing",
2301
+ "name": "isSyncing",
2314
2302
  "bubbles": true,
2315
2303
  "cancelable": true,
2316
2304
  "composed": true,
@@ -252,16 +252,15 @@ export class KritzelEngine {
252
252
  viewportChange;
253
253
  /** Emitted when the awareness state changes (remote user cursors, presence). */
254
254
  awarenessChange;
255
+ /** Emitted when a remote sync starts (`true`, data differs from the local copy) or finishes (`false`). */
256
+ isSyncing;
255
257
  /** Emitted when notifications change. */
256
258
  notificationsChange;
257
259
  /** Emitted when context-menu visibility, items, or position changes. */
258
260
  contextMenuStateChange;
259
261
  /** Emitted when the combined loading state (external `isLoading` prop or internal workspace loading) changes. */
260
262
  loadingChange;
261
- /** Emitted while remote changes are being applied to the active workspace. Stays silent when the remote holds nothing new. */
262
- syncingChange;
263
263
  forceUpdate = 0;
264
- isSyncing = false;
265
264
  /** Manually triggers the `objectsSelectionChange` event. */
266
265
  async triggerSelectionChange() {
267
266
  this.objectsSelectionChange.emit();
@@ -1845,7 +1844,6 @@ export class KritzelEngine {
1845
1844
  _sceneBootstrapOpacity = 1;
1846
1845
  _sceneBootstrapTransitionEnabled = false;
1847
1846
  _sceneBootstrapTransitionTimer = null;
1848
- _remoteChangesUnsubscribe = null;
1849
1847
  _defaultUndoState = {
1850
1848
  canUndo: false,
1851
1849
  canRedo: false,
@@ -1862,17 +1860,6 @@ export class KritzelEngine {
1862
1860
  this.core.store.state.isLoading = this._isWorkspaceLoading || this.isLoading;
1863
1861
  this.loadingChange.emit(this.core.store.state.isLoading);
1864
1862
  }
1865
- syncSyncingState(isSyncing) {
1866
- if (this.isSyncing === isSyncing) {
1867
- return;
1868
- }
1869
- this.isSyncing = isSyncing;
1870
- this.syncingChange.emit(isSyncing);
1871
- }
1872
- clearRemoteChangesSubscription() {
1873
- this._remoteChangesUnsubscribe?.();
1874
- this._remoteChangesUnsubscribe = null;
1875
- }
1876
1863
  isNetworkAvailable() {
1877
1864
  return typeof navigator !== 'undefined' && navigator.onLine;
1878
1865
  }
@@ -1965,7 +1952,6 @@ export class KritzelEngine {
1965
1952
  disconnectedCallback() {
1966
1953
  this.throttledPointerMoveMulti.cancel();
1967
1954
  this._revealedImageKeys.clear();
1968
- this.clearRemoteChangesSubscription();
1969
1955
  if (this._sceneBootstrapTransitionTimer !== null) {
1970
1956
  clearTimeout(this._sceneBootstrapTransitionTimer);
1971
1957
  this._sceneBootstrapTransitionTimer = null;
@@ -2220,7 +2206,6 @@ export class KritzelEngine {
2220
2206
  this._workspaceInitializationTargetKey = targetKey;
2221
2207
  try {
2222
2208
  await initializationPromise;
2223
- this.trackRemoteSynchronization();
2224
2209
  }
2225
2210
  finally {
2226
2211
  // Only the most recent init clears loading state to prevent race conditions
@@ -2232,45 +2217,6 @@ export class KritzelEngine {
2232
2217
  }
2233
2218
  }
2234
2219
  }
2235
- /**
2236
- * Reports syncing only while remote data is actually being reconciled into the
2237
- * active workspace. Yjs suppresses updates that carry nothing new, so a workspace
2238
- * that already matches the remote never reports syncing at all.
2239
- */
2240
- trackRemoteSynchronization() {
2241
- this.clearRemoteChangesSubscription();
2242
- this.syncSyncingState(false);
2243
- const initializedObjects = this.core.store.objects;
2244
- if (!initializedObjects?.hasNetworkSyncProvider || !this.isNetworkAvailable()) {
2245
- return;
2246
- }
2247
- if (initializedObjects.supportsRemoteChangeDetection) {
2248
- this._remoteChangesUnsubscribe = initializedObjects.onRemoteChangesApplied(() => {
2249
- if (this.core.store.objects !== initializedObjects) {
2250
- return;
2251
- }
2252
- this.syncSyncingState(true);
2253
- });
2254
- // The network provider may have already applied remote changes between
2255
- // object-map initialization and this subscription (e.g. an already-connected
2256
- // shared socket resolves the sync handshake almost immediately). Without this
2257
- // check that update is missed entirely and the indicator never appears.
2258
- if (initializedObjects.hasAppliedRemoteChanges) {
2259
- this.syncSyncingState(true);
2260
- }
2261
- }
2262
- else {
2263
- // Custom providers without an update origin cannot be diffed, so fall back to reporting the whole handshake.
2264
- this.syncSyncingState(true);
2265
- }
2266
- void initializedObjects.whenNetworkSynced().finally(() => {
2267
- if (this.core.store.objects !== initializedObjects) {
2268
- return;
2269
- }
2270
- this.clearRemoteChangesSubscription();
2271
- this.syncSyncingState(false);
2272
- });
2273
- }
2274
2220
  emitObjectsChange() {
2275
2221
  const objectsMap = this.core.store.objects;
2276
2222
  if (!objectsMap) {
@@ -2304,6 +2250,9 @@ export class KritzelEngine {
2304
2250
  emitAwarenessChange(states) {
2305
2251
  this.awarenessChange.emit(states);
2306
2252
  }
2253
+ emitIsSyncing(isSyncing) {
2254
+ this.isSyncing.emit(isSyncing);
2255
+ }
2307
2256
  emitObjectsInViewportChange() {
2308
2257
  const visibleObjects = this.core.store.objectsInViewport;
2309
2258
  this.objectsInViewportChange.emit(visibleObjects);
@@ -3521,8 +3470,7 @@ export class KritzelEngine {
3521
3470
  }
3522
3471
  static get states() {
3523
3472
  return {
3524
- "forceUpdate": {},
3525
- "isSyncing": {}
3473
+ "forceUpdate": {}
3526
3474
  };
3527
3475
  }
3528
3476
  static get events() {
@@ -3827,6 +3775,21 @@ export class KritzelEngine {
3827
3775
  }
3828
3776
  }
3829
3777
  }
3778
+ }, {
3779
+ "method": "isSyncing",
3780
+ "name": "isSyncing",
3781
+ "bubbles": true,
3782
+ "cancelable": true,
3783
+ "composed": true,
3784
+ "docs": {
3785
+ "tags": [],
3786
+ "text": "Emitted when a remote sync starts (`true`, data differs from the local copy) or finishes (`false`)."
3787
+ },
3788
+ "complexType": {
3789
+ "original": "boolean",
3790
+ "resolved": "boolean",
3791
+ "references": {}
3792
+ }
3830
3793
  }, {
3831
3794
  "method": "notificationsChange",
3832
3795
  "name": "notificationsChange",
@@ -3886,21 +3849,6 @@ export class KritzelEngine {
3886
3849
  "resolved": "boolean",
3887
3850
  "references": {}
3888
3851
  }
3889
- }, {
3890
- "method": "syncingChange",
3891
- "name": "syncingChange",
3892
- "bubbles": true,
3893
- "cancelable": true,
3894
- "composed": true,
3895
- "docs": {
3896
- "tags": [],
3897
- "text": "Emitted while remote changes are being applied to the active workspace. Stays silent when the remote holds nothing new."
3898
- },
3899
- "complexType": {
3900
- "original": "boolean",
3901
- "resolved": "boolean",
3902
- "references": {}
3903
- }
3904
3852
  }];
3905
3853
  }
3906
3854
  static get methods() {
@@ -3,4 +3,4 @@
3
3
  * This file is auto-generated by the version bump scripts.
4
4
  * Do not modify manually.
5
5
  */
6
- export const KRITZEL_VERSION = '0.4.23';
6
+ export const KRITZEL_VERSION = '0.4.25';
@@ -1,6 +1,6 @@
1
1
  export { g as getAssetPath, r as render, s as setAssetPath, a as setNonce, b as setPlatformOptions } from './p-B43upypT.js';
2
2
  export { K as KritzelBaseObject, b as KritzelLine, a as KritzelPath } from './p-bAacqNHq.js';
3
- export { u as APP_STATE_MIGRATIONS, A as AssetNotFoundError, D as DE_LOCALE, E as EN_LOCALE, F as FR_LOCALE, I as IndexedDBAssetProvider, s as KritzelAlignment, o as KritzelAnchorManager, n as KritzelAssetResolver, e as KritzelBaseTool, f as KritzelBrushTool, l as KritzelCursorHelper, d as KritzelCustomElement, r as KritzelCustomElementRendererRegistry, h as KritzelEraserTool, b as KritzelGroup, a as KritzelImage, i as KritzelImageTool, q as KritzelLicenseManager, g as KritzelLineTool, p as KritzelLocalizationManager, m as KritzelSelectionTool, c as KritzelShape, k as KritzelShapeTool, K as KritzelText, j as KritzelTextTool, S as ShapeType, W as WORKSPACE_MIGRATIONS, t as runMigrations } from './p-EijwLEZx.js';
3
+ export { u as APP_STATE_MIGRATIONS, A as AssetNotFoundError, D as DE_LOCALE, E as EN_LOCALE, F as FR_LOCALE, I as IndexedDBAssetProvider, s as KritzelAlignment, o as KritzelAnchorManager, n as KritzelAssetResolver, e as KritzelBaseTool, f as KritzelBrushTool, l as KritzelCursorHelper, d as KritzelCustomElement, r as KritzelCustomElementRendererRegistry, h as KritzelEraserTool, b as KritzelGroup, a as KritzelImage, i as KritzelImageTool, q as KritzelLicenseManager, g as KritzelLineTool, p as KritzelLocalizationManager, m as KritzelSelectionTool, c as KritzelShape, k as KritzelShapeTool, K as KritzelText, j as KritzelTextTool, S as ShapeType, W as WORKSPACE_MIGRATIONS, t as runMigrations } from './p-gJcH-huF.js';
4
4
  import * as Y from 'yjs';
5
5
  import { IndexeddbPersistence } from 'y-indexeddb';
6
6
  import { WebsocketProvider } from 'y-websocket';
@@ -603,13 +603,10 @@ class WebSocketSyncProvider {
603
603
  provider;
604
604
  isConnected = false;
605
605
  _quiet = false;
606
- _isSynced = false;
607
- _syncedResolvers = [];
608
606
  get awareness() {
609
607
  return this.provider.awareness;
610
608
  }
611
- /** y-websocket applies remote updates with the underlying provider as the Yjs transaction origin. */
612
- get updateOrigin() {
609
+ get rawProvider() {
613
610
  return this.provider;
614
611
  }
615
612
  constructor(docName, doc, options) {
@@ -658,29 +655,11 @@ class WebSocketSyncProvider {
658
655
  }
659
656
  });
660
657
  this.provider.on('sync', (synced) => {
661
- if (!synced) {
662
- return;
663
- }
664
- this._isSynced = true;
665
- this.releaseSyncedWaiters();
666
- if (!this._quiet) {
658
+ if (synced && !this._quiet) {
667
659
  console.info('WebSocket synced');
668
660
  }
669
661
  });
670
662
  }
671
- releaseSyncedWaiters() {
672
- const resolvers = this._syncedResolvers;
673
- this._syncedResolvers = [];
674
- resolvers.forEach(resolve => resolve());
675
- }
676
- async whenSynced() {
677
- if (this._isSynced || this.provider.synced) {
678
- return;
679
- }
680
- return new Promise(resolve => {
681
- this._syncedResolvers.push(resolve);
682
- });
683
- }
684
663
  async connect() {
685
664
  if (this.isConnected) {
686
665
  return;
@@ -712,8 +691,6 @@ class WebSocketSyncProvider {
712
691
  this.provider.disconnect();
713
692
  }
714
693
  this.isConnected = false;
715
- this._isSynced = false;
716
- this.releaseSyncedWaiters();
717
694
  }
718
695
  async reconnect() {
719
696
  this.disconnect();
@@ -724,8 +701,6 @@ class WebSocketSyncProvider {
724
701
  this.provider.destroy();
725
702
  }
726
703
  this.isConnected = false;
727
- this._isSynced = false;
728
- this.releaseSyncedWaiters();
729
704
  }
730
705
  }
731
706
 
@@ -747,12 +722,10 @@ class HocuspocusSyncProvider {
747
722
  _connectionStatus = 'disconnected';
748
723
  visibilityHandler = null;
749
724
  onlineHandler = null;
750
- syncedResolvers = [];
751
725
  get awareness() {
752
726
  return this.provider.awareness;
753
727
  }
754
- /** HocuspocusProvider applies remote updates with itself as the Yjs transaction origin. */
755
- get updateOrigin() {
728
+ get rawProvider() {
756
729
  return this.provider;
757
730
  }
758
731
  get connectionStatus() {
@@ -811,7 +784,6 @@ class HocuspocusSyncProvider {
811
784
  }
812
785
  this.isSynced = true;
813
786
  this._connectionStatus = 'synced';
814
- this.releaseSyncedWaiters();
815
787
  if (!options?.quiet) {
816
788
  console.info(`Hocuspocus synced: ${name}`);
817
789
  }
@@ -1022,19 +994,6 @@ class HocuspocusSyncProvider {
1022
994
  this.disconnect();
1023
995
  return this.connect();
1024
996
  }
1025
- releaseSyncedWaiters() {
1026
- const resolvers = this.syncedResolvers;
1027
- this.syncedResolvers = [];
1028
- resolvers.forEach(resolve => resolve());
1029
- }
1030
- async whenSynced() {
1031
- if (this.isSynced || this.isDestroyed || this.provider.isSynced) {
1032
- return;
1033
- }
1034
- return new Promise(resolve => {
1035
- this.syncedResolvers.push(resolve);
1036
- });
1037
- }
1038
997
  disconnect() {
1039
998
  // Cancel any pending connection attempt
1040
999
  if (this.connectTimeout) {
@@ -1056,7 +1015,6 @@ class HocuspocusSyncProvider {
1056
1015
  this.isConnected = false;
1057
1016
  this.isSynced = false;
1058
1017
  this._connectionStatus = 'disconnected';
1059
- this.releaseSyncedWaiters();
1060
1018
  }
1061
1019
  destroy() {
1062
1020
  // Mark as destroyed first to prevent any callbacks from doing work
@@ -1076,7 +1034,6 @@ class HocuspocusSyncProvider {
1076
1034
  this.isConnected = false;
1077
1035
  this.isSynced = false;
1078
1036
  this._connectionStatus = 'disconnected';
1079
- this.releaseSyncedWaiters();
1080
1037
  }
1081
1038
  }
1082
1039
 
@@ -1,6 +1,6 @@
1
1
  import { p as proxyCustomElement, H, c as createEvent, h, d as Host, t as transformTag } from './p-B43upypT.js';
2
2
  import { K as KritzelIconRegistry, d as defineCustomElement$s } from './p-CSuU8frA.js';
3
- import { v as DEFAULT_STROKE_SIZES, w as DEFAULT_FONT_SIZES, S as ShapeType, m as KritzelSelectionTool, f as KritzelBrushTool, h as KritzelEraserTool, g as KritzelLineTool, k as KritzelShapeTool, j as KritzelTextTool, i as KritzelImageTool, s as KritzelAlignment, x as DEFAULT_SYNC_CONFIG, y as KritzelSelectionGroup, z as KritzelSelectionBox, B as KritzelKeyboardHelper, C as defineCustomElement$x } from './p-EijwLEZx.js';
3
+ import { v as DEFAULT_STROKE_SIZES, w as DEFAULT_FONT_SIZES, S as ShapeType, m as KritzelSelectionTool, f as KritzelBrushTool, h as KritzelEraserTool, g as KritzelLineTool, k as KritzelShapeTool, j as KritzelTextTool, i as KritzelImageTool, s as KritzelAlignment, x as DEFAULT_SYNC_CONFIG, y as KritzelSelectionGroup, z as KritzelSelectionBox, B as KritzelKeyboardHelper, C as defineCustomElement$x } from './p-gJcH-huF.js';
4
4
  import { D as DEFAULT_COLOR_PALETTE, T as ThemeHelper, d as darkTheme, l as lightTheme } from './p-7I4Uzjrw.js';
5
5
  import { D as DEFAULT_TEXT_TOOL_AVAILABLE_FONTS, r as resolveTextToolAvailableFonts, K as KritzelFontRegistry } from './p-DJkKlUyZ.js';
6
6
  import { A as ABSOLUTE_SCALE_MAX, a as ABSOLUTE_SCALE_MIN, d as defineCustomElement$4 } from './p-DtnMdWWB.js';
@@ -39,7 +39,7 @@ import { d as defineCustomElement$i } from './p-DKGg-76-.js';
39
39
  import { d as defineCustomElement$h } from './p-CrHvaLRV.js';
40
40
  import { d as defineCustomElement$g } from './p-jIKskj3S.js';
41
41
  import { d as defineCustomElement$f } from './p-BPsKYMH6.js';
42
- import { d as defineCustomElement$e } from './p-Cb-xlpsJ.js';
42
+ import { d as defineCustomElement$e } from './p-0fhjWRmT.js';
43
43
  import { d as defineCustomElement$d } from './p-BFYtCsZu.js';
44
44
  import { d as defineCustomElement$c } from './p-CwZ3KKFq.js';
45
45
  import { d as defineCustomElement$b } from './p-BozrueXV.js';
@@ -2957,8 +2957,7 @@ const KritzelEditor$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEditor ext
2957
2957
  this.login = createEvent(this, "login");
2958
2958
  this.isPublicChange = createEvent(this, "isPublicChange");
2959
2959
  this.awarenessChange = createEvent(this, "awarenessChange");
2960
- this.syncingChange = createEvent(this, "syncingChange");
2961
- this.loadingChange = createEvent(this, "loadingChange");
2960
+ this.isSyncing = createEvent(this, "isSyncing");
2962
2961
  }
2963
2962
  get host() { return this; }
2964
2963
  scaleMax = ABSOLUTE_SCALE_MAX;
@@ -3198,9 +3197,7 @@ const KritzelEditor$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEditor ext
3198
3197
  login;
3199
3198
  isPublicChange;
3200
3199
  awarenessChange;
3201
- /** Emitted while remote changes are being applied to the active workspace. Stays silent when the remote holds nothing new. */
3202
- syncingChange;
3203
- loadingChange;
3200
+ isSyncing;
3204
3201
  isEngineReady = false;
3205
3202
  isControlsReady = false;
3206
3203
  isWorkspaceManagerReady = false;
@@ -3222,8 +3219,8 @@ const KritzelEditor$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEditor ext
3222
3219
  contextMenuState;
3223
3220
  normalizedControls = [];
3224
3221
  resolvedMoreMenuItems = [];
3225
- isSyncing = false;
3226
3222
  isLoadingOverlayVisible = false;
3223
+ isSyncingIndicatorVisible = false;
3227
3224
  notificationDismissTimeout;
3228
3225
  notificationDismissAnimationTimeout;
3229
3226
  notificationDisplayDurationMs = 5000;
@@ -3706,6 +3703,11 @@ const KritzelEditor$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEditor ext
3706
3703
  event.stopPropagation();
3707
3704
  this.awarenessChange.emit(event.detail);
3708
3705
  }
3706
+ handleIsSyncingChange(event) {
3707
+ event.stopPropagation();
3708
+ this.isSyncingIndicatorVisible = event.detail;
3709
+ this.isSyncing.emit(event.detail);
3710
+ }
3709
3711
  handleNotificationsChange(event) {
3710
3712
  event.stopPropagation();
3711
3713
  this.clearNotificationDismissAnimationTimer();
@@ -4019,40 +4021,40 @@ const KritzelEditor$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEditor ext
4019
4021
  const isLoggedIn = this.isLoggedIn;
4020
4022
  const shouldShowCurrentUser = isLoggedIn;
4021
4023
  const shouldShowLoginButton = this.isReady && !!this.loginConfig && !isLoggedIn;
4022
- return (h(Host, { key: 'ff7d505697bd4c4bd840dadcb04a934b7e243a01' }, h("div", { key: 'b40076c3c79ad3f879e80c58b412b79266de2ea8', class: "editor-content", style: {
4024
+ return (h(Host, { key: 'a24350a0c12d99ccb0d0ec3ab5975d0f1bf7f861' }, h("div", { key: 'bd7029567aeef8cba5290c2bf9937db1af113475', class: "editor-content", style: {
4023
4025
  opacity: this.isEditorVisible ? '1' : '0',
4024
4026
  visibility: this.isEditorVisible ? 'visible' : 'hidden',
4025
4027
  transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out',
4026
- } }, h("div", { key: '1b1171eea60a36ad06da55a3da564bc356526266', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '48b59f3f57ace57debc19a295d4fb642e8c3b23d', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, terms: this.resolvedTerms, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'c66a6faae8bf7115dcce47630ad820af9ba76eb0', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), this.activeNotification && (h("div", { key: '834baedc5f20328deb4ee586f693313306895a71', class: "top-center-notification-layer", role: "presentation" }, h("div", { key: 'f800508a2e076ee3e89820ffff4df81842b175b3', class: { 'top-center-notification-container': true, 'is-dismissing': this.isNotificationDismissing }, role: "presentation" }, h("kritzel-notification-card", { key: '2835ea84e8fa92c41637adaa29d9005f209b2da9', notification: this.activeNotification, locale: this.locale, onDismiss: this.dismissNotification, onHoverChange: event => this.handleNotificationHoverChange(event) })))), this.contextMenuState && this.contextMenuState.items.length > 0 && (h("kritzel-context-menu", { key: '6c49e899b7f933d3f06cd1f8696a590d542214a7', class: "context-menu", items: this.contextMenuState.items, objects: this.contextMenuState.objects, style: {
4028
+ } }, h("div", { key: 'f628dbd94d88c9bdb313a59d73ce86302c90e375', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '5a82d054da31e47d3f8b5c6c403949a5fb97b9dd', visible: this.isWorkspaceManagerVisible, workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, terms: this.resolvedTerms, onWorkspaceChange: event => (this.activeWorkspace = event.detail), onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), h("kritzel-back-to-content", { key: 'a5bccef36c8a49ef2cb7ec029def1c7ba71d1c31', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), this.activeNotification && (h("div", { key: 'c5c359b199528dd7b1b64a6a32ef349037357c5a', class: "top-center-notification-layer", role: "presentation" }, h("div", { key: 'a41cd6c67c56626c2b6f0eb12193af1f80d6a254', class: { 'top-center-notification-container': true, 'is-dismissing': this.isNotificationDismissing }, role: "presentation" }, h("kritzel-notification-card", { key: 'fb49769368ddf0fc74998a96dd26dc446ff2b386', notification: this.activeNotification, locale: this.locale, onDismiss: this.dismissNotification, onHoverChange: event => this.handleNotificationHoverChange(event) })))), this.contextMenuState && this.contextMenuState.items.length > 0 && (h("kritzel-context-menu", { key: '56f38790f477d08761d7542ed3794c52f1f73815', class: "context-menu", items: this.contextMenuState.items, objects: this.contextMenuState.objects, style: {
4027
4029
  position: 'absolute',
4028
4030
  left: `${this.contextMenuState.position.x}px`,
4029
4031
  top: `${this.contextMenuState.position.y}px`,
4030
4032
  zIndex: '10002',
4031
- }, onActionSelected: event => this.handleContextMenuActionSelected(event), onClose: () => this.hideContextMenu() })), h("kritzel-sync-indicator", { key: '9622af1634a939d6689d5a133496d536f5d7865f', visible: this.isSyncing, text: "Syncing..." }), h("kritzel-loading-overlay", { key: '00f142a3eb8b23fbd0bdb6ec53ae95855434516c', visible: this.isLoadingOverlayVisible, text: this.resolvedTerms['editor.loading'] ?? 'Loading...' }), h("kritzel-engine", { key: '39b1d7bfce0a5347fec60cd135d6db8fb4250bfa', ref: el => {
4033
+ }, onActionSelected: event => this.handleContextMenuActionSelected(event), onClose: () => this.hideContextMenu() })), h("kritzel-sync-indicator", { key: '4957b8bae0d7087d586c9d0c6da82cae905d7d08', visible: this.isSyncingIndicatorVisible, text: "Syncing..." }), h("kritzel-loading-overlay", { key: 'e2e99dc452245a2edf7a575ea5fb60aa91be20df', visible: this.isLoadingOverlayVisible, text: this.resolvedTerms['editor.loading'] ?? 'Loading...' }), h("kritzel-engine", { key: 'fcebe1cc1237c8649461f03679f9c76c05dde9c4', ref: el => {
4032
4034
  if (el) {
4033
4035
  this.engineRef = el;
4034
4036
  }
4035
- }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, isObjectDistanceFadingActive: this.isObjectDistanceFadingActive, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, isPanningEnabled: this.isPanningEnabled, isZoomingEnabled: this.isZoomingEnabled, theme: this.theme, themes: this.themes, licenseKey: this.licenseKey, locale: this.locale, locales: this.locales, fallbackLocale: this.fallbackLocale, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event), onNotificationsChange: event => this.handleNotificationsChange(event), onContextMenuStateChange: event => this.handleContextMenuStateChange(event), onSyncingChange: event => (this.isSyncing = event.detail), onLoadingChange: event => (this.isLoadingOverlayVisible = event.detail) }), h("kritzel-controls", { key: '9a708f21ab92ecc6953a35f5db8001b2403f330e', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
4037
+ }, workspace: this.activeWorkspace, activeWorkspaceId: this.activeWorkspaceId, editorId: this.editorId, syncConfig: this.syncConfig, assetStorageConfig: this.assetStorageConfig, user: this.user, scaleMax: this.scaleMax, lockDrawingScale: this.lockDrawingScale, isObjectDistanceFadingActive: this.isObjectDistanceFadingActive, scaleMin: this.scaleMin, cursorTarget: this.cursorTarget, isLoading: this.isLoading, viewportBoundaryLeft: this.viewportBoundaryLeft, viewportBoundaryRight: this.viewportBoundaryRight, viewportBoundaryTop: this.viewportBoundaryTop, viewportBoundaryBottom: this.viewportBoundaryBottom, isPanningEnabled: this.isPanningEnabled, isZoomingEnabled: this.isZoomingEnabled, theme: this.theme, themes: this.themes, licenseKey: this.licenseKey, locale: this.locale, locales: this.locales, fallbackLocale: this.fallbackLocale, debugInfo: this.debugInfo, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.handleWorkspacesChange(event), onActiveWorkspaceChange: event => this.handleActiveWorkspaceChange(event), onObjectsChange: event => this.handleObjectsChange(event), onObjectsAdded: event => this.handleObjectsAdded(event), onObjectsRemoved: event => this.handleObjectsRemoved(event), onObjectsUpdated: event => this.handleObjectsUpdated(event), onUndoStateChange: event => this.handleUndoStateChange(event), onObjectsInViewportChange: event => this.handleObjectsInViewportChange(event), onViewportChange: event => this.handleViewportChange(event), onAwarenessChange: event => this.handleAwarenessChange(event), onIsSyncing: event => this.handleIsSyncingChange(event), onNotificationsChange: event => this.handleNotificationsChange(event), onContextMenuStateChange: event => this.handleContextMenuStateChange(event), onLoadingChange: event => (this.isLoadingOverlayVisible = event.detail) }), h("kritzel-controls", { key: '72b1a3f80bfedb3843d0d54159ad47793db69977', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
4036
4038
  if (el) {
4037
4039
  this.controlsRef = el;
4038
4040
  }
4039
- }, controls: this.normalizedControls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: '6a2b1cd72099db86952ac31aad9655693d0a6a0d', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: 'b3756514bf8de6de8ac7586c626f9759da7f231d', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: 'd5e118bc4d60b867006bac287c5516baf3aa890e', class: "top-right-buttons" }, h("kritzel-settings", { key: 'e4065d36beb9283cdbbf3ae9800f4f8011c0b4f0', ref: el => {
4041
+ }, controls: this.normalizedControls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: '1684a320f1806ae9fdfcfcff115d01f5788737e7', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: '8e85652ded70df043d79c9cd73b226aaefa5d6d4', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: 'a836056bdae11324f4ce79da4b991281c1985358', class: "top-right-buttons" }, h("kritzel-settings", { key: 'e68f4e79bc053e03dc37c18ee153758d284b0d34', ref: el => {
4040
4042
  if (el) {
4041
4043
  this.settingsRef = el;
4042
4044
  }
4043
- }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], availableLocales: this.availableLocaleOptions, settings: this.currentSettingsConfig, terms: this.resolvedTerms, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: '4e18d9b42c9e7fef9433577b983c508559461da2', ref: el => {
4045
+ }, shortcuts: this.shortcuts, availableThemes: this.themes && this.themes.length > 0 ? this.themes.map(t => t.name) : ['light', 'dark'], availableLocales: this.availableLocaleOptions, settings: this.currentSettingsConfig, terms: this.resolvedTerms, onSettingsChange: event => this.handleSettingsChange(event) }), h("kritzel-export", { key: 'f1e9ea467d11b55dbe75d8b0252fd7f5ed37a1a2', ref: el => {
4044
4046
  if (el) {
4045
4047
  this.exportRef = el;
4046
4048
  }
4047
- }, workspaceName: this.activeWorkspace?.name || 'workspace', terms: this.resolvedTerms, onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '56e6b29c9c3dcd7b68af4a1ef7d34224d592ce34', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '3b90bcc7e583fcf3c6845d222ad181ccf234a423', user: this.user, terms: this.resolvedTerms, onClick: () => this.currentUserDialogRef?.open() }), shouldShowCurrentUser && (h("kritzel-current-user-dialog", { key: 'f87702c5a708b6afdb2bc3760895e3e3650a4cb5', ref: el => {
4049
+ }, workspaceName: this.activeWorkspace?.name || 'workspace', terms: this.resolvedTerms, onExportPng: () => this.engineRef.exportViewportAsPng(), onExportSvg: () => this.engineRef.exportViewportAsSvg(), onExportJson: event => this.engineRef.downloadAsJson(event.detail) }), h("kritzel-active-users", { key: '01bb56bd37bc22e82be5a1175f597cdf724c4834', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '5470ef356a4d6332b380e8c75f02f0fccbe861cc', user: this.user, terms: this.resolvedTerms, onClick: () => this.currentUserDialogRef?.open() }), shouldShowCurrentUser && (h("kritzel-current-user-dialog", { key: '229551b18f0443944a96f7b8e833ff1aefb001f4', ref: el => {
4048
4050
  if (el) {
4049
4051
  this.currentUserDialogRef = el;
4050
4052
  }
4051
- }, user: this.user, terms: this.resolvedTerms, onLogoutRequest: this.handleCurrentUserLogout })), shouldShowLoginButton && h("kritzel-button", { key: '015bc0f4c66352136de66d35d28c20070366933f', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in'), h("kritzel-more-menu", { key: 'b3fdf9fdb2a34508002e82dfdef9e9bdbbe57ecc', items: this.resolvedMoreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: 'bac4fbbfa04c261e2b128e766cc43c1062aec2ff', ref: el => {
4053
+ }, user: this.user, terms: this.resolvedTerms, onLogoutRequest: this.handleCurrentUserLogout })), shouldShowLoginButton && h("kritzel-button", { key: '3d9a8ebbe62084e94348265f1f883bc80e625d9c', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in'), h("kritzel-more-menu", { key: '9f7f763c330b27068bc371d98eb22a80adbf359e', items: this.resolvedMoreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: 'c60b860e22394a44270285dea45f02305a05c545', ref: el => {
4052
4054
  if (el) {
4053
4055
  this.shareDialogRef = el;
4054
4056
  }
4055
- }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: 'a7d52bad9e752ad546adf80d257c6a46de031e76', ref: el => {
4057
+ }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '84d0fab11722a7be1d5824b3284f000502277dfc', ref: el => {
4056
4058
  if (el) {
4057
4059
  this.loginDialogRef = el;
4058
4060
  }
@@ -4160,8 +4162,8 @@ const KritzelEditor$1 = /*@__PURE__*/ proxyCustomElement(class KritzelEditor ext
4160
4162
  "contextMenuState": [32],
4161
4163
  "normalizedControls": [32],
4162
4164
  "resolvedMoreMenuItems": [32],
4163
- "isSyncing": [32],
4164
4165
  "isLoadingOverlayVisible": [32],
4166
+ "isSyncingIndicatorVisible": [32],
4165
4167
  "getObjectById": [64],
4166
4168
  "addObject": [64],
4167
4169
  "addObjects": [64],
@@ -1,4 +1,4 @@
1
- import { G as KritzelEngine$1, C as defineCustomElement$1 } from './p-EijwLEZx.js';
1
+ import { G as KritzelEngine$1, C as defineCustomElement$1 } from './p-gJcH-huF.js';
2
2
 
3
3
  const KritzelEngine = KritzelEngine$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -1,4 +1,4 @@
1
- import { K as KritzelSettings$1, d as defineCustomElement$1 } from './p-Cb-xlpsJ.js';
1
+ import { K as KritzelSettings$1, d as defineCustomElement$1 } from './p-0fhjWRmT.js';
2
2
 
3
3
  const KritzelSettings = KritzelSettings$1;
4
4
  const defineCustomElement = defineCustomElement$1;
@@ -12,7 +12,7 @@ import { d as defineCustomElement$1 } from './p-BozrueXV.js';
12
12
  * This file is auto-generated by the version bump scripts.
13
13
  * Do not modify manually.
14
14
  */
15
- const KRITZEL_VERSION = '0.4.23';
15
+ const KRITZEL_VERSION = '0.4.25';
16
16
 
17
17
  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-tab-panel{display:none}.settings-tab-panel.is-active{display:block}.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:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.settings-description{font-size:12px;color:var(--kritzel-settings-description-color, #888888);margin:0;line-height:1.4}.shortcuts-list{display:flex;flex-direction:column;gap:24px}.shortcuts-category{display:flex;flex-direction:column;gap:8px}.shortcuts-category-title{font-size:14px;font-weight:600;color:var(--kritzel-settings-label-color, #333333);margin:0 0 4px 0}.shortcuts-group{display:flex;flex-direction:column;gap:4px}.shortcut-item{display:flex;justify-content:space-between;align-items:center;padding:6px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-item-bg, rgba(0, 0, 0, 0.02))}.shortcut-label{font-size:14px;color:var(--kritzel-settings-content-text-color, #666666)}.shortcut-key{font-family:monospace;font-size:12px;padding:2px 8px;border-radius:4px;background:var(--kritzel-settings-shortcut-key-bg, #f0f0f0);color:var(--kritzel-settings-shortcut-key-color, #333333);border:1px solid var(--kritzel-settings-shortcut-key-border, #ddd)}`;
18
18