kritzel-stencil 0.0.127 → 0.0.128

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 (291) hide show
  1. package/dist/cjs/{index-BacMQbNR.js → index-C7Read21.js} +165 -82
  2. package/dist/cjs/index-C7Read21.js.map +1 -0
  3. package/dist/cjs/{index-C05uAr89.js → index-CUSIflVf.js} +12 -6
  4. package/dist/cjs/index-CUSIflVf.js.map +1 -0
  5. package/dist/cjs/index.cjs.js +1 -3
  6. package/dist/cjs/{kritzel-brush-style_18.cjs.entry.js → kritzel-brush-style_22.cjs.entry.js} +979 -211
  7. package/dist/cjs/loader.cjs.js +2 -4
  8. package/dist/cjs/stencil.cjs.js +3 -5
  9. package/dist/cjs/stencil.cjs.js.map +1 -1
  10. package/dist/collection/classes/commands/add-object.command.js +5 -2
  11. package/dist/collection/classes/commands/add-object.command.js.map +1 -1
  12. package/dist/collection/classes/commands/add-selection-group.command.js +2 -2
  13. package/dist/collection/classes/commands/add-selection-group.command.js.map +1 -1
  14. package/dist/collection/classes/commands/base.command.js +2 -2
  15. package/dist/collection/classes/commands/base.command.js.map +1 -1
  16. package/dist/collection/classes/commands/batch.command.js +2 -2
  17. package/dist/collection/classes/commands/batch.command.js.map +1 -1
  18. package/dist/collection/classes/commands/move-selection-group.command.js +2 -2
  19. package/dist/collection/classes/commands/move-selection-group.command.js.map +1 -1
  20. package/dist/collection/classes/commands/remove-object.command.js +5 -2
  21. package/dist/collection/classes/commands/remove-object.command.js.map +1 -1
  22. package/dist/collection/classes/commands/remove-selection-group.command.js +2 -2
  23. package/dist/collection/classes/commands/remove-selection-group.command.js.map +1 -1
  24. package/dist/collection/classes/commands/resize-selection-group.command.js +2 -2
  25. package/dist/collection/classes/commands/resize-selection-group.command.js.map +1 -1
  26. package/dist/collection/classes/commands/rotate-selection-group.command.js +2 -2
  27. package/dist/collection/classes/commands/rotate-selection-group.command.js.map +1 -1
  28. package/dist/collection/classes/commands/update-object.command.js +5 -2
  29. package/dist/collection/classes/commands/update-object.command.js.map +1 -1
  30. package/dist/collection/classes/commands/update-viewport.command.js +2 -2
  31. package/dist/collection/classes/commands/update-viewport.command.js.map +1 -1
  32. package/dist/collection/classes/database.class.js +227 -0
  33. package/dist/collection/classes/database.class.js.map +1 -0
  34. package/dist/collection/classes/handlers/key.handler.js +0 -1
  35. package/dist/collection/classes/handlers/key.handler.js.map +1 -1
  36. package/dist/collection/classes/handlers/move.handler.js +18 -2
  37. package/dist/collection/classes/handlers/move.handler.js.map +1 -1
  38. package/dist/collection/classes/handlers/resize.handler.js +10 -2
  39. package/dist/collection/classes/handlers/resize.handler.js.map +1 -1
  40. package/dist/collection/classes/handlers/rotation.handler.js +18 -2
  41. package/dist/collection/classes/handlers/rotation.handler.js.map +1 -1
  42. package/dist/collection/classes/history.class.js +18 -5
  43. package/dist/collection/classes/history.class.js.map +1 -1
  44. package/dist/collection/classes/objects/base-object.class.js +1 -0
  45. package/dist/collection/classes/objects/base-object.class.js.map +1 -1
  46. package/dist/collection/classes/objects/custom-element.class.js +1 -0
  47. package/dist/collection/classes/objects/custom-element.class.js.map +1 -1
  48. package/dist/collection/classes/objects/image.class.js +1 -0
  49. package/dist/collection/classes/objects/image.class.js.map +1 -1
  50. package/dist/collection/classes/objects/path.class.js +1 -0
  51. package/dist/collection/classes/objects/path.class.js.map +1 -1
  52. package/dist/collection/classes/objects/selection-box.class.js +1 -0
  53. package/dist/collection/classes/objects/selection-box.class.js.map +1 -1
  54. package/dist/collection/classes/objects/selection-group.class.js +1 -0
  55. package/dist/collection/classes/objects/selection-group.class.js.map +1 -1
  56. package/dist/collection/classes/objects/text.class.js +7 -4
  57. package/dist/collection/classes/objects/text.class.js.map +1 -1
  58. package/dist/collection/classes/registries/icon-registry.class.js +5 -1
  59. package/dist/collection/classes/registries/icon-registry.class.js.map +1 -1
  60. package/dist/collection/classes/store.class.js +143 -20
  61. package/dist/collection/classes/store.class.js.map +1 -1
  62. package/dist/collection/classes/structures/octree.structure.js +4 -0
  63. package/dist/collection/classes/structures/octree.structure.js.map +1 -1
  64. package/dist/collection/classes/tools/image-tool.class.js +3 -0
  65. package/dist/collection/classes/tools/image-tool.class.js.map +1 -1
  66. package/dist/collection/classes/tools/text-tool.class.js +2 -2
  67. package/dist/collection/classes/tools/text-tool.class.js.map +1 -1
  68. package/dist/collection/classes/viewport.class.js +4 -0
  69. package/dist/collection/classes/viewport.class.js.map +1 -1
  70. package/dist/collection/classes/workspace.class.js +10 -0
  71. package/dist/collection/classes/workspace.class.js.map +1 -0
  72. package/dist/collection/collection-manifest.json +6 -2
  73. package/dist/collection/components/core/kritzel-cursor-trail/kritzel-cursor-trail.js +1 -1
  74. package/dist/collection/components/core/kritzel-editor/kritzel-editor.css +5 -0
  75. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js +14 -16
  76. package/dist/collection/components/core/kritzel-editor/kritzel-editor.js.map +1 -1
  77. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js +235 -39
  78. package/dist/collection/components/core/kritzel-engine/kritzel-engine.js.map +1 -1
  79. package/dist/collection/components/shared/kritzel-color/kritzel-color.js +2 -2
  80. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.css +1 -1
  81. package/dist/collection/components/shared/kritzel-color-palette/kritzel-color-palette.js +1 -1
  82. package/dist/collection/components/shared/kritzel-font/kritzel-font.js +1 -1
  83. package/dist/collection/components/shared/kritzel-font-family/kritzel-font-family.js +1 -1
  84. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.css +1 -1
  85. package/dist/collection/components/shared/kritzel-font-size/kritzel-font-size.js +1 -1
  86. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.css +166 -0
  87. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js +272 -0
  88. package/dist/collection/components/shared/kritzel-menu/kritzel-menu.js.map +1 -0
  89. package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js +218 -0
  90. package/dist/collection/components/shared/kritzel-portal/kritzel-portal.js.map +1 -0
  91. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.css +74 -0
  92. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js +324 -0
  93. package/dist/collection/components/shared/kritzel-split-button/kritzel-split-button.js.map +1 -0
  94. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.css +2 -2
  95. package/dist/collection/components/shared/kritzel-stroke-size/kritzel-stroke-size.js +1 -1
  96. package/dist/collection/components/shared/kritzel-tooltip/kritzel-tooltip.js +4 -4
  97. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.css +1 -1
  98. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js +24 -61
  99. package/dist/collection/components/ui/kritzel-context-menu/kritzel-context-menu.js.map +1 -1
  100. package/dist/collection/components/ui/kritzel-control-brush-config/kritzel-control-brush-config.js +2 -2
  101. package/dist/collection/components/ui/kritzel-control-text-config/kritzel-control-text-config.js +2 -2
  102. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.css +3 -3
  103. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js +29 -17
  104. package/dist/collection/components/ui/kritzel-controls/kritzel-controls.js.map +1 -1
  105. package/dist/collection/components/ui/kritzel-utility-panel/kritzel-utility-panel.js +1 -1
  106. package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.css +5 -0
  107. package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.js +209 -0
  108. package/dist/collection/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.js.map +1 -0
  109. package/dist/collection/configs/default-engine-state.js +5 -2
  110. package/dist/collection/configs/default-engine-state.js.map +1 -1
  111. package/dist/collection/helpers/class.helper.js +1 -1
  112. package/dist/collection/helpers/class.helper.js.map +1 -1
  113. package/dist/collection/helpers/html.helper.js +30 -1
  114. package/dist/collection/helpers/html.helper.js.map +1 -1
  115. package/dist/collection/helpers/object.helper.js +1 -1
  116. package/dist/collection/helpers/object.helper.js.map +1 -1
  117. package/dist/collection/interfaces/command.interface.js.map +1 -1
  118. package/dist/collection/interfaces/debug-info.interface.js.map +1 -1
  119. package/dist/collection/interfaces/engine-state.interface.js.map +1 -1
  120. package/dist/collection/interfaces/menu-item.interface.js +2 -0
  121. package/dist/collection/interfaces/menu-item.interface.js.map +1 -0
  122. package/dist/collection/interfaces/object.interface.js.map +1 -1
  123. package/dist/components/index.d.ts +8 -0
  124. package/dist/components/index.js +7 -3
  125. package/dist/components/index.js.map +1 -1
  126. package/dist/components/kritzel-brush-style.js +1 -1
  127. package/dist/components/kritzel-color-palette.js +1 -1
  128. package/dist/components/kritzel-color.js +1 -1
  129. package/dist/components/kritzel-context-menu.js +1 -1
  130. package/dist/components/kritzel-control-brush-config.js +1 -1
  131. package/dist/components/kritzel-control-text-config.js +1 -1
  132. package/dist/components/kritzel-controls.js +1 -1
  133. package/dist/components/kritzel-cursor-trail.js +1 -1
  134. package/dist/components/kritzel-dropdown.js +1 -1
  135. package/dist/components/kritzel-editor.js +79 -49
  136. package/dist/components/kritzel-editor.js.map +1 -1
  137. package/dist/components/kritzel-engine.js +1 -1
  138. package/dist/components/kritzel-font-family.js +1 -1
  139. package/dist/components/kritzel-font-size.js +1 -1
  140. package/dist/components/kritzel-font.js +1 -1
  141. package/dist/components/kritzel-icon.js +1 -1
  142. package/dist/components/kritzel-menu.d.ts +11 -0
  143. package/dist/components/kritzel-menu.js +9 -0
  144. package/dist/components/kritzel-menu.js.map +1 -0
  145. package/dist/components/kritzel-portal.d.ts +11 -0
  146. package/dist/components/kritzel-portal.js +9 -0
  147. package/dist/components/kritzel-portal.js.map +1 -0
  148. package/dist/components/kritzel-split-button.d.ts +11 -0
  149. package/dist/components/kritzel-split-button.js +9 -0
  150. package/dist/components/kritzel-split-button.js.map +1 -0
  151. package/dist/components/kritzel-stroke-size.js +1 -1
  152. package/dist/components/kritzel-tooltip.js +1 -1
  153. package/dist/components/kritzel-utility-panel.js +1 -1
  154. package/dist/components/kritzel-workspace-manager.d.ts +11 -0
  155. package/dist/components/kritzel-workspace-manager.js +9 -0
  156. package/dist/components/kritzel-workspace-manager.js.map +1 -0
  157. package/dist/components/{p-DfJEh7HZ.js → p-5CJxFNEE.js} +9 -7
  158. package/dist/components/p-5CJxFNEE.js.map +1 -0
  159. package/dist/components/{p-ljdIU3DL.js → p-B7VrEdgP.js} +63 -63
  160. package/dist/components/p-B7VrEdgP.js.map +1 -0
  161. package/dist/components/{p-DJc6_PyL.js → p-BAPUTr3K.js} +10 -8
  162. package/dist/components/p-BAPUTr3K.js.map +1 -0
  163. package/dist/components/{p-DSWoCkxm.js → p-BB22cVkU.js} +42 -34
  164. package/dist/components/p-BB22cVkU.js.map +1 -0
  165. package/dist/components/{p-CtiROna-.js → p-BLmFBe2a.js} +12 -6
  166. package/dist/components/p-BLmFBe2a.js.map +1 -0
  167. package/dist/components/p-BU2q3PRS.js +84 -0
  168. package/dist/components/p-BU2q3PRS.js.map +1 -0
  169. package/dist/components/{p-Dp8hrISj.js → p-BZ-j_4CK.js} +8 -6
  170. package/dist/components/p-BZ-j_4CK.js.map +1 -0
  171. package/dist/components/{p-BhC-Et5I.js → p-BaKb8ZLg.js} +16 -14
  172. package/dist/components/p-BaKb8ZLg.js.map +1 -0
  173. package/dist/components/p-Bb6od8He.js +42 -0
  174. package/dist/components/p-Bb6od8He.js.map +1 -0
  175. package/dist/components/{p-DcvujuV_.js → p-BcQTDgzV.js} +10 -8
  176. package/dist/components/p-BcQTDgzV.js.map +1 -0
  177. package/dist/components/p-BeVv4o5c.js +14 -0
  178. package/dist/components/p-BeVv4o5c.js.map +1 -0
  179. package/dist/components/p-BmJbJwkH.js +167 -0
  180. package/dist/components/p-BmJbJwkH.js.map +1 -0
  181. package/dist/components/{p-DJN0U8pI.js → p-BqrTPNyu.js} +10 -7
  182. package/dist/components/p-BqrTPNyu.js.map +1 -0
  183. package/dist/components/{p-NZJPrwJV.js → p-BvlGgLAQ.js} +7 -5
  184. package/dist/components/p-BvlGgLAQ.js.map +1 -0
  185. package/dist/components/{p-BOUCnklW.js → p-BzSz74Ci.js} +9 -7
  186. package/dist/components/p-BzSz74Ci.js.map +1 -0
  187. package/dist/components/{p-CudOuOAW.js → p-D-zg05gA.js} +558 -126
  188. package/dist/components/p-D-zg05gA.js.map +1 -0
  189. package/dist/components/p-D8W6LE-c.js.map +1 -1
  190. package/dist/components/p-DV4ERZv5.js +112 -0
  191. package/dist/components/p-DV4ERZv5.js.map +1 -0
  192. package/dist/components/{p-EQo4-DJT.js → p-DtmZW6eP.js} +8 -6
  193. package/dist/components/p-DtmZW6eP.js.map +1 -0
  194. package/dist/components/{p-C9usqwb5.js → p-V4ui5aWj.js} +9 -7
  195. package/dist/components/p-V4ui5aWj.js.map +1 -0
  196. package/dist/components/{p-BubFkS0u.js → p-_ntxNi8v.js} +9 -7
  197. package/dist/components/p-_ntxNi8v.js.map +1 -0
  198. package/dist/components/{p-BkFzf8vg.js → p-a7KmQzo4.js} +15 -13
  199. package/dist/components/p-a7KmQzo4.js.map +1 -0
  200. package/dist/components/p-hSuNJiIq.js +152 -0
  201. package/dist/components/p-hSuNJiIq.js.map +1 -0
  202. package/dist/components/{p-CmlcJ8Kw.js → p-jG1e48OE.js} +11 -9
  203. package/dist/components/p-jG1e48OE.js.map +1 -0
  204. package/dist/components/{p-D5a8vnRF.js → p-rQeWFfPG.js} +10 -8
  205. package/dist/components/p-rQeWFfPG.js.map +1 -0
  206. package/dist/components/p-sQmW5NRu.js +156 -0
  207. package/dist/components/p-sQmW5NRu.js.map +1 -0
  208. package/dist/esm/{index-D37FADaF.js → index-J4NpPimy.js} +163 -83
  209. package/dist/esm/index-J4NpPimy.js.map +1 -0
  210. package/dist/esm/{index-BGl8znzE.js → index-NiIEUDzj.js} +12 -6
  211. package/dist/esm/index-NiIEUDzj.js.map +1 -0
  212. package/dist/esm/index.js +1 -3
  213. package/dist/esm/{kritzel-brush-style_18.entry.js → kritzel-brush-style_22.entry.js} +969 -205
  214. package/dist/esm/loader.js +3 -5
  215. package/dist/esm/stencil.js +4 -6
  216. package/dist/esm/stencil.js.map +1 -1
  217. package/dist/stencil/index.esm.js +1 -1
  218. package/dist/stencil/p-4a0009e7.entry.js +2 -0
  219. package/dist/stencil/p-4a0009e7.entry.js.map +1 -0
  220. package/dist/stencil/p-J4NpPimy.js +2 -0
  221. package/dist/stencil/p-J4NpPimy.js.map +1 -0
  222. package/dist/stencil/{p-BGl8znzE.js → p-NiIEUDzj.js} +3 -3
  223. package/dist/stencil/p-NiIEUDzj.js.map +1 -0
  224. package/dist/stencil/stencil.esm.js +1 -1
  225. package/dist/stencil/stencil.esm.js.map +1 -1
  226. package/dist/types/classes/commands/add-object.command.d.ts +1 -1
  227. package/dist/types/classes/commands/add-selection-group.command.d.ts +1 -1
  228. package/dist/types/classes/commands/base.command.d.ts +2 -2
  229. package/dist/types/classes/commands/batch.command.d.ts +1 -1
  230. package/dist/types/classes/commands/move-selection-group.command.d.ts +1 -1
  231. package/dist/types/classes/commands/remove-object.command.d.ts +1 -1
  232. package/dist/types/classes/commands/remove-selection-group.command.d.ts +1 -1
  233. package/dist/types/classes/commands/resize-selection-group.command.d.ts +1 -1
  234. package/dist/types/classes/commands/rotate-selection-group.command.d.ts +1 -1
  235. package/dist/types/classes/commands/update-object.command.d.ts +1 -1
  236. package/dist/types/classes/commands/update-viewport.command.d.ts +1 -1
  237. package/dist/types/classes/database.class.d.ts +28 -0
  238. package/dist/types/classes/history.class.d.ts +1 -0
  239. package/dist/types/classes/objects/base-object.class.d.ts +1 -0
  240. package/dist/types/classes/objects/text.class.d.ts +1 -1
  241. package/dist/types/classes/store.class.d.ts +19 -2
  242. package/dist/types/classes/structures/octree.structure.d.ts +1 -0
  243. package/dist/types/classes/workspace.class.d.ts +16 -0
  244. package/dist/types/components/core/kritzel-editor/kritzel-editor.d.ts +6 -1
  245. package/dist/types/components/core/kritzel-engine/kritzel-engine.d.ts +12 -2
  246. package/dist/types/components/shared/kritzel-menu/kritzel-menu.d.ts +24 -0
  247. package/dist/types/components/shared/kritzel-portal/kritzel-portal.d.ts +24 -0
  248. package/dist/types/components/shared/kritzel-split-button/kritzel-split-button.d.ts +24 -0
  249. package/dist/types/components/ui/kritzel-context-menu/kritzel-context-menu.d.ts +3 -4
  250. package/dist/types/components/ui/kritzel-controls/kritzel-controls.d.ts +2 -1
  251. package/dist/types/components/ui/kritzel-workspace-manager/kritzel-workspace-manager.d.ts +25 -0
  252. package/dist/types/components.d.ts +250 -2
  253. package/dist/types/helpers/html.helper.d.ts +3 -1
  254. package/dist/types/interfaces/command.interface.d.ts +1 -1
  255. package/dist/types/interfaces/debug-info.interface.d.ts +1 -0
  256. package/dist/types/interfaces/engine-state.interface.d.ts +3 -0
  257. package/dist/types/interfaces/menu-item.interface.d.ts +9 -0
  258. package/dist/types/interfaces/object.interface.d.ts +1 -0
  259. package/dist/types/stencil-public-runtime.d.ts +21 -0
  260. package/package.json +2 -1
  261. package/dist/cjs/index-BacMQbNR.js.map +0 -1
  262. package/dist/cjs/index-C05uAr89.js.map +0 -1
  263. package/dist/cjs/kritzel-brush-style_18.cjs.entry.js.map +0 -1
  264. package/dist/components/p-2gNwfcSP.js +0 -119
  265. package/dist/components/p-2gNwfcSP.js.map +0 -1
  266. package/dist/components/p-BOUCnklW.js.map +0 -1
  267. package/dist/components/p-BhC-Et5I.js.map +0 -1
  268. package/dist/components/p-BkFzf8vg.js.map +0 -1
  269. package/dist/components/p-BubFkS0u.js.map +0 -1
  270. package/dist/components/p-C9usqwb5.js.map +0 -1
  271. package/dist/components/p-CmlcJ8Kw.js.map +0 -1
  272. package/dist/components/p-CtiROna-.js.map +0 -1
  273. package/dist/components/p-CudOuOAW.js.map +0 -1
  274. package/dist/components/p-D5a8vnRF.js.map +0 -1
  275. package/dist/components/p-DJN0U8pI.js.map +0 -1
  276. package/dist/components/p-DJc6_PyL.js.map +0 -1
  277. package/dist/components/p-DSWoCkxm.js.map +0 -1
  278. package/dist/components/p-DcvujuV_.js.map +0 -1
  279. package/dist/components/p-DfJEh7HZ.js.map +0 -1
  280. package/dist/components/p-Dp8hrISj.js.map +0 -1
  281. package/dist/components/p-EQo4-DJT.js.map +0 -1
  282. package/dist/components/p-NZJPrwJV.js.map +0 -1
  283. package/dist/components/p-ljdIU3DL.js.map +0 -1
  284. package/dist/esm/index-BGl8znzE.js.map +0 -1
  285. package/dist/esm/index-D37FADaF.js.map +0 -1
  286. package/dist/esm/kritzel-brush-style_18.entry.js.map +0 -1
  287. package/dist/stencil/p-BGl8znzE.js.map +0 -1
  288. package/dist/stencil/p-D37FADaF.js +0 -2
  289. package/dist/stencil/p-D37FADaF.js.map +0 -1
  290. package/dist/stencil/p-e6ac7fc6.entry.js +0 -2
  291. package/dist/stencil/p-e6ac7fc6.entry.js.map +0 -1
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var index = require('./index-C05uAr89.js');
4
- var index$1 = require('./index-BacMQbNR.js');
3
+ var index = require('./index-CUSIflVf.js');
4
+ var index$1 = require('./index-C7Read21.js');
5
5
 
6
6
  const kritzelBrushStyleCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box;width:100%}.brush-style-button{display:flex;justify-content:center;align-items:center;width:42px;height:32px;padding:0;border:none;outline:none;background:none;cursor:default;border-radius:0;color:var(--control-text-color);font-weight:bold;-webkit-tap-highlight-color:transparent}.font-style-button:not(:last-child){border-right:1px solid #333333}.font-style-button:hover{background-color:var(--control-hover-bg)}.font-style-button:active{background-color:var(--control-active-bg)}.font-style-button.selected,.font-style-button.selected:hover,.font-style-button.selected:active{background-color:var(--control-selected-bg);color:var(--control-selected-color)}";
7
7
 
@@ -61,13 +61,13 @@ const KritzelColor = class {
61
61
  }
62
62
  render() {
63
63
  const isColorVeryLight = this.isLightColor(this.value);
64
- return (index.h(index.Host, { key: '8f8bb6c8c710bf6f3731b2be82c0857dd13913f1' }, index.h("div", { key: 'd28526ebcb418130ae8f608ea51c6c8dccffb906', class: "checkerboard-bg", style: {
64
+ return (index.h(index.Host, { key: '1468f3502f7d10d182ac72a05ce4b1e520353f8a' }, index.h("div", { key: 'd30d47667b1b72a970c4ee0da887dd59a663eae7', class: "checkerboard-bg", style: {
65
65
  width: `${this.size}px`,
66
66
  height: `${this.size}px`,
67
67
  borderRadius: '50%',
68
68
  display: 'inline-block',
69
69
  position: 'relative',
70
- } }, index.h("div", { key: 'ec6a886f152dd4db4d4a3f86991f3b065ece1b45', class: {
70
+ } }, index.h("div", { key: '073fd85967e53b609103a9fe47028bcda849e5ec', class: {
71
71
  'color-circle': true,
72
72
  'white': isColorVeryLight,
73
73
  }, style: {
@@ -84,7 +84,7 @@ const KritzelColor = class {
84
84
  };
85
85
  KritzelColor.style = kritzelColorCss;
86
86
 
87
- const kritzelColorPaletteCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;width:100%;box-sizing:border-box}.color-grid{width:100%;display:grid;grid-template-columns:repeat(6, 32px);gap:8px;justify-items:center;overflow:hidden;height:40px;transition:height 0.1s ease-in-out}.color-grid.expanded{height:500px}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box}.color-container:hover{background-color:var(--kritzel-color-palette-hover-background-color, #f0f0f0)}.color-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-color-palette-selected-background-color)}";
87
+ const kritzelColorPaletteCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;width:100%;box-sizing:border-box}.color-grid{width:100%;display:grid;grid-template-columns:repeat(6, 32px);gap:8px;justify-items:center;overflow:hidden;height:40px;transition:height 0.1s ease-in-out}.color-grid.expanded{height:500px}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box}.color-container:hover{background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.color-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-color-palette-selected-background-color)}";
88
88
 
89
89
  const KritzelColorPalette = class {
90
90
  constructor(hostRef) {
@@ -109,7 +109,7 @@ const KritzelColorPalette = class {
109
109
  render() {
110
110
  const displayedColors = this.isExpanded ? this.colors : this.colors.slice(0, 6);
111
111
  const expandedHeight = this.isExpanded ? this.calculateHeight() : '32px';
112
- return (index.h(index.Host, { key: 'bae0e5b2c6444f4a447dbcb13bfd427b4f25ddb6' }, index.h("div", { key: '3020fe3b1eef1cafb8e1720716219464d11c0594', class: {
112
+ return (index.h(index.Host, { key: 'dddc32b0904800092d45727e833181af32eb8766' }, index.h("div", { key: '293cbed8e9c62b5f409b7dcdca0df5de9d65b758', class: {
113
113
  'color-grid': true,
114
114
  'expanded': this.isExpanded,
115
115
  }, style: {
@@ -122,83 +122,47 @@ const KritzelColorPalette = class {
122
122
  };
123
123
  KritzelColorPalette.style = kritzelColorPaletteCss;
124
124
 
125
- const kritzelContextMenuCss = ":host{display:block}.menu-container{display:flex;flex-direction:column;background-color:var(--kritzel-context-menu-background-color, #ffffff);border-radius:var(--kritzel-context-menu-border-radius, 12px);box-shadow:var(--kritzel-context-menu-box-shadow, 0 1px 6px rgba(0, 0, 0, 0.12));border:var(--kritzel-context-menu-border, 1px solid #f0f0f0);padding:var(--kritzel-context-menu-padding,4px)}.menu-item{display:flex;align-items:center;gap:var(--kritzel-context-menu-item-gap, 8px);background:none;border:none;text-align:left;padding:var(--kritzel-context-menu-item-padding, 8px);border-radius:var(--kritzel-context-menu-item-border-radius, 12px);cursor:pointer;font-size:var(--kritzel-context-menu-item-font-size, 14px);color:var(--kritzel-context-menu-item-color, #333333);white-space:nowrap;-webkit-tap-highlight-color:transparent}.menu-item:not(.disabled):hover{background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.menu-item:not(.disabled):active{background-color:var(--kritzel-context-menu-item-active-background-color, hsl(0, 0%, 0%, 8.6%))}.menu-item.disabled{color:var(--kritzel-context-menu-item-disabled-color, #aaaaaa);cursor:default}.menu-item kritzel-icon{opacity:0.8;flex-shrink:0}.menu-item.disabled kritzel-icon{opacity:0.4}.label{flex-grow:1}";
125
+ const kritzelContextMenuCss = ":host{display:block}.menu-container{display:flex;flex-direction:column;background-color:var(--kritzel-context-menu-background-color, #ffffff);border-radius:var(--kritzel-context-menu-border-radius, 12px);box-shadow:var(--kritzel-context-menu-box-shadow, 0 1px 6px rgba(0, 0, 0, 0.12));border:var(--kritzel-context-menu-border, 1px solid #ebebeb);padding:var(--kritzel-context-menu-padding,4px)}.menu-item{display:flex;align-items:center;gap:var(--kritzel-context-menu-item-gap, 8px);background:none;border:none;text-align:left;padding:var(--kritzel-context-menu-item-padding, 8px);border-radius:var(--kritzel-context-menu-item-border-radius, 12px);cursor:pointer;font-size:var(--kritzel-context-menu-item-font-size, 14px);color:var(--kritzel-context-menu-item-color, #333333);white-space:nowrap;-webkit-tap-highlight-color:transparent}.menu-item:not(.disabled):hover{background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.menu-item:not(.disabled):active{background-color:var(--kritzel-context-menu-item-active-background-color, hsl(0, 0%, 0%, 8.6%))}.menu-item.disabled{color:var(--kritzel-context-menu-item-disabled-color, #aaaaaa);cursor:default}.menu-item kritzel-icon{opacity:0.8;flex-shrink:0}.menu-item.disabled kritzel-icon{opacity:0.4}.label{flex-grow:1}";
126
126
 
127
127
  const KritzelContextMenu = class {
128
128
  constructor(hostRef) {
129
129
  index.registerInstance(this, hostRef);
130
130
  this.actionSelected = index.createEvent(this, "actionSelected");
131
- this.disabledStates = new Map();
132
- this.visibleItems = [];
131
+ this.processedItems = [];
133
132
  }
134
133
  componentWillLoad() {
135
- this.resolveVisibleItems();
136
- this.resolveDisabledStates();
134
+ this.updateMenuItems();
137
135
  }
138
136
  onItemsChanged() {
139
- this.resolveVisibleItems();
140
- this.resolveDisabledStates();
137
+ this.updateMenuItems();
141
138
  }
142
- handleItemClick(item, index) {
143
- if (!this.disabledStates.get(index)) {
139
+ handleItemClick(item, isDisabled) {
140
+ if (!isDisabled) {
144
141
  this.actionSelected.emit(item);
145
142
  }
146
143
  }
147
- async resolveVisibleItems() {
148
- const visibleItems = [];
149
- const visibilityPromises = this.items.map(async (item, index) => {
150
- let isVisible = true;
151
- if (item.visible !== undefined) {
152
- if (typeof item.visible === 'boolean') {
153
- isVisible = item.visible;
154
- }
155
- else if (typeof item.visible === 'function') {
156
- const result = item.visible(null, this.objects);
157
- if (result instanceof Promise) {
158
- isVisible = await result;
159
- }
160
- else {
161
- isVisible = result;
162
- }
163
- }
164
- }
165
- return { item, index, isVisible };
166
- });
167
- const visibilityResults = await Promise.all(visibilityPromises);
168
- visibilityResults.forEach(({ item, isVisible }) => {
144
+ async evaluateProperty(value, defaultValue) {
145
+ if (typeof value === 'boolean') {
146
+ return value;
147
+ }
148
+ if (typeof value === 'function') {
149
+ return await Promise.resolve(value(null, this.objects));
150
+ }
151
+ return defaultValue;
152
+ }
153
+ async updateMenuItems() {
154
+ const processed = [];
155
+ for (const item of this.items) {
156
+ const isVisible = await this.evaluateProperty(item.visible, true);
169
157
  if (isVisible) {
170
- visibleItems.push(item);
171
- }
172
- });
173
- this.visibleItems = visibleItems;
174
- }
175
- async resolveDisabledStates() {
176
- const newStates = new Map();
177
- const disabledPromises = this.visibleItems.map(async (item, index) => {
178
- let isDisabled = false;
179
- if (typeof item.disabled === 'boolean') {
180
- isDisabled = item.disabled;
158
+ const isDisabled = await this.evaluateProperty(item.disabled, false);
159
+ processed.push({ item, isDisabled });
181
160
  }
182
- else if (typeof item.disabled === 'function') {
183
- const result = item.disabled(null, this.objects);
184
- if (result instanceof Promise) {
185
- isDisabled = await result;
186
- }
187
- else {
188
- isDisabled = result;
189
- }
190
- }
191
- newStates.set(index, isDisabled);
192
- });
193
- await Promise.all(disabledPromises);
194
- this.disabledStates = new Map(newStates);
161
+ }
162
+ this.processedItems = processed;
195
163
  }
196
164
  render() {
197
- return (index.h(index.Host, { key: 'cc1a338a7bf0d32764c2737f4f32774ccb22370a' }, index.h("div", { key: '4a83b9366332e42b506c3c876c00d77498a2b8b5', class: "menu-container" }, this.visibleItems.map((item, index$1) => {
198
- var _a;
199
- const isDisabled = (_a = this.disabledStates.get(index$1)) !== null && _a !== void 0 ? _a : false;
200
- return (index.h("button", { key: `${item.label}-${index$1}`, class: { 'menu-item': true, 'disabled': isDisabled }, onClick: () => this.handleItemClick(item, index$1), onTouchStart: () => this.handleItemClick(item, index$1), disabled: isDisabled }, item.icon && index.h("kritzel-icon", { name: item.icon, size: 16 }), index.h("span", { class: "label" }, item.label)));
201
- }))));
165
+ return (index.h(index.Host, { key: '96569454f806a6d17380315b4d0200236fe22550' }, index.h("div", { key: '0e5899a2901e1e9ab9d657824e105121ce785bdc', class: "menu-container" }, this.processedItems.map(({ item, isDisabled }, index$1) => (index.h("button", { key: `${item.label}-${index$1}`, class: { 'menu-item': true, disabled: isDisabled }, onClick: () => this.handleItemClick(item, isDisabled), onTouchStart: () => this.handleItemClick(item, isDisabled), disabled: isDisabled }, item.icon && index.h("kritzel-icon", { name: item.icon, size: 16 }), index.h("span", { class: "label" }, item.label)))))));
202
166
  }
203
167
  get hostElement() { return index.getElement(this); }
204
168
  static get watchers() { return {
@@ -240,14 +204,14 @@ const KritzelControlBrushConfig = class {
240
204
  this.toolChange.emit(this.tool);
241
205
  }
242
206
  render() {
243
- return (index.h(index.Host, { key: 'c200146a90a3dd72241e098eff555312fd3125a9' }, index.h("div", { key: '886492ec4c5e15954166c4a7569ba832d0e6eff8', style: {
207
+ return (index.h(index.Host, { key: 'd099d1c6722678fdfb06c34eb0860e8819dd17ca' }, index.h("div", { key: '0856f0150666415ee452a0fcec5c76b6d25b82c4', style: {
244
208
  display: 'flex',
245
209
  flexDirection: 'row',
246
210
  alignItems: 'center',
247
211
  justifyContent: 'flex-start',
248
212
  width: '100%',
249
213
  gap: '8px',
250
- } }, index.h("kritzel-brush-style", { key: '64e205189fbd740c01d4fd94c5098edae574d69b', type: this.tool.type, onTypeChange: event => this.handleTypeChange(event) }), index.h("button", { key: '4b2d0fbf4d485350223dbc27601e78ab37be8df5', class: "expand-toggle", onClick: () => this.handleToggleExpand(), title: this.isExpanded ? 'Collapse' : 'Expand', style: this.palette.length > 6 ? { visibillity: 'visible' } : { visibility: 'hidden' } }, index.h("kritzel-icon", { key: '35262e8456901d10c84437e578317287282cf690', name: this.isExpanded ? 'chevron-up' : 'chevron-down' }))), index.h("kritzel-color-palette", { key: '4f519179f419a3e3567d2db39d0d8f9f30d5a6a1', colors: this.palette, selectedColor: this.tool.color, isExpanded: this.isExpanded, isOpaque: true, onColorChange: color => this.handleColorChange(color) }), index.h("kritzel-stroke-size", { key: '05f05946c3ebd2707f1c41c236a2efca47cedbec', selectedSize: this.tool.size, onSizeChange: event => this.handleSizeChange(event) })));
214
+ } }, index.h("kritzel-brush-style", { key: '364e6026d1b280a02c3618c7ded11f40c7e3cba4', type: this.tool.type, onTypeChange: event => this.handleTypeChange(event) }), index.h("button", { key: 'fc58c9ceb9e92ef8c79836e686b9a64653f91210', class: "expand-toggle", onClick: () => this.handleToggleExpand(), title: this.isExpanded ? 'Collapse' : 'Expand', style: this.palette.length > 6 ? { visibillity: 'visible' } : { visibility: 'hidden' } }, index.h("kritzel-icon", { key: 'ab219c72a9ace56853c725ba75767be2079a3c10', name: this.isExpanded ? 'chevron-up' : 'chevron-down' }))), index.h("kritzel-color-palette", { key: '8757c754217a3de88dad2c465ff748571716ae64', colors: this.palette, selectedColor: this.tool.color, isExpanded: this.isExpanded, isOpaque: true, onColorChange: color => this.handleColorChange(color) }), index.h("kritzel-stroke-size", { key: '056b227dd9a92b06588816739b55a80f5ce80835', selectedSize: this.tool.size, onSizeChange: event => this.handleSizeChange(event) })));
251
215
  }
252
216
  static get watchers() { return {
253
217
  "tool": ["handleToolChange"]
@@ -279,14 +243,14 @@ const KritzelControlTextConfig = class {
279
243
  this.toolChange.emit(this.tool);
280
244
  }
281
245
  render() {
282
- return (index.h(index.Host, { key: '1c8463a1f6b7bcf81f3b58fc0064330c50d6ada9' }, index.h("div", { key: '69825e6c9be473dda3597c86d51dffff9a6418fd', style: {
246
+ return (index.h(index.Host, { key: 'f0d35cc43f1fe58a5a26f21dad99f1a733b66cce' }, index.h("div", { key: 'efc7d31c11460015a41185b4215e9ff45970abdd', style: {
283
247
  display: 'flex',
284
248
  flexDirection: 'row',
285
249
  alignItems: 'center',
286
250
  justifyContent: 'flex-start',
287
251
  width: '100%',
288
252
  gap: '8px',
289
- } }, index.h("kritzel-font-family", { key: '56c947950e32989782512a2b00e3be0aaa12d77b', selectedFontFamily: this.tool.fontFamily, onFontFamilyChange: event => this.handleFamilyChange(event) }), index.h("button", { key: '83fdb5908340adc032a7abae9b4b678697e0cff8', class: "expand-toggle", onClick: () => this.handleToggleExpand(), title: this.isExpanded ? 'Collapse' : 'Expand' }, index.h("kritzel-icon", { key: '739c175fbc3c0c5c342f2983d0e47323bc5b56f4', name: this.isExpanded ? 'chevron-up' : 'chevron-down' }))), index.h("kritzel-color-palette", { key: '98251da71574b3487bf6ee46f7e4e95d133e1eea', colors: this.tool.palette, selectedColor: this.tool.fontColor, isExpanded: this.isExpanded, onColorChange: event => this.handleColorChange(event) }), index.h("kritzel-font-size", { key: '95c88611a6631a4db5d200aac57e7eeef2c195b8', selectedSize: this.tool.fontSize, fontFamily: this.tool.fontFamily, onSizeChange: event => this.handleSizeChange(event) })));
253
+ } }, index.h("kritzel-font-family", { key: '7f7d3ccb061d4b0e5e0f181ba4224f3de430a88c', selectedFontFamily: this.tool.fontFamily, onFontFamilyChange: event => this.handleFamilyChange(event) }), index.h("button", { key: '6676fcfa245874d54fa9933888c242c6f611c58c', class: "expand-toggle", onClick: () => this.handleToggleExpand(), title: this.isExpanded ? 'Collapse' : 'Expand' }, index.h("kritzel-icon", { key: '0734f636889c77f9087a2de2899a28ebd8df30a2', name: this.isExpanded ? 'chevron-up' : 'chevron-down' }))), index.h("kritzel-color-palette", { key: '68373ef79578d6a73028da681f1e3b0e8e3e5874', colors: this.tool.palette, selectedColor: this.tool.fontColor, isExpanded: this.isExpanded, onColorChange: event => this.handleColorChange(event) }), index.h("kritzel-font-size", { key: '56e6828f6ceaac3d37910b7d092a30bacbd84519', selectedSize: this.tool.fontSize, fontFamily: this.tool.fontFamily, onSizeChange: event => this.handleSizeChange(event) })));
290
254
  }
291
255
  };
292
256
  KritzelControlTextConfig.style = kritzelControlTextConfigCss;
@@ -297,7 +261,7 @@ class KritzelDevicesHelper {
297
261
  }
298
262
  }
299
263
 
300
- const kritzelControlsCss = ":host{display:flex;flex-direction:column;user-select:none}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap, 8px);height:100%;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 16px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #f0f0f0);z-index:10000;position:relative}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color, #000000);border-radius:var(--kritzel-controls-control-border-radius, 12px);padding:var(--kritzel-controls-control-padding, 8px);border:none;outline:none;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}:host(.mobile) .kritzel-control:hover{background-color:unset}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}:host(.mobile) .kritzel-control:active{background-color:unset}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-divider{width:var(--kritzel-controls-divider-width, 1px);height:var(--kritzel-controls-divider-height, 24px);background-color:var(--kritzel-controls-divider-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;width:40px;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:pointer}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #f0f0f0)}.font-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #f0f0f0)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{position:fixed;bottom:66px;left:50%;transform:translateX(-50%);z-index:10001}";
264
+ const kritzelControlsCss = ":host{display:flex;flex-direction:column;user-select:none}.kritzel-controls{display:flex;flex-direction:row;align-items:center;justify-content:flex-start;gap:var(--kritzel-controls-gap, 8px);height:100%;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 16px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #ebebeb);z-index:10000;position:relative}.kritzel-control{display:flex;justify-content:center;align-items:center;color:var(--kritzel-controls-control-color, #000000);border-radius:var(--kritzel-controls-control-border-radius, 12px);padding:var(--kritzel-controls-control-padding, 8px);border:none;outline:none;background:none;cursor:pointer;-webkit-tap-highlight-color:transparent;font-weight:bold}.kritzel-control:hover{background-color:var(--kritzel-controls-control-hover-background-color, hsl(0, 0%, 0%, 4.3%))}:host(.mobile) .kritzel-control:hover{background-color:unset}.kritzel-control:active{background-color:var(--kritzel-controls-control-active-background-color, hsl(0, 0%, 0%, 8.6%))}:host(.mobile) .kritzel-control:active{background-color:unset}.kritzel-control.selected,.kritzel-control.selected:hover,.kritzel-control.selected:active{background-color:var(--kritzel-controls-control-selected-background-color, #007AFF) !important;color:var(--kritzel-controls-control-selected-color, #ffffff) !important}.kritzel-divider{width:var(--kritzel-controls-divider-width, 1px);height:var(--kritzel-controls-divider-height, 24px);background-color:var(--kritzel-controls-divider-background-color, hsl(0, 0%, 0%, 4.3%))}.kritzel-config-container{position:relative;display:flex;justify-content:center;align-items:center;width:40px;height:40px;box-sizing:border-box;-webkit-tap-highlight-color:transparent}.kritzel-config{display:flex;justify-content:center;align-items:center;cursor:pointer}.color-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.font-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box;background-color:var(--kritzel-color-palette-hover-background-color, #ebebeb)}.no-config{height:24px;width:24px;border-radius:50%;border:1px dashed gray}kritzel-tooltip{position:fixed;bottom:66px;left:50%;transform:translateX(-50%);z-index:10001}";
301
265
 
302
266
  const KritzelControls = class {
303
267
  constructor(hostRef) {
@@ -311,23 +275,28 @@ const KritzelControls = class {
311
275
  this.isTouchDevice = KritzelDevicesHelper.isTouchDevice();
312
276
  this.kritzelEngine = null;
313
277
  }
314
- async handleActiveToolChange(event) {
315
- var _a;
316
- this.activeControl = this.controls.find(control => control.tool === event.detail) || null;
317
- await ((_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.setFocus());
318
- }
319
- handleClick(event) {
278
+ handleDocumentClick(event) {
320
279
  const element = event.target;
321
280
  if (!this.kritzelEngine || element.closest('.kritzel-tooltip')) {
322
281
  return;
323
282
  }
324
283
  this.isTooltipVisible = false;
325
- this.kritzelEngine.enable();
326
284
  }
327
- async closeTooltip() {
285
+ handleKeyDown(event) {
286
+ var _a;
287
+ if (event.key === 'Escape') {
288
+ event.preventDefault();
289
+ this.closeTooltip();
290
+ (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.enable();
291
+ }
292
+ }
293
+ async handleActiveToolChange(event) {
328
294
  var _a;
295
+ this.activeControl = this.controls.find(control => control.tool === event.detail) || null;
296
+ await ((_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.setFocus());
297
+ }
298
+ async closeTooltip() {
329
299
  this.isTooltipVisible = false;
330
- (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.enable();
331
300
  }
332
301
  get activeToolAsTextTool() {
333
302
  var _a;
@@ -375,9 +344,10 @@ const KritzelControls = class {
375
344
  }
376
345
  }
377
346
  handleConfigClick(event) {
347
+ var _a;
378
348
  event.stopPropagation();
379
349
  this.isTooltipVisible = !this.isTooltipVisible;
380
- this.kritzelEngine.disable();
350
+ (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.disable();
381
351
  }
382
352
  async handleToolChange(event) {
383
353
  this.activeControl = Object.assign(Object.assign({}, this.activeControl), { tool: event.detail });
@@ -386,13 +356,13 @@ const KritzelControls = class {
386
356
  render() {
387
357
  var _a, _b;
388
358
  const hasNoConfig = ((_a = this.activeControl) === null || _a === void 0 ? void 0 : _a.config) === undefined || ((_b = this.activeControl) === null || _b === void 0 ? void 0 : _b.config) === null;
389
- return (index.h(index.Host, { key: 'dfb17219cf1d27d86148bc918b8303d74244700c', class: {
359
+ return (index.h(index.Host, { key: 'af04746b6eaa04a51482cd9d25ba3ab303d631f1', class: {
390
360
  mobile: this.isTouchDevice,
391
- } }, this.isUtilityPanelVisible && (index.h("kritzel-utility-panel", { key: 'a5eb7c6b59a193ba0bdde53812882c355a7658d4', style: {
361
+ } }, this.isUtilityPanelVisible && (index.h("kritzel-utility-panel", { key: 'd6ecb1087a332162f3fc809ed4321fc48f72c3e7', style: {
392
362
  position: 'absolute',
393
363
  bottom: '56px',
394
364
  left: '12px',
395
- }, onUndo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.undo(); }, onRedo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.redo(); }, onDelete: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.delete(); } })), index.h("div", { key: 'b51e49664bf6330f22fb07ef64116459ec3832b3', class: "kritzel-controls" }, this.controls.map(control => {
365
+ }, onUndo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.undo(); }, onRedo: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.redo(); }, onDelete: () => { var _a; return (_a = this.kritzelEngine) === null || _a === void 0 ? void 0 : _a.delete(); } })), index.h("div", { key: '34723e47249d53fd544848d2d577deba4df1f131', class: "kritzel-controls" }, this.controls.map(control => {
396
366
  var _a, _b, _c, _d, _e, _f, _g, _h;
397
367
  if (control.type === 'tool') {
398
368
  return (index.h("button", { class: {
@@ -485,7 +455,7 @@ const KritzelCursorTrail = class {
485
455
  }
486
456
  }
487
457
  render() {
488
- return (index.h(index.Host, { key: '2bd830d9a7f97a9a7e96a5b6a40535fdaefb904d' }, this.cursorTrailPoints.length > 1 && (index.h("svg", { key: '3da6a2e65030721cbdb04fba78d15776cb8f281c', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
458
+ return (index.h(index.Host, { key: 'c519ab89ffb793de887a870bafe8772f7584f097' }, this.cursorTrailPoints.length > 1 && (index.h("svg", { key: 'db7ac0975c5a39c0b68d8fd4af4edd4d15f439f3', class: "cursor-trail-svg", xmlns: "http://www.w3.org/2000/svg", style: {
489
459
  position: 'absolute',
490
460
  left: '0',
491
461
  top: '0',
@@ -638,13 +608,17 @@ KritzelIconRegistry.registerIcons({
638
608
  'select-all': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-square-mouse-pointer-icon lucide-square-mouse-pointer"><path d="M12.034 12.681a.498.498 0 0 1 .647-.647l9 3.5a.5.5 0 0 1-.033.943l-3.444 1.068a1 1 0 0 0-.66.66l-1.067 3.443a.5.5 0 0 1-.943.033z"/><path d="M21 11V5a2 2 0 0 0-2-2H5a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h6"/></svg>',
639
609
  'download': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download-icon lucide-download"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg>',
640
610
  'undo': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-undo-icon lucide-undo"><path d="M3 7v6h6"/><path d="M21 17a9 9 0 0 0-9-9 9 9 0 0 0-6 2.3L3 13"/></svg>',
641
- 'redo': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-redo-icon lucide-redo"><path d="M21 7v6h-6"/><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7"/></svg>'
611
+ 'redo': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-redo-icon lucide-redo"><path d="M21 7v6h-6"/><path d="M3 17a9 9 0 0 1 9-9 9 9 0 0 1 6 2.3l3 2.7"/></svg>',
612
+ 'plus': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus-icon lucide-plus"><path d="M5 12h14"/><path d="M12 5v14"/></svg>',
613
+ 'ellipsis-vertical': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-ellipsis-vertical-icon lucide-ellipsis-vertical"><circle cx="12" cy="12" r="1"/><circle cx="12" cy="5" r="1"/><circle cx="12" cy="19" r="1"/></svg>',
614
+ 'x': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x-icon lucide-x"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg>',
615
+ 'check': '<svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check-icon lucide-check"><path d="M20 6 9 17l-5-5"/></svg>'
642
616
  });
643
617
 
644
618
  const ABSOLUTE_SCALE_MAX = 1000;
645
619
  const ABSOLUTE_SCALE_MIN = 0.0001;
646
620
 
647
- const kritzelEditorCss = "kritzel-editor{display:flex;margin:0;position:relative;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}kritzel-controls{position:absolute;bottom:28px}";
621
+ const kritzelEditorCss = "kritzel-editor{display:flex;margin:0;position:relative;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}kritzel-workspace-manager{position:absolute;top:14px;left:14px}kritzel-controls{position:absolute;bottom:28px}";
648
622
 
649
623
  const KritzelEditor = class {
650
624
  constructor(hostRef) {
@@ -734,6 +708,8 @@ const KritzelEditor = class {
734
708
  this.isUtilityPanelVisible = true;
735
709
  this.isEngineReady = false;
736
710
  this.isControlsReady = false;
711
+ this.isWorkspaceManagerReady = false;
712
+ this.workspaces = [];
737
713
  }
738
714
  onIsEngineReady(newValue) {
739
715
  if (newValue && this.isControlsReady) {
@@ -777,32 +753,31 @@ const KritzelEditor = class {
777
753
  event.preventDefault();
778
754
  }
779
755
  }
780
- handleKeyDown(event) {
781
- var _a;
782
- if (event.key === 'Escape') {
783
- event.preventDefault();
784
- (_a = this.controlsRef) === null || _a === void 0 ? void 0 : _a.closeTooltip();
785
- }
786
- }
787
756
  componentDidLoad() {
788
757
  this.registerCustomSvgIcons();
789
758
  }
790
759
  async checkIsReady() {
791
760
  await customElements.whenDefined('kritzel-editor');
761
+ await customElements.whenDefined('kritzel-workspace-manager');
792
762
  await customElements.whenDefined('kritzel-controls');
793
763
  await customElements.whenDefined('kritzel-engine');
794
- if (!this.isEngineReady || !this.isControlsReady) {
764
+ if (!this.isEngineReady || !this.isControlsReady || !this.isWorkspaceManagerReady) {
795
765
  return;
796
766
  }
797
767
  this.isReady.emit(this.host);
798
768
  }
769
+ onEngineReady(event) {
770
+ this.isEngineReady = true;
771
+ this.activeWorkspace = event.detail.activeWorkspace;
772
+ this.workspaces = event.detail.workspaces;
773
+ }
799
774
  registerCustomSvgIcons() {
800
775
  for (const [name, svg] of Object.entries(this.customSvgIcons)) {
801
776
  KritzelIconRegistry.register(name, svg);
802
777
  }
803
778
  }
804
779
  render() {
805
- return (index.h(index.Host, { key: 'ddfb1861cc7fe2acda822b9389c3a049fe626deb' }, index.h("kritzel-engine", { key: 'ccbf2c636bdf63630ac06e1e8d3239c79bb7e774', ref: el => (this.engineRef = el), onIsEngineReady: () => (this.isEngineReady = true), scaleMax: this.scaleMax, scaleMin: this.scaleMin, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems }), index.h("kritzel-controls", { key: 'a0111b00ecbcb18c615c7f12f005f0edfe363af8', ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, style: this.isControlsVisible ? { display: 'flex' } : { display: 'none' }, onIsControlsReady: () => (this.isControlsReady = true) })));
780
+ return (index.h(index.Host, { key: '9fe00d70c1a875076e545ca447e2f8d817ebb2fd' }, index.h("kritzel-workspace-manager", { key: 'ca9ce9f8f277e92f78315e7eaba2bc523da5b9cb', workspaces: this.workspaces, activeWorkspace: this.activeWorkspace, onWorkspaceChange: event => this.activeWorkspace = event.detail, onIsWorkspaceManagerReady: () => (this.isWorkspaceManagerReady = true) }), index.h("kritzel-engine", { key: '098a4690198f0678e7b4c6c897f86ad1698f510f', ref: el => (this.engineRef = el), workspace: this.activeWorkspace, scaleMax: this.scaleMax, scaleMin: this.scaleMin, globalContextMenuItems: this.globalContextMenuItems, objectContextMenuItems: this.objectContextMenuItems, onIsEngineReady: event => this.onEngineReady(event), onWorkspacesChange: event => this.workspaces = event.detail }), index.h("kritzel-controls", { key: 'e1795f5a7460617628c09766f213c212e48f25e5', ref: el => (this.controlsRef = el), controls: this.controls, isUtilityPanelVisible: this.isUtilityPanelVisible, style: this.isControlsVisible ? { display: 'flex' } : { display: 'none' }, onIsControlsReady: () => (this.isControlsReady = true) })));
806
781
  }
807
782
  get host() { return index.getElement(this); }
808
783
  static get watchers() { return {
@@ -873,6 +848,7 @@ class KritzelViewport {
873
848
  this._store.state.hasViewportChanged = true;
874
849
  this._store.state.skipContextMenu = true;
875
850
  this._store.rerender();
851
+ this._store.updateWorkspaceViewport(this._store.state.translateX, this._store.state.translateY, this._store.state.scale);
876
852
  }
877
853
  }
878
854
  if (event.pointerType === 'touch') {
@@ -908,6 +884,7 @@ class KritzelViewport {
908
884
  this.startY = midpointY;
909
885
  this._store.state.hasViewportChanged = true;
910
886
  this._store.rerender();
887
+ this._store.updateWorkspaceViewport(this._store.state.translateX, this._store.state.translateY, this._store.state.scale);
911
888
  }
912
889
  }
913
890
  }
@@ -948,6 +925,7 @@ class KritzelViewport {
948
925
  this._store.state.translateY -= translateYAdjustment;
949
926
  this._store.state.hasViewportChanged = true;
950
927
  this._store.rerender();
928
+ this._store.updateWorkspaceViewport(this._store.state.translateX, this._store.state.translateY, this._store.state.scale);
951
929
  }
952
930
  handlePan(event) {
953
931
  const panSpeed = 0.8;
@@ -955,12 +933,13 @@ class KritzelViewport {
955
933
  this._store.state.translateY -= event.deltaY * panSpeed;
956
934
  this._store.state.hasViewportChanged = true;
957
935
  this._store.rerender();
936
+ this._store.updateWorkspaceViewport(this._store.state.translateX, this._store.state.translateY, this._store.state.scale);
958
937
  }
959
938
  }
960
939
 
961
940
  class UpdateViewportCommand extends index$1.KritzelBaseCommand {
962
- constructor(store, initiator, previousViewport) {
963
- super(store, initiator);
941
+ constructor(store, initiator, previousViewport, skipHistory = false) {
942
+ super(store, initiator, skipHistory);
964
943
  this.previousViewport = previousViewport;
965
944
  this.currentViewport = {
966
945
  scale: this._store.state.scale,
@@ -1038,16 +1017,29 @@ class KritzelHistory {
1038
1017
  translateY: this._store.state.translateY,
1039
1018
  };
1040
1019
  }
1020
+ reset() {
1021
+ this.undoStack.clear();
1022
+ this.redoStack.clear();
1023
+ this.previousViewport = {
1024
+ scale: this._store.state.scale,
1025
+ scaleStep: this._store.state.scaleStep,
1026
+ translateX: this._store.state.translateX,
1027
+ translateY: this._store.state.translateY
1028
+ };
1029
+ }
1041
1030
  executeCommand(command) {
1042
1031
  if (this._store.state.hasViewportChanged) {
1043
1032
  this.addUpdateViewportCommand();
1044
1033
  }
1045
1034
  command.execute();
1046
- if (this._store.state.debugInfo.logCommands)
1047
- console.info('add', command);
1048
- this.undoStack.add(command);
1049
- if (this.redoStack.isEmpty() === false) {
1050
- this.redoStack.clear();
1035
+ if (command.skipHistory === false) {
1036
+ if (this._store.state.debugInfo.logCommands) {
1037
+ console.info('add', command);
1038
+ }
1039
+ this.undoStack.add(command);
1040
+ if (this.redoStack.isEmpty() === false) {
1041
+ this.redoStack.clear();
1042
+ }
1051
1043
  }
1052
1044
  this._store.rerender();
1053
1045
  }
@@ -1102,6 +1094,10 @@ class KritzelOctree {
1102
1094
  this.bounds = bounds;
1103
1095
  this.capacity = capacity;
1104
1096
  }
1097
+ reset() {
1098
+ this.objects = [];
1099
+ this.children = null;
1100
+ }
1105
1101
  insert(object) {
1106
1102
  if (!this.intersects(object.rotatedBoundingBox, this.bounds)) {
1107
1103
  return false;
@@ -1206,35 +1202,8 @@ class KritzelOctree {
1206
1202
  }
1207
1203
  }
1208
1204
 
1209
- class UpdateObjectCommand extends index$1.KritzelBaseCommand {
1210
- constructor(store, initiator, object, updatedProperties) {
1211
- super(store, initiator);
1212
- this.object = object;
1213
- this.updatedProperties = updatedProperties;
1214
- this.previousProperties = {};
1215
- for (const key in updatedProperties) {
1216
- if (updatedProperties.hasOwnProperty(key)) {
1217
- this.previousProperties[key] = this.object[key];
1218
- }
1219
- }
1220
- }
1221
- execute() {
1222
- for (const key in this.updatedProperties) {
1223
- if (this.updatedProperties.hasOwnProperty(key)) {
1224
- this.object[key] = this.updatedProperties[key];
1225
- }
1226
- }
1227
- }
1228
- undo() {
1229
- for (const key in this.previousProperties) {
1230
- if (this.previousProperties.hasOwnProperty(key)) {
1231
- this.object[key] = this.previousProperties[key];
1232
- }
1233
- }
1234
- }
1235
- }
1236
-
1237
1205
  const DEFAULT_ENGINE_STATE = {
1206
+ activeWorkspace: null,
1238
1207
  activeTool: null,
1239
1208
  activeText: null,
1240
1209
  currentPath: null,
@@ -1268,6 +1237,7 @@ const DEFAULT_ENGINE_STATE = {
1268
1237
  showObjectInfo: false,
1269
1238
  showViewportInfo: false,
1270
1239
  logCommands: false,
1240
+ logDatabase: false,
1271
1241
  },
1272
1242
  host: null,
1273
1243
  pointerX: 0,
@@ -1275,7 +1245,7 @@ const DEFAULT_ENGINE_STATE = {
1275
1245
  scale: 1,
1276
1246
  scaleMax: 1,
1277
1247
  scaleMin: 1,
1278
- scaleStep: 0.05,
1248
+ scaleStep: 0.075,
1279
1249
  startX: 0,
1280
1250
  startY: 0,
1281
1251
  translateX: 0,
@@ -1289,13 +1259,254 @@ const DEFAULT_ENGINE_STATE = {
1289
1259
  historyBufferSize: 1000,
1290
1260
  longTouchTimeout: null,
1291
1261
  longTouchDelay: 300,
1292
- pointers: new Map()
1262
+ pointers: new Map(),
1263
+ workspaces: [],
1293
1264
  };
1294
1265
 
1266
+ class KritzelDatabase {
1267
+ constructor(dbName, dbVersion, isLoggingEnabled = false) {
1268
+ this.db = null;
1269
+ this.dbName = dbName;
1270
+ this.dbVersion = dbVersion;
1271
+ this.isLoggingEnabled = isLoggingEnabled;
1272
+ }
1273
+ async open(stores) {
1274
+ return new Promise((resolve, reject) => {
1275
+ if (this.db) {
1276
+ resolve();
1277
+ return;
1278
+ }
1279
+ if (this.isLoggingEnabled) {
1280
+ console.log(`[IndexedDB] Opening database: ${this.dbName}, version: ${this.dbVersion}`);
1281
+ }
1282
+ const request = indexedDB.open(this.dbName, this.dbVersion);
1283
+ request.onerror = () => {
1284
+ console.error('IndexedDB error:', request.error);
1285
+ reject(request.error);
1286
+ };
1287
+ request.onsuccess = () => {
1288
+ this.db = request.result;
1289
+ if (this.isLoggingEnabled) {
1290
+ console.log(`[IndexedDB] Database opened successfully.`);
1291
+ }
1292
+ resolve();
1293
+ };
1294
+ request.onupgradeneeded = event => {
1295
+ if (this.isLoggingEnabled) {
1296
+ console.log(`[IndexedDB] Upgrade needed for database: ${this.dbName}`);
1297
+ }
1298
+ const db = event.target.result;
1299
+ stores.forEach(storeConfig => {
1300
+ if (!db.objectStoreNames.contains(storeConfig.name)) {
1301
+ if (this.isLoggingEnabled) {
1302
+ console.log(`[IndexedDB] Creating store: ${storeConfig.name}`);
1303
+ }
1304
+ const store = db.createObjectStore(storeConfig.name, storeConfig.options);
1305
+ if (storeConfig.indices) {
1306
+ storeConfig.indices.forEach(index => {
1307
+ if (this.isLoggingEnabled) {
1308
+ console.log(`[IndexedDB] Creating index: ${index.name} on store: ${storeConfig.name}`);
1309
+ }
1310
+ store.createIndex(index.name, index.keyPath, index.options);
1311
+ });
1312
+ }
1313
+ }
1314
+ });
1315
+ };
1316
+ });
1317
+ }
1318
+ close() {
1319
+ if (this.db) {
1320
+ if (this.isLoggingEnabled) {
1321
+ console.log(`[IndexedDB] Closing database: ${this.dbName}`);
1322
+ }
1323
+ this.db.close();
1324
+ this.db = null;
1325
+ }
1326
+ }
1327
+ async add(storeName, item) {
1328
+ if (this.isLoggingEnabled) {
1329
+ console.log('[IndexedDB] Add:', { storeName, item });
1330
+ }
1331
+ return this.executeTransaction(storeName, 'readwrite', store => store.add(item));
1332
+ }
1333
+ async get(storeName, key) {
1334
+ if (this.isLoggingEnabled) {
1335
+ console.log('[IndexedDB] Get:', { storeName, key });
1336
+ }
1337
+ return this.executeTransaction(storeName, 'readonly', store => store.get(key));
1338
+ }
1339
+ async getAll(storeName) {
1340
+ if (this.isLoggingEnabled) {
1341
+ console.log('[IndexedDB] GetAll:', { storeName });
1342
+ }
1343
+ return this.executeTransaction(storeName, 'readonly', store => store.getAll());
1344
+ }
1345
+ async update(storeName, item) {
1346
+ if (this.isLoggingEnabled) {
1347
+ console.log('[IndexedDB] Update:', { storeName, item });
1348
+ }
1349
+ return this.executeTransaction(storeName, 'readwrite', store => store.put(item));
1350
+ }
1351
+ async delete(storeName, key) {
1352
+ if (this.isLoggingEnabled) {
1353
+ console.log('[IndexedDB] Delete:', { storeName, key });
1354
+ }
1355
+ return this.executeTransaction(storeName, 'readwrite', store => store.delete(key));
1356
+ }
1357
+ async deleteByRange(storeName, range) {
1358
+ if (this.isLoggingEnabled) {
1359
+ console.log('[IndexedDB] DeleteByRange:', { storeName, range });
1360
+ }
1361
+ return this.executeTransaction(storeName, 'readwrite', store => store.delete(range));
1362
+ }
1363
+ async getAllByRange(storeName, range) {
1364
+ if (this.isLoggingEnabled) {
1365
+ console.log('[IndexedDB] GetAllByRange:', { storeName, range });
1366
+ }
1367
+ return this.executeTransaction(storeName, 'readonly', store => {
1368
+ return store.getAll(range);
1369
+ });
1370
+ }
1371
+ async getAllByIndex(storeName, indexName, query) {
1372
+ if (this.isLoggingEnabled) {
1373
+ console.log('[IndexedDB] GetAllByIndex:', { storeName, indexName, query });
1374
+ }
1375
+ return this.executeTransaction(storeName, 'readonly', store => {
1376
+ const index = store.index(indexName);
1377
+ return index.getAll(query);
1378
+ });
1379
+ }
1380
+ async executeTransaction(storeName, mode, action) {
1381
+ if (!this.db) {
1382
+ throw new Error('Database is not open.');
1383
+ }
1384
+ return new Promise((resolve, reject) => {
1385
+ const transaction = this.db.transaction(storeName, mode);
1386
+ const store = transaction.objectStore(storeName);
1387
+ const request = action(store);
1388
+ let requestResult;
1389
+ transaction.oncomplete = () => {
1390
+ resolve(requestResult);
1391
+ };
1392
+ transaction.onabort = () => {
1393
+ var _a;
1394
+ reject((_a = transaction.error) !== null && _a !== void 0 ? _a : new Error('Transaction aborted'));
1395
+ };
1396
+ transaction.onerror = () => {
1397
+ reject(transaction.error);
1398
+ };
1399
+ request.onsuccess = () => {
1400
+ requestResult = request.result;
1401
+ };
1402
+ });
1403
+ }
1404
+ async batch(actions) {
1405
+ if (!this.db) {
1406
+ throw new Error('Database is not open.');
1407
+ }
1408
+ const storeNames = await this.extractStoreNamesFromActions(actions);
1409
+ if (this.isLoggingEnabled) {
1410
+ console.log('[IndexedDB] Starting batch transaction:', { storeNames });
1411
+ }
1412
+ return new Promise((resolve, reject) => {
1413
+ const transaction = this.db.transaction(storeNames, 'readwrite');
1414
+ const results = [];
1415
+ const promises = [];
1416
+ const tempDbInstance = {
1417
+ add: (storeName, item) => this.add(storeName, item),
1418
+ get: (storeName, key) => this.get(storeName, key),
1419
+ getAll: (storeName) => this.getAll(storeName),
1420
+ update: (storeName, item) => this.update(storeName, item),
1421
+ delete: (storeName, key) => this.delete(storeName, key),
1422
+ deleteByRange: (storeName, range) => this.deleteByRange(storeName, range),
1423
+ getAllByRange: (storeName, range) => this.getAllByRange(storeName, range),
1424
+ getAllByIndex: (storeName, indexName, query) => this.getAllByIndex(storeName, indexName, query),
1425
+ executeTransaction: (storeName, mode, action) => {
1426
+ return new Promise((resolveRequest, rejectRequest) => {
1427
+ if (this.isLoggingEnabled) {
1428
+ console.log('[IndexedDB] Executing batch action:', { storeName, mode });
1429
+ }
1430
+ const store = transaction.objectStore(storeName);
1431
+ const request = action(store);
1432
+ request.onsuccess = () => {
1433
+ if (this.isLoggingEnabled) {
1434
+ console.log('[IndexedDB] Batch action request successful:', { result: request.result });
1435
+ }
1436
+ resolveRequest(request.result);
1437
+ };
1438
+ request.onerror = () => {
1439
+ console.error('[IndexedDB] Batch action request error:', request.error);
1440
+ rejectRequest(request.error);
1441
+ };
1442
+ });
1443
+ },
1444
+ };
1445
+ transaction.oncomplete = () => {
1446
+ if (this.isLoggingEnabled) {
1447
+ console.log('[IndexedDB] Batch transaction complete.');
1448
+ }
1449
+ Promise.all(promises).then(() => resolve(results));
1450
+ };
1451
+ transaction.onabort = () => {
1452
+ var _a;
1453
+ console.error('[IndexedDB] Batch transaction aborted:', transaction.error);
1454
+ reject((_a = transaction.error) !== null && _a !== void 0 ? _a : new Error('Transaction aborted'));
1455
+ };
1456
+ transaction.onerror = () => {
1457
+ console.error('[IndexedDB] Batch transaction error:', transaction.error);
1458
+ reject(transaction.error);
1459
+ };
1460
+ actions.forEach((action, index) => {
1461
+ const promise = action(tempDbInstance)
1462
+ .then(result => {
1463
+ results[index] = result;
1464
+ })
1465
+ .catch(err => {
1466
+ if (!transaction.error) {
1467
+ transaction.abort();
1468
+ }
1469
+ reject(err);
1470
+ });
1471
+ promises.push(promise);
1472
+ });
1473
+ });
1474
+ }
1475
+ async extractStoreNamesFromActions(actions) {
1476
+ const storeNamesSet = new Set();
1477
+ const storeNameCollector = new Proxy(this, {
1478
+ get: (target, prop) => {
1479
+ if (['add', 'get', 'getAll', 'update', 'delete', 'deleteByRange', 'getAllByRange', 'getAllByIndex'].includes(prop)) {
1480
+ return (storeName) => {
1481
+ storeNamesSet.add(storeName);
1482
+ return Promise.resolve();
1483
+ };
1484
+ }
1485
+ return target[prop];
1486
+ },
1487
+ });
1488
+ await Promise.all(actions.map(action => action(storeNameCollector)));
1489
+ return Array.from(storeNamesSet);
1490
+ }
1491
+ }
1492
+
1493
+ class KritzelWorkspace {
1494
+ constructor(id, name, viewport = { translateX: 0, translateY: 0, scale: 1 }) {
1495
+ this.id = id;
1496
+ this.name = name;
1497
+ this.createdAt = new Date();
1498
+ this.updatedAt = new Date();
1499
+ this.viewport = viewport;
1500
+ }
1501
+ }
1502
+
1295
1503
  class KritzelStore {
1296
1504
  get history() {
1297
1505
  return this._history;
1298
1506
  }
1507
+ get database() {
1508
+ return this._database;
1509
+ }
1299
1510
  get state() {
1300
1511
  return this._state;
1301
1512
  }
@@ -1314,12 +1525,16 @@ class KritzelStore {
1314
1525
  get offsetY() {
1315
1526
  return this._state.host.getBoundingClientRect().top;
1316
1527
  }
1528
+ get isDisabled() {
1529
+ return this._state.isEnabled === false || this._state.isReady === false || this._state.activeWorkspace === null;
1530
+ }
1317
1531
  constructor(kritzelEngine) {
1318
1532
  this._listeners = new Map();
1319
1533
  this.objects = [];
1320
1534
  this._state = DEFAULT_ENGINE_STATE;
1321
1535
  this._kritzelEngine = kritzelEngine;
1322
1536
  this._history = new KritzelHistory(this);
1537
+ this._database = new KritzelDatabase('kritzelDB', 1, this._state.debugInfo.logDatabase);
1323
1538
  this._state.objectsOctree = new KritzelOctree({
1324
1539
  x: -Infinity,
1325
1540
  y: -Infinity,
@@ -1329,16 +1544,135 @@ class KritzelStore {
1329
1544
  depth: Infinity,
1330
1545
  });
1331
1546
  }
1332
- rerender() {
1333
- const viewportBounds = {
1334
- x: -this._state.translateX / this._state.scale,
1335
- y: -this._state.translateY / this._state.scale,
1336
- z: this._state.scale,
1337
- width: this._state.viewportWidth / this._state.scale,
1338
- height: this._state.viewportHeight / this._state.scale,
1339
- depth: 100,
1547
+ async initializeDatabase() {
1548
+ await this._database.open([
1549
+ {
1550
+ name: 'objects',
1551
+ options: { keyPath: ['workspaceId', 'id'] },
1552
+ },
1553
+ { name: 'workspaces', options: { keyPath: 'id' } },
1554
+ ]);
1555
+ this.rerender();
1556
+ }
1557
+ async initializeWorkspace(workspace) {
1558
+ var _a;
1559
+ const workspaces = await this.getWorkspaces();
1560
+ const mostRecentWorkspace = [...workspaces].sort((a, b) => b.updatedAt.getTime() - a.updatedAt.getTime())[0];
1561
+ const fallbackWorkspace = new KritzelWorkspace(index$1.ObjectHelper.generateUUID(), 'New Workspace');
1562
+ this._state.activeWorkspace = (_a = workspace !== null && workspace !== void 0 ? workspace : mostRecentWorkspace) !== null && _a !== void 0 ? _a : fallbackWorkspace;
1563
+ const isExistingWorkspace = await this.getWorkspace(this._state.activeWorkspace.id);
1564
+ if (isExistingWorkspace) {
1565
+ await this.updateWorkspace(this._state.activeWorkspace);
1566
+ }
1567
+ else {
1568
+ await this.createWorkspace(this._state.activeWorkspace);
1569
+ }
1570
+ this._state.workspaces = await this.getWorkspaces();
1571
+ this.state.translateX = this._state.activeWorkspace.viewport.translateX;
1572
+ this.state.translateY = this._state.activeWorkspace.viewport.translateY;
1573
+ this.state.scale = this._state.activeWorkspace.viewport.scale;
1574
+ await this.initializeWorkspaceObjects(this._state.activeWorkspace.id);
1575
+ }
1576
+ async initializeWorkspaceObjects(workspaceId) {
1577
+ this._state.objectsOctree.reset();
1578
+ this._history.reset();
1579
+ const objectsFromDb = await this._database.getAllByRange('objects', IDBKeyRange.bound([workspaceId], [workspaceId, '\uffff']));
1580
+ const reviver = new index$1.KritzelReviver(this);
1581
+ objectsFromDb.forEach(element => {
1582
+ const revivedObject = reviver.revive(element);
1583
+ this._state.objectsOctree.insert(revivedObject);
1584
+ });
1585
+ this.rerender();
1586
+ }
1587
+ async updateWorkspaceViewport(translateX, translateY, scale) {
1588
+ if (!this.state.activeWorkspace) {
1589
+ throw new Error('Workspace not initialized');
1590
+ }
1591
+ this.state.activeWorkspace.viewport = {
1592
+ translateX,
1593
+ translateY,
1594
+ scale,
1340
1595
  };
1341
- this.objects = this._state.objectsOctree.query(viewportBounds);
1596
+ this.state.activeWorkspace.updatedAt = new Date();
1597
+ await this._database.update('workspaces', this.state.activeWorkspace);
1598
+ }
1599
+ async addObjectToDatabase(object) {
1600
+ if (!this._database) {
1601
+ throw new Error('Database not initialized');
1602
+ }
1603
+ if (!this.state.activeWorkspace) {
1604
+ throw new Error('Workspace not initialized');
1605
+ }
1606
+ this.state.activeWorkspace.updatedAt = new Date();
1607
+ await this._database.batch([db => db.add('objects', object), db => db.update('workspaces', this.state.activeWorkspace)]).catch(err => {
1608
+ console.error('Error adding object to database:', err);
1609
+ });
1610
+ }
1611
+ async updateObjectInDatabase(object) {
1612
+ if (!this._database) {
1613
+ throw new Error('Database not initialized');
1614
+ }
1615
+ if (!this.state.activeWorkspace) {
1616
+ throw new Error('Workspace not initialized');
1617
+ }
1618
+ this.state.activeWorkspace.updatedAt = new Date();
1619
+ await this._database.batch([db => db.update('objects', object), db => db.update('workspaces', this.state.activeWorkspace)]).catch(err => {
1620
+ console.error('Error updating object in database:', err);
1621
+ });
1622
+ }
1623
+ async deleteObjectFromDatabase(objectId) {
1624
+ if (!this._database) {
1625
+ throw new Error('Database not initialized');
1626
+ }
1627
+ if (!this.state.activeWorkspace) {
1628
+ throw new Error('Workspace not initialized');
1629
+ }
1630
+ this.state.activeWorkspace.updatedAt = new Date();
1631
+ await this._database.batch([db => db.delete('objects', [this.state.activeWorkspace.id, objectId]), db => db.update('workspaces', this.state.activeWorkspace)]).catch(err => {
1632
+ console.error('Error deleting object from database:', err);
1633
+ });
1634
+ }
1635
+ getWorkspace(id) {
1636
+ if (!this._database) {
1637
+ throw new Error('Database not initialized');
1638
+ }
1639
+ return this._database.get('workspaces', id);
1640
+ }
1641
+ getWorkspaces() {
1642
+ if (!this._database) {
1643
+ throw new Error('Database not initialized');
1644
+ }
1645
+ return this._database.getAll('workspaces');
1646
+ }
1647
+ async createWorkspace(workspace) {
1648
+ if (!this._database) {
1649
+ throw new Error('Database not initialized');
1650
+ }
1651
+ workspace.createdAt = new Date();
1652
+ workspace.updatedAt = new Date();
1653
+ await this._database.add('workspaces', workspace);
1654
+ this.state.workspaces.push(workspace);
1655
+ }
1656
+ async updateWorkspace(workspace) {
1657
+ if (!this._database) {
1658
+ throw new Error('Database not initialized');
1659
+ }
1660
+ workspace.updatedAt = new Date();
1661
+ await this._database.update('workspaces', workspace);
1662
+ const index = this.state.workspaces.findIndex(w => w.id === workspace.id);
1663
+ if (index !== -1) {
1664
+ this.state.workspaces[index] = workspace;
1665
+ }
1666
+ }
1667
+ async deleteWorkspace(workspace) {
1668
+ if (!this._database) {
1669
+ throw new Error('Database not initialized');
1670
+ }
1671
+ const objectRange = IDBKeyRange.bound([workspace.id], [workspace.id, '\uffff']);
1672
+ await this._database.deleteByRange('objects', objectRange);
1673
+ await this._database.delete('workspaces', workspace.id);
1674
+ }
1675
+ rerender() {
1342
1676
  if (this._kritzelEngine) {
1343
1677
  this._kritzelEngine.forceUpdate++;
1344
1678
  }
@@ -1380,17 +1714,11 @@ class KritzelStore {
1380
1714
  const commands = [...deleteSelectedObjectsCommand, removeSelectionGroupCommand];
1381
1715
  this.history.executeCommand(new index$1.BatchCommand(this, this.state.selectionGroup, commands));
1382
1716
  }
1383
- deleteObject(id, isHistoryUpdated = true) {
1717
+ deleteObject(id, skipHistory = false) {
1384
1718
  const object = this.findObjectById(id);
1385
1719
  if (object) {
1386
- if (isHistoryUpdated) {
1387
- const removeObjectCommand = new index$1.RemoveObjectCommand(this, this, object);
1388
- this.history.executeCommand(removeObjectCommand);
1389
- }
1390
- else {
1391
- this._state.objectsOctree.remove(obj => obj.id === id);
1392
- this.rerender();
1393
- }
1720
+ const removeObjectCommand = new index$1.RemoveObjectCommand(this, this, object, skipHistory);
1721
+ this.history.executeCommand(removeObjectCommand);
1394
1722
  }
1395
1723
  }
1396
1724
  copy() {
@@ -1420,7 +1748,7 @@ class KritzelStore {
1420
1748
  if (obj.zIndex === max) {
1421
1749
  return;
1422
1750
  }
1423
- return new UpdateObjectCommand(this, this, obj, { zIndex: obj.zIndex + 1 });
1751
+ return new index$1.UpdateObjectCommand(this, this, obj, { zIndex: obj.zIndex + 1 });
1424
1752
  });
1425
1753
  this.history.executeCommand(new index$1.BatchCommand(this, this, increaseZIndexCommands));
1426
1754
  }
@@ -1431,7 +1759,7 @@ class KritzelStore {
1431
1759
  if (obj.zIndex === min) {
1432
1760
  return;
1433
1761
  }
1434
- return new UpdateObjectCommand(this, this, obj, { zIndex: obj.zIndex - 1 });
1762
+ return new index$1.UpdateObjectCommand(this, this, obj, { zIndex: obj.zIndex - 1 });
1435
1763
  });
1436
1764
  this.history.executeCommand(new index$1.BatchCommand(this, this, decreaseZIndexCommands));
1437
1765
  }
@@ -1439,7 +1767,7 @@ class KritzelStore {
1439
1767
  const max = Math.max(...this.allObjects.map(obj => obj.zIndex)) + 1;
1440
1768
  const objects = object ? [object] : this.state.selectionGroup.objects;
1441
1769
  const increaseZIndexCommands = objects.map(obj => {
1442
- return new UpdateObjectCommand(this, this, obj, { zIndex: max });
1770
+ return new index$1.UpdateObjectCommand(this, this, obj, { zIndex: max });
1443
1771
  });
1444
1772
  this.history.executeCommand(new index$1.BatchCommand(this, this, increaseZIndexCommands));
1445
1773
  }
@@ -1447,7 +1775,7 @@ class KritzelStore {
1447
1775
  const min = Math.min(...this.allObjects.map(obj => obj.zIndex)) - 1;
1448
1776
  const objects = object ? [object] : this.state.selectionGroup.objects;
1449
1777
  const decreaseZIndexCommands = objects.map(obj => {
1450
- return new UpdateObjectCommand(this, this, obj, { zIndex: min });
1778
+ return new index$1.UpdateObjectCommand(this, this, obj, { zIndex: min });
1451
1779
  });
1452
1780
  this.history.executeCommand(new index$1.BatchCommand(this, this, decreaseZIndexCommands));
1453
1781
  }
@@ -1504,8 +1832,7 @@ class KritzelStore {
1504
1832
  }
1505
1833
  resetActiveText() {
1506
1834
  if (this.state.activeText && this.state.activeText.value === ' ') {
1507
- this.deleteObject(this.state.activeText.id, false);
1508
- this.history.undoStack.pop();
1835
+ this.deleteObject(this.state.activeText.id, true);
1509
1836
  }
1510
1837
  this.state.activeText = null;
1511
1838
  }
@@ -1572,7 +1899,6 @@ class KritzelKeyHandler extends index$1.KritzelBaseHandler {
1572
1899
  }
1573
1900
  handleKeyDown(event) {
1574
1901
  if (this._store.state.isFocused === false) {
1575
- event.preventDefault();
1576
1902
  return;
1577
1903
  }
1578
1904
  this._store.state.isCtrlKeyPressed = event.ctrlKey;
@@ -1691,13 +2017,18 @@ class KritzelContextMenuHandler extends index$1.KritzelBaseHandler {
1691
2017
 
1692
2018
  class KritzelClassHelper {
1693
2019
  static isInstanceOf(object, className) {
1694
- return object.__class__ === className;
2020
+ return !!object && object.__class__ === className;
1695
2021
  }
1696
2022
  }
1697
2023
 
1698
2024
  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}.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}textarea{all:unset;box-sizing:border-box;outline:none !important;border:none !important;overflow:visible}.resize-handle-overlay.top-left,.resize-handle-overlay.bottom-right{cursor:nwse-resize}.resize-handle-overlay.top-right,.resize-handle-overlay.bottom-left{cursor:nesw-resize}.rotation-handle-overlay{cursor:grab}";
1699
2025
 
1700
2026
  const KritzelEngine = class {
2027
+ onWorkspaceChange(newWorkspace) {
2028
+ if (newWorkspace) {
2029
+ this.store.initializeWorkspace(newWorkspace);
2030
+ }
2031
+ }
1701
2032
  validateScaleMax(newValue) {
1702
2033
  if (newValue > ABSOLUTE_SCALE_MAX) {
1703
2034
  console.warn(`scaleMax cannot be greater than ${ABSOLUTE_SCALE_MAX}.`);
@@ -1728,6 +2059,7 @@ const KritzelEngine = class {
1728
2059
  index.registerInstance(this, hostRef);
1729
2060
  this.isEngineReady = index.createEvent(this, "isEngineReady");
1730
2061
  this.activeToolChange = index.createEvent(this, "activeToolChange");
2062
+ this.workspacesChange = index.createEvent(this, "workspacesChange");
1731
2063
  this.scaleMax = ABSOLUTE_SCALE_MAX;
1732
2064
  this.scaleMin = ABSOLUTE_SCALE_MIN;
1733
2065
  this.forceUpdate = 0;
@@ -1738,18 +2070,23 @@ const KritzelEngine = class {
1738
2070
  this.validateScaleMax(this.scaleMax);
1739
2071
  this.validateScaleMin(this.scaleMin);
1740
2072
  }
1741
- componentDidLoad() {
2073
+ async componentDidLoad() {
1742
2074
  this.contextMenuHandler = new KritzelContextMenuHandler(this.store, this.globalContextMenuItems, this.objectContextMenuItems);
1743
2075
  this.keyHandler = new KritzelKeyHandler(this.store);
1744
2076
  this.viewport = new KritzelViewport(this.store, this.host);
1745
2077
  this._registerStateChangeListeners();
2078
+ await this.store.initializeDatabase();
2079
+ await this.store.initializeWorkspace(this.workspace);
1746
2080
  if (this.store.state.isReady === false) {
1747
2081
  this.store.state.isReady = true;
1748
- this.isEngineReady.emit();
2082
+ this.isEngineReady.emit(this.store.state);
1749
2083
  }
1750
2084
  }
1751
2085
  handleWheel(ev) {
1752
2086
  var _a, _b;
2087
+ if (this.store.isDisabled) {
2088
+ return;
2089
+ }
1753
2090
  if (this.store.state.isContextMenuVisible) {
1754
2091
  this.hideContextMenu();
1755
2092
  }
@@ -1758,11 +2095,11 @@ const KritzelEngine = class {
1758
2095
  }
1759
2096
  handlePointerDown(ev) {
1760
2097
  var _a, _b;
1761
- if (index$1.KritzelEventHelper.isPointerEventOnContextMenu(ev) === false && this.store.state.isContextMenuVisible) {
1762
- this.hideContextMenu();
2098
+ if (this.store.isDisabled) {
1763
2099
  return;
1764
2100
  }
1765
- if (this.store.state.isEnabled === false) {
2101
+ if (index$1.KritzelEventHelper.isPointerEventOnContextMenu(ev) === false && this.store.state.isContextMenuVisible) {
2102
+ this.hideContextMenu();
1766
2103
  return;
1767
2104
  }
1768
2105
  index$1.KritzelEventHelper.onLongTouchPress(ev, (event) => {
@@ -1778,7 +2115,7 @@ const KritzelEngine = class {
1778
2115
  }
1779
2116
  handlePointerMove(ev) {
1780
2117
  var _a, _b;
1781
- if (this.store.state.isEnabled === false) {
2118
+ if (this.store.isDisabled) {
1782
2119
  return;
1783
2120
  }
1784
2121
  this.store.state.pointers.set(ev.pointerId, ev);
@@ -1787,7 +2124,7 @@ const KritzelEngine = class {
1787
2124
  }
1788
2125
  handlePointerUp(ev) {
1789
2126
  var _a, _b;
1790
- if (this.store.state.isEnabled === false) {
2127
+ if (this.store.isDisabled) {
1791
2128
  return;
1792
2129
  }
1793
2130
  this.store.state.pointers.delete(ev.pointerId);
@@ -1797,7 +2134,7 @@ const KritzelEngine = class {
1797
2134
  }
1798
2135
  handlePointerCancel(ev) {
1799
2136
  var _a, _b;
1800
- if (this.store.state.isEnabled === false) {
2137
+ if (this.store.isDisabled) {
1801
2138
  return;
1802
2139
  }
1803
2140
  this.host.releasePointerCapture(ev.pointerId);
@@ -1807,7 +2144,7 @@ const KritzelEngine = class {
1807
2144
  }
1808
2145
  handleContextMenu(ev) {
1809
2146
  ev.preventDefault();
1810
- if (this.store.state.isEnabled === false) {
2147
+ if (this.store.isDisabled) {
1811
2148
  return;
1812
2149
  }
1813
2150
  if (ev.pointerType === 'touch') {
@@ -1825,6 +2162,9 @@ const KritzelEngine = class {
1825
2162
  this.keyHandler.handleKeyUp(ev);
1826
2163
  }
1827
2164
  updateFocus(ev) {
2165
+ if (this.store.isDisabled) {
2166
+ return;
2167
+ }
1828
2168
  const rect = this.store.state.host.getBoundingClientRect();
1829
2169
  const isInside = ev.clientX >= rect.left && ev.clientX <= rect.right && ev.clientY >= rect.top && ev.clientY <= rect.bottom;
1830
2170
  const path = ev.composedPath();
@@ -1832,6 +2172,9 @@ const KritzelEngine = class {
1832
2172
  const isInKritzelEngine = path.includes(kritzelEngineElement || this.host);
1833
2173
  this.store.setState('isFocused', isInside && isInKritzelEngine);
1834
2174
  }
2175
+ handleClick() {
2176
+ this.enable();
2177
+ }
1835
2178
  async registerTool(toolName, toolClass, toolConfig) {
1836
2179
  if (typeof toolClass !== 'function' || !(toolClass.prototype instanceof index$1.KritzelBaseTool)) {
1837
2180
  console.error(`Failed to register tool "${toolName}": Tool class must be a constructor function`);
@@ -1913,7 +2256,7 @@ const KritzelEngine = class {
1913
2256
  }
1914
2257
  async updateObject(object, updatedProperties) {
1915
2258
  this.store.deselectAllObjects();
1916
- const command = new UpdateObjectCommand(this.store, this, object, updatedProperties);
2259
+ const command = new index$1.UpdateObjectCommand(this.store, this, object, updatedProperties);
1917
2260
  this.store.history.executeCommand(command);
1918
2261
  return object;
1919
2262
  }
@@ -1945,7 +2288,7 @@ const KritzelEngine = class {
1945
2288
  }
1946
2289
  async centerObjectInViewport(object) {
1947
2290
  object.centerInViewport();
1948
- const command = new UpdateObjectCommand(this.store, this, object, object);
2291
+ const command = new index$1.UpdateObjectCommand(this.store, this, object, object);
1949
2292
  this.store.history.executeCommand(command);
1950
2293
  return object;
1951
2294
  }
@@ -1953,6 +2296,24 @@ const KritzelEngine = class {
1953
2296
  var _a;
1954
2297
  return ((_a = this.store.state.copiedObjects) === null || _a === void 0 ? void 0 : _a.objects) || [];
1955
2298
  }
2299
+ async createWorkspace(workspace) {
2300
+ return this.store.createWorkspace(workspace).then(() => {
2301
+ this.workspacesChange.emit(this.store.state.workspaces);
2302
+ });
2303
+ }
2304
+ async updateWorkspace(workspace) {
2305
+ return this.store.updateWorkspace(workspace).then(() => {
2306
+ this.workspacesChange.emit(this.store.state.workspaces);
2307
+ });
2308
+ }
2309
+ async deleteWorkspace(workspace) {
2310
+ return this.store.deleteWorkspace(workspace).then(() => {
2311
+ this.workspacesChange.emit(this.store.state.workspaces.filter(ws => ws.id !== workspace.id));
2312
+ });
2313
+ }
2314
+ async getWorkspaces() {
2315
+ return this.store.getWorkspaces();
2316
+ }
1956
2317
  _registerStateChangeListeners() {
1957
2318
  this.store.onStateChange('activeTool', this._handleActiveToolChange.bind(this));
1958
2319
  this.store.onStateChange('isFocused', this._handleIsFocusedChange.bind(this));
@@ -1971,25 +2332,27 @@ const KritzelEngine = class {
1971
2332
  }
1972
2333
  }
1973
2334
  render() {
1974
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4;
2335
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6, _7, _8;
1975
2336
  const computedStyle = window.getComputedStyle(this.host);
1976
2337
  const baseHandleSizePx = computedStyle.getPropertyValue('--kritzel-selection-handle-size').trim() || '6px';
1977
2338
  const baseHandleSize = parseFloat(baseHandleSizePx);
1978
2339
  const baseHandleTouchSize = baseHandleSize * 2 < 14 ? 14 : baseHandleSize;
1979
- return (index.h(index.Host, { key: '9662d9be6c5537340fe8416a5f74f3dec995fc91' }, index.h("div", { key: '4f42e6cf0ee0b77c672e7485a53ffed7a75961fa', class: "debug-panel", style: { display: this.store.state.debugInfo.showViewportInfo ? 'block' : 'none' } }, index.h("div", { key: '75bb2ea8e945c4d65d86a90f4f6da95ccd4425d1' }, "TranslateX: ", (_a = this.store.state) === null || _a === void 0 ? void 0 :
1980
- _a.translateX), index.h("div", { key: '69558794d6b88fece7c8af2be3cf5930174b8fd6' }, "TranslateY: ", (_b = this.store.state) === null || _b === void 0 ? void 0 :
1981
- _b.translateY), index.h("div", { key: 'd2e933f23eef9ee56137906f56c5cbadbaadaf23' }, "ViewportWidth: ", (_c = this.store.state) === null || _c === void 0 ? void 0 :
1982
- _c.viewportWidth), index.h("div", { key: 'c085fee84706c0be930d1e659dedb8a2728130dd' }, "ViewportHeight: ", (_d = this.store.state) === null || _d === void 0 ? void 0 :
1983
- _d.viewportHeight), index.h("div", { key: 'eeef8323ae0bc5047f038f4794aee4ed718d1183' }, "ObjectsInViewport. ", this.store.objects.length), index.h("div", { key: '20172772854ab20ee9dd9b4bf9b969627c649e61' }, "Scale: ", (_e = this.store.state) === null || _e === void 0 ? void 0 :
1984
- _e.scale), index.h("div", { key: '256646b05f63bc6949578acb1739f57a581c86e4' }, "ActiveTool: ", (_g = (_f = this.store.state) === null || _f === void 0 ? void 0 : _f.activeTool) === null || _g === void 0 ? void 0 :
1985
- _g.name), index.h("div", { key: 'd9e17c3c89a135fcbaf1cdfaa8f8123186c74626' }, "HasViewportChanged: ", ((_h = this.store.state) === null || _h === void 0 ? void 0 : _h.hasViewportChanged) ? 'true' : 'false'), index.h("div", { key: '7750bc5b2763e6351eb37f51b54bca965f7e0823' }, "IsEnabled: ", ((_j = this.store.state) === null || _j === void 0 ? void 0 : _j.isEnabled) ? 'true' : 'false'), index.h("div", { key: '59ca295c0ab33fe6d82ccd1072fe64672c9f21b7' }, "IsScaling: ", ((_k = this.store.state) === null || _k === void 0 ? void 0 : _k.isScaling) ? 'true' : 'false'), index.h("div", { key: 'b413ddf6bbc8e7e758abd811f3e66a71a4961a04' }, "IsPanning: ", ((_l = this.store.state) === null || _l === void 0 ? void 0 : _l.isPanning) ? 'true' : 'false'), index.h("div", { key: 'c941fe71c6d3a124bcb02ff6d1efa33d943646aa' }, "IsFocused: ", this.store.state.isFocused ? 'true' : 'false'), index.h("div", { key: 'f060e324991d0885770cfbedf8332047a3ede890' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), index.h("div", { key: 'ec3f85f2cc61bb55210cfa952ce8b1af66c4caf4' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), index.h("div", { key: '0376abe30d6456038a98383a82eff2ec955fd69a' }, "IsResizeHandleSelected: ", this.store.state.isResizeHandleSelected ? 'true' : 'false'), index.h("div", { key: '546d868377d654400e9013f8df54389e08a2c02d' }, "IsRotationHandleSelected: ", this.store.state.isRotationHandleSelected ? 'true' : 'false'), index.h("div", { key: 'b233911cad585a5318dd0a83258d477dd3e286f7' }, "IsDrawing: ", this.store.state.isDrawing ? 'true' : 'false'), index.h("div", { key: '4fd9f89a72c49bb681695030245d4622ffe281b5' }, "IsWriting: ", this.store.state.isWriting ? 'true' : 'false'), index.h("div", { key: 'e7c3b3485b945fff20dd0c6601727b52478a283b' }, "PointerX: ", (_m = this.store.state) === null || _m === void 0 ? void 0 :
1986
- _m.pointerX), index.h("div", { key: '0e940ac9609f23f1e4855206dda52c52eec14fe5' }, "PointerY: ", (_o = this.store.state) === null || _o === void 0 ? void 0 :
1987
- _o.pointerY), index.h("div", { key: '60475be8341d3a8e28416d91a38d188bce30d15b' }, "SelectedObjects: ", ((_p = this.store.state.selectionGroup) === null || _p === void 0 ? void 0 : _p.objects.length) || 0)), index.h("div", { key: '16608718942fd141d17a5d398045e178fa37eacf', id: "origin", class: "origin", style: {
1988
- transform: `matrix(${(_q = this.store.state) === null || _q === void 0 ? void 0 : _q.scale}, 0, 0, ${(_r = this.store.state) === null || _r === void 0 ? void 0 : _r.scale}, ${(_s = this.store.state) === null || _s === void 0 ? void 0 : _s.translateX}, ${(_t = this.store.state) === null || _t === void 0 ? void 0 : _t.translateY})`,
1989
- } }, (_u = this.store.objects) === null || _u === void 0 ? void 0 :
1990
- _u.map(object => {
2340
+ return (index.h(index.Host, { key: 'c7e747aa6106e7904cf9f44db37fa285a6fb4434' }, index.h("div", { key: 'b75652ab9f9531dce765cbe448ad3131c172d06a', class: "debug-panel", style: { display: this.store.state.debugInfo.showViewportInfo ? 'block' : 'none' } }, index.h("div", { key: 'fd1355bd640b9296949f6bbcf084589578654db6' }, "ActiveWorkspaceId: ", (_b = (_a = this.store.state) === null || _a === void 0 ? void 0 : _a.activeWorkspace) === null || _b === void 0 ? void 0 :
2341
+ _b.id), index.h("div", { key: '8520e3e774e97ebc42ee86401fbfbafbe41c88e8' }, "ActiveWorkspaceName: ", (_d = (_c = this.store.state) === null || _c === void 0 ? void 0 : _c.activeWorkspace) === null || _d === void 0 ? void 0 :
2342
+ _d.name), index.h("div", { key: 'f247b4d76cd018e787a9b59829deedeb6c5c5272' }, "TranslateX: ", (_e = this.store.state) === null || _e === void 0 ? void 0 :
2343
+ _e.translateX), index.h("div", { key: 'e0438479bc9e950ef2cbe88ed0aa0b8ec1888890' }, "TranslateY: ", (_f = this.store.state) === null || _f === void 0 ? void 0 :
2344
+ _f.translateY), index.h("div", { key: '1735fde66588e285039bcc090dee71630608d666' }, "ViewportWidth: ", (_g = this.store.state) === null || _g === void 0 ? void 0 :
2345
+ _g.viewportWidth), index.h("div", { key: '15f8b3305c27a395b8aa6463c5acec42bb3e3ddd' }, "ViewportHeight: ", (_h = this.store.state) === null || _h === void 0 ? void 0 :
2346
+ _h.viewportHeight), index.h("div", { key: 'd2e39bae191c7256967d0140f38e75dccf95f24c' }, "ObjectsInViewport. ", this.store.objects.length), index.h("div", { key: 'cd3f53ff4a8f119a2ef975133f69fc3798fe0f71' }, "Scale: ", (_j = this.store.state) === null || _j === void 0 ? void 0 :
2347
+ _j.scale), index.h("div", { key: 'b1f8c77589a80fe49d0947602bda46438921f7a8' }, "ActiveTool: ", (_l = (_k = this.store.state) === null || _k === void 0 ? void 0 : _k.activeTool) === null || _l === void 0 ? void 0 :
2348
+ _l.name), index.h("div", { key: '41cd94f58f71cd5c1cffc679ada5fc51f6ceeea7' }, "HasViewportChanged: ", ((_m = this.store.state) === null || _m === void 0 ? void 0 : _m.hasViewportChanged) ? 'true' : 'false'), index.h("div", { key: 'bf8495bb924673aad3a9ca57ed0bf9ac23874dfb' }, "IsEnabled: ", ((_o = this.store.state) === null || _o === void 0 ? void 0 : _o.isEnabled) ? 'true' : 'false'), index.h("div", { key: '3823936f5b46b100742f94fac8d7e87ed93ddb58' }, "IsScaling: ", ((_p = this.store.state) === null || _p === void 0 ? void 0 : _p.isScaling) ? 'true' : 'false'), index.h("div", { key: '62eb836fff78b050cdab8cbef54f88f9d5b644ba' }, "IsPanning: ", ((_q = this.store.state) === null || _q === void 0 ? void 0 : _q.isPanning) ? 'true' : 'false'), index.h("div", { key: 'dac6b8d18ae8f6317bdd318ad48a9612f9942613' }, "IsFocused: ", this.store.state.isFocused ? 'true' : 'false'), index.h("div", { key: 'af232e2cd738e255029f5611531c246ac63a28ce' }, "IsSelecting: ", this.isSelecting ? 'true' : 'false'), index.h("div", { key: '95a44fef4b6befe95bfadfc62957103b48bf76b6' }, "IsSelectionActive: ", this.isSelectionActive ? 'true' : 'false'), index.h("div", { key: 'e8162d4de449a0d6756c2f540fca28353c193438' }, "IsResizeHandleSelected: ", this.store.state.isResizeHandleSelected ? 'true' : 'false'), index.h("div", { key: '4440d023cd4982c834736e06863698c3baf72353' }, "IsRotationHandleSelected: ", this.store.state.isRotationHandleSelected ? 'true' : 'false'), index.h("div", { key: 'd3e467dd18e53850df4d5bedf2b69f54b1fbe5c6' }, "IsDrawing: ", this.store.state.isDrawing ? 'true' : 'false'), index.h("div", { key: 'df6e4bca16cbe4346786a544d6f6c53d87bdb699' }, "IsWriting: ", this.store.state.isWriting ? 'true' : 'false'), index.h("div", { key: '532aebf1ff35cc578f12e36cdaf00713ffc76b97' }, "PointerX: ", (_r = this.store.state) === null || _r === void 0 ? void 0 :
2349
+ _r.pointerX), index.h("div", { key: 'f710f8c8d27979da4a40e50452e2cdd63cdefa98' }, "PointerY: ", (_s = this.store.state) === null || _s === void 0 ? void 0 :
2350
+ _s.pointerY), index.h("div", { key: '0175010e1d5a22be81ca0b2d88dd1aff217eacfd' }, "SelectedObjects: ", ((_t = this.store.state.selectionGroup) === null || _t === void 0 ? void 0 : _t.objects.length) || 0)), index.h("div", { key: 'dc2964c479405ed147bd5f090e24262595a474e2', id: "origin", class: "origin", style: {
2351
+ transform: `matrix(${(_u = this.store.state) === null || _u === void 0 ? void 0 : _u.scale}, 0, 0, ${(_v = this.store.state) === null || _v === void 0 ? void 0 : _v.scale}, ${(_w = this.store.state) === null || _w === void 0 ? void 0 : _w.translateX}, ${(_x = this.store.state) === null || _x === void 0 ? void 0 : _x.translateY})`,
2352
+ } }, (_y = this.store.state.objectsOctree.allObjects()) === null || _y === void 0 ? void 0 :
2353
+ _y.map(object => {
1991
2354
  var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u;
1992
- return (index.h("div", { style: { transform: object === null || object === void 0 ? void 0 : object.transformationMatrix, transformOrigin: 'top left', zIndex: object.zIndex.toString(), position: 'absolute' } }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", key: object.id, id: object.id, class: "object", style: {
2355
+ return (index.h("div", { key: object.id, style: { display: object.isInViewport() ? 'block' : 'none', transform: object === null || object === void 0 ? void 0 : object.transformationMatrix, transformOrigin: 'top left', zIndex: object.zIndex.toString(), position: 'absolute' } }, index.h("svg", { xmlns: "http://www.w3.org/2000/svg", id: object.id, class: "object", style: {
1993
2356
  height: object === null || object === void 0 ? void 0 : object.totalHeight.toString(),
1994
2357
  width: object === null || object === void 0 ? void 0 : object.totalWidth.toString(),
1995
2358
  left: '0',
@@ -2008,17 +2371,17 @@ const KritzelEngine = class {
2008
2371
  borderStyle: 'solid',
2009
2372
  padding: object.padding + 'px',
2010
2373
  overflow: 'visible',
2011
- } }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (index.h("svg", { ref: el => el ? object.mount(el) : object.unmount(), xmlns: "http://www.w3.org/2000/svg", style: {
2374
+ } }, KritzelClassHelper.isInstanceOf(object, 'KritzelPath') && (index.h("svg", { ref: el => (el ? object.mount(el) : object.unmount()), xmlns: "http://www.w3.org/2000/svg", style: {
2012
2375
  height: object === null || object === void 0 ? void 0 : object.height.toString(),
2013
2376
  width: object === null || object === void 0 ? void 0 : object.width.toString(),
2014
2377
  position: 'absolute',
2015
2378
  overflow: 'visible',
2016
- }, viewBox: object === null || object === void 0 ? void 0 : object.viewBox }, index.h("path", { d: object === null || object === void 0 ? void 0 : object.d, fill: object.fill, stroke: object === null || object === void 0 ? void 0 : object.stroke }))), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (index.h("img", { ref: el => el ? object.mount(el) : object.unmount(), src: object.src, style: {
2379
+ }, viewBox: object === null || object === void 0 ? void 0 : object.viewBox }, index.h("path", { d: object === null || object === void 0 ? void 0 : object.d, fill: object.fill, stroke: object === null || object === void 0 ? void 0 : object.stroke }))), KritzelClassHelper.isInstanceOf(object, 'KritzelImage') && (index.h("img", { ref: el => (el ? object.mount(el) : object.unmount()), src: object.src, style: {
2017
2380
  width: '100%',
2018
2381
  height: '100%',
2019
2382
  userSelect: 'none',
2020
2383
  pointerEvents: 'none',
2021
- }, draggable: false, onDragStart: e => e.preventDefault() })), KritzelClassHelper.isInstanceOf(object, 'KritzelText') && (index.h("textarea", { ref: el => el ? object.mount(el) : object.unmount(), value: object.value, onKeyDown: event => object.handleKeyDown(event), onInput: event => object.handleInput(event), rows: object.rows, style: {
2384
+ }, draggable: false, onDragStart: e => e.preventDefault() })), KritzelClassHelper.isInstanceOf(object, 'KritzelText') && (index.h("textarea", { ref: el => (el ? object.mount(el) : object.unmount()), value: object.value, onKeyDown: event => object.handleKeyDown(event), onInput: event => object.handleInput(event), rows: object.rows, style: {
2022
2385
  width: '100%',
2023
2386
  height: '100%',
2024
2387
  color: object.fontColor,
@@ -2034,16 +2397,16 @@ const KritzelEngine = class {
2034
2397
  pointerEvents: object.isReadonly ? 'none' : 'auto',
2035
2398
  cursor: object.isReadonly ? 'default' : 'text',
2036
2399
  caretColor: object.isReadonly ? 'transparent' : 'auto',
2037
- } })), KritzelClassHelper.isInstanceOf(object, 'KritzelCustomElement') && (index.h("div", { ref: el => el ? object.mount(el) : object.unmount(), style: {
2400
+ } })), KritzelClassHelper.isInstanceOf(object, 'KritzelCustomElement') && (index.h("div", { ref: el => (el ? object.mount(el) : object.unmount()), style: {
2038
2401
  width: '100%',
2039
2402
  height: '100%',
2040
2403
  pointerEvents: 'auto',
2041
2404
  overflow: 'hidden',
2042
2405
  display: 'block',
2043
- } })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') && (index.h("div", { ref: el => el ? object.mount(el) : object.unmount(), style: {
2406
+ } })), KritzelClassHelper.isInstanceOf(object, 'KritzelSelectionGroup') && (index.h("div", { ref: el => (el ? object.mount(el) : object.unmount()), style: {
2044
2407
  width: '100%',
2045
2408
  height: '100%',
2046
- } })), KritzelClassHelper.isInstanceOf(object, 'KrtizelSelectionBox') && (index.h("div", { ref: el => el ? object.mount(el) : object.unmount(), style: {
2409
+ } })), KritzelClassHelper.isInstanceOf(object, 'KrtizelSelectionBox') && (index.h("div", { ref: el => (el ? object.mount(el) : object.unmount()), style: {
2047
2410
  width: '100%',
2048
2411
  height: '100%',
2049
2412
  } }))), index.h("line", { x1: "0", y1: "0", x2: object.totalWidth, y2: "0", style: {
@@ -2087,17 +2450,17 @@ const KritzelEngine = class {
2087
2450
  fill: 'transparent',
2088
2451
  cursor: 'grab',
2089
2452
  }, visibility: object.isSelected && !this.isSelecting ? 'visible' : 'hidden' }), index.h("g", { style: { display: this.store.state.debugInfo.showObjectInfo ? 'block' : 'none', pointerEvents: 'none' } }, index.h("foreignObject", { x: object.totalWidth.toString(), y: "0", width: "400px", height: "160px", style: { minHeight: '0', minWidth: '0', display: object.isDebugInfoVisible ? 'block' : 'none' } }, index.h("div", { style: { width: '100%', height: '100%' } }, index.h("div", { style: { whiteSpace: 'nowrap' } }, "zIndex: ", object.zIndex), index.h("div", { style: { whiteSpace: 'nowrap' } }, "translateX: ", object.translateX), index.h("div", { style: { whiteSpace: 'nowrap' } }, "translateY: ", object.translateY), index.h("div", { style: { whiteSpace: 'nowrap' } }, "width: ", object.width), index.h("div", { style: { whiteSpace: 'nowrap' } }, "height: ", object.height), index.h("div", { style: { whiteSpace: 'nowrap' } }, "scale: ", object.scale), index.h("div", { style: { whiteSpace: 'nowrap' } }, "rotation: ", object.rotation), index.h("div", { style: { whiteSpace: 'nowrap' } }, "x: ", object.x), index.h("div", { style: { whiteSpace: 'nowrap' } }, "y: ", object.y)))))));
2090
- }), index.h("svg", { key: 'd945e3fae758a66d8d17875203561602446acf9a', class: "object", xmlns: "http://www.w3.org/2000/svg", style: {
2091
- height: (_v = this.store.state.currentPath) === null || _v === void 0 ? void 0 : _v.height.toString(),
2092
- width: (_w = this.store.state.currentPath) === null || _w === void 0 ? void 0 : _w.width.toString(),
2453
+ }), index.h("svg", { key: '86f9a08bea3ac2d261b14b2eec471fafd20ca11f', class: "object", xmlns: "http://www.w3.org/2000/svg", style: {
2454
+ height: (_z = this.store.state.currentPath) === null || _z === void 0 ? void 0 : _z.height.toString(),
2455
+ width: (_0 = this.store.state.currentPath) === null || _0 === void 0 ? void 0 : _0.width.toString(),
2093
2456
  left: '0',
2094
2457
  top: '0',
2095
- zIndex: (_x = this.store.state.currentPath) === null || _x === void 0 ? void 0 : _x.zIndex.toString(),
2458
+ zIndex: (_1 = this.store.state.currentPath) === null || _1 === void 0 ? void 0 : _1.zIndex.toString(),
2096
2459
  position: 'absolute',
2097
- transform: (_y = this.store.state.currentPath) === null || _y === void 0 ? void 0 : _y.transformationMatrix,
2460
+ transform: (_2 = this.store.state.currentPath) === null || _2 === void 0 ? void 0 : _2.transformationMatrix,
2098
2461
  transformOrigin: 'top left',
2099
2462
  overflow: 'visible',
2100
- }, viewBox: (_z = this.store.state.currentPath) === null || _z === void 0 ? void 0 : _z.viewBox }, index.h("path", { key: '111070848aa210dabf4150a9e69326c7a32a2bb7', d: (_0 = this.store.state.currentPath) === null || _0 === void 0 ? void 0 : _0.d, fill: (_1 = this.store.state.currentPath) === null || _1 === void 0 ? void 0 : _1.fill, stroke: (_2 = this.store.state.currentPath) === null || _2 === void 0 ? void 0 : _2.stroke }))), this.store.state.isContextMenuVisible && (index.h("kritzel-context-menu", { key: '13f61253ab96655d6816bfba60b7c1c8e0697533', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.store.state.contextMenuItems, objects: ((_3 = this.store.state.selectionGroup) === null || _3 === void 0 ? void 0 : _3.objects) || [], style: {
2463
+ }, viewBox: (_3 = this.store.state.currentPath) === null || _3 === void 0 ? void 0 : _3.viewBox }, index.h("path", { key: '66ebcf1791c993d62b34a2e4da1d4279428a17dd', d: (_4 = this.store.state.currentPath) === null || _4 === void 0 ? void 0 : _4.d, fill: (_5 = this.store.state.currentPath) === null || _5 === void 0 ? void 0 : _5.fill, stroke: (_6 = this.store.state.currentPath) === null || _6 === void 0 ? void 0 : _6.stroke }))), this.store.state.isContextMenuVisible && (index.h("kritzel-context-menu", { key: 'af91784e3afc84b71d5186237d287c31d472d80a', class: "context-menu", ref: el => (this.contextMenuElement = el), items: this.store.state.contextMenuItems, objects: ((_7 = this.store.state.selectionGroup) === null || _7 === void 0 ? void 0 : _7.objects) || [], style: {
2101
2464
  position: 'fixed',
2102
2465
  left: `${this.store.state.contextMenuX}px`,
2103
2466
  top: `${this.store.state.contextMenuY}px`,
@@ -2109,10 +2472,11 @@ const KritzelEngine = class {
2109
2472
  y: (-this.store.state.translateY + this.store.state.contextMenuY) / this.store.state.scale,
2110
2473
  }, (_a = this.store.state.selectionGroup) === null || _a === void 0 ? void 0 : _a.objects);
2111
2474
  this.hideContextMenu();
2112
- } })), ((_4 = this.store.state) === null || _4 === void 0 ? void 0 : _4.activeTool) instanceof index$1.KritzelEraserTool && !this.store.state.isScaling && index.h("kritzel-cursor-trail", { key: 'bcbedb0fd45a7b87e82e78326bfdc0d1a872c1aa', store: this.store })));
2475
+ } })), ((_8 = this.store.state) === null || _8 === void 0 ? void 0 : _8.activeTool) instanceof index$1.KritzelEraserTool && !this.store.state.isScaling && index.h("kritzel-cursor-trail", { key: '573a4422b742044df5f240b260bc66e83d004520', store: this.store })));
2113
2476
  }
2114
2477
  get host() { return index.getElement(this); }
2115
2478
  static get watchers() { return {
2479
+ "workspace": ["onWorkspaceChange"],
2116
2480
  "scaleMax": ["validateScaleMax"],
2117
2481
  "scaleMin": ["validateScaleMin"]
2118
2482
  }; }
@@ -2129,7 +2493,7 @@ const KritzelFont = class {
2129
2493
  this.color = '#000000';
2130
2494
  }
2131
2495
  render() {
2132
- return (index.h(index.Host, { key: 'e4123d3701933d5de1d5c063f69f6823db849baf' }, index.h("div", { key: '81dde2ff263a8bf110b9c0f0be4a5adc5852fa2f', class: "font-preview", style: {
2496
+ return (index.h(index.Host, { key: 'd318355704f1bf66468dd793e5e38da827076d3b' }, index.h("div", { key: '447b4fba97f5d1900060859943438733667aed08', class: "font-preview", style: {
2133
2497
  fontFamily: this.fontFamily,
2134
2498
  fontSize: `${this.size}px`,
2135
2499
  color: this.color
@@ -2174,12 +2538,12 @@ const KritzelFontFamily = class {
2174
2538
  label: option.label,
2175
2539
  style: { fontFamily: option.value },
2176
2540
  }));
2177
- return (index.h(index.Host, { key: 'b56a2dcc19e11c8cf84449d94f43fd93a882ac4e' }, index.h("kritzel-dropdown", { key: '999c75650ce8d83c5b52eda5c96ce0b040e67475', options: dropdownOptions, value: this.selectedFontFamily, onValueChanged: this.handleDropdownValueChange, selectStyles: { fontFamily: this.selectedFontFamily } }, index.h("button", { key: 'defbe8238c3037a5128f59f33a51f6ec9fd08dc3', class: "font-style-button", slot: "suffix" }, "B"), index.h("button", { key: '7dd5a7256dde1d38b495f67bdec2d605fde0a1ec', class: "font-style-button italic-text", slot: "suffix" }, "I"))));
2541
+ return (index.h(index.Host, { key: '801b1dbc2b7da7d00fb00ed6a8d8ee7be3e9ef17' }, index.h("kritzel-dropdown", { key: '5f774c0b31ca16a1c8acda1c73ea3aacc2784649', options: dropdownOptions, value: this.selectedFontFamily, onValueChanged: this.handleDropdownValueChange, selectStyles: { fontFamily: this.selectedFontFamily } }, index.h("button", { key: '3c101155ff08854f665750f8988fb3691a77c04a', class: "font-style-button", slot: "suffix" }, "B"), index.h("button", { key: '48d2ead137a8a35f06fb8b5487431e2ce613c755', class: "font-style-button italic-text", slot: "suffix" }, "I"))));
2178
2542
  }
2179
2543
  };
2180
2544
  KritzelFontFamily.style = kritzelFontFamilyCss;
2181
2545
 
2182
- const kritzelFontSizeCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box}.size-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:4px;cursor:pointer;border:2px solid transparent;box-sizing:border-box;border-radius:50%}.size-container:hover{background-color:var(--kritzel-font-size-hover-background-color, #f0f0f0)}.size-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-font-size-selected-background-color, #e0e0e0)}";
2546
+ const kritzelFontSizeCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box}.size-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:4px;cursor:pointer;border:2px solid transparent;box-sizing:border-box;border-radius:50%}.size-container:hover{background-color:var(--kritzel-font-size-hover-background-color, #ebebeb)}.size-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-font-size-selected-background-color, #e0e0e0)}";
2183
2547
 
2184
2548
  const KritzelFontSize = class {
2185
2549
  constructor(hostRef) {
@@ -2194,7 +2558,7 @@ const KritzelFontSize = class {
2194
2558
  this.sizeChange.emit(size);
2195
2559
  }
2196
2560
  render() {
2197
- return (index.h(index.Host, { key: 'b741185f77e6e6f9fa7a5023d90936d1ebb48d30' }, this.sizes.map(size => (index.h("div", { class: {
2561
+ return (index.h(index.Host, { key: '08571feed86b37208956608b170ca1f782b7fb18' }, this.sizes.map(size => (index.h("div", { class: {
2198
2562
  'size-container': true,
2199
2563
  'selected': this.selectedSize === size,
2200
2564
  }, onClick: () => this.handleSizeClick(size) }, index.h("kritzel-font", { fontFamily: this.fontFamily, size: size }))))));
@@ -2224,7 +2588,307 @@ const KritzelIcon = class {
2224
2588
  };
2225
2589
  KritzelIcon.style = kritzelIconCss;
2226
2590
 
2227
- const kritzelStrokeSizeCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box}.size-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box}.size-container:hover{background-color:var(--kritzel-stroke-size-hover-background-color, #f0f0f0)}.size-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-stroke-size-selected-background-color, #f0f0f0)}";
2591
+ const kritzelMenuCss = ":host{display:flex;flex-direction:column;min-width:180px;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 12px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #ebebeb);z-index:2;gap:var(--kritzel-menu-item-gap, 4px);overflow-y:auto;scrollbar-color:#ebebeb transparent;scrollbar-width:thin}button{all:unset;background:transparent;border:0;padding:0;margin:0;font:inherit;color:inherit;line-height:inherit;text-align:inherit;cursor:pointer;appearance:none;-webkit-appearance:none;-moz-appearance:none;border-radius:0;-webkit-tap-highlight-color:transparent}button:focus{outline:none}:host(:focus){outline:none}.menu-item{display:flex;align-items:center;justify-content:space-between;padding:var(--kritzel-context-menu-item-padding, 8px);border-radius:var(--kritzel-context-menu-item-border-radius, 12px);cursor:pointer;font-family:sans-serif;font-size:var(--kritzel-context-menu-item-font-size, 14px);color:var(--kritzel-context-menu-item-color, #333333);gap:var(--kritzel-context-menu-item-gap, 12px)}.menu-item:focus,.menu-item:focus-within{outline:none;background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.menu-item-label{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.menu-item:not(.disabled):not(.inactive):not(.active):hover{background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.menu-item:not(.disabled):not(.inactive):not(.active):active{background-color:var(--kritzel-context-menu-item-active-background-color, hsl(0, 0%, 0%, 8.6%))}.menu-item.active{color:var(--kritzel-controls-background-color, #ffffff);background-color:var(--kritzel-controls-control-selected-background-color, #007aff)}.menu-item.active kritzel-icon{filter:brightness(0) invert(1)}.menu-item.active:hover{background-color:var(--kritzel-controls-control-selected-hover-background-color, #0075f1)}.menu-item.disabled{color:var(--kritzel-context-menu-item-disabled-color, #aaaaaa);background-color:transparent;cursor:default}.menu-item.child-open{background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%)) !important}.menu-item.active.menu-item.child-open{background-color:var(--kritzel-controls-control-selected-active-background-color, #0075f1) !important}.menu-item kritzel-icon{opacity:0.8;flex-shrink:0}.menu-item.disabled kritzel-icon{opacity:0.4}.menu-item.edit-mode input{background:transparent;border:none;outline:none;font-size:inherit;font-family:inherit;color:inherit;padding:0;width:100%;padding:2px 0px;border-bottom:1px solid var(--kritzel-context-menu-item-color, #333333)}.menu-item.active.edit-mode input{border-bottom:1px solid var(--kritzel-controls-background-color, #ffffff)}.menu-item.edit-mode input::selection{background-color:var(--kritzel-controls-control-selected-background-color, #007aff);border-radius:4px;color:var(--kritzel-controls-background-color, #ffffff)}.menu-item.active.edit-mode input::selection{background-color:var(--kritzel-menu-item-selected-input-background-color, #ffffff34)}.menu-item-button{background:transparent;border:none;outline:none;cursor:pointer;padding:4px;border-radius:8px;display:flex;align-items:center;justify-content:center}.menu-item-button:hover{background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.menu-item-button:focus{background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.edit-container,.view-container{width:100%;display:flex;align-items:center;justify-content:space-between;gap:var(--kritzel-context-menu-item-gap, 4px)}";
2592
+
2593
+ const KritzelMenu = class {
2594
+ constructor(hostRef) {
2595
+ index.registerInstance(this, hostRef);
2596
+ this.close = index.createEvent(this, "close");
2597
+ this.items = [];
2598
+ this.parentIndex = null;
2599
+ this.parent = null;
2600
+ this.activeItemIndex = null;
2601
+ this.editingIndex = null;
2602
+ this.openChildMenuIndex = null;
2603
+ this.childMenuAnchor = null;
2604
+ this.cancelButton = null;
2605
+ this.saveButton = null;
2606
+ }
2607
+ onEditingIndexChange(newValue) {
2608
+ if (newValue === null) {
2609
+ this.openChildMenuIndex = null;
2610
+ this.editInput = undefined;
2611
+ return;
2612
+ }
2613
+ }
2614
+ handleWindowClick(event) {
2615
+ if (this.openChildMenuIndex === null) {
2616
+ return;
2617
+ }
2618
+ const target = event.target;
2619
+ if (!this.host.contains(target)) {
2620
+ this.openChildMenuIndex = null;
2621
+ }
2622
+ }
2623
+ handleEscape(event) {
2624
+ var _a;
2625
+ if (event.key === 'Escape') {
2626
+ if (this.openChildMenuIndex !== null) {
2627
+ return;
2628
+ }
2629
+ if (this.editingIndex !== null) {
2630
+ (_a = this.cancelButton) === null || _a === void 0 ? void 0 : _a.click();
2631
+ return;
2632
+ }
2633
+ this.close.emit();
2634
+ }
2635
+ }
2636
+ handleEnter(event) {
2637
+ var _a;
2638
+ if (event.key === 'Enter') {
2639
+ if (this.editingIndex !== null) {
2640
+ (_a = this.saveButton) === null || _a === void 0 ? void 0 : _a.click();
2641
+ return;
2642
+ }
2643
+ }
2644
+ }
2645
+ componentDidLoad() {
2646
+ requestAnimationFrame(() => {
2647
+ this.host.focus();
2648
+ });
2649
+ }
2650
+ isViewMode(index) {
2651
+ return this.editingIndex !== index;
2652
+ }
2653
+ handleSelect(item) {
2654
+ var _a;
2655
+ if (item.disabled || this.editingIndex !== null || this.openChildMenuIndex !== null) {
2656
+ return;
2657
+ }
2658
+ (_a = item.select) === null || _a === void 0 ? void 0 : _a.call(item, item);
2659
+ }
2660
+ render() {
2661
+ return (index.h(index.Host, { key: '6d98c1d40c1af36b7b36c45ddc96fb89ab6ebdca', tabIndex: 0 }, this.items.map((item, index$1) => (index.h("button", { tabIndex: 0, class: {
2662
+ 'menu-item': true,
2663
+ 'disabled': item.disabled,
2664
+ 'inactive': this.openChildMenuIndex !== null && this.openChildMenuIndex !== index$1,
2665
+ 'child-open': this.openChildMenuIndex === index$1,
2666
+ 'edit-mode': this.editingIndex === index$1,
2667
+ 'active': this.activeItemIndex === index$1,
2668
+ }, onClick: () => this.handleSelect(item) }, this.isViewMode(index$1) === true && (index.h("div", { class: "view-container" }, index.h("span", { class: "menu-item-label" }, item.label), index.h("div", null, item.children && item.children.length > 0 && (index.h("button", { class: "menu-item-button", tabIndex: 0, onClick: event => {
2669
+ if (this.editingIndex !== null)
2670
+ return;
2671
+ event.stopPropagation();
2672
+ this.childMenuAnchor = this.openChildMenuIndex === index$1 ? null : event.currentTarget;
2673
+ this.openChildMenuIndex = this.openChildMenuIndex === index$1 ? null : index$1;
2674
+ } }, index.h("kritzel-icon", { name: "ellipsis-vertical", size: 16 }))), this.openChildMenuIndex === index$1 && (index.h("kritzel-portal", { anchor: this.childMenuAnchor, offsetY: 4, onClose: () => this.openChildMenuIndex = null }, index.h("kritzel-menu", { style: { minWidth: '100px' }, items: item.children, parentIndex: index$1, parent: item, onClose: () => {
2675
+ var _a;
2676
+ this.openChildMenuIndex = null;
2677
+ (_a = this.childMenuAnchor) === null || _a === void 0 ? void 0 : _a.focus();
2678
+ } })))))), this.isViewMode(index$1) === false && (index.h("div", { class: "edit-container" }, index.h("input", { tabIndex: 0, ref: el => {
2679
+ this.editInput = el;
2680
+ requestAnimationFrame(() => {
2681
+ var _a, _b;
2682
+ (_a = this.editInput) === null || _a === void 0 ? void 0 : _a.focus();
2683
+ (_b = this.editInput) === null || _b === void 0 ? void 0 : _b.select();
2684
+ });
2685
+ }, type: "text", name: 'menu-item-' + index$1, value: item.label, onInput: e => (item.label = e.target.value) }), index.h("div", { style: { display: 'flex', gap: '8px' } }, index.h("button", { ref: el => (this.cancelButton = el), class: "menu-item-button", tabIndex: 0, onClick: () => { var _a; return (_a = item.cancel) === null || _a === void 0 ? void 0 : _a.call(item, item); } }, index.h("kritzel-icon", { name: "x", size: 16 })), index.h("button", { ref: el => (this.saveButton = el), class: "menu-item-button", tabIndex: 0, onClick: () => { var _a; return (_a = item.save) === null || _a === void 0 ? void 0 : _a.call(item, item); } }, index.h("kritzel-icon", { name: "check", size: 16 }))))))))));
2686
+ }
2687
+ get host() { return index.getElement(this); }
2688
+ static get watchers() { return {
2689
+ "editingIndex": ["onEditingIndexChange"]
2690
+ }; }
2691
+ };
2692
+ KritzelMenu.style = kritzelMenuCss;
2693
+
2694
+ class KritzelHTMLHelper {
2695
+ static getNumericValueFromStyle(element, property) {
2696
+ const value = window.getComputedStyle(element).getPropertyValue(property);
2697
+ return parseFloat(value) || 0;
2698
+ }
2699
+ static getScrollableParent(element) {
2700
+ var _a, _b;
2701
+ if (!element) {
2702
+ return window;
2703
+ }
2704
+ const parent = (_b = (_a = element.parentNode) === null || _a === void 0 ? void 0 : _a.host) !== null && _b !== void 0 ? _b : element.parentElement;
2705
+ if (!parent || parent.tagName === 'BODY') {
2706
+ return window;
2707
+ }
2708
+ const style = window.getComputedStyle(parent);
2709
+ if (style.overflow === 'auto' || style.overflowY === 'auto' || style.overflow === 'scroll' || style.overflowY === 'scroll') {
2710
+ return parent;
2711
+ }
2712
+ return this.getScrollableParent(parent);
2713
+ }
2714
+ static isElementInViewport(element) {
2715
+ if (!element) {
2716
+ return false;
2717
+ }
2718
+ const scrollableParent = this.getScrollableParent(element);
2719
+ const rect = element.getBoundingClientRect();
2720
+ if (scrollableParent === window) {
2721
+ const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
2722
+ const viewportWidth = window.innerWidth || document.documentElement.clientWidth;
2723
+ return rect.top >= 0 && rect.left >= 0 && rect.bottom <= viewportHeight && rect.right <= viewportWidth;
2724
+ }
2725
+ const parentRect = scrollableParent.getBoundingClientRect();
2726
+ return rect.top >= parentRect.top && rect.left >= parentRect.left && rect.bottom <= parentRect.bottom && rect.right <= parentRect.right;
2727
+ }
2728
+ }
2729
+
2730
+ const DEFAULT_OFFSET = 0;
2731
+ const MIN_LEFT_POSITION = 0;
2732
+ const Z_INDEX = '9005';
2733
+ const ID_PORTAL = 'portal';
2734
+ const KritzelPortal = class {
2735
+ constructor(hostRef) {
2736
+ index.registerInstance(this, hostRef);
2737
+ this.close = index.createEvent(this, "close");
2738
+ this.autoFocus = true;
2739
+ this.moved = false;
2740
+ this.handleScroll = () => {
2741
+ const isAnchorInViewport = KritzelHTMLHelper.isElementInViewport(this.anchor);
2742
+ if (!isAnchorInViewport) {
2743
+ this.close.emit();
2744
+ return;
2745
+ }
2746
+ this.calculatePosition();
2747
+ };
2748
+ }
2749
+ anchorChanged(newValue) {
2750
+ if (newValue) {
2751
+ this.calculatePosition();
2752
+ }
2753
+ }
2754
+ handleResize() {
2755
+ this.calculatePosition();
2756
+ }
2757
+ calculateLeft() {
2758
+ var _a;
2759
+ if (!this.anchor || !this.portal)
2760
+ return 0;
2761
+ const refRect = this.anchor.getBoundingClientRect();
2762
+ const portalRect = this.portal.getBoundingClientRect();
2763
+ const offset = (_a = this.offsetX) !== null && _a !== void 0 ? _a : DEFAULT_OFFSET;
2764
+ let left = refRect.left + offset;
2765
+ const maxLeft = window.innerWidth - portalRect.width - MIN_LEFT_POSITION;
2766
+ if (left < MIN_LEFT_POSITION)
2767
+ left = MIN_LEFT_POSITION;
2768
+ if (left > maxLeft)
2769
+ left = maxLeft;
2770
+ return Math.round(left + window.scrollX);
2771
+ }
2772
+ calculateTop() {
2773
+ var _a;
2774
+ if (!this.anchor || !this.portal)
2775
+ return 0;
2776
+ const refRect = this.anchor.getBoundingClientRect();
2777
+ const portalRect = this.portal.getBoundingClientRect();
2778
+ const offset = (_a = this.offsetY) !== null && _a !== void 0 ? _a : DEFAULT_OFFSET;
2779
+ let top = refRect.bottom + offset;
2780
+ if (top + portalRect.height > window.innerHeight) {
2781
+ top = refRect.top - portalRect.height - offset;
2782
+ }
2783
+ return Math.round(top + window.scrollY);
2784
+ }
2785
+ createPortal() {
2786
+ this.portal = document.createElement('div');
2787
+ this.portal.setAttribute('id', ID_PORTAL);
2788
+ this.portal.style.zIndex = Z_INDEX;
2789
+ this.portal.style.position = 'absolute';
2790
+ this.portal.style.top = '0px';
2791
+ this.portal.style.left = '0px';
2792
+ document.body.append(this.portal);
2793
+ }
2794
+ moveElementToPortal() {
2795
+ this.portal.appendChild(this.element);
2796
+ this.moved = true;
2797
+ }
2798
+ calculatePosition() {
2799
+ if (!this.anchor || !this.portal)
2800
+ return;
2801
+ const top = this.calculateTop();
2802
+ const left = this.calculateLeft();
2803
+ this.portal.style.top = `${top}px`;
2804
+ this.portal.style.left = `${left}px`;
2805
+ }
2806
+ componentWillLoad() {
2807
+ this.createPortal();
2808
+ }
2809
+ componentDidLoad() {
2810
+ var _a;
2811
+ this.moveElementToPortal();
2812
+ if (this.anchor) {
2813
+ this.calculatePosition();
2814
+ this.scrollableParent = KritzelHTMLHelper.getScrollableParent(this.anchor);
2815
+ (_a = this.scrollableParent) === null || _a === void 0 ? void 0 : _a.addEventListener('scroll', this.handleScroll);
2816
+ }
2817
+ }
2818
+ disconnectedCallback() {
2819
+ var _a;
2820
+ this.moved ? this.portal.remove() : (this.moved = true);
2821
+ (_a = this.scrollableParent) === null || _a === void 0 ? void 0 : _a.removeEventListener('scroll', this.handleScroll);
2822
+ }
2823
+ render() {
2824
+ return (index.h(index.Host, { key: 'e39525c3e9ddbf738b63ac0c08d8c1e2264783b1', ref: el => (this.element = el) }, index.h("slot", { key: '95202c5bea32c77dc1dde0a12a58ac9bcebd8812' })));
2825
+ }
2826
+ static get watchers() { return {
2827
+ "anchor": ["anchorChanged"]
2828
+ }; }
2829
+ };
2830
+
2831
+ const kritzelSplitButtonCss = ":host{position:relative;display:flex;align-items:center;font-family:sans-serif;z-index:1;padding:var(--kritzel-controls-padding, 4px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 12px);box-shadow:var(--kritzel-controls-box-shadow, 0 0 3px rgba(0, 0, 0, 0.08));border:var(--kritzel-controls-border, 1px solid #ebebeb);gap:var(--kritzel-context-menu-item-gap, 4px)}:host(:focus){outline:none}button{border:none;background-color:transparent;padding:0;margin:0;font-family:inherit;font-size:inherit;color:inherit;-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;text-align:center;display:flex;align-items:center;justify-content:center;pointer-events:all;-webkit-tap-highlight-color:transparent}.split-main-button,.split-menu-button{height:auto;display:flex;align-items:center;padding:var(--kritzel-controls-padding, 8px);background-color:var(--kritzel-controls-background-color, #ffffff);border-radius:var(--kritzel-controls-border-radius, 12px);font-size:var(--kritzel-context-menu-item-font-size, 14px)}.split-main-button:hover,.split-menu-button:hover{background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.split-main-button:focus,.split-menu-button:focus{outline:none;background-color:var(--kritzel-context-menu-item-hover-background-color, hsl(0, 0%, 0%, 4.3%))}.split-main-button{gap:var(--kritzel-context-menu-item-gap, 4px)}.split-menu-button{border-left:none;justify-content:center}.split-divider{width:var(--kritzel-controls-divider-width, 1px);height:24px;background-color:var(--kritzel-controls-divider-background-color, hsl(0, 0%, 0%, 4.3%))}";
2832
+
2833
+ const KritzelSplitButton = class {
2834
+ constructor(hostRef) {
2835
+ index.registerInstance(this, hostRef);
2836
+ this.buttonClick = index.createEvent(this, "buttonClick");
2837
+ this.optionSelect = index.createEvent(this, "optionSelect");
2838
+ this.menuOpened = index.createEvent(this, "menuOpened");
2839
+ this.menuClosed = index.createEvent(this, "menuClosed");
2840
+ this.dropdownIcon = 'chevron-down';
2841
+ this.options = [];
2842
+ this.disabled = false;
2843
+ this.activeItemIndex = null;
2844
+ this.editingIndex = null;
2845
+ this.isMenuOpen = false;
2846
+ this.handleDocumentClick = (event) => {
2847
+ const path = (event.composedPath && event.composedPath()) || [];
2848
+ const clickedInside = path.some(node => (node === null || node === void 0 ? void 0 : node.tagName) === 'KRITZEL-SPLIT-BUTTON' || (node === null || node === void 0 ? void 0 : node.tagName) === 'KRITZEL-MENU');
2849
+ if (!clickedInside) {
2850
+ this.closeMenu();
2851
+ }
2852
+ else if (this.isMenuOpen) {
2853
+ document.addEventListener('click', this.handleDocumentClick, { once: true });
2854
+ }
2855
+ };
2856
+ this.toggleMenu = () => {
2857
+ if (this.isMenuOpen) {
2858
+ this.closeMenu();
2859
+ }
2860
+ else {
2861
+ this.openMenu();
2862
+ }
2863
+ };
2864
+ this.handleButtonClick = () => {
2865
+ if (!this.disabled) {
2866
+ this.buttonClick.emit();
2867
+ }
2868
+ };
2869
+ }
2870
+ async openMenu() {
2871
+ if (this.disabled || this.isMenuOpen)
2872
+ return;
2873
+ this.isMenuOpen = true;
2874
+ this.menuOpened.emit();
2875
+ document.addEventListener('click', this.handleDocumentClick, { once: true });
2876
+ }
2877
+ async closeMenu() {
2878
+ if (this.disabled || !this.isMenuOpen)
2879
+ return;
2880
+ this.isMenuOpen = false;
2881
+ this.menuClosed.emit();
2882
+ this.host.focus();
2883
+ }
2884
+ render() {
2885
+ return (index.h(index.Host, { key: 'cf133b2867dffe6b9d70259c7d44b86342411d38', tabIndex: 0 }, index.h("button", { key: '3044cd9cbe02dde919a276b9f1d8f1f24b8514e9', class: "split-main-button", tabIndex: 0, onClick: this.handleButtonClick, disabled: this.disabled }, this.buttonIcon && index.h("kritzel-icon", { key: '4ed314f7288df567bb35a909c4919cf353788dd2', name: this.buttonIcon }), this.buttonText && (index.h("span", { key: '68b2148200e4698468aae137d16a4b5f17764f9f' }, this.buttonText, " (", this.options.length, ")"))), index.h("div", { key: '5047a2aea1d31e80fba8f6350e4b64572198c87d', class: "split-divider" }), index.h("button", { key: 'd7b33d9c717553d7cff3c3d2fafe90ce9dce1e67', ref: el => (this.splitMenuButton = el), class: "split-menu-button", tabIndex: 0, onClick: this.toggleMenu, disabled: this.disabled }, index.h("kritzel-icon", { key: 'a3d485aee5e9843c2d07d367a0d5743bfc8f3d5c', name: this.dropdownIcon })), index.h("kritzel-portal", { key: '2bb8f5c58884e6c73d3d7025a8e6efce770ab039', anchor: this.host, offsetY: 4 }, this.isMenuOpen && (index.h("kritzel-menu", { key: '3f2bb51a43ec78ff8664d5f625afa21cf9ecfb8c', style: { maxHeight: '300px', width: '180px' }, items: this.options, activeItemIndex: this.activeItemIndex, editingIndex: this.editingIndex, onClose: () => this.closeMenu() })))));
2886
+ }
2887
+ get host() { return index.getElement(this); }
2888
+ };
2889
+ KritzelSplitButton.style = kritzelSplitButtonCss;
2890
+
2891
+ const kritzelStrokeSizeCss = ":host{display:flex;align-items:flex-start;gap:8px;padding:8px;box-sizing:border-box}.size-container{display:flex;justify-content:center;align-items:center;width:32px;height:32px;border-radius:50%;cursor:pointer;border:2px solid transparent;box-sizing:border-box}.size-container:hover{background-color:var(--kritzel-stroke-size-hover-background-color, #ebebeb)}.size-container.selected{border-color:var(--kritzel-selection-border-color, #007AFF);background-color:var(--kritzel-stroke-size-selected-background-color, #ebebeb)}";
2228
2892
 
2229
2893
  const KritzelStrokeSize = class {
2230
2894
  constructor(hostRef) {
@@ -2238,7 +2902,7 @@ const KritzelStrokeSize = class {
2238
2902
  this.sizeChange.emit(size);
2239
2903
  }
2240
2904
  render() {
2241
- return (index.h(index.Host, { key: 'b481b62184551bc776042f58d2f27beba837f61d' }, this.sizes.map(size => (index.h("div", { class: {
2905
+ return (index.h(index.Host, { key: '0185d3243c35c49169324c98f87df6a286fc3d31' }, this.sizes.map(size => (index.h("div", { class: {
2242
2906
  'size-container': true,
2243
2907
  'selected': this.selectedSize === size,
2244
2908
  }, onClick: () => this.handleSizeClick(size) }, index.h("kritzel-color", { value: '#000000', size: size }))))));
@@ -2287,23 +2951,23 @@ const KritzelTooltip = class {
2287
2951
  }
2288
2952
  }
2289
2953
  render() {
2290
- return (index.h(index.Host, { key: 'aed123eda0750df66229f0dd40eeafea39360901', style: {
2954
+ return (index.h(index.Host, { key: '7610e8185e037813cc363daa3212a4164a20daaf', style: {
2291
2955
  position: 'fixed',
2292
2956
  zIndex: '9999',
2293
2957
  transition: 'opacity 0.3s ease-in-out, transform 0.3s ease-in-out',
2294
2958
  visibility: this.isVisible ? 'visible' : 'hidden',
2295
2959
  left: !this.isMobileView ? `${this.positionX}px` : '50%',
2296
2960
  marginBottom: `${this.offsetY + this.arrowSize}px`,
2297
- } }, index.h("div", { key: 'ebd77cc44aea3a3ff193717f2dae7eedb55023fd', class: "tooltip-content", onClick: event => event.stopPropagation() }, index.h("slot", { key: '70966228bbe59b894eb472704f08b340c32bbad9' }), index.h("div", { key: '0d82c0f5b1531b39e48b9e80045771e3dda53964', class: "tooltip-arrow-wrapper", style: {
2961
+ } }, index.h("div", { key: 'bd5c1f0f7ff3afddfcf2469277189d026e79b453', class: "tooltip-content", onClick: event => event.stopPropagation() }, index.h("slot", { key: '547e5a8fcb8131225461881a1ad0125fa4b0d55b' }), index.h("div", { key: 'de1d30c31667a81a36873d32bec20fcc911ec89f', class: "tooltip-arrow-wrapper", style: {
2298
2962
  position: 'fixed',
2299
2963
  left: this.arrowOffset,
2300
2964
  bottom: `-${this.arrowSize * 2}px`,
2301
- } }, index.h("div", { key: '24b911e6fe5b5b9a1009d28c797c4c3d00f6f7c7', class: "tooltip-arrow", style: {
2965
+ } }, index.h("div", { key: 'ebbf83bd4d35e252b0258a7c81ebcef48ac10004', class: "tooltip-arrow", style: {
2302
2966
  borderLeft: `${this.arrowSize}px solid transparent`,
2303
2967
  borderRight: `${this.arrowSize}px solid transparent`,
2304
2968
  borderTop: `${this.arrowSize}px solid var(--kritzel-controls-tooltip-background-color, #ffffff)`,
2305
2969
  filter: 'drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2))',
2306
- } }), index.h("div", { key: '2a15c5e8614e57a763aa3d8d4f8d4138146ac0a7', class: "tooltip-arrow-rect", style: {
2970
+ } }), index.h("div", { key: '918ca46c438657dc4f72ccc73f81d58076d637c5', class: "tooltip-arrow-rect", style: {
2307
2971
  position: 'relative',
2308
2972
  width: `${this.arrowSize * 2}px`,
2309
2973
  height: `${this.arrowSize}px`,
@@ -2337,11 +3001,113 @@ const KritzelUtilityPanel = class {
2337
3001
  this.redo.emit();
2338
3002
  }
2339
3003
  render() {
2340
- return (index.h(index.Host, { key: 'f381fac2cb032ca19c6945ef4f39673ea0bd0cc5' }, index.h("button", { key: '1f7200672970baf1d0cfcaa116fa3f8f9a39832a', class: "utility-button", onClick: event => this.handleUndo(event) }, index.h("kritzel-icon", { key: '755d9201d80d8db086f07b38e90a01a06e980b50', name: "undo" })), index.h("button", { key: '06e4d5c2956f23245c3d48f21c15d54e8bef8119', class: "utility-button", onClick: event => this.handleRedo(event) }, index.h("kritzel-icon", { key: '13eb6b31c45b67ac399fc7c84b941ddce04c5c86', name: "redo" })), index.h("div", { key: '7f03a576a37649db679b93604c2654d29cc81da4', class: "utility-separator" }), index.h("button", { key: '0c40613e9f6a049cec872d71e9f948d685ec1dbe', class: "utility-button" }, index.h("kritzel-icon", { key: '8cba73bcb02ef8b7c182ba2fd16d98d6855f1c1b', name: "delete", onClick: () => this.delete.emit() }))));
3004
+ return (index.h(index.Host, { key: 'cf7b5c501b6535fda22b17ea218e90bd60223c6e' }, index.h("button", { key: '05db2cee7f2e191674167ef503e70718200bf904', class: "utility-button", onClick: event => this.handleUndo(event) }, index.h("kritzel-icon", { key: '10412c038b9d4e66851c8a0c9b51b99607bac397', name: "undo" })), index.h("button", { key: 'edf0289de8ce5cddd9341bc1855eae095274226c', class: "utility-button", onClick: event => this.handleRedo(event) }, index.h("kritzel-icon", { key: '46263e3d3f166b224c9a18ba383085e020fac51a', name: "redo" })), index.h("div", { key: '3a6c0eca21f44887683d6308ca5741b095eceb77', class: "utility-separator" }), index.h("button", { key: 'ced83e0c47fc920edabdc5b3379a8805f1827374', class: "utility-button" }, index.h("kritzel-icon", { key: 'd49c6412d778d34fe21e86482f2114631621106a', name: "delete", onClick: () => this.delete.emit() }))));
2341
3005
  }
2342
3006
  };
2343
3007
  KritzelUtilityPanel.style = kritzelUtilityPanelCss;
2344
3008
 
3009
+ const kritzelWorkspaceManagerCss = ":host{display:flex;flex-direction:column;z-index:1}";
3010
+
3011
+ const KritzelWorkspaceManager = class {
3012
+ constructor(hostRef) {
3013
+ index.registerInstance(this, hostRef);
3014
+ this.isWorkspaceManagerReady = index.createEvent(this, "isWorkspaceManagerReady");
3015
+ this.workspaceChange = index.createEvent(this, "workspaceChange");
3016
+ this.workspaces = [];
3017
+ this.editingIndex = null;
3018
+ this.newWorkspace = null;
3019
+ this.kritzelEngine = null;
3020
+ this.handleNewWorkspace = async () => {
3021
+ var _a;
3022
+ await ((_a = this.splitButtonRef) === null || _a === void 0 ? void 0 : _a.openMenu());
3023
+ requestAnimationFrame(() => {
3024
+ this.newWorkspace = new KritzelWorkspace(index$1.ObjectHelper.generateUUID(), 'New Workspace');
3025
+ this.editingIndex = 0;
3026
+ });
3027
+ };
3028
+ this.handleMenuClosed = () => {
3029
+ this.editingIndex = null;
3030
+ this.newWorkspace = null;
3031
+ };
3032
+ this.handleSave = async (item) => {
3033
+ const workspace = item.value;
3034
+ const updatedWorkspace = Object.assign(Object.assign({}, workspace), { name: item.label });
3035
+ if (this.newWorkspace) {
3036
+ await this.kritzelEngine.createWorkspace(updatedWorkspace);
3037
+ this.selectWorkspace(updatedWorkspace);
3038
+ }
3039
+ else {
3040
+ await this.kritzelEngine.updateWorkspace(updatedWorkspace);
3041
+ }
3042
+ this.editingIndex = null;
3043
+ this.newWorkspace = null;
3044
+ };
3045
+ this.handleRename = (index) => {
3046
+ this.editingIndex = index;
3047
+ };
3048
+ this.handleDelete = async (workspaceToDelete) => {
3049
+ var _a;
3050
+ await this.kritzelEngine.deleteWorkspace(workspaceToDelete);
3051
+ if (((_a = this.activeWorkspace) === null || _a === void 0 ? void 0 : _a.id) === workspaceToDelete.id) {
3052
+ const newActiveWorkspace = this.sortedWorkspaces.find(w => w.id !== workspaceToDelete.id) || null;
3053
+ this.selectWorkspace(newActiveWorkspace);
3054
+ }
3055
+ };
3056
+ }
3057
+ get sortedWorkspaces() {
3058
+ const uniqueWorkspaces = [...new Map(this.workspaces.map(workspace => [workspace.id, workspace])).values()];
3059
+ return [this.newWorkspace, ...uniqueWorkspaces].filter(ws => ws !== null).sort((a, b) => b.createdAt.getTime() - a.createdAt.getTime());
3060
+ }
3061
+ get activeItemIndex() {
3062
+ return this.sortedWorkspaces.findIndex(ws => { var _a; return ws.id === ((_a = this.activeWorkspace) === null || _a === void 0 ? void 0 : _a.id); });
3063
+ }
3064
+ async componentWillLoad() {
3065
+ await this.initializeEngine();
3066
+ this.isWorkspaceManagerReady.emit();
3067
+ }
3068
+ async initializeEngine() {
3069
+ await customElements.whenDefined('kritzel-engine');
3070
+ this.kritzelEngine = this.host.parentElement.querySelector('kritzel-engine');
3071
+ if (!this.kritzelEngine) {
3072
+ throw new Error('kritzel-engine not found in parent element.');
3073
+ }
3074
+ }
3075
+ handleSelect(workspace) {
3076
+ this.selectWorkspace(workspace);
3077
+ }
3078
+ selectWorkspace(workspace) {
3079
+ if (this.editingIndex !== null)
3080
+ return;
3081
+ this.activeWorkspace = this.sortedWorkspaces.find(ws => ws.id === workspace.id);
3082
+ this.workspaceChange.emit(workspace);
3083
+ }
3084
+ render() {
3085
+ const workspaceSelectionOptions = this.sortedWorkspaces.map((ws, index) => ({
3086
+ label: ws.name,
3087
+ value: ws,
3088
+ select: () => this.handleSelect(ws),
3089
+ cancel: this.handleMenuClosed,
3090
+ save: this.handleSave,
3091
+ children: [
3092
+ {
3093
+ label: 'Rename',
3094
+ value: 'rename',
3095
+ select: () => this.handleRename(index),
3096
+ },
3097
+ {
3098
+ label: 'Delete',
3099
+ value: 'delete',
3100
+ disabled: this.sortedWorkspaces.length <= 1,
3101
+ select: () => this.handleDelete(ws),
3102
+ },
3103
+ ],
3104
+ }));
3105
+ return (index.h(index.Host, { key: '1703451717d5583d6520edfbcdbe38a5b8f6840f' }, index.h("kritzel-split-button", { key: 'efd5d9b714ee72b23fd28c9b20ea6985957fe9b9', ref: el => (this.splitButtonRef = el), buttonIcon: "plus", options: workspaceSelectionOptions, activeItemIndex: this.activeItemIndex, editingIndex: this.editingIndex, onButtonClick: this.handleNewWorkspace, onMenuClosed: this.handleMenuClosed })));
3106
+ }
3107
+ get host() { return index.getElement(this); }
3108
+ };
3109
+ KritzelWorkspaceManager.style = kritzelWorkspaceManagerCss;
3110
+
2345
3111
  exports.kritzel_brush_style = KritzelBrushStyle;
2346
3112
  exports.kritzel_color = KritzelColor;
2347
3113
  exports.kritzel_color_palette = KritzelColorPalette;
@@ -2357,9 +3123,11 @@ exports.kritzel_font = KritzelFont;
2357
3123
  exports.kritzel_font_family = KritzelFontFamily;
2358
3124
  exports.kritzel_font_size = KritzelFontSize;
2359
3125
  exports.kritzel_icon = KritzelIcon;
3126
+ exports.kritzel_menu = KritzelMenu;
3127
+ exports.kritzel_portal = KritzelPortal;
3128
+ exports.kritzel_split_button = KritzelSplitButton;
2360
3129
  exports.kritzel_stroke_size = KritzelStrokeSize;
2361
3130
  exports.kritzel_tooltip = KritzelTooltip;
2362
3131
  exports.kritzel_utility_panel = KritzelUtilityPanel;
2363
- //# sourceMappingURL=kritzel-brush-style.kritzel-color.kritzel-color-palette.kritzel-context-menu.kritzel-control-brush-config.kritzel-control-text-config.kritzel-controls.kritzel-cursor-trail.kritzel-dropdown.kritzel-editor.kritzel-engine.kritzel-font.kritzel-font-family.kritzel-font-size.kritzel-icon.kritzel-stroke-size.kritzel-tooltip.kritzel-utility-panel.entry.cjs.js.map
2364
-
2365
- //# sourceMappingURL=kritzel-brush-style_18.cjs.entry.js.map
3132
+ exports.kritzel_workspace_manager = KritzelWorkspaceManager;
3133
+ //# sourceMappingURL=kritzel-brush-style.kritzel-color.kritzel-color-palette.kritzel-context-menu.kritzel-control-brush-config.kritzel-control-text-config.kritzel-controls.kritzel-cursor-trail.kritzel-dropdown.kritzel-editor.kritzel-engine.kritzel-font.kritzel-font-family.kritzel-font-size.kritzel-icon.kritzel-menu.kritzel-portal.kritzel-split-button.kritzel-stroke-size.kritzel-tooltip.kritzel-utility-panel.kritzel-workspace-manager.entry.cjs.js.map