@xom11/whiteboard 0.24.2 → 0.25.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 (84) hide show
  1. package/README.md +84 -11
  2. package/dist/ai.d.mts +422 -566
  3. package/dist/ai.d.ts +422 -566
  4. package/dist/ai.js +1527 -407
  5. package/dist/ai.js.map +1 -1
  6. package/dist/ai.mjs +1008 -512
  7. package/dist/ai.mjs.map +1 -1
  8. package/dist/catalog.json +4 -4
  9. package/dist/{chunk-BKSXPNPQ.mjs → chunk-AYSFWUPK.mjs} +4 -3
  10. package/dist/chunk-AYSFWUPK.mjs.map +1 -0
  11. package/dist/chunk-B4NJJZFR.mjs +18 -0
  12. package/dist/chunk-B4NJJZFR.mjs.map +1 -0
  13. package/dist/{chunk-LVNCYP4J.mjs → chunk-CJBLJUWG.mjs} +5 -5
  14. package/dist/{chunk-LVNCYP4J.mjs.map → chunk-CJBLJUWG.mjs.map} +1 -1
  15. package/dist/{chunk-7WQXXEVR.mjs → chunk-ESVPQWHX.mjs} +5 -5
  16. package/dist/{chunk-7WQXXEVR.mjs.map → chunk-ESVPQWHX.mjs.map} +1 -1
  17. package/dist/{chunk-KRC2XOIG.mjs → chunk-I24QOHPU.mjs} +3 -3
  18. package/dist/{chunk-KRC2XOIG.mjs.map → chunk-I24QOHPU.mjs.map} +1 -1
  19. package/dist/{chunk-ZBJBQKJ2.mjs → chunk-IHUFOV7L.mjs} +4 -19
  20. package/dist/chunk-IHUFOV7L.mjs.map +1 -0
  21. package/dist/{chunk-AZIARTGX.mjs → chunk-M42TGYT6.mjs} +3 -3
  22. package/dist/{chunk-AZIARTGX.mjs.map → chunk-M42TGYT6.mjs.map} +1 -1
  23. package/dist/{chunk-45CGKJ7S.mjs → chunk-NDEZJKNY.mjs} +4 -4
  24. package/dist/{chunk-45CGKJ7S.mjs.map → chunk-NDEZJKNY.mjs.map} +1 -1
  25. package/dist/{chunk-BEZSQKPY.mjs → chunk-ONBCUWVI.mjs} +5 -4
  26. package/dist/chunk-ONBCUWVI.mjs.map +1 -0
  27. package/dist/{chunk-WM2VDYQA.mjs → chunk-REIJZDVZ.mjs} +4 -3
  28. package/dist/chunk-REIJZDVZ.mjs.map +1 -0
  29. package/dist/{chunk-2WF6KIGF.mjs → chunk-TB4CL25L.mjs} +9 -8
  30. package/dist/chunk-TB4CL25L.mjs.map +1 -0
  31. package/dist/chunk-VNCCIV6O.mjs +938 -0
  32. package/dist/chunk-VNCCIV6O.mjs.map +1 -0
  33. package/dist/{chunk-CGZZO4BX.mjs → chunk-VRHWDZ66.mjs} +5 -5
  34. package/dist/{chunk-CGZZO4BX.mjs.map → chunk-VRHWDZ66.mjs.map} +1 -1
  35. package/dist/{chunk-4DS3MKID.mjs → chunk-YSJOVBCD.mjs} +4 -4
  36. package/dist/{chunk-4DS3MKID.mjs.map → chunk-YSJOVBCD.mjs.map} +1 -1
  37. package/dist/geometry-2d.d.mts +2 -2
  38. package/dist/geometry-2d.d.ts +2 -2
  39. package/dist/geometry-2d.js +1383 -23
  40. package/dist/geometry-2d.js.map +1 -1
  41. package/dist/geometry-2d.mjs +6 -5
  42. package/dist/geometry-3d.d.mts +2 -2
  43. package/dist/geometry-3d.d.ts +2 -2
  44. package/dist/geometry-3d.js +2 -2
  45. package/dist/geometry-3d.js.map +1 -1
  46. package/dist/geometry-3d.mjs +5 -4
  47. package/dist/graph-2d.d.mts +2 -2
  48. package/dist/graph-2d.d.ts +2 -2
  49. package/dist/graph-2d.js +2 -2
  50. package/dist/graph-2d.js.map +1 -1
  51. package/dist/graph-2d.mjs +8 -7
  52. package/dist/{host-ZIQ77W33.mjs → host-A64ITWVX.mjs} +7 -6
  53. package/dist/host-A64ITWVX.mjs.map +1 -0
  54. package/dist/{host-EPZCNFLH.mjs → host-L7FMFZUW.mjs} +226 -29
  55. package/dist/host-L7FMFZUW.mjs.map +1 -0
  56. package/dist/{host-LKCMYEAV.mjs → host-QK53UYMD.mjs} +11 -10
  57. package/dist/host-QK53UYMD.mjs.map +1 -0
  58. package/dist/index.d.mts +3 -3
  59. package/dist/index.d.ts +3 -3
  60. package/dist/index.js +1414 -54
  61. package/dist/index.js.map +1 -1
  62. package/dist/index.mjs +18 -17
  63. package/dist/index.mjs.map +1 -1
  64. package/dist/latex.d.mts +2 -2
  65. package/dist/latex.d.ts +2 -2
  66. package/dist/render-3WTY7NZB.mjs +9 -0
  67. package/dist/{render-SA4JTOW3.mjs.map → render-3WTY7NZB.mjs.map} +1 -1
  68. package/dist/serialize-SRJVKYUG.mjs +8 -0
  69. package/dist/{serialize-JAVOU22E.mjs.map → serialize-SRJVKYUG.mjs.map} +1 -1
  70. package/dist/{types-vtvyKGAA.d.mts → types-DWRyCa2m.d.mts} +187 -2
  71. package/dist/{types-Crbefnfe.d.ts → types-DWRyCa2m.d.ts} +187 -2
  72. package/package.json +1 -1
  73. package/dist/chunk-2WF6KIGF.mjs.map +0 -1
  74. package/dist/chunk-BEZSQKPY.mjs.map +0 -1
  75. package/dist/chunk-BKSXPNPQ.mjs.map +0 -1
  76. package/dist/chunk-WM2VDYQA.mjs.map +0 -1
  77. package/dist/chunk-ZBJBQKJ2.mjs.map +0 -1
  78. package/dist/host-EPZCNFLH.mjs.map +0 -1
  79. package/dist/host-LKCMYEAV.mjs.map +0 -1
  80. package/dist/host-ZIQ77W33.mjs.map +0 -1
  81. package/dist/render-SA4JTOW3.mjs +0 -8
  82. package/dist/serialize-JAVOU22E.mjs +0 -7
  83. package/dist/types-DxlMPh-6.d.mts +0 -49
  84. package/dist/types-DxlMPh-6.d.ts +0 -49
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/scene/render/types2d.ts","../src/core/scene/render/JxgRenderer.ts"],"names":[],"mappings":"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","file":"chunk-AYSFWUPK.mjs","sourcesContent":["// src/core/scene/render/types2d.ts\nimport type { RenderCtx } from '../types';\n\nexport type Theme2D = {\n stroke: string;\n fill: string;\n label: string;\n axis: string;\n grid: string;\n pointFill: string;\n};\n\nexport const DEFAULT_THEME_2D: Theme2D = {\n stroke: '#0f172a',\n fill: '#60a5fa',\n label: '#0f172a',\n axis: '#94a3b8',\n grid: '#e2e8f0',\n pointFill: '#1e40af',\n};\n\nexport type RenderCtx2D = RenderCtx & {\n theme: Theme2D;\n};\n","// src/core/scene/render/JxgRenderer.ts\nimport type { Store } from '../store';\nimport type { State, SceneObject, RenderCtx } from '../types';\nimport { getKind } from '../registry';\nimport { DEFAULT_THEME_2D, type Theme2D } from './types2d';\nimport { collectFreeVars } from '../expressions/parser';\n\nexport type JxgRendererOptions = { theme?: Theme2D };\n\nexport class JxgRenderer {\n private board: unknown;\n private store: Store;\n private theme: Theme2D;\n private elements = new Map<string, unknown>();\n private unsubscribe: () => void;\n private disposed = false;\n\n /** Chỉ dùng cho domain='graph2d': parameter.label → parameter.value */\n private paramMap: Record<string, number> = {};\n /** Chỉ dùng cho domain='graph2d': function2d.id → expression string */\n private functionExpr: Record<string, string> = {};\n\n constructor(store: Store, board: unknown, options: JxgRendererOptions = {}) {\n this.store = store;\n this.board = board;\n this.theme = options.theme ?? DEFAULT_THEME_2D;\n this.unsubscribe = store.subscribe((next, prev) => this.applyDiff(prev, next));\n // Render state hiện tại (vd LOAD chạy trước khi subscribe).\n this.applyDiff(undefined, store.getState());\n }\n\n private ctx(): RenderCtx {\n return {\n jxg: this.board,\n resolveRef: (id: string) => {\n // Synthetic \"<polyId>:border:<N>\" → polygon.borders[N]. Polygon edges\n // là sub-segment do JSXGraph auto-tạo bên trong polygon; chúng không\n // có scene id riêng. Synthetic id cho phép construct tools (vd\n // perpendicular qua một cạnh đa giác) tham chiếu cạnh như một line.\n const m = /^(.+):border:(\\d+)$/.exec(id);\n if (m) {\n const poly = this.elements.get(m[1]) as { borders?: unknown[] } | undefined;\n if (!poly) throw new Error(`[scene/2d] resolveRef: chưa render polygon id=\"${m[1]}\"`);\n const borders = poly.borders;\n const idx = parseInt(m[2], 10);\n if (!Array.isArray(borders) || !borders[idx]) {\n throw new Error(`[scene/2d] resolveRef: polygon \"${m[1]}\" không có border[${idx}]`);\n }\n return borders[idx];\n }\n const el = this.elements.get(id);\n if (!el) throw new Error(`[scene/2d] resolveRef: chưa render id=\"${id}\"`);\n return el;\n },\n defaults: { theme: this.theme, _functionExpr: this.functionExpr },\n paramMap: this.paramMap,\n };\n }\n\n /**\n * Rebuild `paramMap` và `functionExpr` từ state hiện tại.\n * Chỉ chạy khi domain='graph2d'. Chi phí thấp vì parameters thường ≤ 8.\n */\n private rebuildGraphMaps(state: State): void {\n if (state.meta.domain !== 'graph2d') return;\n const params: Record<string, number> = {};\n const fns: Record<string, string> = {};\n for (const id of state.order) {\n const obj = state.objects[id];\n if (obj.kind === 'parameter') {\n params[obj.label] = (obj.attrs as { value: number }).value;\n } else if (obj.kind === 'function2d') {\n fns[obj.id] = (obj.attrs as { expression: string }).expression;\n }\n }\n this.paramMap = params;\n this.functionExpr = fns;\n }\n\n private create(obj: SceneObject): void {\n try {\n const def = getKind(obj.kind);\n const el = def.render(obj, this.ctx());\n this.elements.set(obj.id, el);\n this.attachFreePointDragSync(obj, el);\n } catch (err) {\n console.warn(`[scene/render/2d] không render được ${obj.kind} id=\"${obj.id}\":`, err);\n }\n }\n\n /**\n * Đồng bộ toạ độ live của free point về scene.constraint khi user kéo bằng\n * tay (Move tool / mobile drag). JSXGraph mutate obj.X()/Y() ngay nhưng\n * constraint vẫn giữ giá trị lúc tạo → serialize sẽ ra SVG y hệt cũ →\n * fileId SHA-256 trùng → Excalidraw bỏ qua refresh. (Regression từ\n * commit f41f366 sau scene v2 port.)\n *\n * Chỉ áp dụng cho free point — glider/intersection/midpoint không drag được\n * trực tiếp (toạ độ derived từ ref khác).\n */\n private attachFreePointDragSync(obj: SceneObject, el: unknown): void {\n if (obj.kind !== 'point') return;\n const c = (obj.attrs as { constraint?: { kind?: string } }).constraint;\n if (!c || c.kind !== 'free') return;\n \n const point = el as any;\n if (typeof point.on !== 'function') return;\n const sceneId = obj.id;\n point.on('up', () => {\n if (this.disposed) return;\n if (typeof point.X !== 'function' || typeof point.Y !== 'function') return;\n const x = point.X();\n const y = point.Y();\n if (!Number.isFinite(x) || !Number.isFinite(y)) return;\n const cur = this.store.getState().objects[sceneId];\n if (!cur) return;\n const curC = (cur.attrs as { constraint?: { kind?: string; x?: number; y?: number } }).constraint;\n if (!curC || curC.kind !== 'free') return;\n if (curC.x === x && curC.y === y) return;\n this.store.dispatch({\n type: 'UPDATE_ATTRS',\n payload: { id: sceneId, patch: { constraint: { kind: 'free', x, y } } },\n });\n });\n }\n\n private remove(id: string): void {\n // Selection halo (nếu có) phải bị xoá TRƯỚC element gốc — halo tham chiếu\n // tới point1/point2/center/vertices của element gốc qua lambda; xoá element\n // gốc trước sẽ làm halo dangling.\n this.removeHalo(id);\n this.selectedIds.delete(id);\n const el = this.elements.get(id);\n if (!el) return;\n try {\n const helpers = (el as Record<string, unknown>)._helpers;\n // Element chính bị remove trước, sau đó helpers (glider phụ trợ cho\n // tangent ...). Helpers thường là parent của element chính — nếu xoá\n // parent trước, JSXGraph có thể phàn nàn dangling reference.\n (this.board as { removeObject?: (e: unknown) => void }).removeObject?.(el);\n if (Array.isArray(helpers)) {\n for (const h of helpers) {\n try {\n (this.board as { removeObject?: (e: unknown) => void }).removeObject?.(h);\n } catch { /* ignore */ }\n }\n }\n } catch (err) {\n console.warn(`[scene/render/2d] không remove được id=\"${id}\":`, err);\n }\n this.elements.delete(id);\n }\n\n private applyDiff(prev: State | undefined, next: State): void {\n if (this.disposed) return;\n\n // Rebuild paramMap + functionExpr TRƯỚC khi diff, để ctx() có đúng\n // paramMap khi render lần đầu tiên.\n this.rebuildGraphMaps(next);\n\n const prevObjs = prev?.objects ?? {};\n const nextObjs = next.objects;\n\n // Xoá ids biến mất.\n for (const id of Object.keys(prevObjs)) {\n if (!(id in nextObjs)) this.remove(id);\n }\n\n // Thêm/cập nhật theo state.order — đảm bảo refs có trước.\n for (const id of next.order) {\n const cur = nextObjs[id];\n const old = prevObjs[id] as SceneObject | undefined;\n if (!old) {\n this.create(cur);\n continue;\n }\n if (Object.is(old, cur)) continue;\n const def = getKind(cur.kind);\n const existing = this.elements.get(id);\n if (def.update && existing) {\n try { def.update(cur, old, this.ctx(), existing); continue; }\n catch (err) { console.warn(`[scene/render/2d] update fail, recreate:`, err); }\n }\n this.remove(id);\n this.create(cur);\n }\n\n // Sau diff bình thường: nếu domain='graph2d', detect parameter value changes\n // và force re-render các function2d phụ thuộc.\n if (next.meta.domain === 'graph2d' && prev) {\n const changedParams = new Set<string>();\n for (const id of next.order) {\n const cur = next.objects[id];\n const old = prev.objects[id] as SceneObject | undefined;\n if (cur.kind !== 'parameter' || old?.kind !== 'parameter') continue;\n if ((cur.attrs as { value: number }).value !== (old.attrs as { value: number }).value) {\n changedParams.add(cur.label);\n }\n }\n if (changedParams.size > 0) {\n for (const id of next.order) {\n const obj = next.objects[id];\n if (obj.kind !== 'function2d') continue;\n const expr = (obj.attrs as { expression: string }).expression;\n const refs = collectFreeVars(expr);\n if (refs.some((r) => changedParams.has(r))) {\n this.remove(id);\n this.create(obj);\n }\n }\n }\n }\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.unsubscribe();\n for (const id of Array.from(this.elements.keys())) this.remove(id);\n this.disposed = true;\n }\n\n /** Return the rendered JSXGraph element for a scene id, or null if not found. */\n getElement(id: string): unknown {\n return this.elements.get(id) ?? null;\n }\n\n /** Return a read-only view of the scene id → JSXGraph element map (for hit-test). */\n listElements(): Map<string, unknown> {\n return this.elements;\n }\n\n // Selection halo overlay model: thay vì đổi màu element gốc thành đỏ, tạo\n // một halo element gray phía sau (lower layer) → giữ nguyên màu gốc. Hỗ\n // trợ multi-select cho cả canvas click-selection lẫn ObjectListPanel.\n private selectedIds: Set<string> = new Set();\n private haloMap: Map<string, unknown[]> = new Map();\n\n highlight(ids: string | string[] | null): void {\n if (this.disposed) return;\n const newIds = new Set<string>(\n ids == null ? [] : Array.isArray(ids) ? ids : [ids],\n );\n // Remove halos cho ids đã bị bỏ chọn.\n for (const id of this.selectedIds) {\n if (!newIds.has(id)) this.removeHalo(id);\n }\n // Add halos cho ids mới chọn.\n for (const id of newIds) {\n if (!this.selectedIds.has(id) && this.elements.has(id)) this.addHalo(id);\n }\n this.selectedIds = newIds;\n try {\n (this.board as { update?: () => void }).update?.();\n } catch { /* ignore */ }\n }\n\n private removeHalo(id: string): void {\n const halos = this.haloMap.get(id);\n if (!halos) return;\n const board = this.board as { removeObject?: (e: unknown) => void };\n for (const h of halos) {\n try { board.removeObject?.(h); } catch { /* ignore */ }\n }\n this.haloMap.delete(id);\n }\n\n private addHalo(id: string): void {\n const el = this.elements.get(id) as\n | {\n elType?: string;\n getAttribute?: (k: string) => unknown;\n X?: () => number;\n Y?: () => number;\n point1?: unknown;\n point2?: unknown;\n center?: unknown;\n Radius?: () => number;\n vertices?: unknown[];\n }\n | undefined;\n if (!el) return;\n const board = this.board as {\n create?: (kind: string, parents: unknown[], attrs?: unknown) => unknown;\n };\n if (!board.create) return;\n\n // Selection palette — gray fill + darker gray border (xem\n // tham chiếu /tmp/ss.png).\n const SEL_STROKE = '#475569'; // slate-600\n const SEL_FILL = '#cbd5e1'; // slate-300\n const haloBase = {\n strokeColor: SEL_STROKE,\n strokeOpacity: 0.55,\n fillColor: SEL_FILL,\n fillOpacity: 0.3,\n fixed: true,\n withLabel: false,\n name: '',\n highlight: false,\n layer: 4,\n needsRegularUpdate: true,\n };\n const halos: unknown[] = [];\n try {\n switch (el.elType) {\n case 'point':\n case 'glider':\n case 'intersection': {\n const baseSize = (el.getAttribute?.('size') as number | undefined) ?? 4;\n const halo = board.create('point', [\n () => el.X?.() ?? 0,\n () => el.Y?.() ?? 0,\n ], {\n ...haloBase,\n size: baseSize + 6,\n face: 'o',\n strokeWidth: 2,\n strokeOpacity: 0.75,\n fillOpacity: 0.25,\n });\n halos.push(halo);\n break;\n }\n case 'segment': {\n if (el.point1 && el.point2) {\n const halo = board.create('segment', [el.point1, el.point2], {\n ...haloBase,\n strokeWidth: 9,\n straightFirst: false,\n straightLast: false,\n });\n halos.push(halo);\n }\n break;\n }\n case 'line':\n case 'arrow':\n case 'ray':\n case 'vector':\n case 'tangent':\n case 'normal':\n case 'parallel':\n case 'perpendicular':\n case 'bisector': {\n if (el.point1 && el.point2) {\n const halo = board.create('line', [el.point1, el.point2], {\n ...haloBase,\n strokeWidth: 9,\n });\n halos.push(halo);\n }\n break;\n }\n case 'circle': {\n if (el.center && typeof el.Radius === 'function') {\n const halo = board.create('circle', [el.center, () => el.Radius?.() ?? 0], {\n ...haloBase,\n strokeWidth: 9,\n fillOpacity: 0,\n });\n halos.push(halo);\n }\n break;\n }\n case 'polygon': {\n if (Array.isArray(el.vertices) && el.vertices.length >= 3) {\n // JSXGraph polygon.vertices có thể append vertex đầu lặp lại ở\n // cuối để đóng path — trim cho an toàn.\n const last = el.vertices.length - 1;\n const verts = el.vertices[last] === el.vertices[0]\n ? el.vertices.slice(0, last)\n : el.vertices.slice();\n const halo = board.create('polygon', verts, {\n ...haloBase,\n fillOpacity: 0.2,\n borders: {\n strokeColor: SEL_STROKE,\n strokeWidth: 7,\n strokeOpacity: 0.55,\n highlight: false,\n },\n });\n halos.push(halo);\n }\n break;\n }\n default:\n // Các kind khác (curve, arc, sector, angle, ...) — chưa hỗ trợ halo.\n break;\n }\n } catch (err) {\n console.warn('[scene/render/2d] halo create fail:', err);\n }\n if (halos.length) this.haloMap.set(id, halos);\n }\n}\n"]}
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ // src/core/scene/registry.ts
3
+ var registry = /* @__PURE__ */ new Map();
4
+ function registerKind(def) {
5
+ if (registry.has(def.type)) {
6
+ console.warn(`[scene] kind "${def.type}" \u0111\xE3 \u0111\u01B0\u1EE3c \u0111\u0103ng k\xFD \u2014 ghi \u0111\xE8 \u0111\u1ECBnh ngh\u0129a c\u0169`);
7
+ }
8
+ registry.set(def.type, def);
9
+ }
10
+ function getKind(type) {
11
+ const def = registry.get(type);
12
+ if (!def) throw new Error(`[scene] unknown kind: ${type}`);
13
+ return def;
14
+ }
15
+
16
+ export { getKind, registerKind };
17
+ //# sourceMappingURL=chunk-B4NJJZFR.mjs.map
18
+ //# sourceMappingURL=chunk-B4NJJZFR.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/scene/registry.ts"],"names":[],"mappings":";AAGA,IAAM,QAAA,uBAAe,GAAA,EAAqB;AAEnC,SAAS,aAA0C,GAAA,EAAuB;AAC/E,EAAA,IAAI,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,IAAI,CAAA,EAAG;AAC1B,IAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,cAAA,EAAiB,GAAA,CAAI,IAAI,CAAA,6GAAA,CAA0C,CAAA;AAAA,EAClF;AACA,EAAA,QAAA,CAAS,GAAA,CAAI,GAAA,CAAI,IAAA,EAAM,GAAyB,CAAA;AAClD;AAEO,SAAS,QAAQ,IAAA,EAAuB;AAC7C,EAAA,MAAM,GAAA,GAAM,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA;AAC7B,EAAA,IAAI,CAAC,GAAA,EAAK,MAAM,IAAI,KAAA,CAAM,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAE,CAAA;AACzD,EAAA,OAAO,GAAA;AACT","file":"chunk-B4NJJZFR.mjs","sourcesContent":["// src/core/scene/registry.ts\nimport type { KindDef } from './types';\n\nconst registry = new Map<string, KindDef>();\n\nexport function registerKind<A = Record<string, unknown>>(def: KindDef<A>): void {\n if (registry.has(def.type)) {\n console.warn(`[scene] kind \"${def.type}\" đã được đăng ký — ghi đè định nghĩa cũ`);\n }\n registry.set(def.type, def as unknown as KindDef);\n}\n\nexport function getKind(type: string): KindDef {\n const def = registry.get(type);\n if (!def) throw new Error(`[scene] unknown kind: ${type}`);\n return def;\n}\n\nexport function listKinds(): KindDef[] {\n return Array.from(registry.values());\n}\n\n// Chỉ dùng cho test — reset registry giữa các test case.\nexport function __clearRegistryForTests(): void {\n registry.clear();\n}\n"]}
@@ -1,8 +1,8 @@
1
1
  "use client";
2
- import { paletteFor } from './chunk-AZIARTGX.mjs';
3
- import { JxgRenderer } from './chunk-BKSXPNPQ.mjs';
2
+ import { paletteFor } from './chunk-M42TGYT6.mjs';
3
+ import { JxgRenderer } from './chunk-AYSFWUPK.mjs';
4
4
  import { renderJsxgOffscreen } from './chunk-ICR4CVOE.mjs';
5
- import { createStore } from './chunk-ZBJBQKJ2.mjs';
5
+ import { createStore } from './chunk-IHUFOV7L.mjs';
6
6
 
7
7
  // src/stamps/graph-2d/render.ts
8
8
  var DEFAULT_WIDTH = 600;
@@ -53,5 +53,5 @@ async function renderGraphSvgFromState(state, _isDark, width = DEFAULT_WIDTH, he
53
53
  }
54
54
 
55
55
  export { renderGraphSvgFromState };
56
- //# sourceMappingURL=chunk-LVNCYP4J.mjs.map
57
- //# sourceMappingURL=chunk-LVNCYP4J.mjs.map
56
+ //# sourceMappingURL=chunk-CJBLJUWG.mjs.map
57
+ //# sourceMappingURL=chunk-CJBLJUWG.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stamps/graph-2d/render.ts"],"names":[],"mappings":";;;;;;AAUA,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,cAAA,GAAiB,GAAA;AAEvB,eAAsB,wBACpB,KAAA,EACA,OAAA,EACA,KAAA,GAAQ,aAAA,EACR,SAAS,cAAA,EACQ;AACjB,EAAA,MAAM,OAAA,GAAU,WAAW,KAAK,CAAA;AAChC,EAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AACnB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,KAAW,SAAA,GAAY,KAAK,IAAA,GAAO,IAAA;AACrD,EAAA,MAAM,IAAA,GAAyC;AAAA,IAC7C,MAAM,IAAA,IAAQ,GAAA;AAAA,IACd,MAAM,IAAA,IAAQ,EAAA;AAAA,IACd,MAAM,IAAA,IAAQ,EAAA;AAAA,IACd,MAAM,IAAA,IAAQ;AAAA,GAChB;AACA,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,mBAAA,CAAoB;AAAA,MAC9C,IAAA;AAAA,MACA,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,MACtB,IAAA,EAAM,MAAM,QAAA,IAAY,IAAA;AAAA,MACxB,IAAA,EAAM,MAAM,QAAA,IAAY,IAAA;AAAA,MACxB,eAAA,EAAiB,KAAA;AAAA,MACjB,YAAA,EAAc,CAAC,GAAA,KAAQ;AAErB,QAAA,MAAM,OAAQ,GAAA,CAAY,OAAA;AAC1B,QAAA,IAAI,CAAC,IAAA,EAAM;AACX,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,KAAK,OAAA,GAAU,UAAA;AACpB,QAAA,IAAA,CAAK,KAAK,cAAA,GAAiB,KAAA;AAC3B,QAAA,IAAA,CAAK,KAAK,UAAA,GAAa,KAAA;AACvB,QAAA,IAAA,CAAK,KAAK,QAAA,GAAW,KAAA;AACrB,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,KAAA;AAChC,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,EAAC;AAC5B,QAAA,IAAA,CAAK,MAAM,OAAA,GAAU,UAAA;AACrB,QAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,KAAA;AACjC,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,IAAA;AAChC,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,IAAA;AAAA,MAClC,CAAA;AAAA,MACA,KAAA,EAAO,CAAC,KAAA,KAAU;AAChB,QAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,QAAA,OAAO,IAAI,WAAA,CAAY,KAAA,EAAO,KAAK,CAAA;AAAA,MACrC;AAAA,KACD,CAAA;AACD,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,EAAA;AAAA,EACT;AACF","file":"chunk-LVNCYP4J.mjs","sourcesContent":["// src/stamps/graph-2d/render.ts\n// Offscreen SVG export từ graph2d State. Dùng cho insert/restore stamp.\n//\n// LƯU Ý: Luôn dùng light palette — Excalidraw tự invert trong dark mode.\nimport type { State } from '../../core/scene/types';\nimport { createStore } from '../../core/scene/store';\nimport { JxgRenderer } from '../../core/scene/render/JxgRenderer';\nimport { paletteFor } from './editor/theme';\nimport { renderJsxgOffscreen } from '../shared/jxgOffscreenRender';\n\nconst DEFAULT_WIDTH = 600;\nconst DEFAULT_HEIGHT = 400;\n\nexport async function renderGraphSvgFromState(\n state: State,\n _isDark: boolean,\n width = DEFAULT_WIDTH,\n height = DEFAULT_HEIGHT,\n): Promise<string> {\n const palette = paletteFor(false);\n const meta = state.meta;\n const view = meta.domain === 'graph2d' ? meta.view : null;\n const bbox: [number, number, number, number] = [\n view?.xMin ?? -10,\n view?.yMax ?? 10,\n view?.xMax ?? 10,\n view?.yMin ?? -10,\n ];\n try {\n const { svgString } = await renderJsxgOffscreen({\n bbox,\n dims: { width, height },\n axis: view?.showAxis ?? true,\n grid: view?.showGrid ?? true,\n keepAspectRatio: false,\n applyOptions: (JXG) => {\n \n const opts = (JXG as any).Options;\n if (!opts) return;\n opts.text = opts.text || {};\n opts.text.display = 'internal';\n opts.text.useASCIIMathML = false;\n opts.text.useMathJax = false;\n opts.text.useKatex = false;\n opts.text.strokeColor = palette.label;\n opts.label = opts.label || {};\n opts.label.display = 'internal';\n opts.label.strokeColor = palette.label;\n opts.axis = opts.axis || {};\n opts.axis.strokeColor = palette.axis;\n opts.grid = opts.grid || {};\n opts.grid.strokeColor = palette.grid;\n },\n setup: (board) => {\n const store = createStore(state);\n return new JxgRenderer(store, board);\n },\n });\n return svgString;\n } catch {\n // Match old contract: callers expect '' when no SVG produced.\n return '';\n }\n}\n"]}
1
+ {"version":3,"sources":["../src/stamps/graph-2d/render.ts"],"names":[],"mappings":";;;;;;AAUA,IAAM,aAAA,GAAgB,GAAA;AACtB,IAAM,cAAA,GAAiB,GAAA;AAEvB,eAAsB,wBACpB,KAAA,EACA,OAAA,EACA,KAAA,GAAQ,aAAA,EACR,SAAS,cAAA,EACQ;AACjB,EAAA,MAAM,OAAA,GAAU,WAAW,KAAK,CAAA;AAChC,EAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AACnB,EAAA,MAAM,IAAA,GAAO,IAAA,CAAK,MAAA,KAAW,SAAA,GAAY,KAAK,IAAA,GAAO,IAAA;AACrD,EAAA,MAAM,IAAA,GAAyC;AAAA,IAC7C,MAAM,IAAA,IAAQ,GAAA;AAAA,IACd,MAAM,IAAA,IAAQ,EAAA;AAAA,IACd,MAAM,IAAA,IAAQ,EAAA;AAAA,IACd,MAAM,IAAA,IAAQ;AAAA,GAChB;AACA,EAAA,IAAI;AACF,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,mBAAA,CAAoB;AAAA,MAC9C,IAAA;AAAA,MACA,IAAA,EAAM,EAAE,KAAA,EAAO,MAAA,EAAO;AAAA,MACtB,IAAA,EAAM,MAAM,QAAA,IAAY,IAAA;AAAA,MACxB,IAAA,EAAM,MAAM,QAAA,IAAY,IAAA;AAAA,MACxB,eAAA,EAAiB,KAAA;AAAA,MACjB,YAAA,EAAc,CAAC,GAAA,KAAQ;AAErB,QAAA,MAAM,OAAQ,GAAA,CAAY,OAAA;AAC1B,QAAA,IAAI,CAAC,IAAA,EAAM;AACX,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,KAAK,OAAA,GAAU,UAAA;AACpB,QAAA,IAAA,CAAK,KAAK,cAAA,GAAiB,KAAA;AAC3B,QAAA,IAAA,CAAK,KAAK,UAAA,GAAa,KAAA;AACvB,QAAA,IAAA,CAAK,KAAK,QAAA,GAAW,KAAA;AACrB,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,KAAA;AAChC,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAA,IAAS,EAAC;AAC5B,QAAA,IAAA,CAAK,MAAM,OAAA,GAAU,UAAA;AACrB,QAAA,IAAA,CAAK,KAAA,CAAM,cAAc,OAAA,CAAQ,KAAA;AACjC,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,IAAA;AAChC,QAAA,IAAA,CAAK,IAAA,GAAO,IAAA,CAAK,IAAA,IAAQ,EAAC;AAC1B,QAAA,IAAA,CAAK,IAAA,CAAK,cAAc,OAAA,CAAQ,IAAA;AAAA,MAClC,CAAA;AAAA,MACA,KAAA,EAAO,CAAC,KAAA,KAAU;AAChB,QAAA,MAAM,KAAA,GAAQ,YAAY,KAAK,CAAA;AAC/B,QAAA,OAAO,IAAI,WAAA,CAAY,KAAA,EAAO,KAAK,CAAA;AAAA,MACrC;AAAA,KACD,CAAA;AACD,IAAA,OAAO,SAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AAEN,IAAA,OAAO,EAAA;AAAA,EACT;AACF","file":"chunk-CJBLJUWG.mjs","sourcesContent":["// src/stamps/graph-2d/render.ts\n// Offscreen SVG export từ graph2d State. Dùng cho insert/restore stamp.\n//\n// LƯU Ý: Luôn dùng light palette — Excalidraw tự invert trong dark mode.\nimport type { State } from '../../core/scene/types';\nimport { createStore } from '../../core/scene/store';\nimport { JxgRenderer } from '../../core/scene/render/JxgRenderer';\nimport { paletteFor } from './editor/theme';\nimport { renderJsxgOffscreen } from '../shared/jxgOffscreenRender';\n\nconst DEFAULT_WIDTH = 600;\nconst DEFAULT_HEIGHT = 400;\n\nexport async function renderGraphSvgFromState(\n state: State,\n _isDark: boolean,\n width = DEFAULT_WIDTH,\n height = DEFAULT_HEIGHT,\n): Promise<string> {\n const palette = paletteFor(false);\n const meta = state.meta;\n const view = meta.domain === 'graph2d' ? meta.view : null;\n const bbox: [number, number, number, number] = [\n view?.xMin ?? -10,\n view?.yMax ?? 10,\n view?.xMax ?? 10,\n view?.yMin ?? -10,\n ];\n try {\n const { svgString } = await renderJsxgOffscreen({\n bbox,\n dims: { width, height },\n axis: view?.showAxis ?? true,\n grid: view?.showGrid ?? true,\n keepAspectRatio: false,\n applyOptions: (JXG) => {\n \n const opts = (JXG as any).Options;\n if (!opts) return;\n opts.text = opts.text || {};\n opts.text.display = 'internal';\n opts.text.useASCIIMathML = false;\n opts.text.useMathJax = false;\n opts.text.useKatex = false;\n opts.text.strokeColor = palette.label;\n opts.label = opts.label || {};\n opts.label.display = 'internal';\n opts.label.strokeColor = palette.label;\n opts.axis = opts.axis || {};\n opts.axis.strokeColor = palette.axis;\n opts.grid = opts.grid || {};\n opts.grid.strokeColor = palette.grid;\n },\n setup: (board) => {\n const store = createStore(state);\n return new JxgRenderer(store, board);\n },\n });\n return svgString;\n } catch {\n // Match old contract: callers expect '' when no SVG produced.\n return '';\n }\n}\n"]}
@@ -1,13 +1,13 @@
1
1
  "use client";
2
- import { renderGraphSvgFromState } from './chunk-LVNCYP4J.mjs';
2
+ import { renderGraphSvgFromState } from './chunk-CJBLJUWG.mjs';
3
3
  import { isGraph2DCustomData } from './chunk-O4WIZFRQ.mjs';
4
- import { parseSceneState } from './chunk-KRC2XOIG.mjs';
4
+ import { parseSceneState } from './chunk-I24QOHPU.mjs';
5
5
  import { svgToStampFile } from './chunk-5UTGXHLJ.mjs';
6
6
  import { lazy } from 'react';
7
7
  import { jsxs, jsx } from 'react/jsx-runtime';
8
8
 
9
9
  var Graph2DStampHost = lazy(
10
- () => import('./host-LKCMYEAV.mjs').then((m) => ({ default: m.Graph2DStampHost }))
10
+ () => import('./host-QK53UYMD.mjs').then((m) => ({ default: m.Graph2DStampHost }))
11
11
  );
12
12
  var Graph2DIcon = /* @__PURE__ */ jsxs(
13
13
  "svg",
@@ -57,5 +57,5 @@ var graph2dStamp = {
57
57
  };
58
58
 
59
59
  export { graph2dStamp };
60
- //# sourceMappingURL=chunk-7WQXXEVR.mjs.map
61
- //# sourceMappingURL=chunk-7WQXXEVR.mjs.map
60
+ //# sourceMappingURL=chunk-ESVPQWHX.mjs.map
61
+ //# sourceMappingURL=chunk-ESVPQWHX.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stamps/graph-2d/index.tsx"],"names":[],"mappings":";;;;;;;AAUA,IAAM,gBAAA,GAAmB,IAAA;AAAA,EAAK,MAC5B,OAAO,qBAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,gBAAA,EAAiB,CAAE;AAChE,CAAA;AAEA,IAAM,WAAA,mBACJ,IAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,KAAA,EAAM,IAAA;AAAA,IACN,MAAA,EAAO,IAAA;AAAA,IACP,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,MAAA;AAAA,IACL,MAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAY,KAAA;AAAA,IACZ,aAAA,EAAc,OAAA;AAAA,IACd,cAAA,EAAe,OAAA;AAAA,IACf,aAAA,EAAY,MAAA;AAAA,IAEZ,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,GAAE,iBAAA,EAAkB,CAAA;AAAA,sBAC1B,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,4BAAA,EAA6B;AAAA;AAAA;AACvC,CAAA;AAGK,IAAM,YAAA,GAA6C;AAAA,EACxD,IAAA,EAAM,SAAA;AAAA,EACN,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,WAAA;AAAA,EACd,YAAA,EAAc,sCAAA;AAAA,EACd,WAAA,EAAa,WAAA;AAAA,EACb,aAAA,EAAe,eAAA;AAAA,EACf,YAAA,EAAc,IAAA;AAAA,EACd,iBAAA,EAAmB,mBAAA;AAAA,EAEnB,MAAM,wBAAwB,IAAA,EAAgC;AAC5D,IAAA,IAAI,CAAC,mBAAA,CAAoB,IAAI,CAAA,EAAG;AAC9B,MAAA,MAAM,IAAI,MAAM,gFAAwE,CAAA;AAAA,IAC1F;AACA,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,IAAA,CAAK,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,MAAM,2EAA8D,CAAA;AAC1F,IAAA,OAAO,uBAAA,CAAwB,OAAO,KAAK,CAAA;AAAA,EAC7C,CAAA;AAAA,EAEA,MAAM,0BAA0B,OAAA,EAA4C;AAC1E,IAAA,MAAM,OAAO,OAAA,CAAQ,UAAA;AACrB,IAAA,MAAM,SAAU,OAAA,CAAuC,MAAA;AACvD,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,mBAAA,CAAoB,IAAI,GAAG,OAAO,IAAA;AAClD,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,IAAA,CAAK,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,IAAA,MAAM,SAAA,GAAY,MAAM,uBAAA,CAAwB,KAAA,EAAO,KAAK,CAAA;AAC5D,IAAA,OAAO,cAAA,CAAe,WAAW,MAAM,CAAA;AAAA,EACzC,CAAA;AAAA,EAEA,IAAA,EAAM;AACR","file":"chunk-7WQXXEVR.mjs","sourcesContent":["'use client';\nimport { lazy, type ReactNode } from 'react';\nimport { renderGraphSvgFromState } from './render';\nimport { isGraph2DCustomData, type Graph2DCustomData } from './types';\nimport { parseSceneState } from './serialize';\nimport { svgToStampFile } from '../shared/svgToStampFile';\nimport type { RestoredStampFile, StampType } from '../shared/types';\n\nexport type { Graph2DCustomData };\n\nconst Graph2DStampHost = lazy(() =>\n import('./host').then((m) => ({ default: m.Graph2DStampHost })),\n);\n\nconst Graph2DIcon: ReactNode = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M3 3L3 21L21 21\" />\n <path d=\"M6 16Q9 8 12 10Q15 12 18 6\" />\n </svg>\n);\n\nexport const graph2dStamp: StampType<Graph2DCustomData> = {\n kind: 'graph2d',\n shortcutKey: 'h',\n toolbarLabel: '📈',\n toolbarTitle: 'Chèn đồ thị 2D (H)',\n toolbarIcon: Graph2DIcon,\n toolbarTestId: 'graph2d-stamp',\n experimental: true,\n matchesCustomData: isGraph2DCustomData,\n\n async renderSvgFromCustomData(data: unknown): Promise<string> {\n if (!isGraph2DCustomData(data)) {\n throw new Error('graph2dStamp.renderSvgFromCustomData: customData không phải graph2d v2');\n }\n const state = parseSceneState(data.jsonState);\n if (!state) throw new Error('graph2dStamp.renderSvgFromCustomData: jsonState không hợp lệ');\n return renderGraphSvgFromState(state, false);\n },\n\n async restoreFileFromCustomData(element): Promise<RestoredStampFile | null> {\n const data = element.customData;\n const fileId = (element as { fileId?: string | null }).fileId;\n if (!fileId || !isGraph2DCustomData(data)) return null;\n const state = parseSceneState(data.jsonState);\n if (!state) return null;\n const svgString = await renderGraphSvgFromState(state, false);\n return svgToStampFile(svgString, fileId);\n },\n\n Host: Graph2DStampHost,\n};\n"]}
1
+ {"version":3,"sources":["../src/stamps/graph-2d/index.tsx"],"names":[],"mappings":";;;;;;;AAUA,IAAM,gBAAA,GAAmB,IAAA;AAAA,EAAK,MAC5B,OAAO,qBAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,gBAAA,EAAiB,CAAE;AAChE,CAAA;AAEA,IAAM,WAAA,mBACJ,IAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,KAAA,EAAM,IAAA;AAAA,IACN,MAAA,EAAO,IAAA;AAAA,IACP,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,MAAA;AAAA,IACL,MAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAY,KAAA;AAAA,IACZ,aAAA,EAAc,OAAA;AAAA,IACd,cAAA,EAAe,OAAA;AAAA,IACf,aAAA,EAAY,MAAA;AAAA,IAEZ,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,GAAE,iBAAA,EAAkB,CAAA;AAAA,sBAC1B,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,4BAAA,EAA6B;AAAA;AAAA;AACvC,CAAA;AAGK,IAAM,YAAA,GAA6C;AAAA,EACxD,IAAA,EAAM,SAAA;AAAA,EACN,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,WAAA;AAAA,EACd,YAAA,EAAc,sCAAA;AAAA,EACd,WAAA,EAAa,WAAA;AAAA,EACb,aAAA,EAAe,eAAA;AAAA,EACf,YAAA,EAAc,IAAA;AAAA,EACd,iBAAA,EAAmB,mBAAA;AAAA,EAEnB,MAAM,wBAAwB,IAAA,EAAgC;AAC5D,IAAA,IAAI,CAAC,mBAAA,CAAoB,IAAI,CAAA,EAAG;AAC9B,MAAA,MAAM,IAAI,MAAM,gFAAwE,CAAA;AAAA,IAC1F;AACA,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,IAAA,CAAK,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,KAAA,EAAO,MAAM,IAAI,MAAM,2EAA8D,CAAA;AAC1F,IAAA,OAAO,uBAAA,CAAwB,OAAO,KAAK,CAAA;AAAA,EAC7C,CAAA;AAAA,EAEA,MAAM,0BAA0B,OAAA,EAA4C;AAC1E,IAAA,MAAM,OAAO,OAAA,CAAQ,UAAA;AACrB,IAAA,MAAM,SAAU,OAAA,CAAuC,MAAA;AACvD,IAAA,IAAI,CAAC,MAAA,IAAU,CAAC,mBAAA,CAAoB,IAAI,GAAG,OAAO,IAAA;AAClD,IAAA,MAAM,KAAA,GAAQ,eAAA,CAAgB,IAAA,CAAK,SAAS,CAAA;AAC5C,IAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,IAAA,MAAM,SAAA,GAAY,MAAM,uBAAA,CAAwB,KAAA,EAAO,KAAK,CAAA;AAC5D,IAAA,OAAO,cAAA,CAAe,WAAW,MAAM,CAAA;AAAA,EACzC,CAAA;AAAA,EAEA,IAAA,EAAM;AACR","file":"chunk-ESVPQWHX.mjs","sourcesContent":["'use client';\nimport { lazy, type ReactNode } from 'react';\nimport { renderGraphSvgFromState } from './render';\nimport { isGraph2DCustomData, type Graph2DCustomData } from './types';\nimport { parseSceneState } from './serialize';\nimport { svgToStampFile } from '../shared/svgToStampFile';\nimport type { RestoredStampFile, StampType } from '../shared/types';\n\nexport type { Graph2DCustomData };\n\nconst Graph2DStampHost = lazy(() =>\n import('./host').then((m) => ({ default: m.Graph2DStampHost })),\n);\n\nconst Graph2DIcon: ReactNode = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n <path d=\"M3 3L3 21L21 21\" />\n <path d=\"M6 16Q9 8 12 10Q15 12 18 6\" />\n </svg>\n);\n\nexport const graph2dStamp: StampType<Graph2DCustomData> = {\n kind: 'graph2d',\n shortcutKey: 'h',\n toolbarLabel: '📈',\n toolbarTitle: 'Chèn đồ thị 2D (H)',\n toolbarIcon: Graph2DIcon,\n toolbarTestId: 'graph2d-stamp',\n experimental: true,\n matchesCustomData: isGraph2DCustomData,\n\n async renderSvgFromCustomData(data: unknown): Promise<string> {\n if (!isGraph2DCustomData(data)) {\n throw new Error('graph2dStamp.renderSvgFromCustomData: customData không phải graph2d v2');\n }\n const state = parseSceneState(data.jsonState);\n if (!state) throw new Error('graph2dStamp.renderSvgFromCustomData: jsonState không hợp lệ');\n return renderGraphSvgFromState(state, false);\n },\n\n async restoreFileFromCustomData(element): Promise<RestoredStampFile | null> {\n const data = element.customData;\n const fileId = (element as { fileId?: string | null }).fileId;\n if (!fileId || !isGraph2DCustomData(data)) return null;\n const state = parseSceneState(data.jsonState);\n if (!state) return null;\n const svgString = await renderGraphSvgFromState(state, false);\n return svgToStampFile(svgString, fileId);\n },\n\n Host: Graph2DStampHost,\n};\n"]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { serializeScene } from './chunk-WM2VDYQA.mjs';
2
+ import { serializeScene } from './chunk-REIJZDVZ.mjs';
3
3
 
4
4
  // src/stamps/graph-2d/serialize.ts
5
5
  function stringifySceneState(state) {
@@ -24,5 +24,5 @@ function parseSceneState(json) {
24
24
  }
25
25
 
26
26
  export { parseSceneState, stringifySceneState };
27
- //# sourceMappingURL=chunk-KRC2XOIG.mjs.map
28
- //# sourceMappingURL=chunk-KRC2XOIG.mjs.map
27
+ //# sourceMappingURL=chunk-I24QOHPU.mjs.map
28
+ //# sourceMappingURL=chunk-I24QOHPU.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stamps/graph-2d/serialize.ts"],"names":[],"mappings":";;;AASO,SAAS,oBAAoB,KAAA,EAAsB;AACxD,EAAA,OAAO,eAAe,KAAK,CAAA;AAC7B;AAEO,SAAS,gBAAgB,IAAA,EAA4B;AAC1D,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACvB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAU,OAAO,IAAA;AAC5C,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,IAAI,CAAA,CAAE,IAAA,EAAM,MAAA,KAAW,SAAA,EAAW,OAAO,IAAA;AACzC,EAAA,IAAI,CAAC,EAAE,IAAA,EAAM,IAAA,IAAQ,OAAO,CAAA,CAAE,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AAC7D,EAAA,IAAI,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,EAAU,OAAO,IAAA;AAC1C,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,KAAK,GAAG,OAAO,IAAA;AACpC,EAAA,IAAI,CAAC,CAAA,CAAE,OAAA,IAAW,OAAO,CAAA,CAAE,OAAA,KAAY,UAAU,OAAO,IAAA;AACxD,EAAA,OAAO,GAAA;AACT","file":"chunk-KRC2XOIG.mjs","sourcesContent":["// src/stamps/graph-2d/serialize.ts\n//\n// graph-2d đã dùng plain State (không envelope) ngay từ đầu. Sau Tier D PR 3,\n// thin wrapper qua shared helper cho serialize. parseSceneState giữ behavior\n// null-on-invalid để host/index.tsx có thể discriminate \"customData hỏng\".\n\nimport { serializeScene } from '../shared/serializeScene';\nimport type { State } from '../../core/scene/types';\n\nexport function stringifySceneState(state: State): string {\n return serializeScene(state);\n}\n\nexport function parseSceneState(json: string): State | null {\n if (!json) return null;\n let raw: unknown;\n try {\n raw = JSON.parse(json);\n } catch {\n return null;\n }\n if (!raw || typeof raw !== 'object') return null;\n const v = raw as Partial<State>;\n if (v.meta?.domain !== 'graph2d') return null;\n if (!v.meta?.view || typeof v.meta.view !== 'object') return null;\n if (typeof v.counter !== 'number') return null;\n if (!Array.isArray(v.order)) return null;\n if (!v.objects || typeof v.objects !== 'object') return null;\n return raw as State;\n}\n"]}
1
+ {"version":3,"sources":["../src/stamps/graph-2d/serialize.ts"],"names":[],"mappings":";;;AASO,SAAS,oBAAoB,KAAA,EAAsB;AACxD,EAAA,OAAO,eAAe,KAAK,CAAA;AAC7B;AAEO,SAAS,gBAAgB,IAAA,EAA4B;AAC1D,EAAA,IAAI,CAAC,MAAM,OAAO,IAAA;AAClB,EAAA,IAAI,GAAA;AACJ,EAAA,IAAI;AACF,IAAA,GAAA,GAAM,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,EACvB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,UAAU,OAAO,IAAA;AAC5C,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,IAAI,CAAA,CAAE,IAAA,EAAM,MAAA,KAAW,SAAA,EAAW,OAAO,IAAA;AACzC,EAAA,IAAI,CAAC,EAAE,IAAA,EAAM,IAAA,IAAQ,OAAO,CAAA,CAAE,IAAA,CAAK,IAAA,KAAS,QAAA,EAAU,OAAO,IAAA;AAC7D,EAAA,IAAI,OAAO,CAAA,CAAE,OAAA,KAAY,QAAA,EAAU,OAAO,IAAA;AAC1C,EAAA,IAAI,CAAC,KAAA,CAAM,OAAA,CAAQ,CAAA,CAAE,KAAK,GAAG,OAAO,IAAA;AACpC,EAAA,IAAI,CAAC,CAAA,CAAE,OAAA,IAAW,OAAO,CAAA,CAAE,OAAA,KAAY,UAAU,OAAO,IAAA;AACxD,EAAA,OAAO,GAAA;AACT","file":"chunk-I24QOHPU.mjs","sourcesContent":["// src/stamps/graph-2d/serialize.ts\n//\n// graph-2d đã dùng plain State (không envelope) ngay từ đầu. Sau Tier D PR 3,\n// thin wrapper qua shared helper cho serialize. parseSceneState giữ behavior\n// null-on-invalid để host/index.tsx có thể discriminate \"customData hỏng\".\n\nimport { serializeScene } from '../shared/serializeScene';\nimport type { State } from '../../core/scene/types';\n\nexport function stringifySceneState(state: State): string {\n return serializeScene(state);\n}\n\nexport function parseSceneState(json: string): State | null {\n if (!json) return null;\n let raw: unknown;\n try {\n raw = JSON.parse(json);\n } catch {\n return null;\n }\n if (!raw || typeof raw !== 'object') return null;\n const v = raw as Partial<State>;\n if (v.meta?.domain !== 'graph2d') return null;\n if (!v.meta?.view || typeof v.meta.view !== 'object') return null;\n if (typeof v.counter !== 'number') return null;\n if (!Array.isArray(v.order)) return null;\n if (!v.objects || typeof v.objects !== 'object') return null;\n return raw as State;\n}\n"]}
@@ -1,22 +1,7 @@
1
1
  "use client";
2
+ import { getKind } from './chunk-B4NJJZFR.mjs';
2
3
  import { produce } from 'immer';
3
4
 
4
- // src/core/scene/store.ts
5
-
6
- // src/core/scene/registry.ts
7
- var registry = /* @__PURE__ */ new Map();
8
- function registerKind(def) {
9
- if (registry.has(def.type)) {
10
- console.warn(`[scene] kind "${def.type}" \u0111\xE3 \u0111\u01B0\u1EE3c \u0111\u0103ng k\xFD \u2014 ghi \u0111\xE8 \u0111\u1ECBnh ngh\u0129a c\u0169`);
11
- }
12
- registry.set(def.type, def);
13
- }
14
- function getKind(type) {
15
- const def = registry.get(type);
16
- if (!def) throw new Error(`[scene] unknown kind: ${type}`);
17
- return def;
18
- }
19
-
20
5
  // src/core/scene/reducer.ts
21
6
  function collectDependents(state, rootId) {
22
7
  const dependents = /* @__PURE__ */ new Set([rootId]);
@@ -325,6 +310,6 @@ function collectFreeVars(expression) {
325
310
  return out.sort();
326
311
  }
327
312
 
328
- export { collectFreeVars, compile, createStore, getKind, registerKind, validate };
329
- //# sourceMappingURL=chunk-ZBJBQKJ2.mjs.map
330
- //# sourceMappingURL=chunk-ZBJBQKJ2.mjs.map
313
+ export { collectFreeVars, compile, createStore, validate };
314
+ //# sourceMappingURL=chunk-IHUFOV7L.mjs.map
315
+ //# sourceMappingURL=chunk-IHUFOV7L.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/scene/reducer.ts","../src/core/scene/store.ts","../src/core/scene/expressions/parser.ts"],"names":[],"mappings":"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","file":"chunk-IHUFOV7L.mjs","sourcesContent":["// src/core/scene/reducer.ts\nimport type { Draft } from 'immer';\nimport type { Action, State, SceneObject } from './types';\nimport { getKind } from './registry';\n\nfunction collectDependents(state: Draft<State> | State, rootId: string): Set<string> {\n const dependents = new Set<string>([rootId]);\n let grew = true;\n while (grew) {\n grew = false;\n for (const obj of Object.values(state.objects) as SceneObject[]) {\n if (dependents.has(obj.id)) continue;\n let kindDef;\n try { kindDef = getKind(obj.kind); } catch { continue; }\n const refs = kindDef.dependsOn(obj.attrs as never);\n if (refs.some(r => dependents.has(r))) {\n dependents.add(obj.id);\n grew = true;\n }\n }\n }\n return dependents;\n}\n\nexport function reduce(draft: Draft<State>, action: Action): void {\n switch (action.type) {\n case 'ADD': {\n const { obj } = action.payload;\n if (draft.objects[obj.id]) throw new Error(`[scene] id \"${obj.id}\" đã tồn tại`);\n const kindDef = getKind(obj.kind);\n kindDef.validate?.(obj.attrs as never);\n draft.objects[obj.id] = obj;\n draft.order.push(obj.id);\n draft.counter += 1;\n return;\n }\n case 'UPDATE': {\n const { id, patch } = action.payload;\n const obj = draft.objects[id];\n if (!obj) return;\n Object.assign(obj, patch);\n return;\n }\n case 'UPDATE_ATTRS': {\n const { id, patch } = action.payload;\n const obj = draft.objects[id];\n if (!obj) return;\n const kindDef = getKind(obj.kind);\n const nextAttrs = { ...(obj.attrs as object), ...patch };\n kindDef.validate?.(nextAttrs as never);\n obj.attrs = nextAttrs;\n return;\n }\n case 'DELETE': {\n const { id } = action.payload;\n if (!draft.objects[id]) return;\n const toDelete = collectDependents(draft, id);\n for (const delId of toDelete) {\n delete draft.objects[delId];\n }\n draft.order = draft.order.filter(x => !toDelete.has(x));\n return;\n }\n case 'RESET': {\n draft.objects = {};\n draft.order = [];\n draft.counter = 0;\n return;\n }\n case 'LOAD': {\n const { state } = action.payload;\n draft.objects = { ...state.objects };\n draft.order = [...state.order];\n draft.counter = state.counter;\n // Cast qua Draft<State['meta']> — immer chấp nhận structurally\n // identical shape, chỉ stricter readonly.\n draft.meta = { ...state.meta } as typeof draft.meta;\n return;\n }\n case 'TRANSACTION': {\n for (const sub of action.payload.actions) {\n reduce(draft, sub);\n }\n return;\n }\n case 'UPDATE_VIEW': {\n // Action payload typed cho graph-2d ViewSettings. Bỏ qua nếu domain\n // khác (view shape không tương thích — 2d dùng bbox, 3d dùng bbox3D).\n if (draft.meta.domain !== 'graph2d') return;\n Object.assign(draft.meta.view, action.payload.patch);\n return;\n }\n }\n}\n","// src/core/scene/store.ts\nimport { produce } from 'immer';\nimport { reduce } from './reducer';\nimport type { Action, State } from './types';\n\nexport type StoreListener = (next: State, prev: State, action: Action) => void;\n\nexport interface Store {\n getState(): State;\n dispatch(action: Action): void;\n subscribe(listener: StoreListener): () => void;\n undo(): void;\n redo(): void;\n canUndo(): boolean;\n canRedo(): boolean;\n transaction(fn: (dispatch: (a: Action) => void) => void): void;\n withoutHistory(fn: () => void): void;\n}\n\nexport type StoreOptions = { historyLimit?: number };\n\nconst HISTORY_DEFAULT = 100;\n\nconst UNDO_ACTION: Action = { type: 'TRANSACTION', payload: { actions: [] } };\nconst REDO_ACTION: Action = { type: 'TRANSACTION', payload: { actions: [] } };\n\nexport function createStore(initial: State, options: StoreOptions = {}): Store {\n const limit = options.historyLimit ?? HISTORY_DEFAULT;\n let state = initial;\n const past: State[] = [];\n const future: State[] = [];\n const listeners = new Set<StoreListener>();\n let dispatching = false;\n let suspendHistory = false;\n let transactionActions: Action[] | null = null;\n\n function notify(prev: State, action: Action): void {\n listeners.forEach(l => l(state, prev, action));\n }\n\n function pushHistory(prev: State): void {\n if (suspendHistory) return;\n past.push(prev);\n if (past.length > limit) past.shift();\n future.length = 0;\n }\n\n function applyAction(action: Action): void {\n const prev = state;\n state = produce(state, draft => { reduce(draft, action); });\n if (state !== prev) {\n pushHistory(prev);\n notify(prev, action);\n }\n }\n\n return {\n getState: () => state,\n\n dispatch(action: Action) {\n if (dispatching) throw new Error('[scene] không được dispatch trong subscriber');\n if (transactionActions) {\n transactionActions.push(action);\n return;\n }\n dispatching = true;\n try { applyAction(action); } finally { dispatching = false; }\n },\n\n subscribe(listener) {\n listeners.add(listener);\n return () => { listeners.delete(listener); };\n },\n\n undo() {\n const prev = past.pop();\n if (!prev) return;\n future.push(state);\n const old = state;\n state = prev;\n notify(old, UNDO_ACTION);\n },\n\n redo() {\n const next = future.pop();\n if (!next) return;\n past.push(state);\n if (past.length > limit) past.shift();\n const old = state;\n state = next;\n notify(old, REDO_ACTION);\n },\n\n canUndo: () => past.length > 0,\n canRedo: () => future.length > 0,\n\n transaction(fn) {\n if (transactionActions) throw new Error('[scene] transaction lồng nhau không hỗ trợ');\n transactionActions = [];\n try { fn((a) => { transactionActions!.push(a); }); }\n finally {\n const actions = transactionActions;\n transactionActions = null;\n if (actions.length > 0) {\n applyAction({ type: 'TRANSACTION', payload: { actions } });\n }\n }\n },\n\n withoutHistory(fn) {\n const prevSuspend = suspendHistory;\n suspendHistory = true;\n try { fn(); } finally { suspendHistory = prevSuspend; }\n },\n };\n}\n","// src/core/scene/expressions/parser.ts\n// Pure expression parser cho function2d kind. Không import JSXGraph/React.\n\nexport const ALLOWED_CONSTANTS = ['pi', 'e'] as const;\nexport const ALLOWED_FUNCTIONS = [\n 'sin', 'cos', 'tan',\n 'asin', 'acos', 'atan', 'atan2',\n 'sinh', 'cosh', 'tanh',\n 'exp', 'log', 'log10', 'ln',\n 'sqrt', 'cbrt', 'abs',\n 'floor', 'ceil', 'round',\n 'min', 'max', 'pow',\n] as const;\n\nconst ID_RE = /[A-Za-z_][A-Za-z0-9_]*/g;\nconst UNSAFE_RE = /[=;{}]|\\beval\\b|\\bnew\\b|\\breturn\\b|\\bthis\\b|\\bwindow\\b|\\bdocument\\b|\\bglobal\\b|\\bprocess\\b/;\n\nconst NUMBER_RE = /^[+-]?(\\d+\\.?\\d*|\\.\\d+)([eE][+-]?\\d+)?$/;\n\nexport type ValidateResult = { ok: true } | { ok: false; error: string };\n\n// Detect identifiers used as function calls (followed by '(')\nconst FUNC_CALL_RE = /([A-Za-z_][A-Za-z0-9_]*)\\s*\\(/g;\n\n/** Kiểm tra expression có hợp lệ không. */\nexport function validate(expression: string): ValidateResult {\n const trimmed = expression.trim();\n if (!trimmed) return { ok: false, error: 'Biểu thức rỗng' };\n if (UNSAFE_RE.test(trimmed)) return { ok: false, error: 'Biểu thức chứa toán tử hoặc identifier không cho phép' };\n\n // Replace ^ với ** (JS không có ^)\n const jsExpr = trimmed.replace(/\\^/g, '**');\n\n // Check function call identifiers — must be in ALLOWED_FUNCTIONS\n let fm: RegExpExecArray | null;\n FUNC_CALL_RE.lastIndex = 0;\n while ((fm = FUNC_CALL_RE.exec(jsExpr)) !== null) {\n const fnName = fm[1];\n if (!(ALLOWED_FUNCTIONS as readonly string[]).includes(fnName)) {\n return { ok: false, error: `Hàm không hợp lệ: ${fnName}` };\n }\n }\n\n // Check identifiers\n const ids = new Set<string>();\n let m: RegExpExecArray | null;\n ID_RE.lastIndex = 0;\n while ((m = ID_RE.exec(jsExpr)) !== null) ids.add(m[0]);\n\n for (const id of ids) {\n if (id === 'x') continue;\n if ((ALLOWED_CONSTANTS as readonly string[]).includes(id)) continue;\n if ((ALLOWED_FUNCTIONS as readonly string[]).includes(id)) continue;\n // Remaining identifiers treat as parameter — OK at validate time.\n if (!/^[A-Za-z_][A-Za-z0-9_]*$/.test(id)) {\n return { ok: false, error: `Identifier không hợp lệ: ${id}` };\n }\n }\n\n // Try syntactic compile (with dummy params) to catch syntax errors.\n try {\n buildFunctionBody(jsExpr, Array.from(ids).filter(\n (id) => id !== 'x' && !(ALLOWED_CONSTANTS as readonly string[]).includes(id) && !(ALLOWED_FUNCTIONS as readonly string[]).includes(id),\n ));\n } catch (err) {\n return { ok: false, error: `Cú pháp lỗi: ${(err as Error).message}` };\n }\n\n return { ok: true };\n}\n\n/**\n * Compile expression thành function (x: number) => number.\n * - `params` map từ identifier → value để inline vào closure.\n * - Trả string error nếu invalid.\n */\nexport function compile(\n expression: string,\n params: Record<string, number>,\n): ((x: number) => number) | string {\n const v = validate(expression);\n if (!v.ok) return v.error;\n const jsExpr = expression.trim().replace(/\\^/g, '**');\n\n const ids = new Set<string>();\n let m: RegExpExecArray | null;\n ID_RE.lastIndex = 0;\n while ((m = ID_RE.exec(jsExpr)) !== null) ids.add(m[0]);\n\n const paramNames: string[] = [];\n for (const id of ids) {\n if (id === 'x') continue;\n if ((ALLOWED_CONSTANTS as readonly string[]).includes(id)) continue;\n if ((ALLOWED_FUNCTIONS as readonly string[]).includes(id)) continue;\n paramNames.push(id);\n }\n\n try {\n const body = buildFunctionBody(jsExpr, paramNames);\n \n const fn = new Function('x', ...paramNames, body) as (\n x: number,\n ...args: number[]\n ) => number;\n const args = paramNames.map((name) => params[name] ?? NaN);\n return (x: number) => fn(x, ...args);\n } catch (err) {\n return `Compile error: ${(err as Error).message}`;\n }\n}\n\nfunction buildFunctionBody(jsExpr: string, _paramNames: string[]): string {\n // Inline Math constants and functions.\n // sin → Math.sin, pi → Math.PI, e → Math.E, ln → Math.log.\n let body = jsExpr;\n body = body.replace(/\\bln\\b/g, 'Math.log');\n body = body.replace(/\\blog\\b/g, 'Math.log10');\n body = body.replace(/\\bpi\\b/g, '(Math.PI)');\n body = body.replace(/\\be\\b(?!\\w)/g, '(Math.E)');\n for (const fn of ALLOWED_FUNCTIONS) {\n if (fn === 'log' || fn === 'log10') continue; // already handled\n body = body.replace(new RegExp(`\\\\b${fn}\\\\b`, 'g'), `Math.${fn}`);\n }\n return `\"use strict\"; return (${body});`;\n}\n\n/** Liệt kê free identifiers (≠ x, ≠ allowed const/func). */\nexport function collectFreeVars(expression: string): string[] {\n const v = validate(expression);\n if (!v.ok) return [];\n const ids = new Set<string>();\n let m: RegExpExecArray | null;\n ID_RE.lastIndex = 0;\n while ((m = ID_RE.exec(expression)) !== null) ids.add(m[0]);\n const out: string[] = [];\n for (const id of ids) {\n if (id === 'x') continue;\n if ((ALLOWED_CONSTANTS as readonly string[]).includes(id)) continue;\n if ((ALLOWED_FUNCTIONS as readonly string[]).includes(id)) continue;\n if (NUMBER_RE.test(id)) continue;\n out.push(id);\n }\n return out.sort();\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { DEFAULT_THEME_2D } from './chunk-BKSXPNPQ.mjs';
2
+ import { DEFAULT_THEME_2D } from './chunk-AYSFWUPK.mjs';
3
3
 
4
4
  // src/stamps/graph-2d/editor/theme.ts
5
5
  var GRAPH_THEME_LIGHT = {
@@ -19,5 +19,5 @@ function paletteFor(isDark) {
19
19
  }
20
20
 
21
21
  export { paletteFor };
22
- //# sourceMappingURL=chunk-AZIARTGX.mjs.map
23
- //# sourceMappingURL=chunk-AZIARTGX.mjs.map
22
+ //# sourceMappingURL=chunk-M42TGYT6.mjs.map
23
+ //# sourceMappingURL=chunk-M42TGYT6.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stamps/graph-2d/editor/theme.ts"],"names":[],"mappings":";;;AAIO,IAAM,iBAAA,GAA6B;AAAA,EACxC,GAAG;AACL,CAAA;AAEO,IAAM,gBAAA,GAA4B;AAAA,EACvC,GAAG,gBAAA;AAAA,EACH,MAAA,EAAQ,SAAA;AAAA,EACR,IAAA,EAAM,SAAA;AAAA,EACN,KAAA,EAAO,SAAA;AAAA,EACP,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,SAAA;AAAA,EACN,SAAA,EAAW;AACb,CAAA;AAEO,SAAS,WAAW,MAAA,EAA0B;AACnD,EAAA,OAAO,SAAS,gBAAA,GAAmB,iBAAA;AACrC","file":"chunk-AZIARTGX.mjs","sourcesContent":["// src/stamps/graph-2d/editor/theme.ts\nimport type { Theme2D } from '../../../core/scene/render/types2d';\nimport { DEFAULT_THEME_2D } from '../../../core/scene/render/types2d';\n\nexport const GRAPH_THEME_LIGHT: Theme2D = {\n ...DEFAULT_THEME_2D,\n};\n\nexport const GRAPH_THEME_DARK: Theme2D = {\n ...DEFAULT_THEME_2D,\n stroke: '#f1f5f9',\n fill: '#3b82f6',\n label: '#f1f5f9',\n axis: '#475569',\n grid: '#334155',\n pointFill: '#93c5fd',\n};\n\nexport function paletteFor(isDark: boolean): Theme2D {\n return isDark ? GRAPH_THEME_DARK : GRAPH_THEME_LIGHT;\n}\n\nexport const FUNCTION_COLORS = [\n '#2563eb', '#dc2626', '#16a34a', '#9333ea',\n '#ea580c', '#0891b2', '#db2777', '#65a30d',\n] as const;\n\nexport const FUNCTION_NAMES = ['f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'] as const;\nexport const PARAMETER_NAMES = ['a', 'b', 'c', 'd', 'k', 't', 'm', 'n'] as const;\n"]}
1
+ {"version":3,"sources":["../src/stamps/graph-2d/editor/theme.ts"],"names":[],"mappings":";;;AAIO,IAAM,iBAAA,GAA6B;AAAA,EACxC,GAAG;AACL,CAAA;AAEO,IAAM,gBAAA,GAA4B;AAAA,EACvC,GAAG,gBAAA;AAAA,EACH,MAAA,EAAQ,SAAA;AAAA,EACR,IAAA,EAAM,SAAA;AAAA,EACN,KAAA,EAAO,SAAA;AAAA,EACP,IAAA,EAAM,SAAA;AAAA,EACN,IAAA,EAAM,SAAA;AAAA,EACN,SAAA,EAAW;AACb,CAAA;AAEO,SAAS,WAAW,MAAA,EAA0B;AACnD,EAAA,OAAO,SAAS,gBAAA,GAAmB,iBAAA;AACrC","file":"chunk-M42TGYT6.mjs","sourcesContent":["// src/stamps/graph-2d/editor/theme.ts\nimport type { Theme2D } from '../../../core/scene/render/types2d';\nimport { DEFAULT_THEME_2D } from '../../../core/scene/render/types2d';\n\nexport const GRAPH_THEME_LIGHT: Theme2D = {\n ...DEFAULT_THEME_2D,\n};\n\nexport const GRAPH_THEME_DARK: Theme2D = {\n ...DEFAULT_THEME_2D,\n stroke: '#f1f5f9',\n fill: '#3b82f6',\n label: '#f1f5f9',\n axis: '#475569',\n grid: '#334155',\n pointFill: '#93c5fd',\n};\n\nexport function paletteFor(isDark: boolean): Theme2D {\n return isDark ? GRAPH_THEME_DARK : GRAPH_THEME_LIGHT;\n}\n\nexport const FUNCTION_COLORS = [\n '#2563eb', '#dc2626', '#16a34a', '#9333ea',\n '#ea580c', '#0891b2', '#db2777', '#65a30d',\n] as const;\n\nexport const FUNCTION_NAMES = ['f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'] as const;\nexport const PARAMETER_NAMES = ['a', 'b', 'c', 'd', 'k', 't', 'm', 'n'] as const;\n"]}
@@ -1,11 +1,11 @@
1
1
  "use client";
2
- import { isGeometry3DCustomData, renderGeometry3DSvgFromState } from './chunk-BEZSQKPY.mjs';
2
+ import { isGeometry3DCustomData, renderGeometry3DSvgFromState } from './chunk-ONBCUWVI.mjs';
3
3
  import { svgToStampFile } from './chunk-5UTGXHLJ.mjs';
4
4
  import { lazy } from 'react';
5
5
  import { jsxs, jsx } from 'react/jsx-runtime';
6
6
 
7
7
  var Geometry3DStampHost = lazy(
8
- () => import('./host-ZIQ77W33.mjs').then((m) => ({ default: m.Geometry3DStampHost }))
8
+ () => import('./host-A64ITWVX.mjs').then((m) => ({ default: m.Geometry3DStampHost }))
9
9
  );
10
10
  var Geometry3DIcon = /* @__PURE__ */ jsxs(
11
11
  "svg",
@@ -57,5 +57,5 @@ var geometry3dStamp = {
57
57
  };
58
58
 
59
59
  export { geometry3dStamp };
60
- //# sourceMappingURL=chunk-45CGKJ7S.mjs.map
61
- //# sourceMappingURL=chunk-45CGKJ7S.mjs.map
60
+ //# sourceMappingURL=chunk-NDEZJKNY.mjs.map
61
+ //# sourceMappingURL=chunk-NDEZJKNY.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/stamps/geometry-3d/index.tsx"],"names":[],"mappings":";;;;;AAgBA,IAAM,mBAAA,GAAsB,IAAA;AAAA,EAAK,MAC/B,OAAO,qBAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,mBAAA,EAAoB,CAAE;AACnE,CAAA;AAEA,IAAM,cAAA,mBACJ,IAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,KAAA,EAAM,IAAA;AAAA,IACN,MAAA,EAAO,IAAA;AAAA,IACP,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,MAAA;AAAA,IACL,MAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAY,KAAA;AAAA,IACZ,aAAA,EAAc,OAAA;AAAA,IACd,cAAA,EAAe,OAAA;AAAA,IACf,aAAA,EAAY,MAAA;AAAA,IAGZ,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,GAAE,2BAAA,EAA4B,CAAA;AAAA,sBAEpC,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,0BAAA,EAA2B,CAAA;AAAA,sBAEnC,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6BAAA,EAA8B;AAAA;AAAA;AACxC,CAAA;AAGK,IAAM,eAAA,GAAmD;AAAA,EAC9D,IAAA,EAAM,YAAA;AAAA,EACN,YAAA,EAAc,IAAA;AAAA,EACd,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,YAAA,EAAc,gBAAA;AAAA,EACd,WAAA,EAAa,cAAA;AAAA,EACb,aAAA,EAAe,0BAAA;AAAA,EACf,iBAAA,EAAmB,sBAAA;AAAA,EACnB,MAAM,wBAAwB,IAAA,EAAgC;AAC5D,IAAA,IAAI,CAAC,sBAAA,CAAuB,IAAI,CAAA,EAAG;AACjC,MAAA,MAAM,IAAI,MAAM,mFAA2E,CAAA;AAAA,IAC7F;AACA,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,4BAAA,CAA6B,KAAK,SAAS,CAAA;AACvE,IAAA,OAAO,SAAA;AAAA,EACT,CAAA;AAAA,EACA,yBAAA,EAA2B,OAAO,OAAA,KAA+C;AAC/E,IAAA,MAAM,OAAO,OAAA,CAAQ,UAAA;AACrB,IAAA,MAAM,SAAU,OAAA,CAAuC,MAAA;AACvD,IAAA,IAAI,CAAC,QAAQ,CAAC,MAAA,IAAU,CAAC,sBAAA,CAAuB,IAAI,GAAG,OAAO,IAAA;AAC9D,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,4BAAA,CAA6B,KAAK,SAAS,CAAA;AACvE,MAAA,OAAO,cAAA,CAAe,WAAW,MAAM,CAAA;AAAA,IACzC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF,CAAA;AAAA,EACA,IAAA,EAAM;AACR","file":"chunk-45CGKJ7S.mjs","sourcesContent":["'use client';\n\nimport { lazy, type ReactNode } from 'react';\nimport {\n isGeometry3DCustomData,\n type Geometry3DCustomData,\n} from './serialize';\nimport { renderGeometry3DSvgFromState } from './render';\nimport type {\n RestoredStampFile,\n StampType,\n} from '../shared/types';\nimport { svgToStampFile } from '../shared/svgToStampFile';\n\nexport type { Geometry3DCustomData };\n\nconst Geometry3DStampHost = lazy(() =>\n import('./host').then((m) => ({ default: m.Geometry3DStampHost })),\n);\n\nconst Geometry3DIcon: ReactNode = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n {/* Mặt trước */}\n <path d=\"M4 9 L4 20 L14 20 L14 9 Z\" />\n {/* Mặt trên */}\n <path d=\"M4 9 L10 4 L20 4 L14 9 Z\" />\n {/* Mặt phải */}\n <path d=\"M14 9 L20 4 L20 15 L14 20 Z\" />\n </svg>\n);\n\nexport const geometry3dStamp: StampType<Geometry3DCustomData> = {\n kind: 'geometry3d',\n experimental: true,\n shortcutKey: 'd',\n toolbarLabel: 'D',\n toolbarTitle: 'Hình 3D (D)',\n toolbarIcon: Geometry3DIcon,\n toolbarTestId: 'stamp-toolbar-geometry3d',\n matchesCustomData: isGeometry3DCustomData,\n async renderSvgFromCustomData(data: unknown): Promise<string> {\n if (!isGeometry3DCustomData(data)) {\n throw new Error('geometry3dStamp.renderSvgFromCustomData: customData không phải geometry3d');\n }\n const { svgString } = await renderGeometry3DSvgFromState(data.jsonState);\n return svgString;\n },\n restoreFileFromCustomData: async (element): Promise<RestoredStampFile | null> => {\n const data = element.customData as Geometry3DCustomData | undefined;\n const fileId = (element as { fileId?: string | null }).fileId;\n if (!data || !fileId || !isGeometry3DCustomData(data)) return null;\n try {\n const { svgString } = await renderGeometry3DSvgFromState(data.jsonState);\n return svgToStampFile(svgString, fileId);\n } catch {\n return null;\n }\n },\n Host: Geometry3DStampHost,\n};\n"]}
1
+ {"version":3,"sources":["../src/stamps/geometry-3d/index.tsx"],"names":[],"mappings":";;;;;AAgBA,IAAM,mBAAA,GAAsB,IAAA;AAAA,EAAK,MAC/B,OAAO,qBAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,mBAAA,EAAoB,CAAE;AACnE,CAAA;AAEA,IAAM,cAAA,mBACJ,IAAA;AAAA,EAAC,KAAA;AAAA,EAAA;AAAA,IACC,KAAA,EAAM,IAAA;AAAA,IACN,MAAA,EAAO,IAAA;AAAA,IACP,OAAA,EAAQ,WAAA;AAAA,IACR,IAAA,EAAK,MAAA;AAAA,IACL,MAAA,EAAO,cAAA;AAAA,IACP,WAAA,EAAY,KAAA;AAAA,IACZ,aAAA,EAAc,OAAA;AAAA,IACd,cAAA,EAAe,OAAA;AAAA,IACf,aAAA,EAAY,MAAA;AAAA,IAGZ,QAAA,EAAA;AAAA,sBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,GAAE,2BAAA,EAA4B,CAAA;AAAA,sBAEpC,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,0BAAA,EAA2B,CAAA;AAAA,sBAEnC,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,6BAAA,EAA8B;AAAA;AAAA;AACxC,CAAA;AAGK,IAAM,eAAA,GAAmD;AAAA,EAC9D,IAAA,EAAM,YAAA;AAAA,EACN,YAAA,EAAc,IAAA;AAAA,EACd,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,YAAA,EAAc,gBAAA;AAAA,EACd,WAAA,EAAa,cAAA;AAAA,EACb,aAAA,EAAe,0BAAA;AAAA,EACf,iBAAA,EAAmB,sBAAA;AAAA,EACnB,MAAM,wBAAwB,IAAA,EAAgC;AAC5D,IAAA,IAAI,CAAC,sBAAA,CAAuB,IAAI,CAAA,EAAG;AACjC,MAAA,MAAM,IAAI,MAAM,mFAA2E,CAAA;AAAA,IAC7F;AACA,IAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,4BAAA,CAA6B,KAAK,SAAS,CAAA;AACvE,IAAA,OAAO,SAAA;AAAA,EACT,CAAA;AAAA,EACA,yBAAA,EAA2B,OAAO,OAAA,KAA+C;AAC/E,IAAA,MAAM,OAAO,OAAA,CAAQ,UAAA;AACrB,IAAA,MAAM,SAAU,OAAA,CAAuC,MAAA;AACvD,IAAA,IAAI,CAAC,QAAQ,CAAC,MAAA,IAAU,CAAC,sBAAA,CAAuB,IAAI,GAAG,OAAO,IAAA;AAC9D,IAAA,IAAI;AACF,MAAA,MAAM,EAAE,SAAA,EAAU,GAAI,MAAM,4BAAA,CAA6B,KAAK,SAAS,CAAA;AACvE,MAAA,OAAO,cAAA,CAAe,WAAW,MAAM,CAAA;AAAA,IACzC,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF,CAAA;AAAA,EACA,IAAA,EAAM;AACR","file":"chunk-NDEZJKNY.mjs","sourcesContent":["'use client';\n\nimport { lazy, type ReactNode } from 'react';\nimport {\n isGeometry3DCustomData,\n type Geometry3DCustomData,\n} from './serialize';\nimport { renderGeometry3DSvgFromState } from './render';\nimport type {\n RestoredStampFile,\n StampType,\n} from '../shared/types';\nimport { svgToStampFile } from '../shared/svgToStampFile';\n\nexport type { Geometry3DCustomData };\n\nconst Geometry3DStampHost = lazy(() =>\n import('./host').then((m) => ({ default: m.Geometry3DStampHost })),\n);\n\nconst Geometry3DIcon: ReactNode = (\n <svg\n width=\"20\"\n height=\"20\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1.6\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n >\n {/* Mặt trước */}\n <path d=\"M4 9 L4 20 L14 20 L14 9 Z\" />\n {/* Mặt trên */}\n <path d=\"M4 9 L10 4 L20 4 L14 9 Z\" />\n {/* Mặt phải */}\n <path d=\"M14 9 L20 4 L20 15 L14 20 Z\" />\n </svg>\n);\n\nexport const geometry3dStamp: StampType<Geometry3DCustomData> = {\n kind: 'geometry3d',\n experimental: true,\n shortcutKey: 'd',\n toolbarLabel: 'D',\n toolbarTitle: 'Hình 3D (D)',\n toolbarIcon: Geometry3DIcon,\n toolbarTestId: 'stamp-toolbar-geometry3d',\n matchesCustomData: isGeometry3DCustomData,\n async renderSvgFromCustomData(data: unknown): Promise<string> {\n if (!isGeometry3DCustomData(data)) {\n throw new Error('geometry3dStamp.renderSvgFromCustomData: customData không phải geometry3d');\n }\n const { svgString } = await renderGeometry3DSvgFromState(data.jsonState);\n return svgString;\n },\n restoreFileFromCustomData: async (element): Promise<RestoredStampFile | null> => {\n const data = element.customData as Geometry3DCustomData | undefined;\n const fileId = (element as { fileId?: string | null }).fileId;\n if (!data || !fileId || !isGeometry3DCustomData(data)) return null;\n try {\n const { svgString } = await renderGeometry3DSvgFromState(data.jsonState);\n return svgToStampFile(svgString, fileId);\n } catch {\n return null;\n }\n },\n Host: Geometry3DStampHost,\n};\n"]}
@@ -1,9 +1,10 @@
1
1
  "use client";
2
2
  import { paletteFor } from './chunk-R5FL6S7L.mjs';
3
3
  import { renderJsxgOffscreen } from './chunk-ICR4CVOE.mjs';
4
- import { serializeScene, deserializeScene } from './chunk-WM2VDYQA.mjs';
5
- import { getKind, createStore } from './chunk-ZBJBQKJ2.mjs';
4
+ import { serializeScene, deserializeScene } from './chunk-REIJZDVZ.mjs';
5
+ import { createStore } from './chunk-IHUFOV7L.mjs';
6
6
  import { DEFAULT_VIEW_3D } from './chunk-73Q7ADVL.mjs';
7
+ import { getKind } from './chunk-B4NJJZFR.mjs';
7
8
 
8
9
  // src/stamps/geometry-3d/serialize.ts
9
10
  function isGeometry3DCustomData(data) {
@@ -385,5 +386,5 @@ async function renderGeometry3DSvgFromState(jsonState) {
385
386
  }
386
387
 
387
388
  export { DEFAULT_VIEW3D, GROUND_PLANE_ATTRS, GROUND_PLANE_RANGE, JxgRenderer3D, VIEW3D_ATTRS, deserializeBoard3D, isGeometry3DCustomData, paletteFor2 as paletteFor, renderGeometry3DSvgFromState, serializeBoard3D };
388
- //# sourceMappingURL=chunk-BEZSQKPY.mjs.map
389
- //# sourceMappingURL=chunk-BEZSQKPY.mjs.map
389
+ //# sourceMappingURL=chunk-ONBCUWVI.mjs.map
390
+ //# sourceMappingURL=chunk-ONBCUWVI.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/stamps/geometry-3d/serialize.ts","../src/core/scene/render/types.ts","../src/core/scene/render/JxgRenderer3D.ts","../src/stamps/geometry-3d/editor/theme.ts","../src/stamps/geometry-3d/render.ts"],"names":["paletteFor"],"mappings":"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","file":"chunk-ONBCUWVI.mjs","sourcesContent":["// src/stamps/geometry-3d/serialize.ts\n//\n// Sau Tier D PR 3: customData.jsonState chỉ chứa `JSON.stringify(state)`.\n// View info (bbox3D/azimuth/elevation) nằm trong `state.meta.view` (View3D shape).\n//\n// Type guard `isGeometry3DCustomData` giữ ở đây để index.tsx + host import từ\n// 1 chỗ.\n\nimport { serializeScene, deserializeScene } from '../shared/serializeScene';\nimport type { State, View3D } from '../../core/scene';\nimport type { BaseStampCustomData } from '../shared/types';\n\nexport interface Geometry3DCustomData extends BaseStampCustomData {\n kind: 'geometry3d';\n version: 2;\n jsonState: string;\n}\n\nexport function isGeometry3DCustomData(data: unknown): data is Geometry3DCustomData {\n if (!data || typeof data !== 'object') return false;\n const d = data as Partial<Geometry3DCustomData>;\n return (\n d.kind === 'geometry3d' &&\n d.version === 2 &&\n typeof d.jsonState === 'string'\n );\n}\n\nexport function serializeBoard3D(state: State, view: View3D): string {\n const withView: State = {\n ...state,\n meta: { domain: '3d', version: state.meta.version, view },\n };\n return serializeScene(withView);\n}\n\nexport function deserializeBoard3D(raw: string): State {\n return deserializeScene('3d', raw);\n}\n","// src/core/scene/render/types.ts\nimport type { RenderCtx } from '../types';\n\nexport type Theme3D = {\n point: { size: number; color: string };\n line: { strokeWidth: number; color: string };\n plane: { fillOpacity: number; color: string };\n};\n\nexport const DEFAULT_THEME_3D: Theme3D = {\n point: { size: 4, color: '#1e40af' },\n line: { strokeWidth: 2, color: '#0f172a' },\n plane: { fillOpacity: 0.15, color: '#60a5fa' },\n};\n\nexport type RenderCtx3D = RenderCtx & {\n theme: Theme3D;\n};\n","// src/core/scene/render/JxgRenderer3D.ts\nimport type { Store } from '../store';\nimport type { State, SceneObject, RenderCtx } from '../types';\nimport { getKind } from '../registry';\nimport { DEFAULT_THEME_3D, type Theme3D } from './types';\n\nexport type JxgRenderer3DOptions = { theme?: Theme3D };\n\nexport class JxgRenderer3D {\n private view: unknown;\n private store: Store;\n private theme: Theme3D;\n private elements = new Map<string, unknown>();\n private unsubscribe: () => void;\n private disposed = false;\n\n constructor(store: Store, view: unknown, options: JxgRenderer3DOptions = {}) {\n this.store = store;\n this.view = view;\n this.theme = options.theme ?? DEFAULT_THEME_3D;\n // Subscribe first, then render current state.\n this.unsubscribe = store.subscribe((next, prev) => this.applyDiff(prev, next));\n // Render initial state (e.g. if LOAD ran before subscribe).\n this.applyDiff(undefined, store.getState());\n }\n\n private ctx(): RenderCtx {\n return {\n jxg: this.view,\n resolveRef: (id: string) => {\n const el = this.elements.get(id);\n if (el === undefined) {\n throw new Error(`[scene] resolveRef: chưa render id=\"${id}\"`);\n }\n return el;\n },\n defaults: {},\n };\n }\n\n private create(obj: SceneObject): void {\n try {\n const def = getKind(obj.kind);\n const el = def.render(obj, this.ctx());\n this.elements.set(obj.id, el);\n } catch (err) {\n console.warn(`[scene/render] không render được ${obj.kind} id=\"${obj.id}\":`, err);\n }\n }\n\n private remove(id: string): void {\n // Selection halo phải bị xoá TRƯỚC element gốc (halo tham chiếu parent).\n this.removeHalo(id);\n this.selectedIds.delete(id);\n const el = this.elements.get(id);\n if (el === undefined) return;\n try {\n this.removeFromView(el);\n } catch (err) {\n console.warn(`[scene/render] không remove được id=\"${id}\":`, err);\n }\n this.elements.delete(id);\n }\n\n private removeFromView(el: unknown): void {\n const view = this.view as { removeObject?: (e: unknown) => void };\n if (el && typeof el === 'object') {\n const asObj = el as Record<string, unknown>;\n // Composite shape: { faces: [] } for polyhedron/cylinder/cone.\n if (Array.isArray(asObj['faces'])) {\n for (const face of asObj['faces'] as unknown[]) {\n view.removeObject?.(face);\n }\n // Also remove hidden vertex points if present (_verts).\n if (Array.isArray(asObj['_verts'])) {\n for (const v of asObj['_verts'] as unknown[]) {\n view.removeObject?.(v);\n }\n }\n return;\n }\n }\n view.removeObject?.(el);\n }\n\n private applyDiff(prev: State | undefined, next: State): void {\n if (this.disposed) return;\n const prevObjs = prev?.objects ?? {};\n const nextObjs = next.objects;\n\n // Remove ids that disappeared (iterate in order of prev to respect dependencies).\n for (const id of Object.keys(prevObjs)) {\n if (!(id in nextObjs)) {\n this.remove(id);\n }\n }\n\n // Add or update in next.order (preserves dependency order).\n for (const id of next.order) {\n const cur = nextObjs[id] as SceneObject | undefined;\n if (!cur) continue;\n const old = prevObjs[id] as SceneObject | undefined;\n if (!old) {\n // New object.\n this.create(cur);\n continue;\n }\n if (Object.is(old, cur)) {\n // Unchanged (same Immer reference).\n continue;\n }\n // Changed: try update hook, otherwise remove + recreate.\n let def;\n try { def = getKind(cur.kind); } catch { continue; }\n const existing = this.elements.get(id);\n if (def.update && existing !== undefined) {\n try {\n def.update(cur, old, this.ctx(), existing);\n continue;\n } catch (err) {\n console.warn(`[scene/render] update fail, recreate id=\"${id}\":`, err);\n }\n }\n this.remove(id);\n this.create(cur);\n }\n }\n\n dispose(): void {\n if (this.disposed) return;\n this.unsubscribe();\n this.disposed = true;\n for (const id of Array.from(this.elements.keys())) {\n this.remove(id);\n }\n }\n\n listElements(): Map<string, unknown> {\n return this.elements;\n }\n\n // Selection halo overlay (3D): multi-select, halo phía sau element gốc cho\n // các kind đơn giản (point3d, segment/line/ray/vector). Các composite shape\n // (polyhedron/cone/cylinder/plane) chưa hỗ trợ halo overlay — bỏ qua.\n private selectedIds: Set<string> = new Set();\n private haloMap: Map<string, unknown[]> = new Map();\n\n highlight(ids: string | string[] | null): void {\n if (this.disposed) return;\n const newIds = new Set<string>(\n ids == null ? [] : Array.isArray(ids) ? ids : [ids],\n );\n for (const id of this.selectedIds) {\n if (!newIds.has(id)) this.removeHalo(id);\n }\n for (const id of newIds) {\n if (!this.selectedIds.has(id) && this.elements.has(id)) this.addHalo(id);\n }\n this.selectedIds = newIds;\n try {\n (this.view as { update?: () => void }).update?.();\n } catch { /* ignore */ }\n }\n\n private removeHalo(id: string): void {\n const halos = this.haloMap.get(id);\n if (!halos) return;\n const view = this.view as { removeObject?: (e: unknown) => void };\n for (const h of halos) {\n try { view.removeObject?.(h); } catch { /* ignore */ }\n }\n this.haloMap.delete(id);\n }\n\n private addHalo(id: string): void {\n const el = this.elements.get(id) as\n | {\n elType?: string;\n getAttribute?: (k: string) => unknown;\n point1?: unknown;\n point2?: unknown;\n element2D?: { X?: () => number; Y?: () => number };\n }\n | undefined;\n if (!el) return;\n const view = this.view as {\n create?: (kind: string, parents: unknown[], attrs?: unknown) => unknown;\n };\n if (!view.create) return;\n\n const SEL_STROKE = '#475569';\n const SEL_FILL = '#cbd5e1';\n const haloBase = {\n strokeColor: SEL_STROKE,\n strokeOpacity: 0.55,\n fillColor: SEL_FILL,\n fillOpacity: 0.3,\n fixed: true,\n withLabel: false,\n name: '',\n highlight: false,\n needsRegularUpdate: true,\n };\n const halos: unknown[] = [];\n try {\n switch (el.elType) {\n case 'point3d': {\n // 3D point: tạo point3d ở cùng coords với size to + gray. Lấy coords\n // qua element2D.X/Y (JSXGraph 3D nội bộ chiếu xuống 2D plane), nhưng\n // an toàn nhất là reference element gốc và đọc Z() / coords() runtime.\n const elAny = el as unknown as {\n X?: () => number; Y?: () => number; Z?: () => number;\n getAttribute?: (k: string) => unknown;\n };\n const baseSize = (elAny.getAttribute?.('size') as number | undefined) ?? 4;\n if (typeof elAny.X === 'function' && typeof elAny.Y === 'function' && typeof elAny.Z === 'function') {\n const halo = view.create('point3d', [\n () => elAny.X?.() ?? 0,\n () => elAny.Y?.() ?? 0,\n () => elAny.Z?.() ?? 0,\n ], {\n ...haloBase,\n size: baseSize + 6,\n face: 'o',\n strokeWidth: 2,\n strokeOpacity: 0.75,\n fillOpacity: 0.25,\n });\n halos.push(halo);\n }\n break;\n }\n case 'line3d': {\n if (el.point1 && el.point2) {\n const halo = view.create('line3d', [el.point1, el.point2], {\n ...haloBase,\n strokeWidth: 9,\n straightFirst: (el.getAttribute?.('straightFirst') as boolean | undefined) ?? false,\n straightLast: (el.getAttribute?.('straightLast') as boolean | undefined) ?? false,\n });\n halos.push(halo);\n }\n break;\n }\n default:\n // Composite/plane/sphere/cone/cylinder/polygon3d/polyhedron3d:\n // halo overlay khó (composite faces, depth ordering) — bỏ qua.\n // Selection visible qua ObjectListPanel row highlight thay vì\n // halo trên canvas.\n break;\n }\n } catch (err) {\n console.warn('[scene/render/3d] halo create fail:', err);\n }\n if (halos.length) this.haloMap.set(id, halos);\n }\n}\n","import {\n paletteFor as palette2D,\n} from '../../geometry-2d/editor/theme';\nimport type { Theme2D } from '../../../core/scene/render/types2d';\n\nexport type Geom3DPalette = Theme2D & {\n view3dBg: string;\n axisX: string;\n axisY: string;\n axisZ: string;\n};\n\nexport function paletteFor(isDark: boolean): Geom3DPalette {\n const base = palette2D(isDark);\n return {\n ...base,\n view3dBg: isDark ? '#1a1a1a' : '#ffffff',\n axisX: '#d63b3b',\n axisY: '#2d8a2d',\n axisZ: '#2d6dd6',\n };\n}\n\nexport const DEFAULT_VIEW3D: {\n azimuth: number;\n elevation: number;\n bbox3D: [number, number, number, number, number, number];\n} = {\n azimuth: 0.7,\n elevation: 0.4,\n bbox3D: [-3, -3, -3, 3, 3, 3],\n};\n\nexport const VIEW3D_ATTRS = (isDark: boolean) => {\n const p = paletteFor(isDark);\n const axisLabel = (color: string) => ({\n strokeColor: color,\n fontSize: 14,\n offset: [10, 0] as [number, number],\n });\n return {\n az: { slider: { visible: false }, point2: { visible: false } },\n el: { slider: { visible: false } },\n projection: 'central' as const,\n // GeoGebra-style: axes pass through origin (0,0,0) instead of bbox border.\n axesPosition: 'center' as const,\n xAxis: {\n strokeColor: p.axisX,\n strokeWidth: 2,\n lastArrow: { type: 2, size: 8 },\n name: 'x',\n withLabel: true,\n label: axisLabel(p.axisX),\n },\n yAxis: {\n strokeColor: p.axisY,\n strokeWidth: 2,\n lastArrow: { type: 2, size: 8 },\n name: 'y',\n withLabel: true,\n label: axisLabel(p.axisY),\n },\n zAxis: {\n strokeColor: p.axisZ,\n strokeWidth: 2,\n lastArrow: { type: 2, size: 8 },\n name: 'z',\n withLabel: true,\n label: axisLabel(p.axisZ),\n },\n // GeoGebra-style: hide ALL bbox wall planes; the XY ground plane is drawn\n // explicitly at z=0 via the helper below (so it coincides with Ox/Oy).\n xPlaneRear: { visible: false, mesh3d: { visible: false } },\n yPlaneRear: { visible: false, mesh3d: { visible: false } },\n zPlaneRear: { visible: false, mesh3d: { visible: false } },\n };\n};\n\nexport const GROUND_PLANE_ATTRS = (isDark: boolean) => ({\n fillColor: isDark ? '#2a2a2a' : '#e6e6e6',\n fillOpacity: isDark ? 0.5 : 0.55,\n strokeColor: isDark ? '#3a3a3a' : '#cfcfcf',\n strokeOpacity: 0.7,\n strokeWidth: 1,\n fixed: true,\n highlight: false,\n withLabel: false,\n layer: 0,\n});\n\n/** XY ground plane extent (square around origin in user units). */\nexport const GROUND_PLANE_RANGE: [number, number] = [-3, 3];\n","\"use client\";\n\nimport { deserializeBoard3D } from './serialize';\nimport { createStore } from '../../core/scene';\nimport { DEFAULT_VIEW_3D, type View3D } from '../../core/scene/types';\nimport { JxgRenderer3D } from '../../core/scene/render/JxgRenderer3D';\nimport { GROUND_PLANE_ATTRS, GROUND_PLANE_RANGE, VIEW3D_ATTRS } from './editor/theme';\nimport { renderJsxgOffscreen } from '../shared/jxgOffscreenRender';\n\nexport interface RenderResult {\n svgString: string;\n width: number;\n height: number;\n}\n\nconst OUTPUT_WIDTH = 1024;\nconst OUTPUT_HEIGHT = 768;\nconst BBOX_2D: [number, number, number, number] = [-6, 6, 6, -6];\n\n \ntype JxgObj = any;\n\nexport async function renderGeometry3DSvgFromState(jsonState: string): Promise<RenderResult> {\n const state = deserializeBoard3D(jsonState);\n const view3DInfo: View3D = state.meta.domain === '3d' ? state.meta.view : DEFAULT_VIEW_3D;\n\n const { svgString } = await renderJsxgOffscreen({\n bbox: BBOX_2D,\n dims: { width: OUTPUT_WIDTH, height: OUTPUT_HEIGHT },\n axis: false,\n grid: false,\n keepAspectRatio: true,\n applyOptions: (JXG) => {\n JXG.Options.text.display = 'internal';\n },\n setup: (board) => {\n const baseAttrs = VIEW3D_ATTRS(false);\n const view: JxgObj = (board as { create: (k: string, p: unknown[], a: unknown) => JxgObj }).create(\n 'view3d',\n [\n [-5, -5],\n [10, 10],\n [\n [view3DInfo.bbox3D[0], view3DInfo.bbox3D[3]],\n [view3DInfo.bbox3D[1], view3DInfo.bbox3D[4]],\n [view3DInfo.bbox3D[2], view3DInfo.bbox3D[5]],\n ],\n ],\n {\n ...baseAttrs,\n az: { ...baseAttrs.az, slider: { ...baseAttrs.az.slider, start: view3DInfo.azimuth } },\n el: { ...baseAttrs.el, slider: { ...baseAttrs.el.slider, start: view3DInfo.elevation } },\n },\n );\n\n try {\n \n const v = view as any;\n v?.az_slide?.setValue?.(view3DInfo.azimuth);\n v?.el_slide?.setValue?.(view3DInfo.elevation);\n v?.board?.update?.();\n } catch {\n /* older JSXGraph may not expose az_slide on view3d */\n }\n\n try {\n (view as { create: (k: string, p: unknown[], a: unknown) => JxgObj }).create(\n 'plane3d',\n [\n [0, 0, 0],\n [1, 0, 0],\n [0, 1, 0],\n GROUND_PLANE_RANGE,\n GROUND_PLANE_RANGE,\n ],\n GROUND_PLANE_ATTRS(false),\n );\n } catch {\n /* swallow */\n }\n\n const store = createStore(state);\n const renderer = new JxgRenderer3D(store, view);\n\n try {\n \n (view as any)?.board?.update?.();\n } catch {\n /* swallow */\n }\n\n return renderer;\n },\n postProcessSvg: (clone) => {\n clone.setAttribute('width', String(OUTPUT_WIDTH));\n clone.setAttribute('height', String(OUTPUT_HEIGHT));\n },\n });\n\n return { svgString, width: OUTPUT_WIDTH, height: OUTPUT_HEIGHT };\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  "use client";
2
- import { registerKind, compile, validate } from './chunk-ZBJBQKJ2.mjs';
2
+ import { compile, validate } from './chunk-IHUFOV7L.mjs';
3
3
  import { createEmptyState } from './chunk-73Q7ADVL.mjs';
4
+ import { registerKind } from './chunk-B4NJJZFR.mjs';
4
5
  import * as React from 'react';
5
6
 
6
7
  // src/core/scene/selectors.ts
@@ -1767,5 +1768,5 @@ function deserializeScene(domain, raw) {
1767
1768
  }
1768
1769
 
1769
1770
  export { deserializeScene, listObjects, nextLabel, serializeScene, useEditorState };
1770
- //# sourceMappingURL=chunk-WM2VDYQA.mjs.map
1771
- //# sourceMappingURL=chunk-WM2VDYQA.mjs.map
1771
+ //# sourceMappingURL=chunk-REIJZDVZ.mjs.map
1772
+ //# sourceMappingURL=chunk-REIJZDVZ.mjs.map