@xom11/whiteboard 0.30.0 → 0.32.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.
- package/dist/ai.d.mts +374 -59
- package/dist/ai.d.ts +374 -59
- package/dist/ai.js +7542 -545
- package/dist/ai.js.map +1 -1
- package/dist/ai.mjs +7243 -569
- package/dist/ai.mjs.map +1 -1
- package/dist/catalog.json +5 -5
- package/dist/{chunk-ZTQBUKLJ.mjs → chunk-4EXRNZRX.mjs} +781 -95
- package/dist/chunk-4EXRNZRX.mjs.map +1 -0
- package/dist/{chunk-PPKHCRRE.mjs → chunk-C76SOFXF.mjs} +3 -3
- package/dist/{chunk-PPKHCRRE.mjs.map → chunk-C76SOFXF.mjs.map} +1 -1
- package/dist/{chunk-IHUFOV7L.mjs → chunk-CH6SFONH.mjs} +15 -3
- package/dist/chunk-CH6SFONH.mjs.map +1 -0
- package/dist/{chunk-XVVLT6B3.mjs → chunk-DBG6DZ2V.mjs} +4 -4
- package/dist/{chunk-XVVLT6B3.mjs.map → chunk-DBG6DZ2V.mjs.map} +1 -1
- package/dist/{chunk-BU5KLO3P.mjs → chunk-DCFZTKFE.mjs} +14 -6
- package/dist/chunk-DCFZTKFE.mjs.map +1 -0
- package/dist/{chunk-SF3U7ZF4.mjs → chunk-DJM5EWTT.mjs} +231 -16
- package/dist/chunk-DJM5EWTT.mjs.map +1 -0
- package/dist/{chunk-V3YJ6JFL.mjs → chunk-F42MZ745.mjs} +3 -3
- package/dist/{chunk-V3YJ6JFL.mjs.map → chunk-F42MZ745.mjs.map} +1 -1
- package/dist/{chunk-5JM35CXV.mjs → chunk-FI2MGX5H.mjs} +4 -4
- package/dist/{chunk-5JM35CXV.mjs.map → chunk-FI2MGX5H.mjs.map} +1 -1
- package/dist/{chunk-SZDAS7LK.mjs → chunk-IE2GGHNF.mjs} +131 -81
- package/dist/chunk-IE2GGHNF.mjs.map +1 -0
- package/dist/{chunk-BNBOIDO5.mjs → chunk-K7VJU7LQ.mjs} +3 -3
- package/dist/{chunk-BNBOIDO5.mjs.map → chunk-K7VJU7LQ.mjs.map} +1 -1
- package/dist/{chunk-H22OZYTW.mjs → chunk-KLGPAMJS.mjs} +55 -43
- package/dist/chunk-KLGPAMJS.mjs.map +1 -0
- package/dist/{chunk-CXHNVYMD.mjs → chunk-KWDBVLST.mjs} +5 -5
- package/dist/{chunk-CXHNVYMD.mjs.map → chunk-KWDBVLST.mjs.map} +1 -1
- package/dist/{chunk-73Q7ADVL.mjs → chunk-MNHOFOM5.mjs} +2 -2
- package/dist/{chunk-73Q7ADVL.mjs.map → chunk-MNHOFOM5.mjs.map} +1 -1
- package/dist/{chunk-QRUAEXLR.mjs → chunk-MOAXHVKI.mjs} +5 -5
- package/dist/{chunk-QRUAEXLR.mjs.map → chunk-MOAXHVKI.mjs.map} +1 -1
- package/dist/{chunk-QGNU34T7.mjs → chunk-QLQ4MJNO.mjs} +10 -4
- package/dist/chunk-QLQ4MJNO.mjs.map +1 -0
- package/dist/chunk-SUXIMLYN.mjs +238 -0
- package/dist/chunk-SUXIMLYN.mjs.map +1 -0
- package/dist/{chunk-OQIQNKPQ.mjs → chunk-XSTGTEGP.mjs} +5 -5
- package/dist/{chunk-OQIQNKPQ.mjs.map → chunk-XSTGTEGP.mjs.map} +1 -1
- package/dist/geometry-2d.d.mts +1 -1
- package/dist/geometry-2d.d.ts +1 -1
- package/dist/geometry-2d.js +1329 -288
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +6 -6
- package/dist/geometry-3d.d.mts +1 -1
- package/dist/geometry-3d.d.ts +1 -1
- package/dist/geometry-3d.js +4136 -462
- package/dist/geometry-3d.js.map +1 -1
- package/dist/geometry-3d.mjs +5 -5
- package/dist/graph-2d.d.mts +1 -1
- package/dist/graph-2d.d.ts +1 -1
- package/dist/graph-2d.js +1010 -208
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +8 -8
- package/dist/{handleExtractProblem-BrDY9ifM.d.ts → handleExtractProblem-mtJyhEw3.d.mts} +2 -0
- package/dist/{handleExtractProblem-BrDY9ifM.d.mts → handleExtractProblem-mtJyhEw3.d.ts} +2 -0
- package/dist/{host-ZQCDAT6O.mjs → host-H2IGOKJU.mjs} +3 -3
- package/dist/{host-ZQCDAT6O.mjs.map → host-H2IGOKJU.mjs.map} +1 -1
- package/dist/{host-3UFGFMJ2.mjs → host-JNLJ5BVR.mjs} +92 -45
- package/dist/host-JNLJ5BVR.mjs.map +1 -0
- package/dist/{host-HOSJHQ5H.mjs → host-VRWLQSMH.mjs} +14 -13
- package/dist/host-VRWLQSMH.mjs.map +1 -0
- package/dist/host-W4U6YCSX.mjs +4973 -0
- package/dist/host-W4U6YCSX.mjs.map +1 -0
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +4577 -600
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +35 -29
- package/dist/index.mjs.map +1 -1
- package/dist/latex.d.mts +1 -1
- package/dist/latex.d.ts +1 -1
- package/dist/latex.js +8 -2
- package/dist/latex.js.map +1 -1
- package/dist/latex.mjs +1 -1
- package/dist/render-NMS7OAV6.mjs +10 -0
- package/dist/{render-ZX2O2IK7.mjs.map → render-NMS7OAV6.mjs.map} +1 -1
- package/dist/serialize-7UZWQQ4I.mjs +9 -0
- package/dist/{serialize-N4G6RFBB.mjs.map → serialize-7UZWQQ4I.mjs.map} +1 -1
- package/dist/{types-C3FjpoUi.d.mts → types-tePd94vW.d.mts} +8 -0
- package/dist/{types-C3FjpoUi.d.ts → types-tePd94vW.d.ts} +8 -0
- package/package.json +4 -1
- package/dist/chunk-BU5KLO3P.mjs.map +0 -1
- package/dist/chunk-H22OZYTW.mjs.map +0 -1
- package/dist/chunk-IHUFOV7L.mjs.map +0 -1
- package/dist/chunk-QGNU34T7.mjs.map +0 -1
- package/dist/chunk-QK6OVDLC.mjs +0 -103
- package/dist/chunk-QK6OVDLC.mjs.map +0 -1
- package/dist/chunk-SF3U7ZF4.mjs.map +0 -1
- package/dist/chunk-SZDAS7LK.mjs.map +0 -1
- package/dist/chunk-ZTQBUKLJ.mjs.map +0 -1
- package/dist/host-2ISGVO7O.mjs +0 -2377
- package/dist/host-2ISGVO7O.mjs.map +0 -1
- package/dist/host-3UFGFMJ2.mjs.map +0 -1
- package/dist/host-HOSJHQ5H.mjs.map +0 -1
- package/dist/render-ZX2O2IK7.mjs +0 -10
- package/dist/serialize-N4G6RFBB.mjs +0 -9
|
@@ -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-
|
|
7
|
+
() => import('./host-H2IGOKJU.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-
|
|
39
|
-
//# sourceMappingURL=chunk-
|
|
38
|
+
//# sourceMappingURL=chunk-C76SOFXF.mjs.map
|
|
39
|
+
//# sourceMappingURL=chunk-C76SOFXF.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-
|
|
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"]}
|
|
@@ -191,6 +191,18 @@ function createStore(initial, options = {}) {
|
|
|
191
191
|
};
|
|
192
192
|
}
|
|
193
193
|
|
|
194
|
+
// src/core/scene/kinds/_label.ts
|
|
195
|
+
function labelOpts(labelOffset, dflt) {
|
|
196
|
+
const offset = labelOffset ?? dflt;
|
|
197
|
+
return { label: { fixed: false, ...offset ? { offset } : {} } };
|
|
198
|
+
}
|
|
199
|
+
function readLabelOffset(label) {
|
|
200
|
+
const off = label.evalVisProp?.("offset") ?? label.visProp?.offset;
|
|
201
|
+
const rel = label.relativeCoords?.scrCoords;
|
|
202
|
+
if (!off || !rel || off.length < 2 || rel.length < 3) return null;
|
|
203
|
+
return [Math.round(off[0] + rel[1]), Math.round(off[1] - rel[2])];
|
|
204
|
+
}
|
|
205
|
+
|
|
194
206
|
// src/core/scene/expressions/parser.ts
|
|
195
207
|
var ALLOWED_CONSTANTS = ["pi", "e"];
|
|
196
208
|
var ALLOWED_FUNCTIONS = [
|
|
@@ -310,6 +322,6 @@ function collectFreeVars(expression) {
|
|
|
310
322
|
return out.sort();
|
|
311
323
|
}
|
|
312
324
|
|
|
313
|
-
export { collectFreeVars, compile, createStore, validate };
|
|
314
|
-
//# sourceMappingURL=chunk-
|
|
315
|
-
//# sourceMappingURL=chunk-
|
|
325
|
+
export { collectFreeVars, compile, createStore, labelOpts, readLabelOffset, validate };
|
|
326
|
+
//# sourceMappingURL=chunk-CH6SFONH.mjs.map
|
|
327
|
+
//# sourceMappingURL=chunk-CH6SFONH.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/scene/reducer.ts","../src/core/scene/store.ts","../src/core/scene/kinds/_label.ts","../src/core/scene/expressions/parser.ts"],"names":[],"mappings":"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","file":"chunk-CH6SFONH.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/kinds/_label.ts\n/** Offset nhãn (pixel) so với anchor. offset[1] dương = nhãn đi lên (quy ước JSXGraph). */\nexport type LabelOffset = [number, number];\n\n/**\n * Opts cho `label` của một JSXGraph element: luôn `fixed:false` (kéo được).\n * `labelOffset` (nếu có) hoặc `dflt` (nếu có) thành `offset`. Không có cả hai\n * → chỉ `{ fixed:false }` (giữ default JSXGraph, byte-identical với hiện tại\n * cho line/circle vốn không set offset).\n */\nexport function labelOpts(\n labelOffset?: LabelOffset,\n dflt?: LabelOffset,\n): { label: Record<string, unknown> } {\n const offset = labelOffset ?? dflt;\n return { label: { fixed: false, ...(offset ? { offset } : {}) } };\n}\n\n/**\n * Đọc offset-tổng (pixel) của một label JSXGraph sau khi user kéo, quy về dạng\n * thuần `offset` (để zero relativeCoords mà vị trí không đổi):\n * x = offset[0] + rel.scrCoords[1]\n * y = offset[1] - rel.scrCoords[2] (screen-y xuống, offset-y lên)\n * Trả null nếu thiếu dữ liệu.\n */\nexport function readLabelOffset(label: {\n evalVisProp?: (k: string) => unknown;\n visProp?: { offset?: number[] };\n relativeCoords?: { scrCoords?: number[] };\n}): LabelOffset | null {\n const off = (label.evalVisProp?.('offset') as number[] | undefined) ?? label.visProp?.offset;\n const rel = label.relativeCoords?.scrCoords;\n if (!off || !rel || off.length < 2 || rel.length < 3) return null;\n return [Math.round(off[0] + rel[1]), Math.round(off[1] - rel[2])];\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,11 +1,11 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { isGeometryCustomData, renderGeometrySvgFromState } from './chunk-
|
|
2
|
+
import { isGeometryCustomData, renderGeometrySvgFromState } from './chunk-KLGPAMJS.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 GeometryStampHost = lazy(
|
|
8
|
-
() => import('./host-
|
|
8
|
+
() => import('./host-JNLJ5BVR.mjs').then((m) => ({ default: m.GeometryStampHost }))
|
|
9
9
|
);
|
|
10
10
|
var GeometryIcon = /* @__PURE__ */ jsxs("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: [
|
|
11
11
|
/* @__PURE__ */ jsx("polygon", { points: "4,20 20,20 12,5" }),
|
|
@@ -38,5 +38,5 @@ var geometryStamp = {
|
|
|
38
38
|
};
|
|
39
39
|
|
|
40
40
|
export { geometryStamp };
|
|
41
|
-
//# sourceMappingURL=chunk-
|
|
42
|
-
//# sourceMappingURL=chunk-
|
|
41
|
+
//# sourceMappingURL=chunk-DBG6DZ2V.mjs.map
|
|
42
|
+
//# sourceMappingURL=chunk-DBG6DZ2V.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/stamps/geometry-2d/index.tsx"],"names":[],"mappings":";;;;;AAgBA,IAAM,iBAAA,GAAoB,IAAA;AAAA,EAAK,MAC7B,OAAO,qBAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,iBAAA,EAAkB,CAAE;AACjE,CAAA;AAEA,IAAM,YAAA,wBACH,KAAA,EAAA,EAAI,KAAA,EAAM,MAAK,MAAA,EAAO,IAAA,EAAK,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAY,KAAA,EAAM,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,eAAY,MAAA,EAC3J,QAAA,EAAA;AAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAQ,QAAO,iBAAA,EAAkB,CAAA;AAAA,kBAClC,GAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,CAAA,EAAE,KAAA,EAAM,IAAA,EAAK,cAAA,EAAe,MAAA,EAAO,MAAA,EAAO,CAAA;AAAA,kBACjE,GAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,CAAA,EAAE,KAAA,EAAM,IAAA,EAAK,cAAA,EAAe,MAAA,EAAO,MAAA,EAAO,CAAA;AAAA,kBAClE,GAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,CAAA,EAAE,KAAA,EAAM,IAAA,EAAK,cAAA,EAAe,MAAA,EAAO,MAAA,EAAO;AAAA,CAAA,EACnE,CAAA;AAGK,IAAM,aAAA,GAA+C;AAAA,EAC1D,IAAA,EAAM,UAAA;AAAA,EACN,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,YAAA,EAAc,8BAAA;AAAA,EACd,WAAA,EAAa,YAAA;AAAA,EACb,aAAA,EAAe,wBAAA;AAAA,EACf,iBAAA,EAAmB,oBAAA;AAAA,EACnB,MAAM,wBAAwB,IAAA,EAAM;AAClC,IAAA,IAAI,CAAC,oBAAA,CAAqB,IAAI,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAI,MAAM,+EAAuE,CAAA;AAAA,IACzF;AACA,IAAA,OAAO,0BAAA,CAA2B,KAAK,SAAS,CAAA;AAAA,EAClD,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,QAAQ,CAAC,MAAA,IAAU,CAAC,oBAAA,CAAqB,IAAI,GAAG,OAAO,IAAA;AAC5D,IAAA,MAAM,SAAA,GAAY,MAAM,0BAAA,CAA2B,IAAA,CAAK,SAAS,CAAA;AACjE,IAAA,OAAO,cAAA,CAAe,WAAW,MAAM,CAAA;AAAA,EACzC,CAAA;AAAA,EACA,IAAA,EAAM;AACR","file":"chunk-
|
|
1
|
+
{"version":3,"sources":["../src/stamps/geometry-2d/index.tsx"],"names":[],"mappings":";;;;;AAgBA,IAAM,iBAAA,GAAoB,IAAA;AAAA,EAAK,MAC7B,OAAO,qBAAQ,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,MAAO,EAAE,OAAA,EAAS,CAAA,CAAE,iBAAA,EAAkB,CAAE;AACjE,CAAA;AAEA,IAAM,YAAA,wBACH,KAAA,EAAA,EAAI,KAAA,EAAM,MAAK,MAAA,EAAO,IAAA,EAAK,SAAQ,WAAA,EAAY,IAAA,EAAK,QAAO,MAAA,EAAO,cAAA,EAAe,aAAY,KAAA,EAAM,aAAA,EAAc,SAAQ,cAAA,EAAe,OAAA,EAAQ,eAAY,MAAA,EAC3J,QAAA,EAAA;AAAA,kBAAA,GAAA,CAAC,SAAA,EAAA,EAAQ,QAAO,iBAAA,EAAkB,CAAA;AAAA,kBAClC,GAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,GAAA,EAAI,EAAA,EAAG,IAAA,EAAK,CAAA,EAAE,KAAA,EAAM,IAAA,EAAK,cAAA,EAAe,MAAA,EAAO,MAAA,EAAO,CAAA;AAAA,kBACjE,GAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,IAAA,EAAK,CAAA,EAAE,KAAA,EAAM,IAAA,EAAK,cAAA,EAAe,MAAA,EAAO,MAAA,EAAO,CAAA;AAAA,kBAClE,GAAA,CAAC,QAAA,EAAA,EAAO,EAAA,EAAG,IAAA,EAAK,EAAA,EAAG,GAAA,EAAI,CAAA,EAAE,KAAA,EAAM,IAAA,EAAK,cAAA,EAAe,MAAA,EAAO,MAAA,EAAO;AAAA,CAAA,EACnE,CAAA;AAGK,IAAM,aAAA,GAA+C;AAAA,EAC1D,IAAA,EAAM,UAAA;AAAA,EACN,WAAA,EAAa,GAAA;AAAA,EACb,YAAA,EAAc,GAAA;AAAA,EACd,YAAA,EAAc,8BAAA;AAAA,EACd,WAAA,EAAa,YAAA;AAAA,EACb,aAAA,EAAe,wBAAA;AAAA,EACf,iBAAA,EAAmB,oBAAA;AAAA,EACnB,MAAM,wBAAwB,IAAA,EAAM;AAClC,IAAA,IAAI,CAAC,oBAAA,CAAqB,IAAI,CAAA,EAAG;AAC/B,MAAA,MAAM,IAAI,MAAM,+EAAuE,CAAA;AAAA,IACzF;AACA,IAAA,OAAO,0BAAA,CAA2B,KAAK,SAAS,CAAA;AAAA,EAClD,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,QAAQ,CAAC,MAAA,IAAU,CAAC,oBAAA,CAAqB,IAAI,GAAG,OAAO,IAAA;AAC5D,IAAA,MAAM,SAAA,GAAY,MAAM,0BAAA,CAA2B,IAAA,CAAK,SAAS,CAAA;AACjE,IAAA,OAAO,cAAA,CAAe,WAAW,MAAM,CAAA;AAAA,EACzC,CAAA;AAAA,EACA,IAAA,EAAM;AACR","file":"chunk-DBG6DZ2V.mjs","sourcesContent":["'use client';\n\nimport { lazy, type ReactNode } from 'react';\nimport { renderGeometrySvgFromState } from './render';\nimport type {\n RestoredStampFile,\n StampType,\n} from '../shared/types';\nimport { svgToStampFile } from '../shared/svgToStampFile';\nimport {\n isGeometryCustomData,\n type GeometryCustomData,\n} from './types';\n\nexport type { GeometryCustomData };\n\nconst GeometryStampHost = lazy(() =>\n import('./host').then((m) => ({ default: m.GeometryStampHost })),\n);\n\nconst GeometryIcon: ReactNode = (\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 <polygon points=\"4,20 20,20 12,5\" />\n <circle cx=\"4\" cy=\"20\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"20\" cy=\"20\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\" />\n <circle cx=\"12\" cy=\"5\" r=\"1.4\" fill=\"currentColor\" stroke=\"none\" />\n </svg>\n);\n\nexport const geometryStamp: StampType<GeometryCustomData> = {\n kind: 'geometry',\n shortcutKey: 'g',\n toolbarLabel: 'G',\n toolbarTitle: 'Chèn hình học (G)',\n toolbarIcon: GeometryIcon,\n toolbarTestId: 'stamp-toolbar-geometry',\n matchesCustomData: isGeometryCustomData,\n async renderSvgFromCustomData(data) {\n if (!isGeometryCustomData(data)) {\n throw new Error('geometryStamp.renderSvgFromCustomData: customData không phải geometry');\n }\n return renderGeometrySvgFromState(data.jsonState);\n },\n async restoreFileFromCustomData(element): Promise<RestoredStampFile | null> {\n const data = element.customData as GeometryCustomData | undefined;\n const fileId = (element as { fileId?: string | null }).fileId;\n if (!data || !fileId || !isGeometryCustomData(data)) return null;\n const svgString = await renderGeometrySvgFromState(data.jsonState);\n return svgToStampFile(svgString, fileId);\n },\n Host: GeometryStampHost,\n};\n"]}
|
|
@@ -1,9 +1,9 @@
|
|
|
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-
|
|
5
|
-
import { createStore } from './chunk-
|
|
6
|
-
import { DEFAULT_VIEW_3D } from './chunk-
|
|
4
|
+
import { serializeScene, deserializeScene } from './chunk-4EXRNZRX.mjs';
|
|
5
|
+
import { createStore } from './chunk-CH6SFONH.mjs';
|
|
6
|
+
import { DEFAULT_VIEW_3D } from './chunk-MNHOFOM5.mjs';
|
|
7
7
|
import { getKind } from './chunk-B4NJJZFR.mjs';
|
|
8
8
|
|
|
9
9
|
// src/stamps/geometry-3d/serialize.ts
|
|
@@ -56,7 +56,9 @@ var JxgRenderer3D = class {
|
|
|
56
56
|
}
|
|
57
57
|
return el;
|
|
58
58
|
},
|
|
59
|
-
defaults: {}
|
|
59
|
+
defaults: {},
|
|
60
|
+
// State sống cho điểm phái sinh 3D (constraintToWorld đọc toạ độ gốc hiện tại).
|
|
61
|
+
getState: () => this.store.getState()
|
|
60
62
|
};
|
|
61
63
|
}
|
|
62
64
|
create(obj) {
|
|
@@ -95,6 +97,12 @@ var JxgRenderer3D = class {
|
|
|
95
97
|
}
|
|
96
98
|
return;
|
|
97
99
|
}
|
|
100
|
+
view.removeObject?.(el);
|
|
101
|
+
const anchor = asObj["point"];
|
|
102
|
+
if (anchor && typeof anchor === "object" && anchor["_is_new"] === true) {
|
|
103
|
+
view.removeObject?.(anchor);
|
|
104
|
+
}
|
|
105
|
+
return;
|
|
98
106
|
}
|
|
99
107
|
view.removeObject?.(el);
|
|
100
108
|
}
|
|
@@ -386,5 +394,5 @@ async function renderGeometry3DSvgFromState(jsonState) {
|
|
|
386
394
|
}
|
|
387
395
|
|
|
388
396
|
export { DEFAULT_VIEW3D, GROUND_PLANE_ATTRS, GROUND_PLANE_RANGE, JxgRenderer3D, VIEW3D_ATTRS, deserializeBoard3D, isGeometry3DCustomData, paletteFor2 as paletteFor, renderGeometry3DSvgFromState, serializeBoard3D };
|
|
389
|
-
//# sourceMappingURL=chunk-
|
|
390
|
-
//# sourceMappingURL=chunk-
|
|
397
|
+
//# sourceMappingURL=chunk-DCFZTKFE.mjs.map
|
|
398
|
+
//# sourceMappingURL=chunk-DCFZTKFE.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-DCFZTKFE.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 // State sống cho điểm phái sinh 3D (constraintToWorld đọc toạ độ gốc hiện tại).\n getState: () => this.store.getState(),\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 view.removeObject?.(el);\n // Mặt PHÁI SINH (plane3d construction, render bằng [point, dir1, dir2] điểm-\n // hàm): JSXGraph createPlane3D tạo internal anchor point3d (_is_new) làm gốc\n // NHƯNG KHÔNG adopt làm child (khác createLine3D có guard _is_new) →\n // removeObject(plane) bỏ sót anchor → orphan đọc state-sống MỖI FRAME, tích\n // luỹ qua mỗi remove+recreate. Dọn thủ công; CHỈ point `_is_new` (KHÔNG đụng\n // điểm scene thật của mặt 3-điểm — anchor đó không _is_new). Verify adversarial 2026-06-21.\n const anchor = asObj['point'] as Record<string, unknown> | undefined;\n if (anchor && typeof anchor === 'object' && anchor['_is_new'] === true) {\n view.removeObject?.(anchor);\n }\n return;\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"]}
|