@xom11/whiteboard 0.31.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 +148 -27
- package/dist/ai.d.ts +148 -27
- package/dist/ai.js +2652 -430
- package/dist/ai.js.map +1 -1
- package/dist/ai.mjs +2482 -426
- package/dist/ai.mjs.map +1 -1
- package/dist/catalog.json +4 -4
- package/dist/{chunk-JJ4FPCBE.mjs → chunk-4EXRNZRX.mjs} +641 -75
- package/dist/chunk-4EXRNZRX.mjs.map +1 -0
- package/dist/{chunk-BMYC2ILT.mjs → chunk-DBG6DZ2V.mjs} +4 -4
- package/dist/{chunk-BMYC2ILT.mjs.map → chunk-DBG6DZ2V.mjs.map} +1 -1
- package/dist/{chunk-T3N4BSJV.mjs → chunk-DCFZTKFE.mjs} +13 -5
- package/dist/chunk-DCFZTKFE.mjs.map +1 -0
- package/dist/{chunk-DWIEVCGK.mjs → chunk-DJM5EWTT.mjs} +53 -3
- package/dist/chunk-DJM5EWTT.mjs.map +1 -0
- package/dist/{chunk-44JY2AKC.mjs → chunk-F42MZ745.mjs} +3 -3
- package/dist/{chunk-44JY2AKC.mjs.map → chunk-F42MZ745.mjs.map} +1 -1
- package/dist/{chunk-TMRFSOM7.mjs → chunk-FI2MGX5H.mjs} +4 -4
- package/dist/{chunk-TMRFSOM7.mjs.map → chunk-FI2MGX5H.mjs.map} +1 -1
- package/dist/{chunk-KOXOC2FI.mjs → chunk-KLGPAMJS.mjs} +10 -7
- package/dist/chunk-KLGPAMJS.mjs.map +1 -0
- 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-K5BS2H56.mjs → chunk-MOAXHVKI.mjs} +4 -4
- package/dist/{chunk-K5BS2H56.mjs.map → chunk-MOAXHVKI.mjs.map} +1 -1
- package/dist/chunk-SUXIMLYN.mjs +238 -0
- package/dist/chunk-SUXIMLYN.mjs.map +1 -0
- package/dist/{chunk-LTLLQUMN.mjs → chunk-XSTGTEGP.mjs} +4 -4
- package/dist/{chunk-LTLLQUMN.mjs.map → chunk-XSTGTEGP.mjs.map} +1 -1
- package/dist/geometry-2d.js +883 -119
- package/dist/geometry-2d.js.map +1 -1
- package/dist/geometry-2d.mjs +4 -4
- package/dist/geometry-3d.js +3995 -471
- package/dist/geometry-3d.js.map +1 -1
- package/dist/geometry-3d.mjs +4 -4
- package/dist/graph-2d.js +706 -111
- package/dist/graph-2d.js.map +1 -1
- package/dist/graph-2d.mjs +4 -4
- 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-KMWP7KBT.mjs → host-JNLJ5BVR.mjs} +8 -8
- package/dist/{host-KMWP7KBT.mjs.map → host-JNLJ5BVR.mjs.map} +1 -1
- package/dist/{host-4FIUNIDQ.mjs → host-VRWLQSMH.mjs} +7 -7
- package/dist/{host-4FIUNIDQ.mjs.map → host-VRWLQSMH.mjs.map} +1 -1
- package/dist/host-W4U6YCSX.mjs +4973 -0
- package/dist/host-W4U6YCSX.mjs.map +1 -0
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4090 -392
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +27 -21
- package/dist/index.mjs.map +1 -1
- package/dist/serialize-7UZWQQ4I.mjs +9 -0
- package/dist/{serialize-PGHQZEPV.mjs.map → serialize-7UZWQQ4I.mjs.map} +1 -1
- package/package.json +4 -1
- package/dist/chunk-DWIEVCGK.mjs.map +0 -1
- package/dist/chunk-JJ4FPCBE.mjs.map +0 -1
- package/dist/chunk-KOXOC2FI.mjs.map +0 -1
- package/dist/chunk-QK6OVDLC.mjs +0 -103
- package/dist/chunk-QK6OVDLC.mjs.map +0 -1
- package/dist/chunk-T3N4BSJV.mjs.map +0 -1
- package/dist/host-4ZB4XD4S.mjs +0 -2378
- package/dist/host-4ZB4XD4S.mjs.map +0 -1
- package/dist/serialize-PGHQZEPV.mjs +0 -9
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/stamps/geometry-2d/serialize.ts","../src/stamps/geometry-2d/autoFitBbox.ts","../src/stamps/geometry-2d/autoFitBoard.ts","../src/stamps/geometry-2d/labelLayout.ts","../src/stamps/geometry-2d/render.ts","../src/stamps/geometry-2d/types.ts"],"names":[],"mappings":"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","file":"chunk-KOXOC2FI.mjs","sourcesContent":["// src/stamps/geometry-2d/serialize.ts\n//\n// Sau Tier D PR 3: customData.jsonState chỉ chứa `JSON.stringify(state)`\n// (không còn envelope `{version, bbox, state, showAxis, showGrid}`).\n// View info (bbox/axis/grid) nằm trong `state.meta.view` (View2D shape).\n\nimport { serializeScene, deserializeScene } from '../shared/serializeScene';\nimport type { State, View2D } from '../../core/scene';\n\nexport function serializeBoard(state: State, view: View2D): string {\n const withView: State = {\n ...state,\n meta: { domain: '2d', version: state.meta.version, view },\n };\n return serializeScene(withView);\n}\n\nexport function deserializeBoard(raw: string): State {\n return deserializeScene('2d', raw);\n}\n","// Pure geometry helpers for auto-fitting an AI-generated figure into a viewport.\n//\n// Two concerns, both visual-quality fixes:\n// 1. Outlier-robust extent — a single far-flung point or an oversized circle\n// must not compress the main cluster into a sliver (eval cau-13, cau-04).\n// We use Tukey IQR fences per axis to trim statistical outliers.\n// 2. Aspect correction — the offscreen container is sized from the DEFAULT\n// square bbox, so the fitted bbox must be expanded to the same aspect or\n// JSXGraph's setBoundingBox stretches the units → circles become ellipses\n// (eval cau-08). We grow the shorter axis (never shrink) so everything in\n// the robust extent stays visible.\n\n/**\n * Robust [min, max] of a sample using Tukey fences (Q1 - k·IQR, Q3 + k·IQR).\n * Values outside the fence are dropped before taking min/max. With no outliers\n * this returns the raw [min, max]. For < 4 samples IQR is meaningless → raw range.\n */\nexport function robustRange(values: number[], k = 1.5): [number, number] {\n const n = values.length;\n if (n === 0) return [0, 0];\n const sorted = [...values].sort((a, b) => a - b);\n if (n < 4) return [sorted[0], sorted[n - 1]];\n const quantile = (p: number): number => {\n const idx = (n - 1) * p;\n const lo = Math.floor(idx);\n const hi = Math.ceil(idx);\n if (lo === hi) return sorted[lo];\n return sorted[lo] + (sorted[hi] - sorted[lo]) * (idx - lo);\n };\n const q1 = quantile(0.25);\n const q3 = quantile(0.75);\n const iqr = q3 - q1;\n const fenceLo = q1 - k * iqr;\n const fenceHi = q3 + k * iqr;\n let min = Infinity;\n let max = -Infinity;\n for (const v of sorted) {\n if (v < fenceLo || v > fenceHi) continue;\n if (v < min) min = v;\n if (v > max) max = v;\n }\n if (!Number.isFinite(min) || !Number.isFinite(max)) return [sorted[0], sorted[n - 1]];\n return [min, max];\n}\n\nexport interface CircleExtent {\n cx: number;\n cy: number;\n r: number;\n}\n\n// A circle whose radius exceeds this multiple of the point-cluster diagonal is\n// treated as an oversized outlier and excluded from the fit (it still draws,\n// just clipped). Keeps a normal circumcircle in-frame while preventing a single\n// degenerate giant circle from compressing the whole figure (eval cau-13).\nconst CIRCLE_MAX_FACTOR = 1.0;\n\n/**\n * Compute a JSXGraph bbox `[xmin, ymax, xmax, ymin]` fitted to the figure.\n *\n * Points are reduced to a robust extent via Tukey IQR fences (trims stray\n * intersection points that fly off to huge coords). Circles are included WHOLE\n * (never per-edge trimmed — a clipped circle looks broken) unless a circle is\n * egregiously larger than the point cluster, in which case it is excluded. The\n * result is padded and expanded to `aspect` (= container width / height) so\n * units stay square (round circles). Returns null when there is no geometry.\n */\nexport function computeAutoFitBbox(\n points: ReadonlyArray<readonly [number, number]>,\n circles: ReadonlyArray<CircleExtent>,\n aspect: number,\n padPct = 0.12,\n): [number, number, number, number] | null {\n const xs = points.map((p) => p[0]).filter(Number.isFinite);\n const ys = points.map((p) => p[1]).filter(Number.isFinite);\n\n let xmin = Infinity, xmax = -Infinity, ymin = Infinity, ymax = -Infinity;\n let clusterDiag = 0;\n if (xs.length >= 2 && ys.length >= 2) {\n [xmin, xmax] = robustRange(xs);\n [ymin, ymax] = robustRange(ys);\n clusterDiag = Math.hypot(xmax - xmin, ymax - ymin);\n }\n\n for (const c of circles) {\n if (!Number.isFinite(c.cx) || !Number.isFinite(c.cy) || !Number.isFinite(c.r)) continue;\n // Exclude an oversized circle only when we have a point cluster to compare to.\n if (clusterDiag > 0 && c.r > CIRCLE_MAX_FACTOR * clusterDiag) continue;\n xmin = Math.min(xmin, c.cx - c.r); xmax = Math.max(xmax, c.cx + c.r);\n ymin = Math.min(ymin, c.cy - c.r); ymax = Math.max(ymax, c.cy + c.r);\n }\n\n if (!Number.isFinite(xmin) || !Number.isFinite(xmax) || !Number.isFinite(ymin) || !Number.isFinite(ymax)) {\n return null;\n }\n let w = xmax - xmin;\n let h = ymax - ymin;\n\n // Degenerate (all coincident / fully collinear on one axis): floor to 1 unit.\n if (w < 0.5) { const cx = (xmin + xmax) / 2; xmin = cx - 0.5; xmax = cx + 0.5; w = 1; }\n if (h < 0.5) { const cy = (ymin + ymax) / 2; ymin = cy - 0.5; ymax = cy + 0.5; h = 1; }\n\n const padX = w * padPct;\n const padY = h * padPct;\n xmin -= padX; xmax += padX; ymin -= padY; ymax += padY;\n w = xmax - xmin; h = ymax - ymin;\n\n // Expand the shorter axis so width/height matches the container aspect.\n const curAspect = w / h;\n if (curAspect < aspect) {\n const newW = h * aspect;\n const cx = (xmin + xmax) / 2;\n xmin = cx - newW / 2; xmax = cx + newW / 2;\n } else if (curAspect > aspect) {\n const newH = w / aspect;\n const cy = (ymin + ymax) / 2;\n ymin = cy - newH / 2; ymax = cy + newH / 2;\n }\n\n return [xmin, ymax, xmax, ymin];\n}\n","import { DEFAULT_VIEW_2D } from '../../core/scene/types';\nimport { computeAutoFitBbox } from './autoFitBbox';\n\n/**\n * Auto-fit helpers chia sẻ giữa offscreen render (render.ts) và editor MiniBoard.\n *\n * Trước đây logic này CHỈ nằm trong render.ts (offscreen) → ảnh chèn vào canvas\n * được fit gọn, NHƯNG editor MiniBoard lúc re-edit boot ở bbox default (không\n * fit) → figure trong editor nhỏ/lệch so với ảnh ngoài canvas. Tách ra để cả\n * hai dùng chung → editor view khớp ảnh đã chèn.\n */\n\ntype JxgBoardLike = {\n objectsList?: unknown[];\n setBoundingBox?: (bbox: [number, number, number, number]) => void;\n update?: () => void;\n fullUpdate?: () => void;\n};\n\nexport function isDefaultBbox(bbox: readonly number[]): boolean {\n const d = DEFAULT_VIEW_2D.bbox;\n return bbox.length === 4 && bbox[0] === d[0] && bbox[1] === d[1] && bbox[2] === d[2] && bbox[3] === d[3];\n}\n\n/**\n * Thu thập toạ độ point + tâm/bán kính circle từ board rồi tính bbox fit\n * (Tukey IQR trim outlier + expand theo `aspect`). KHÔNG mutate board.\n * Trả null nếu board không có entity hợp lệ.\n */\nexport function fittedBboxFromBoard(\n board: unknown,\n aspect: number,\n): [number, number, number, number] | null {\n const objs = (board as JxgBoardLike)?.objectsList;\n if (!Array.isArray(objs)) return null;\n const points: [number, number][] = [];\n const circles: { cx: number; cy: number; r: number }[] = [];\n for (const raw of objs) {\n\n const o = raw as any;\n // OBJECT_CLASS_POINT = 1\n if (o?.elementClass === 1 && typeof o.X === 'function' && typeof o.Y === 'function') {\n const x = o.X(), y = o.Y();\n if (Number.isFinite(x) && Number.isFinite(y)) points.push([x, y]);\n } else if (o?.elementClass === 3 && o.center?.X && typeof o.Radius === 'function') {\n // OBJECT_CLASS_CIRCLE\n const cx = o.center.X(), cy = o.center.Y(), r = o.Radius();\n if (Number.isFinite(cx) && Number.isFinite(cy) && Number.isFinite(r)) {\n circles.push({ cx, cy, r });\n }\n }\n }\n const safeAspect = Number.isFinite(aspect) && aspect > 0 ? aspect : 1;\n return computeAutoFitBbox(points, circles, safeAspect);\n}\n\n/**\n * Tính bbox fit từ board rồi setBoundingBox (mutate board). No-op nếu board\n * rỗng / không tính được bbox.\n */\nexport function autoFitBoardToContent(board: unknown, aspect: number): void {\n const bbox = fittedBboxFromBoard(board, aspect);\n if (!bbox) return;\n const b = board as JxgBoardLike;\n try {\n b.setBoundingBox?.(bbox);\n if (typeof b.update === 'function') b.update();\n if (typeof b.fullUpdate === 'function') b.fullUpdate();\n } catch { /* ignore */ }\n}\n","// Anti-collision label placement for AI-generated figures.\n//\n// JSXGraph places every point label at a fixed [10,10] pixel offset (up-right).\n// When points cluster, labels overlap and overlap interior lines. We push each\n// label radially OUTWARD from the figure centroid: points on the left get a\n// left offset, points on the right get a right offset, etc. Offsets are in the\n// SAME sign convention as JSXGraph's label `offset` attribute (it negates the\n// y internally for screen space), so [dirX·R, dirY·R] in math coords maps\n// directly to a screen offset away from the centroid.\n\nexport interface LabeledPoint {\n id: string;\n x: number;\n y: number;\n}\n\nexport function radialLabelOffsets(\n points: LabeledPoint[],\n R = 14,\n): Map<string, [number, number]> {\n const out = new Map<string, [number, number]>();\n if (points.length < 2) return out;\n\n const cx = points.reduce((s, p) => s + p.x, 0) / points.length;\n const cy = points.reduce((s, p) => s + p.y, 0) / points.length;\n\n for (const p of points) {\n let dx = p.x - cx;\n let dy = p.y - cy;\n const len = Math.hypot(dx, dy);\n if (len < 1e-9) {\n // Point sits on the centroid → no meaningful direction; push up.\n dx = 0;\n dy = 1;\n } else {\n dx /= len;\n dy /= len;\n }\n out.set(p.id, [Math.round(dx * R), Math.round(dy * R)]);\n }\n return out;\n}\n","import { deserializeBoard } from './serialize';\nimport { paletteFor } from './editor/theme';\nimport { createStore } from '../../core/scene';\nimport { DEFAULT_VIEW_2D } from '../../core/scene/types';\nimport { JxgRenderer } from '../../core/scene/render/JxgRenderer';\nimport { renderJsxgOffscreen } from '../shared/jxgOffscreenRender';\nimport { autoFitBoardToContent, isDefaultBbox } from './autoFitBoard';\nimport { radialLabelOffsets } from './labelLayout';\n\n/**\n * Re-render geometry SVG từ jsonState đã serialize. Dùng cho:\n * 1. Restore math-stamp file sau khi reload page (Excalidraw mất binary files).\n * 2. Generate SVG lúc INSERT (thay vì clone DOM với màu theo theme editor).\n *\n * LƯU Ý quan trọng — luôn dùng LIGHT palette (nét đậm). Excalidraw apply CSS\n * `filter: invert(93%) hue-rotate(180deg)` lên canvas trong dark mode → nét\n * đậm tự đảo thành sáng. Nếu ta bake nét sáng vào SVG cho dark mode, filter\n * sẽ đảo thành đậm → chìm vào nền tối. Giải pháp: luôn dùng nét đậm + để\n * Excalidraw tự lo invert.\n *\n * Implementation: tạo 1 div ẩn (off-screen, real dimensions để JSXGraph render\n * chuẩn), initBoard, replay creation log từ jsonState, dump SVG, dọn dẹp.\n *\n * Container dimensions phải MATCH aspect ratio của bbox (đã được editor lưu\n * sau khi JSXGraph adjust với keepAspectRatio:true). Trước đây hardcode\n * 400×300 + keepAspectRatio:false làm shape bị kéo dãn (circle thành ellipse,\n * góc vuông lệch) khi bbox không 4:3 → ảnh hiển thị khác với editor lúc\n * double-click. Fix: tính container W/H từ bbox + keepAspectRatio:true để\n * SVG output khớp với view trong editor.\n *\n * Lý do JXG.Options.text.display = 'internal': JSXGraph mặc định render\n * label bằng HTML <div> overlay → clone SVG export sẽ thiếu label.\n */\n\n// Canvas max-axis (px) cho view tham chiếu (un-zoomed). Trước đây dùng\n// PIXELS_PER_UNIT=20 cố định → figure px BẤT BIẾN với zoom (chỉ canvas đổi),\n// và zoom-in (bbox nhỏ lại) lại cho element NHỎ hơn — ngược trực giác. Giờ\n// pxPerUnit = DEFAULT_VIEW_PX / maxSpan(bbox): max-axis canvas luôn ~constant,\n// figure bên trong scale theo zoom (zoom-in → span nhỏ → figure to ra) → ảnh\n// chèn KHỚP với view trong editor (WYSIWYG). Bump 400→500 nên figure mặc định\n// (gen ra) cũng to hơn một tí.\nconst DEFAULT_VIEW_PX = 500;\nconst MIN_DIM = 100;\nconst MAX_DIM = 1200;\nconst FALLBACK_W = 400;\nconst FALLBACK_H = 300;\n\nexport function containerDimsForBbox(bbox: [number, number, number, number]): { width: number; height: number } {\n const [xmin, ymax, xmax, ymin] = bbox;\n const w = Math.abs(xmax - xmin);\n const h = Math.abs(ymax - ymin);\n if (!Number.isFinite(w) || !Number.isFinite(h) || w <= 0 || h <= 0) {\n return { width: FALLBACK_W, height: FALLBACK_H };\n }\n const pxPerUnit = DEFAULT_VIEW_PX / Math.max(w, h);\n let width = w * pxPerUnit;\n let height = h * pxPerUnit;\n const maxAxis = Math.max(width, height);\n if (maxAxis > MAX_DIM) {\n const ratio = MAX_DIM / maxAxis;\n width *= ratio;\n height *= ratio;\n }\n const minAxis = Math.min(width, height);\n if (minAxis < MIN_DIM) {\n const ratio = MIN_DIM / minAxis;\n width *= ratio;\n height *= ratio;\n }\n return { width: Math.round(width), height: Math.round(height) };\n}\n\n/**\n * Đẩy label điểm ra xa centroid (radial) để giảm chồng nhãn. Chỉ chạy cho\n * AI-generated figure (shouldAutoFit) — stamp user-edit giữ layout nhãn mặc định.\n */\nfunction applyRadialLabelOffsets(board: any): void {\n const objs = board?.objectsList;\n if (!Array.isArray(objs)) return;\n const pts: { id: string; x: number; y: number; el: any }[] = [];\n for (const o of objs) {\n if (o?.elementClass === 1 && typeof o.X === 'function' && o.label) {\n const x = o.X(), y = o.Y();\n if (Number.isFinite(x) && Number.isFinite(y)) pts.push({ id: o.id, x, y, el: o });\n }\n }\n const offsets = radialLabelOffsets(pts.map((p) => ({ id: p.id, x: p.x, y: p.y })));\n if (offsets.size === 0) return;\n for (const p of pts) {\n const off = offsets.get(p.id);\n if (!off) continue;\n try { p.el.setAttribute({ label: { offset: off } }); } catch { /* ignore */ }\n }\n try {\n if (typeof board.update === 'function') board.update();\n } catch { /* ignore */ }\n}\n\nexport async function renderGeometrySvgFromState(jsonState: string): Promise<string> {\n const state = deserializeBoard(jsonState);\n const view = state.meta.domain === '2d' ? state.meta.view : DEFAULT_VIEW_2D;\n const bbox = view.bbox as [number, number, number, number];\n const shouldAutoFit = isDefaultBbox(bbox);\n // Stamps inserted vào Excalidraw canvas → luôn dùng light palette.\n // Excalidraw's THEME_FILTER tự đảo nét trong dark mode.\n const palette = paletteFor(false);\n const dims = containerDimsForBbox(bbox);\n const { svgString } = await renderJsxgOffscreen({\n bbox,\n dims,\n axis: view.showAxis,\n grid: view.showGrid,\n keepAspectRatio: true,\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 const renderer = new JxgRenderer(store, board);\n if (shouldAutoFit) {\n autoFitBoardToContent(board, dims.width / dims.height);\n applyRadialLabelOffsets(board);\n }\n return renderer;\n },\n });\n return svgString;\n}\n","import type { BaseStampCustomData } from '../shared/types';\n\nexport interface GeometryCustomData extends BaseStampCustomData {\n kind: 'geometry';\n version: 1;\n jsonState: string;\n}\n\nexport function isGeometryCustomData(data: unknown): data is GeometryCustomData {\n if (!data || typeof data !== 'object') return false;\n const d = data as Partial<GeometryCustomData>;\n return d.kind === 'geometry' && d.version === 1 && typeof d.jsonState === 'string';\n}\n"]}
|
package/dist/chunk-QK6OVDLC.mjs
DELETED
|
@@ -1,103 +0,0 @@
|
|
|
1
|
-
"use client";
|
|
2
|
-
// src/stamps/geometry-2d/ai/vision/tesseract.ts
|
|
3
|
-
var DEFAULT_LANG = "vie+eng";
|
|
4
|
-
async function runTesseractOcr(image, opts = {}) {
|
|
5
|
-
if (opts.signal?.aborted) {
|
|
6
|
-
const err = new Error("Tesseract OCR aborted");
|
|
7
|
-
err.name = "AbortError";
|
|
8
|
-
throw err;
|
|
9
|
-
}
|
|
10
|
-
const { createWorker } = await import('tesseract.js');
|
|
11
|
-
const lang = opts.lang ?? DEFAULT_LANG;
|
|
12
|
-
const worker = await createWorker(lang);
|
|
13
|
-
try {
|
|
14
|
-
const dataUrl = `data:${image.mediaType};base64,${image.base64}`;
|
|
15
|
-
const { data } = await worker.recognize(dataUrl);
|
|
16
|
-
return { text: data.text, confidence: data.confidence };
|
|
17
|
-
} finally {
|
|
18
|
-
await worker.terminate();
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
// src/stamps/geometry-2d/ai/vision/extractProblem.ts
|
|
23
|
-
var MIN_HIGH_CONFIDENCE_CHARS = 10;
|
|
24
|
-
var MAX_TEXT_CHARS = 2e3;
|
|
25
|
-
var TESSERACT_HIGH_CONFIDENCE_THRESHOLD = 70;
|
|
26
|
-
async function extractProblemFromImage(image, opts = {}) {
|
|
27
|
-
let raw;
|
|
28
|
-
try {
|
|
29
|
-
raw = await runTesseractOcr(image, {
|
|
30
|
-
...opts.tesseractLang ? { lang: opts.tesseractLang } : {},
|
|
31
|
-
...opts.signal ? { signal: opts.signal } : {}
|
|
32
|
-
});
|
|
33
|
-
} catch (e) {
|
|
34
|
-
const err = e;
|
|
35
|
-
return {
|
|
36
|
-
ok: false,
|
|
37
|
-
reason: "unreadable",
|
|
38
|
-
message: "Tesseract OCR fail: " + (err.message ?? "?")
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
const text = postProcess(raw.text);
|
|
42
|
-
if (text.length === 0) {
|
|
43
|
-
return { ok: false, reason: "empty", message: "Tesseract kh\xF4ng tr\xEDch \u0111\u01B0\u1EE3c text." };
|
|
44
|
-
}
|
|
45
|
-
const tooShort = text.length < MIN_HIGH_CONFIDENCE_CHARS;
|
|
46
|
-
const lowConf = raw.confidence < TESSERACT_HIGH_CONFIDENCE_THRESHOLD;
|
|
47
|
-
const confidence = tooShort || lowConf ? "low" : "high";
|
|
48
|
-
return {
|
|
49
|
-
ok: true,
|
|
50
|
-
text,
|
|
51
|
-
confidence,
|
|
52
|
-
usage: { inputTokens: 0, outputTokens: 0 }
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
function postProcess(raw) {
|
|
56
|
-
let t = raw.trim();
|
|
57
|
-
t = t.replace(/\*\*(.+?)\*\*/g, "$1");
|
|
58
|
-
t = t.replace(/\*(.+?)\*/g, "$1");
|
|
59
|
-
t = t.replace(/_(.+?)_/g, "$1");
|
|
60
|
-
t = t.replace(/```[\s\S]*?```/g, "").replace(/`([^`]+)`/g, "$1");
|
|
61
|
-
t = t.replace(/\s+/g, " ").trim();
|
|
62
|
-
t = t.normalize("NFC");
|
|
63
|
-
if (t.length > MAX_TEXT_CHARS) t = t.slice(0, MAX_TEXT_CHARS);
|
|
64
|
-
return t;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
// src/stamps/geometry-2d/ai/handleExtractProblem.ts
|
|
68
|
-
async function handleExtractProblem(image, opts = {}) {
|
|
69
|
-
try {
|
|
70
|
-
const r = await extractProblemFromImage(image, opts);
|
|
71
|
-
if (r.ok) {
|
|
72
|
-
if (r.confidence === "low") {
|
|
73
|
-
return {
|
|
74
|
-
kind: "low-confidence",
|
|
75
|
-
text: r.text,
|
|
76
|
-
warning: "OCR c\xF3 th\u1EC3 kh\xF4ng ch\xEDnh x\xE1c, ki\u1EC3m tra tr\u01B0\u1EDBc khi v\u1EBD.",
|
|
77
|
-
usage: r.usage
|
|
78
|
-
};
|
|
79
|
-
}
|
|
80
|
-
return { kind: "success", text: r.text, usage: r.usage };
|
|
81
|
-
}
|
|
82
|
-
if (r.reason === "not-math") {
|
|
83
|
-
return { kind: "refused", reason: "not-math", message: r.message };
|
|
84
|
-
}
|
|
85
|
-
if (r.reason === "unsupported") {
|
|
86
|
-
return { kind: "error", code: "unsupported", message: r.message };
|
|
87
|
-
}
|
|
88
|
-
if (r.reason === "unreadable") {
|
|
89
|
-
return { kind: "error", code: "network", message: r.message };
|
|
90
|
-
}
|
|
91
|
-
return { kind: "error", code: "empty", message: r.message };
|
|
92
|
-
} catch (e) {
|
|
93
|
-
return {
|
|
94
|
-
kind: "error",
|
|
95
|
-
code: "unexpected",
|
|
96
|
-
message: e instanceof Error ? e.message : String(e)
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
export { extractProblemFromImage, handleExtractProblem, runTesseractOcr };
|
|
102
|
-
//# sourceMappingURL=chunk-QK6OVDLC.mjs.map
|
|
103
|
-
//# sourceMappingURL=chunk-QK6OVDLC.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/stamps/geometry-2d/ai/vision/tesseract.ts","../src/stamps/geometry-2d/ai/vision/extractProblem.ts","../src/stamps/geometry-2d/ai/handleExtractProblem.ts"],"names":[],"mappings":"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","file":"chunk-QK6OVDLC.mjs","sourcesContent":["// src/stamps/geometry-2d/ai/vision/tesseract.ts\n//\n// Tesseract.js wrapper cho client-side OCR đề toán. Default vie+eng, terminate\n// worker sau mỗi call (không cache v1). Lazy import giữ bundle slim.\n\nimport type { ImagePart } from './types';\n\nexport interface TesseractOcrOptions {\n /** Tesseract language code. Default 'vie+eng' cho đề toán VN. */\n lang?: string;\n signal?: AbortSignal;\n}\n\nexport interface TesseractOcrResult {\n text: string;\n /** Confidence 0–100 (Tesseract scale). */\n confidence: number;\n}\n\nconst DEFAULT_LANG = 'vie+eng';\n\nexport async function runTesseractOcr(\n image: ImagePart,\n opts: TesseractOcrOptions = {},\n): Promise<TesseractOcrResult> {\n if (opts.signal?.aborted) {\n const err = new Error('Tesseract OCR aborted');\n err.name = 'AbortError';\n throw err;\n }\n\n const { createWorker } = await import('tesseract.js');\n const lang = opts.lang ?? DEFAULT_LANG;\n const worker = await createWorker(lang);\n\n try {\n const dataUrl = `data:${image.mediaType};base64,${image.base64}`;\n const { data } = await worker.recognize(dataUrl);\n return { text: data.text, confidence: data.confidence };\n } finally {\n await worker.terminate();\n }\n}\n","// src/stamps/geometry-2d/ai/vision/extractProblem.ts\n//\n// Orchestrator vision → text. Engine duy nhất: Tesseract.js client-side OCR,\n// offline, không cần network / LLM / API key. (Engine 'llm' cũ đã gỡ.)\n\nimport { runTesseractOcr } from './tesseract';\nimport type { ImagePart } from './types';\n\n// Ngưỡng: text ngắn hơn thì force confidence=low bất kể engine report gì.\nconst MIN_HIGH_CONFIDENCE_CHARS = 10;\nconst MAX_TEXT_CHARS = 2000;\n// Tesseract confidence (0-100): ≥ ngưỡng này coi như high.\nconst TESSERACT_HIGH_CONFIDENCE_THRESHOLD = 70;\n\nexport interface ExtractProblemOptions {\n /** Tesseract language. Default 'vie+eng' cho đề toán VN. */\n tesseractLang?: string;\n signal?: AbortSignal;\n}\n\nexport interface ExtractProblemSuccess {\n ok: true;\n text: string;\n confidence: 'high' | 'low';\n usage: { inputTokens: number; outputTokens: number };\n}\n\nexport interface ExtractProblemFailure {\n ok: false;\n reason: 'not-math' | 'unreadable' | 'empty' | 'unsupported';\n message: string;\n}\n\nexport type ExtractProblemOutcome = ExtractProblemSuccess | ExtractProblemFailure;\n\nexport async function extractProblemFromImage(\n image: ImagePart,\n opts: ExtractProblemOptions = {},\n): Promise<ExtractProblemOutcome> {\n let raw: { text: string; confidence: number };\n try {\n raw = await runTesseractOcr(image, {\n ...(opts.tesseractLang ? { lang: opts.tesseractLang } : {}),\n ...(opts.signal ? { signal: opts.signal } : {}),\n });\n } catch (e) {\n const err = e as { message?: string };\n return {\n ok: false,\n reason: 'unreadable',\n message: 'Tesseract OCR fail: ' + (err.message ?? '?'),\n };\n }\n\n const text = postProcess(raw.text);\n if (text.length === 0) {\n return { ok: false, reason: 'empty', message: 'Tesseract không trích được text.' };\n }\n\n const tooShort = text.length < MIN_HIGH_CONFIDENCE_CHARS;\n const lowConf = raw.confidence < TESSERACT_HIGH_CONFIDENCE_THRESHOLD;\n const confidence: 'high' | 'low' = tooShort || lowConf ? 'low' : 'high';\n\n return {\n ok: true,\n text,\n confidence,\n usage: { inputTokens: 0, outputTokens: 0 },\n };\n}\n\nfunction postProcess(raw: string): string {\n let t = raw.trim();\n t = t.replace(/\\*\\*(.+?)\\*\\*/g, '$1');\n t = t.replace(/\\*(.+?)\\*/g, '$1');\n t = t.replace(/_(.+?)_/g, '$1');\n t = t.replace(/```[\\s\\S]*?```/g, '').replace(/`([^`]+)`/g, '$1');\n t = t.replace(/\\s+/g, ' ').trim();\n t = t.normalize('NFC');\n if (t.length > MAX_TEXT_CHARS) t = t.slice(0, MAX_TEXT_CHARS);\n return t;\n}\n","// src/stamps/geometry-2d/ai/handleExtractProblem.ts\n//\n// Façade UI-friendly cho extractProblemFromImage. Map outcome → UI result kind.\n// Engine = Tesseract client-side (offline, không LLM).\n\nimport {\n extractProblemFromImage,\n type ExtractProblemOptions,\n} from './vision/extractProblem';\nimport type { ImagePart } from './vision/types';\n\nexport interface HandleExtractProblemOptions extends ExtractProblemOptions {}\n\nexport type ExtractUiResult =\n | {\n kind: 'success';\n text: string;\n usage: { inputTokens: number; outputTokens: number };\n }\n | {\n kind: 'low-confidence';\n text: string;\n warning: string;\n usage: { inputTokens: number; outputTokens: number };\n }\n | {\n kind: 'refused';\n reason: 'not-math';\n message: string;\n }\n | {\n kind: 'error';\n code: 'network' | 'unsupported' | 'unexpected' | 'empty';\n message: string;\n };\n\nexport async function handleExtractProblem(\n image: ImagePart,\n opts: HandleExtractProblemOptions = {},\n): Promise<ExtractUiResult> {\n try {\n const r = await extractProblemFromImage(image, opts);\n if (r.ok) {\n if (r.confidence === 'low') {\n return {\n kind: 'low-confidence',\n text: r.text,\n warning: 'OCR có thể không chính xác, kiểm tra trước khi vẽ.',\n usage: r.usage,\n };\n }\n return { kind: 'success', text: r.text, usage: r.usage };\n }\n if (r.reason === 'not-math') {\n return { kind: 'refused', reason: 'not-math', message: r.message };\n }\n if (r.reason === 'unsupported') {\n return { kind: 'error', code: 'unsupported', message: r.message };\n }\n if (r.reason === 'unreadable') {\n return { kind: 'error', code: 'network', message: r.message };\n }\n return { kind: 'error', code: 'empty', message: r.message };\n } catch (e) {\n return {\n kind: 'error',\n code: 'unexpected',\n message: e instanceof Error ? e.message : String(e),\n };\n }\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
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-T3N4BSJV.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"]}
|