kritzel-stencil 0.3.33 → 0.3.35

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 (158) hide show
  1. package/dist/cjs/index-Xav9JFHg.js +2 -2
  2. package/dist/cjs/index.cjs.js +1 -1
  3. package/dist/cjs/{kritzel-active-users_45.cjs.entry.js → kritzel-active-users_46.cjs.entry.js} +3223 -76
  4. package/dist/cjs/loader.cjs.js +1 -1
  5. package/dist/cjs/{schema.constants-BHr5Bcqs.js → schema.constants-Di56GD6q.js} +16 -3
  6. package/dist/cjs/stencil.cjs.js +1 -1
  7. package/dist/collection/classes/objects/shape.class.js +14 -3
  8. package/dist/collection/collection-manifest.json +1 -0
  9. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +5 -0
  10. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +26 -18
  11. package/dist/collection/components/core/kritzel-engine/kritzel-engine.css +0 -41
  12. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +20 -2
  13. package/dist/collection/components/core/kritzel-watermark/kritzel-watermark.js +1 -1
  14. package/dist/collection/components/shared/kritzel-avatar/kritzel-avatar.js +3 -3
  15. package/dist/collection/components/shared/kritzel-button/kritzel-button.css +1 -0
  16. package/dist/collection/components/shared/kritzel-button/kritzel-button.js +2 -2
  17. package/dist/collection/components/shared/kritzel-color/kritzel-color.js +2 -2
  18. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +1 -1
  19. package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
  20. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +1 -1
  21. package/dist/collection/components/shared/kritzel-input/kritzel-input.js +1 -1
  22. package/dist/collection/components/shared/kritzel-master-detail/kritzel-master-detail.js +3 -3
  23. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +1 -1
  24. package/dist/collection/components/shared/kritzel-menu-item/kritzel-menu-item.js +2 -2
  25. package/dist/collection/components/shared/kritzel-numeric-input/kritzel-numeric-input.js +1 -1
  26. package/dist/collection/components/shared/kritzel-opacity-slider/kritzel-opacity-slider.js +1 -1
  27. package/dist/collection/components/shared/kritzel-pill-tabs/kritzel-pill-tabs.css +10 -0
  28. package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +1 -1
  29. package/dist/collection/components/shared/kritzel-slide-toggle/kritzel-slide-toggle.js +1 -1
  30. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +1 -1
  31. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
  32. package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +2 -2
  33. package/dist/collection/components/ui/kritzel-back-to-content/kritzel-back-to-content.js +1 -1
  34. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +6 -6
  35. package/dist/collection/components/ui/kritzel-current-user/kritzel-current-user.js +1 -8
  36. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.css +10 -0
  37. package/dist/collection/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.js +25 -1
  38. package/dist/collection/components/ui/kritzel-export/kritzel-export.js +1 -1
  39. package/dist/collection/components/ui/kritzel-loading-overlay/kritzel-loading-overlay.css +50 -0
  40. package/dist/collection/components/ui/kritzel-loading-overlay/kritzel-loading-overlay.js +70 -0
  41. package/dist/collection/components/ui/kritzel-login-dialog/kritzel-login-dialog.js +1 -1
  42. package/dist/collection/components/ui/kritzel-more-menu/kritzel-more-menu.js +1 -1
  43. package/dist/collection/components/ui/kritzel-settings/kritzel-settings.js +1 -1
  44. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.css +17 -0
  45. package/dist/collection/components/ui/kritzel-share-dialog/kritzel-share-dialog.js +44 -3
  46. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
  47. package/dist/collection/components/ui/kritzel-zoom-panel/kritzel-zoom-panel.js +1 -1
  48. package/dist/collection/constants/version.js +1 -1
  49. package/dist/collection/themes/dark-theme.js +1 -0
  50. package/dist/collection/themes/light-theme.js +1 -0
  51. package/dist/components/index.d.ts +2 -0
  52. package/dist/components/index.js +1 -1
  53. package/dist/components/kritzel-active-users.js +1 -1
  54. package/dist/components/kritzel-avatar.js +1 -1
  55. package/dist/components/kritzel-awareness-cursors.js +1 -1
  56. package/dist/components/kritzel-back-to-content.js +1 -1
  57. package/dist/components/kritzel-button.js +1 -1
  58. package/dist/components/kritzel-color-palette.js +1 -1
  59. package/dist/components/kritzel-color.js +1 -1
  60. package/dist/components/kritzel-controls.js +1 -1
  61. package/dist/components/kritzel-current-user-dialog.js +1 -1
  62. package/dist/components/kritzel-current-user.js +1 -1
  63. package/dist/components/kritzel-editor.js +1 -1
  64. package/dist/components/kritzel-engine.js +1 -1
  65. package/dist/components/kritzel-export.js +1 -1
  66. package/dist/components/kritzel-font-size.js +1 -1
  67. package/dist/components/kritzel-font.js +1 -1
  68. package/dist/components/kritzel-input.js +1 -1
  69. package/dist/components/kritzel-loading-overlay.d.ts +11 -0
  70. package/dist/components/kritzel-loading-overlay.js +1 -0
  71. package/dist/components/kritzel-login-dialog.js +1 -1
  72. package/dist/components/kritzel-master-detail.js +1 -1
  73. package/dist/components/kritzel-menu-item.js +1 -1
  74. package/dist/components/kritzel-menu.js +1 -1
  75. package/dist/components/kritzel-more-menu.js +1 -1
  76. package/dist/components/kritzel-numeric-input.js +1 -1
  77. package/dist/components/kritzel-opacity-slider.js +1 -1
  78. package/dist/components/kritzel-pill-tabs.js +1 -1
  79. package/dist/components/kritzel-portal.js +1 -1
  80. package/dist/components/kritzel-settings.js +1 -1
  81. package/dist/components/kritzel-share-dialog.js +1 -1
  82. package/dist/components/kritzel-slide-toggle.js +1 -1
  83. package/dist/components/kritzel-split-button.js +1 -1
  84. package/dist/components/kritzel-stroke-size.js +1 -1
  85. package/dist/components/kritzel-tool-config.js +1 -1
  86. package/dist/components/kritzel-tooltip.js +1 -1
  87. package/dist/components/kritzel-utility-panel.js +1 -1
  88. package/dist/components/kritzel-watermark.js +1 -1
  89. package/dist/components/kritzel-workspace-manager.js +1 -1
  90. package/dist/components/kritzel-zoom-panel.js +1 -1
  91. package/dist/components/{p-CO0eEzos.js → p-1nG2hxfJ.js} +1 -1
  92. package/dist/components/{p-DfIknZRl.js → p-2Swq9rEm.js} +1 -1
  93. package/dist/components/{p-Cb5YwXbC.js → p-8xkoVMfO.js} +1 -1
  94. package/dist/components/p-BFTU3MAI.js +1 -0
  95. package/dist/components/{p-14NPx-_P.js → p-BH4AasB1.js} +1 -1
  96. package/dist/components/{p-Dl3MwBL1.js → p-BJlf4iHH.js} +1 -1
  97. package/dist/components/{p-BntMEYss.js → p-BKOsmXB5.js} +1 -1
  98. package/dist/components/{p-DSd5xTAH.js → p-BLOPBDUF.js} +1 -1
  99. package/dist/components/p-B_6RNask.js +1 -0
  100. package/dist/components/{p-NwN6r0N0.js → p-Bd_yPNfg.js} +1 -1
  101. package/dist/components/{p-COhjyuRa.js → p-BlozPPKi.js} +1 -1
  102. package/dist/components/{p-C1jg5IQi.js → p-Bm_BWQa4.js} +1 -1
  103. package/dist/components/p-BmyTdQGy.js +1 -0
  104. package/dist/components/{p-BmX2Vb4Z.js → p-BoA6RXEA.js} +1 -1
  105. package/dist/components/{p-BixEMVtW.js → p-BulDbBWB.js} +1 -1
  106. package/dist/components/{p-D0RYktBV.js → p-BzJEwFtn.js} +1 -1
  107. package/dist/components/{p-CdkNxxut.js → p-BzrxIesp.js} +1 -1
  108. package/dist/components/{p-vf28uSsc.js → p-CMphprF1.js} +1 -1
  109. package/dist/components/{p-D0v9WP5w.js → p-CVhcOiEA.js} +1 -1
  110. package/dist/components/{p-CC0J_kEP.js → p-CwuGA058.js} +1 -1
  111. package/dist/components/p-D09kgc5Q.js +1 -0
  112. package/dist/components/p-D52oKO_e.js +1 -0
  113. package/dist/components/{p-M9m9-OEY.js → p-D8TOEhPY.js} +1 -1
  114. package/dist/components/p-D9BugXUi.js +9 -0
  115. package/dist/components/p-DEqpY4K2.js +1 -0
  116. package/dist/components/{p-BrAeYciD.js → p-DIMNEOTW.js} +1 -1
  117. package/dist/components/{p-DeqALrzV.js → p-DMAScsJF.js} +1 -1
  118. package/dist/components/{p-y5T0_Wvi.js → p-DPpPd5GI.js} +1 -1
  119. package/dist/components/{p-Bg0xIZiR.js → p-DSOc0eIT.js} +1 -1
  120. package/dist/components/{p-W1ZwImdd.js → p-DXcjIb_a.js} +1 -1
  121. package/dist/components/{p-DPlEzPKO.js → p-DZcwchEg.js} +1 -1
  122. package/dist/components/{p-BX-nQAyH.js → p-DgnK50xO.js} +1 -1
  123. package/dist/components/p-Di5dpXrF.js +1 -0
  124. package/dist/components/{p-CZQz_mul.js → p-Ds-P2bYH.js} +1 -1
  125. package/dist/components/{p-meY80XnF.js → p-jzuGPW5o.js} +1 -1
  126. package/dist/components/p-oGAPPwAL.js +1 -0
  127. package/dist/components/{p-BEucPbiz.js → p-sLHApVnR.js} +1 -1
  128. package/dist/components/{p-DEpnJBA3.js → p-yD_3Z3K1.js} +1 -1
  129. package/dist/components/{p-C4-Som48.js → p-zd7zXld8.js} +1 -1
  130. package/dist/esm/index-Dhio9uis.js +2 -2
  131. package/dist/esm/index.js +2 -2
  132. package/dist/esm/{kritzel-active-users_45.entry.js → kritzel-active-users_46.entry.js} +3223 -77
  133. package/dist/esm/loader.js +1 -1
  134. package/dist/esm/{schema.constants-3oYjlURq.js → schema.constants-Cphx5M7a.js} +16 -3
  135. package/dist/esm/stencil.js +1 -1
  136. package/dist/stencil/index.esm.js +1 -1
  137. package/dist/stencil/p-Cphx5M7a.js +1 -0
  138. package/dist/stencil/p-ac77b486.entry.js +9 -0
  139. package/dist/stencil/stencil.esm.js +1 -1
  140. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +5 -0
  141. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +2 -0
  142. package/dist/types/components/ui/kritzel-current-user/kritzel-current-user.d.ts +0 -3
  143. package/dist/types/components/ui/kritzel-current-user-dialog/kritzel-current-user-dialog.d.ts +4 -0
  144. package/dist/types/components/ui/kritzel-loading-overlay/kritzel-loading-overlay.d.ts +11 -0
  145. package/dist/types/components/ui/kritzel-share-dialog/kritzel-share-dialog.d.ts +4 -0
  146. package/dist/types/components.d.ts +61 -0
  147. package/dist/types/constants/version.d.ts +1 -1
  148. package/dist/types/interfaces/theme.interface.d.ts +8 -0
  149. package/package.json +6 -4
  150. package/dist/components/p-BG6hOSrm.js +0 -1
  151. package/dist/components/p-COdwK_mi.js +0 -1
  152. package/dist/components/p-CQZYGZzF.js +0 -9
  153. package/dist/components/p-Ckpa5tHF.js +0 -1
  154. package/dist/components/p-CpzicliK.js +0 -1
  155. package/dist/components/p-XDNjFYRB.js +0 -1
  156. package/dist/components/p-X_pyPCe8.js +0 -1
  157. package/dist/stencil/p-3oYjlURq.js +0 -1
  158. package/dist/stencil/p-767b5a14.entry.js +0 -9
@@ -1,11 +1,15 @@
1
1
  import { r as registerInstance, h, H as Host, c as createEvent, g as getElement } from './index-Dhio9uis.js';
2
- import { c as KritzelPath, e as KritzelLine, R as KritzelColorHelper, T as KritzelDevicesHelper, q as KritzelSelectionTool, n as KritzelTextTool, U as KritzelMouseButton, V as KritzelHTMLHelper, X as DEFAULT_STROKE_SIZES, Y as DEFAULT_COLOR_PALETTE, S as ShapeType, D as DEFAULT_BRUSH_CONFIG, j as KritzelBrushTool, l as KritzelEraserTool, z as DEFAULT_LINE_TOOL_CONFIG, k as KritzelLineTool, o as KritzelShapeTool, y as DEFAULT_TEXT_CONFIG, m as KritzelImageTool, L as KritzelAlignment, B as DEFAULT_ASSET_STORAGE_CONFIG, Z as ObjectHelper, _ as ThemeHelper, E as darkTheme, C as lightTheme, $ as KritzelSelectionGroup, a0 as KritzelSelectionBox, a1 as KritzelIconRegistry, a2 as KritzelKeyboardHelper, a3 as KritzelBaseHandler, s as KritzelWorkspace, f as KritzelGroup, h as KritzelCustomElement, d as KritzelImage, g as KritzelShape, b as KritzelText, M as runMigrations, Q as CURRENT_WORKSPACE_SCHEMA_VERSION, O as WORKSPACE_MIGRATIONS, a4 as KritzelClassHelper, P as CURRENT_APP_STATE_SCHEMA_VERSION, N as APP_STATE_MIGRATIONS, p as KritzelCursorHelper, a5 as imageCompression, t as KritzelAnchorManager, u as KritzelThemeManager, v as KritzelLocalizationManager, w as KritzelLicenseManager, r as KritzelAssetResolver, a6 as KritzelEventHelper, W as WORKSPACE_EXPORT_VERSION } from './schema.constants-3oYjlURq.js';
2
+ import { c as KritzelPath, e as KritzelLine, R as KritzelColorHelper, T as KritzelDevicesHelper, q as KritzelSelectionTool, n as KritzelTextTool, U as KritzelMouseButton, V as KritzelHTMLHelper, X as DEFAULT_STROKE_SIZES, Y as DEFAULT_COLOR_PALETTE, S as ShapeType, D as DEFAULT_BRUSH_CONFIG, j as KritzelBrushTool, l as KritzelEraserTool, z as DEFAULT_LINE_TOOL_CONFIG, k as KritzelLineTool, o as KritzelShapeTool, y as DEFAULT_TEXT_CONFIG, m as KritzelImageTool, L as KritzelAlignment, B as DEFAULT_ASSET_STORAGE_CONFIG, Z as ObjectHelper, _ as ThemeHelper, E as darkTheme, C as lightTheme, $ as KritzelSelectionGroup, a0 as KritzelSelectionBox, a1 as KritzelIconRegistry, a2 as KritzelKeyboardHelper, a3 as KritzelBaseHandler, s as KritzelWorkspace, f as KritzelGroup, h as KritzelCustomElement, d as KritzelImage, g as KritzelShape, b as KritzelText, M as runMigrations, Q as CURRENT_WORKSPACE_SCHEMA_VERSION, O as WORKSPACE_MIGRATIONS, a4 as KritzelClassHelper, P as CURRENT_APP_STATE_SCHEMA_VERSION, N as APP_STATE_MIGRATIONS, p as KritzelCursorHelper, a5 as imageCompression, t as KritzelAnchorManager, u as KritzelThemeManager, v as KritzelLocalizationManager, w as KritzelLicenseManager, r as KritzelAssetResolver, a6 as KritzelEventHelper, W as WORKSPACE_EXPORT_VERSION } from './schema.constants-Cphx5M7a.js';
3
3
  import * as Y from 'yjs';
4
4
  import 'y-indexeddb';
5
5
  import 'y-websocket';
6
6
 
7
7
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
8
8
 
9
+ function getDefaultExportFromCjs (x) {
10
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
11
+ }
12
+
9
13
  const kritzelActiveUsersCss = () => `:host{display:inline-flex;align-items:center}.avatars{display:flex;align-items:center}.avatar-wrapper{position:relative;transition:margin-left 200ms ease}.avatar-wrapper kritzel-avatar{border-radius:50%;box-shadow:0 0 0 2px var(--kritzel-active-users-avatar-border-color, #ffffff)}.avatars:hover .avatar-wrapper{margin-left:-6px !important}.avatar-tooltip{position:absolute;top:100%;left:50%;transform:translateX(-50%);margin-top:12px;padding:4px 8px;background-color:var(--kritzel-active-users-tooltip-background, #333333);color:var(--kritzel-active-users-tooltip-color, #ffffff);font-family:sans-serif;font-size:12px;font-weight:500;border-radius:4px;white-space:nowrap;width:max-content;pointer-events:none;opacity:0;transition:opacity 150ms ease}.avatar-wrapper:hover .avatar-tooltip,.overflow-count:hover .avatar-tooltip{opacity:1}.overflow-count{position:relative;margin-left:8px;font-family:sans-serif;font-size:var(--kritzel-active-users-overflow-font-size, 14px);font-weight:500;color:var(--kritzel-active-users-overflow-color, #666666);white-space:nowrap;cursor:default}.overflow-count .avatar-tooltip{white-space:nowrap;text-align:left;margin-top:20px}`;
10
14
 
11
15
  const KritzelActiveUsers = class {
@@ -132,16 +136,16 @@ const KritzelAvatar = class {
132
136
  height: `${this.size}px`,
133
137
  fontSize: `${Math.round(this.size * 0.4)}px`,
134
138
  };
135
- return (h(Host, { key: '4bdbe2c1d5d3a1708189166498ae4e36c19c46ff', style: containerStyles, class: {
139
+ return (h(Host, { key: '116725d55e4443e80216b3b3251e957d2009b43e', style: containerStyles, class: {
136
140
  'has-image': !!showImage,
137
141
  'has-initials': !!showInitials,
138
142
  'has-default': !!showDefaultIcon,
139
- }, role: "img", "aria-label": this.getDisplayName() || 'User avatar' }, showImage && (h("img", { key: '55c3a13c9d514ea700c6b1a9339cd0dff1828b2b', src: imageUrl, alt: "", class: "avatar-image", ref: (el) => {
143
+ }, role: "img", "aria-label": this.getDisplayName() || 'User avatar' }, showImage && (h("img", { key: 'd70ad4eb484404b18c13e066e8c10b3c86918ee5', src: imageUrl, alt: "", class: "avatar-image", ref: (el) => {
140
144
  if (el) {
141
145
  el.referrerPolicy = 'no-referrer';
142
146
  el.crossOrigin = 'anonymous';
143
147
  }
144
- }, onError: this.handleImageError })), showInitials && (h("span", { key: 'b60cbe2b94ea1d2cd2a09d10c928290fc1469a4a', class: "avatar-initials", style: { backgroundColor: this.getBackgroundColor() } }, initials)), showDefaultIcon && (h("span", { key: 'e8a0f49952b5b7e5e4a1fe3d67e68a56081d5e4c', class: "avatar-default" }, h("svg", { key: '1fdc256fd53aa5c866bb0e81fdd40393c8a7d69d', viewBox: "0 0 24 24", fill: "currentColor" }, h("path", { key: '8f3a5a6775154e46a2f331534fe75671b9ad081a', d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" }))))));
148
+ }, onError: this.handleImageError })), showInitials && (h("span", { key: '21a9022cffdb69e0c3626e513cb3c036a9d3a16d', class: "avatar-initials", style: { backgroundColor: this.getBackgroundColor() } }, initials)), showDefaultIcon && (h("span", { key: '43e676af007bf254b1921f3efcbc7fff4e204359', class: "avatar-default" }, h("svg", { key: 'a7378795539a902e28ca644a80f1ca00cc9f818a', viewBox: "0 0 24 24", fill: "currentColor" }, h("path", { key: '31548a495a86f033325c98cfcc0ae398b6bb8281', d: "M12 12c2.21 0 4-1.79 4-4s-1.79-4-4-4-4 1.79-4 4 1.79 4 4 4zm0 2c-2.67 0-8 1.34-8 4v2h16v-2c0-2.66-5.33-4-8-4z" }))))));
145
149
  }
146
150
  static get watchers() { return {
147
151
  "user": [{
@@ -451,12 +455,12 @@ const KritzelBackToContent = class {
451
455
  this.backToContent.emit();
452
456
  };
453
457
  render() {
454
- return (h(Host, { key: 'a7d52616642f45a0c0e7b76deb3cc5994184b968' }, h("button", { key: '9e7acae2b62f7f66ee0127545ee8ab115f9d340e', class: { 'back-to-content-button': true, visible: this.visible }, onClick: this.handleClick, "aria-label": this.text }, h("kritzel-icon", { key: '6c404376643554cdb86c33957c066dd4580f19f1', name: "chevrons-left" }))));
458
+ return (h(Host, { key: 'ab9e9297f5f26bcf79ec32e51ee0ff2524ad421f' }, h("button", { key: 'c32536edc9943bc9ad66f4fa727338bb01e148a6', class: { 'back-to-content-button': true, visible: this.visible }, onClick: this.handleClick, "aria-label": this.text }, h("kritzel-icon", { key: 'bd3aa6ffe524ad9093d1e0693574dc2d63c311bd', name: "chevrons-left" }))));
455
459
  }
456
460
  };
457
461
  KritzelBackToContent.style = kritzelBackToContentCss();
458
462
 
459
- const kritzelButtonCss = () => `:host{display:inline-block;font-family:sans-serif}button{border:none;background-color:transparent;padding:0;margin:0;font-family:inherit;font-size:inherit;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:var(--kritzel-global-pointer-cursor, pointer);display:inline-flex;align-items:center;justify-content:center;gap:6px;border-radius:var(--kritzel-button-border-radius, 8px);padding:var(--kritzel-button-padding, 12px 20px);font-size:var(--kritzel-button-font-size, 14px);font-weight:var(--kritzel-button-font-weight, 500);transition:background-color 0.15s ease, opacity 0.15s ease;-webkit-tap-highlight-color:transparent}button.primary{background-color:var(--kritzel-button-primary-background-color, #007AFF);color:var(--kritzel-button-primary-color, #ffffff)}button.primary:hover{background-color:var(--kritzel-button-primary-hover-background-color, #006ae6)}button.primary:active{background-color:var(--kritzel-button-primary-active-background-color, #005bbf)}button.secondary{background-color:var(--kritzel-button-secondary-background-color, #f0f0f0);color:var(--kritzel-button-secondary-color, #333333)}button.secondary:hover{background-color:var(--kritzel-button-secondary-hover-background-color, #e0e0e0)}button.secondary:active{background-color:var(--kritzel-button-secondary-active-background-color, #d0d0d0)}button.text{background-color:transparent;color:var(--kritzel-button-text-color, #007AFF)}button.text:hover{background-color:var(--kritzel-button-text-hover-background-color, rgba(0, 122, 255, 0.08))}button.text:active{background-color:var(--kritzel-button-text-active-background-color, rgba(0, 122, 255, 0.15))}button.disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}`;
463
+ const kritzelButtonCss = () => `:host{display:inline-block;font-family:sans-serif}button{border:none;background-color:transparent;padding:0;margin:0;font-family:inherit;font-size:inherit;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:var(--kritzel-global-pointer-cursor, pointer);display:inline-flex;width:var(--kritzel-button-width, auto);align-items:center;justify-content:center;gap:6px;border-radius:var(--kritzel-button-border-radius, 8px);padding:var(--kritzel-button-padding, 12px 20px);font-size:var(--kritzel-button-font-size, 14px);font-weight:var(--kritzel-button-font-weight, 500);transition:background-color 0.15s ease, opacity 0.15s ease;-webkit-tap-highlight-color:transparent}button.primary{background-color:var(--kritzel-button-primary-background-color, #007AFF);color:var(--kritzel-button-primary-color, #ffffff)}button.primary:hover{background-color:var(--kritzel-button-primary-hover-background-color, #006ae6)}button.primary:active{background-color:var(--kritzel-button-primary-active-background-color, #005bbf)}button.secondary{background-color:var(--kritzel-button-secondary-background-color, #f0f0f0);color:var(--kritzel-button-secondary-color, #333333)}button.secondary:hover{background-color:var(--kritzel-button-secondary-hover-background-color, #e0e0e0)}button.secondary:active{background-color:var(--kritzel-button-secondary-active-background-color, #d0d0d0)}button.text{background-color:transparent;color:var(--kritzel-button-text-color, #007AFF)}button.text:hover{background-color:var(--kritzel-button-text-hover-background-color, rgba(0, 122, 255, 0.08))}button.text:active{background-color:var(--kritzel-button-text-active-background-color, rgba(0, 122, 255, 0.15))}button.disabled{opacity:0.4;cursor:not-allowed;pointer-events:none}`;
460
464
 
461
465
  const KritzelButton = class {
462
466
  constructor(hostRef) {
@@ -478,11 +482,11 @@ const KritzelButton = class {
478
482
  this.buttonClick.emit();
479
483
  };
480
484
  render() {
481
- return (h(Host, { key: '0de2b5dcf75de9f5b7de0c6b876bd18733bf21b9' }, h("button", { key: '5ab9d80167c6b90add7779d4b1c3ebb80fafaed5', type: this.type, class: {
485
+ return (h(Host, { key: 'b9de2a1261ca0cb491f6980db6a596c48fa45b3a' }, h("button", { key: 'a9507ea0f6a1d9fcb19a7df16bea54cc0ead24f9', type: this.type, class: {
482
486
  'kritzel-button': true,
483
487
  [this.variant]: true,
484
488
  'disabled': this.disabled,
485
- }, disabled: this.disabled, onClick: this.handleClick }, h("slot", { key: 'dc105f7d1f87aa55c314d942a1cc6522b272526a' }))));
489
+ }, disabled: this.disabled, onClick: this.handleClick }, h("slot", { key: '8449a26d4f9fe0226c6150a6639c522486b59780' }))));
486
490
  }
487
491
  };
488
492
  KritzelButton.style = kritzelButtonCss();
@@ -530,13 +534,13 @@ const KritzelColorComponent = class {
530
534
  render() {
531
535
  const resolvedColor = this.resolveColor();
532
536
  const isColorVeryLight = this.isLightColor(resolvedColor);
533
- return (h(Host, { key: '0d56c7ad01eddd523ebcf11a32e68367c96090bd' }, h("div", { key: '0bef4cb73804b98e6eea6b3cf006c19c8786bdb9', class: "checkerboard-bg", style: {
537
+ return (h(Host, { key: 'e39c77c55942b9c615e404efabf4939b2cf05a34' }, h("div", { key: 'ac343295592ea80ca7d3da61ca1244dd1aaa50db', class: "checkerboard-bg", style: {
534
538
  width: `${this.size}px`,
535
539
  height: `${this.size}px`,
536
540
  borderRadius: '50%',
537
541
  display: 'inline-block',
538
542
  position: 'relative',
539
- } }, h("div", { key: '5be9714c3ddd56ae77c2870333ff97a59b58bd45', class: {
543
+ } }, h("div", { key: '4c87934b3febd4c41874cd290d86a9a9a557e3e5', class: {
540
544
  'color-circle': true,
541
545
  'white': isColorVeryLight,
542
546
  }, style: {
@@ -592,7 +596,7 @@ const KritzelColorPalette = class {
592
596
  render() {
593
597
  const displayedColors = this.isExpanded ? this.colors : this.colors.slice(0, 6);
594
598
  const expandedHeight = this.isExpanded ? this.calculateHeight() : '32px';
595
- return (h(Host, { key: '6d003ec5b92f586532782144c25ca5a733741f20' }, h("div", { key: '031838b45da4916aa91d87c066ac950cfe3a1ddc', class: {
599
+ return (h(Host, { key: '16aa405a43b3943473e577c5a6ab86adf4ae1ba9' }, h("div", { key: 'f65bb286889700dc1f0e8d84ff59721071b7b73a', class: {
596
600
  'color-grid': true,
597
601
  'expanded': this.isExpanded,
598
602
  }, style: {
@@ -1160,13 +1164,13 @@ const KritzelControls = class {
1160
1164
  // Separate tool controls from config control
1161
1165
  const toolControls = this.internalControls.filter(c => c.type === 'tool' || c.type === 'separator');
1162
1166
  const configControl = this.internalControls.find(c => c.type === 'config' && c.name === this.firstConfig?.name);
1163
- return (h(Host, { key: '266e38cdeffb8c22a7f778e865e5fab6b461f5b6', style: { display: this.visible ? '' : 'none' }, class: {
1167
+ return (h(Host, { key: 'f66fd3057bd88d31d7d585f2c286feb7e33c3611', style: { display: this.visible ? '' : 'none' }, class: {
1164
1168
  mobile: this.isTouchDevice,
1165
- } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '5e75ece000ac02675d3d226461b7f522dcf5ead9', style: {
1169
+ } }, this.isUtilityPanelVisible && (h("kritzel-utility-panel", { key: '4841cd070407422f0081dd528566d3943d2db7cd', style: {
1166
1170
  position: 'absolute',
1167
1171
  bottom: '56px',
1168
1172
  left: '12px',
1169
- }, undoState: this.undoState, terms: this.terms, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: 'fc98b1675afe1abb6a8d391c4ace34c7f0e46677', class: "kritzel-controls" }, h("div", { key: 'b17bc9e9a65646735c56f78a326a281229fa9790', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), h("div", { key: '9ab9d5c44e515551d75f27c31875de72e9d3407c', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
1173
+ }, undoState: this.undoState, terms: this.terms, onUndo: () => this.kritzelEngine?.undo(), onRedo: () => this.kritzelEngine?.redo(), onDelete: () => this.kritzelEngine?.delete() })), h("div", { key: '54fb1da3f8b070c4c75e27930c95ca06f46f48f1', class: "kritzel-controls" }, h("div", { key: '9ce27b621a8fb668716f1eb15f3b01302e476d86', class: { 'scroll-indicator-left': true, 'visible': this.canScrollLeft } }), h("div", { key: 'eb9f499b5139c481b5748b09ecf21cd414918a11', class: "kritzel-tools-scroll", ref: el => (this.toolsScrollRef = el), onScroll: this.handleToolsScroll }, toolControls.map(control => {
1170
1174
  // Check if this control has sub-options (split-button)
1171
1175
  if (control.subOptions?.length) {
1172
1176
  const selectedSubOption = this.getSelectedSubOption(control);
@@ -1196,10 +1200,10 @@ const KritzelControls = class {
1196
1200
  'kritzel-control': true,
1197
1201
  'selected': this.activeControl?.name === control?.name,
1198
1202
  }, key: control.name, "data-testid": `tool-${control.name}`, onClick: _event => this.handleControlClick?.(control), "aria-label": control.name.charAt(0).toUpperCase() + control.name.slice(1) }, h("kritzel-icon", { name: control.icon })));
1199
- })), h("div", { key: 'fad7512f5d1aa68905a56b8f22d498380f166f9f', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (h("div", { class: {
1203
+ })), h("div", { key: 'c990abf4ff2970e6519c605135f3fbded691e91a', class: { 'scroll-indicator-right': true, 'visible': this.canScrollRight && !(configControl && this.activeControl && hasConfigUI) } }), configControl && this.activeControl && (h("div", { class: {
1200
1204
  'kritzel-config-container': true,
1201
1205
  'visible': hasConfigUI,
1202
- }, key: configControl.name }, h("div", { key: '2ff7cb3ad18608102f3d8188b5936cf00b00451f', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), h("kritzel-tooltip", { key: '10f15f717c8573cbad6ea53b412ad56254099ad1', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, h("kritzel-tool-config", { key: 'a1b0ed8ecc2696a591e32add642a3d5cb2bf7f4a', tool: this.activeControl.tool, theme: this.theme, engine: this.kritzelEngine, terms: this.terms, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), h("div", { key: '7ac8214a3dbad5323a38cad3ff7324b57f9dbfb5', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
1206
+ }, key: configControl.name }, h("div", { key: '1c163b818eed3a76bda9e802b083d2bfe8431c87', class: { 'config-gradient-left': true, 'visible': this.needsScrolling } }), h("kritzel-tooltip", { key: 'f7252d9aa17bdde580ca31cd558ba93d99822937', anchorElement: this.host.shadowRoot?.querySelector('.kritzel-config-container'), triggerElement: this.configTriggerRef }, h("kritzel-tool-config", { key: 'a15a873d8740d5c45a657bb4677a514fe9e183de', tool: this.activeControl.tool, theme: this.theme, engine: this.kritzelEngine, terms: this.terms, onToolChange: event => this.handleToolChange?.(event), onDisplayValuesChange: this.handleDisplayValuesChange, style: { width: '100%', height: '100%' } })), h("div", { key: 'ffbf1e35387ee732c6877f8425dbe07234d8233f', tabIndex: hasConfigUI ? 0 : -1, class: "kritzel-config", "data-testid": "tool-config", ref: el => {
1203
1207
  if (el)
1204
1208
  this.configTriggerRef = el;
1205
1209
  }, onKeyDown: event => {
@@ -1208,7 +1212,7 @@ const KritzelControls = class {
1208
1212
  }
1209
1213
  }, style: {
1210
1214
  cursor: 'pointer',
1211
- } }, this.displayValues && (h("div", { key: '7e64f79859f7f2b03d72bb7a93fb295e7d2b2ac0', class: "color-container" }, h("kritzel-color", { key: 'b87d9861949379d84954ef1ecb554e13317b3287', value: this.displayValues.color, theme: this.theme, size: 18, style: {
1215
+ } }, this.displayValues && (h("div", { key: 'eb272119da9354eb069231c3d29a196c5b0e4aa2', class: "color-container" }, h("kritzel-color", { key: '465b3af943d740b83bd260ee493840edd235a9af', value: this.displayValues.color, theme: this.theme, size: 18, style: {
1212
1216
  borderRadius: '50%',
1213
1217
  border: 'none',
1214
1218
  } })))))))));
@@ -1231,7 +1235,6 @@ const KritzelCurrentUser = class {
1231
1235
  constructor(hostRef) {
1232
1236
  registerInstance(this, hostRef);
1233
1237
  }
1234
- get host() { return getElement(this); }
1235
1238
  /**
1236
1239
  * The current user to display
1237
1240
  */
@@ -1242,28 +1245,26 @@ const KritzelCurrentUser = class {
1242
1245
  avatarSize = 40;
1243
1246
  /** Resolved localized strings keyed by term key, supplied by the editor. */
1244
1247
  terms = {};
1245
- dialogRef;
1246
- handleAvatarClick = (event) => {
1247
- event.stopPropagation();
1248
- this.dialogRef?.open();
1249
- };
1250
1248
  render() {
1251
- return (h(Host, { key: 'bdee6b71c08d6ea22aec40e88ba56077882b301d' }, h("kritzel-avatar", { key: '97bcaaa6b683c0d26d547ac5cbd9df7814f0cd80', user: this.user, size: this.avatarSize, onClick: this.handleAvatarClick }), h("kritzel-current-user-dialog", { key: 'c984ea1803bcf2b06569fd66d12e4e7054235225', ref: el => (this.dialogRef = el), user: this.user, terms: this.terms })));
1249
+ return (h(Host, { key: 'e9746bbb98dbdae8f73ac7129bc1eb772746c576' }, h("kritzel-avatar", { key: '04f493ba649484cd95607c54b77e27134baa3122', user: this.user, size: this.avatarSize })));
1252
1250
  }
1253
1251
  };
1254
1252
  KritzelCurrentUser.style = kritzelCurrentUserCss();
1255
1253
 
1256
- const kritzelCurrentUserDialogCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-width-small:380px}.user-info{display:flex;flex-direction:column;align-items:center;gap:8px;padding:8px 0}.user-name{font-size:18px;font-weight:600;color:var(--kritzel-current-user-dialog-name-color, #333333);text-align:center;margin-top:8px}.user-email{font-size:14px;color:var(--kritzel-current-user-dialog-email-color, #666666);text-align:center}`;
1254
+ const kritzelCurrentUserDialogCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-width-small:380px}.user-info{display:flex;flex-direction:column;align-items:center;gap:8px;padding:8px 0}.user-name{font-size:18px;font-weight:600;color:var(--kritzel-current-user-dialog-name-color, #333333);text-align:center;margin-top:8px}.user-email{font-size:14px;color:var(--kritzel-current-user-dialog-email-color, #666666);text-align:center}.logout-button{margin-top:16px;width:100%;--kritzel-button-width:100%;--kritzel-button-primary-background-color:var(--kritzel-current-user-dialog-logout-button-background-color, #007AFF);--kritzel-button-primary-hover-background-color:var(--kritzel-current-user-dialog-logout-button-hover-background-color, #006ae6);--kritzel-button-primary-active-background-color:var(--kritzel-current-user-dialog-logout-button-active-background-color, #005bbf);--kritzel-button-primary-color:var(--kritzel-current-user-dialog-logout-button-color, #ffffff)}`;
1257
1255
 
1258
1256
  const KritzelCurrentUserDialog = class {
1259
1257
  constructor(hostRef) {
1260
1258
  registerInstance(this, hostRef);
1259
+ this.logoutRequest = createEvent(this, "logoutRequest");
1261
1260
  }
1262
1261
  get host() { return getElement(this); }
1263
1262
  user;
1264
1263
  /** Resolved localized strings keyed by term key, supplied by the editor. */
1265
1264
  terms = {};
1266
1265
  isDialogOpen = false;
1266
+ /** Emitted when the user clicks the logout action. */
1267
+ logoutRequest;
1267
1268
  async open() {
1268
1269
  this.isDialogOpen = true;
1269
1270
  }
@@ -1273,6 +1274,10 @@ const KritzelCurrentUserDialog = class {
1273
1274
  closeDialog = () => {
1274
1275
  this.isDialogOpen = false;
1275
1276
  };
1277
+ handleLogout = () => {
1278
+ this.logoutRequest.emit();
1279
+ this.closeDialog();
1280
+ };
1276
1281
  getDisplayName() {
1277
1282
  if (!this.user)
1278
1283
  return undefined;
@@ -1282,7 +1287,7 @@ const KritzelCurrentUserDialog = class {
1282
1287
  }
1283
1288
  render() {
1284
1289
  const displayName = this.getDisplayName();
1285
- return (h(Host, { key: '042455d68a432e0e218d5b8750fb1d22b0d202fc' }, h("kritzel-dialog", { key: '058abbc8e1c38c647cc02e85c272e89693cab22a', dialogTitle: this.terms['currentUser.dialogTitle'] ?? 'Account', isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: 'ee141b2e91f093527e2d8f6649bade8e1a14f130', class: "user-info" }, h("kritzel-avatar", { key: '2734bb0d3c69df14d26c204eeaf726174afaabc0', user: this.user, size: 80 }), displayName && h("div", { key: '56cbad7a51264ebada0cb029e6455aabb9cb4ae9', class: "user-name" }, displayName), this.user?.email && h("div", { key: 'ef9075dfdeb52ce6f90bb41d1348fbdf7dbb93ee', class: "user-email" }, this.user.email)))));
1290
+ return (h(Host, { key: '6eb573d072c5c0b47de4a88538a507adf49bd9b4' }, h("kritzel-dialog", { key: '9e85ed790f146ac408023759b1fe87e60bc80282', dialogTitle: this.terms['currentUser.dialogTitle'] ?? 'Account', isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: '33a55e6023ad6f63514085d57b7278d4733bd411', class: "user-info" }, h("kritzel-avatar", { key: '4580f83fc6c5bcf8a1ffcd0d635da233817233d3', user: this.user, size: 80 }), displayName && h("div", { key: '5e2b98005e9b4ab7cc3db2dc81f4180e8ba3abea', class: "user-name" }, displayName), this.user?.email && h("div", { key: '1041266c4a4525d2f08c60d59bec5a518de2184b', class: "user-email" }, this.user.email), h("kritzel-button", { key: 'b695c05d24ab9d4d252a45ec496d75d79583ed4d', class: "logout-button", variant: "primary", onButtonClick: this.handleLogout }, this.terms['menu.logout'] ?? 'Logout')))));
1286
1291
  }
1287
1292
  };
1288
1293
  KritzelCurrentUserDialog.style = kritzelCurrentUserDialogCss();
@@ -2106,7 +2111,7 @@ const DEFAULT_SYNC_CONFIG = {
2106
2111
  providers: [],
2107
2112
  };
2108
2113
 
2109
- const kritzelEditorCss = () => `kritzel-editor{display:flex;margin:0;position:relative;container-type:inline-size;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-align:start;line-height:normal}kritzel-controls{position:absolute;left:0;right:0;margin-inline:auto;width:max-content;max-width:calc(100% - 16px);bottom:var(--kritzel-editor-controls-bottom, 14px);transition:transform var(--kritzel-editor-controls-transition-duration, 0.1s) var(--kritzel-editor-controls-transition, ease-in-out)}kritzel-controls.keyboard-open{transform:var(--kritzel-editor-controls-transform, translateY(300%))}.top-left-buttons{position:absolute;top:var(--kritzel-editor-top-left-buttons-top, 14px);left:var(--kritzel-editor-top-left-buttons-left, 14px);display:flex;align-items:flex-start;gap:8px}.top-center-notification-layer{position:absolute;top:var(--kritzel-editor-top-center-notification-top, 14px);left:0;right:0;z-index:var(--kritzel-editor-top-center-notification-z-index, 10001);display:flex;justify-content:center;pointer-events:none}.top-center-notification-container{width:min(90vw, 420px);pointer-events:auto;animation:kritzel-notification-slide-in var(--kritzel-editor-notification-animation-duration, 220ms) var(--kritzel-editor-notification-animation-easing, cubic-bezier(0.22, 1, 0.36, 1))}.top-center-notification-container.is-dismissing{animation:kritzel-notification-fade-out var(--kritzel-editor-notification-dismiss-animation-duration, 180ms) var(--kritzel-editor-notification-dismiss-animation-easing, ease-in) forwards}@keyframes kritzel-notification-slide-in{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes kritzel-notification-fade-out{from{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-6px)}}@media (prefers-reduced-motion: reduce){.top-center-notification-container{animation:none}}.top-right-buttons{position:absolute;top:var(--kritzel-editor-top-right-buttons-top, 14px);right:var(--kritzel-editor-top-right-buttons-right, 14px);display:flex;align-items:center;gap:8px}.bottom-left-buttons{position:absolute;left:var(--kritzel-editor-top-left-buttons-left, 14px);bottom:var(--kritzel-editor-controls-bottom, 14px);display:flex;align-items:flex-end}@container (max-width: 767px){.bottom-left-buttons{display:none}}.top-right-button{display:flex;align-items:center;justify-content:center;width:50px;height:50px;padding:0;border:var(--kritzel-split-button-border, 1px solid #ebebeb);border-radius:var(--kritzel-split-button-border-radius, 12px);background-color:var(--kritzel-split-button-background-color, #ffffff);cursor:var(--kritzel-global-pointer-cursor, pointer);box-shadow:var(--kritzel-split-button-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));transition:background-color 150ms ease;-webkit-tap-highlight-color:transparent}.top-right-button:hover{background-color:#f5f5f5}.top-right-button:active{background-color:#ebebeb}`;
2114
+ const kritzelEditorCss = () => `kritzel-editor{display:flex;margin:0;position:relative;container-type:inline-size;overflow:hidden;width:100%;height:100%;align-items:center;justify-content:center;touch-action:manipulation;user-select:none;-webkit-touch-callout:none;-webkit-user-select:none;-khtml-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;text-align:start;line-height:normal}.editor-content{position:absolute;inset:0}kritzel-controls{position:absolute;left:0;right:0;margin-inline:auto;width:max-content;max-width:calc(100% - 16px);bottom:var(--kritzel-editor-controls-bottom, 14px);transition:transform var(--kritzel-editor-controls-transition-duration, 0.1s) var(--kritzel-editor-controls-transition, ease-in-out)}kritzel-controls.keyboard-open{transform:var(--kritzel-editor-controls-transform, translateY(300%))}.top-left-buttons{position:absolute;top:var(--kritzel-editor-top-left-buttons-top, 14px);left:var(--kritzel-editor-top-left-buttons-left, 14px);display:flex;align-items:flex-start;gap:8px}.top-center-notification-layer{position:absolute;top:var(--kritzel-editor-top-center-notification-top, 14px);left:0;right:0;z-index:var(--kritzel-editor-top-center-notification-z-index, 10001);display:flex;justify-content:center;pointer-events:none}.top-center-notification-container{width:min(90vw, 420px);pointer-events:auto;animation:kritzel-notification-slide-in var(--kritzel-editor-notification-animation-duration, 220ms) var(--kritzel-editor-notification-animation-easing, cubic-bezier(0.22, 1, 0.36, 1))}.top-center-notification-container.is-dismissing{animation:kritzel-notification-fade-out var(--kritzel-editor-notification-dismiss-animation-duration, 180ms) var(--kritzel-editor-notification-dismiss-animation-easing, ease-in) forwards}@keyframes kritzel-notification-slide-in{from{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes kritzel-notification-fade-out{from{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-6px)}}@media (prefers-reduced-motion: reduce){.top-center-notification-container{animation:none}}.top-right-buttons{position:absolute;top:var(--kritzel-editor-top-right-buttons-top, 14px);right:var(--kritzel-editor-top-right-buttons-right, 14px);display:flex;align-items:center;gap:8px}.bottom-left-buttons{position:absolute;left:var(--kritzel-editor-top-left-buttons-left, 14px);bottom:var(--kritzel-editor-controls-bottom, 14px);display:flex;align-items:flex-end}@container (max-width: 767px){.bottom-left-buttons{display:none}}.top-right-button{display:flex;align-items:center;justify-content:center;width:50px;height:50px;padding:0;border:var(--kritzel-split-button-border, 1px solid #ebebeb);border-radius:var(--kritzel-split-button-border-radius, 12px);background-color:var(--kritzel-split-button-background-color, #ffffff);cursor:var(--kritzel-global-pointer-cursor, pointer);box-shadow:var(--kritzel-split-button-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));transition:background-color 150ms ease;-webkit-tap-highlight-color:transparent}.top-right-button:hover{background-color:#f5f5f5}.top-right-button:active{background-color:#ebebeb}`;
2110
2115
 
2111
2116
  const KritzelEditor = class {
2112
2117
  constructor(hostRef) {
@@ -2337,6 +2342,8 @@ const KritzelEditor = class {
2337
2342
  isEditorVisible = false;
2338
2343
  activeNotification;
2339
2344
  isNotificationDismissing = false;
2345
+ /** Combined loading state reported by the engine (external `isLoading` prop or internal workspace loading). Starts true so the overlay is shown until the engine reports otherwise. */
2346
+ isEngineLoading = true;
2340
2347
  notificationDismissTimeout;
2341
2348
  notificationDismissAnimationTimeout;
2342
2349
  notificationDisplayDurationMs = 5000;
@@ -2642,6 +2649,7 @@ const KritzelEditor = class {
2642
2649
  splitButtonRef;
2643
2650
  shareDialogRef;
2644
2651
  loginDialogRef;
2652
+ currentUserDialogRef;
2645
2653
  componentWillLoad() {
2646
2654
  this.loadSettingsFromStorage();
2647
2655
  this.applyTheme();
@@ -2762,6 +2770,10 @@ const KritzelEditor = class {
2762
2770
  event.stopPropagation();
2763
2771
  this.awarenessChange.emit(event.detail);
2764
2772
  }
2773
+ handleLoadingChange(event) {
2774
+ event.stopPropagation();
2775
+ this.isEngineLoading = event.detail;
2776
+ }
2765
2777
  handleNotificationsChange(event) {
2766
2778
  event.stopPropagation();
2767
2779
  this.clearNotificationDismissAnimationTimer();
@@ -2866,15 +2878,7 @@ const KritzelEditor = class {
2866
2878
  label: this.resolvedTerms['menu.settings'] ?? 'Settings',
2867
2879
  icon: 'settings',
2868
2880
  action: () => this.settingsRef.open(),
2869
- },
2870
- {
2871
- id: 'logout',
2872
- label: this.resolvedTerms['menu.logout'] ?? 'Logout',
2873
- icon: 'log-out',
2874
- color: '#ff3b30',
2875
- isVisible: this.isLoggedIn,
2876
- action: () => this.logout.emit(),
2877
- },
2881
+ }
2878
2882
  ];
2879
2883
  }
2880
2884
  handleToggleIsPublic = async (event) => {
@@ -2900,6 +2904,9 @@ const KritzelEditor = class {
2900
2904
  handleProviderLogin = (event) => {
2901
2905
  this.login.emit(event.detail);
2902
2906
  };
2907
+ handleCurrentUserLogout = () => {
2908
+ this.logout.emit();
2909
+ };
2903
2910
  get isLoggedIn() {
2904
2911
  return !!this.user && !this.user.isGuest;
2905
2912
  }
@@ -3051,35 +3058,40 @@ const KritzelEditor = class {
3051
3058
  const isLoggedIn = this.isLoggedIn;
3052
3059
  const shouldShowCurrentUser = isLoggedIn;
3053
3060
  const shouldShowLoginButton = this.isReady && !!this.loginConfig && !isLoggedIn;
3054
- return (h(Host, { key: '56b172459e6d940229dc1d4f409157e403ad5f27', style: {
3061
+ return (h(Host, { key: 'a397bb3a5ab632193a0d6af07054d9235c8af7ba' }, h("kritzel-loading-overlay", { key: '8ac3ec51ec15a7ce3dfac4e1afb7e2d272d6fee2', visible: this.isLoading || !this.isEditorVisible || this.isEngineLoading, text: this.resolvedTerms['engine.loading'] ?? 'Loading...' }), h("div", { key: '0ac709cf7d3e9889f99675f20c1f2ac5bcca55da', class: "editor-content", style: {
3055
3062
  opacity: this.isEditorVisible ? '1' : '0',
3056
3063
  visibility: this.isEditorVisible ? 'visible' : 'hidden',
3057
3064
  transition: 'opacity 0.2s ease-in-out, visibility 0.2s ease-in-out',
3058
- } }, h("div", { key: '93a2195c14402f38416b2d377c684e2650418edb', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: '1b42b21bc35e1fc56202e19a78053e46d87ca51a', 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: '3b90b69a5b83a6e5593d4f752c4094a2a3af8c4d', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), this.activeNotification && (h("div", { key: '9c2ee1e10212145bf2f97a1a7f27746aa18cfc98', class: "top-center-notification-layer", role: "presentation" }, h("div", { key: 'a77b025329da64e1f1223a2f749aa2fc60e5c469', class: { 'top-center-notification-container': true, 'is-dismissing': this.isNotificationDismissing }, role: "presentation" }, h("kritzel-notification-card", { key: '9ced0bc5213ec8c3387915cd71272a1f56161405', notification: this.activeNotification, locale: this.locale, onDismiss: this.dismissNotification, onHoverChange: event => this.handleNotificationHoverChange(event) })))), h("kritzel-engine", { key: '884b7f088e164a51c49158c409904ca5419f2d55', ref: el => {
3065
+ } }, h("div", { key: '019cbb191155260c635cb13a4d94eebbb5913045', class: "top-left-buttons" }, h("kritzel-workspace-manager", { key: 'b9a60281c57f90dedebd2a01ccc27a689a8f2a09', 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: 'b0b625e1cd07f29d9622b03e49cf75c9324b2d38', visible: this.isBackToContentButtonVisible, text: this.resolvedTerms['backToContent.label'] ?? 'Back to content', onBackToContent: () => this.backToContent() })), this.activeNotification && (h("div", { key: '80868e85dc8a0810750ff5dd04c59057d81fb823', class: "top-center-notification-layer", role: "presentation" }, h("div", { key: '8cfe3895cb8dcd137950daff0e677d397c20817b', class: { 'top-center-notification-container': true, 'is-dismissing': this.isNotificationDismissing }, role: "presentation" }, h("kritzel-notification-card", { key: 'f50a8ff5fba9ee8df8bb0fa5c2b3198ad30fd8cd', notification: this.activeNotification, locale: this.locale, onDismiss: this.dismissNotification, onHoverChange: event => this.handleNotificationHoverChange(event) })))), h("kritzel-engine", { key: '7b31643384b19dfd84b6093a4ccb719dd04b7669', ref: el => {
3059
3066
  if (el) {
3060
3067
  this.engineRef = el;
3061
3068
  }
3062
- }, 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) }), h("kritzel-controls", { key: '3a7c22f037d551636c53190eb07b318c2b857162', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
3069
+ }, 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), onLoadingChange: event => this.handleLoadingChange(event) }), h("kritzel-controls", { key: '14ee52a07381785c4b8ce1f2e1b7304d44e0e128', visible: this.isControlsVisible, class: { 'keyboard-open': this.isVirtualKeyboardOpen }, ref: el => {
3063
3070
  if (el) {
3064
3071
  this.controlsRef = el;
3065
3072
  }
3066
- }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'c0dad9086679397c46f5550c38686a9b7d8bae6c', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: '1639d6d2092ecd3fbc657dfdcfc3f12c02539329', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: '45313b28a5e4bd75d09980e4765c2241d54fe1df', class: "top-right-buttons" }, h("kritzel-settings", { key: '33737a005cd6580505ee741be0dc40bd69873276', ref: el => {
3073
+ }, controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, undoState: this.undoState ?? undefined, theme: this.theme, terms: this.resolvedTerms, onIsControlsReady: () => (this.isControlsReady = true) }), h("div", { key: 'c9ddf5fe7d74f32aff8182ce9dd70931f35a7274', class: "bottom-left-buttons" }, h("kritzel-zoom-panel", { key: '3ede1bacaa3ff6876429347c8edc20939b1ec59e', visible: this.isZoomPanelVisible, disabled: !this.isZoomingEnabled, zoomPercent: this.currentZoomPercent, terms: this.resolvedTerms, onZoomIn: () => this.zoomIn(), onZoomOut: () => this.zoomOut() })), h("div", { key: 'af1f5f33065d5693e1c363f6e0d49d43cf839f88', class: "top-right-buttons" }, h("kritzel-settings", { key: 'f281c4b2c47d0fa15e947c2bd9e6e34f6ab064cf', ref: el => {
3067
3074
  if (el) {
3068
3075
  this.settingsRef = el;
3069
3076
  }
3070
- }, 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: '9e13001850b15b9ce9d8a502466ed9fa05ac1518', ref: el => {
3077
+ }, 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: 'aa9f4d755cd429e287bd9dc513f059006e47c037', ref: el => {
3071
3078
  if (el) {
3072
3079
  this.exportRef = el;
3073
3080
  }
3074
- }, 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: 'f2494af1241ecc068ace09b23cfd405c76bd1273', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '7f199e3493805977b5e5b8d2c736f31729919f96', user: this.user, terms: this.resolvedTerms }), shouldShowLoginButton && (h("kritzel-button", { key: 'c6c192ddb1245acc771ac550c1fe3e4f9bc08eab', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in')), h("kritzel-more-menu", { key: '869194078a4c90d42c5ebd604bc58b4f55fc4cb6', items: this.moreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: '8daed8fd7267aca056b6a53626c721e2f23cead4', ref: el => {
3081
+ }, 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: 'e7f019162bf7fa84c591e78c9255ed54d49d624f', users: this.activeUsers }), shouldShowCurrentUser && h("kritzel-current-user", { key: '5b51e312ca1d94717c8eae781435a1c253dfecc3', user: this.user, terms: this.resolvedTerms, onClick: () => this.currentUserDialogRef?.open() }), shouldShowCurrentUser && (h("kritzel-current-user-dialog", { key: '328297225ea30570baa1aeec8dffda3e5fb90f6e', ref: el => {
3082
+ if (el) {
3083
+ this.currentUserDialogRef = el;
3084
+ this.currentUserDialogRef.addEventListener('logoutRequest', this.handleCurrentUserLogout);
3085
+ }
3086
+ }, user: this.user, terms: this.resolvedTerms })), shouldShowLoginButton && (h("kritzel-button", { key: '719da0f8c343b0e3be80b37318bb27e102ea0f1e', onButtonClick: () => this.loginDialogRef?.open() }, this.resolvedTerms['login.dialogTitle'] ?? 'Sign in')), h("kritzel-more-menu", { key: 'c3d0f82f8e21b53b966fcc99c598051b6e294b6a', items: this.moreMenuItems, visible: this.isMoreMenuVisible, terms: this.resolvedTerms }), h("kritzel-share-dialog", { key: '49a929e16684131fe4e0c7cc9d5f5ad769b6785c', ref: el => {
3075
3087
  if (el) {
3076
3088
  this.shareDialogRef = el;
3077
3089
  }
3078
- }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: 'b65ea0940cee31b152b60881180fab2445c92b0c', ref: el => {
3090
+ }, isPublic: this.currentIsPublic, workspaceId: this.activeWorkspace?.id, terms: this.resolvedTerms, onToggleIsPublic: this.handleToggleIsPublic }), this.loginConfig && (h("kritzel-login-dialog", { key: '113bd2574096d3e64ff36b2b8d152b28ff4ba8f7', ref: el => {
3079
3091
  if (el) {
3080
3092
  this.loginDialogRef = el;
3081
3093
  }
3082
- }, providers: this.loginConfig.providers, dialogTitle: this.loginConfig.title ?? this.resolvedTerms['login.dialogTitle'] ?? 'Sign in', subtitle: this.loginConfig.subtitle, onProviderLogin: this.handleProviderLogin })))));
3094
+ }, providers: this.loginConfig.providers, dialogTitle: this.loginConfig.title ?? this.resolvedTerms['login.dialogTitle'] ?? 'Sign in', subtitle: this.loginConfig.subtitle, onProviderLogin: this.handleProviderLogin }))))));
3083
3095
  }
3084
3096
  static get watchers() { return {
3085
3097
  "isEngineReady": [{
@@ -27397,7 +27409,7 @@ class KritzelWheelHelper {
27397
27409
  }
27398
27410
  }
27399
27411
 
27400
- const kritzelEngineCss = () => `:host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.ProseMirror{outline:none}p,h1,h2,h3,h4,h5,h6,blockquote,pre{margin:0;padding:0}.workspace-loading-overlay{position:absolute;inset:0;z-index:9999;display:flex;align-items:center;justify-content:center;gap:10px;background-color:var(--kritzel-engine-loading-overlay-background, rgba(255, 255, 255, 0.6));color:var(--kritzel-engine-loading-overlay-color, #333);font-family:var(--kritzel-font-family, sans-serif);font-size:1.25rem;pointer-events:all;animation:workspace-loading-fade-in 200ms ease-out var(--kritzel-engine-loading-overlay-delay, 300ms) forwards;opacity:0}.workspace-loading-spinner{width:20px;height:20px;box-sizing:border-box;display:block;flex-shrink:0;border:2px solid var(--kritzel-engine-loading-overlay-spinner-color, #cccccc);border-top-color:var(--kritzel-engine-loading-overlay-spinner-active-color, #333333);border-radius:50%;animation:workspace-loading-spin 0.6s linear infinite}@keyframes workspace-loading-spin{to{transform:rotate(360deg)}}@keyframes workspace-loading-fade-in{to{opacity:1}}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}.PlaygroundEditorTheme__quote{margin:0;margin-left:20px;margin-bottom:10px;font-size:15px;color:rgb(101, 103, 107);border-left-color:rgb(206, 208, 212);border-left-width:4px;border-left-style:solid;padding-left:16px}`;
27412
+ const kritzelEngineCss = () => `:host{display:block;position:relative;height:100%;width:100%;overflow:hidden;background-color:var(--kritzel-engine-background-color, #ffffff)}:host,:host *{touch-action:none;user-select:none}.ProseMirror{outline:none}p,h1,h2,h3,h4,h5,h6,blockquote,pre{margin:0;padding:0}.debug-panel{position:absolute;pointer-events:none;top:0;right:0}.origin{position:relative;top:0;left:0;height:0;width:0;pointer-events:none;-webkit-transform-origin:top left;-moz-transform-origin:top left;transform-origin:top left;overflow:visible}.object{overflow:visible}.PlaygroundEditorTheme__quote{margin:0;margin-left:20px;margin-bottom:10px;font-size:15px;color:rgb(101, 103, 107);border-left-color:rgb(206, 208, 212);border-left-width:4px;border-left-style:solid;padding-left:16px}`;
27401
27413
 
27402
27414
  const KritzelEngine = class {
27403
27415
  get host() { return getElement(this); }
@@ -27627,6 +27639,8 @@ const KritzelEngine = class {
27627
27639
  awarenessChange;
27628
27640
  /** Emitted when notifications change. */
27629
27641
  notificationsChange;
27642
+ /** Emitted when the combined loading state (external `isLoading` prop or internal workspace loading) changes. */
27643
+ loadingChange;
27630
27644
  forceUpdate = 0;
27631
27645
  /** Manually triggers the `objectsSelectionChange` event. */
27632
27646
  async triggerSelectionChange() {
@@ -29085,6 +29099,7 @@ const KritzelEngine = class {
29085
29099
  _objectDistanceFadeCloseMinOpacity = 0;
29086
29100
  syncLoadingState() {
29087
29101
  this.core.store.state.isLoading = this._isWorkspaceLoading || this.isLoading;
29102
+ this.loadingChange.emit(this.core.store.state.isLoading);
29088
29103
  }
29089
29104
  applyToolConfig(tool, toolConfig) {
29090
29105
  Object.entries(toolConfig).forEach(([key, value]) => {
@@ -29130,6 +29145,7 @@ const KritzelEngine = class {
29130
29145
  this.viewportChange = createEvent(this, "viewportChange");
29131
29146
  this.awarenessChange = createEvent(this, "awarenessChange");
29132
29147
  this.notificationsChange = createEvent(this, "notificationsChange");
29148
+ this.loadingChange = createEvent(this, "loadingChange");
29133
29149
  this.core = new KritzelCore(this);
29134
29150
  }
29135
29151
  disconnectedCallback() {
@@ -29484,7 +29500,7 @@ const KritzelEngine = class {
29484
29500
  }
29485
29501
  render() {
29486
29502
  if (!this.viewport) {
29487
- return (h(Host, null, this.core.store.state.isLoading && (h("div", { class: "workspace-loading-overlay" }, h("span", { class: "workspace-loading-spinner" }), this.core.localizationManager.translate('engine.loading')))));
29503
+ return h(Host, null);
29488
29504
  }
29489
29505
  const currentTheme = this.core.themeManager.getStoredTheme();
29490
29506
  const computedStyle = window.getComputedStyle(this.host);
@@ -29541,7 +29557,7 @@ const KritzelEngine = class {
29541
29557
  this.emitObjectsInViewportChange();
29542
29558
  }
29543
29559
  }
29544
- return (h(Host, null, this.core.store.state.isLoading && (h("div", { class: "workspace-loading-overlay" }, h("span", { class: "workspace-loading-spinner" }), "Loading...")), this.core.store.state.debugInfo.showViewportInfo && (h("div", { class: "debug-panel" }, h("div", null, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", null, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", null, "TranslateX: ", this.core.store.state?.translateX), h("div", null, "TranslateY: ", this.core.store.state?.translateY), h("div", null, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", null, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", null, "PointerCount: ", this.core.store.state.pointers.size), h("div", null, "Scale: ", this.core.store.state?.scale), h("div", null, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", null, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", null, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", null, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", null, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", null, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", null, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", null, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", null, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", null, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", null, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", null, "PointerX: ", this.core.store.state?.pointerX), h("div", null, "PointerY: ", this.core.store.state?.pointerY), h("div", null, "TotalObjects: ", this.core.store.totalObjectCount), h("div", null, "ObjectsInViewport: ", this.core.store.objectsInViewport.length), h("div", null, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", null, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { id: "origin", class: "origin", style: {
29560
+ return (h(Host, null, this.core.store.state.debugInfo.showViewportInfo && (h("div", { class: "debug-panel" }, h("div", null, "ActiveWorkspaceId: ", this.core.store.state?.activeWorkspace?.id), h("div", null, "ActiveWorkspaceName: ", this.core.store.state?.activeWorkspace?.name), h("div", null, "TranslateX: ", this.core.store.state?.translateX), h("div", null, "TranslateY: ", this.core.store.state?.translateY), h("div", null, "ViewportWidth: ", this.core.store.state?.viewportWidth), h("div", null, "ViewportHeight: ", this.core.store.state?.viewportHeight), h("div", null, "PointerCount: ", this.core.store.state.pointers.size), h("div", null, "Scale: ", this.core.store.state?.scale), h("div", null, "ActiveTool: ", this.core.store.state?.activeTool?.name), h("div", null, "HasViewportChanged: ", this.core.store.state?.hasViewportChanged ? 'true' : 'false'), h("div", null, "IsEnabled: ", this.core.store.state?.isEnabled ? 'true' : 'false'), h("div", null, "IsScaling: ", this.core.store.state?.isScaling ? 'true' : 'false'), h("div", null, "IsPanning: ", this.core.store.state?.isPanning ? 'true' : 'false'), h("div", null, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), h("div", null, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), h("div", null, "IsResizeHandleSelected: ", this.core.store.state.isResizeHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleSelected: ", this.core.store.state.isRotationHandleSelected ? 'true' : 'false'), h("div", null, "IsRotationHandleHovered: ", this.core.store.state.isRotationHandleHovered ? 'true' : 'false'), h("div", null, "IsDrawing: ", this.core.store.state.isDrawing ? 'true' : 'false'), h("div", null, "IsWriting: ", this.core.store.state.isWriting ? 'true' : 'false'), h("div", null, "IsPointerDown: ", this.core.store.isPointerDown ? 'true' : 'false'), h("div", null, "PointerX: ", this.core.store.state?.pointerX), h("div", null, "PointerY: ", this.core.store.state?.pointerY), h("div", null, "TotalObjects: ", this.core.store.totalObjectCount), h("div", null, "ObjectsInViewport: ", this.core.store.objectsInViewport.length), h("div", null, "SelectedObjects: ", this.core.store.selectionGroup?.objects.length || 0), h("div", null, "ViewportCenter: (", viewportCenterX.toFixed(2), ", ", viewportCenterY.toFixed(2), ")"))), h("div", { id: "origin", class: "origin", style: {
29545
29561
  transform: `matrix(${this.core.store.state?.scale}, 0, 0, ${this.core.store.state?.scale}, ${this.core.store.state?.translateX}, ${this.core.store.state?.translateY})`,
29546
29562
  } }, visibleObjects?.map(object => {
29547
29563
  const { multiplied: effectiveOpacity, overridden: effectiveOpacityString } = this.getObjectEffectiveOpacity(object, viewportScale);
@@ -30139,7 +30155,7 @@ const KritzelExport = class {
30139
30155
  return (h("div", { class: "export-tab-content" }, h("kritzel-input", { label: this.terms['export.filename.label'] ?? 'Filename', value: this.exportFilename, placeholder: this.terms['export.filename.placeholder'] ?? 'Enter filename', suffix: ".json", onValueChange: this.handleFilenameChange })));
30140
30156
  }
30141
30157
  render() {
30142
- return (h(Host, { key: 'fd219fffd4d8bb528e6a90055c2b43a5f5a73060' }, h("kritzel-dialog", { key: '9f4ba5b05f5ad31084aab457386a86cbc6d4f2bc', isOpen: this.isDialogOpen, dialogTitle: this.terms['export.dialogTitle'] ?? 'Export', closable: true, contained: true, onDialogClose: this.closeDialog }, h("div", { key: '920bb8f20b42897680084bde47270b3812e2f3e4', class: "export-content" }, h("kritzel-pill-tabs", { key: '7090bd0a371457adceaa4bd7461a616839a66349', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport(), h("button", { key: 'ddf36c1e7cb81409c2cecfa6585e0f1dd7aca2c3', class: "export-primary-button", onClick: this.handleExport }, this.terms['export.exportButton'] ?? 'Export')))));
30158
+ return (h(Host, { key: '5706e0f8688777826452ca0cf81e2581f6e2d14a' }, h("kritzel-dialog", { key: '8d0d26a672604aec2b899a7ea05ab40031ac9c43', isOpen: this.isDialogOpen, dialogTitle: this.terms['export.dialogTitle'] ?? 'Export', closable: true, contained: true, onDialogClose: this.closeDialog }, h("div", { key: 'a4c3f5a2961aca9dd5cba4045b8bd53635681ab0', class: "export-content" }, h("kritzel-pill-tabs", { key: '51a40a8596e492130cc8fa4c977cde916d7d8392', tabs: this.tabs, value: this.activeTab, onValueChange: this.handleTabChange }), this.activeTab === 'viewport' && this.renderViewportExport(), this.activeTab === 'workspace' && this.renderWorkspaceExport(), h("button", { key: 'a4b8e1503a0a8e682d10623bc334fcc70b5ea243', class: "export-primary-button", onClick: this.handleExport }, this.terms['export.exportButton'] ?? 'Export')))));
30143
30159
  }
30144
30160
  };
30145
30161
  KritzelExport.style = kritzelExportCss();
@@ -30154,7 +30170,7 @@ const KritzelFont = class {
30154
30170
  size = 24;
30155
30171
  color = '#000000';
30156
30172
  render() {
30157
- return (h(Host, { key: 'e37350dd092fb7c81a5624bfdc39c3b9af66b894' }, h("div", { key: 'a962ccc23a48f62b86d49ae41b1c9c27bdc9a5b9', class: "font-preview", style: {
30173
+ return (h(Host, { key: '054371cac30a2433611139a670406b0a1e3b99ff' }, h("div", { key: 'b4f2142b3cb31d067f39952a38b6f665f28f63bf', class: "font-preview", style: {
30158
30174
  fontFamily: this.fontFamily,
30159
30175
  fontSize: `${this.size}px`,
30160
30176
  color: this.color
@@ -30230,7 +30246,7 @@ const KritzelFontSize = class {
30230
30246
  render() {
30231
30247
  const color = 'var(--kritzel-global-text-primary)';
30232
30248
  const sizes = this.sizes ?? [];
30233
- return (h(Host, { key: 'a314e990b56cb4e819c4d83a139016b1658606b8' }, sizes.map(size => (h("div", { tabIndex: 0, class: {
30249
+ return (h(Host, { key: '56eb19367abe312bac3b626cfcae3b1ff6e90d21' }, sizes.map(size => (h("div", { tabIndex: 0, class: {
30234
30250
  'size-container': true,
30235
30251
  'selected': this.selectedSize === size,
30236
30252
  }, onClick: () => this.handleSizeClick(size), onKeyDown: event => this.handleKeyDown(event, size) }, h("kritzel-font", { fontFamily: this.fontFamily, size: size, color: color }))))));
@@ -30297,7 +30313,7 @@ const KritzelInput = class {
30297
30313
  this.valueChange.emit(input.value);
30298
30314
  };
30299
30315
  render() {
30300
- return (h(Host, { key: '7e16272802a5485207721f4f01ddf8e956b56dac' }, h("div", { key: 'ab60dacd08c6199db507d896c00cd0c788ecf7fa', class: "input-container" }, this.label && h("label", { key: 'e2e5769ca2954442da5a0f2a2abb07847986eac8', class: "input-label" }, this.label), h("div", { key: 'e7131f6d1a770cf71de9f7086e3a8a092296b80e', class: { 'input-wrapper': true, 'has-suffix': !!this.suffix } }, h("input", { key: '565cb30ed36818badc148475c596b468cdd2a65b', type: this.type, class: "text-input", value: this.inputValue, placeholder: this.placeholder, disabled: this.disabled, onInput: this.handleInput }), this.suffix && h("span", { key: 'ec4afb63443b6c89a829e515df7d33066f0f8def', class: "input-suffix" }, this.suffix)))));
30316
+ return (h(Host, { key: '46a0a48902a06ad85edcbaad3679ce3fe9ba850c' }, h("div", { key: 'a6beaf920614aa959d2fbd68b7268afba8637358', class: "input-container" }, this.label && h("label", { key: 'ca6d3fb3c22f1540795dbb0695ddd9b87cc05eee', class: "input-label" }, this.label), h("div", { key: '78d116e82531a9cca996d594792245449bcaf9c8', class: { 'input-wrapper': true, 'has-suffix': !!this.suffix } }, h("input", { key: '0d10d6356dea3a11338172bbe8c3c878eefcc708', type: this.type, class: "text-input", value: this.inputValue, placeholder: this.placeholder, disabled: this.disabled, onInput: this.handleInput }), this.suffix && h("span", { key: '0e6166ba8728efc1035302d7fb048306efbe5a68', class: "input-suffix" }, this.suffix)))));
30301
30317
  }
30302
30318
  static get watchers() { return {
30303
30319
  "value": [{
@@ -30390,6 +30406,26 @@ const KritzelLineEndings = class {
30390
30406
  };
30391
30407
  KritzelLineEndings.style = kritzelLineEndingsCss();
30392
30408
 
30409
+ const kritzelLoadingOverlayCss = () => `:host{display:contents}.loading-overlay{position:absolute;inset:0;z-index:var(--kritzel-loading-overlay-z-index, 9999);display:flex;align-items:center;justify-content:center;gap:10px;background-color:var(--kritzel-loading-overlay-background, rgba(255, 255, 255, 0.6));color:var(--kritzel-loading-overlay-color, #333);font-family:var(--kritzel-font-family, sans-serif);font-size:1.25rem;opacity:0;pointer-events:none;visibility:hidden}.loading-overlay.visible{pointer-events:all;visibility:visible;animation:kritzel-loading-fade-in 200ms ease-out var(--kritzel-loading-overlay-delay, 300ms) forwards}.loading-spinner{width:20px;height:20px;box-sizing:border-box;display:block;flex-shrink:0;border:2px solid var(--kritzel-loading-overlay-spinner-color, #cccccc);border-top-color:var(--kritzel-loading-overlay-spinner-active-color, #333333);border-radius:50%;animation:kritzel-loading-spin 0.6s linear infinite}@keyframes kritzel-loading-spin{to{transform:rotate(360deg)}}@keyframes kritzel-loading-fade-in{to{opacity:1}}`;
30410
+
30411
+ const KritzelLoadingOverlay = class {
30412
+ constructor(hostRef) {
30413
+ registerInstance(this, hostRef);
30414
+ }
30415
+ /**
30416
+ * Whether the overlay is visible
30417
+ */
30418
+ visible = false;
30419
+ /**
30420
+ * The text to display next to the spinner
30421
+ */
30422
+ text = 'Loading...';
30423
+ render() {
30424
+ return (h(Host, { key: 'b8c4784803ca5a0e6bf3f25c1d39139307bb6d50' }, h("div", { key: '5a8a2c44f1800c0275d1a94aa0eb5c2854be63b5', class: { 'loading-overlay': true, visible: this.visible }, "aria-hidden": this.visible ? 'false' : 'true' }, h("span", { key: '04e33166e054d7a600a83dacd48e3fb50ab69d22', class: "loading-spinner" }), this.text)));
30425
+ }
30426
+ };
30427
+ KritzelLoadingOverlay.style = kritzelLoadingOverlayCss();
30428
+
30393
30429
  const kritzelLoginDialogCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-width-small:380px}.login-content{display:flex;flex-direction:column;gap:20px}.login-subtitle{font-size:13px;color:var(--kritzel-login-dialog-subtitle-color, #666666);margin:0;line-height:1.5;text-align:center}.login-providers{display:flex;flex-direction:column;gap:10px}.provider-button{display:flex;align-items:center;justify-content:center;gap:10px;width:100%;padding:12px 16px;border:1px solid var(--kritzel-login-dialog-button-border-color, #e0e0e0);border-radius:8px;background:var(--kritzel-login-dialog-button-background, #ffffff);color:var(--kritzel-login-dialog-button-text-color, #333333);font-size:14px;font-weight:500;font-family:inherit;cursor:var(--kritzel-global-pointer-cursor, pointer);transition:background-color 0.15s ease, border-color 0.15s ease, opacity 0.15s ease;-webkit-tap-highlight-color:transparent}.provider-button:hover:not(:disabled){background:var(--kritzel-login-dialog-button-hover-background, #f5f5f5);border-color:var(--kritzel-login-dialog-button-hover-border-color, #cccccc)}.provider-button:active:not(:disabled){background:var(--kritzel-login-dialog-button-active-background, #ebebeb)}.provider-button:focus-visible{outline:revert;outline-offset:revert}.provider-button.is-disabled{opacity:0.5;cursor:default;pointer-events:none}.provider-button.is-loading{cursor:default}.provider-label{flex-shrink:0}.provider-button.is-loading .provider-label{opacity:0.7}@keyframes kritzel-login-spin{to{transform:rotate(360deg)}}.spinner{width:20px;height:20px;box-sizing:border-box;display:block;flex-shrink:0;border:2px solid var(--kritzel-login-dialog-spinner-color, #cccccc);border-top-color:var(--kritzel-login-dialog-spinner-active-color, #333333);border-radius:50%;animation:kritzel-login-spin 0.6s linear infinite}`;
30394
30430
 
30395
30431
  const KritzelLoginDialog = class {
@@ -30437,7 +30473,7 @@ const KritzelLoginDialog = class {
30437
30473
  this.dialogClosed.emit();
30438
30474
  };
30439
30475
  render() {
30440
- return (h(Host, { key: '6ef65077c95d32fee8da4b70ad2e832ad1bb78f7' }, h("kritzel-dialog", { key: '04f3d3350393475c7267d8ca90c0b3f0fce10c38', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: 'c2ed4e339d86dcea23b4a0778b8966a6ae36107a', class: "login-content" }, this.subtitle && (h("p", { key: 'ae46baa70526d057b3427459903287489e645e08', class: "login-subtitle" }, this.subtitle)), h("div", { key: '1055d5861e5281be234094a3c5c86a6aaf58935f', class: "login-providers" }, this.providers.map(provider => (h("button", { key: provider.name, class: {
30476
+ return (h(Host, { key: '5cedcb4fa0a9026338e930cfbbdbfa1df9853530' }, h("kritzel-dialog", { key: '1502a2dc67630b0a1399ef6e8d1a2fdcd4d50913', dialogTitle: this.dialogTitle, isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, size: "small", contained: true }, h("div", { key: 'f84a888ccc0b1cb2052e30af56a08910da8d85b5', class: "login-content" }, this.subtitle && (h("p", { key: '971040609c43efea30a7bfd0c1a3de2113f77a2b', class: "login-subtitle" }, this.subtitle)), h("div", { key: 'ecb0c648ce0d9a8ca8b10e6a520273d817c7a0fe', class: "login-providers" }, this.providers.map(provider => (h("button", { key: provider.name, class: {
30441
30477
  'provider-button': true,
30442
30478
  'is-loading': this.loadingProvider === provider.name,
30443
30479
  'is-disabled': this.loadingProvider !== null && this.loadingProvider !== provider.name,
@@ -30543,15 +30579,15 @@ const KritzelMasterDetail = class {
30543
30579
  const selectedItem = this.items.find(item => item.id === this.selectedItemId);
30544
30580
  const panelId = 'master-detail-panel';
30545
30581
  const selectedTabId = selectedItem ? `tab-${selectedItem.id}` : undefined;
30546
- return (h(Host, { key: 'e094bc3df0e0d1598e84c9a17a033079b1db33f6' }, h("div", { key: '79509ba5d63703fe36650b07b5172f77bd6eafde', class: {
30582
+ return (h(Host, { key: '0edf50b0b853633b88bf481f97f22aceba9e163e' }, h("div", { key: '21a0a3f81e5a60889ccd152c905cb41f52c3e037', class: {
30547
30583
  'master-detail-container': true,
30548
30584
  'is-mobile-detail-visible': this.showMobileDetail,
30549
- } }, h("nav", { key: '79d200d8c2e54789a33fc88b07c48f034de140ad', class: "master-menu", role: "tablist", "aria-orientation": "vertical", "aria-label": "Settings categories" }, this.items.map((item, index) => (h("button", { key: item.id, id: `tab-${item.id}`, ref: el => this.setTabRef(el, index), class: {
30585
+ } }, h("nav", { key: '41f88248cc372c8cae4cb50a19edf462a01e43f2', class: "master-menu", role: "tablist", "aria-orientation": "vertical", "aria-label": "Settings categories" }, this.items.map((item, index) => (h("button", { key: item.id, id: `tab-${item.id}`, ref: el => this.setTabRef(el, index), class: {
30550
30586
  'menu-item': true,
30551
30587
  'is-selected': item.id === this.selectedItemId,
30552
30588
  'is-disabled': !!item.disabled,
30553
30589
  'is-focused': index === this.focusedIndex,
30554
- }, role: "tab", "aria-selected": item.id === this.selectedItemId ? 'true' : 'false', "aria-controls": panelId, "aria-disabled": item.disabled ? 'true' : undefined, tabIndex: this.getTabIndex(item, index), disabled: item.disabled, onClick: () => this.handleItemClick(item), onKeyDown: e => this.handleKeyDown(e, item, index), onFocus: () => this.handleFocus(index), onBlur: this.handleBlur }, item.icon && (h("kritzel-icon", { name: item.icon, size: 20, class: "menu-item-icon" })), h("span", { class: "menu-item-label" }, item.label), h("span", { class: "menu-item-chevron", "aria-hidden": "true" }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "m9 18 6-6-6-6" }))))))), h("div", { key: '642b65781509d192330bb2602dd081585d16f76d', id: panelId, class: "detail-panel", role: "tabpanel", "aria-labelledby": selectedTabId }, h("button", { key: '18a922dbaad63f05bc3ca7de176de4996b5d7fcb', class: "mobile-back-button", onClick: this.handleBackClick, "aria-label": "Back to menu" }, h("kritzel-icon", { key: 'b31732cef2ffdb78e67be7ab793aaaf60e373763', name: "chevron-left", size: 20, class: "mobile-back-icon" }), "Back"), h("slot", { key: '48fe4ae631a8c0b2db9e4a232edb6300d603562c' })))));
30590
+ }, role: "tab", "aria-selected": item.id === this.selectedItemId ? 'true' : 'false', "aria-controls": panelId, "aria-disabled": item.disabled ? 'true' : undefined, tabIndex: this.getTabIndex(item, index), disabled: item.disabled, onClick: () => this.handleItemClick(item), onKeyDown: e => this.handleKeyDown(e, item, index), onFocus: () => this.handleFocus(index), onBlur: this.handleBlur }, item.icon && (h("kritzel-icon", { name: item.icon, size: 20, class: "menu-item-icon" })), h("span", { class: "menu-item-label" }, item.label), h("span", { class: "menu-item-chevron", "aria-hidden": "true" }, h("svg", { viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", "stroke-width": "1.5", "stroke-linecap": "round", "stroke-linejoin": "round" }, h("path", { d: "m9 18 6-6-6-6" }))))))), h("div", { key: 'f8447facf3dfdbd7772823654847e1b90b03f73e', id: panelId, class: "detail-panel", role: "tabpanel", "aria-labelledby": selectedTabId }, h("button", { key: '3edc9784267613e6b3a706739bbb537161e4c747', class: "mobile-back-button", onClick: this.handleBackClick, "aria-label": "Back to menu" }, h("kritzel-icon", { key: 'ec0b4691735578525e5863842271366e04b13fb7', name: "chevron-left", size: 20, class: "mobile-back-icon" }), "Back"), h("slot", { key: 'c21fbaff78f98859b9756427125b60504d4bb630' })))));
30555
30591
  }
30556
30592
  static get watchers() { return {
30557
30593
  "selectedItemId": [{
@@ -30624,7 +30660,7 @@ const KritzelMenu = class {
30624
30660
  this.itemCloseChildMenu.emit(event.detail);
30625
30661
  };
30626
30662
  render() {
30627
- return (h(Host, { key: '6dfdc7928ae69aa191b2c64f9db79801e6978e92', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && h("div", { key: 'ab8fa25f1b6ee0b7960cb0df84c40b1a7648c4e9', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (h("kritzel-menu-item", { key: item.id, "data-testid": `menu-item-${item.id}`, item: item, parent: this.parent, style: { pointerEvents: this.editingMenuItem && !item.isEditing ? 'none' : 'auto' }, onItemSelect: this.handleItemSelect, onItemSave: this.handleSave, onItemCancel: this.handleCancel, onItemToggleChildMenu: this.handleToggleChildMenu, onItemCloseChildMenu: this.handleCloseChildMenu })))));
30663
+ return (h(Host, { key: '27a90a3a8549517a2d6e341a5da13496bf714970', tabIndex: 0, onClick: e => e.stopPropagation() }, this.openChildMenuItem && h("div", { key: 'c0c2351fac389f6676b38481eaacee553ca6867a', class: "has-open-child-overlay", onClick: this.onOverlayClick }), this.items.map(item => (h("kritzel-menu-item", { key: item.id, "data-testid": `menu-item-${item.id}`, item: item, parent: this.parent, style: { pointerEvents: this.editingMenuItem && !item.isEditing ? 'none' : 'auto' }, onItemSelect: this.handleItemSelect, onItemSave: this.handleSave, onItemCancel: this.handleCancel, onItemToggleChildMenu: this.handleToggleChildMenu, onItemCloseChildMenu: this.handleCloseChildMenu })))));
30628
30664
  }
30629
30665
  };
30630
30666
  KritzelMenu.style = kritzelMenuCss();
@@ -30729,12 +30765,12 @@ const KritzelMenuItem = class {
30729
30765
  ];
30730
30766
  }
30731
30767
  render() {
30732
- return (h(Host, { key: 'dbdcfcee7fd36fe0b9c405dd3d1641aa62465e53', tabIndex: this.item.isDisabled ? -1 : 0, class: {
30768
+ return (h(Host, { key: '9d6653a630da5a3da38291d89d6d7d59d6994e02', tabIndex: this.item.isDisabled ? -1 : 0, class: {
30733
30769
  'selected': this.item.isSelected,
30734
30770
  'editing': this.item.isEditing,
30735
30771
  'disabled': this.item.isDisabled,
30736
30772
  'child-open': this.item.isChildMenuOpen,
30737
- }, onClick: this.handleItemSelect }, h("div", { key: 'ef97c7cf48190c1bbdde0dd9011cc1d5674b7c94', class: "menu-item-overlay" }), this.item.isEditing ? this.renderEditMode() : this.renderViewMode()));
30773
+ }, onClick: this.handleItemSelect }, h("div", { key: '48a1678296e672c6c03fb3e1473c42d3a246d481', class: "menu-item-overlay" }), this.item.isEditing ? this.renderEditMode() : this.renderViewMode()));
30738
30774
  }
30739
30775
  static get watchers() { return {
30740
30776
  "item": [{
@@ -30807,7 +30843,7 @@ const KritzelMoreMenu = class {
30807
30843
  this.closeMenu();
30808
30844
  };
30809
30845
  render() {
30810
- return (h(Host, { key: '3e7179c87713cb0087d2d2053f97db8f603f7321', class: { mobile: this.isTouchDevice }, style: { display: this.visible ? '' : 'none' } }, h("div", { key: '23d6be1ec2c25cd0335c1134f18aad7d5be25c85', class: { 'more-menu-wrapper': true, visible: this.visible } }, h("button", { key: 'e3064ba3f7b4c20e8447e16327b73d0f47f3842b', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu, "aria-label": this.terms['moreMenu.ariaLabel'] ?? 'More options' }, h("kritzel-icon", { key: 'feed090efe4f80c62a29c8146c2d7d8041624381', name: this.icon, size: this.iconSize })), h("kritzel-portal", { key: '7b1a5db932c7bfb5ea8f4d666571c4f7fbbcd238', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, h("kritzel-menu", { key: '65b1225b15a494d49712ad1d2d108e90f09507e9', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
30846
+ return (h(Host, { key: 'b7736b67210f2d2f6b54296dd680104548d61641', class: { mobile: this.isTouchDevice }, style: { display: this.visible ? '' : 'none' } }, h("div", { key: '076ecc02a1469bd87cb27f63f1d41183bedb11d4', class: { 'more-menu-wrapper': true, visible: this.visible } }, h("button", { key: 'cefe02e440391eb079af7b8accc367a291e93d6a', class: "more-menu-button", "data-testid": "more-menu-button", onClick: this.toggleMenu, "aria-label": this.terms['moreMenu.ariaLabel'] ?? 'More options' }, h("kritzel-icon", { key: 'cb6f4dd0f37ac0fbf1e1c28a0dc06e097e38ee00', name: this.icon, size: this.iconSize })), h("kritzel-portal", { key: '29099deb5b56b1a1388caa81a3c7104a05ad66a7', anchor: this.menuAnchor, offsetY: this.offsetY, onClose: this.closeMenu }, h("kritzel-menu", { key: 'b77286ec05add0a20bbc46f99ac7210395d0d33d', items: this.visibleItems, onItemSelect: this.handleMenuItemSelect })))));
30811
30847
  }
30812
30848
  };
30813
30849
  KritzelMoreMenu.style = kritzelMoreMenuCss();
@@ -30974,7 +31010,7 @@ const KritzelNumericInput = class {
30974
31010
  this.valueChange.emit(newValue);
30975
31011
  };
30976
31012
  render() {
30977
- return (h(Host, { key: '008f18fc5ab81adcd82364706ca7d4c39ea39d77' }, h("div", { key: '5d91b2ec6e0458d186d923c422e8f6461ac7c51a', class: "input-container" }, this.label && h("label", { key: '45c911f1e11ff8289ab876192511f506eb65c940', class: "input-label" }, this.label), h("div", { key: 'f5e0bd1610a4085a291cc1d32787b68066757c69', class: "input-wrapper" }, h("input", { key: '897b1af7725f59df86a530836dda802e8cb04038', type: "number", class: "numeric-input", title: "", min: this.min === Number.MIN_SAFE_INTEGER ? undefined : this.min, max: this.max === Number.MAX_SAFE_INTEGER ? undefined : this.max, step: this.step, value: this.inputValue, placeholder: this.placeholder, onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown, onInvalid: this.handleInvalid }), h("div", { key: '1acab70c82ff7431f916685084a6e5dd827cdca3', class: "spinner-buttons" }, h("button", { key: 'd93c4bec338d49ead87897baf61d2e036999a035', type: "button", class: "spinner-button spinner-up", onClick: this.handleIncrement, tabIndex: -1, "aria-label": "Increase value" }, h("svg", { key: '1e52d43c1eb1e9a43025302a7cd1f3d74c038c36', viewBox: "0 0 10 6", class: "spinner-icon" }, h("path", { key: '2a96516390bd9caf5b6a3617d07f7b10e2b42451', d: "M1 5L5 1L9 5", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))), h("button", { key: '038cf61f4b8982a17bf5c279d78556872a03efea', type: "button", class: "spinner-button spinner-down", onClick: this.handleDecrement, tabIndex: -1, "aria-label": "Decrease value" }, h("svg", { key: '30110c2ad975b51049a902953c52be66c1b7b0af', viewBox: "0 0 10 6", class: "spinner-icon" }, h("path", { key: '5abe735234debfa80a983d2fb60eeeaedb1dbf9b', d: "M1 1L5 5L9 1", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))))))));
31013
+ return (h(Host, { key: '8901e0b56ccbc344420483a4a56663f7cd74d9e8' }, h("div", { key: '5f3d6b5c56007e11383aa69f60f22031b0e8f332', class: "input-container" }, this.label && h("label", { key: '2cb102a5b6c16d068f4f304fbcc6241f79fc0ce8', class: "input-label" }, this.label), h("div", { key: '96441095acc3d9a8e77b6d2bac2ceda683c9c976', class: "input-wrapper" }, h("input", { key: '523a5485111077e20faded235df6362e5ea9cfd4', type: "number", class: "numeric-input", title: "", min: this.min === Number.MIN_SAFE_INTEGER ? undefined : this.min, max: this.max === Number.MAX_SAFE_INTEGER ? undefined : this.max, step: this.step, value: this.inputValue, placeholder: this.placeholder, onInput: this.handleInput, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown, onInvalid: this.handleInvalid }), h("div", { key: '2071e98125a8d014513e93052bd8c1fee17932a5', class: "spinner-buttons" }, h("button", { key: '12422e5285dfb532dbbb6eb1a36dbcb3de50f2bc', type: "button", class: "spinner-button spinner-up", onClick: this.handleIncrement, tabIndex: -1, "aria-label": "Increase value" }, h("svg", { key: '49ad5625c80fae6706ba4ab91f47bd550481ef74', viewBox: "0 0 10 6", class: "spinner-icon" }, h("path", { key: 'ff7d19b61baeb5ba58bb60f2cc629bcec6eb4411', d: "M1 5L5 1L9 5", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))), h("button", { key: 'e4fec28e4fc997e007127f2b30b00cc752433221', type: "button", class: "spinner-button spinner-down", onClick: this.handleDecrement, tabIndex: -1, "aria-label": "Decrease value" }, h("svg", { key: '27bf06cde8de11f4a97090911afd6b8993463112', viewBox: "0 0 10 6", class: "spinner-icon" }, h("path", { key: 'ed7071dd79bfe509ebb319ce43ecb3e982dd4157', d: "M1 1L5 5L9 1", stroke: "currentColor", "stroke-width": "1.5", fill: "none", "stroke-linecap": "round", "stroke-linejoin": "round" }))))))));
30978
31014
  }
30979
31015
  static get watchers() { return {
30980
31016
  "value": [{
@@ -31013,7 +31049,7 @@ const KritzelOpacitySlider = class {
31013
31049
  }
31014
31050
  render() {
31015
31051
  const percentage = this.getPercentage();
31016
- return (h(Host, { key: 'e3a18981e5193ecd1ffaae5c807bdf6fa67e9695' }, h("div", { key: 'ee5ff0bb1355ca4f7e5d727ab8861933259c1a82', class: "opacity-container" }, h("div", { key: '6362fb3dba6910c55f5fe3b2a4245bcbb33dcdbb', class: "slider-wrapper" }, h("input", { key: 'f435f00fff7cc17ccdc181f39b29e032f6c5bf8d', type: "range", class: "opacity-slider", min: this.min, max: this.max, step: this.step, value: this.value, onInput: (e) => this.handleInput(e), style: {
31052
+ return (h(Host, { key: '2dadd8a7c4d1af748e91a6005433288ab231f2e8' }, h("div", { key: '65ae90d95bffff244d97329754cf0cb8f73331fa', class: "opacity-container" }, h("div", { key: '90e95347f7015882112f0653a25347e715233227', class: "slider-wrapper" }, h("input", { key: '15836bc089c1725062016677d3b95384d1958431', type: "range", class: "opacity-slider", min: this.min, max: this.max, step: this.step, value: this.value, onInput: (e) => this.handleInput(e), style: {
31017
31053
  '--slider-progress': `${percentage}%`,
31018
31054
  '--kritzel-opacity-slider-thumb-border-color': this.previewColor,
31019
31055
  } })))));
@@ -31021,7 +31057,7 @@ const KritzelOpacitySlider = class {
31021
31057
  };
31022
31058
  KritzelOpacitySlider.style = kritzelOpacitySliderCss();
31023
31059
 
31024
- const kritzelPillTabsCss = () => `:host{display:block}.pill-tabs-container{display:inline-flex;align-items:center;gap:4px;padding:4px;border-radius:var(--kritzel-pill-tabs-border-radius, 10px);background:var(--kritzel-pill-tabs-background, #f0f0f0);box-sizing:border-box}.pill-tab{display:flex;align-items:center;justify-content:center;gap:6px;padding:8px 16px;border:none;border-radius:var(--kritzel-pill-tabs-tab-border-radius, 8px);background:var(--kritzel-pill-tabs-tab-background, transparent);color:var(--kritzel-pill-tabs-tab-text-color, #666666);font-family:inherit;font-size:14px;font-weight:500;cursor:var(--kritzel-global-pointer-cursor, pointer);transition:background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;white-space:nowrap}.pill-tab:hover:not(.selected){background:var(--kritzel-pill-tabs-tab-background-hover, rgba(0, 0, 0, 0.05))}.pill-tab.selected{background:var(--kritzel-pill-tabs-tab-background-selected, #ffffff);color:var(--kritzel-pill-tabs-tab-text-color-selected, #000000);box-shadow:var(--kritzel-pill-tabs-tab-shadow-selected, 0 1px 3px rgba(0, 0, 0, 0.1))}.pill-tab:focus{outline:none}.pill-tab:focus-visible{box-shadow:0 0 0 2px var(--kritzel-global-focus-ring-color, rgba(0, 122, 255, 0.3))}.pill-tab-label{line-height:1}.pill-tab kritzel-icon{flex-shrink:0}`;
31060
+ const kritzelPillTabsCss = () => `:host{display:block;max-width:100%}.pill-tabs-container{display:inline-flex;align-items:center;gap:4px;padding:4px;max-width:100%;border-radius:var(--kritzel-pill-tabs-border-radius, 10px);background:var(--kritzel-pill-tabs-background, #f0f0f0);box-sizing:border-box}.pill-tab{display:flex;align-items:center;justify-content:center;gap:6px;min-width:0;max-width:100%;padding:8px 16px;border:none;border-radius:var(--kritzel-pill-tabs-tab-border-radius, 8px);background:var(--kritzel-pill-tabs-tab-background, transparent);color:var(--kritzel-pill-tabs-tab-text-color, #666666);font-family:inherit;font-size:14px;font-weight:500;cursor:var(--kritzel-global-pointer-cursor, pointer);transition:background-color 0.15s ease, color 0.15s ease, box-shadow 0.15s ease;white-space:nowrap}.pill-tab:hover:not(.selected){background:var(--kritzel-pill-tabs-tab-background-hover, rgba(0, 0, 0, 0.05))}.pill-tab.selected{background:var(--kritzel-pill-tabs-tab-background-selected, #ffffff);color:var(--kritzel-pill-tabs-tab-text-color-selected, #000000);box-shadow:var(--kritzel-pill-tabs-tab-shadow-selected, 0 1px 3px rgba(0, 0, 0, 0.1))}.pill-tab:focus{outline:none}.pill-tab:focus-visible{box-shadow:0 0 0 2px var(--kritzel-global-focus-ring-color, rgba(0, 122, 255, 0.3))}.pill-tab-label{display:block;min-width:0;max-width:var(--kritzel-pill-tabs-tab-label-max-width, 10rem);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;line-height:1}.pill-tab kritzel-icon{flex-shrink:0}`;
31025
31061
 
31026
31062
  const KritzelPillTabs = class {
31027
31063
  constructor(hostRef) {
@@ -31366,7 +31402,7 @@ const KritzelPortal = class {
31366
31402
  this.portal.style.visibility = 'visible';
31367
31403
  }
31368
31404
  render() {
31369
- return (h(Host, { key: '95fbfde070f33a7f1b59026de7c687a2f6d0119c', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: '14af59a35c5caf71079f7afb5ea6f4c5f13b05f8' })));
31405
+ return (h(Host, { key: '72273b4c7811473072ee27668836a5ddddcfd618', style: { display: this.anchor ? 'block' : 'none' } }, h("slot", { key: 'b4f37ca27c47ab950a4639162fa31a3c2362d6f7' })));
31370
31406
  }
31371
31407
  static get watchers() { return {
31372
31408
  "anchor": [{
@@ -31380,7 +31416,7 @@ const KritzelPortal = class {
31380
31416
  * This file is auto-generated by the version bump scripts.
31381
31417
  * Do not modify manually.
31382
31418
  */
31383
- const KRITZEL_VERSION = '0.3.33';
31419
+ const KRITZEL_VERSION = '0.3.35';
31384
31420
 
31385
31421
  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: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)}`;
31386
31422
 
@@ -31605,7 +31641,7 @@ const KritzelSettings = class {
31605
31641
  }
31606
31642
  }
31607
31643
  render() {
31608
- return (h(Host, { key: '8b96261465efeabb2eb0cf724d29699de5e230a8' }, h("kritzel-dialog", { key: '273a9df290bb97d59000a97f91821e7bad3f3896', isOpen: this.isDialogOpen, dialogTitle: this.t('settings.dialogTitle', 'Settings'), size: "large", contained: true, onDialogClose: this.closeDialog }, h("kritzel-master-detail", { key: '64d17dfaa2a0baf2d4a5d00fe5fc65ad40c96ec6', items: this.categories, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
31644
+ return (h(Host, { key: '7e65885051a30635291bb98fb87addf0bdbca8e8' }, h("kritzel-dialog", { key: 'c795bad227882904d8dda96768e8ccdd7c48df71', isOpen: this.isDialogOpen, dialogTitle: this.t('settings.dialogTitle', 'Settings'), size: "large", contained: true, onDialogClose: this.closeDialog }, h("kritzel-master-detail", { key: 'eff1486d14d4b55441b9a52b293da7459771331d', items: this.categories, selectedItemId: this.selectedCategoryId, onItemSelect: this.handleCategorySelect }, this.renderCategoryContent()))));
31609
31645
  }
31610
31646
  static get watchers() { return {
31611
31647
  "settings": [{
@@ -31649,7 +31685,3078 @@ const KritzelShapeFill = class {
31649
31685
  };
31650
31686
  KritzelShapeFill.style = kritzelShapeFillCss();
31651
31687
 
31652
- const kritzelShareDialogCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-width-small:420px}.share-content{display:flex;flex-direction:column;gap:20px}.share-section{display:flex;flex-direction:column;gap:8px}.share-section-revoke{padding-top:12px;border-top:1px solid var(--kritzel-share-dialog-border-color, #e5e5e5)}.share-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.share-label-group{display:flex;flex-direction:column;gap:8px;flex:1}.share-label{font-size:14px;font-weight:600;color:var(--kritzel-share-dialog-label-color, #333333);margin:0}.share-description{font-size:12px;color:var(--kritzel-share-dialog-description-color, #666666);margin:0;line-height:1.4}.share-url-container{display:flex;align-items:center;gap:8px;background:var(--kritzel-share-dialog-input-background, #f5f5f5);border:1px solid var(--kritzel-share-dialog-input-border-color, #e0e0e0);border-radius:6px;padding:4px 4px 4px 12px}.share-url-input{flex:1;border:none;background:transparent;font-size:13px;color:var(--kritzel-share-dialog-input-text-color, #333333);outline:none;min-width:0;padding:8px 0}.share-url-input:focus{outline:none}.share-url-input::selection{background:var(--kritzel-share-dialog-selection-color, #cce5ff)}.copy-button{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:4px;background:var(--kritzel-share-dialog-copy-button-background, #ffffff);color:var(--kritzel-share-dialog-copy-button-color, #666666);cursor:pointer;transition:all 0.15s ease;flex-shrink:0}.copy-button:hover{background:var(--kritzel-share-dialog-copy-button-hover-background, #e8e8e8);color:var(--kritzel-share-dialog-copy-button-hover-color, #333333)}.copy-button.copy-success{background:var(--kritzel-share-dialog-copy-success-background, #d4edda);color:var(--kritzel-share-dialog-copy-success-color, #28a745)}.revoke-button{align-self:flex-start;padding:8px 16px;border:1px solid var(--kritzel-share-dialog-revoke-button-border-color, #dc3545);border-radius:6px;background:transparent;color:var(--kritzel-share-dialog-revoke-button-color, #dc3545);font-size:13px;font-weight:500;cursor:pointer;transition:all 0.15s ease}.revoke-button:hover{background:var(--kritzel-share-dialog-revoke-button-hover-background, #dc3545);color:var(--kritzel-share-dialog-revoke-button-hover-color, #ffffff)}kritzel-dropdown{--kritzel-dropdown-trigger-padding:8px 12px;--kritzel-dropdown-trigger-font-size:13px}`;
31688
+ var browser = {};
31689
+
31690
+ var canPromise;
31691
+ var hasRequiredCanPromise;
31692
+
31693
+ function requireCanPromise () {
31694
+ if (hasRequiredCanPromise) return canPromise;
31695
+ hasRequiredCanPromise = 1;
31696
+ // can-promise has a crash in some versions of react native that dont have
31697
+ // standard global objects
31698
+ // https://github.com/soldair/node-qrcode/issues/157
31699
+
31700
+ canPromise = function () {
31701
+ return typeof Promise === 'function' && Promise.prototype && Promise.prototype.then
31702
+ };
31703
+ return canPromise;
31704
+ }
31705
+
31706
+ var qrcode = {};
31707
+
31708
+ var utils$1 = {};
31709
+
31710
+ var hasRequiredUtils$1;
31711
+
31712
+ function requireUtils$1 () {
31713
+ if (hasRequiredUtils$1) return utils$1;
31714
+ hasRequiredUtils$1 = 1;
31715
+ let toSJISFunction;
31716
+ const CODEWORDS_COUNT = [
31717
+ 0, // Not used
31718
+ 26, 44, 70, 100, 134, 172, 196, 242, 292, 346,
31719
+ 404, 466, 532, 581, 655, 733, 815, 901, 991, 1085,
31720
+ 1156, 1258, 1364, 1474, 1588, 1706, 1828, 1921, 2051, 2185,
31721
+ 2323, 2465, 2611, 2761, 2876, 3034, 3196, 3362, 3532, 3706
31722
+ ];
31723
+
31724
+ /**
31725
+ * Returns the QR Code size for the specified version
31726
+ *
31727
+ * @param {Number} version QR Code version
31728
+ * @return {Number} size of QR code
31729
+ */
31730
+ utils$1.getSymbolSize = function getSymbolSize (version) {
31731
+ if (!version) throw new Error('"version" cannot be null or undefined')
31732
+ if (version < 1 || version > 40) throw new Error('"version" should be in range from 1 to 40')
31733
+ return version * 4 + 17
31734
+ };
31735
+
31736
+ /**
31737
+ * Returns the total number of codewords used to store data and EC information.
31738
+ *
31739
+ * @param {Number} version QR Code version
31740
+ * @return {Number} Data length in bits
31741
+ */
31742
+ utils$1.getSymbolTotalCodewords = function getSymbolTotalCodewords (version) {
31743
+ return CODEWORDS_COUNT[version]
31744
+ };
31745
+
31746
+ /**
31747
+ * Encode data with Bose-Chaudhuri-Hocquenghem
31748
+ *
31749
+ * @param {Number} data Value to encode
31750
+ * @return {Number} Encoded value
31751
+ */
31752
+ utils$1.getBCHDigit = function (data) {
31753
+ let digit = 0;
31754
+
31755
+ while (data !== 0) {
31756
+ digit++;
31757
+ data >>>= 1;
31758
+ }
31759
+
31760
+ return digit
31761
+ };
31762
+
31763
+ utils$1.setToSJISFunction = function setToSJISFunction (f) {
31764
+ if (typeof f !== 'function') {
31765
+ throw new Error('"toSJISFunc" is not a valid function.')
31766
+ }
31767
+
31768
+ toSJISFunction = f;
31769
+ };
31770
+
31771
+ utils$1.isKanjiModeEnabled = function () {
31772
+ return typeof toSJISFunction !== 'undefined'
31773
+ };
31774
+
31775
+ utils$1.toSJIS = function toSJIS (kanji) {
31776
+ return toSJISFunction(kanji)
31777
+ };
31778
+ return utils$1;
31779
+ }
31780
+
31781
+ var errorCorrectionLevel = {};
31782
+
31783
+ var hasRequiredErrorCorrectionLevel;
31784
+
31785
+ function requireErrorCorrectionLevel () {
31786
+ if (hasRequiredErrorCorrectionLevel) return errorCorrectionLevel;
31787
+ hasRequiredErrorCorrectionLevel = 1;
31788
+ (function (exports) {
31789
+ exports.L = { bit: 1 };
31790
+ exports.M = { bit: 0 };
31791
+ exports.Q = { bit: 3 };
31792
+ exports.H = { bit: 2 };
31793
+
31794
+ function fromString (string) {
31795
+ if (typeof string !== 'string') {
31796
+ throw new Error('Param is not a string')
31797
+ }
31798
+
31799
+ const lcStr = string.toLowerCase();
31800
+
31801
+ switch (lcStr) {
31802
+ case 'l':
31803
+ case 'low':
31804
+ return exports.L
31805
+
31806
+ case 'm':
31807
+ case 'medium':
31808
+ return exports.M
31809
+
31810
+ case 'q':
31811
+ case 'quartile':
31812
+ return exports.Q
31813
+
31814
+ case 'h':
31815
+ case 'high':
31816
+ return exports.H
31817
+
31818
+ default:
31819
+ throw new Error('Unknown EC Level: ' + string)
31820
+ }
31821
+ }
31822
+
31823
+ exports.isValid = function isValid (level) {
31824
+ return level && typeof level.bit !== 'undefined' &&
31825
+ level.bit >= 0 && level.bit < 4
31826
+ };
31827
+
31828
+ exports.from = function from (value, defaultValue) {
31829
+ if (exports.isValid(value)) {
31830
+ return value
31831
+ }
31832
+
31833
+ try {
31834
+ return fromString(value)
31835
+ } catch (e) {
31836
+ return defaultValue
31837
+ }
31838
+ };
31839
+ } (errorCorrectionLevel));
31840
+ return errorCorrectionLevel;
31841
+ }
31842
+
31843
+ var bitBuffer;
31844
+ var hasRequiredBitBuffer;
31845
+
31846
+ function requireBitBuffer () {
31847
+ if (hasRequiredBitBuffer) return bitBuffer;
31848
+ hasRequiredBitBuffer = 1;
31849
+ function BitBuffer () {
31850
+ this.buffer = [];
31851
+ this.length = 0;
31852
+ }
31853
+
31854
+ BitBuffer.prototype = {
31855
+
31856
+ get: function (index) {
31857
+ const bufIndex = Math.floor(index / 8);
31858
+ return ((this.buffer[bufIndex] >>> (7 - index % 8)) & 1) === 1
31859
+ },
31860
+
31861
+ put: function (num, length) {
31862
+ for (let i = 0; i < length; i++) {
31863
+ this.putBit(((num >>> (length - i - 1)) & 1) === 1);
31864
+ }
31865
+ },
31866
+
31867
+ getLengthInBits: function () {
31868
+ return this.length
31869
+ },
31870
+
31871
+ putBit: function (bit) {
31872
+ const bufIndex = Math.floor(this.length / 8);
31873
+ if (this.buffer.length <= bufIndex) {
31874
+ this.buffer.push(0);
31875
+ }
31876
+
31877
+ if (bit) {
31878
+ this.buffer[bufIndex] |= (0x80 >>> (this.length % 8));
31879
+ }
31880
+
31881
+ this.length++;
31882
+ }
31883
+ };
31884
+
31885
+ bitBuffer = BitBuffer;
31886
+ return bitBuffer;
31887
+ }
31888
+
31889
+ /**
31890
+ * Helper class to handle QR Code symbol modules
31891
+ *
31892
+ * @param {Number} size Symbol size
31893
+ */
31894
+
31895
+ var bitMatrix;
31896
+ var hasRequiredBitMatrix;
31897
+
31898
+ function requireBitMatrix () {
31899
+ if (hasRequiredBitMatrix) return bitMatrix;
31900
+ hasRequiredBitMatrix = 1;
31901
+ function BitMatrix (size) {
31902
+ if (!size || size < 1) {
31903
+ throw new Error('BitMatrix size must be defined and greater than 0')
31904
+ }
31905
+
31906
+ this.size = size;
31907
+ this.data = new Uint8Array(size * size);
31908
+ this.reservedBit = new Uint8Array(size * size);
31909
+ }
31910
+
31911
+ /**
31912
+ * Set bit value at specified location
31913
+ * If reserved flag is set, this bit will be ignored during masking process
31914
+ *
31915
+ * @param {Number} row
31916
+ * @param {Number} col
31917
+ * @param {Boolean} value
31918
+ * @param {Boolean} reserved
31919
+ */
31920
+ BitMatrix.prototype.set = function (row, col, value, reserved) {
31921
+ const index = row * this.size + col;
31922
+ this.data[index] = value;
31923
+ if (reserved) this.reservedBit[index] = true;
31924
+ };
31925
+
31926
+ /**
31927
+ * Returns bit value at specified location
31928
+ *
31929
+ * @param {Number} row
31930
+ * @param {Number} col
31931
+ * @return {Boolean}
31932
+ */
31933
+ BitMatrix.prototype.get = function (row, col) {
31934
+ return this.data[row * this.size + col]
31935
+ };
31936
+
31937
+ /**
31938
+ * Applies xor operator at specified location
31939
+ * (used during masking process)
31940
+ *
31941
+ * @param {Number} row
31942
+ * @param {Number} col
31943
+ * @param {Boolean} value
31944
+ */
31945
+ BitMatrix.prototype.xor = function (row, col, value) {
31946
+ this.data[row * this.size + col] ^= value;
31947
+ };
31948
+
31949
+ /**
31950
+ * Check if bit at specified location is reserved
31951
+ *
31952
+ * @param {Number} row
31953
+ * @param {Number} col
31954
+ * @return {Boolean}
31955
+ */
31956
+ BitMatrix.prototype.isReserved = function (row, col) {
31957
+ return this.reservedBit[row * this.size + col]
31958
+ };
31959
+
31960
+ bitMatrix = BitMatrix;
31961
+ return bitMatrix;
31962
+ }
31963
+
31964
+ var alignmentPattern = {};
31965
+
31966
+ /**
31967
+ * Alignment pattern are fixed reference pattern in defined positions
31968
+ * in a matrix symbology, which enables the decode software to re-synchronise
31969
+ * the coordinate mapping of the image modules in the event of moderate amounts
31970
+ * of distortion of the image.
31971
+ *
31972
+ * Alignment patterns are present only in QR Code symbols of version 2 or larger
31973
+ * and their number depends on the symbol version.
31974
+ */
31975
+
31976
+ var hasRequiredAlignmentPattern;
31977
+
31978
+ function requireAlignmentPattern () {
31979
+ if (hasRequiredAlignmentPattern) return alignmentPattern;
31980
+ hasRequiredAlignmentPattern = 1;
31981
+ (function (exports) {
31982
+ const getSymbolSize = requireUtils$1().getSymbolSize;
31983
+
31984
+ /**
31985
+ * Calculate the row/column coordinates of the center module of each alignment pattern
31986
+ * for the specified QR Code version.
31987
+ *
31988
+ * The alignment patterns are positioned symmetrically on either side of the diagonal
31989
+ * running from the top left corner of the symbol to the bottom right corner.
31990
+ *
31991
+ * Since positions are simmetrical only half of the coordinates are returned.
31992
+ * Each item of the array will represent in turn the x and y coordinate.
31993
+ * @see {@link getPositions}
31994
+ *
31995
+ * @param {Number} version QR Code version
31996
+ * @return {Array} Array of coordinate
31997
+ */
31998
+ exports.getRowColCoords = function getRowColCoords (version) {
31999
+ if (version === 1) return []
32000
+
32001
+ const posCount = Math.floor(version / 7) + 2;
32002
+ const size = getSymbolSize(version);
32003
+ const intervals = size === 145 ? 26 : Math.ceil((size - 13) / (2 * posCount - 2)) * 2;
32004
+ const positions = [size - 7]; // Last coord is always (size - 7)
32005
+
32006
+ for (let i = 1; i < posCount - 1; i++) {
32007
+ positions[i] = positions[i - 1] - intervals;
32008
+ }
32009
+
32010
+ positions.push(6); // First coord is always 6
32011
+
32012
+ return positions.reverse()
32013
+ };
32014
+
32015
+ /**
32016
+ * Returns an array containing the positions of each alignment pattern.
32017
+ * Each array's element represent the center point of the pattern as (x, y) coordinates
32018
+ *
32019
+ * Coordinates are calculated expanding the row/column coordinates returned by {@link getRowColCoords}
32020
+ * and filtering out the items that overlaps with finder pattern
32021
+ *
32022
+ * @example
32023
+ * For a Version 7 symbol {@link getRowColCoords} returns values 6, 22 and 38.
32024
+ * The alignment patterns, therefore, are to be centered on (row, column)
32025
+ * positions (6,22), (22,6), (22,22), (22,38), (38,22), (38,38).
32026
+ * Note that the coordinates (6,6), (6,38), (38,6) are occupied by finder patterns
32027
+ * and are not therefore used for alignment patterns.
32028
+ *
32029
+ * let pos = getPositions(7)
32030
+ * // [[6,22], [22,6], [22,22], [22,38], [38,22], [38,38]]
32031
+ *
32032
+ * @param {Number} version QR Code version
32033
+ * @return {Array} Array of coordinates
32034
+ */
32035
+ exports.getPositions = function getPositions (version) {
32036
+ const coords = [];
32037
+ const pos = exports.getRowColCoords(version);
32038
+ const posLength = pos.length;
32039
+
32040
+ for (let i = 0; i < posLength; i++) {
32041
+ for (let j = 0; j < posLength; j++) {
32042
+ // Skip if position is occupied by finder patterns
32043
+ if ((i === 0 && j === 0) || // top-left
32044
+ (i === 0 && j === posLength - 1) || // bottom-left
32045
+ (i === posLength - 1 && j === 0)) { // top-right
32046
+ continue
32047
+ }
32048
+
32049
+ coords.push([pos[i], pos[j]]);
32050
+ }
32051
+ }
32052
+
32053
+ return coords
32054
+ };
32055
+ } (alignmentPattern));
32056
+ return alignmentPattern;
32057
+ }
32058
+
32059
+ var finderPattern = {};
32060
+
32061
+ var hasRequiredFinderPattern;
32062
+
32063
+ function requireFinderPattern () {
32064
+ if (hasRequiredFinderPattern) return finderPattern;
32065
+ hasRequiredFinderPattern = 1;
32066
+ const getSymbolSize = requireUtils$1().getSymbolSize;
32067
+ const FINDER_PATTERN_SIZE = 7;
32068
+
32069
+ /**
32070
+ * Returns an array containing the positions of each finder pattern.
32071
+ * Each array's element represent the top-left point of the pattern as (x, y) coordinates
32072
+ *
32073
+ * @param {Number} version QR Code version
32074
+ * @return {Array} Array of coordinates
32075
+ */
32076
+ finderPattern.getPositions = function getPositions (version) {
32077
+ const size = getSymbolSize(version);
32078
+
32079
+ return [
32080
+ // top-left
32081
+ [0, 0],
32082
+ // top-right
32083
+ [size - FINDER_PATTERN_SIZE, 0],
32084
+ // bottom-left
32085
+ [0, size - FINDER_PATTERN_SIZE]
32086
+ ]
32087
+ };
32088
+ return finderPattern;
32089
+ }
32090
+
32091
+ var maskPattern = {};
32092
+
32093
+ /**
32094
+ * Data mask pattern reference
32095
+ * @type {Object}
32096
+ */
32097
+
32098
+ var hasRequiredMaskPattern;
32099
+
32100
+ function requireMaskPattern () {
32101
+ if (hasRequiredMaskPattern) return maskPattern;
32102
+ hasRequiredMaskPattern = 1;
32103
+ (function (exports) {
32104
+ exports.Patterns = {
32105
+ PATTERN000: 0,
32106
+ PATTERN001: 1,
32107
+ PATTERN010: 2,
32108
+ PATTERN011: 3,
32109
+ PATTERN100: 4,
32110
+ PATTERN101: 5,
32111
+ PATTERN110: 6,
32112
+ PATTERN111: 7
32113
+ };
32114
+
32115
+ /**
32116
+ * Weighted penalty scores for the undesirable features
32117
+ * @type {Object}
32118
+ */
32119
+ const PenaltyScores = {
32120
+ N1: 3,
32121
+ N2: 3,
32122
+ N3: 40,
32123
+ N4: 10
32124
+ };
32125
+
32126
+ /**
32127
+ * Check if mask pattern value is valid
32128
+ *
32129
+ * @param {Number} mask Mask pattern
32130
+ * @return {Boolean} true if valid, false otherwise
32131
+ */
32132
+ exports.isValid = function isValid (mask) {
32133
+ return mask != null && mask !== '' && !isNaN(mask) && mask >= 0 && mask <= 7
32134
+ };
32135
+
32136
+ /**
32137
+ * Returns mask pattern from a value.
32138
+ * If value is not valid, returns undefined
32139
+ *
32140
+ * @param {Number|String} value Mask pattern value
32141
+ * @return {Number} Valid mask pattern or undefined
32142
+ */
32143
+ exports.from = function from (value) {
32144
+ return exports.isValid(value) ? parseInt(value, 10) : undefined
32145
+ };
32146
+
32147
+ /**
32148
+ * Find adjacent modules in row/column with the same color
32149
+ * and assign a penalty value.
32150
+ *
32151
+ * Points: N1 + i
32152
+ * i is the amount by which the number of adjacent modules of the same color exceeds 5
32153
+ */
32154
+ exports.getPenaltyN1 = function getPenaltyN1 (data) {
32155
+ const size = data.size;
32156
+ let points = 0;
32157
+ let sameCountCol = 0;
32158
+ let sameCountRow = 0;
32159
+ let lastCol = null;
32160
+ let lastRow = null;
32161
+
32162
+ for (let row = 0; row < size; row++) {
32163
+ sameCountCol = sameCountRow = 0;
32164
+ lastCol = lastRow = null;
32165
+
32166
+ for (let col = 0; col < size; col++) {
32167
+ let module = data.get(row, col);
32168
+ if (module === lastCol) {
32169
+ sameCountCol++;
32170
+ } else {
32171
+ if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5);
32172
+ lastCol = module;
32173
+ sameCountCol = 1;
32174
+ }
32175
+
32176
+ module = data.get(col, row);
32177
+ if (module === lastRow) {
32178
+ sameCountRow++;
32179
+ } else {
32180
+ if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5);
32181
+ lastRow = module;
32182
+ sameCountRow = 1;
32183
+ }
32184
+ }
32185
+
32186
+ if (sameCountCol >= 5) points += PenaltyScores.N1 + (sameCountCol - 5);
32187
+ if (sameCountRow >= 5) points += PenaltyScores.N1 + (sameCountRow - 5);
32188
+ }
32189
+
32190
+ return points
32191
+ };
32192
+
32193
+ /**
32194
+ * Find 2x2 blocks with the same color and assign a penalty value
32195
+ *
32196
+ * Points: N2 * (m - 1) * (n - 1)
32197
+ */
32198
+ exports.getPenaltyN2 = function getPenaltyN2 (data) {
32199
+ const size = data.size;
32200
+ let points = 0;
32201
+
32202
+ for (let row = 0; row < size - 1; row++) {
32203
+ for (let col = 0; col < size - 1; col++) {
32204
+ const last = data.get(row, col) +
32205
+ data.get(row, col + 1) +
32206
+ data.get(row + 1, col) +
32207
+ data.get(row + 1, col + 1);
32208
+
32209
+ if (last === 4 || last === 0) points++;
32210
+ }
32211
+ }
32212
+
32213
+ return points * PenaltyScores.N2
32214
+ };
32215
+
32216
+ /**
32217
+ * Find 1:1:3:1:1 ratio (dark:light:dark:light:dark) pattern in row/column,
32218
+ * preceded or followed by light area 4 modules wide
32219
+ *
32220
+ * Points: N3 * number of pattern found
32221
+ */
32222
+ exports.getPenaltyN3 = function getPenaltyN3 (data) {
32223
+ const size = data.size;
32224
+ let points = 0;
32225
+ let bitsCol = 0;
32226
+ let bitsRow = 0;
32227
+
32228
+ for (let row = 0; row < size; row++) {
32229
+ bitsCol = bitsRow = 0;
32230
+ for (let col = 0; col < size; col++) {
32231
+ bitsCol = ((bitsCol << 1) & 0x7FF) | data.get(row, col);
32232
+ if (col >= 10 && (bitsCol === 0x5D0 || bitsCol === 0x05D)) points++;
32233
+
32234
+ bitsRow = ((bitsRow << 1) & 0x7FF) | data.get(col, row);
32235
+ if (col >= 10 && (bitsRow === 0x5D0 || bitsRow === 0x05D)) points++;
32236
+ }
32237
+ }
32238
+
32239
+ return points * PenaltyScores.N3
32240
+ };
32241
+
32242
+ /**
32243
+ * Calculate proportion of dark modules in entire symbol
32244
+ *
32245
+ * Points: N4 * k
32246
+ *
32247
+ * k is the rating of the deviation of the proportion of dark modules
32248
+ * in the symbol from 50% in steps of 5%
32249
+ */
32250
+ exports.getPenaltyN4 = function getPenaltyN4 (data) {
32251
+ let darkCount = 0;
32252
+ const modulesCount = data.data.length;
32253
+
32254
+ for (let i = 0; i < modulesCount; i++) darkCount += data.data[i];
32255
+
32256
+ const k = Math.abs(Math.ceil((darkCount * 100 / modulesCount) / 5) - 10);
32257
+
32258
+ return k * PenaltyScores.N4
32259
+ };
32260
+
32261
+ /**
32262
+ * Return mask value at given position
32263
+ *
32264
+ * @param {Number} maskPattern Pattern reference value
32265
+ * @param {Number} i Row
32266
+ * @param {Number} j Column
32267
+ * @return {Boolean} Mask value
32268
+ */
32269
+ function getMaskAt (maskPattern, i, j) {
32270
+ switch (maskPattern) {
32271
+ case exports.Patterns.PATTERN000: return (i + j) % 2 === 0
32272
+ case exports.Patterns.PATTERN001: return i % 2 === 0
32273
+ case exports.Patterns.PATTERN010: return j % 3 === 0
32274
+ case exports.Patterns.PATTERN011: return (i + j) % 3 === 0
32275
+ case exports.Patterns.PATTERN100: return (Math.floor(i / 2) + Math.floor(j / 3)) % 2 === 0
32276
+ case exports.Patterns.PATTERN101: return (i * j) % 2 + (i * j) % 3 === 0
32277
+ case exports.Patterns.PATTERN110: return ((i * j) % 2 + (i * j) % 3) % 2 === 0
32278
+ case exports.Patterns.PATTERN111: return ((i * j) % 3 + (i + j) % 2) % 2 === 0
32279
+
32280
+ default: throw new Error('bad maskPattern:' + maskPattern)
32281
+ }
32282
+ }
32283
+
32284
+ /**
32285
+ * Apply a mask pattern to a BitMatrix
32286
+ *
32287
+ * @param {Number} pattern Pattern reference number
32288
+ * @param {BitMatrix} data BitMatrix data
32289
+ */
32290
+ exports.applyMask = function applyMask (pattern, data) {
32291
+ const size = data.size;
32292
+
32293
+ for (let col = 0; col < size; col++) {
32294
+ for (let row = 0; row < size; row++) {
32295
+ if (data.isReserved(row, col)) continue
32296
+ data.xor(row, col, getMaskAt(pattern, row, col));
32297
+ }
32298
+ }
32299
+ };
32300
+
32301
+ /**
32302
+ * Returns the best mask pattern for data
32303
+ *
32304
+ * @param {BitMatrix} data
32305
+ * @return {Number} Mask pattern reference number
32306
+ */
32307
+ exports.getBestMask = function getBestMask (data, setupFormatFunc) {
32308
+ const numPatterns = Object.keys(exports.Patterns).length;
32309
+ let bestPattern = 0;
32310
+ let lowerPenalty = Infinity;
32311
+
32312
+ for (let p = 0; p < numPatterns; p++) {
32313
+ setupFormatFunc(p);
32314
+ exports.applyMask(p, data);
32315
+
32316
+ // Calculate penalty
32317
+ const penalty =
32318
+ exports.getPenaltyN1(data) +
32319
+ exports.getPenaltyN2(data) +
32320
+ exports.getPenaltyN3(data) +
32321
+ exports.getPenaltyN4(data);
32322
+
32323
+ // Undo previously applied mask
32324
+ exports.applyMask(p, data);
32325
+
32326
+ if (penalty < lowerPenalty) {
32327
+ lowerPenalty = penalty;
32328
+ bestPattern = p;
32329
+ }
32330
+ }
32331
+
32332
+ return bestPattern
32333
+ };
32334
+ } (maskPattern));
32335
+ return maskPattern;
32336
+ }
32337
+
32338
+ var errorCorrectionCode = {};
32339
+
32340
+ var hasRequiredErrorCorrectionCode;
32341
+
32342
+ function requireErrorCorrectionCode () {
32343
+ if (hasRequiredErrorCorrectionCode) return errorCorrectionCode;
32344
+ hasRequiredErrorCorrectionCode = 1;
32345
+ const ECLevel = requireErrorCorrectionLevel();
32346
+
32347
+ const EC_BLOCKS_TABLE = [
32348
+ // L M Q H
32349
+ 1, 1, 1, 1,
32350
+ 1, 1, 1, 1,
32351
+ 1, 1, 2, 2,
32352
+ 1, 2, 2, 4,
32353
+ 1, 2, 4, 4,
32354
+ 2, 4, 4, 4,
32355
+ 2, 4, 6, 5,
32356
+ 2, 4, 6, 6,
32357
+ 2, 5, 8, 8,
32358
+ 4, 5, 8, 8,
32359
+ 4, 5, 8, 11,
32360
+ 4, 8, 10, 11,
32361
+ 4, 9, 12, 16,
32362
+ 4, 9, 16, 16,
32363
+ 6, 10, 12, 18,
32364
+ 6, 10, 17, 16,
32365
+ 6, 11, 16, 19,
32366
+ 6, 13, 18, 21,
32367
+ 7, 14, 21, 25,
32368
+ 8, 16, 20, 25,
32369
+ 8, 17, 23, 25,
32370
+ 9, 17, 23, 34,
32371
+ 9, 18, 25, 30,
32372
+ 10, 20, 27, 32,
32373
+ 12, 21, 29, 35,
32374
+ 12, 23, 34, 37,
32375
+ 12, 25, 34, 40,
32376
+ 13, 26, 35, 42,
32377
+ 14, 28, 38, 45,
32378
+ 15, 29, 40, 48,
32379
+ 16, 31, 43, 51,
32380
+ 17, 33, 45, 54,
32381
+ 18, 35, 48, 57,
32382
+ 19, 37, 51, 60,
32383
+ 19, 38, 53, 63,
32384
+ 20, 40, 56, 66,
32385
+ 21, 43, 59, 70,
32386
+ 22, 45, 62, 74,
32387
+ 24, 47, 65, 77,
32388
+ 25, 49, 68, 81
32389
+ ];
32390
+
32391
+ const EC_CODEWORDS_TABLE = [
32392
+ // L M Q H
32393
+ 7, 10, 13, 17,
32394
+ 10, 16, 22, 28,
32395
+ 15, 26, 36, 44,
32396
+ 20, 36, 52, 64,
32397
+ 26, 48, 72, 88,
32398
+ 36, 64, 96, 112,
32399
+ 40, 72, 108, 130,
32400
+ 48, 88, 132, 156,
32401
+ 60, 110, 160, 192,
32402
+ 72, 130, 192, 224,
32403
+ 80, 150, 224, 264,
32404
+ 96, 176, 260, 308,
32405
+ 104, 198, 288, 352,
32406
+ 120, 216, 320, 384,
32407
+ 132, 240, 360, 432,
32408
+ 144, 280, 408, 480,
32409
+ 168, 308, 448, 532,
32410
+ 180, 338, 504, 588,
32411
+ 196, 364, 546, 650,
32412
+ 224, 416, 600, 700,
32413
+ 224, 442, 644, 750,
32414
+ 252, 476, 690, 816,
32415
+ 270, 504, 750, 900,
32416
+ 300, 560, 810, 960,
32417
+ 312, 588, 870, 1050,
32418
+ 336, 644, 952, 1110,
32419
+ 360, 700, 1020, 1200,
32420
+ 390, 728, 1050, 1260,
32421
+ 420, 784, 1140, 1350,
32422
+ 450, 812, 1200, 1440,
32423
+ 480, 868, 1290, 1530,
32424
+ 510, 924, 1350, 1620,
32425
+ 540, 980, 1440, 1710,
32426
+ 570, 1036, 1530, 1800,
32427
+ 570, 1064, 1590, 1890,
32428
+ 600, 1120, 1680, 1980,
32429
+ 630, 1204, 1770, 2100,
32430
+ 660, 1260, 1860, 2220,
32431
+ 720, 1316, 1950, 2310,
32432
+ 750, 1372, 2040, 2430
32433
+ ];
32434
+
32435
+ /**
32436
+ * Returns the number of error correction block that the QR Code should contain
32437
+ * for the specified version and error correction level.
32438
+ *
32439
+ * @param {Number} version QR Code version
32440
+ * @param {Number} errorCorrectionLevel Error correction level
32441
+ * @return {Number} Number of error correction blocks
32442
+ */
32443
+ errorCorrectionCode.getBlocksCount = function getBlocksCount (version, errorCorrectionLevel) {
32444
+ switch (errorCorrectionLevel) {
32445
+ case ECLevel.L:
32446
+ return EC_BLOCKS_TABLE[(version - 1) * 4 + 0]
32447
+ case ECLevel.M:
32448
+ return EC_BLOCKS_TABLE[(version - 1) * 4 + 1]
32449
+ case ECLevel.Q:
32450
+ return EC_BLOCKS_TABLE[(version - 1) * 4 + 2]
32451
+ case ECLevel.H:
32452
+ return EC_BLOCKS_TABLE[(version - 1) * 4 + 3]
32453
+ default:
32454
+ return undefined
32455
+ }
32456
+ };
32457
+
32458
+ /**
32459
+ * Returns the number of error correction codewords to use for the specified
32460
+ * version and error correction level.
32461
+ *
32462
+ * @param {Number} version QR Code version
32463
+ * @param {Number} errorCorrectionLevel Error correction level
32464
+ * @return {Number} Number of error correction codewords
32465
+ */
32466
+ errorCorrectionCode.getTotalCodewordsCount = function getTotalCodewordsCount (version, errorCorrectionLevel) {
32467
+ switch (errorCorrectionLevel) {
32468
+ case ECLevel.L:
32469
+ return EC_CODEWORDS_TABLE[(version - 1) * 4 + 0]
32470
+ case ECLevel.M:
32471
+ return EC_CODEWORDS_TABLE[(version - 1) * 4 + 1]
32472
+ case ECLevel.Q:
32473
+ return EC_CODEWORDS_TABLE[(version - 1) * 4 + 2]
32474
+ case ECLevel.H:
32475
+ return EC_CODEWORDS_TABLE[(version - 1) * 4 + 3]
32476
+ default:
32477
+ return undefined
32478
+ }
32479
+ };
32480
+ return errorCorrectionCode;
32481
+ }
32482
+
32483
+ var polynomial = {};
32484
+
32485
+ var galoisField = {};
32486
+
32487
+ var hasRequiredGaloisField;
32488
+
32489
+ function requireGaloisField () {
32490
+ if (hasRequiredGaloisField) return galoisField;
32491
+ hasRequiredGaloisField = 1;
32492
+ const EXP_TABLE = new Uint8Array(512);
32493
+ const LOG_TABLE = new Uint8Array(256)
32494
+ /**
32495
+ * Precompute the log and anti-log tables for faster computation later
32496
+ *
32497
+ * For each possible value in the galois field 2^8, we will pre-compute
32498
+ * the logarithm and anti-logarithm (exponential) of this value
32499
+ *
32500
+ * ref {@link https://en.wikiversity.org/wiki/Reed%E2%80%93Solomon_codes_for_coders#Introduction_to_mathematical_fields}
32501
+ */
32502
+ ;(function initTables () {
32503
+ let x = 1;
32504
+ for (let i = 0; i < 255; i++) {
32505
+ EXP_TABLE[i] = x;
32506
+ LOG_TABLE[x] = i;
32507
+
32508
+ x <<= 1; // multiply by 2
32509
+
32510
+ // The QR code specification says to use byte-wise modulo 100011101 arithmetic.
32511
+ // This means that when a number is 256 or larger, it should be XORed with 0x11D.
32512
+ if (x & 0x100) { // similar to x >= 256, but a lot faster (because 0x100 == 256)
32513
+ x ^= 0x11D;
32514
+ }
32515
+ }
32516
+
32517
+ // Optimization: double the size of the anti-log table so that we don't need to mod 255 to
32518
+ // stay inside the bounds (because we will mainly use this table for the multiplication of
32519
+ // two GF numbers, no more).
32520
+ // @see {@link mul}
32521
+ for (let i = 255; i < 512; i++) {
32522
+ EXP_TABLE[i] = EXP_TABLE[i - 255];
32523
+ }
32524
+ }());
32525
+
32526
+ /**
32527
+ * Returns log value of n inside Galois Field
32528
+ *
32529
+ * @param {Number} n
32530
+ * @return {Number}
32531
+ */
32532
+ galoisField.log = function log (n) {
32533
+ if (n < 1) throw new Error('log(' + n + ')')
32534
+ return LOG_TABLE[n]
32535
+ };
32536
+
32537
+ /**
32538
+ * Returns anti-log value of n inside Galois Field
32539
+ *
32540
+ * @param {Number} n
32541
+ * @return {Number}
32542
+ */
32543
+ galoisField.exp = function exp (n) {
32544
+ return EXP_TABLE[n]
32545
+ };
32546
+
32547
+ /**
32548
+ * Multiplies two number inside Galois Field
32549
+ *
32550
+ * @param {Number} x
32551
+ * @param {Number} y
32552
+ * @return {Number}
32553
+ */
32554
+ galoisField.mul = function mul (x, y) {
32555
+ if (x === 0 || y === 0) return 0
32556
+
32557
+ // should be EXP_TABLE[(LOG_TABLE[x] + LOG_TABLE[y]) % 255] if EXP_TABLE wasn't oversized
32558
+ // @see {@link initTables}
32559
+ return EXP_TABLE[LOG_TABLE[x] + LOG_TABLE[y]]
32560
+ };
32561
+ return galoisField;
32562
+ }
32563
+
32564
+ var hasRequiredPolynomial;
32565
+
32566
+ function requirePolynomial () {
32567
+ if (hasRequiredPolynomial) return polynomial;
32568
+ hasRequiredPolynomial = 1;
32569
+ (function (exports) {
32570
+ const GF = requireGaloisField();
32571
+
32572
+ /**
32573
+ * Multiplies two polynomials inside Galois Field
32574
+ *
32575
+ * @param {Uint8Array} p1 Polynomial
32576
+ * @param {Uint8Array} p2 Polynomial
32577
+ * @return {Uint8Array} Product of p1 and p2
32578
+ */
32579
+ exports.mul = function mul (p1, p2) {
32580
+ const coeff = new Uint8Array(p1.length + p2.length - 1);
32581
+
32582
+ for (let i = 0; i < p1.length; i++) {
32583
+ for (let j = 0; j < p2.length; j++) {
32584
+ coeff[i + j] ^= GF.mul(p1[i], p2[j]);
32585
+ }
32586
+ }
32587
+
32588
+ return coeff
32589
+ };
32590
+
32591
+ /**
32592
+ * Calculate the remainder of polynomials division
32593
+ *
32594
+ * @param {Uint8Array} divident Polynomial
32595
+ * @param {Uint8Array} divisor Polynomial
32596
+ * @return {Uint8Array} Remainder
32597
+ */
32598
+ exports.mod = function mod (divident, divisor) {
32599
+ let result = new Uint8Array(divident);
32600
+
32601
+ while ((result.length - divisor.length) >= 0) {
32602
+ const coeff = result[0];
32603
+
32604
+ for (let i = 0; i < divisor.length; i++) {
32605
+ result[i] ^= GF.mul(divisor[i], coeff);
32606
+ }
32607
+
32608
+ // remove all zeros from buffer head
32609
+ let offset = 0;
32610
+ while (offset < result.length && result[offset] === 0) offset++;
32611
+ result = result.slice(offset);
32612
+ }
32613
+
32614
+ return result
32615
+ };
32616
+
32617
+ /**
32618
+ * Generate an irreducible generator polynomial of specified degree
32619
+ * (used by Reed-Solomon encoder)
32620
+ *
32621
+ * @param {Number} degree Degree of the generator polynomial
32622
+ * @return {Uint8Array} Buffer containing polynomial coefficients
32623
+ */
32624
+ exports.generateECPolynomial = function generateECPolynomial (degree) {
32625
+ let poly = new Uint8Array([1]);
32626
+ for (let i = 0; i < degree; i++) {
32627
+ poly = exports.mul(poly, new Uint8Array([1, GF.exp(i)]));
32628
+ }
32629
+
32630
+ return poly
32631
+ };
32632
+ } (polynomial));
32633
+ return polynomial;
32634
+ }
32635
+
32636
+ var reedSolomonEncoder;
32637
+ var hasRequiredReedSolomonEncoder;
32638
+
32639
+ function requireReedSolomonEncoder () {
32640
+ if (hasRequiredReedSolomonEncoder) return reedSolomonEncoder;
32641
+ hasRequiredReedSolomonEncoder = 1;
32642
+ const Polynomial = requirePolynomial();
32643
+
32644
+ function ReedSolomonEncoder (degree) {
32645
+ this.genPoly = undefined;
32646
+ this.degree = degree;
32647
+
32648
+ if (this.degree) this.initialize(this.degree);
32649
+ }
32650
+
32651
+ /**
32652
+ * Initialize the encoder.
32653
+ * The input param should correspond to the number of error correction codewords.
32654
+ *
32655
+ * @param {Number} degree
32656
+ */
32657
+ ReedSolomonEncoder.prototype.initialize = function initialize (degree) {
32658
+ // create an irreducible generator polynomial
32659
+ this.degree = degree;
32660
+ this.genPoly = Polynomial.generateECPolynomial(this.degree);
32661
+ };
32662
+
32663
+ /**
32664
+ * Encodes a chunk of data
32665
+ *
32666
+ * @param {Uint8Array} data Buffer containing input data
32667
+ * @return {Uint8Array} Buffer containing encoded data
32668
+ */
32669
+ ReedSolomonEncoder.prototype.encode = function encode (data) {
32670
+ if (!this.genPoly) {
32671
+ throw new Error('Encoder not initialized')
32672
+ }
32673
+
32674
+ // Calculate EC for this data block
32675
+ // extends data size to data+genPoly size
32676
+ const paddedData = new Uint8Array(data.length + this.degree);
32677
+ paddedData.set(data);
32678
+
32679
+ // The error correction codewords are the remainder after dividing the data codewords
32680
+ // by a generator polynomial
32681
+ const remainder = Polynomial.mod(paddedData, this.genPoly);
32682
+
32683
+ // return EC data blocks (last n byte, where n is the degree of genPoly)
32684
+ // If coefficients number in remainder are less than genPoly degree,
32685
+ // pad with 0s to the left to reach the needed number of coefficients
32686
+ const start = this.degree - remainder.length;
32687
+ if (start > 0) {
32688
+ const buff = new Uint8Array(this.degree);
32689
+ buff.set(remainder, start);
32690
+
32691
+ return buff
32692
+ }
32693
+
32694
+ return remainder
32695
+ };
32696
+
32697
+ reedSolomonEncoder = ReedSolomonEncoder;
32698
+ return reedSolomonEncoder;
32699
+ }
32700
+
32701
+ var version = {};
32702
+
32703
+ var mode = {};
32704
+
32705
+ var versionCheck = {};
32706
+
32707
+ /**
32708
+ * Check if QR Code version is valid
32709
+ *
32710
+ * @param {Number} version QR Code version
32711
+ * @return {Boolean} true if valid version, false otherwise
32712
+ */
32713
+
32714
+ var hasRequiredVersionCheck;
32715
+
32716
+ function requireVersionCheck () {
32717
+ if (hasRequiredVersionCheck) return versionCheck;
32718
+ hasRequiredVersionCheck = 1;
32719
+ versionCheck.isValid = function isValid (version) {
32720
+ return !isNaN(version) && version >= 1 && version <= 40
32721
+ };
32722
+ return versionCheck;
32723
+ }
32724
+
32725
+ var regex = {};
32726
+
32727
+ var hasRequiredRegex;
32728
+
32729
+ function requireRegex () {
32730
+ if (hasRequiredRegex) return regex;
32731
+ hasRequiredRegex = 1;
32732
+ const numeric = '[0-9]+';
32733
+ const alphanumeric = '[A-Z $%*+\\-./:]+';
32734
+ let kanji = '(?:[u3000-u303F]|[u3040-u309F]|[u30A0-u30FF]|' +
32735
+ '[uFF00-uFFEF]|[u4E00-u9FAF]|[u2605-u2606]|[u2190-u2195]|u203B|' +
32736
+ '[u2010u2015u2018u2019u2025u2026u201Cu201Du2225u2260]|' +
32737
+ '[u0391-u0451]|[u00A7u00A8u00B1u00B4u00D7u00F7])+';
32738
+ kanji = kanji.replace(/u/g, '\\u');
32739
+
32740
+ const byte = '(?:(?![A-Z0-9 $%*+\\-./:]|' + kanji + ')(?:.|[\r\n]))+';
32741
+
32742
+ regex.KANJI = new RegExp(kanji, 'g');
32743
+ regex.BYTE_KANJI = new RegExp('[^A-Z0-9 $%*+\\-./:]+', 'g');
32744
+ regex.BYTE = new RegExp(byte, 'g');
32745
+ regex.NUMERIC = new RegExp(numeric, 'g');
32746
+ regex.ALPHANUMERIC = new RegExp(alphanumeric, 'g');
32747
+
32748
+ const TEST_KANJI = new RegExp('^' + kanji + '$');
32749
+ const TEST_NUMERIC = new RegExp('^' + numeric + '$');
32750
+ const TEST_ALPHANUMERIC = new RegExp('^[A-Z0-9 $%*+\\-./:]+$');
32751
+
32752
+ regex.testKanji = function testKanji (str) {
32753
+ return TEST_KANJI.test(str)
32754
+ };
32755
+
32756
+ regex.testNumeric = function testNumeric (str) {
32757
+ return TEST_NUMERIC.test(str)
32758
+ };
32759
+
32760
+ regex.testAlphanumeric = function testAlphanumeric (str) {
32761
+ return TEST_ALPHANUMERIC.test(str)
32762
+ };
32763
+ return regex;
32764
+ }
32765
+
32766
+ var hasRequiredMode;
32767
+
32768
+ function requireMode () {
32769
+ if (hasRequiredMode) return mode;
32770
+ hasRequiredMode = 1;
32771
+ (function (exports) {
32772
+ const VersionCheck = requireVersionCheck();
32773
+ const Regex = requireRegex();
32774
+
32775
+ /**
32776
+ * Numeric mode encodes data from the decimal digit set (0 - 9)
32777
+ * (byte values 30HEX to 39HEX).
32778
+ * Normally, 3 data characters are represented by 10 bits.
32779
+ *
32780
+ * @type {Object}
32781
+ */
32782
+ exports.NUMERIC = {
32783
+ id: 'Numeric',
32784
+ bit: 1 << 0,
32785
+ ccBits: [10, 12, 14]
32786
+ };
32787
+
32788
+ /**
32789
+ * Alphanumeric mode encodes data from a set of 45 characters,
32790
+ * i.e. 10 numeric digits (0 - 9),
32791
+ * 26 alphabetic characters (A - Z),
32792
+ * and 9 symbols (SP, $, %, *, +, -, ., /, :).
32793
+ * Normally, two input characters are represented by 11 bits.
32794
+ *
32795
+ * @type {Object}
32796
+ */
32797
+ exports.ALPHANUMERIC = {
32798
+ id: 'Alphanumeric',
32799
+ bit: 1 << 1,
32800
+ ccBits: [9, 11, 13]
32801
+ };
32802
+
32803
+ /**
32804
+ * In byte mode, data is encoded at 8 bits per character.
32805
+ *
32806
+ * @type {Object}
32807
+ */
32808
+ exports.BYTE = {
32809
+ id: 'Byte',
32810
+ bit: 1 << 2,
32811
+ ccBits: [8, 16, 16]
32812
+ };
32813
+
32814
+ /**
32815
+ * The Kanji mode efficiently encodes Kanji characters in accordance with
32816
+ * the Shift JIS system based on JIS X 0208.
32817
+ * The Shift JIS values are shifted from the JIS X 0208 values.
32818
+ * JIS X 0208 gives details of the shift coded representation.
32819
+ * Each two-byte character value is compacted to a 13-bit binary codeword.
32820
+ *
32821
+ * @type {Object}
32822
+ */
32823
+ exports.KANJI = {
32824
+ id: 'Kanji',
32825
+ bit: 1 << 3,
32826
+ ccBits: [8, 10, 12]
32827
+ };
32828
+
32829
+ /**
32830
+ * Mixed mode will contain a sequences of data in a combination of any of
32831
+ * the modes described above
32832
+ *
32833
+ * @type {Object}
32834
+ */
32835
+ exports.MIXED = {
32836
+ bit: -1
32837
+ };
32838
+
32839
+ /**
32840
+ * Returns the number of bits needed to store the data length
32841
+ * according to QR Code specifications.
32842
+ *
32843
+ * @param {Mode} mode Data mode
32844
+ * @param {Number} version QR Code version
32845
+ * @return {Number} Number of bits
32846
+ */
32847
+ exports.getCharCountIndicator = function getCharCountIndicator (mode, version) {
32848
+ if (!mode.ccBits) throw new Error('Invalid mode: ' + mode)
32849
+
32850
+ if (!VersionCheck.isValid(version)) {
32851
+ throw new Error('Invalid version: ' + version)
32852
+ }
32853
+
32854
+ if (version >= 1 && version < 10) return mode.ccBits[0]
32855
+ else if (version < 27) return mode.ccBits[1]
32856
+ return mode.ccBits[2]
32857
+ };
32858
+
32859
+ /**
32860
+ * Returns the most efficient mode to store the specified data
32861
+ *
32862
+ * @param {String} dataStr Input data string
32863
+ * @return {Mode} Best mode
32864
+ */
32865
+ exports.getBestModeForData = function getBestModeForData (dataStr) {
32866
+ if (Regex.testNumeric(dataStr)) return exports.NUMERIC
32867
+ else if (Regex.testAlphanumeric(dataStr)) return exports.ALPHANUMERIC
32868
+ else if (Regex.testKanji(dataStr)) return exports.KANJI
32869
+ else return exports.BYTE
32870
+ };
32871
+
32872
+ /**
32873
+ * Return mode name as string
32874
+ *
32875
+ * @param {Mode} mode Mode object
32876
+ * @returns {String} Mode name
32877
+ */
32878
+ exports.toString = function toString (mode) {
32879
+ if (mode && mode.id) return mode.id
32880
+ throw new Error('Invalid mode')
32881
+ };
32882
+
32883
+ /**
32884
+ * Check if input param is a valid mode object
32885
+ *
32886
+ * @param {Mode} mode Mode object
32887
+ * @returns {Boolean} True if valid mode, false otherwise
32888
+ */
32889
+ exports.isValid = function isValid (mode) {
32890
+ return mode && mode.bit && mode.ccBits
32891
+ };
32892
+
32893
+ /**
32894
+ * Get mode object from its name
32895
+ *
32896
+ * @param {String} string Mode name
32897
+ * @returns {Mode} Mode object
32898
+ */
32899
+ function fromString (string) {
32900
+ if (typeof string !== 'string') {
32901
+ throw new Error('Param is not a string')
32902
+ }
32903
+
32904
+ const lcStr = string.toLowerCase();
32905
+
32906
+ switch (lcStr) {
32907
+ case 'numeric':
32908
+ return exports.NUMERIC
32909
+ case 'alphanumeric':
32910
+ return exports.ALPHANUMERIC
32911
+ case 'kanji':
32912
+ return exports.KANJI
32913
+ case 'byte':
32914
+ return exports.BYTE
32915
+ default:
32916
+ throw new Error('Unknown mode: ' + string)
32917
+ }
32918
+ }
32919
+
32920
+ /**
32921
+ * Returns mode from a value.
32922
+ * If value is not a valid mode, returns defaultValue
32923
+ *
32924
+ * @param {Mode|String} value Encoding mode
32925
+ * @param {Mode} defaultValue Fallback value
32926
+ * @return {Mode} Encoding mode
32927
+ */
32928
+ exports.from = function from (value, defaultValue) {
32929
+ if (exports.isValid(value)) {
32930
+ return value
32931
+ }
32932
+
32933
+ try {
32934
+ return fromString(value)
32935
+ } catch (e) {
32936
+ return defaultValue
32937
+ }
32938
+ };
32939
+ } (mode));
32940
+ return mode;
32941
+ }
32942
+
32943
+ var hasRequiredVersion;
32944
+
32945
+ function requireVersion () {
32946
+ if (hasRequiredVersion) return version;
32947
+ hasRequiredVersion = 1;
32948
+ (function (exports) {
32949
+ const Utils = requireUtils$1();
32950
+ const ECCode = requireErrorCorrectionCode();
32951
+ const ECLevel = requireErrorCorrectionLevel();
32952
+ const Mode = requireMode();
32953
+ const VersionCheck = requireVersionCheck();
32954
+
32955
+ // Generator polynomial used to encode version information
32956
+ const G18 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8) | (1 << 5) | (1 << 2) | (1 << 0);
32957
+ const G18_BCH = Utils.getBCHDigit(G18);
32958
+
32959
+ function getBestVersionForDataLength (mode, length, errorCorrectionLevel) {
32960
+ for (let currentVersion = 1; currentVersion <= 40; currentVersion++) {
32961
+ if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, mode)) {
32962
+ return currentVersion
32963
+ }
32964
+ }
32965
+
32966
+ return undefined
32967
+ }
32968
+
32969
+ function getReservedBitsCount (mode, version) {
32970
+ // Character count indicator + mode indicator bits
32971
+ return Mode.getCharCountIndicator(mode, version) + 4
32972
+ }
32973
+
32974
+ function getTotalBitsFromDataArray (segments, version) {
32975
+ let totalBits = 0;
32976
+
32977
+ segments.forEach(function (data) {
32978
+ const reservedBits = getReservedBitsCount(data.mode, version);
32979
+ totalBits += reservedBits + data.getBitsLength();
32980
+ });
32981
+
32982
+ return totalBits
32983
+ }
32984
+
32985
+ function getBestVersionForMixedData (segments, errorCorrectionLevel) {
32986
+ for (let currentVersion = 1; currentVersion <= 40; currentVersion++) {
32987
+ const length = getTotalBitsFromDataArray(segments, currentVersion);
32988
+ if (length <= exports.getCapacity(currentVersion, errorCorrectionLevel, Mode.MIXED)) {
32989
+ return currentVersion
32990
+ }
32991
+ }
32992
+
32993
+ return undefined
32994
+ }
32995
+
32996
+ /**
32997
+ * Returns version number from a value.
32998
+ * If value is not a valid version, returns defaultValue
32999
+ *
33000
+ * @param {Number|String} value QR Code version
33001
+ * @param {Number} defaultValue Fallback value
33002
+ * @return {Number} QR Code version number
33003
+ */
33004
+ exports.from = function from (value, defaultValue) {
33005
+ if (VersionCheck.isValid(value)) {
33006
+ return parseInt(value, 10)
33007
+ }
33008
+
33009
+ return defaultValue
33010
+ };
33011
+
33012
+ /**
33013
+ * Returns how much data can be stored with the specified QR code version
33014
+ * and error correction level
33015
+ *
33016
+ * @param {Number} version QR Code version (1-40)
33017
+ * @param {Number} errorCorrectionLevel Error correction level
33018
+ * @param {Mode} mode Data mode
33019
+ * @return {Number} Quantity of storable data
33020
+ */
33021
+ exports.getCapacity = function getCapacity (version, errorCorrectionLevel, mode) {
33022
+ if (!VersionCheck.isValid(version)) {
33023
+ throw new Error('Invalid QR Code version')
33024
+ }
33025
+
33026
+ // Use Byte mode as default
33027
+ if (typeof mode === 'undefined') mode = Mode.BYTE;
33028
+
33029
+ // Total codewords for this QR code version (Data + Error correction)
33030
+ const totalCodewords = Utils.getSymbolTotalCodewords(version);
33031
+
33032
+ // Total number of error correction codewords
33033
+ const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel);
33034
+
33035
+ // Total number of data codewords
33036
+ const dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8;
33037
+
33038
+ if (mode === Mode.MIXED) return dataTotalCodewordsBits
33039
+
33040
+ const usableBits = dataTotalCodewordsBits - getReservedBitsCount(mode, version);
33041
+
33042
+ // Return max number of storable codewords
33043
+ switch (mode) {
33044
+ case Mode.NUMERIC:
33045
+ return Math.floor((usableBits / 10) * 3)
33046
+
33047
+ case Mode.ALPHANUMERIC:
33048
+ return Math.floor((usableBits / 11) * 2)
33049
+
33050
+ case Mode.KANJI:
33051
+ return Math.floor(usableBits / 13)
33052
+
33053
+ case Mode.BYTE:
33054
+ default:
33055
+ return Math.floor(usableBits / 8)
33056
+ }
33057
+ };
33058
+
33059
+ /**
33060
+ * Returns the minimum version needed to contain the amount of data
33061
+ *
33062
+ * @param {Segment} data Segment of data
33063
+ * @param {Number} [errorCorrectionLevel=H] Error correction level
33064
+ * @param {Mode} mode Data mode
33065
+ * @return {Number} QR Code version
33066
+ */
33067
+ exports.getBestVersionForData = function getBestVersionForData (data, errorCorrectionLevel) {
33068
+ let seg;
33069
+
33070
+ const ecl = ECLevel.from(errorCorrectionLevel, ECLevel.M);
33071
+
33072
+ if (Array.isArray(data)) {
33073
+ if (data.length > 1) {
33074
+ return getBestVersionForMixedData(data, ecl)
33075
+ }
33076
+
33077
+ if (data.length === 0) {
33078
+ return 1
33079
+ }
33080
+
33081
+ seg = data[0];
33082
+ } else {
33083
+ seg = data;
33084
+ }
33085
+
33086
+ return getBestVersionForDataLength(seg.mode, seg.getLength(), ecl)
33087
+ };
33088
+
33089
+ /**
33090
+ * Returns version information with relative error correction bits
33091
+ *
33092
+ * The version information is included in QR Code symbols of version 7 or larger.
33093
+ * It consists of an 18-bit sequence containing 6 data bits,
33094
+ * with 12 error correction bits calculated using the (18, 6) Golay code.
33095
+ *
33096
+ * @param {Number} version QR Code version
33097
+ * @return {Number} Encoded version info bits
33098
+ */
33099
+ exports.getEncodedBits = function getEncodedBits (version) {
33100
+ if (!VersionCheck.isValid(version) || version < 7) {
33101
+ throw new Error('Invalid QR Code version')
33102
+ }
33103
+
33104
+ let d = version << 12;
33105
+
33106
+ while (Utils.getBCHDigit(d) - G18_BCH >= 0) {
33107
+ d ^= (G18 << (Utils.getBCHDigit(d) - G18_BCH));
33108
+ }
33109
+
33110
+ return (version << 12) | d
33111
+ };
33112
+ } (version));
33113
+ return version;
33114
+ }
33115
+
33116
+ var formatInfo = {};
33117
+
33118
+ var hasRequiredFormatInfo;
33119
+
33120
+ function requireFormatInfo () {
33121
+ if (hasRequiredFormatInfo) return formatInfo;
33122
+ hasRequiredFormatInfo = 1;
33123
+ const Utils = requireUtils$1();
33124
+
33125
+ const G15 = (1 << 10) | (1 << 8) | (1 << 5) | (1 << 4) | (1 << 2) | (1 << 1) | (1 << 0);
33126
+ const G15_MASK = (1 << 14) | (1 << 12) | (1 << 10) | (1 << 4) | (1 << 1);
33127
+ const G15_BCH = Utils.getBCHDigit(G15);
33128
+
33129
+ /**
33130
+ * Returns format information with relative error correction bits
33131
+ *
33132
+ * The format information is a 15-bit sequence containing 5 data bits,
33133
+ * with 10 error correction bits calculated using the (15, 5) BCH code.
33134
+ *
33135
+ * @param {Number} errorCorrectionLevel Error correction level
33136
+ * @param {Number} mask Mask pattern
33137
+ * @return {Number} Encoded format information bits
33138
+ */
33139
+ formatInfo.getEncodedBits = function getEncodedBits (errorCorrectionLevel, mask) {
33140
+ const data = ((errorCorrectionLevel.bit << 3) | mask);
33141
+ let d = data << 10;
33142
+
33143
+ while (Utils.getBCHDigit(d) - G15_BCH >= 0) {
33144
+ d ^= (G15 << (Utils.getBCHDigit(d) - G15_BCH));
33145
+ }
33146
+
33147
+ // xor final data with mask pattern in order to ensure that
33148
+ // no combination of Error Correction Level and data mask pattern
33149
+ // will result in an all-zero data string
33150
+ return ((data << 10) | d) ^ G15_MASK
33151
+ };
33152
+ return formatInfo;
33153
+ }
33154
+
33155
+ var segments = {};
33156
+
33157
+ var numericData;
33158
+ var hasRequiredNumericData;
33159
+
33160
+ function requireNumericData () {
33161
+ if (hasRequiredNumericData) return numericData;
33162
+ hasRequiredNumericData = 1;
33163
+ const Mode = requireMode();
33164
+
33165
+ function NumericData (data) {
33166
+ this.mode = Mode.NUMERIC;
33167
+ this.data = data.toString();
33168
+ }
33169
+
33170
+ NumericData.getBitsLength = function getBitsLength (length) {
33171
+ return 10 * Math.floor(length / 3) + ((length % 3) ? ((length % 3) * 3 + 1) : 0)
33172
+ };
33173
+
33174
+ NumericData.prototype.getLength = function getLength () {
33175
+ return this.data.length
33176
+ };
33177
+
33178
+ NumericData.prototype.getBitsLength = function getBitsLength () {
33179
+ return NumericData.getBitsLength(this.data.length)
33180
+ };
33181
+
33182
+ NumericData.prototype.write = function write (bitBuffer) {
33183
+ let i, group, value;
33184
+
33185
+ // The input data string is divided into groups of three digits,
33186
+ // and each group is converted to its 10-bit binary equivalent.
33187
+ for (i = 0; i + 3 <= this.data.length; i += 3) {
33188
+ group = this.data.substr(i, 3);
33189
+ value = parseInt(group, 10);
33190
+
33191
+ bitBuffer.put(value, 10);
33192
+ }
33193
+
33194
+ // If the number of input digits is not an exact multiple of three,
33195
+ // the final one or two digits are converted to 4 or 7 bits respectively.
33196
+ const remainingNum = this.data.length - i;
33197
+ if (remainingNum > 0) {
33198
+ group = this.data.substr(i);
33199
+ value = parseInt(group, 10);
33200
+
33201
+ bitBuffer.put(value, remainingNum * 3 + 1);
33202
+ }
33203
+ };
33204
+
33205
+ numericData = NumericData;
33206
+ return numericData;
33207
+ }
33208
+
33209
+ var alphanumericData;
33210
+ var hasRequiredAlphanumericData;
33211
+
33212
+ function requireAlphanumericData () {
33213
+ if (hasRequiredAlphanumericData) return alphanumericData;
33214
+ hasRequiredAlphanumericData = 1;
33215
+ const Mode = requireMode();
33216
+
33217
+ /**
33218
+ * Array of characters available in alphanumeric mode
33219
+ *
33220
+ * As per QR Code specification, to each character
33221
+ * is assigned a value from 0 to 44 which in this case coincides
33222
+ * with the array index
33223
+ *
33224
+ * @type {Array}
33225
+ */
33226
+ const ALPHA_NUM_CHARS = [
33227
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
33228
+ 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
33229
+ 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
33230
+ ' ', '$', '%', '*', '+', '-', '.', '/', ':'
33231
+ ];
33232
+
33233
+ function AlphanumericData (data) {
33234
+ this.mode = Mode.ALPHANUMERIC;
33235
+ this.data = data;
33236
+ }
33237
+
33238
+ AlphanumericData.getBitsLength = function getBitsLength (length) {
33239
+ return 11 * Math.floor(length / 2) + 6 * (length % 2)
33240
+ };
33241
+
33242
+ AlphanumericData.prototype.getLength = function getLength () {
33243
+ return this.data.length
33244
+ };
33245
+
33246
+ AlphanumericData.prototype.getBitsLength = function getBitsLength () {
33247
+ return AlphanumericData.getBitsLength(this.data.length)
33248
+ };
33249
+
33250
+ AlphanumericData.prototype.write = function write (bitBuffer) {
33251
+ let i;
33252
+
33253
+ // Input data characters are divided into groups of two characters
33254
+ // and encoded as 11-bit binary codes.
33255
+ for (i = 0; i + 2 <= this.data.length; i += 2) {
33256
+ // The character value of the first character is multiplied by 45
33257
+ let value = ALPHA_NUM_CHARS.indexOf(this.data[i]) * 45;
33258
+
33259
+ // The character value of the second digit is added to the product
33260
+ value += ALPHA_NUM_CHARS.indexOf(this.data[i + 1]);
33261
+
33262
+ // The sum is then stored as 11-bit binary number
33263
+ bitBuffer.put(value, 11);
33264
+ }
33265
+
33266
+ // If the number of input data characters is not a multiple of two,
33267
+ // the character value of the final character is encoded as a 6-bit binary number.
33268
+ if (this.data.length % 2) {
33269
+ bitBuffer.put(ALPHA_NUM_CHARS.indexOf(this.data[i]), 6);
33270
+ }
33271
+ };
33272
+
33273
+ alphanumericData = AlphanumericData;
33274
+ return alphanumericData;
33275
+ }
33276
+
33277
+ var byteData;
33278
+ var hasRequiredByteData;
33279
+
33280
+ function requireByteData () {
33281
+ if (hasRequiredByteData) return byteData;
33282
+ hasRequiredByteData = 1;
33283
+ const Mode = requireMode();
33284
+
33285
+ function ByteData (data) {
33286
+ this.mode = Mode.BYTE;
33287
+ if (typeof (data) === 'string') {
33288
+ this.data = new TextEncoder().encode(data);
33289
+ } else {
33290
+ this.data = new Uint8Array(data);
33291
+ }
33292
+ }
33293
+
33294
+ ByteData.getBitsLength = function getBitsLength (length) {
33295
+ return length * 8
33296
+ };
33297
+
33298
+ ByteData.prototype.getLength = function getLength () {
33299
+ return this.data.length
33300
+ };
33301
+
33302
+ ByteData.prototype.getBitsLength = function getBitsLength () {
33303
+ return ByteData.getBitsLength(this.data.length)
33304
+ };
33305
+
33306
+ ByteData.prototype.write = function (bitBuffer) {
33307
+ for (let i = 0, l = this.data.length; i < l; i++) {
33308
+ bitBuffer.put(this.data[i], 8);
33309
+ }
33310
+ };
33311
+
33312
+ byteData = ByteData;
33313
+ return byteData;
33314
+ }
33315
+
33316
+ var kanjiData;
33317
+ var hasRequiredKanjiData;
33318
+
33319
+ function requireKanjiData () {
33320
+ if (hasRequiredKanjiData) return kanjiData;
33321
+ hasRequiredKanjiData = 1;
33322
+ const Mode = requireMode();
33323
+ const Utils = requireUtils$1();
33324
+
33325
+ function KanjiData (data) {
33326
+ this.mode = Mode.KANJI;
33327
+ this.data = data;
33328
+ }
33329
+
33330
+ KanjiData.getBitsLength = function getBitsLength (length) {
33331
+ return length * 13
33332
+ };
33333
+
33334
+ KanjiData.prototype.getLength = function getLength () {
33335
+ return this.data.length
33336
+ };
33337
+
33338
+ KanjiData.prototype.getBitsLength = function getBitsLength () {
33339
+ return KanjiData.getBitsLength(this.data.length)
33340
+ };
33341
+
33342
+ KanjiData.prototype.write = function (bitBuffer) {
33343
+ let i;
33344
+
33345
+ // In the Shift JIS system, Kanji characters are represented by a two byte combination.
33346
+ // These byte values are shifted from the JIS X 0208 values.
33347
+ // JIS X 0208 gives details of the shift coded representation.
33348
+ for (i = 0; i < this.data.length; i++) {
33349
+ let value = Utils.toSJIS(this.data[i]);
33350
+
33351
+ // For characters with Shift JIS values from 0x8140 to 0x9FFC:
33352
+ if (value >= 0x8140 && value <= 0x9FFC) {
33353
+ // Subtract 0x8140 from Shift JIS value
33354
+ value -= 0x8140;
33355
+
33356
+ // For characters with Shift JIS values from 0xE040 to 0xEBBF
33357
+ } else if (value >= 0xE040 && value <= 0xEBBF) {
33358
+ // Subtract 0xC140 from Shift JIS value
33359
+ value -= 0xC140;
33360
+ } else {
33361
+ throw new Error(
33362
+ 'Invalid SJIS character: ' + this.data[i] + '\n' +
33363
+ 'Make sure your charset is UTF-8')
33364
+ }
33365
+
33366
+ // Multiply most significant byte of result by 0xC0
33367
+ // and add least significant byte to product
33368
+ value = (((value >>> 8) & 0xff) * 0xC0) + (value & 0xff);
33369
+
33370
+ // Convert result to a 13-bit binary string
33371
+ bitBuffer.put(value, 13);
33372
+ }
33373
+ };
33374
+
33375
+ kanjiData = KanjiData;
33376
+ return kanjiData;
33377
+ }
33378
+
33379
+ var dijkstra = {exports: {}};
33380
+
33381
+ var hasRequiredDijkstra;
33382
+
33383
+ function requireDijkstra () {
33384
+ if (hasRequiredDijkstra) return dijkstra.exports;
33385
+ hasRequiredDijkstra = 1;
33386
+ (function (module) {
33387
+
33388
+ /******************************************************************************
33389
+ * Created 2008-08-19.
33390
+ *
33391
+ * Dijkstra path-finding functions. Adapted from the Dijkstar Python project.
33392
+ *
33393
+ * Copyright (C) 2008
33394
+ * Wyatt Baldwin <self@wyattbaldwin.com>
33395
+ * All rights reserved
33396
+ *
33397
+ * Licensed under the MIT license.
33398
+ *
33399
+ * http://www.opensource.org/licenses/mit-license.php
33400
+ *
33401
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33402
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33403
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
33404
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
33405
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
33406
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
33407
+ * THE SOFTWARE.
33408
+ *****************************************************************************/
33409
+ var dijkstra = {
33410
+ single_source_shortest_paths: function(graph, s, d) {
33411
+ // Predecessor map for each node that has been encountered.
33412
+ // node ID => predecessor node ID
33413
+ var predecessors = {};
33414
+
33415
+ // Costs of shortest paths from s to all nodes encountered.
33416
+ // node ID => cost
33417
+ var costs = {};
33418
+ costs[s] = 0;
33419
+
33420
+ // Costs of shortest paths from s to all nodes encountered; differs from
33421
+ // `costs` in that it provides easy access to the node that currently has
33422
+ // the known shortest path from s.
33423
+ // XXX: Do we actually need both `costs` and `open`?
33424
+ var open = dijkstra.PriorityQueue.make();
33425
+ open.push(s, 0);
33426
+
33427
+ var closest,
33428
+ u, v,
33429
+ cost_of_s_to_u,
33430
+ adjacent_nodes,
33431
+ cost_of_e,
33432
+ cost_of_s_to_u_plus_cost_of_e,
33433
+ cost_of_s_to_v,
33434
+ first_visit;
33435
+ while (!open.empty()) {
33436
+ // In the nodes remaining in graph that have a known cost from s,
33437
+ // find the node, u, that currently has the shortest path from s.
33438
+ closest = open.pop();
33439
+ u = closest.value;
33440
+ cost_of_s_to_u = closest.cost;
33441
+
33442
+ // Get nodes adjacent to u...
33443
+ adjacent_nodes = graph[u] || {};
33444
+
33445
+ // ...and explore the edges that connect u to those nodes, updating
33446
+ // the cost of the shortest paths to any or all of those nodes as
33447
+ // necessary. v is the node across the current edge from u.
33448
+ for (v in adjacent_nodes) {
33449
+ if (adjacent_nodes.hasOwnProperty(v)) {
33450
+ // Get the cost of the edge running from u to v.
33451
+ cost_of_e = adjacent_nodes[v];
33452
+
33453
+ // Cost of s to u plus the cost of u to v across e--this is *a*
33454
+ // cost from s to v that may or may not be less than the current
33455
+ // known cost to v.
33456
+ cost_of_s_to_u_plus_cost_of_e = cost_of_s_to_u + cost_of_e;
33457
+
33458
+ // If we haven't visited v yet OR if the current known cost from s to
33459
+ // v is greater than the new cost we just found (cost of s to u plus
33460
+ // cost of u to v across e), update v's cost in the cost list and
33461
+ // update v's predecessor in the predecessor list (it's now u).
33462
+ cost_of_s_to_v = costs[v];
33463
+ first_visit = (typeof costs[v] === 'undefined');
33464
+ if (first_visit || cost_of_s_to_v > cost_of_s_to_u_plus_cost_of_e) {
33465
+ costs[v] = cost_of_s_to_u_plus_cost_of_e;
33466
+ open.push(v, cost_of_s_to_u_plus_cost_of_e);
33467
+ predecessors[v] = u;
33468
+ }
33469
+ }
33470
+ }
33471
+ }
33472
+
33473
+ if (typeof d !== 'undefined' && typeof costs[d] === 'undefined') {
33474
+ var msg = ['Could not find a path from ', s, ' to ', d, '.'].join('');
33475
+ throw new Error(msg);
33476
+ }
33477
+
33478
+ return predecessors;
33479
+ },
33480
+
33481
+ extract_shortest_path_from_predecessor_list: function(predecessors, d) {
33482
+ var nodes = [];
33483
+ var u = d;
33484
+ while (u) {
33485
+ nodes.push(u);
33486
+ u = predecessors[u];
33487
+ }
33488
+ nodes.reverse();
33489
+ return nodes;
33490
+ },
33491
+
33492
+ find_path: function(graph, s, d) {
33493
+ var predecessors = dijkstra.single_source_shortest_paths(graph, s, d);
33494
+ return dijkstra.extract_shortest_path_from_predecessor_list(
33495
+ predecessors, d);
33496
+ },
33497
+
33498
+ /**
33499
+ * A very naive priority queue implementation.
33500
+ */
33501
+ PriorityQueue: {
33502
+ make: function (opts) {
33503
+ var T = dijkstra.PriorityQueue,
33504
+ t = {},
33505
+ key;
33506
+ opts = opts || {};
33507
+ for (key in T) {
33508
+ if (T.hasOwnProperty(key)) {
33509
+ t[key] = T[key];
33510
+ }
33511
+ }
33512
+ t.queue = [];
33513
+ t.sorter = opts.sorter || T.default_sorter;
33514
+ return t;
33515
+ },
33516
+
33517
+ default_sorter: function (a, b) {
33518
+ return a.cost - b.cost;
33519
+ },
33520
+
33521
+ /**
33522
+ * Add a new item to the queue and ensure the highest priority element
33523
+ * is at the front of the queue.
33524
+ */
33525
+ push: function (value, cost) {
33526
+ var item = {value: value, cost: cost};
33527
+ this.queue.push(item);
33528
+ this.queue.sort(this.sorter);
33529
+ },
33530
+
33531
+ /**
33532
+ * Return the highest priority element in the queue.
33533
+ */
33534
+ pop: function () {
33535
+ return this.queue.shift();
33536
+ },
33537
+
33538
+ empty: function () {
33539
+ return this.queue.length === 0;
33540
+ }
33541
+ }
33542
+ };
33543
+
33544
+
33545
+ // node.js module exports
33546
+ {
33547
+ module.exports = dijkstra;
33548
+ }
33549
+ } (dijkstra));
33550
+ return dijkstra.exports;
33551
+ }
33552
+
33553
+ var hasRequiredSegments;
33554
+
33555
+ function requireSegments () {
33556
+ if (hasRequiredSegments) return segments;
33557
+ hasRequiredSegments = 1;
33558
+ (function (exports) {
33559
+ const Mode = requireMode();
33560
+ const NumericData = requireNumericData();
33561
+ const AlphanumericData = requireAlphanumericData();
33562
+ const ByteData = requireByteData();
33563
+ const KanjiData = requireKanjiData();
33564
+ const Regex = requireRegex();
33565
+ const Utils = requireUtils$1();
33566
+ const dijkstra = requireDijkstra();
33567
+
33568
+ /**
33569
+ * Returns UTF8 byte length
33570
+ *
33571
+ * @param {String} str Input string
33572
+ * @return {Number} Number of byte
33573
+ */
33574
+ function getStringByteLength (str) {
33575
+ return unescape(encodeURIComponent(str)).length
33576
+ }
33577
+
33578
+ /**
33579
+ * Get a list of segments of the specified mode
33580
+ * from a string
33581
+ *
33582
+ * @param {Mode} mode Segment mode
33583
+ * @param {String} str String to process
33584
+ * @return {Array} Array of object with segments data
33585
+ */
33586
+ function getSegments (regex, mode, str) {
33587
+ const segments = [];
33588
+ let result;
33589
+
33590
+ while ((result = regex.exec(str)) !== null) {
33591
+ segments.push({
33592
+ data: result[0],
33593
+ index: result.index,
33594
+ mode: mode,
33595
+ length: result[0].length
33596
+ });
33597
+ }
33598
+
33599
+ return segments
33600
+ }
33601
+
33602
+ /**
33603
+ * Extracts a series of segments with the appropriate
33604
+ * modes from a string
33605
+ *
33606
+ * @param {String} dataStr Input string
33607
+ * @return {Array} Array of object with segments data
33608
+ */
33609
+ function getSegmentsFromString (dataStr) {
33610
+ const numSegs = getSegments(Regex.NUMERIC, Mode.NUMERIC, dataStr);
33611
+ const alphaNumSegs = getSegments(Regex.ALPHANUMERIC, Mode.ALPHANUMERIC, dataStr);
33612
+ let byteSegs;
33613
+ let kanjiSegs;
33614
+
33615
+ if (Utils.isKanjiModeEnabled()) {
33616
+ byteSegs = getSegments(Regex.BYTE, Mode.BYTE, dataStr);
33617
+ kanjiSegs = getSegments(Regex.KANJI, Mode.KANJI, dataStr);
33618
+ } else {
33619
+ byteSegs = getSegments(Regex.BYTE_KANJI, Mode.BYTE, dataStr);
33620
+ kanjiSegs = [];
33621
+ }
33622
+
33623
+ const segs = numSegs.concat(alphaNumSegs, byteSegs, kanjiSegs);
33624
+
33625
+ return segs
33626
+ .sort(function (s1, s2) {
33627
+ return s1.index - s2.index
33628
+ })
33629
+ .map(function (obj) {
33630
+ return {
33631
+ data: obj.data,
33632
+ mode: obj.mode,
33633
+ length: obj.length
33634
+ }
33635
+ })
33636
+ }
33637
+
33638
+ /**
33639
+ * Returns how many bits are needed to encode a string of
33640
+ * specified length with the specified mode
33641
+ *
33642
+ * @param {Number} length String length
33643
+ * @param {Mode} mode Segment mode
33644
+ * @return {Number} Bit length
33645
+ */
33646
+ function getSegmentBitsLength (length, mode) {
33647
+ switch (mode) {
33648
+ case Mode.NUMERIC:
33649
+ return NumericData.getBitsLength(length)
33650
+ case Mode.ALPHANUMERIC:
33651
+ return AlphanumericData.getBitsLength(length)
33652
+ case Mode.KANJI:
33653
+ return KanjiData.getBitsLength(length)
33654
+ case Mode.BYTE:
33655
+ return ByteData.getBitsLength(length)
33656
+ }
33657
+ }
33658
+
33659
+ /**
33660
+ * Merges adjacent segments which have the same mode
33661
+ *
33662
+ * @param {Array} segs Array of object with segments data
33663
+ * @return {Array} Array of object with segments data
33664
+ */
33665
+ function mergeSegments (segs) {
33666
+ return segs.reduce(function (acc, curr) {
33667
+ const prevSeg = acc.length - 1 >= 0 ? acc[acc.length - 1] : null;
33668
+ if (prevSeg && prevSeg.mode === curr.mode) {
33669
+ acc[acc.length - 1].data += curr.data;
33670
+ return acc
33671
+ }
33672
+
33673
+ acc.push(curr);
33674
+ return acc
33675
+ }, [])
33676
+ }
33677
+
33678
+ /**
33679
+ * Generates a list of all possible nodes combination which
33680
+ * will be used to build a segments graph.
33681
+ *
33682
+ * Nodes are divided by groups. Each group will contain a list of all the modes
33683
+ * in which is possible to encode the given text.
33684
+ *
33685
+ * For example the text '12345' can be encoded as Numeric, Alphanumeric or Byte.
33686
+ * The group for '12345' will contain then 3 objects, one for each
33687
+ * possible encoding mode.
33688
+ *
33689
+ * Each node represents a possible segment.
33690
+ *
33691
+ * @param {Array} segs Array of object with segments data
33692
+ * @return {Array} Array of object with segments data
33693
+ */
33694
+ function buildNodes (segs) {
33695
+ const nodes = [];
33696
+ for (let i = 0; i < segs.length; i++) {
33697
+ const seg = segs[i];
33698
+
33699
+ switch (seg.mode) {
33700
+ case Mode.NUMERIC:
33701
+ nodes.push([seg,
33702
+ { data: seg.data, mode: Mode.ALPHANUMERIC, length: seg.length },
33703
+ { data: seg.data, mode: Mode.BYTE, length: seg.length }
33704
+ ]);
33705
+ break
33706
+ case Mode.ALPHANUMERIC:
33707
+ nodes.push([seg,
33708
+ { data: seg.data, mode: Mode.BYTE, length: seg.length }
33709
+ ]);
33710
+ break
33711
+ case Mode.KANJI:
33712
+ nodes.push([seg,
33713
+ { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
33714
+ ]);
33715
+ break
33716
+ case Mode.BYTE:
33717
+ nodes.push([
33718
+ { data: seg.data, mode: Mode.BYTE, length: getStringByteLength(seg.data) }
33719
+ ]);
33720
+ }
33721
+ }
33722
+
33723
+ return nodes
33724
+ }
33725
+
33726
+ /**
33727
+ * Builds a graph from a list of nodes.
33728
+ * All segments in each node group will be connected with all the segments of
33729
+ * the next group and so on.
33730
+ *
33731
+ * At each connection will be assigned a weight depending on the
33732
+ * segment's byte length.
33733
+ *
33734
+ * @param {Array} nodes Array of object with segments data
33735
+ * @param {Number} version QR Code version
33736
+ * @return {Object} Graph of all possible segments
33737
+ */
33738
+ function buildGraph (nodes, version) {
33739
+ const table = {};
33740
+ const graph = { start: {} };
33741
+ let prevNodeIds = ['start'];
33742
+
33743
+ for (let i = 0; i < nodes.length; i++) {
33744
+ const nodeGroup = nodes[i];
33745
+ const currentNodeIds = [];
33746
+
33747
+ for (let j = 0; j < nodeGroup.length; j++) {
33748
+ const node = nodeGroup[j];
33749
+ const key = '' + i + j;
33750
+
33751
+ currentNodeIds.push(key);
33752
+ table[key] = { node: node, lastCount: 0 };
33753
+ graph[key] = {};
33754
+
33755
+ for (let n = 0; n < prevNodeIds.length; n++) {
33756
+ const prevNodeId = prevNodeIds[n];
33757
+
33758
+ if (table[prevNodeId] && table[prevNodeId].node.mode === node.mode) {
33759
+ graph[prevNodeId][key] =
33760
+ getSegmentBitsLength(table[prevNodeId].lastCount + node.length, node.mode) -
33761
+ getSegmentBitsLength(table[prevNodeId].lastCount, node.mode);
33762
+
33763
+ table[prevNodeId].lastCount += node.length;
33764
+ } else {
33765
+ if (table[prevNodeId]) table[prevNodeId].lastCount = node.length;
33766
+
33767
+ graph[prevNodeId][key] = getSegmentBitsLength(node.length, node.mode) +
33768
+ 4 + Mode.getCharCountIndicator(node.mode, version); // switch cost
33769
+ }
33770
+ }
33771
+ }
33772
+
33773
+ prevNodeIds = currentNodeIds;
33774
+ }
33775
+
33776
+ for (let n = 0; n < prevNodeIds.length; n++) {
33777
+ graph[prevNodeIds[n]].end = 0;
33778
+ }
33779
+
33780
+ return { map: graph, table: table }
33781
+ }
33782
+
33783
+ /**
33784
+ * Builds a segment from a specified data and mode.
33785
+ * If a mode is not specified, the more suitable will be used.
33786
+ *
33787
+ * @param {String} data Input data
33788
+ * @param {Mode | String} modesHint Data mode
33789
+ * @return {Segment} Segment
33790
+ */
33791
+ function buildSingleSegment (data, modesHint) {
33792
+ let mode;
33793
+ const bestMode = Mode.getBestModeForData(data);
33794
+
33795
+ mode = Mode.from(modesHint, bestMode);
33796
+
33797
+ // Make sure data can be encoded
33798
+ if (mode !== Mode.BYTE && mode.bit < bestMode.bit) {
33799
+ throw new Error('"' + data + '"' +
33800
+ ' cannot be encoded with mode ' + Mode.toString(mode) +
33801
+ '.\n Suggested mode is: ' + Mode.toString(bestMode))
33802
+ }
33803
+
33804
+ // Use Mode.BYTE if Kanji support is disabled
33805
+ if (mode === Mode.KANJI && !Utils.isKanjiModeEnabled()) {
33806
+ mode = Mode.BYTE;
33807
+ }
33808
+
33809
+ switch (mode) {
33810
+ case Mode.NUMERIC:
33811
+ return new NumericData(data)
33812
+
33813
+ case Mode.ALPHANUMERIC:
33814
+ return new AlphanumericData(data)
33815
+
33816
+ case Mode.KANJI:
33817
+ return new KanjiData(data)
33818
+
33819
+ case Mode.BYTE:
33820
+ return new ByteData(data)
33821
+ }
33822
+ }
33823
+
33824
+ /**
33825
+ * Builds a list of segments from an array.
33826
+ * Array can contain Strings or Objects with segment's info.
33827
+ *
33828
+ * For each item which is a string, will be generated a segment with the given
33829
+ * string and the more appropriate encoding mode.
33830
+ *
33831
+ * For each item which is an object, will be generated a segment with the given
33832
+ * data and mode.
33833
+ * Objects must contain at least the property "data".
33834
+ * If property "mode" is not present, the more suitable mode will be used.
33835
+ *
33836
+ * @param {Array} array Array of objects with segments data
33837
+ * @return {Array} Array of Segments
33838
+ */
33839
+ exports.fromArray = function fromArray (array) {
33840
+ return array.reduce(function (acc, seg) {
33841
+ if (typeof seg === 'string') {
33842
+ acc.push(buildSingleSegment(seg, null));
33843
+ } else if (seg.data) {
33844
+ acc.push(buildSingleSegment(seg.data, seg.mode));
33845
+ }
33846
+
33847
+ return acc
33848
+ }, [])
33849
+ };
33850
+
33851
+ /**
33852
+ * Builds an optimized sequence of segments from a string,
33853
+ * which will produce the shortest possible bitstream.
33854
+ *
33855
+ * @param {String} data Input string
33856
+ * @param {Number} version QR Code version
33857
+ * @return {Array} Array of segments
33858
+ */
33859
+ exports.fromString = function fromString (data, version) {
33860
+ const segs = getSegmentsFromString(data, Utils.isKanjiModeEnabled());
33861
+
33862
+ const nodes = buildNodes(segs);
33863
+ const graph = buildGraph(nodes, version);
33864
+ const path = dijkstra.find_path(graph.map, 'start', 'end');
33865
+
33866
+ const optimizedSegs = [];
33867
+ for (let i = 1; i < path.length - 1; i++) {
33868
+ optimizedSegs.push(graph.table[path[i]].node);
33869
+ }
33870
+
33871
+ return exports.fromArray(mergeSegments(optimizedSegs))
33872
+ };
33873
+
33874
+ /**
33875
+ * Splits a string in various segments with the modes which
33876
+ * best represent their content.
33877
+ * The produced segments are far from being optimized.
33878
+ * The output of this function is only used to estimate a QR Code version
33879
+ * which may contain the data.
33880
+ *
33881
+ * @param {string} data Input string
33882
+ * @return {Array} Array of segments
33883
+ */
33884
+ exports.rawSplit = function rawSplit (data) {
33885
+ return exports.fromArray(
33886
+ getSegmentsFromString(data, Utils.isKanjiModeEnabled())
33887
+ )
33888
+ };
33889
+ } (segments));
33890
+ return segments;
33891
+ }
33892
+
33893
+ var hasRequiredQrcode;
33894
+
33895
+ function requireQrcode () {
33896
+ if (hasRequiredQrcode) return qrcode;
33897
+ hasRequiredQrcode = 1;
33898
+ const Utils = requireUtils$1();
33899
+ const ECLevel = requireErrorCorrectionLevel();
33900
+ const BitBuffer = requireBitBuffer();
33901
+ const BitMatrix = requireBitMatrix();
33902
+ const AlignmentPattern = requireAlignmentPattern();
33903
+ const FinderPattern = requireFinderPattern();
33904
+ const MaskPattern = requireMaskPattern();
33905
+ const ECCode = requireErrorCorrectionCode();
33906
+ const ReedSolomonEncoder = requireReedSolomonEncoder();
33907
+ const Version = requireVersion();
33908
+ const FormatInfo = requireFormatInfo();
33909
+ const Mode = requireMode();
33910
+ const Segments = requireSegments();
33911
+
33912
+ /**
33913
+ * QRCode for JavaScript
33914
+ *
33915
+ * modified by Ryan Day for nodejs support
33916
+ * Copyright (c) 2011 Ryan Day
33917
+ *
33918
+ * Licensed under the MIT license:
33919
+ * http://www.opensource.org/licenses/mit-license.php
33920
+ *
33921
+ //---------------------------------------------------------------------
33922
+ // QRCode for JavaScript
33923
+ //
33924
+ // Copyright (c) 2009 Kazuhiko Arase
33925
+ //
33926
+ // URL: http://www.d-project.com/
33927
+ //
33928
+ // Licensed under the MIT license:
33929
+ // http://www.opensource.org/licenses/mit-license.php
33930
+ //
33931
+ // The word "QR Code" is registered trademark of
33932
+ // DENSO WAVE INCORPORATED
33933
+ // http://www.denso-wave.com/qrcode/faqpatent-e.html
33934
+ //
33935
+ //---------------------------------------------------------------------
33936
+ */
33937
+
33938
+ /**
33939
+ * Add finder patterns bits to matrix
33940
+ *
33941
+ * @param {BitMatrix} matrix Modules matrix
33942
+ * @param {Number} version QR Code version
33943
+ */
33944
+ function setupFinderPattern (matrix, version) {
33945
+ const size = matrix.size;
33946
+ const pos = FinderPattern.getPositions(version);
33947
+
33948
+ for (let i = 0; i < pos.length; i++) {
33949
+ const row = pos[i][0];
33950
+ const col = pos[i][1];
33951
+
33952
+ for (let r = -1; r <= 7; r++) {
33953
+ if (row + r <= -1 || size <= row + r) continue
33954
+
33955
+ for (let c = -1; c <= 7; c++) {
33956
+ if (col + c <= -1 || size <= col + c) continue
33957
+
33958
+ if ((r >= 0 && r <= 6 && (c === 0 || c === 6)) ||
33959
+ (c >= 0 && c <= 6 && (r === 0 || r === 6)) ||
33960
+ (r >= 2 && r <= 4 && c >= 2 && c <= 4)) {
33961
+ matrix.set(row + r, col + c, true, true);
33962
+ } else {
33963
+ matrix.set(row + r, col + c, false, true);
33964
+ }
33965
+ }
33966
+ }
33967
+ }
33968
+ }
33969
+
33970
+ /**
33971
+ * Add timing pattern bits to matrix
33972
+ *
33973
+ * Note: this function must be called before {@link setupAlignmentPattern}
33974
+ *
33975
+ * @param {BitMatrix} matrix Modules matrix
33976
+ */
33977
+ function setupTimingPattern (matrix) {
33978
+ const size = matrix.size;
33979
+
33980
+ for (let r = 8; r < size - 8; r++) {
33981
+ const value = r % 2 === 0;
33982
+ matrix.set(r, 6, value, true);
33983
+ matrix.set(6, r, value, true);
33984
+ }
33985
+ }
33986
+
33987
+ /**
33988
+ * Add alignment patterns bits to matrix
33989
+ *
33990
+ * Note: this function must be called after {@link setupTimingPattern}
33991
+ *
33992
+ * @param {BitMatrix} matrix Modules matrix
33993
+ * @param {Number} version QR Code version
33994
+ */
33995
+ function setupAlignmentPattern (matrix, version) {
33996
+ const pos = AlignmentPattern.getPositions(version);
33997
+
33998
+ for (let i = 0; i < pos.length; i++) {
33999
+ const row = pos[i][0];
34000
+ const col = pos[i][1];
34001
+
34002
+ for (let r = -2; r <= 2; r++) {
34003
+ for (let c = -2; c <= 2; c++) {
34004
+ if (r === -2 || r === 2 || c === -2 || c === 2 ||
34005
+ (r === 0 && c === 0)) {
34006
+ matrix.set(row + r, col + c, true, true);
34007
+ } else {
34008
+ matrix.set(row + r, col + c, false, true);
34009
+ }
34010
+ }
34011
+ }
34012
+ }
34013
+ }
34014
+
34015
+ /**
34016
+ * Add version info bits to matrix
34017
+ *
34018
+ * @param {BitMatrix} matrix Modules matrix
34019
+ * @param {Number} version QR Code version
34020
+ */
34021
+ function setupVersionInfo (matrix, version) {
34022
+ const size = matrix.size;
34023
+ const bits = Version.getEncodedBits(version);
34024
+ let row, col, mod;
34025
+
34026
+ for (let i = 0; i < 18; i++) {
34027
+ row = Math.floor(i / 3);
34028
+ col = i % 3 + size - 8 - 3;
34029
+ mod = ((bits >> i) & 1) === 1;
34030
+
34031
+ matrix.set(row, col, mod, true);
34032
+ matrix.set(col, row, mod, true);
34033
+ }
34034
+ }
34035
+
34036
+ /**
34037
+ * Add format info bits to matrix
34038
+ *
34039
+ * @param {BitMatrix} matrix Modules matrix
34040
+ * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
34041
+ * @param {Number} maskPattern Mask pattern reference value
34042
+ */
34043
+ function setupFormatInfo (matrix, errorCorrectionLevel, maskPattern) {
34044
+ const size = matrix.size;
34045
+ const bits = FormatInfo.getEncodedBits(errorCorrectionLevel, maskPattern);
34046
+ let i, mod;
34047
+
34048
+ for (i = 0; i < 15; i++) {
34049
+ mod = ((bits >> i) & 1) === 1;
34050
+
34051
+ // vertical
34052
+ if (i < 6) {
34053
+ matrix.set(i, 8, mod, true);
34054
+ } else if (i < 8) {
34055
+ matrix.set(i + 1, 8, mod, true);
34056
+ } else {
34057
+ matrix.set(size - 15 + i, 8, mod, true);
34058
+ }
34059
+
34060
+ // horizontal
34061
+ if (i < 8) {
34062
+ matrix.set(8, size - i - 1, mod, true);
34063
+ } else if (i < 9) {
34064
+ matrix.set(8, 15 - i - 1 + 1, mod, true);
34065
+ } else {
34066
+ matrix.set(8, 15 - i - 1, mod, true);
34067
+ }
34068
+ }
34069
+
34070
+ // fixed module
34071
+ matrix.set(size - 8, 8, 1, true);
34072
+ }
34073
+
34074
+ /**
34075
+ * Add encoded data bits to matrix
34076
+ *
34077
+ * @param {BitMatrix} matrix Modules matrix
34078
+ * @param {Uint8Array} data Data codewords
34079
+ */
34080
+ function setupData (matrix, data) {
34081
+ const size = matrix.size;
34082
+ let inc = -1;
34083
+ let row = size - 1;
34084
+ let bitIndex = 7;
34085
+ let byteIndex = 0;
34086
+
34087
+ for (let col = size - 1; col > 0; col -= 2) {
34088
+ if (col === 6) col--;
34089
+
34090
+ while (true) {
34091
+ for (let c = 0; c < 2; c++) {
34092
+ if (!matrix.isReserved(row, col - c)) {
34093
+ let dark = false;
34094
+
34095
+ if (byteIndex < data.length) {
34096
+ dark = (((data[byteIndex] >>> bitIndex) & 1) === 1);
34097
+ }
34098
+
34099
+ matrix.set(row, col - c, dark);
34100
+ bitIndex--;
34101
+
34102
+ if (bitIndex === -1) {
34103
+ byteIndex++;
34104
+ bitIndex = 7;
34105
+ }
34106
+ }
34107
+ }
34108
+
34109
+ row += inc;
34110
+
34111
+ if (row < 0 || size <= row) {
34112
+ row -= inc;
34113
+ inc = -inc;
34114
+ break
34115
+ }
34116
+ }
34117
+ }
34118
+ }
34119
+
34120
+ /**
34121
+ * Create encoded codewords from data input
34122
+ *
34123
+ * @param {Number} version QR Code version
34124
+ * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
34125
+ * @param {ByteData} data Data input
34126
+ * @return {Uint8Array} Buffer containing encoded codewords
34127
+ */
34128
+ function createData (version, errorCorrectionLevel, segments) {
34129
+ // Prepare data buffer
34130
+ const buffer = new BitBuffer();
34131
+
34132
+ segments.forEach(function (data) {
34133
+ // prefix data with mode indicator (4 bits)
34134
+ buffer.put(data.mode.bit, 4);
34135
+
34136
+ // Prefix data with character count indicator.
34137
+ // The character count indicator is a string of bits that represents the
34138
+ // number of characters that are being encoded.
34139
+ // The character count indicator must be placed after the mode indicator
34140
+ // and must be a certain number of bits long, depending on the QR version
34141
+ // and data mode
34142
+ // @see {@link Mode.getCharCountIndicator}.
34143
+ buffer.put(data.getLength(), Mode.getCharCountIndicator(data.mode, version));
34144
+
34145
+ // add binary data sequence to buffer
34146
+ data.write(buffer);
34147
+ });
34148
+
34149
+ // Calculate required number of bits
34150
+ const totalCodewords = Utils.getSymbolTotalCodewords(version);
34151
+ const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel);
34152
+ const dataTotalCodewordsBits = (totalCodewords - ecTotalCodewords) * 8;
34153
+
34154
+ // Add a terminator.
34155
+ // If the bit string is shorter than the total number of required bits,
34156
+ // a terminator of up to four 0s must be added to the right side of the string.
34157
+ // If the bit string is more than four bits shorter than the required number of bits,
34158
+ // add four 0s to the end.
34159
+ if (buffer.getLengthInBits() + 4 <= dataTotalCodewordsBits) {
34160
+ buffer.put(0, 4);
34161
+ }
34162
+
34163
+ // If the bit string is fewer than four bits shorter, add only the number of 0s that
34164
+ // are needed to reach the required number of bits.
34165
+
34166
+ // After adding the terminator, if the number of bits in the string is not a multiple of 8,
34167
+ // pad the string on the right with 0s to make the string's length a multiple of 8.
34168
+ while (buffer.getLengthInBits() % 8 !== 0) {
34169
+ buffer.putBit(0);
34170
+ }
34171
+
34172
+ // Add pad bytes if the string is still shorter than the total number of required bits.
34173
+ // Extend the buffer to fill the data capacity of the symbol corresponding to
34174
+ // the Version and Error Correction Level by adding the Pad Codewords 11101100 (0xEC)
34175
+ // and 00010001 (0x11) alternately.
34176
+ const remainingByte = (dataTotalCodewordsBits - buffer.getLengthInBits()) / 8;
34177
+ for (let i = 0; i < remainingByte; i++) {
34178
+ buffer.put(i % 2 ? 0x11 : 0xEC, 8);
34179
+ }
34180
+
34181
+ return createCodewords(buffer, version, errorCorrectionLevel)
34182
+ }
34183
+
34184
+ /**
34185
+ * Encode input data with Reed-Solomon and return codewords with
34186
+ * relative error correction bits
34187
+ *
34188
+ * @param {BitBuffer} bitBuffer Data to encode
34189
+ * @param {Number} version QR Code version
34190
+ * @param {ErrorCorrectionLevel} errorCorrectionLevel Error correction level
34191
+ * @return {Uint8Array} Buffer containing encoded codewords
34192
+ */
34193
+ function createCodewords (bitBuffer, version, errorCorrectionLevel) {
34194
+ // Total codewords for this QR code version (Data + Error correction)
34195
+ const totalCodewords = Utils.getSymbolTotalCodewords(version);
34196
+
34197
+ // Total number of error correction codewords
34198
+ const ecTotalCodewords = ECCode.getTotalCodewordsCount(version, errorCorrectionLevel);
34199
+
34200
+ // Total number of data codewords
34201
+ const dataTotalCodewords = totalCodewords - ecTotalCodewords;
34202
+
34203
+ // Total number of blocks
34204
+ const ecTotalBlocks = ECCode.getBlocksCount(version, errorCorrectionLevel);
34205
+
34206
+ // Calculate how many blocks each group should contain
34207
+ const blocksInGroup2 = totalCodewords % ecTotalBlocks;
34208
+ const blocksInGroup1 = ecTotalBlocks - blocksInGroup2;
34209
+
34210
+ const totalCodewordsInGroup1 = Math.floor(totalCodewords / ecTotalBlocks);
34211
+
34212
+ const dataCodewordsInGroup1 = Math.floor(dataTotalCodewords / ecTotalBlocks);
34213
+ const dataCodewordsInGroup2 = dataCodewordsInGroup1 + 1;
34214
+
34215
+ // Number of EC codewords is the same for both groups
34216
+ const ecCount = totalCodewordsInGroup1 - dataCodewordsInGroup1;
34217
+
34218
+ // Initialize a Reed-Solomon encoder with a generator polynomial of degree ecCount
34219
+ const rs = new ReedSolomonEncoder(ecCount);
34220
+
34221
+ let offset = 0;
34222
+ const dcData = new Array(ecTotalBlocks);
34223
+ const ecData = new Array(ecTotalBlocks);
34224
+ let maxDataSize = 0;
34225
+ const buffer = new Uint8Array(bitBuffer.buffer);
34226
+
34227
+ // Divide the buffer into the required number of blocks
34228
+ for (let b = 0; b < ecTotalBlocks; b++) {
34229
+ const dataSize = b < blocksInGroup1 ? dataCodewordsInGroup1 : dataCodewordsInGroup2;
34230
+
34231
+ // extract a block of data from buffer
34232
+ dcData[b] = buffer.slice(offset, offset + dataSize);
34233
+
34234
+ // Calculate EC codewords for this data block
34235
+ ecData[b] = rs.encode(dcData[b]);
34236
+
34237
+ offset += dataSize;
34238
+ maxDataSize = Math.max(maxDataSize, dataSize);
34239
+ }
34240
+
34241
+ // Create final data
34242
+ // Interleave the data and error correction codewords from each block
34243
+ const data = new Uint8Array(totalCodewords);
34244
+ let index = 0;
34245
+ let i, r;
34246
+
34247
+ // Add data codewords
34248
+ for (i = 0; i < maxDataSize; i++) {
34249
+ for (r = 0; r < ecTotalBlocks; r++) {
34250
+ if (i < dcData[r].length) {
34251
+ data[index++] = dcData[r][i];
34252
+ }
34253
+ }
34254
+ }
34255
+
34256
+ // Apped EC codewords
34257
+ for (i = 0; i < ecCount; i++) {
34258
+ for (r = 0; r < ecTotalBlocks; r++) {
34259
+ data[index++] = ecData[r][i];
34260
+ }
34261
+ }
34262
+
34263
+ return data
34264
+ }
34265
+
34266
+ /**
34267
+ * Build QR Code symbol
34268
+ *
34269
+ * @param {String} data Input string
34270
+ * @param {Number} version QR Code version
34271
+ * @param {ErrorCorretionLevel} errorCorrectionLevel Error level
34272
+ * @param {MaskPattern} maskPattern Mask pattern
34273
+ * @return {Object} Object containing symbol data
34274
+ */
34275
+ function createSymbol (data, version, errorCorrectionLevel, maskPattern) {
34276
+ let segments;
34277
+
34278
+ if (Array.isArray(data)) {
34279
+ segments = Segments.fromArray(data);
34280
+ } else if (typeof data === 'string') {
34281
+ let estimatedVersion = version;
34282
+
34283
+ if (!estimatedVersion) {
34284
+ const rawSegments = Segments.rawSplit(data);
34285
+
34286
+ // Estimate best version that can contain raw splitted segments
34287
+ estimatedVersion = Version.getBestVersionForData(rawSegments, errorCorrectionLevel);
34288
+ }
34289
+
34290
+ // Build optimized segments
34291
+ // If estimated version is undefined, try with the highest version
34292
+ segments = Segments.fromString(data, estimatedVersion || 40);
34293
+ } else {
34294
+ throw new Error('Invalid data')
34295
+ }
34296
+
34297
+ // Get the min version that can contain data
34298
+ const bestVersion = Version.getBestVersionForData(segments, errorCorrectionLevel);
34299
+
34300
+ // If no version is found, data cannot be stored
34301
+ if (!bestVersion) {
34302
+ throw new Error('The amount of data is too big to be stored in a QR Code')
34303
+ }
34304
+
34305
+ // If not specified, use min version as default
34306
+ if (!version) {
34307
+ version = bestVersion;
34308
+
34309
+ // Check if the specified version can contain the data
34310
+ } else if (version < bestVersion) {
34311
+ throw new Error('\n' +
34312
+ 'The chosen QR Code version cannot contain this amount of data.\n' +
34313
+ 'Minimum version required to store current data is: ' + bestVersion + '.\n'
34314
+ )
34315
+ }
34316
+
34317
+ const dataBits = createData(version, errorCorrectionLevel, segments);
34318
+
34319
+ // Allocate matrix buffer
34320
+ const moduleCount = Utils.getSymbolSize(version);
34321
+ const modules = new BitMatrix(moduleCount);
34322
+
34323
+ // Add function modules
34324
+ setupFinderPattern(modules, version);
34325
+ setupTimingPattern(modules);
34326
+ setupAlignmentPattern(modules, version);
34327
+
34328
+ // Add temporary dummy bits for format info just to set them as reserved.
34329
+ // This is needed to prevent these bits from being masked by {@link MaskPattern.applyMask}
34330
+ // since the masking operation must be performed only on the encoding region.
34331
+ // These blocks will be replaced with correct values later in code.
34332
+ setupFormatInfo(modules, errorCorrectionLevel, 0);
34333
+
34334
+ if (version >= 7) {
34335
+ setupVersionInfo(modules, version);
34336
+ }
34337
+
34338
+ // Add data codewords
34339
+ setupData(modules, dataBits);
34340
+
34341
+ if (isNaN(maskPattern)) {
34342
+ // Find best mask pattern
34343
+ maskPattern = MaskPattern.getBestMask(modules,
34344
+ setupFormatInfo.bind(null, modules, errorCorrectionLevel));
34345
+ }
34346
+
34347
+ // Apply mask pattern
34348
+ MaskPattern.applyMask(maskPattern, modules);
34349
+
34350
+ // Replace format info bits with correct values
34351
+ setupFormatInfo(modules, errorCorrectionLevel, maskPattern);
34352
+
34353
+ return {
34354
+ modules: modules,
34355
+ version: version,
34356
+ errorCorrectionLevel: errorCorrectionLevel,
34357
+ maskPattern: maskPattern,
34358
+ segments: segments
34359
+ }
34360
+ }
34361
+
34362
+ /**
34363
+ * QR Code
34364
+ *
34365
+ * @param {String | Array} data Input data
34366
+ * @param {Object} options Optional configurations
34367
+ * @param {Number} options.version QR Code version
34368
+ * @param {String} options.errorCorrectionLevel Error correction level
34369
+ * @param {Function} options.toSJISFunc Helper func to convert utf8 to sjis
34370
+ */
34371
+ qrcode.create = function create (data, options) {
34372
+ if (typeof data === 'undefined' || data === '') {
34373
+ throw new Error('No input text')
34374
+ }
34375
+
34376
+ let errorCorrectionLevel = ECLevel.M;
34377
+ let version;
34378
+ let mask;
34379
+
34380
+ if (typeof options !== 'undefined') {
34381
+ // Use higher error correction level as default
34382
+ errorCorrectionLevel = ECLevel.from(options.errorCorrectionLevel, ECLevel.M);
34383
+ version = Version.from(options.version);
34384
+ mask = MaskPattern.from(options.maskPattern);
34385
+
34386
+ if (options.toSJISFunc) {
34387
+ Utils.setToSJISFunction(options.toSJISFunc);
34388
+ }
34389
+ }
34390
+
34391
+ return createSymbol(data, version, errorCorrectionLevel, mask)
34392
+ };
34393
+ return qrcode;
34394
+ }
34395
+
34396
+ var canvas = {};
34397
+
34398
+ var utils = {};
34399
+
34400
+ var hasRequiredUtils;
34401
+
34402
+ function requireUtils () {
34403
+ if (hasRequiredUtils) return utils;
34404
+ hasRequiredUtils = 1;
34405
+ (function (exports) {
34406
+ function hex2rgba (hex) {
34407
+ if (typeof hex === 'number') {
34408
+ hex = hex.toString();
34409
+ }
34410
+
34411
+ if (typeof hex !== 'string') {
34412
+ throw new Error('Color should be defined as hex string')
34413
+ }
34414
+
34415
+ let hexCode = hex.slice().replace('#', '').split('');
34416
+ if (hexCode.length < 3 || hexCode.length === 5 || hexCode.length > 8) {
34417
+ throw new Error('Invalid hex color: ' + hex)
34418
+ }
34419
+
34420
+ // Convert from short to long form (fff -> ffffff)
34421
+ if (hexCode.length === 3 || hexCode.length === 4) {
34422
+ hexCode = Array.prototype.concat.apply([], hexCode.map(function (c) {
34423
+ return [c, c]
34424
+ }));
34425
+ }
34426
+
34427
+ // Add default alpha value
34428
+ if (hexCode.length === 6) hexCode.push('F', 'F');
34429
+
34430
+ const hexValue = parseInt(hexCode.join(''), 16);
34431
+
34432
+ return {
34433
+ r: (hexValue >> 24) & 255,
34434
+ g: (hexValue >> 16) & 255,
34435
+ b: (hexValue >> 8) & 255,
34436
+ a: hexValue & 255,
34437
+ hex: '#' + hexCode.slice(0, 6).join('')
34438
+ }
34439
+ }
34440
+
34441
+ exports.getOptions = function getOptions (options) {
34442
+ if (!options) options = {};
34443
+ if (!options.color) options.color = {};
34444
+
34445
+ const margin = typeof options.margin === 'undefined' ||
34446
+ options.margin === null ||
34447
+ options.margin < 0
34448
+ ? 4
34449
+ : options.margin;
34450
+
34451
+ const width = options.width && options.width >= 21 ? options.width : undefined;
34452
+ const scale = options.scale || 4;
34453
+
34454
+ return {
34455
+ width: width,
34456
+ scale: width ? 4 : scale,
34457
+ margin: margin,
34458
+ color: {
34459
+ dark: hex2rgba(options.color.dark || '#000000ff'),
34460
+ light: hex2rgba(options.color.light || '#ffffffff')
34461
+ },
34462
+ type: options.type,
34463
+ rendererOpts: options.rendererOpts || {}
34464
+ }
34465
+ };
34466
+
34467
+ exports.getScale = function getScale (qrSize, opts) {
34468
+ return opts.width && opts.width >= qrSize + opts.margin * 2
34469
+ ? opts.width / (qrSize + opts.margin * 2)
34470
+ : opts.scale
34471
+ };
34472
+
34473
+ exports.getImageWidth = function getImageWidth (qrSize, opts) {
34474
+ const scale = exports.getScale(qrSize, opts);
34475
+ return Math.floor((qrSize + opts.margin * 2) * scale)
34476
+ };
34477
+
34478
+ exports.qrToImageData = function qrToImageData (imgData, qr, opts) {
34479
+ const size = qr.modules.size;
34480
+ const data = qr.modules.data;
34481
+ const scale = exports.getScale(size, opts);
34482
+ const symbolSize = Math.floor((size + opts.margin * 2) * scale);
34483
+ const scaledMargin = opts.margin * scale;
34484
+ const palette = [opts.color.light, opts.color.dark];
34485
+
34486
+ for (let i = 0; i < symbolSize; i++) {
34487
+ for (let j = 0; j < symbolSize; j++) {
34488
+ let posDst = (i * symbolSize + j) * 4;
34489
+ let pxColor = opts.color.light;
34490
+
34491
+ if (i >= scaledMargin && j >= scaledMargin &&
34492
+ i < symbolSize - scaledMargin && j < symbolSize - scaledMargin) {
34493
+ const iSrc = Math.floor((i - scaledMargin) / scale);
34494
+ const jSrc = Math.floor((j - scaledMargin) / scale);
34495
+ pxColor = palette[data[iSrc * size + jSrc] ? 1 : 0];
34496
+ }
34497
+
34498
+ imgData[posDst++] = pxColor.r;
34499
+ imgData[posDst++] = pxColor.g;
34500
+ imgData[posDst++] = pxColor.b;
34501
+ imgData[posDst] = pxColor.a;
34502
+ }
34503
+ }
34504
+ };
34505
+ } (utils));
34506
+ return utils;
34507
+ }
34508
+
34509
+ var hasRequiredCanvas;
34510
+
34511
+ function requireCanvas () {
34512
+ if (hasRequiredCanvas) return canvas;
34513
+ hasRequiredCanvas = 1;
34514
+ (function (exports) {
34515
+ const Utils = requireUtils();
34516
+
34517
+ function clearCanvas (ctx, canvas, size) {
34518
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
34519
+
34520
+ if (!canvas.style) canvas.style = {};
34521
+ canvas.height = size;
34522
+ canvas.width = size;
34523
+ canvas.style.height = size + 'px';
34524
+ canvas.style.width = size + 'px';
34525
+ }
34526
+
34527
+ function getCanvasElement () {
34528
+ try {
34529
+ return document.createElement('canvas')
34530
+ } catch (e) {
34531
+ throw new Error('You need to specify a canvas element')
34532
+ }
34533
+ }
34534
+
34535
+ exports.render = function render (qrData, canvas, options) {
34536
+ let opts = options;
34537
+ let canvasEl = canvas;
34538
+
34539
+ if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {
34540
+ opts = canvas;
34541
+ canvas = undefined;
34542
+ }
34543
+
34544
+ if (!canvas) {
34545
+ canvasEl = getCanvasElement();
34546
+ }
34547
+
34548
+ opts = Utils.getOptions(opts);
34549
+ const size = Utils.getImageWidth(qrData.modules.size, opts);
34550
+
34551
+ const ctx = canvasEl.getContext('2d');
34552
+ const image = ctx.createImageData(size, size);
34553
+ Utils.qrToImageData(image.data, qrData, opts);
34554
+
34555
+ clearCanvas(ctx, canvasEl, size);
34556
+ ctx.putImageData(image, 0, 0);
34557
+
34558
+ return canvasEl
34559
+ };
34560
+
34561
+ exports.renderToDataURL = function renderToDataURL (qrData, canvas, options) {
34562
+ let opts = options;
34563
+
34564
+ if (typeof opts === 'undefined' && (!canvas || !canvas.getContext)) {
34565
+ opts = canvas;
34566
+ canvas = undefined;
34567
+ }
34568
+
34569
+ if (!opts) opts = {};
34570
+
34571
+ const canvasEl = exports.render(qrData, canvas, opts);
34572
+
34573
+ const type = opts.type || 'image/png';
34574
+ const rendererOpts = opts.rendererOpts || {};
34575
+
34576
+ return canvasEl.toDataURL(type, rendererOpts.quality)
34577
+ };
34578
+ } (canvas));
34579
+ return canvas;
34580
+ }
34581
+
34582
+ var svgTag = {};
34583
+
34584
+ var hasRequiredSvgTag;
34585
+
34586
+ function requireSvgTag () {
34587
+ if (hasRequiredSvgTag) return svgTag;
34588
+ hasRequiredSvgTag = 1;
34589
+ const Utils = requireUtils();
34590
+
34591
+ function getColorAttrib (color, attrib) {
34592
+ const alpha = color.a / 255;
34593
+ const str = attrib + '="' + color.hex + '"';
34594
+
34595
+ return alpha < 1
34596
+ ? str + ' ' + attrib + '-opacity="' + alpha.toFixed(2).slice(1) + '"'
34597
+ : str
34598
+ }
34599
+
34600
+ function svgCmd (cmd, x, y) {
34601
+ let str = cmd + x;
34602
+ if (typeof y !== 'undefined') str += ' ' + y;
34603
+
34604
+ return str
34605
+ }
34606
+
34607
+ function qrToPath (data, size, margin) {
34608
+ let path = '';
34609
+ let moveBy = 0;
34610
+ let newRow = false;
34611
+ let lineLength = 0;
34612
+
34613
+ for (let i = 0; i < data.length; i++) {
34614
+ const col = Math.floor(i % size);
34615
+ const row = Math.floor(i / size);
34616
+
34617
+ if (!col && !newRow) newRow = true;
34618
+
34619
+ if (data[i]) {
34620
+ lineLength++;
34621
+
34622
+ if (!(i > 0 && col > 0 && data[i - 1])) {
34623
+ path += newRow
34624
+ ? svgCmd('M', col + margin, 0.5 + row + margin)
34625
+ : svgCmd('m', moveBy, 0);
34626
+
34627
+ moveBy = 0;
34628
+ newRow = false;
34629
+ }
34630
+
34631
+ if (!(col + 1 < size && data[i + 1])) {
34632
+ path += svgCmd('h', lineLength);
34633
+ lineLength = 0;
34634
+ }
34635
+ } else {
34636
+ moveBy++;
34637
+ }
34638
+ }
34639
+
34640
+ return path
34641
+ }
34642
+
34643
+ svgTag.render = function render (qrData, options, cb) {
34644
+ const opts = Utils.getOptions(options);
34645
+ const size = qrData.modules.size;
34646
+ const data = qrData.modules.data;
34647
+ const qrcodesize = size + opts.margin * 2;
34648
+
34649
+ const bg = !opts.color.light.a
34650
+ ? ''
34651
+ : '<path ' + getColorAttrib(opts.color.light, 'fill') +
34652
+ ' d="M0 0h' + qrcodesize + 'v' + qrcodesize + 'H0z"/>';
34653
+
34654
+ const path =
34655
+ '<path ' + getColorAttrib(opts.color.dark, 'stroke') +
34656
+ ' d="' + qrToPath(data, size, opts.margin) + '"/>';
34657
+
34658
+ const viewBox = 'viewBox="' + '0 0 ' + qrcodesize + ' ' + qrcodesize + '"';
34659
+
34660
+ const width = !opts.width ? '' : 'width="' + opts.width + '" height="' + opts.width + '" ';
34661
+
34662
+ const svgTag = '<svg xmlns="http://www.w3.org/2000/svg" ' + width + viewBox + ' shape-rendering="crispEdges">' + bg + path + '</svg>\n';
34663
+
34664
+ if (typeof cb === 'function') {
34665
+ cb(null, svgTag);
34666
+ }
34667
+
34668
+ return svgTag
34669
+ };
34670
+ return svgTag;
34671
+ }
34672
+
34673
+ var hasRequiredBrowser;
34674
+
34675
+ function requireBrowser () {
34676
+ if (hasRequiredBrowser) return browser;
34677
+ hasRequiredBrowser = 1;
34678
+ const canPromise = requireCanPromise();
34679
+
34680
+ const QRCode = requireQrcode();
34681
+ const CanvasRenderer = requireCanvas();
34682
+ const SvgRenderer = requireSvgTag();
34683
+
34684
+ function renderCanvas (renderFunc, canvas, text, opts, cb) {
34685
+ const args = [].slice.call(arguments, 1);
34686
+ const argsNum = args.length;
34687
+ const isLastArgCb = typeof args[argsNum - 1] === 'function';
34688
+
34689
+ if (!isLastArgCb && !canPromise()) {
34690
+ throw new Error('Callback required as last argument')
34691
+ }
34692
+
34693
+ if (isLastArgCb) {
34694
+ if (argsNum < 2) {
34695
+ throw new Error('Too few arguments provided')
34696
+ }
34697
+
34698
+ if (argsNum === 2) {
34699
+ cb = text;
34700
+ text = canvas;
34701
+ canvas = opts = undefined;
34702
+ } else if (argsNum === 3) {
34703
+ if (canvas.getContext && typeof cb === 'undefined') {
34704
+ cb = opts;
34705
+ opts = undefined;
34706
+ } else {
34707
+ cb = opts;
34708
+ opts = text;
34709
+ text = canvas;
34710
+ canvas = undefined;
34711
+ }
34712
+ }
34713
+ } else {
34714
+ if (argsNum < 1) {
34715
+ throw new Error('Too few arguments provided')
34716
+ }
34717
+
34718
+ if (argsNum === 1) {
34719
+ text = canvas;
34720
+ canvas = opts = undefined;
34721
+ } else if (argsNum === 2 && !canvas.getContext) {
34722
+ opts = text;
34723
+ text = canvas;
34724
+ canvas = undefined;
34725
+ }
34726
+
34727
+ return new Promise(function (resolve, reject) {
34728
+ try {
34729
+ const data = QRCode.create(text, opts);
34730
+ resolve(renderFunc(data, canvas, opts));
34731
+ } catch (e) {
34732
+ reject(e);
34733
+ }
34734
+ })
34735
+ }
34736
+
34737
+ try {
34738
+ const data = QRCode.create(text, opts);
34739
+ cb(null, renderFunc(data, canvas, opts));
34740
+ } catch (e) {
34741
+ cb(e);
34742
+ }
34743
+ }
34744
+
34745
+ browser.create = QRCode.create;
34746
+ browser.toCanvas = renderCanvas.bind(null, CanvasRenderer.render);
34747
+ browser.toDataURL = renderCanvas.bind(null, CanvasRenderer.renderToDataURL);
34748
+
34749
+ // only svg for now.
34750
+ browser.toString = renderCanvas.bind(null, function (data, _, opts) {
34751
+ return SvgRenderer.render(data, opts)
34752
+ });
34753
+ return browser;
34754
+ }
34755
+
34756
+ var browserExports = requireBrowser();
34757
+ var QRCode = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
34758
+
34759
+ const kritzelShareDialogCss = () => `:host{display:contents}kritzel-dialog{--kritzel-dialog-width-small:420px}.share-content{display:flex;flex-direction:column;gap:20px}.share-section{display:flex;flex-direction:column;gap:8px}.share-section-revoke{padding-top:12px;border-top:1px solid var(--kritzel-share-dialog-border-color, #e5e5e5)}.share-row{display:flex;align-items:center;justify-content:space-between;gap:16px}.share-label-group{display:flex;flex-direction:column;gap:8px;flex:1}.share-label{font-size:14px;font-weight:600;color:var(--kritzel-share-dialog-label-color, #333333);margin:0}.share-description{font-size:12px;color:var(--kritzel-share-dialog-description-color, #666666);margin:0;line-height:1.4}.share-url-container{display:flex;align-items:center;gap:8px;background:var(--kritzel-share-dialog-input-background, #f5f5f5);border:1px solid var(--kritzel-share-dialog-input-border-color, #e0e0e0);border-radius:6px;padding:4px 4px 4px 12px}.share-qr-container{display:flex;justify-content:center;margin-top:16px;margin-bottom:16px}.share-qr-image{width:180px;height:180px;border-radius:8px;border:1px solid var(--kritzel-share-dialog-qr-border-color, #e0e0e0);background:var(--kritzel-share-dialog-qr-background, #ffffff);padding:8px;box-sizing:border-box}.share-url-input{flex:1;border:none;background:transparent;font-size:13px;color:var(--kritzel-share-dialog-input-text-color, #333333);outline:none;min-width:0;padding:8px 0}.share-url-input:focus{outline:none}.share-url-input::selection{background:var(--kritzel-share-dialog-selection-color, #cce5ff)}.copy-button{display:flex;align-items:center;justify-content:center;width:36px;height:36px;border:none;border-radius:4px;background:var(--kritzel-share-dialog-copy-button-background, #ffffff);color:var(--kritzel-share-dialog-copy-button-color, #666666);cursor:pointer;transition:all 0.15s ease;flex-shrink:0}.copy-button:hover{background:var(--kritzel-share-dialog-copy-button-hover-background, #e8e8e8);color:var(--kritzel-share-dialog-copy-button-hover-color, #333333)}.copy-button.copy-success{background:var(--kritzel-share-dialog-copy-success-background, #d4edda);color:var(--kritzel-share-dialog-copy-success-color, #28a745)}.revoke-button{align-self:flex-start;padding:8px 16px;border:1px solid var(--kritzel-share-dialog-revoke-button-border-color, #dc3545);border-radius:6px;background:transparent;color:var(--kritzel-share-dialog-revoke-button-color, #dc3545);font-size:13px;font-weight:500;cursor:pointer;transition:all 0.15s ease}.revoke-button:hover{background:var(--kritzel-share-dialog-revoke-button-hover-background, #dc3545);color:var(--kritzel-share-dialog-revoke-button-hover-color, #ffffff)}kritzel-dropdown{--kritzel-dropdown-trigger-padding:8px 12px;--kritzel-dropdown-trigger-font-size:13px}`;
31653
34760
 
31654
34761
  const KritzelShareDialog = class {
31655
34762
  constructor(hostRef) {
@@ -31670,10 +34777,16 @@ const KritzelShareDialog = class {
31670
34777
  terms = {};
31671
34778
  onIsPublicChange(newValue) {
31672
34779
  this.internalIsPublic = newValue;
34780
+ void this.updateQrCodeDataUrl();
34781
+ }
34782
+ onWorkspaceIdChange() {
34783
+ void this.updateQrCodeDataUrl();
31673
34784
  }
31674
34785
  isDialogOpen = false;
31675
34786
  internalIsPublic = false;
31676
34787
  copySuccess = false;
34788
+ qrCodeDataUrl = '';
34789
+ qrCodeUpdateSequence = 0;
31677
34790
  /**
31678
34791
  * Emitted when the user toggles the public sharing state.
31679
34792
  */
@@ -31688,6 +34801,7 @@ const KritzelShareDialog = class {
31688
34801
  async open() {
31689
34802
  this.internalIsPublic = this.isPublic;
31690
34803
  this.isDialogOpen = true;
34804
+ await this.updateQrCodeDataUrl();
31691
34805
  }
31692
34806
  /**
31693
34807
  * Closes the share dialog.
@@ -31699,8 +34813,37 @@ const KritzelShareDialog = class {
31699
34813
  const enabled = event.detail;
31700
34814
  // Update local state optimistically for immediate UI feedback
31701
34815
  this.internalIsPublic = enabled;
34816
+ void this.updateQrCodeDataUrl();
31702
34817
  this.toggleIsPublic.emit(enabled);
31703
34818
  };
34819
+ async updateQrCodeDataUrl() {
34820
+ if (!this.internalIsPublic) {
34821
+ this.qrCodeDataUrl = '';
34822
+ return;
34823
+ }
34824
+ const shareUrl = this.getShareUrl();
34825
+ if (!shareUrl) {
34826
+ this.qrCodeDataUrl = '';
34827
+ return;
34828
+ }
34829
+ const sequence = ++this.qrCodeUpdateSequence;
34830
+ try {
34831
+ const dataUrl = await QRCode.toDataURL(shareUrl, {
34832
+ margin: 1,
34833
+ width: 180,
34834
+ });
34835
+ if (sequence !== this.qrCodeUpdateSequence) {
34836
+ return;
34837
+ }
34838
+ this.qrCodeDataUrl = dataUrl;
34839
+ }
34840
+ catch {
34841
+ if (sequence !== this.qrCodeUpdateSequence) {
34842
+ return;
34843
+ }
34844
+ this.qrCodeDataUrl = '';
34845
+ }
34846
+ }
31704
34847
  getShareUrl() {
31705
34848
  if (!this.workspaceId)
31706
34849
  return '';
@@ -31738,13 +34881,16 @@ const KritzelShareDialog = class {
31738
34881
  this.dialogClosed.emit();
31739
34882
  };
31740
34883
  render() {
31741
- return (h(Host, { key: '031cf5d1ab48f2791454d4c7348352295359d225' }, h("kritzel-dialog", { key: 'cdce63c86ca329a97d1f1787adcb2b92bbfa40f9', dialogTitle: this.terms['share.dialogTitle'] ?? 'Share Workspace', size: "small", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, contained: true }, h("div", { key: 'dbb62b3cb175358955b11f6c2d74b0b0eecf212e', class: "share-content" }, h("div", { key: '8dc0eaea9644b60ff33812dac20def226fa14232', class: "share-section" }, h("div", { key: 'd3cfbf05c28a01681b1223edb6f0b73998ccfd08', class: "share-row" }, h("div", { key: '2400f062f92dd918341391cf71086c2676f7fc66', class: "share-label-group" }, h("label", { key: 'ab01691b9f53f59f92116a2994b6e3551d347c7b', class: "share-label" }, this.terms['share.linkSharing.label'] ?? 'Link sharing'), h("p", { key: 'fd830ad21e32e4fc5d8ba97d5cea7ef8da15fba4', class: "share-description" }, this.internalIsPublic
34884
+ return (h(Host, { key: 'b96c4cc6a9e4778715f496574f307a540285f70c' }, h("kritzel-dialog", { key: '9a9cead56cc50042f59f677c0a846fc9fff01a8b', dialogTitle: this.terms['share.dialogTitle'] ?? 'Share Workspace', size: "small", isOpen: this.isDialogOpen, onDialogClose: this.closeDialog, contained: true }, h("div", { key: 'f1ffe37126343d84f9cb70f85530596d594c6e04', class: "share-content" }, h("div", { key: 'e1b20fccdb127eb30d240a2812742977b6512113', class: "share-section" }, h("div", { key: 'fb0d4226d638309fd5696dace0cc0c73d82150fc', class: "share-row" }, h("div", { key: '301a27b975bb63610d94e1140aef39aa0594dda6', class: "share-label-group" }, h("label", { key: 'acf694843423d42414951ae88ec7eee541dd8f7f', class: "share-label" }, this.terms['share.linkSharing.label'] ?? 'Link sharing'), h("p", { key: '4c29b6448a27c69fceadb4166bc878216010475f', class: "share-description" }, this.internalIsPublic
31742
34885
  ? (this.terms['share.linkSharing.enabledDescription'] ?? 'Anyone with the link can access this workspace.')
31743
- : (this.terms['share.linkSharing.disabledDescription'] ?? 'Link sharing is disabled. Only you can access this workspace.'))), h("kritzel-slide-toggle", { key: '6f1a71ba524b34753ccd5437eab00bfcbeffdd79', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: this.terms['share.linkSharing.toggleLabel'] ?? 'Enable link sharing' }))), this.internalIsPublic && (h("div", { key: '298680e1afdf0094c5393aa95c4983a0a8dd5e18', class: "share-section" }, h("div", { key: '546645a748cf9a42df0c8163f2478ef31445273a', class: "share-url-container" }, h("input", { key: '9d5b93d762d1cd899f3fc8041380bae603a4919c', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), h("button", { key: '747a7ca4a25827de6934b7df30cabc2db4583e1b', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? (this.terms['share.copyLink.copied'] ?? 'Copied!') : (this.terms['share.copyLink.title'] ?? 'Copy link') }, h("kritzel-icon", { key: '096ca9a0527796462769dc9d42dd81d8f97f2865', name: this.copySuccess ? 'check' : 'copy', size: 18 })))))))));
34886
+ : (this.terms['share.linkSharing.disabledDescription'] ?? 'Link sharing is disabled. Only you can access this workspace.'))), h("kritzel-slide-toggle", { key: 'c813213e7cf53125993de209e15c921779c019b6', checked: this.internalIsPublic, onCheckedChange: this.handleToggleChange, label: this.terms['share.linkSharing.toggleLabel'] ?? 'Enable link sharing' }))), this.internalIsPublic && (h("div", { key: 'af32cbadc775ce4ca3c79bdc0f8b4351c8723b28', class: "share-section" }, h("div", { key: 'd5c4e2b8a77306a141cc73c37dc6c57b1dc9daa5', class: "share-url-container" }, h("input", { key: 'f2f364c3fabd7f693247f5ad05594bd089a194ea', type: "text", class: "share-url-input", value: this.getShareUrl(), readOnly: true, onClick: (e) => e.target.select() }), h("button", { key: 'd27a6f00e6b14bff3f4c8d1694cc8a38eebc5ec0', class: { 'copy-button': true, 'copy-success': this.copySuccess }, onClick: this.handleCopyUrl, title: this.copySuccess ? (this.terms['share.copyLink.copied'] ?? 'Copied!') : (this.terms['share.copyLink.title'] ?? 'Copy link') }, h("kritzel-icon", { key: '60c72ee8d789dc14baa4c169f70c78837b0cbd0c', name: this.copySuccess ? 'check' : 'copy', size: 18 }))), this.qrCodeDataUrl && (h("div", { key: 'f5d361b7ed145ab5f4f7b89f9c63046ce831220b', class: "share-qr-container" }, h("img", { key: '5f2d4650dffab907f5a53dfb2fd4c337da3e51ee', class: "share-qr-image", src: this.qrCodeDataUrl, alt: "QR code for share link" })))))))));
31744
34887
  }
31745
34888
  static get watchers() { return {
31746
34889
  "isPublic": [{
31747
34890
  "onIsPublicChange": 0
34891
+ }],
34892
+ "workspaceId": [{
34893
+ "onWorkspaceIdChange": 0
31748
34894
  }]
31749
34895
  }; }
31750
34896
  };
@@ -31778,7 +34924,7 @@ const KritzelSlideToggle = class {
31778
34924
  }
31779
34925
  };
31780
34926
  render() {
31781
- return (h(Host, { key: '5850c758ccf3263b21c397219bf2301fa088087d', class: { checked: this.checked, disabled: this.disabled }, tabIndex: this.disabled ? -1 : 0, role: "switch", "aria-checked": this.checked ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.label, onClick: this.handleToggle, onKeyDown: this.handleKeyDown }, h("div", { key: 'df0adeca0447a13d5499219ac9d27b526252fdbe', class: "toggle-track" }, h("div", { key: '3938239bbdca29e62ed72229dfcf1904fcbaa983', class: "toggle-thumb" }))));
34927
+ return (h(Host, { key: '00160c9cfdafa0d53f3acfb1fb235b29abf2622a', class: { checked: this.checked, disabled: this.disabled }, tabIndex: this.disabled ? -1 : 0, role: "switch", "aria-checked": this.checked ? 'true' : 'false', "aria-disabled": this.disabled ? 'true' : 'false', "aria-label": this.label, onClick: this.handleToggle, onKeyDown: this.handleKeyDown }, h("div", { key: '385008948ffbdc0f26249d2d833aae8f04eeb6a0', class: "toggle-track" }, h("div", { key: '43929e94335589feb24ee45f1c34a270653dd412', class: "toggle-thumb" }))));
31782
34928
  }
31783
34929
  };
31784
34930
  KritzelSlideToggle.style = kritzelSlideToggleCss();
@@ -31878,7 +35024,7 @@ const KritzelSplitButton = class {
31878
35024
  this.menuScrollTop = event.target.scrollTop;
31879
35025
  };
31880
35026
  render() {
31881
- return (h(Host, { key: 'd6856a86b3be4d9a22c5e78df1bda19113cb988b', class: { mobile: this.isTouchDevice } }, h("button", { key: 'd26026af275a8bd5717254223d5829e3d7f02bcb', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.mainButtonDisabled, "aria-label": "Main action" }, this.buttonIcon && h("kritzel-icon", { key: '1b3e2f4c2f8245b281d0f85458fd6bcc0cc73c59', name: this.buttonIcon })), h("div", { key: 'b002b904e168d62075fa086c88df72e36cc8e8c2', class: "split-divider" }), h("button", { key: 'd39084da6775613f2c896f3fa1ae4e216505bacc', ref: el => (this.splitMenuButtonRef = el), class: "split-menu-button", tabIndex: 0, onClick: this.toggleMenu, disabled: this.menuButtonDisabled, "aria-label": "Open menu" }, h("kritzel-icon", { key: 'b1bc427b0d7cd26a283dbeb772dee0a6d2ca172c', name: this.dropdownIcon })), h("kritzel-portal", { key: 'e76300f48a23772a5923ea2cbd0824590302e7e7', anchor: this.anchorElement, offsetY: 4, onClose: this.closeMenu }, h("kritzel-menu", { key: 'f110b9315ec63dca9bb1b615136b2d3e284567ba', ref: el => (this.menuRef = el), items: this.items, onItemSelect: this.handleItemSelect, onItemSave: this.handleItemSave, onItemCancel: this.handleItemCancel, onItemToggleChildMenu: this.handleItemToggleChildMenu, onItemCloseChildMenu: this.handleItemCloseChildMenu, onClose: this.closeMenu, onScroll: this.handleScroll }))));
35027
+ return (h(Host, { key: 'fa22dc1185ef07d8127d9ee9f6dbe482d126f934', class: { mobile: this.isTouchDevice } }, h("button", { key: 'a48aba702b70e9b24ad5486dde61fa9f9c8f7cdc', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.mainButtonDisabled, "aria-label": "Main action" }, this.buttonIcon && h("kritzel-icon", { key: '0d1c9a3e9f744541dd6ebe491105f6ee65233543', name: this.buttonIcon })), h("div", { key: 'c9db29f0b9c9cf1974d78f4f60be9e1b0e26c5d2', class: "split-divider" }), h("button", { key: '57addfd5228b7c7668be902c53683d12c976b89b', ref: el => (this.splitMenuButtonRef = el), class: "split-menu-button", tabIndex: 0, onClick: this.toggleMenu, disabled: this.menuButtonDisabled, "aria-label": "Open menu" }, h("kritzel-icon", { key: 'd860cc503043425860b1234b5d34693bfdd1d5ab', name: this.dropdownIcon })), h("kritzel-portal", { key: 'cd6dda8869aea4205d922fc639073019bbd2b102', anchor: this.anchorElement, offsetY: 4, onClose: this.closeMenu }, h("kritzel-menu", { key: '1ef1c2b319662e7a2af15b46362addcc75bceb68', ref: el => (this.menuRef = el), items: this.items, onItemSelect: this.handleItemSelect, onItemSave: this.handleItemSave, onItemCancel: this.handleItemCancel, onItemToggleChildMenu: this.handleItemToggleChildMenu, onItemCloseChildMenu: this.handleItemCloseChildMenu, onClose: this.closeMenu, onScroll: this.handleScroll }))));
31882
35028
  }
31883
35029
  };
31884
35030
  KritzelSplitButton.style = kritzelSplitButtonCss();
@@ -31899,7 +35045,7 @@ const KritzelStrokeSize = class {
31899
35045
  }
31900
35046
  render() {
31901
35047
  const sizes = this.sizes ?? [];
31902
- return (h(Host, { key: 'bde2cc986aebbe869a3eea026654229dee0d3e0e' }, h("div", { key: 'f84c4b844b865080f4e0e245bbccc6d77ac3f049', class: "size-grid" }, sizes.map(size => (h("div", { tabIndex: 0, class: {
35048
+ return (h(Host, { key: 'ba181d798d2bf7b60308746635d2077ce1353b83' }, h("div", { key: '048fc8934190359b9337747567844ca88925a6ce', class: "size-grid" }, sizes.map(size => (h("div", { tabIndex: 0, class: {
31903
35049
  'size-container': true,
31904
35050
  'selected': this.selectedSize === size,
31905
35051
  }, onClick: () => this.handleSizeClick(size) }, h("kritzel-color", { value: 'var(--kritzel-global-text-primary)', size: size })))))));
@@ -32280,14 +35426,14 @@ const KritzelTooltip = class {
32280
35426
  }
32281
35427
  }
32282
35428
  render() {
32283
- return (h(Host, { key: 'ba4d13171aa25acac6c615ee12f35eab96d0aad6', style: {
35429
+ return (h(Host, { key: '1e318ff48b72ae5e0853a92c61fd4174d6e45271', style: {
32284
35430
  position: 'fixed',
32285
35431
  zIndex: '9999',
32286
35432
  transition: 'opacity 0.3s ease-in-out, transform 0.3s ease-in-out',
32287
35433
  visibility: this.isVisible ? 'visible' : 'hidden',
32288
35434
  left: `${this.positionX}px`,
32289
35435
  bottom: `${this.positionY}px`,
32290
- } }, h("div", { key: '923168164a018b08eac4246d88c7f8648b71d078', class: "tooltip-content", onClick: event => event.stopPropagation(), onPointerDown: event => event.stopPropagation(), onMouseDown: event => event.stopPropagation() }, h("slot", { key: 'aafad8ab026d591ebb9e2aeffa15d07718eba261' }))));
35436
+ } }, h("div", { key: 'c66c9978787c59de6ca29944f666354fed2ab4c3', class: "tooltip-content", onClick: event => event.stopPropagation(), onPointerDown: event => event.stopPropagation(), onMouseDown: event => event.stopPropagation() }, h("slot", { key: '664e78076bb988b0829b805aad4393c443db2dc7' }))));
32291
35437
  }
32292
35438
  static get watchers() { return {
32293
35439
  "triggerElement": [{
@@ -32328,7 +35474,7 @@ const KritzelUtilityPanel = class {
32328
35474
  this.redo.emit();
32329
35475
  }
32330
35476
  render() {
32331
- return (h(Host, { key: '22f3826d57b4d8f0e476951a860bde3dbc6c7200' }, h("button", { key: 'c3259c5e924b3cf74920dc4676ec8a682c3273e8', class: "utility-button", "data-testid": "utility-undo", disabled: !this.undoState?.canUndo, onClick: event => this.handleUndo(event), "aria-label": this.terms['utility.undo'] ?? 'Undo' }, h("kritzel-icon", { key: 'ab4e9da6b60d9fa470fd8f5002f2acd5a758a8ba', name: "undo" })), h("button", { key: 'd17e25e78831b5ee13596cc2639cfbb5bd75a1cb', class: "utility-button", "data-testid": "utility-redo", disabled: !this.undoState?.canRedo, onClick: event => this.handleRedo(event), "aria-label": this.terms['utility.redo'] ?? 'Redo' }, h("kritzel-icon", { key: '7ae8cec39ffab1303d76315ab85ac575b886b233', name: "redo" })), h("div", { key: 'f54e0262f133ad0eed0bbf853b67edd6c2f5e87f', class: "utility-separator" }), h("button", { key: '162d6e85965338b5700e661595dc6da6131ebccf', class: "utility-button", "data-testid": "utility-delete", onClick: () => this.delete.emit(), "aria-label": this.terms['utility.delete'] ?? 'Delete selected items' }, h("kritzel-icon", { key: 'dc00247ed45f09b86ad9314395f56e70d1122a4b', name: "delete" }))));
35477
+ return (h(Host, { key: '90b96b2f4693016650394e085c1ccf5c61759713' }, h("button", { key: '325e3a869061ce7fda2d86e74250f4ea7414da8e', class: "utility-button", "data-testid": "utility-undo", disabled: !this.undoState?.canUndo, onClick: event => this.handleUndo(event), "aria-label": this.terms['utility.undo'] ?? 'Undo' }, h("kritzel-icon", { key: '70335427bc3a9a54a994ad22935bde4010d8f96b', name: "undo" })), h("button", { key: 'cf3000675d594ffe64f947b57e5aabe084be32a7', class: "utility-button", "data-testid": "utility-redo", disabled: !this.undoState?.canRedo, onClick: event => this.handleRedo(event), "aria-label": this.terms['utility.redo'] ?? 'Redo' }, h("kritzel-icon", { key: 'b33336374abb36a7cdb685fb970805ec1f4073e2', name: "redo" })), h("div", { key: '34323fd33574ba65c825687fec5b772facbd2c62', class: "utility-separator" }), h("button", { key: 'aff157ab166ed15b8f9172b5b63f62996ed51c6e', class: "utility-button", "data-testid": "utility-delete", onClick: () => this.delete.emit(), "aria-label": this.terms['utility.delete'] ?? 'Delete selected items' }, h("kritzel-icon", { key: '413104d9d493fc47ad5ae8e61af514dfd530f6ee', name: "delete" }))));
32332
35478
  }
32333
35479
  };
32334
35480
  KritzelUtilityPanel.style = kritzelUtilityPanelCss();
@@ -32349,7 +35495,7 @@ const KritzelWatermark = class {
32349
35495
  label;
32350
35496
  render() {
32351
35497
  const label = this.label ?? this.core.localizationManager.translate('watermark.poweredBy');
32352
- return (h(Host, { key: '975534180d82064e38fa0289a2955e97a4ca0a08' }, h("a", { key: 'c59723d1f5bf3089256c0b610d0574bfc385ef85', class: "watermark-link", href: KRITZEL_WEBSITE_URL, target: "_blank", rel: "noopener noreferrer", part: "watermark", onPointerDown: (ev) => ev.stopPropagation(), onPointerUp: (ev) => ev.stopPropagation() }, label)));
35498
+ return (h(Host, { key: '0eccc75e51c7ac199e23d8f3a871593f1fb65a17' }, h("a", { key: '2029f8b56ba8609ca621447eac0df9d30ebfbbbe', class: "watermark-link", href: KRITZEL_WEBSITE_URL, target: "_blank", rel: "noopener noreferrer", part: "watermark", onPointerDown: (ev) => ev.stopPropagation(), onPointerUp: (ev) => ev.stopPropagation() }, label)));
32353
35499
  }
32354
35500
  };
32355
35501
  KritzelWatermark.style = kritzelWatermarkCss();
@@ -32537,9 +35683,9 @@ const KritzelZoomPanel = class {
32537
35683
  return Number.isFinite(this.zoomPercent) ? Math.max(1, Math.round(this.zoomPercent)) : 100;
32538
35684
  }
32539
35685
  render() {
32540
- return (h(Host, { key: '00d5c674581d4efa40da3a2ad5cbdd8295406590' }, h("div", { key: 'c7a4158f57b8062f37ee69f7b198442ec357d746', class: { panel: true, visible: this.visible } }, h("button", { key: 'e20344f5e522d481185a9dab7afdb2668cf44408', class: "zoom-button", type: "button", "aria-label": this.terms['zoom.zoomOut'] ?? 'Zoom out', disabled: this.disabled, onClick: this.handleZoomOut }, h("kritzel-icon", { key: '4fc1eeb78669894b0939a96c5e6945cea5056ac1', name: "minus" })), h("span", { key: 'ed26096e2ca76fe91b50d73ea6c9481996d01590', class: "zoom-level", "aria-live": "polite" }, this.normalizedZoomPercent, "%"), h("button", { key: '42609c6e8558b7d9e9e348b864639ead6c4cc9bb', class: "zoom-button", type: "button", "aria-label": this.terms['zoom.zoomIn'] ?? 'Zoom in', disabled: this.disabled, onClick: this.handleZoomIn }, h("kritzel-icon", { key: '3a321afb57f532ef867bae73751314f3fd355214', name: "plus" })))));
35686
+ return (h(Host, { key: '56b65a376d4bd94553416e07f2621192c4457bc2' }, h("div", { key: 'bdbfea3b3ee7e37eeb5c5f03388eb92ed8af9962', class: { panel: true, visible: this.visible } }, h("button", { key: 'de5ad152aaf7965f731bee95170b67e62af94ea2', class: "zoom-button", type: "button", "aria-label": this.terms['zoom.zoomOut'] ?? 'Zoom out', disabled: this.disabled, onClick: this.handleZoomOut }, h("kritzel-icon", { key: '104eb632666c55c032a40e6df2097aaa643fd23b', name: "minus" })), h("span", { key: 'd601b324e26a6c2737138b8f151b13dcdb2d20ab', class: "zoom-level", "aria-live": "polite" }, this.normalizedZoomPercent, "%"), h("button", { key: 'c976d03c69978f2d5cedf2a94b38419ed81088f6', class: "zoom-button", type: "button", "aria-label": this.terms['zoom.zoomIn'] ?? 'Zoom in', disabled: this.disabled, onClick: this.handleZoomIn }, h("kritzel-icon", { key: '844105bd53f3307425789aa6baf0ac3c25407414', name: "plus" })))));
32541
35687
  }
32542
35688
  };
32543
35689
  KritzelZoomPanel.style = kritzelZoomPanelCss();
32544
35690
 
32545
- export { KritzelActiveUsers as kritzel_active_users, KritzelAvatar as kritzel_avatar, KritzelAwarenessCursors as kritzel_awareness_cursors, KritzelBackToContent as kritzel_back_to_content, KritzelButton as kritzel_button, KritzelColorComponent as kritzel_color, KritzelColorPalette as kritzel_color_palette, KritzelContextMenu as kritzel_context_menu, KritzelControls as kritzel_controls, KritzelCurrentUser as kritzel_current_user, KritzelCurrentUserDialog as kritzel_current_user_dialog, KritzelCursorTrail as kritzel_cursor_trail, KritzelDialog as kritzel_dialog, KritzelDropdown as kritzel_dropdown, KritzelEditor as kritzel_editor, KritzelEngine as kritzel_engine, KritzelExport as kritzel_export, KritzelFont as kritzel_font, KritzelFontFamily as kritzel_font_family, KritzelFontSize as kritzel_font_size, KritzelIcon as kritzel_icon, KritzelInput as kritzel_input, KritzelLineEndings as kritzel_line_endings, KritzelLoginDialog as kritzel_login_dialog, KritzelMasterDetail as kritzel_master_detail, KritzelMenu as kritzel_menu, KritzelMenuItem as kritzel_menu_item, KritzelMoreMenu as kritzel_more_menu, KritzelNotificationCard as kritzel_notification_card, KritzelNumericInput as kritzel_numeric_input, KritzelOpacitySlider as kritzel_opacity_slider, KritzelPillTabs as kritzel_pill_tabs, KritzelPortal as kritzel_portal, KritzelSettings as kritzel_settings, KritzelShapeFill as kritzel_shape_fill, KritzelShareDialog as kritzel_share_dialog, KritzelSlideToggle as kritzel_slide_toggle, KritzelSplitButton as kritzel_split_button, KritzelStrokeSize as kritzel_stroke_size, KritzelToolConfig as kritzel_tool_config, KritzelTooltip as kritzel_tooltip, KritzelUtilityPanel as kritzel_utility_panel, KritzelWatermark as kritzel_watermark, KritzelWorkspaceManager as kritzel_workspace_manager, KritzelZoomPanel as kritzel_zoom_panel };
35691
+ export { KritzelActiveUsers as kritzel_active_users, KritzelAvatar as kritzel_avatar, KritzelAwarenessCursors as kritzel_awareness_cursors, KritzelBackToContent as kritzel_back_to_content, KritzelButton as kritzel_button, KritzelColorComponent as kritzel_color, KritzelColorPalette as kritzel_color_palette, KritzelContextMenu as kritzel_context_menu, KritzelControls as kritzel_controls, KritzelCurrentUser as kritzel_current_user, KritzelCurrentUserDialog as kritzel_current_user_dialog, KritzelCursorTrail as kritzel_cursor_trail, KritzelDialog as kritzel_dialog, KritzelDropdown as kritzel_dropdown, KritzelEditor as kritzel_editor, KritzelEngine as kritzel_engine, KritzelExport as kritzel_export, KritzelFont as kritzel_font, KritzelFontFamily as kritzel_font_family, KritzelFontSize as kritzel_font_size, KritzelIcon as kritzel_icon, KritzelInput as kritzel_input, KritzelLineEndings as kritzel_line_endings, KritzelLoadingOverlay as kritzel_loading_overlay, KritzelLoginDialog as kritzel_login_dialog, KritzelMasterDetail as kritzel_master_detail, KritzelMenu as kritzel_menu, KritzelMenuItem as kritzel_menu_item, KritzelMoreMenu as kritzel_more_menu, KritzelNotificationCard as kritzel_notification_card, KritzelNumericInput as kritzel_numeric_input, KritzelOpacitySlider as kritzel_opacity_slider, KritzelPillTabs as kritzel_pill_tabs, KritzelPortal as kritzel_portal, KritzelSettings as kritzel_settings, KritzelShapeFill as kritzel_shape_fill, KritzelShareDialog as kritzel_share_dialog, KritzelSlideToggle as kritzel_slide_toggle, KritzelSplitButton as kritzel_split_button, KritzelStrokeSize as kritzel_stroke_size, KritzelToolConfig as kritzel_tool_config, KritzelTooltip as kritzel_tooltip, KritzelUtilityPanel as kritzel_utility_panel, KritzelWatermark as kritzel_watermark, KritzelWorkspaceManager as kritzel_workspace_manager, KritzelZoomPanel as kritzel_zoom_panel };