@xom11/whiteboard 0.32.0 → 0.33.0

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 (68) hide show
  1. package/dist/ai.d.mts +1 -1
  2. package/dist/ai.d.ts +1 -1
  3. package/dist/ai.mjs +2 -2
  4. package/dist/catalog.json +4 -4
  5. package/dist/{chunk-FI2MGX5H.mjs → chunk-4NJUTCFF.mjs} +3 -3
  6. package/dist/{chunk-FI2MGX5H.mjs.map → chunk-4NJUTCFF.mjs.map} +1 -1
  7. package/dist/{chunk-XSTGTEGP.mjs → chunk-BZZ5BROM.mjs} +4 -5
  8. package/dist/chunk-BZZ5BROM.mjs.map +1 -0
  9. package/dist/{host-JNLJ5BVR.mjs → chunk-C3RDFBQ5.mjs} +17 -32
  10. package/dist/chunk-C3RDFBQ5.mjs.map +1 -0
  11. package/dist/chunk-C7C66BAV.mjs +11 -0
  12. package/dist/chunk-C7C66BAV.mjs.map +1 -0
  13. package/dist/{chunk-DBG6DZ2V.mjs → chunk-FOPZOVI3.mjs} +5 -4
  14. package/dist/chunk-FOPZOVI3.mjs.map +1 -0
  15. package/dist/{chunk-MOAXHVKI.mjs → chunk-GKDQ5IV7.mjs} +3 -3
  16. package/dist/{chunk-MOAXHVKI.mjs.map → chunk-GKDQ5IV7.mjs.map} +1 -1
  17. package/dist/{chunk-KLGPAMJS.mjs → chunk-NBMYET5H.mjs} +3 -10
  18. package/dist/{chunk-KLGPAMJS.mjs.map → chunk-NBMYET5H.mjs.map} +1 -1
  19. package/dist/{chunk-DJM5EWTT.mjs → chunk-NTFG7ZRN.mjs} +2 -2
  20. package/dist/{chunk-DJM5EWTT.mjs.map → chunk-NTFG7ZRN.mjs.map} +1 -1
  21. package/dist/{chunk-C76SOFXF.mjs → chunk-QCK3Z5WN.mjs} +3 -3
  22. package/dist/{chunk-C76SOFXF.mjs.map → chunk-QCK3Z5WN.mjs.map} +1 -1
  23. package/dist/geometry-2d.d.mts +1 -1
  24. package/dist/geometry-2d.d.ts +1 -1
  25. package/dist/geometry-2d.js +146 -115
  26. package/dist/geometry-2d.js.map +1 -1
  27. package/dist/geometry-2d.mjs +4 -3
  28. package/dist/geometry-3d.d.mts +1 -1
  29. package/dist/geometry-3d.d.ts +1 -1
  30. package/dist/geometry-3d.js +6 -4
  31. package/dist/geometry-3d.js.map +1 -1
  32. package/dist/geometry-3d.mjs +2 -2
  33. package/dist/graph-2d.d.mts +1 -1
  34. package/dist/graph-2d.d.ts +1 -1
  35. package/dist/graph-2d.js +6 -4
  36. package/dist/graph-2d.js.map +1 -1
  37. package/dist/graph-2d.mjs +2 -2
  38. package/dist/host-6WTLCXUE.mjs +62 -0
  39. package/dist/host-6WTLCXUE.mjs.map +1 -0
  40. package/dist/{host-H2IGOKJU.mjs → host-BWIXT5TR.mjs} +3 -3
  41. package/dist/{host-H2IGOKJU.mjs.map → host-BWIXT5TR.mjs.map} +1 -1
  42. package/dist/{host-VRWLQSMH.mjs → host-QDVRULJV.mjs} +10 -7
  43. package/dist/host-QDVRULJV.mjs.map +1 -0
  44. package/dist/{host-W4U6YCSX.mjs → host-USOIVTQB.mjs} +10 -7
  45. package/dist/host-USOIVTQB.mjs.map +1 -0
  46. package/dist/index.d.mts +13 -3
  47. package/dist/index.d.ts +13 -3
  48. package/dist/index.js +173 -119
  49. package/dist/index.js.map +1 -1
  50. package/dist/index.mjs +31 -16
  51. package/dist/index.mjs.map +1 -1
  52. package/dist/latex.d.mts +1 -1
  53. package/dist/latex.d.ts +1 -1
  54. package/dist/latex.mjs +1 -1
  55. package/dist/studio.d.mts +35 -0
  56. package/dist/studio.d.ts +35 -0
  57. package/dist/studio.js +10883 -0
  58. package/dist/studio.js.map +1 -0
  59. package/dist/studio.mjs +28 -0
  60. package/dist/studio.mjs.map +1 -0
  61. package/dist/{types-tePd94vW.d.mts → types-eEEEVsLF.d.mts} +1 -1
  62. package/dist/{types-tePd94vW.d.ts → types-eEEEVsLF.d.ts} +1 -1
  63. package/package.json +9 -2
  64. package/dist/chunk-DBG6DZ2V.mjs.map +0 -1
  65. package/dist/chunk-XSTGTEGP.mjs.map +0 -1
  66. package/dist/host-JNLJ5BVR.mjs.map +0 -1
  67. package/dist/host-VRWLQSMH.mjs.map +0 -1
  68. package/dist/host-W4U6YCSX.mjs.map +0 -1
@@ -4,7 +4,7 @@ import { lazy } from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
6
6
  var LatexStampHost = lazy(
7
- () => import('./host-H2IGOKJU.mjs').then((m) => ({ default: m.LatexStampHost }))
7
+ () => import('./host-BWIXT5TR.mjs').then((m) => ({ default: m.LatexStampHost }))
8
8
  );
9
9
  var LatexIcon = /* @__PURE__ */ jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.6", strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: /* @__PURE__ */ jsx("path", { d: "M17 5 H7 L13 12 L7 19 H17" }) });
10
10
  var latexStamp = {
@@ -35,5 +35,5 @@ var latexStamp = {
35
35
  };
36
36
 
37
37
  export { latexStamp };
38
- //# sourceMappingURL=chunk-C76SOFXF.mjs.map
39
- //# sourceMappingURL=chunk-C76SOFXF.mjs.map
38
+ //# sourceMappingURL=chunk-QCK3Z5WN.mjs.map
39
+ //# sourceMappingURL=chunk-QCK3Z5WN.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stamps/latex/index.tsx"],"names":[],"mappings":";;;;AAYA,IAAM,cAAA,GAAiB,IAAA;AAAA,EAAK,MAC1B,OAAO,qBAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,cAAA,EAAe,CAAE;AAC9D,CAAA;AAEA,IAAM,SAAA,mBACJ,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,IAAA,EAAK,QAAO,IAAA,EAAK,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,gBAAe,WAAA,EAAY,KAAA,EAAM,aAAA,EAAc,OAAA,EAAQ,cAAA,EAAe,OAAA,EAAQ,aAAA,EAAY,MAAA,EAC3J,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,2BAAA,EAA4B,CAAA,EACtC,CAAA;AAGK,IAAM,UAAA,GAAyC;AAAA,EACpD,IAAA,EAAM,OAAA;AAAA,EACN,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,YAAA,EAAc,qCAAA;AAAA,EACd,WAAA,EAAa,SAAA;AAAA,EACb,aAAA,EAAe,qBAAA;AAAA,EACf,iBAAA,EAAmB,iBAAA;AAAA,EACnB,MAAM,wBAAwB,IAAA,EAAM;AAClC,IAAA,IAAI,CAAC,iBAAA,CAAkB,IAAI,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,MAAM,yEAAiE,CAAA;AAAA,IACnF;AACA,IAAA,OAAO,gBAAA,CAAiB,IAAA,CAAK,GAAA,EAAK,IAAA,CAAK,WAAW,CAAA;AAAA,EACpD,CAAA;AAAA,EACA,MAAM,0BAA0B,OAAA,EAA4C;AAC1E,IAAA,MAAM,OAAO,OAAA,CAAQ,UAAA;AACrB,IAAA,MAAM,SAAU,OAAA,CAAuC,MAAA;AACvD,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAA,EAAQ,OAAO,IAAA;AAC7B,IAAA,IAAI,CAAC,iBAAA,CAAkB,IAAI,CAAA,EAAG,OAAO,IAAA;AACrC,IAAA,MAAM,YAAY,MAAM,gBAAA,CAAiB,IAAA,CAAK,GAAA,EAAK,KAAK,WAAW,CAAA;AACnE,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,kBAAA,CAAmB,SAAS,CAAC,CAAA;AACnD,IAAA,MAAM,OAAA,GAAU,4BAAA,IACd,OAAO,IAAA,KAAS,WAAA,GAAc,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,SAAS,QAAQ,CAAA,CAAA;AAEhF,IAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAU,eAAA,EAAgB;AAAA,EACtD,CAAA;AAAA,EACA,IAAA,EAAM;AACR","file":"chunk-C76SOFXF.mjs","sourcesContent":["'use client';\n\nimport { lazy } from 'react';\nimport { renderLatexToSvg } from './render';\nimport type {\n RestoredStampFile,\n StampType,\n} from '../shared/types';\nimport { isLatexCustomData, type LatexCustomData } from './types';\n\nexport type { LatexCustomData };\n\nconst LatexStampHost = lazy(() =>\n import('./host').then((m) => ({ default: m.LatexStampHost })),\n);\n\nconst LatexIcon = (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M17 5 H7 L13 12 L7 19 H17\" />\n </svg>\n);\n\nexport const latexStamp: StampType<LatexCustomData> = {\n kind: 'latex',\n shortcutKey: 'l',\n toolbarLabel: 'L',\n toolbarTitle: 'Chèn công thức LaTeX (L)',\n toolbarIcon: LatexIcon,\n toolbarTestId: 'stamp-toolbar-latex',\n matchesCustomData: isLatexCustomData,\n async renderSvgFromCustomData(data) {\n if (!isLatexCustomData(data)) {\n throw new Error('latexStamp.renderSvgFromCustomData: customData không phải latex');\n }\n return renderLatexToSvg(data.src, data.displayMode);\n },\n async restoreFileFromCustomData(element): Promise<RestoredStampFile | null> {\n const data = element.customData as LatexCustomData | undefined;\n const fileId = (element as { fileId?: string | null }).fileId;\n if (!data || !fileId) return null;\n if (!isLatexCustomData(data)) return null;\n const svgString = await renderLatexToSvg(data.src, data.displayMode);\n const utf8 = unescape(encodeURIComponent(svgString));\n const dataURL = 'data:image/svg+xml;base64,' + (\n typeof btoa !== 'undefined' ? btoa(utf8) : Buffer.from(utf8).toString('base64')\n );\n return { fileId, dataURL, mimeType: 'image/svg+xml' };\n },\n Host: LatexStampHost,\n};\n"]}
1
+ {"version":3,"sources":["../src/stamps/latex/index.tsx"],"names":[],"mappings":";;;;AAYA,IAAM,cAAA,GAAiB,IAAA;AAAA,EAAK,MAC1B,OAAO,qBAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,cAAA,EAAe,CAAE;AAC9D,CAAA;AAEA,IAAM,SAAA,mBACJ,GAAA,CAAC,KAAA,EAAA,EAAI,KAAA,EAAM,IAAA,EAAK,QAAO,IAAA,EAAK,OAAA,EAAQ,WAAA,EAAY,IAAA,EAAK,MAAA,EAAO,MAAA,EAAO,gBAAe,WAAA,EAAY,KAAA,EAAM,aAAA,EAAc,OAAA,EAAQ,cAAA,EAAe,OAAA,EAAQ,aAAA,EAAY,MAAA,EAC3J,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,2BAAA,EAA4B,CAAA,EACtC,CAAA;AAGK,IAAM,UAAA,GAAyC;AAAA,EACpD,IAAA,EAAM,OAAA;AAAA,EACN,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,YAAA,EAAc,qCAAA;AAAA,EACd,WAAA,EAAa,SAAA;AAAA,EACb,aAAA,EAAe,qBAAA;AAAA,EACf,iBAAA,EAAmB,iBAAA;AAAA,EACnB,MAAM,wBAAwB,IAAA,EAAM;AAClC,IAAA,IAAI,CAAC,iBAAA,CAAkB,IAAI,CAAA,EAAG;AAC5B,MAAA,MAAM,IAAI,MAAM,yEAAiE,CAAA;AAAA,IACnF;AACA,IAAA,OAAO,gBAAA,CAAiB,IAAA,CAAK,GAAA,EAAK,IAAA,CAAK,WAAW,CAAA;AAAA,EACpD,CAAA;AAAA,EACA,MAAM,0BAA0B,OAAA,EAA4C;AAC1E,IAAA,MAAM,OAAO,OAAA,CAAQ,UAAA;AACrB,IAAA,MAAM,SAAU,OAAA,CAAuC,MAAA;AACvD,IAAA,IAAI,CAAC,IAAA,IAAQ,CAAC,MAAA,EAAQ,OAAO,IAAA;AAC7B,IAAA,IAAI,CAAC,iBAAA,CAAkB,IAAI,CAAA,EAAG,OAAO,IAAA;AACrC,IAAA,MAAM,YAAY,MAAM,gBAAA,CAAiB,IAAA,CAAK,GAAA,EAAK,KAAK,WAAW,CAAA;AACnE,IAAA,MAAM,IAAA,GAAO,QAAA,CAAS,kBAAA,CAAmB,SAAS,CAAC,CAAA;AACnD,IAAA,MAAM,OAAA,GAAU,4BAAA,IACd,OAAO,IAAA,KAAS,WAAA,GAAc,IAAA,CAAK,IAAI,CAAA,GAAI,MAAA,CAAO,IAAA,CAAK,IAAI,CAAA,CAAE,SAAS,QAAQ,CAAA,CAAA;AAEhF,IAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAU,eAAA,EAAgB;AAAA,EACtD,CAAA;AAAA,EACA,IAAA,EAAM;AACR","file":"chunk-QCK3Z5WN.mjs","sourcesContent":["'use client';\n\nimport { lazy } from 'react';\nimport { renderLatexToSvg } from './render';\nimport type {\n RestoredStampFile,\n StampType,\n} from '../shared/types';\nimport { isLatexCustomData, type LatexCustomData } from './types';\n\nexport type { LatexCustomData };\n\nconst LatexStampHost = lazy(() =>\n import('./host').then((m) => ({ default: m.LatexStampHost })),\n);\n\nconst LatexIcon = (\n <svg width=\"20\" height=\"20\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"1.6\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M17 5 H7 L13 12 L7 19 H17\" />\n </svg>\n);\n\nexport const latexStamp: StampType<LatexCustomData> = {\n kind: 'latex',\n shortcutKey: 'l',\n toolbarLabel: 'L',\n toolbarTitle: 'Chèn công thức LaTeX (L)',\n toolbarIcon: LatexIcon,\n toolbarTestId: 'stamp-toolbar-latex',\n matchesCustomData: isLatexCustomData,\n async renderSvgFromCustomData(data) {\n if (!isLatexCustomData(data)) {\n throw new Error('latexStamp.renderSvgFromCustomData: customData không phải latex');\n }\n return renderLatexToSvg(data.src, data.displayMode);\n },\n async restoreFileFromCustomData(element): Promise<RestoredStampFile | null> {\n const data = element.customData as LatexCustomData | undefined;\n const fileId = (element as { fileId?: string | null }).fileId;\n if (!data || !fileId) return null;\n if (!isLatexCustomData(data)) return null;\n const svgString = await renderLatexToSvg(data.src, data.displayMode);\n const utf8 = unescape(encodeURIComponent(svgString));\n const dataURL = 'data:image/svg+xml;base64,' + (\n typeof btoa !== 'undefined' ? btoa(utf8) : Buffer.from(utf8).toString('base64')\n );\n return { fileId, dataURL, mimeType: 'image/svg+xml' };\n },\n Host: LatexStampHost,\n};\n"]}
@@ -1,4 +1,4 @@
1
- import { B as BaseStampCustomData, S as StampType } from './types-tePd94vW.mjs';
1
+ import { B as BaseStampCustomData, S as StampType } from './types-eEEEVsLF.mjs';
2
2
  import 'react';
3
3
  import '@excalidraw/excalidraw/element/types';
4
4
 
@@ -1,4 +1,4 @@
1
- import { B as BaseStampCustomData, S as StampType } from './types-tePd94vW.js';
1
+ import { B as BaseStampCustomData, S as StampType } from './types-eEEEVsLF.js';
2
2
  import 'react';
3
3
  import '@excalidraw/excalidraw/element/types';
4
4
 
@@ -11344,92 +11344,10 @@ var init_useChordShortcut = __esm({
11344
11344
  A_CODE2 = "a".charCodeAt(0);
11345
11345
  }
11346
11346
  });
11347
-
11348
- // src/stamps/shared/insertImage.ts
11349
- function buildStampImageElement(api, fileId, width, height, customData, x, y) {
11350
- const appState = api?.getAppState() ?? { scrollX: 0, scrollY: 0, width: 800, height: 600, zoom: { value: 1 } };
11351
- const cx = x ?? appState.scrollX + (appState.width ?? 800) / 2 / (appState.zoom?.value ?? 1) - width / 2;
11352
- const cy = y ?? appState.scrollY + (appState.height ?? 600) / 2 / (appState.zoom?.value ?? 1) - height / 2;
11353
- return {
11354
- type: "image",
11355
- id: "stamp_" + Date.now() + "_" + Math.random().toString(36).slice(2, 8),
11356
- x: cx,
11357
- y: cy,
11358
- width,
11359
- height,
11360
- fileId,
11361
- customData,
11362
- angle: 0,
11363
- strokeColor: "transparent",
11364
- backgroundColor: "transparent",
11365
- fillStyle: "solid",
11366
- strokeWidth: 1,
11367
- strokeStyle: "solid",
11368
- roughness: 0,
11369
- opacity: 100,
11370
- groupIds: [],
11371
- roundness: null,
11372
- seed: Math.floor(Math.random() * 1e9),
11373
- versionNonce: 0,
11374
- version: 1,
11375
- isDeleted: false,
11376
- boundElements: null,
11377
- updated: Date.now(),
11378
- link: null,
11379
- locked: false,
11380
- status: "saved",
11381
- scale: [1, 1]
11382
- };
11383
- }
11384
- async function insertStampImage(api, opts) {
11385
- const { dataURL, fileId, width, height, mimeType } = await createStampFile(opts.svgString);
11386
- api.addFiles([{ id: fileId, dataURL, mimeType, created: Date.now() }]);
11387
- const customData = opts.makeCustomData();
11388
- const elements = api.getSceneElements();
11389
- const editingId = opts.editingElementId ?? null;
11390
- if (editingId) {
11391
- const old = elements.find((e) => e.id === editingId) ;
11392
- const oldLongest = old ? Math.max(old.width ?? 0, old.height ?? 0) : 0;
11393
- const newLongest = Math.max(width, height);
11394
- const scale2 = oldLongest > 0 && newLongest > 0 ? oldLongest / newLongest : 1;
11395
- const w = width * scale2;
11396
- const h = height * scale2;
11397
- const updated = elements.map(
11398
- (e) => e.id === editingId ? { ...e, fileId, customData, width: w, height: h } : e
11399
- );
11400
- api.updateScene({ elements: updated, appState: clearAppStateAfterInsert() });
11401
- return { fileId, width: w, height: h, elementId: editingId };
11402
- }
11403
- const newElement = buildStampImageElement(
11404
- api,
11405
- fileId,
11406
- width,
11407
- height,
11408
- customData,
11409
- opts.position?.x,
11410
- opts.position?.y
11411
- );
11412
- api.updateScene({
11413
- elements: [...elements, newElement],
11414
- appState: clearAppStateAfterInsert()
11415
- });
11416
- return { fileId, width, height, elementId: newElement.id };
11417
- }
11418
- var clearAppStateAfterInsert;
11419
- var init_insertImage = __esm({
11420
- "src/stamps/shared/insertImage.ts"() {
11421
- init_svgToStampFile();
11422
- clearAppStateAfterInsert = () => ({
11423
- selectedElementIds: {},
11424
- croppingElementId: null
11425
- });
11426
- }
11427
- });
11428
- function useStampStore(domain, editingElement, parseInitial) {
11347
+ function useStampStore(domain, makeInitialState) {
11429
11348
  const ref = React2.useRef(null);
11430
11349
  if (!ref.current) {
11431
- const initial = editingElement?.customData ? parseInitial(editingElement.customData) ?? createEmptyState(domain) : createEmptyState(domain);
11432
- ref.current = createStore(initial);
11350
+ ref.current = createStore(makeInitialState?.() ?? createEmptyState(domain));
11433
11351
  }
11434
11352
  return ref.current;
11435
11353
  }
@@ -12006,38 +11924,29 @@ var init_dslRenderRow = __esm({
12006
11924
  init_describeDsl();
12007
11925
  }
12008
11926
  });
12009
-
12010
- // src/stamps/geometry-2d/host.tsx
12011
- var host_exports = {};
12012
- __export(host_exports, {
12013
- GeometryStampHost: () => GeometryStampHost
12014
- });
12015
- function parseInitialState(data) {
12016
- if (!isGeometryCustomData(data)) return null;
12017
- return deserializeBoard(data.jsonState);
12018
- }
12019
- var GeometryStampHost;
12020
- var init_host = __esm({
12021
- "src/stamps/geometry-2d/host.tsx"() {
11927
+ var GeometryStudio;
11928
+ var init_GeometryStudio = __esm({
11929
+ "src/stamps/geometry-2d/studio/GeometryStudio.tsx"() {
12022
11930
  "use client";
12023
11931
  init_StampLeftPanel();
12024
11932
  init_icons();
12025
11933
  init_EditorPanel();
12026
11934
  init_tools();
12027
11935
  init_useChordShortcut();
12028
- init_insertImage();
12029
11936
  init_serialize();
12030
- init_types3();
12031
11937
  init_scene();
12032
11938
  init_useIsMobile();
12033
11939
  init_useStampStore();
12034
11940
  init_dslRenderRow();
12035
- GeometryStampHost = React2.forwardRef(
12036
- function GeometryStampHost2({ api, editingElement, onClose, isDark, generateGeometryFigure, onGeometryDraft }, ref) {
11941
+ GeometryStudio = React2.forwardRef(
11942
+ function GeometryStudio2({ initialJsonState, onCommit, onClose, isDark, api, generateGeometryFigure, onGeometryDraft }, ref) {
12037
11943
  const panelRef = React2.useRef(null);
12038
11944
  const { isMobile } = useIsMobile();
12039
11945
  const [drawerOpen, setDrawerOpen] = React2.useState(false);
12040
- const sceneStore = useStampStore("2d", editingElement, parseInitialState);
11946
+ const sceneStore = useStampStore(
11947
+ "2d",
11948
+ () => initialJsonState ? deserializeBoard(initialJsonState) : null
11949
+ );
12041
11950
  const initialMeta = sceneStore.getState().meta;
12042
11951
  const initialView = initialMeta.domain === "2d" ? initialMeta.view : DEFAULT_VIEW_2D;
12043
11952
  const [selectedTool, setSelectedTool] = React2.useState("move");
@@ -12061,24 +11970,15 @@ var init_host = __esm({
12061
11970
  const renderRow = React2.useMemo(() => makeDslRenderRow(sceneStore), [sceneStore]);
12062
11971
  const handleInsert = React2.useCallback(
12063
11972
  async (jsonState, svgString) => {
12064
- if (!api) return;
12065
11973
  try {
12066
- await insertStampImage(api, {
12067
- svgString,
12068
- makeCustomData: () => ({
12069
- kind: "geometry",
12070
- version: 1,
12071
- jsonState
12072
- }),
12073
- editingElementId: editingElement?.id ?? null,
12074
- preserveExistingSize: true
12075
- });
11974
+ const committed = await onCommit(jsonState, svgString);
11975
+ if (committed === false) return;
12076
11976
  } catch (err) {
12077
- console.error("Geometry insert failed:", err);
11977
+ console.error("Geometry commit failed:", err);
12078
11978
  }
12079
11979
  onClose();
12080
11980
  },
12081
- [api, editingElement?.id, onClose]
11981
+ [onCommit, onClose]
12082
11982
  );
12083
11983
  React2.useImperativeHandle(
12084
11984
  ref,
@@ -12160,6 +12060,137 @@ var init_host = __esm({
12160
12060
  }
12161
12061
  });
12162
12062
 
12063
+ // src/stamps/shared/insertImage.ts
12064
+ function buildStampImageElement(api, fileId, width, height, customData, x, y) {
12065
+ const appState = api?.getAppState() ?? { scrollX: 0, scrollY: 0, width: 800, height: 600, zoom: { value: 1 } };
12066
+ const cx = x ?? appState.scrollX + (appState.width ?? 800) / 2 / (appState.zoom?.value ?? 1) - width / 2;
12067
+ const cy = y ?? appState.scrollY + (appState.height ?? 600) / 2 / (appState.zoom?.value ?? 1) - height / 2;
12068
+ return {
12069
+ type: "image",
12070
+ id: "stamp_" + Date.now() + "_" + Math.random().toString(36).slice(2, 8),
12071
+ x: cx,
12072
+ y: cy,
12073
+ width,
12074
+ height,
12075
+ fileId,
12076
+ customData,
12077
+ angle: 0,
12078
+ strokeColor: "transparent",
12079
+ backgroundColor: "transparent",
12080
+ fillStyle: "solid",
12081
+ strokeWidth: 1,
12082
+ strokeStyle: "solid",
12083
+ roughness: 0,
12084
+ opacity: 100,
12085
+ groupIds: [],
12086
+ roundness: null,
12087
+ seed: Math.floor(Math.random() * 1e9),
12088
+ versionNonce: 0,
12089
+ version: 1,
12090
+ isDeleted: false,
12091
+ boundElements: null,
12092
+ updated: Date.now(),
12093
+ link: null,
12094
+ locked: false,
12095
+ status: "saved",
12096
+ scale: [1, 1]
12097
+ };
12098
+ }
12099
+ async function insertStampImage(api, opts) {
12100
+ const { dataURL, fileId, width, height, mimeType } = await createStampFile(opts.svgString);
12101
+ api.addFiles([{ id: fileId, dataURL, mimeType, created: Date.now() }]);
12102
+ const customData = opts.makeCustomData();
12103
+ const elements = api.getSceneElements();
12104
+ const editingId = opts.editingElementId ?? null;
12105
+ if (editingId) {
12106
+ const old = elements.find((e) => e.id === editingId) ;
12107
+ const oldLongest = old ? Math.max(old.width ?? 0, old.height ?? 0) : 0;
12108
+ const newLongest = Math.max(width, height);
12109
+ const scale2 = oldLongest > 0 && newLongest > 0 ? oldLongest / newLongest : 1;
12110
+ const w = width * scale2;
12111
+ const h = height * scale2;
12112
+ const updated = elements.map(
12113
+ (e) => e.id === editingId ? { ...e, fileId, customData, width: w, height: h } : e
12114
+ );
12115
+ api.updateScene({ elements: updated, appState: clearAppStateAfterInsert() });
12116
+ return { fileId, width: w, height: h, elementId: editingId };
12117
+ }
12118
+ const newElement = buildStampImageElement(
12119
+ api,
12120
+ fileId,
12121
+ width,
12122
+ height,
12123
+ customData,
12124
+ opts.position?.x,
12125
+ opts.position?.y
12126
+ );
12127
+ api.updateScene({
12128
+ elements: [...elements, newElement],
12129
+ appState: clearAppStateAfterInsert()
12130
+ });
12131
+ return { fileId, width, height, elementId: newElement.id };
12132
+ }
12133
+ var clearAppStateAfterInsert;
12134
+ var init_insertImage = __esm({
12135
+ "src/stamps/shared/insertImage.ts"() {
12136
+ init_svgToStampFile();
12137
+ clearAppStateAfterInsert = () => ({
12138
+ selectedElementIds: {},
12139
+ croppingElementId: null
12140
+ });
12141
+ }
12142
+ });
12143
+
12144
+ // src/stamps/geometry-2d/host.tsx
12145
+ var host_exports = {};
12146
+ __export(host_exports, {
12147
+ GeometryStampHost: () => GeometryStampHost
12148
+ });
12149
+ var GeometryStampHost;
12150
+ var init_host = __esm({
12151
+ "src/stamps/geometry-2d/host.tsx"() {
12152
+ "use client";
12153
+ init_GeometryStudio();
12154
+ init_insertImage();
12155
+ init_types3();
12156
+ GeometryStampHost = React2.forwardRef(
12157
+ function GeometryStampHost2({ api, editingElement, onClose, isDark, generateGeometryFigure, onGeometryDraft }, ref) {
12158
+ const initialJsonState = isGeometryCustomData(editingElement?.customData) ? editingElement.customData.jsonState : void 0;
12159
+ const handleCommit = React2.useCallback(
12160
+ async (jsonState, svgString) => {
12161
+ if (!api) return false;
12162
+ await insertStampImage(api, {
12163
+ svgString,
12164
+ makeCustomData: () => ({
12165
+ kind: "geometry",
12166
+ version: 1,
12167
+ jsonState
12168
+ }),
12169
+ editingElementId: editingElement?.id ?? null,
12170
+ preserveExistingSize: true
12171
+ });
12172
+ return true;
12173
+ },
12174
+ [api, editingElement?.id]
12175
+ );
12176
+ return /* @__PURE__ */ jsxRuntime.jsx(
12177
+ GeometryStudio,
12178
+ {
12179
+ ref,
12180
+ initialJsonState,
12181
+ onCommit: handleCommit,
12182
+ onClose,
12183
+ isDark,
12184
+ api,
12185
+ generateGeometryFigure,
12186
+ onGeometryDraft
12187
+ }
12188
+ );
12189
+ }
12190
+ );
12191
+ }
12192
+ });
12193
+
12163
12194
  // src/stamps/geometry-2d/index.tsx
12164
12195
  init_render();
12165
12196
  init_svgToStampFile();