lineadraw 0.5.0 → 0.7.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/README.md +221 -13
- package/bin/lineadraw.mjs +193 -25
- package/dist/chunk-L4FNH35X.js +80 -0
- package/dist/chunk-L4FNH35X.js.map +1 -0
- package/dist/chunk-NCNZ7A6M.js +7957 -0
- package/dist/chunk-NCNZ7A6M.js.map +1 -0
- package/dist/chunk-PZ5AY32C.js +10 -0
- package/dist/chunk-PZ5AY32C.js.map +1 -0
- package/dist/embedded-F5ZJYFHC.js +10 -0
- package/dist/embedded-F5ZJYFHC.js.map +1 -0
- package/dist/exportDxf-2HC6UIBS.js +8 -0
- package/dist/exportDxf-2HC6UIBS.js.map +1 -0
- package/dist/node-2RH2EKXG.js +255 -0
- package/dist/node-2RH2EKXG.js.map +1 -0
- package/dist/pkg/linea_dwg_bg.wasm +0 -0
- package/dist/sdk.d.ts +5925 -0
- package/dist/sdk.js +8165 -0
- package/dist/sdk.js.map +1 -0
- package/lib/init.mjs +3 -3
- package/lib/manifest.mjs +33 -67
- package/lineadraw.d.ts +1506 -177
- package/package.json +33 -5
- package/templates/tsconfig.json +3 -8
package/dist/sdk.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/document.ts","../../core/src/geometry/arcs.ts","../../core/src/geometry/ellipse.ts","../../core/src/geometry/bounds.ts","../../core/src/geometry/polyline.ts","../../core/src/paint/sink.ts","../../core/src/model/builtinPat.ts","../../core/src/model/hatchPatterns.ts","../../core/src/model/document.ts","../../core/src/model/paperLayout.ts","../../core/src/model/scale.ts","../../core/src/model/defaults.ts","../../core/src/model/assets.ts","../../core/src/serialize.ts","../../core/src/export/svg/svgSink.ts","../../core/src/paint/painters/line.ts","../../core/src/paint/painters/point.ts","../../core/src/paint/painters/polyline.ts","../../core/src/paint/painters/circle.ts","../../core/src/paint/painters/arc.ts","../../core/src/paint/painters/ellipse.ts","../../core/src/paint/painters/hatch.ts","../../core/src/paint/painters/arrows.ts","../../core/src/paint/painters/text.ts","../../core/src/paint/painters/dimension.ts","../../core/src/paint/lineTypes.ts","../../core/src/paint/painters/block.ts","../../core/src/paint/painters/viewport.ts","../../core/src/paint/painters/image.ts","../../core/src/paint/painters/table.ts","../../core/src/snap/nearIndex.ts","../../core/src/snap/buildEntry.ts","../../core/src/import/dxf/importDxf.ts","../../core/src/import/dxf/extraEntities.ts","../../core/src/import/dxf/objectsSection.ts","../../core/src/reference/reference.ts","../../core/src/paint/style.ts","../../core/src/paint/rebaseSink.ts","../../core/src/paint/painters/reference.ts","../../core/src/paint/painters/index.ts","../../core/src/extensions/blockThumbnail.ts","../../core/src/extensions/scriptModules.ts","../../core/src/extensions/commandModules.ts","../../core/src/paint/fontCoverage.ts","../../core/src/paint/layoutPaint.ts","../../core/src/paint/printPalette.ts","../../core/src/dwg.ts","../../core/src/export/pdf/exportPdf.ts","../../core/src/export/pdf/pdfSink.ts","../../core/src/export/svg/renderSvg.ts","../../core/src/import/pdf/convertPage.ts","../../core/src/import/pdf/importPdf.ts","../../core/src/operations/types.ts","../../core/src/operations/apply.ts","../../core/src/operations/diff.ts","../../core/src/operations/kernel.ts","../../core/src/drawing/localDrawing.ts","../../core/src/drawing/runCommand.ts","../../core/src/export/png/renderPng.ts"],"sourcesContent":["// The scripting-first document handle: core's browser-safe `LocalDrawing`\n// (the `Drawing` interface over one DocumentKernel — docs/interaction-\n// surface.md) plus the Node-only pieces: file open/save, PNG rasterization,\n// PDF export with the embedded fonts, and path-taking import/export helpers.\n// Ergonomics only — never new semantics. See docs/agent-sdk-mcp.md.\n\nimport { readFile, writeFile } from \"node:fs/promises\";\nimport { dirname, isAbsolute, resolve } from \"node:path\";\nimport {\n approximateTextMeasurer,\n contentFromDocument,\n documentFromDxf,\n documentFromImage,\n documentFromJson,\n dwgToDxf,\n emptyDocument,\n imagePixelSize,\n measureContentBounds,\n pdfToModel,\n documentWithObjects,\n type LineaDocument as CoreDocument,\n type ReferenceObject,\n type ReferenceContent,\n type ReferenceSource,\n rebaseReferenceSource,\n LocalDrawing,\n renderLayoutsToPdf,\n selectPdfLayouts,\n runCommandModule,\n runDocumentCommand,\n usedEmbedFontIds,\n type DxfImportOptions,\n type DxfImportReport,\n type LineaDocument,\n type PdfImportOptions,\n type PdfImportReport,\n type PointInput,\n type RenderPdfOptions,\n type RenderPngOptions,\n} from \"@lineadraw/core\";\nimport {\n embeddedPdfFonts,\n renderLayoutToPng,\n renderModelToPng,\n} from \"@lineadraw/core/node\";\nimport type { DwgVersion } from \"@lineadraw/core\";\n\nexport type {\n AddOptions,\n DocumentSummary,\n DxfImportOptions,\n DxfImportReport,\n LayoutOptions,\n ObjectInput,\n PdfImportReport,\n PointInput,\n QueryFilter,\n RenderPdfOptions as PdfOptions,\n RenderPngOptions as PngOptions,\n RenderSvgOptions as SvgOptions,\n SheetName,\n ViewportOptions,\n} from \"@lineadraw/core\";\nexport { parseScale } from \"@lineadraw/core\";\n\n/** A drawing's name from its file: the base name without the extension. */\nconst nameOfPath = (path: string): string =>\n (path.split(/[/\\\\]/).pop() ?? path).replace(/\\.(linea|lineadraw)$/i, \"\");\n\n/** A referenced file's bytes → a document, by format (Node: a raster PDF\n * reference draws as vectors — there is no canvas to rasterize with). */\nconst referenceDocument = async (\n ref: ReferenceObject,\n bytes: Uint8Array,\n): Promise<CoreDocument> => {\n switch (ref.format) {\n case \"linea\":\n return documentFromJson(new TextDecoder().decode(bytes));\n case \"dxf\":\n return documentFromDxf(new TextDecoder().decode(bytes));\n case \"dwg\":\n return documentFromDxf(await dwgToDxf(bytes));\n case \"pdf\": {\n const result = await pdfToModel(bytes, { page: ref.pdfPage ?? 1 });\n return documentWithObjects((d) => ({\n objects: result.objects.map((o) => ({ ...o, layerId: d.layers[0].id })),\n }));\n }\n case \"png\":\n case \"jpg\": {\n const size = imagePixelSize(bytes);\n if (!size) throw new Error(`${ref.name}: not a PNG/JPEG`);\n const mime = ref.format === \"png\" ? \"image/png\" : \"image/jpeg\";\n const px = 25.4 / 96;\n return documentFromImage(\n `data:${mime};base64,${Buffer.from(bytes).toString(\"base64\")}`,\n size.width * px,\n size.height * px,\n );\n }\n }\n};\n\nexport class Drawing extends LocalDrawing {\n private path?: string;\n\n constructor(\n doc: LineaDocument,\n filePath?: string,\n migration: { from: number; to: number } | null = null,\n ) {\n super(doc, migration);\n this.path = filePath;\n if (filePath) this.name = nameOfPath(filePath);\n }\n\n /** The file this drawing was opened from / last saved to, if any. */\n get filePath(): string | undefined {\n return this.path;\n }\n\n /** Block scripts compiled AND referenced files loaded (relative paths\n * against this drawing's folder) — renders include their content. A file\n * that can't be read stays a frame. */\n override async ready(): Promise<void> {\n await super.ready();\n const refs = [\n ...this.objects,\n ...this.layouts.flatMap((l) => l.objects),\n ].filter((o): o is ReferenceObject => o.type === \"reference\");\n for (const ref of refs) {\n const content = await this.loadReference(ref, ref.source, 0, new Set());\n if (content) this.referenceContent.set(ref.id, content);\n else this.referenceContent.delete(ref.id); // missing → frame\n }\n }\n\n /** One reference's content (null when unreadable); a .linea's own\n * references load relative to it — depth-limited, never re-entering a\n * file above in the chain (the editor's rules). */\n private async loadReference(\n ref: ReferenceObject,\n source: ReferenceSource,\n depth: number,\n seen: ReadonlySet<string>,\n ): Promise<ReferenceContent | null> {\n let doc: CoreDocument;\n try {\n doc = await referenceDocument(ref, await this.readSource(source));\n } catch {\n return null;\n }\n const content = contentFromDocument(doc, ref.id);\n if (ref.format === \"linea\" && depth + 1 < 4) {\n const above = new Set(seen).add(JSON.stringify(source));\n const nested = new Map<string, ReferenceContent>();\n for (const child of content.objects) {\n if (child.type !== \"reference\") continue;\n const childSource = rebaseReferenceSource(child.source, source);\n if (above.has(JSON.stringify(childSource))) continue;\n const c = await this.loadReference(\n child,\n childSource,\n depth + 1,\n above,\n );\n if (c) nested.set(child.id, c);\n }\n content.resolveReference = (r) => nested.get(r.id) ?? null;\n }\n return {\n ...content,\n bounds: measureContentBounds(content, approximateTextMeasurer),\n };\n }\n\n private async readSource(source: ReferenceSource): Promise<Uint8Array> {\n if (source.kind === \"url\") {\n const res = await fetch(source.url);\n if (!res.ok) throw new Error(`HTTP ${res.status}`);\n return new Uint8Array(await res.arrayBuffer());\n }\n const p = source.path;\n const abs =\n isAbsolute(p) || !this.path ? p : resolve(dirname(this.path), p);\n return new Uint8Array(await readFile(abs));\n }\n\n // --- render / export (Node) ------------------------------------------------\n\n /** Rasterize model space (or a paper layout via `layout`) to PNG bytes\n * (Node only — lazy native rasterizer). */\n async renderPng(opts: RenderPngOptions = {}): Promise<Uint8Array> {\n if (opts.layout !== undefined)\n return renderLayoutToPng(\n this.resolveLayout(opts.layout),\n this.paintContext(),\n opts,\n );\n return renderModelToPng(this.paintContext(), opts);\n }\n\n /** Multi-page PDF of the layouts (default: all) with the embedded fonts. */\n async renderPdf(opts: RenderPdfOptions = {}): Promise<Uint8Array> {\n const doc = this.state;\n const layouts = selectPdfLayouts(doc.layouts, opts, () =>\n this.makeLayout(\"Layout 1\"),\n );\n const pdf = renderLayoutsToPdf(\n layouts,\n this.paintContext(),\n embeddedPdfFonts(usedEmbedFontIds(doc)),\n );\n return new Uint8Array(pdf.output(\"arraybuffer\"));\n }\n\n async exportSvg(\n path: string,\n opts?: Parameters<LocalDrawing[\"renderSvg\"]>[0],\n ): Promise<void> {\n await writeFile(path, this.renderSvg(opts), \"utf8\");\n }\n async exportPng(path: string, opts?: RenderPngOptions): Promise<void> {\n await writeFile(path, await this.renderPng(opts));\n }\n async exportDxf(path: string): Promise<void> {\n await writeFile(path, await this.toDxf(), \"utf8\");\n }\n async exportDwg(\n path: string,\n opts?: { version?: DwgVersion },\n ): Promise<void> {\n await writeFile(path, await this.toDwg(opts));\n }\n async exportPdf(path: string, opts?: RenderPdfOptions): Promise<void> {\n await writeFile(path, await this.renderPdf(opts));\n }\n /** Write the `.linea` JSON; `path` defaults to (and updates) filePath. */\n async save(path?: string): Promise<string> {\n const target = path ?? this.path;\n if (!target)\n throw new Error(\n \"save() needs a path (document was not opened from a file)\",\n );\n this.path = target;\n this.name = nameOfPath(target); // the file name IS the name\n await writeFile(target, this.toLinea(), \"utf8\");\n return target;\n }\n\n // --- import from files (the in-memory imports are core's LocalDrawing) -----------------------------------------------------\n\n async importDxf(\n path: string,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDxfText(await readFile(path, \"utf8\"), opts);\n }\n\n async importDwg(\n path: string,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDwgData(await readFile(path), opts);\n }\n\n async importPdf(\n path: string,\n opts?: PdfImportOptions,\n ): Promise<PdfImportReport> {\n const data = await readFile(path);\n return this.importPdfData(\n data.buffer.slice(data.byteOffset, data.byteOffset + data.byteLength),\n opts,\n );\n }\n\n // --- scripts ---------------------------------------------------------------\n\n /** Run a command module source (`defineCommand`) against this drawing as\n * ONE undo step, headlessly: declared `inputs` must be supplied; declared\n * `params` take their defaults unless given by name (unknown names and\n * wrong types throw). Resolves with the script's return value. */\n runScript(\n source: string,\n inputs?: readonly PointInput[],\n params?: Readonly<Record<string, unknown>>,\n ): Promise<unknown> {\n return runCommandModule(source, { document: this, inputs, params });\n }\n\n /** Run one of the document's own commands (by exported id). */\n runUserCommand(\n id: string,\n inputs?: readonly PointInput[],\n params?: Readonly<Record<string, unknown>>,\n ): Promise<unknown> {\n return runDocumentCommand(id, { document: this, inputs, params });\n }\n}\n\n// --- entry points ----------------------------------------------------------\n\n/** A fresh empty document, optionally named (until saved to a file, whose\n * name then takes over). */\nexport function newDrawing(name?: string): Drawing {\n const drawing = new Drawing(emptyDocument());\n if (name !== undefined) drawing.name = name;\n return drawing;\n}\n\n/** The pre-migration schema version of raw `.linea` JSON (best effort). */\nconst rawVersion = (text: string): number | null => {\n try {\n const v = (JSON.parse(text) as { version?: unknown }).version;\n return typeof v === \"number\" ? v : null;\n } catch {\n return null;\n }\n};\n\nconst withMigration = (text: string, filePath?: string): Drawing => {\n const from = rawVersion(text);\n const doc = documentFromJson(text);\n const migration =\n from !== null && from !== doc.version ? { from, to: doc.version } : null;\n return new Drawing(doc, filePath, migration);\n};\n\n/** Parse a `.linea` JSON string. */\nexport function drawingFromJson(text: string): Drawing {\n return withMigration(text);\n}\n\n/** Open a `.linea` file (parse + migrate) into an in-process kernel. */\nexport async function openDrawing(path: string): Promise<Drawing> {\n const doc = withMigration(await readFile(path, \"utf8\"), path);\n await doc.ready(); // block scripts evaluate definitively from the start\n return doc;\n}\n","// Arc math, including DXF-style bulge conversion.\n// A bulge is tan(sweep/4): 0 = straight, positive = CCW arc from a to b.\n\nimport type { Vec2 } from \"./vec2\";\nimport {\n add,\n angle,\n cross,\n dist,\n dot,\n len,\n mid,\n norm,\n normAngle,\n perp,\n rot,\n scale,\n sub,\n} from \"./vec2\";\n\nexport interface ArcGeom {\n center: Vec2;\n radius: number;\n /** Start angle, radians CCW from +X. */\n startAngle: number;\n /** End angle. The arc always runs CCW from startAngle to endAngle. */\n endAngle: number;\n}\n\n/** CCW sweep of an arc in (0, 2π]. */\nexport const arcSweep = (a: ArcGeom): number => {\n const s = normAngle(a.endAngle - a.startAngle);\n return s === 0 ? Math.PI * 2 : s;\n};\n\nexport const pointOnArc = (a: ArcGeom, angle: number): Vec2 => ({\n x: a.center.x + Math.cos(angle) * a.radius,\n y: a.center.y + Math.sin(angle) * a.radius,\n});\n\nexport const arcStartPoint = (a: ArcGeom): Vec2 => pointOnArc(a, a.startAngle);\nexport const arcEndPoint = (a: ArcGeom): Vec2 => pointOnArc(a, a.endAngle);\nexport const arcMidPoint = (a: ArcGeom): Vec2 =>\n pointOnArc(a, a.startAngle + arcSweep(a) / 2);\n\n/** Is the angle within the CCW range [startAngle, endAngle]? */\nexport const angleInArc = (a: ArcGeom, angle: number): boolean =>\n normAngle(angle - a.startAngle) <= arcSweep(a) + 1e-12;\n\n/**\n * Convert a bulged polyline segment (a → b, bulge) to arc geometry.\n * Returns null for straight segments (bulge ≈ 0) or degenerate points.\n * Negative bulge = CW visual arc; we normalize so the ArcGeom is always CCW\n * by swapping start/end angles.\n */\nexport const bulgeToArc = (a: Vec2, b: Vec2, bulge: number): ArcGeom | null => {\n if (Math.abs(bulge) < 1e-12) return null;\n const chord = dist(a, b);\n if (chord < 1e-12) return null;\n const sweep = 4 * Math.atan(bulge); // signed, CCW positive\n const radius = Math.abs(chord / (2 * Math.sin(sweep / 2)));\n // Sagitta-based center: offset from chord midpoint along the perpendicular.\n const m = mid(a, b);\n const dir = scale(sub(b, a), 1 / chord);\n // Signed distance from chord midpoint to center, along the left normal of\n // a→b: positive bulge (CCW) puts the center on the left for a minor arc,\n // on the right for a major arc (tan flips sign past π); negative mirrors.\n const h = chord / 2 / Math.tan(sweep / 2);\n const center = add(m, scale(perp(dir), h));\n const angA = angle(sub(a, center));\n const angB = angle(sub(b, center));\n return bulge > 0\n ? { center, radius, startAngle: angA, endAngle: angB }\n : { center, radius, startAngle: angB, endAngle: angA };\n};\n\n/** Bulge value for an arc from a to b through point m (all on the arc). */\nexport const bulgeFrom3Points = (a: Vec2, m: Vec2, b: Vec2): number => {\n // The heading change from chord a→m to chord m→b is half the arc's sweep\n // (inscribed angle), so bulge = tan(sweep/4) = tan(turn/2).\n let turn = angle(sub(b, m)) - angle(sub(m, a));\n while (turn > Math.PI) turn -= 2 * Math.PI;\n while (turn < -Math.PI) turn += 2 * Math.PI;\n return Math.tan(turn / 2);\n};\n\n/**\n * Unit tangent at the END of a bulged segment a → b, pointing in the direction\n * of travel (a → b). Straight segment (bulge ≈ 0) → norm(b - a); an arc's end\n * tangent leads the chord by half the sweep.\n */\nexport const bulgeEndTangent = (a: Vec2, b: Vec2, bulge: number): Vec2 =>\n rot(norm(sub(b, a)), 2 * Math.atan(bulge));\n\n/**\n * Bulge of the circular arc from `start` to `end` whose tangent at `start` is\n * `tangent` (need not be unit) — the tangent-continuous arc. Positive = CCW,\n * 0 when the tangent aligns with the chord (a straight segment). The signed\n * tangent-to-chord angle is half the sweep, so bulge = tan(angle / 2).\n */\nexport const bulgeFromTangent = (\n start: Vec2,\n tangent: Vec2,\n end: Vec2,\n): number => {\n const chord = sub(end, start);\n if (len(chord) < 1e-12 || len(tangent) < 1e-12) return 0;\n const half = Math.atan2(cross(tangent, chord), dot(tangent, chord));\n return Math.tan(half / 2);\n};\n\n/** Circle through 3 points; null when collinear. */\nexport const circleFrom3Points = (\n p1: Vec2,\n p2: Vec2,\n p3: Vec2,\n): { center: Vec2; radius: number } | null => {\n const ax = p1.x;\n const ay = p1.y;\n const bx = p2.x;\n const by = p2.y;\n const cx = p3.x;\n const cy = p3.y;\n const d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by));\n if (Math.abs(d) < 1e-12) return null;\n const a2 = ax * ax + ay * ay;\n const b2 = bx * bx + by * by;\n const c2 = cx * cx + cy * cy;\n const center = {\n x: (a2 * (by - cy) + b2 * (cy - ay) + c2 * (ay - by)) / d,\n y: (a2 * (cx - bx) + b2 * (ax - cx) + c2 * (bx - ax)) / d,\n };\n return { center, radius: dist(center, p1) };\n};\n\n/**\n * Arc through 3 points: start, a point on the arc, end.\n * Returns CCW geometry from start to end passing through the middle point.\n */\nexport const arcFrom3Points = (\n start: Vec2,\n on: Vec2,\n end: Vec2,\n): ArcGeom | null => {\n const c = circleFrom3Points(start, on, end);\n if (!c) return null;\n const angS = angle(sub(start, c.center));\n const angO = angle(sub(on, c.center));\n const angE = angle(sub(end, c.center));\n // CCW from start: does \"on\" lie within the CCW range start→end?\n const ccw: ArcGeom = {\n center: c.center,\n radius: c.radius,\n startAngle: angS,\n endAngle: angE,\n };\n if (angleInArc(ccw, angO)) return ccw;\n return {\n center: c.center,\n radius: c.radius,\n startAngle: angE,\n endAngle: angS,\n };\n};\n\n/** Closest point on an arc to p (accounting for angular range; falls back to nearest endpoint). */\nexport const closestPointOnArc = (a: ArcGeom, p: Vec2): Vec2 => {\n const v = sub(p, a.center);\n const ang = angle(v);\n if (angleInArc(a, ang)) return pointOnArc(a, ang);\n const s = arcStartPoint(a);\n const e = arcEndPoint(a);\n return dist(p, s) <= dist(p, e) ? s : e;\n};\n\n/** Distance from p to the arc curve. */\nexport const distToArc = (a: ArcGeom, p: Vec2): number =>\n dist(p, closestPointOnArc(a, p));\n\n/** Tessellate an arc into points (including both endpoints), targeting a chord tolerance in mm. */\nexport const tessellateArc = (a: ArcGeom, chordTolerance = 0.1): Vec2[] => {\n const sweep = arcSweep(a);\n // chord error e = r(1 - cos(dθ/2)) → dθ = 2·acos(1 - e/r)\n const maxStep =\n a.radius <= chordTolerance\n ? sweep\n : 2 * Math.acos(Math.max(-1, 1 - chordTolerance / a.radius));\n const n = Math.max(2, Math.ceil(sweep / Math.max(maxStep, 1e-3)));\n const pts: Vec2[] = [];\n for (let i = 0; i <= n; i++) {\n pts.push(pointOnArc(a, a.startAngle + (sweep * i) / n));\n }\n return pts;\n};\n","// Ellipse math in DXF form: center + majorAxis endpoint vector + ratio\n// (minor/major). Points are parameterized by t: p(t) = c + M·cos t + m·sin t,\n// where m = perp(M)·ratio. startAngle/endAngle bound a CCW parametric range.\n\nimport type { Vec2 } from \"./vec2\";\nimport { add, distSq, len, normAngle, perp, scale } from \"./vec2\";\n\nexport interface EllipseGeom {\n center: Vec2;\n majorAxis: Vec2;\n /** minor/major in (0, 1]. */\n ratio: number;\n startAngle: number;\n endAngle: number;\n}\n\nexport const ellipseSweep = (e: EllipseGeom): number => {\n const s = normAngle(e.endAngle - e.startAngle);\n return s === 0 ? Math.PI * 2 : s;\n};\n\nexport const isFullEllipse = (e: EllipseGeom): boolean =>\n Math.abs(ellipseSweep(e) - Math.PI * 2) < 1e-9;\n\n/** Area of the full ellipse (π·rx·ry), independent of the angular range. */\nexport const ellipseArea = (e: EllipseGeom): number =>\n Math.PI * len(e.majorAxis) ** 2 * e.ratio;\n\nexport const pointOnEllipse = (e: EllipseGeom, t: number): Vec2 => {\n const minor = scale(perp(e.majorAxis), e.ratio);\n return add(\n add(e.center, scale(e.majorAxis, Math.cos(t))),\n scale(minor, Math.sin(t)),\n );\n};\n\nexport const paramInEllipse = (e: EllipseGeom, t: number): boolean =>\n normAngle(t - e.startAngle) <= ellipseSweep(e) + 1e-12;\n\n/** Max chord deviation (mm) of ellipse tessellations from the true curve. */\nconst ELLIPSE_CHORD_TOLERANCE = 0.1;\n\n/**\n * Tessellate into points (both endpoints included). Parametric steps sized so\n * chord error stays under ~tolerance for the major radius.\n */\nexport const tessellateEllipse = (\n e: EllipseGeom,\n tolerance = ELLIPSE_CHORD_TOLERANCE,\n): Vec2[] => {\n const major = len(e.majorAxis);\n const sweep = ellipseSweep(e);\n const maxStep =\n major <= tolerance\n ? sweep\n : 2 * Math.acos(Math.max(-1, 1 - tolerance / major));\n const n = Math.max(8, Math.ceil(sweep / Math.max(maxStep, 1e-3)));\n const pts: Vec2[] = [];\n for (let i = 0; i <= n; i++) {\n pts.push(pointOnEllipse(e, e.startAngle + (sweep * i) / n));\n }\n return pts;\n};\n\n/**\n * Closest point on the ellipse curve to p — coarse parametric scan refined by\n * golden-section iterations. Good to well under render tolerance; exact\n * root-finding isn't worth it for snapping/hit-testing.\n */\nexport const closestPointOnEllipse = (e: EllipseGeom, p: Vec2): Vec2 => {\n const sweep = ellipseSweep(e);\n const SCAN = 64;\n let bestT = e.startAngle;\n let bestD = Infinity;\n for (let i = 0; i <= SCAN; i++) {\n const t = e.startAngle + (sweep * i) / SCAN;\n const d = distSq(p, pointOnEllipse(e, t));\n if (d < bestD) {\n bestD = d;\n bestT = t;\n }\n }\n // Refine around bestT.\n let lo = bestT - sweep / SCAN;\n let hi = bestT + sweep / SCAN;\n for (let i = 0; i < 24; i++) {\n const m1 = lo + (hi - lo) * 0.382;\n const m2 = lo + (hi - lo) * 0.618;\n if (distSq(p, pointOnEllipse(e, m1)) < distSq(p, pointOnEllipse(e, m2)))\n hi = m2;\n else lo = m1;\n }\n const t = (lo + hi) / 2;\n const clamped = paramInEllipse(e, t) ? t : bestT;\n return pointOnEllipse(e, clamped);\n};\n","// Axis-aligned bounding boxes in world mm.\n\nimport type { Vec2 } from \"./vec2\";\n\nexport interface AABB {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nexport const emptyBounds = (): AABB => ({\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n});\n\nexport const boundsOfPoints = (pts: Vec2[]): AABB => {\n const b = emptyBounds();\n for (const p of pts) {\n if (p.x < b.minX) b.minX = p.x;\n if (p.y < b.minY) b.minY = p.y;\n if (p.x > b.maxX) b.maxX = p.x;\n if (p.y > b.maxY) b.maxY = p.y;\n }\n return b;\n};\n\nexport const unionBounds = (a: AABB, b: AABB): AABB => ({\n minX: Math.min(a.minX, b.minX),\n minY: Math.min(a.minY, b.minY),\n maxX: Math.max(a.maxX, b.maxX),\n maxY: Math.max(a.maxY, b.maxY),\n});\n\nexport const addPointToBounds = (b: AABB, p: Vec2): void => {\n if (p.x < b.minX) b.minX = p.x;\n if (p.y < b.minY) b.minY = p.y;\n if (p.x > b.maxX) b.maxX = p.x;\n if (p.y > b.maxY) b.maxY = p.y;\n};\n\nexport const boundsIntersect = (a: AABB, b: AABB): boolean =>\n a.minX <= b.maxX && a.maxX >= b.minX && a.minY <= b.maxY && a.maxY >= b.minY;\n\nexport const boundsContainBounds = (outer: AABB, inner: AABB): boolean =>\n inner.minX >= outer.minX &&\n inner.maxX <= outer.maxX &&\n inner.minY >= outer.minY &&\n inner.maxY <= outer.maxY;\n\nexport const isEmptyBounds = (b: AABB): boolean =>\n b.minX > b.maxX || b.minY > b.maxY;\n\nexport const boundsCenter = (b: AABB): Vec2 => ({\n x: (b.minX + b.maxX) / 2,\n y: (b.minY + b.maxY) / 2,\n});\n\n/** AABB spanned by two arbitrary corner points. */\nexport const boundsOfCorners = (a: Vec2, b: Vec2): AABB => ({\n minX: Math.min(a.x, b.x),\n minY: Math.min(a.y, b.y),\n maxX: Math.max(a.x, b.x),\n maxY: Math.max(a.y, b.y),\n});\n","// Shared derived geometry for bulged vertex chains (polylines, hatch loops).\n\nimport type { Vec2 } from \"./vec2\";\nimport { angle, dist, dot, normAngle, sub } from \"./vec2\";\nimport type { Segment } from \"./line\";\nimport type { ArcGeom } from \"./arcs\";\nimport {\n arcSweep,\n bulgeFrom3Points,\n bulgeToArc,\n pointOnArc,\n tessellateArc,\n} from \"./arcs\";\n\n/**\n * A vertex of a bulged chain; bulge = tan(sweep/4), 0 = straight (DXF\n * LWPOLYLINE convention). Structurally compatible with the model's\n * zod-derived PolylineVertex — geometry stays model-free.\n */\nexport interface PolylineVertex {\n x: number;\n y: number;\n bulge: number;\n}\n\nexport interface Curves {\n segments: Segment[];\n arcs: ArcGeom[];\n}\n\n/** Exact curves (straight segments + analytic arcs) of a vertex chain. */\nexport const verticesToCurves = (\n vertices: PolylineVertex[],\n closed: boolean,\n): Curves => {\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n for (let i = 0; i < segCount; i++) {\n const va = vertices[i];\n const vb = vertices[(i + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n const arc = bulgeToArc(a, b, va.bulge);\n if (arc) arcs.push(arc);\n else segments.push({ a, b });\n }\n return { segments, arcs };\n};\n\n/** Tessellated closed polygon ring of a vertex chain (arc segments flattened). */\nexport const verticesToPolygon = (\n vertices: PolylineVertex[],\n chordTolerance = 0.1,\n): Vec2[] => {\n const ring: Vec2[] = [];\n const n = vertices.length;\n for (let i = 0; i < n; i++) {\n const va = vertices[i];\n const vb = vertices[(i + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n ring.push(a);\n const arc = bulgeToArc(a, b, va.bulge);\n if (arc) {\n const pts = tessellateArc(arc, chordTolerance);\n // pts includes endpoints; keep interior points in travel order (a → b).\n const interior = pts.slice(1, -1);\n if (va.bulge < 0) interior.reverse();\n ring.push(...interior);\n }\n }\n return ring;\n};\n\n/** Absolute area enclosed by a polygon ring (shoelace formula). */\nexport const polygonArea = (ring: Vec2[]): number => {\n let sum = 0;\n const n = ring.length;\n for (let i = 0; i < n; i++) {\n const p = ring[i];\n const q = ring[(i + 1) % n];\n sum += p.x * q.y - q.x * p.y;\n }\n return Math.abs(sum) / 2;\n};\n\n/** Length of a vertex chain in mm, bulge arcs exact; `closed` adds the\n * last → first segment. */\nexport const chainLength = (\n points: readonly { x: number; y: number; bulge: number }[],\n closed: boolean,\n): number => {\n let sum = 0;\n const n = closed ? points.length : points.length - 1;\n for (let i = 0; i < n; i++) {\n const a = points[i];\n const b = points[(i + 1) % points.length];\n const arc = bulgeToArc(a, b, a.bulge);\n sum += arc ? arc.radius * arcSweep(arc) : dist(a, b);\n }\n return sum;\n};\n\n/** Area enclosed by a closed polyline (bulge-aware via tessellation). */\nexport const polylineArea = (points: PolylineVertex[]): number =>\n polygonArea(verticesToPolygon(points));\n\n/** Net hatch area: outer loop minus holes (even-odd). */\nexport const hatchArea = (loops: { points: PolylineVertex[] }[]): number => {\n const areas = loops.map((l) => polygonArea(verticesToPolygon(l.points)));\n if (areas.length === 0) return 0;\n const holes = areas.slice(1).reduce((a, b) => a + b, 0);\n return Math.max(areas[0] - holes, 0);\n};\n\n// ---------------------------------------------------------------------------\n// Chain editing (grip editing, add/remove vertex). All functions are pure and\n// return the input array unchanged (same reference) on out-of-range indices.\n// ---------------------------------------------------------------------------\n\n/** Clamp a bulge to the sane editing range: snap |b| < 0.02 to straight, cap ±4. */\nexport const clampBulge = (b: number): number => {\n if (!Number.isFinite(b) || Math.abs(b) < 0.02) return 0;\n return Math.max(-4, Math.min(4, b));\n};\n\n/** Both endpoints of segment segIndex moved by delta; every bulge is kept, so\n * the segment's own arc translates rigidly while its neighbors reshape. */\nexport const translateChainSegment = (\n vertices: PolylineVertex[],\n closed: boolean,\n segIndex: number,\n delta: Vec2,\n): PolylineVertex[] => {\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n if (segIndex < 0 || segIndex >= segCount) return vertices;\n const j = (segIndex + 1) % n;\n return vertices.map((v, i) =>\n i === segIndex || i === j\n ? { ...v, x: v.x + delta.x, y: v.y + delta.y }\n : v,\n );\n};\n\n/**\n * Insert a vertex on segment segIndex at (the projection of) p; the new\n * vertex lands at index segIndex + 1. A bulged segment splits by sweep\n * fraction so both halves reconstruct the original circle (bulge = tan of a\n * quarter of each half's signed sweep); straight segments stay straight.\n * No-op when p coincides with an endpoint.\n */\nexport const insertChainVertex = (\n vertices: PolylineVertex[],\n closed: boolean,\n segIndex: number,\n p: Vec2,\n): PolylineVertex[] => {\n const n = vertices.length;\n const segCount = closed ? n : n - 1;\n if (segIndex < 0 || segIndex >= segCount) return vertices;\n const va = vertices[segIndex];\n const vb = vertices[(segIndex + 1) % n];\n const a = { x: va.x, y: va.y };\n const b = { x: vb.x, y: vb.y };\n if (dist(p, a) < 1e-9 || dist(p, b) < 1e-9) return vertices;\n const arc = bulgeToArc(a, b, va.bulge);\n let pos: Vec2;\n let bulgeA: number;\n let bulgeB: number;\n if (arc) {\n // Travel fraction t of p's angular projection. ArcGeom is normalized\n // CCW, so for a negative bulge travel a→b runs from endAngle backwards.\n const sweep = arcSweep(arc);\n const ang = angle(sub(p, arc.center));\n const from =\n va.bulge > 0\n ? normAngle(ang - arc.startAngle)\n : normAngle(arc.endAngle - ang);\n let t = from / sweep;\n if (!Number.isFinite(t)) t = 0.5;\n t = Math.min(0.99, Math.max(0.01, t));\n const theta = 4 * Math.atan(va.bulge); // signed total sweep\n bulgeA = Math.tan((t * theta) / 4);\n bulgeB = Math.tan(((1 - t) * theta) / 4);\n pos = pointOnArc(\n arc,\n va.bulge > 0 ? arc.startAngle + t * sweep : arc.endAngle - t * sweep,\n );\n } else {\n const ab = sub(b, a);\n const l2 = dot(ab, ab);\n let t = l2 < 1e-18 ? 0.5 : dot(sub(p, a), ab) / l2;\n t = Math.min(0.99, Math.max(0.01, t));\n pos = { x: a.x + ab.x * t, y: a.y + ab.y * t };\n bulgeA = 0;\n bulgeB = 0;\n }\n const out = vertices.slice();\n out[segIndex] = { ...va, bulge: bulgeA };\n out.splice(segIndex + 1, 0, { x: pos.x, y: pos.y, bulge: bulgeB });\n return out;\n};\n\n/**\n * Remove vertex i, merging its two adjacent segments. Two straight segments\n * merging stay straight (removing a corner shouldn't invent an arc); anything\n * arced re-solves through the removed vertex to roughly preserve the shape.\n * Open-chain endpoints just drop (the adjoining segment disappears).\n * Returns null at the minimum vertex count (open: 2, closed: 3).\n */\nexport const removeChainVertex = (\n vertices: PolylineVertex[],\n closed: boolean,\n i: number,\n): PolylineVertex[] | null => {\n const n = vertices.length;\n if (i < 0 || i >= n) return null;\n if (n <= (closed ? 3 : 2)) return null;\n const out = vertices.slice();\n if (!closed && (i === 0 || i === n - 1)) {\n out.splice(i, 1);\n // Zero the new last vertex's (unused) bulge so closing the chain later\n // doesn't resurrect a stale arc.\n if (i === n - 1) out[out.length - 1] = { ...out[out.length - 1], bulge: 0 };\n return out;\n }\n const j = (i - 1 + n) % n;\n const prev = vertices[j];\n const removed = vertices[i];\n const next = vertices[(i + 1) % n];\n const merged =\n Math.abs(prev.bulge) < 1e-12 && Math.abs(removed.bulge) < 1e-12\n ? 0\n : clampBulge(\n bulgeFrom3Points(\n { x: prev.x, y: prev.y },\n { x: removed.x, y: removed.y },\n { x: next.x, y: next.y },\n ),\n );\n out[j] = { ...prev, bulge: merged };\n out.splice(i, 1);\n return out;\n};\n\n/**\n * Insert a coincident copy right after vertex i. The copy takes over the\n * outgoing segment's bulge (the zero-length lead-in stays straight), so the\n * geometry is unchanged until the copy is dragged apart.\n */\nexport const duplicateChainVertex = (\n vertices: PolylineVertex[],\n i: number,\n): PolylineVertex[] => {\n const n = vertices.length;\n if (i < 0 || i >= n) return vertices;\n const out = vertices.slice();\n out[i] = { ...vertices[i], bulge: 0 };\n out.splice(i + 1, 0, { ...vertices[i] });\n return out;\n};\n\n/** Even-odd point-in-polygon over multiple rings. */\nexport const pointInRings = (rings: Vec2[][], p: Vec2): boolean => {\n let inside = false;\n for (const ring of rings) {\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n const a = ring[i];\n const b = ring[j];\n if (\n a.y > p.y !== b.y > p.y &&\n p.x < ((b.x - a.x) * (p.y - a.y)) / (b.y - a.y) + a.x\n ) {\n inside = !inside;\n }\n }\n }\n return inside;\n};\n","// GeometrySink — the abstract drawing surface every object painter targets.\n// Painters are written ONCE against this interface and retargeted to:\n// - CanvasSink (screen rendering, src/canvas/canvasSink.ts)\n// - PdfSink (vector PDF export, Phase 4)\n// - DXF entity writers (dimension/leader explosion, Phase 5)\n\nimport type { Vec2 } from \"../geometry/vec2\";\n\nexport interface StrokeStyle {\n color: string;\n /**\n * Lineweight in OUTPUT units (paper mm). Never scaled by the world\n * transform — each sink decides how to realize it (canvas clamps to a\n * screen-px range, PDF uses it verbatim).\n */\n widthMm: number;\n dashMm?: number[];\n /** Paint opacity 0..1 (undefined = opaque). */\n opacity?: number;\n}\n\nexport interface FillStyle {\n color: string;\n /** Paint opacity 0..1 (undefined = opaque). */\n opacity?: number;\n /** Gradient fill (undefined = flat fill), in world/sheet coordinates —\n * the same space as the path. linear: `color` at `from` → `color2` at\n * `to`. radial: `color` at `from` (the center) → `color2` at radius\n * |to − from|. */\n gradient?: {\n shape: \"linear\" | \"radial\";\n from: Vec2;\n to: Vec2;\n color2: string;\n };\n}\n\nexport interface TextSpec {\n text: string;\n anchor: Vec2;\n /** Cap height in current drawing units (world mm before transforms). */\n heightMm: number;\n /** Radians CCW. */\n rotation: number;\n hAlign: \"left\" | \"center\" | \"right\";\n vAlign: \"bottom\" | \"center\" | \"top\";\n color: string;\n /** Font id (model/fonts.ts); absent = default font. */\n font?: string;\n /** Horizontal glyph scale (AutoCAD width factor); absent = 1. */\n widthFactor?: number;\n /** Paint opacity 0..1 (undefined = opaque). */\n opacity?: number;\n}\n\n/** A placed raster image (PNG/JPEG data URL). */\nexport interface ImageSpec {\n /** data: URL with the encoded pixels. */\n data: string;\n /** Bottom-left corner in current drawing units (world/sheet mm). */\n origin: Vec2;\n widthMm: number;\n heightMm: number;\n /** Radians CCW about `origin`. */\n rotation: number;\n /** 0..1. */\n opacity: number;\n}\n\n/** Affine transform [a, b, c, d, e, f]: x' = a·x + c·y + e, y' = b·x + d·y + f. */\nexport type Mat2x3 = [number, number, number, number, number, number];\n\nexport interface Rect {\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\nexport interface GeometrySink {\n beginPath(): void;\n moveTo(p: Vec2): void;\n lineTo(p: Vec2): void;\n bezierTo(c1: Vec2, c2: Vec2, end: Vec2): void;\n /** Circular arc from startAngle to endAngle; ccw = increasing angle (world CCW). */\n arc(\n center: Vec2,\n r: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean,\n ): void;\n ellipse(\n center: Vec2,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ): void;\n closePath(): void;\n stroke(s: StrokeStyle): void;\n fill(f: FillStyle): void;\n text(t: TextSpec): void;\n /** Draw a raster image (decoding is the sink's concern). */\n image(i: ImageSpec): void;\n /** Advance width; implementations must honor font + widthFactor. */\n measureText(\n text: string,\n heightMm: number,\n font?: string,\n widthFactor?: number,\n ): { width: number };\n pushTransform(m: Mat2x3): void;\n popTransform(): void;\n pushClipRect(r: Rect): void;\n popClip(): void;\n /**\n * Optional structure hooks bracketing ONE model object's output. Sinks\n * with structured output (SVG) group + annotate the elements; raster/PDF\n * sinks omit them. Paint loops call them via optional chaining.\n */\n beginObject?(id: string, layer?: string): void;\n endObject?(): void;\n}\n\n// ---------------------------------------------------------------------------\n// Matrix helpers\n// ---------------------------------------------------------------------------\n\nexport const matIdentity: Mat2x3 = [1, 0, 0, 1, 0, 0];\n\nexport const matMultiply = (m: Mat2x3, n: Mat2x3): Mat2x3 => [\n m[0] * n[0] + m[2] * n[1],\n m[1] * n[0] + m[3] * n[1],\n m[0] * n[2] + m[2] * n[3],\n m[1] * n[2] + m[3] * n[3],\n m[0] * n[4] + m[2] * n[5] + m[4],\n m[1] * n[4] + m[3] * n[5] + m[5],\n];\n\nexport const matApply = (m: Mat2x3, p: Vec2): Vec2 => ({\n x: m[0] * p.x + m[2] * p.y + m[4],\n y: m[1] * p.x + m[3] * p.y + m[5],\n});\n\n// ---------------------------------------------------------------------------\n// Curve → bezier decomposition (used by non-canvas sinks)\n// ---------------------------------------------------------------------------\n\nexport interface CubicBezier {\n start: Vec2;\n c1: Vec2;\n c2: Vec2;\n end: Vec2;\n}\n\n/**\n * Signed sweep from startAngle to endAngle in the requested direction —\n * positive for ccw (increasing angle), negative for cw. Angles come from\n * atan2 ∈ (−π, π], so a raw `end − start` flips arcs that cross the ±π seam;\n * this normalizes into (0, 2π] / [−2π, 0), treating equal angles as a full\n * circle.\n */\nexport const signedArcSweep = (\n startAngle: number,\n endAngle: number,\n ccw: boolean,\n): number => {\n const TAU = Math.PI * 2;\n let sweep = ccw\n ? (((endAngle - startAngle) % TAU) + TAU) % TAU\n : -((((startAngle - endAngle) % TAU) + TAU) % TAU);\n if (sweep === 0) sweep = ccw ? TAU : -TAU;\n return sweep;\n};\n\n/**\n * Decompose a circular arc (CCW from startAngle over `sweep` > 0) into cubic\n * beziers with ≤90° segments (standard k = 4/3·tan(θ/4) approximation).\n */\nexport const arcToBeziers = (\n center: Vec2,\n r: number,\n startAngle: number,\n sweep: number,\n): CubicBezier[] => {\n const n = Math.max(1, Math.ceil(Math.abs(sweep) / (Math.PI / 2)));\n const step = sweep / n;\n const k = (4 / 3) * Math.tan(step / 4);\n const result: CubicBezier[] = [];\n for (let i = 0; i < n; i++) {\n const a0 = startAngle + step * i;\n const a1 = a0 + step;\n const p0 = {\n x: center.x + r * Math.cos(a0),\n y: center.y + r * Math.sin(a0),\n };\n const p1 = {\n x: center.x + r * Math.cos(a1),\n y: center.y + r * Math.sin(a1),\n };\n result.push({\n start: p0,\n c1: { x: p0.x - r * k * Math.sin(a0), y: p0.y + r * k * Math.cos(a0) },\n c2: { x: p1.x + r * k * Math.sin(a1), y: p1.y - r * k * Math.cos(a1) },\n end: p1,\n });\n }\n return result;\n};\n\n// ---------------------------------------------------------------------------\n// Hatch pattern generation (shared by canvas, PDF, and DXF outputs)\n// ---------------------------------------------------------------------------\n\n/** v-extent (perpendicular range) of the rings, or null if empty. */\nconst vExtent = (\n rings: Vec2[][],\n v: Vec2,\n): { min: number; max: number } | null => {\n let min = Infinity;\n let max = -Infinity;\n for (const ring of rings) {\n for (const p of ring) {\n const dv = p.x * v.x + p.y * v.y;\n if (dv < min) min = dv;\n if (dv > max) max = dv;\n }\n }\n return Number.isFinite(min) ? { min, max } : null;\n};\n\n/**\n * u-coordinates (sorted) where the scanline at perpendicular offset `off`\n * crosses the ring edges. Consecutive pairs bound the even-odd interior.\n */\nconst scanlineCrossings = (\n rings: Vec2[][],\n u: Vec2,\n v: Vec2,\n off: number,\n): number[] => {\n const crossings: number[] = [];\n for (const ring of rings) {\n for (let i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n const a = ring[j];\n const b = ring[i];\n const va = a.x * v.x + a.y * v.y;\n const vb = b.x * v.x + b.y * v.y;\n // Half-open interval avoids double-counting shared vertices.\n if (va < off === vb < off) continue;\n const t = (off - va) / (vb - va);\n const px = a.x + (b.x - a.x) * t;\n const py = a.y + (b.y - a.y) * t;\n crossings.push(px * u.x + py * u.y);\n }\n }\n crossings.sort((x, y) => x - y);\n return crossings;\n};\n\n/**\n * Parallel pattern lines at `angle` spaced `spacing` apart (anchored at the\n * world origin), clipped to the even-odd interior of the tessellated rings.\n * Pure geometry — every output target strokes the same segments. This is the\n * simple single-family \"lines\" fill; pattern fills use computeHatchFamily.\n */\nexport const computeHatchLines = (\n rings: Vec2[][],\n angle: number,\n spacing: number,\n): { a: Vec2; b: Vec2 }[] =>\n spacing <= 0\n ? []\n : computeHatchFamily(rings, {\n angle,\n origin: { x: 0, y: 0 },\n deltaAlong: 0,\n deltaPerp: spacing,\n });\n\nexport interface HatchLineFamily {\n /** Line direction, radians CCW (the fill's rotation already folded in). */\n angle: number;\n /**\n * Anchor point of the family in world coords (the .pat origin, with the\n * fill's rotation + scale already folded in). Its perpendicular component\n * phases the parallel lines; its along-line component phases the dashes.\n */\n origin: Vec2;\n /**\n * Signed shift ALONG the line between successive lines (the .pat delta-x,\n * scaled). Only shifts dash phase per line — no effect on solid families.\n */\n deltaAlong: number;\n /**\n * Signed PERPENDICULAR step between successive lines (the .pat delta-y,\n * scaled). Must be non-zero.\n */\n deltaPerp: number;\n /**\n * Along-line dash cycle, world mm: >0 pen-down, <0 gap, 0 dot. Solid line\n * when omitted/empty. Already scaled by the caller.\n */\n dashesMm?: number[];\n}\n\n/** A tiny mark stroked for a zero-length (dot) dash so it stays visible. */\nconst DOT_LENGTH_MM = 0.35;\n\n/**\n * Split a solid segment (a→b, in the +`u` direction) into its drawn dash\n * sub-segments. The dash cycle's phase-zero sits at along-coordinate `along0`\n * (the family line's anchor), so dashes stay in register line-to-line.\n */\nconst splitByDashes = (\n a: Vec2,\n b: Vec2,\n u: Vec2,\n dashes: number[],\n along0: number,\n out: { a: Vec2; b: Vec2 }[],\n): void => {\n const len = (b.x - a.x) * u.x + (b.y - a.y) * u.y;\n if (len <= 1e-9) return;\n const cycle = dashes.reduce((s, d) => s + Math.abs(d), 0);\n if (cycle <= 1e-9) {\n out.push({ a, b });\n return;\n }\n const pt = (d: number): Vec2 => ({ x: a.x + u.x * d, y: a.y + u.y * d });\n // Phase of `a` within the cycle, measured from the family anchor `along0`.\n const base = a.x * u.x + a.y * u.y - along0;\n let phase = ((base % cycle) + cycle) % cycle;\n let idx = 0;\n for (; idx < dashes.length; idx++) {\n const w = Math.abs(dashes[idx]);\n if (phase < w || w <= 1e-9) break;\n phase -= w;\n }\n if (idx >= dashes.length) {\n idx = 0;\n phase = 0;\n }\n let remaining = Math.max(0, Math.abs(dashes[idx]) - phase);\n let pos = 0;\n let guard = 0;\n while (pos < len - 1e-9 && guard++ < 100000) {\n const w = Math.abs(dashes[idx]);\n const draw = dashes[idx] >= 0;\n if (w <= 1e-9) {\n // Dot: emit a short mark centered on `pos`, then advance to the next\n // element (the following gap) without consuming length.\n if (draw) {\n const s0 = Math.max(0, pos - DOT_LENGTH_MM / 2);\n const s1 = Math.min(len, pos + DOT_LENGTH_MM / 2);\n if (s1 > s0) out.push({ a: pt(s0), b: pt(s1) });\n }\n idx = (idx + 1) % dashes.length;\n remaining = Math.abs(dashes[idx]);\n continue;\n }\n const step = Math.min(remaining, len - pos);\n if (draw) out.push({ a: pt(pos), b: pt(pos + step) });\n pos += step;\n remaining -= step;\n if (remaining <= 1e-9) {\n idx = (idx + 1) % dashes.length;\n remaining = Math.abs(dashes[idx]);\n }\n }\n};\n\n/**\n * One family of a hatch pattern: parallel (optionally dashed) lines stepped by\n * `(deltaAlong, deltaPerp)` from `origin`, clipped to the even-odd interior of\n * the rings. Unlike computeHatchLines this honors the family origin (line\n * phase) and delta-x (per-line dash phase), which is what makes multi-family\n * patterns (ANSI32's paired lines, brick/earth offsets) render correctly.\n */\nexport const computeHatchFamily = (\n rings: Vec2[][],\n family: HatchLineFamily,\n): { a: Vec2; b: Vec2 }[] => {\n const { deltaPerp } = family;\n if (rings.length === 0 || Math.abs(deltaPerp) <= 1e-9) return [];\n const u = { x: Math.cos(family.angle), y: Math.sin(family.angle) };\n const v = { x: -u.y, y: u.x };\n const ext = vExtent(rings, v);\n if (!ext) return [];\n\n const oV = family.origin.x * v.x + family.origin.y * v.y;\n const oU = family.origin.x * u.x + family.origin.y * u.y;\n // Contiguous integer line indices whose perpendicular offset (oV + i·dPerp)\n // lands in [min, max] — the min/max form handles either sign of deltaPerp.\n const iA = (ext.min - oV) / deltaPerp;\n const iB = (ext.max - oV) / deltaPerp;\n const iLo = Math.ceil(Math.min(iA, iB));\n const iHi = Math.floor(Math.max(iA, iB));\n const dashes =\n family.dashesMm && family.dashesMm.length ? family.dashesMm : null;\n\n const out: { a: Vec2; b: Vec2 }[] = [];\n for (let i = iLo; i <= iHi; i++) {\n const off = oV + i * deltaPerp;\n const along0 = oU + i * family.deltaAlong; // dash-phase anchor for this line\n const crossings = scanlineCrossings(rings, u, v, off);\n for (let k = 0; k + 1 < crossings.length; k += 2) {\n const c0 = crossings[k];\n const c1 = crossings[k + 1];\n if (c1 - c0 < 1e-9) continue;\n const a = { x: u.x * c0 + v.x * off, y: u.y * c0 + v.y * off };\n const b = { x: u.x * c1 + v.x * off, y: u.y * c1 + v.y * off };\n if (dashes) splitByDashes(a, b, u, dashes, along0, out);\n else out.push({ a, b });\n }\n }\n return out;\n};\n\n/** Same decomposition for an elliptical arc (rx/ry with axis rotation). */\nexport const ellipseArcToBeziers = (\n center: Vec2,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n sweep: number,\n): CubicBezier[] => {\n const cosR = Math.cos(rotation);\n const sinR = Math.sin(rotation);\n const map = (p: Vec2): Vec2 => ({\n x: center.x + p.x * cosR - p.y * sinR,\n y: center.y + p.x * sinR + p.y * cosR,\n });\n return arcToBeziers({ x: 0, y: 0 }, 1, startAngle, sweep).map((b) => ({\n start: map({ x: b.start.x * rx, y: b.start.y * ry }),\n c1: map({ x: b.c1.x * rx, y: b.c1.y * ry }),\n c2: map({ x: b.c2.x * rx, y: b.c2.y * ry }),\n end: map({ x: b.end.x * rx, y: b.end.y * ry }),\n }));\n};\n","// GENERATED — do not edit. Mirror of builtin.pat (the built-in hatch\n// pattern library, lengths in mm). Regenerate with:\n// npm run gen:patterns -w @lineadraw/core\n\nexport const BUILTIN_PAT = `;; Linea built-in hatch pattern library.\n;;\n;; Format: .pat syntax - a \\`*NAME,description\\` header followed by one line\n;; family per row: \\`angle, x-origin, y-origin, delta-x, delta-y [, dash...]\\`\n;; (angle in degrees CCW; delta-x shifts successive lines along their own\n;; direction - dash phase - and delta-y is the perpendicular spacing;\n;; dashes: >0 pen-down, <0 gap, 0 dot). All lengths are millimeters (ISO\n;; scaling).\n;;\n;; The pattern geometry is functional interchange data, kept name- and\n;; value-compatible with the predefined DXF HATCH patterns other CAD\n;; applications resolve - ANSI/ISO/JIS/GOST section conventions plus common\n;; architectural textures. Descriptions and organization are Linea's\n;; own. There is no SOLID entry: solid fill is its own fill kind, not a\n;; line-family pattern.\n;;\n;; After editing, regenerate the embedded TS mirror:\n;; npm run gen:patterns -w @lineadraw/core\n;;\n\n;; Material and texture patterns.\n\n*ANGLE,Steel angle framing\n0, 0, 0, 0, 6.985, 5.08, -1.905\n90, 0, 0, 0, 6.985, 5.08, -1.905\n*ANSI31,Cast iron; general section (ANSI)\n45, 0, 0, 0, 3.175\n*ANSI32,Steel (ANSI)\n45, 0, 0, 0, 9.525\n45, 4.49013, 0, 0, 9.525\n*ANSI33,Bronze, brass, copper (ANSI)\n45, 0, 0, 0, 6.35\n45, 4.49013, 0, 0, 6.35, 3.175, -1.5875\n*ANSI34,Plastic, rubber (ANSI)\n45, 0, 0, 0, 19.05\n45, 4.49013, 0, 0, 19.05\n45, 8.98026, 0, 0, 19.05\n45, 13.4704, 0, 0, 19.05\n*ANSI35,Fire brick, refractory (ANSI)\n45, 0, 0, 0, 6.35\n45, 4.49013, 0, 0, 6.35, 7.9375, -1.5875, 0, -1.5875\n*ANSI36,Marble, slate, glass (ANSI)\n45, 0, 0, 5.55625, 3.175, 7.9375, -1.5875, 0, -1.5875\n*ANSI37,Lead, zinc, insulation (ANSI)\n45, 0, 0, 0, 3.175\n135, 0, 0, 0, 3.175\n*ANSI38,Aluminum (ANSI)\n45, 0, 0, 0, 3.175\n135, 0, 0, 6.35, 3.175, 7.9375, -4.7625\n*AR-B816,Block wall 8x16, running bond\n0, 0, 0, 0, 203.2\n90, 0, 0, 203.2, 203.2, 203.2, -203.2\n*AR-B816C,Block wall 8x16 with mortar joints\n0, 0, 0, 203.2, 203.2, 396.875, -9.525\n0, -203.2, 9.525, 203.2, 203.2, 396.875, -9.525\n90, 0, 0, 203.2, 203.2, -212.725, 193.675\n90, -9.525, 0, 203.2, 203.2, -212.725, 193.675\n*AR-B88,Block wall 8x8, running bond\n0, 0, 0, 0, 203.2\n90, 0, 0, 203.2, 101.6, 203.2, -203.2\n*AR-BRELM,Brick wall, English bond, mortar joints\n0, 0, 0, 0, 135.484, 193.675, -9.525\n0, 0, 57.15, 0, 135.484, 193.675, -9.525\n0, 50.8, 67.7418, 0, 135.484, 92.075, -9.525\n0, 50.8, 124.892, 0, 135.484, 92.075, -9.525\n90, 0, 0, 0, 203.2, 57.15, -78.334\n90, -9.525, 0, 0, 203.2, 57.15, -78.334\n90, 50.8, 67.7418, 0, 101.6, 57.15, -78.334\n90, 41.275, 67.7418, 0, 101.6, 57.15, -78.334\n*AR-BRSTD,Brick wall, running bond\n0, 0, 0, 0, 67.7418\n90, 0, 0, 67.7418, 101.6, 67.7418, -67.7418\n*AR-CONC,Concrete, random aggregate\n50, 0, 0, 104.896, -149.807, 19.05, -209.55\n355, 0, 0, -51.76101082,187.25814969, 15.24, -167.64058417\n100.4514447,15.182007,-1.3282535,145.5569059,-176.270089,16.1900088,-178.0902446\n46.1842, 0, 50.8, 157.343, -224.71, 28.575, -314.325\n96.63555761,22.5899,47.2965,218.33577212,-264.40480444,24.28502314,-267.13560816\n351.18415117,0,50.8,196.67912063,280.88740361,22.85996707,-251.45973192\n21, 25.4, 38.1, 104.89565868, -149.80652586, 19.05, -209.55\n326, 25.4, 38.1, -51.7604, 187.258, 15.24, -167.64\n71.451445,38.0345326,29.5779001,145.5567546,-176.2700748,16.1900088,-178.0899376\n37.5, 0, 0, 53.9242, 65.2018, 0, -165.608, 0, -170.18, 0, -168.275\n7.5, 0, 0, 79.3242, 90.6018, 0, -97.028, 0, -161.798, 0, -64.135\n-32.5, -56.642, 0, 117.434, 68.0212, 0, -63.5, 0, -198.12, 0, -262.89\n-42.5, -82.042, 0, 92.0344, 118.821, 0, -82.55, 0, -131.572, 0, -186.69\n*AR-HBONE,Brick paving, herringbone at 45 deg\n45, 0, 0, 101.6, 101.6, 304.8, -101.6\n135, 71.842, 71.842, 101.6, -101.6, 304.8, -101.6\n*AR-PARQ1,Parquet flooring, basket weave\n90, 0, 0, 304.8, 304.8, 304.8, -304.8\n90, 50.8, 0, 304.8, 304.8, 304.8, -304.8\n90, 101.6, 0, 304.8, 304.8, 304.8, -304.8\n90, 152.4, 0, 304.8, 304.8, 304.8, -304.8\n90, 203.2, 0, 304.8, 304.8, 304.8, -304.8\n90, 254, 0, 304.8, 304.8, 304.8, -304.8\n90, 304.8, 0, 304.8, 304.8, 304.8, -304.8\n0, 0, 304.8, 304.8, -304.8, 304.8, -304.8\n0, 0, 355.6, 304.8, -304.8, 304.8, -304.8\n0, 0, 406.4, 304.8, -304.8, 304.8, -304.8\n0, 0, 457.2, 304.8, -304.8, 304.8, -304.8\n0, 0, 508, 304.8, -304.8, 304.8, -304.8\n0, 0, 558.8, 304.8, -304.8, 304.8, -304.8\n0, 0, 609.6, 304.8, -304.8, 304.8, -304.8\n*AR-RROOF,Roof shingles\n0, 0, 0, 55.88, 25.4, 381, -50.8, 127, -25.4\n0, 33.782, 12.7, -25.4, 33.782, 76.2, -8.382, 152.4, -19.05\n0, 12.7, 21.59, 132.08, 17.018, 203.2, -35.56, 101.6, -25.4\n*AR-RSHKE,Roof wood shakes\n0, 0, 0, 647.7, 304.8, 152.4, -127, 177.8, -76.2, 228.6, -101.6\n0, 152.4, 12.7, 647.7, 304.8, 127, -482.6, 101.6, -152.4\n0, 457.2, -19.05, 647.7, 304.8, 76.2, -787.4\n90, 0, 0, 304.8, 215.9, 292.1, -927.1\n90, 152.4, 0, 304.8, 215.9, 285.75, -933.45\n90, 279.4, 0, 304.8, 215.9, 266.7, -952.5\n90, 457.2, -19.05, 304.8, 215.9, 292.1, -927.1\n90, 533.4, -19.05, 304.8, 215.9, 292.1, -927.1\n90, 762, 0, 304.8, 215.9, 279.4, -939.8\n*AR-SAND,Sand stipple\n37.5, 0, 0, 28.5242, 39.8018, 0, -38.608, 0, -43.18, 0, -41.275\n7.5, 0, 0, 53.9242, 65.2018, 0, -20.828, 0, -34.798, 0, -13.335\n-32.5, -31.242, 0, 66.6344, 42.6212, 0, -12.7, 0, -45.72, 0, -59.69\n-42.5, -31.242, 0, 41.2344, 68.0212, 0, -6.35, 0, -29.972, 0, -34.29\n*BOX,Interlocking box weave\n90, 0, 0, 0, 25.4\n90, 6.35, 0, 0, 25.4\n0, 0, 0, 0, 25.4, -6.35, 6.35\n0, 0, 6.35, 0, 25.4, -6.35, 6.35\n0, 0, 12.7, 0, 25.4, 6.35, -6.35\n0, 0, 19.05, 0, 25.4, 6.35, -6.35\n90, 12.7, 0, 0, 25.4, 6.35, -6.35\n90, 19.05, 0, 0, 25.4, 6.35, -6.35\n*BRASS,Brass\n0, 0, 0, 0, 6.35\n0, 0, 3.175, 0, 6.35, 3.175, -1.5875\n*BRICK,Brick coursing\n0, 0, 0, 0, 6.35\n90, 0, 0, 0, 12.7, 6.35, -6.35\n90, 6.35, 0, 0, 12.7, -6.35, 6.35\n*BRSTONE,Brick and stone mix\n0, 0, 0, 0, 8.382\n90, 22.86, 0, 8.382, 12.7, 8.382, -8.382\n90, 20.32, 0, 8.382, 12.7, 8.382, -8.382\n0, 22.86, 1.397, 12.7, 8.382, -22.86, 2.54\n0, 22.86, 2.794, 12.7, 8.382, -22.86, 2.54\n0, 22.86, 4.191, 12.7, 8.382, -22.86, 2.54\n0, 22.86, 5.588, 12.7, 8.382, -22.86, 2.54\n0, 22.86, 6.985, 12.7, 8.382, -22.86, 2.54\n*CLAY,Clay\n0, 0, 0, 0, 4.7625\n0, 0, 0.79375, 0, 4.7625\n0, 0, 1.5875, 0, 4.7625\n0, 0, 3.175, 0, 4.7625, 4.7625, -3.175\n*CORK,Cork\n0, 0, 0, 0, 3.175\n135, 1.5875, -1.5875, 0, 8.98026, 4.49013, -4.49013\n135, 2.38125, -1.5875, 0, 8.98026, 4.49013, -4.49013\n135, 3.175, -1.5875, 0, 8.98026, 4.49013, -4.49013\n*CROSS,Cross tiling\n0, 0, 0, 6.35, 6.35, 3.175, -9.525\n90, 1.5875, -1.5875, 6.35, 6.35, 3.175, -9.525\n*DASH,Staggered dashes\n0, 0, 0, 3.175, 3.175, 3.175, -3.175\n*DOLMIT,Layered rock (dolomite)\n0, 0, 0, 0, 6.35\n45, 0, 0, 0, 17.9605,8.98025612106915355989072339,-17.9605122421383071197814467\n*DOTS,Dot screen\n0, 0, 0, 0.79375, 1.5875, 0, -1.5875\n*EARTH,Earth (section)\n0, 0, 0, 6.35, 6.35, 6.35, -6.35\n0, 0, 2.38125, 6.35, 6.35, 6.35, -6.35\n0, 0, 4.7625, 6.35, 6.35, 6.35, -6.35\n90, 0.79375, 5.55625, 6.35, 6.35, 6.35, -6.35\n90, 3.175, 5.55625, 6.35, 6.35, 6.35, -6.35\n90, 5.55625, 5.55625, 6.35, 6.35, 6.35, -6.35\n*ESCHER,Isometric cube tiling\n60, 0, 0, -15.24, 26.3964542936, 27.94, -2.54\n180, 0, 0, -15.24, 26.3964542936, 27.94, -2.54\n300, 0, 0, 15.24, 26.3964542936, 27.94, -2.54\n60, 2.54, 0, -15.24, 26.3964542936, 5.08, -25.4\n300, 2.54, 0, 15.24, 26.3964542936, 5.08, -25.4\n60, -1.27, 2.199704516, -15.24, 26.3964542936, 5.08, -25.4\n180, -1.27, 2.199704516, -15.24, 26.3964542936, 5.08, -25.4\n300, -1.27, -2.199704516, 15.24, 26.3964542936, 5.08, -25.4\n180, -1.27, -2.199704516, -15.24, 26.3964542936, 5.08, -25.4\n60, -10.16, 0, -15.24, 26.3964542936, 5.08, -25.4\n300, -10.16, 0, 15.24, 26.3964542936, 5.08, -25.4\n60, 5.08, -8.7988180894, -15.24, 26.3964542936, 5.08, -25.4\n180, 5.08, -8.7988180894, -15.24, 26.3964542936, 5.08, -25.4\n300, 5.08, 8.7988180894, 15.24, 26.3964542936, 5.08, -25.4\n180, 5.08, 8.7988180894, -15.24, 26.3964542936, 5.08, -25.4\n0, 5.08, 4.3994090574, -15.24, 26.3964542936, 17.78, -12.7\n0, 5.08, -4.3994090574, -15.24, 26.3964542936, 17.78, -12.7\n120, 1.27, 6.5991135734, 15.24, 26.3964542936, 17.78, -12.7\n120, -6.35, 2.199704516, 15.24, 26.3964542936, 17.78, -12.7\n240, -6.35, -2.199704516, 15.24, 26.3964542936, 17.78, -12.7\n240, 1.27, -6.5991135734, 15.24, 26.3964542936, 17.78, -12.7\n*FLEX,Flexible material\n0, 0, 0, 0, 6.35, 6.35, -6.35\n45,6.35,0,4.490128053,4.490128053,1.5875,-5.8052561314,1.5875,-8.9802561314\n*GOST_GLASS,Glass (GOST)\n45, 0, 0, 6, -6, 5, -7\n45, 2.121320, 0, 6, -6, 2, -10\n45, 0, 2.121320, 6, -6, 2, -10\n*GOST_GROUND,Ground (GOST)\n45, 0, 0, 10, -10, 20\n45, 3, 0, 10, -10, 20\n45, 6, 0, 10, -10, 20\n*GOST_WOOD,Wood (GOST)\n90, 0, 0, 0, -6, 10, -2\n90, 2, -2, 0, -6, 6, -1.5, 3, -1.5\n90, 4, -5, 0, -6, 10, -2\n*GRASS,Grass\n90, 0, 0, 17.96051224, 17.96051224, 4.7625, -31.15852448\n45, 0, 0, 0, 25.4, 4.7625, -20.6375\n135, 0, 0, 0, 25.4, 4.7625, -20.6375\n*GRATE,Grating\n0, 0, 0, 0, 0.79375\n90, 0, 0, 0, 3.175\n*GRAVEL,Gravel, random cobbles\n228.0127875,18.288,25.4,305.85067529778,1.88796713245,3.4172144,-338.30483639565\n184.969741,16.002,22.86,-305.8545235377,1.10019612724,5.8640472,-580.54048893524\n132.5104471,10.16,22.352,-377.59492241548,1.56030959675,4.1348152,-409.347227941\n267.273689,.254,16.002,-508.63316875916,1.20815479432,5.3400452,-528.66437425738\n292.83365418,0.0,10.668,-330.19770134945,1.23208097566,5.236337,-518.39807745344\n357.273689,2.032,5.842,-508.63316875916,1.20815479432,5.3400452,-528.66437425738\n37.69424047,7.366,5.588,-416.58997273292,.91357450169,7.0619366,-699.13115314247\n72.25532837,12.954,9.906,586.40373773403,.96766293399,6.6671952,-660.05256601905\n121.42956562,14.986,16.256,387.71230339293,1.2040754753,5.35813,-530.45545698712\n175.2363583,12.192,20.828,-280.5442400419,2.10935518695,6.1171328,-299.7393695\n222.3974378,6.096,21.336,413.48123885686,.81554484621,7.9107792,-783.16772512177\n138.81407483,25.4,15.748,234.164238558,2.38943100688,2.7000454,-267.30565824344\n171.4692344,23.368,17.526,-334.082478726,1.25594916784,5.1368198,-508.5463899704\n225.00000,18.288,18.288,17.96051224214,17.96051224214,3.5920934,-32.32893108428\n203.19859051,16.51,21.336,-136.74251918,3.33518339548,1.9344132,-191.50622368894\n291.80140949,14.732,20.574,-80.18324702488,4.71666158921,2.7356562,-134.0475299\n30.96375653,15.748,18.034,91.47734531502,4.35606406258,4.4431966,-143.6629815291\n161.56505118,19.558,20.32,-56.2252967978,8.03218525675,3.2128714,-77.10898116828\n16.389540334,0.0,20.574,265.17991128726,1.43340492604,4.50088,-445.58826672539\n70.34617594,4.318,21.844,-297.29446803469,1.70858889651,3.7759894,-373.822156782\n293.19859051,19.558,25.4,-136.7425191801,3.33518339548,3.868801,-189.57183588894\n343.61045967,21.082,21.844,-265.17991128725,1.433404926,4.50088,-445.5882667254\n339.44395478,0.0,4.826,-136.75087638398,2.97284513779,4.340352,-212.67734313106\n294.7751406,4.064,3.302,-306.90424056705,1.77401295215,3.6367212,-360.0359338072\n66.80140949,19.812,0.0,136.74251918012,3.33518339452,3.868801,-189.57183588894\n17.35402464,21.336,3.556,-345.47402804977,1.51523696536,4.2578274,-421.523759802\n69.44395478,7.366,0.0,-136.75087638396,2.97284513874,2.170176,-214.84751913106\n101.309932474,18.288,0.0,104.60834648271,4.98134983255,1.295146,-128.21994964526\n165.963756532,18.034,1.27,-80.085263387,6.16040487582,5.236337,-99.49054589069\n186.00900596,12.954,2.54,-255.26337856879,1.32949676118,4.85267,-480.41364863337\n303.69006753,15.748,15.748,-56.35753993648,7.0446924921,3.6632388,-87.9177635968\n353.15722659,17.78,12.7,434.77679606606,1.0087628707,6.3955676,-633.16009065031\n60.9453959,24.13,11.938,-204.76648550216,2.46706609031,2.6150824,-258.8939231811\n90.0000000,25.4,14.224,25.4,25.4,1.524,-23.876\n120.25643716,12.446,3.302,-204.77318477297,1.8283320086,3.5286696,-349.339407732\n48.01278750,10.668,6.35,305.85067529778,1.88796713138,6.8344288,-334.88762199565\n0.000000000,15.24,11.43,25.4,25.4,6.604,-18.796\n325.3048465,21.844,11.43,310.04235091354,-1.6064370526,4.0160956,-397.5931672414\n254.0546041,25.146,9.144,104.6687497289,3.48895832444,3.6982908,-181.21650038772\n207.64597536,24.13,5.588,545.36007557253,1.07143433066,6.021451,-596.12464422938\n175.42607874,18.796,2.794,331.1739336186,1.01276432357,6.3702946,-630.6584645624\n*HEX,Hexagonal mesh\n0, 0, 0, 0, 5.4992613154, 3.175, -6.35\n120, 0, 0, 0, 5.4992613154, 3.175, -6.35\n60, 3.175, 0, 0, 5.4992613154, 3.175, -6.35\n*HONEY,Honeycomb\n0, 0, 0, 4.7625, 2.749630645, 3.175, -6.35\n120, 0, 0, 4.7625, 2.749630645, 3.175, -6.35\n60, 0, 0, 4.7625, 2.749630645, -6.35, 3.175\n*HOUND,Houndstooth\n0, 0, 0, 6.35, 1.5875, 25.4, -12.7\n90, 0, 0, -6.35, 1.5875, 25.4, -12.7\n*INSUL,Insulation batt\n0, 0, 0, 0, 9.525\n0, 0, 3.175, 0, 9.525, 3.175, -3.175\n0, 0, 6.35, 0, 9.525, 3.175, -3.175\n*LINE,Horizontal lines\n0, 0, 0, 0, 3.175\n*MUDST,Mud / sand (geological)\n0, 0, 0, 12.7, 6.35, 6.35, -6.35, 0, -6.35, 0, -6.35\n*NET,Square grid\n0, 0, 0, 0, 3.175\n90, 0, 0, 0, 3.175\n*NET3,Triangular grid\n0, 0, 0, 0, 3.175\n60, 0, 0, 0, 3.175\n120, 0, 0, 0, 3.175\n*PLAST,Plastic\n0, 0, 0, 0, 6.35\n0, 0, 0.79375, 0, 6.35\n0, 0, 1.5875, 0, 6.35\n*PLASTI,Plastic, dense\n0, 0, 0, 0, 6.35\n0, 0, 0.79375, 0, 6.35\n0, 0, 1.5875, 0, 6.35\n0, 0, 3.96875, 0, 6.35\n*SACNCR,Concrete, dotted diagonal\n45, 0, 0, 0, 2.38125\n45, 1.6838, 0, 0, 2.38125, 0, -2.38125\n*SQUARE,Dashed square lattice\n0, 0, 0, 0, 3.175, 3.175, -3.175\n90, 0, 0, 0, 3.175, 3.175, -3.175\n*STARS,Six-pointed star lattice\n0, 0, 0, 0, 5.4992613154, 3.175, -3.175\n60, 0, 0, 0, 5.4992613154, 3.175, -3.175\n120, 1.5875, 2.7496306704, 0, 5.4992613154, 3.175, -3.175\n*STEEL,Steel, paired lines\n45, 0, 0, 0, 3.175\n45, 0, 1.5875, 0, 3.175\n*SWAMP,Swamp / marsh\n0, 0, 0, 12.7, 21.9970452362, 3.175, -22.225\n90, 1.5875, 0, 21.9970452362, 12.7, 1.5875, -42.4065904724\n90, 1.984375, 0, 21.9970452362, 12.7, 1.27, -42.7240904724\n90, 1.190625, 0, 21.9970452362, 12.7, 1.27, -42.7240904724\n60, 2.38125, 0, 12.7, 21.9970452362, 1.016, -24.384\n120, 0.79375, 0, 12.7, 21.9970452362, 1.016, -24.384\n*TRANS,Heat-transfer surface\n0, 0, 0, 0, 6.35\n0, 0, 3.175, 0, 6.35, 3.175, -3.175\n*TRIANG,Triangle tiling\n60, 0, 0, 4.7625, 8.2488919604, 4.7625, -4.7625\n120, 0, 0, 4.7625, 8.2488919604, 4.7625, -4.7625\n0, -2.38125, 4.1244459802, 4.7625, 8.2488919604, 4.7625, -4.7625\n*ZIGZAG,Stair-step zigzag\n0, 0, 0, 3.175, 3.175, 3.175, -3.175\n90, 3.175, 0, 3.175, 3.175, 3.175, -3.175\n\n;; Hatch companions to the ISO 128 line types (1 mm pen base).\n\n*ACAD_ISO02W100,ISO dashed\n0, 0,0, 0,5, 12,-3\n*ACAD_ISO03W100,ISO dashed, wide gaps\n0, 0,0, 0,5, 12,-18\n*ACAD_ISO04W100,ISO long-dash dot\n0, 0,0, 0,5, 24,-3,.5,-3\n*ACAD_ISO05W100,ISO long-dash double-dot\n0, 0,0, 0,5, 24,-3,.5,-3,.5,-3\n*ACAD_ISO06W100,ISO long-dash triple-dot\n0, 0,0, 0,5, 24,-3,.5,-3,.5,-6.5\n0, 0,0, 0,5, -34,.5,-3\n*ACAD_ISO07W100,ISO dotted\n0, 0,0, 0,5, .5,-3\n*ACAD_ISO08W100,ISO long-dash short-dash\n0, 0,0, 0,5, 24,-3,6,-3\n*ACAD_ISO09W100,ISO long-dash double short-dash\n0, 0,0, 0,5, 24,-3,6,-3,6,-3\n*ACAD_ISO10W100,ISO dash dot\n0, 0,0, 0,5, 12,-3,.5,-3\n*ACAD_ISO11W100,ISO double-dash dot\n0, 0,0, 0,5, 12,-3,12,-3,.5,-3\n*ACAD_ISO12W100,ISO dash double-dot\n0, 0,0, 0,5, 12,-3,.5,-3,.5,-3\n*ACAD_ISO13W100,ISO double-dash double-dot\n0, 0,0, 0,5, 12,-3,12,-3,.5,-6.5\n0, 0,0, 0,5, -33.5,.5,-3\n*ACAD_ISO14W100,ISO dash triple-dot\n0, 0,0, 0,5, 12,-3,.5,-3,.5,-6.5\n0, 0,0, 0,5, -22,.5,-3\n*ACAD_ISO15W100,ISO double-dash triple-dot\n0, 0,0, 0,5, 12,-3,12,-3,.5,-10\n0, 0,0, 0,5, -33.5,.5,-3,.5,-3\n\n;; JIS A 0150 section patterns.\n\n*JIS_LC_20,Lightweight concrete, 20 mm (JIS)\n45,0,0,0,20\n45,.4,0,0,20\n*JIS_LC_20A,Lightweight concrete, 20 mm wide (JIS)\n45,0,0,0,20\n45,1,0,0,20\n*JIS_LC_8,Lightweight concrete, 8 mm (JIS)\n45,0,0,0,7.8\n45,.4,0,0,7.8\n*JIS_LC_8A,Lightweight concrete, 8 mm wide (JIS)\n45,0,0,0,7.8\n45,1,0,0,7.8\n*JIS_RC_10,Reinforced concrete, 10 mm (JIS)\n45,0,0,0,10\n45,.725,0,0,10\n45,1.45,0,0,10\n*JIS_RC_15,Reinforced concrete, 15 mm (JIS)\n45,0,0,0,15\n45,.725,0,0,15\n45,1.45,0,0,15\n*JIS_RC_18,Reinforced concrete, 18 mm (JIS)\n45,0,0,0,18\n45,1,0,0,18\n45,2,0,0,18\n*JIS_RC_30,Reinforced concrete, 30 mm (JIS)\n45,0,0,0,30\n45,1,0,0,30\n45,2,0,0,30\n*JIS_STN_1E,Stone, 1 mm (JIS)\n45, 0, 0, 0, 1\n45, .705, 0, 0,1, 1, -.5\n*JIS_STN_2.5,Stone, 2.5 mm (JIS)\n45, 0, 0, 0, 2.5\n45, 1.765, 0, 0,2.5, 1.2, -.5\n*JIS_WOOD,Wood (JIS)\n45,0,0,0,.70710678\n`;\n","// Named hatch patterns — the AutoCAD .pat line-family model (Tier 2 of\n// docs/hatch-patterns.md). A pattern is N families of parallel, optionally\n// dashed lines. Painting iterates the families and clips each to the boundary\n// loops (computeHatchFamily, ../paint/sink); DXF export maps the curated names\n// 1:1 onto the standard predefined HATCH patterns.\n\nimport type { Vec2 } from \"../geometry/vec2\";\nimport { computeHatchFamily } from \"../paint/sink\";\nimport { BUILTIN_PAT } from \"./builtinPat\";\n\n/**\n * One family of parallel lines, in the pattern's own frame (before the fill's\n * rotation/scale). Mirrors an acad .pat definition line\n * `angle, x-origin, y-origin, delta-x, delta-y [, dash…]`:\n * - `angle` radians CCW,\n * - `origin` base point (mm),\n * - `deltaX` shift ALONG the line between successive lines — only affects dash\n * phase, ignored for solid families,\n * - `deltaY` PERPENDICULAR spacing between successive lines (mm, > 0),\n * - `dashesMm` dash cycle along the line: >0 pen-down, <0 gap, 0 dot; omitted\n * means a solid line.\n */\nexport interface PatternLine {\n angle: number;\n origin: Vec2;\n deltaX: number;\n deltaY: number;\n dashesMm?: number[];\n}\n\nexport interface HatchPattern {\n name: string;\n /** Human description from the .pat header (for UI/tooltip). */\n description?: string;\n lines: PatternLine[];\n}\n\n/**\n * Parse acad .pat text into patterns. `unitScale` converts the file's length\n * units to world mm: inch-based .pat files need 25.4 (the default) while the\n * ISO-scaled builtin.pat is already mm (pass 1). Either way ANSI31 lands\n * at the 3.175 mm / scale-1 spacing the DXF layer assumes (ANSI31_BASE_SPACING).\n * Comment (`;`) and blank lines are skipped.\n */\nexport const parsePatternDefinitions = (\n text: string,\n unitScale = 25.4,\n): HatchPattern[] => {\n const DEG2RAD = Math.PI / 180;\n const patterns: HatchPattern[] = [];\n let current: HatchPattern | null = null;\n for (const raw of text.split(/\\r?\\n/)) {\n const line = raw.trim();\n if (!line || line.startsWith(\";\")) continue;\n if (line.startsWith(\"*\")) {\n const [name, ...desc] = line.slice(1).split(\",\");\n current = { name: name.trim(), lines: [] };\n const d = desc.join(\",\").trim();\n if (d) current.description = d;\n patterns.push(current);\n continue;\n }\n if (!current) continue;\n const n = line.split(\",\").map((s) => Number(s.trim()));\n if (n.length < 5 || n.some((v) => Number.isNaN(v))) continue;\n const [angle, x, y, dx, dy, ...dashes] = n;\n current.lines.push({\n angle: angle * DEG2RAD,\n origin: { x: x * unitScale, y: y * unitScale },\n deltaX: dx * unitScale,\n deltaY: dy * unitScale,\n dashesMm: dashes.length ? dashes.map((v) => v * unitScale) : undefined,\n });\n }\n return patterns.filter((p) => p.lines.length > 0);\n};\n\n// Built-in library = the embedded catalogue (builtin.pat, lengths already in\n// mm). Names match the standard DXF predefined patterns, so DXF export/import\n// is a direct name mapping. `SOLID` is filtered defensively — a solid fill is\n// its own `fill.kind`, not a line-family pattern.\nconst BUILT_IN_PATTERNS: HatchPattern[] = parsePatternDefinitions(\n BUILTIN_PAT,\n 1,\n).filter((p) => p.name.toUpperCase() !== \"SOLID\");\n\n// Normalize for lookup: uppercase and fold the punctuation that drifts between\n// the .pat names, the DXF predefined enum, and AutoCAD output (hyphens, dots,\n// and spaces all become `_`), so `AR-CONC`, `AR_CONC`, and `ar conc` resolve to\n// the same pattern. The .pat names are collision-free under this fold.\nconst normalizeName = (name: string): string =>\n name\n .trim()\n .toUpperCase()\n .replace(/[\\s.-]+/g, \"_\");\n\nconst BUILT_IN_BY_NAME = new Map(\n BUILT_IN_PATTERNS.map((p) => [normalizeName(p.name), p]),\n);\n\n/** Ordered built-in pattern names (drives the property-panel dropdown). */\nexport const HATCH_PATTERN_NAMES: string[] = BUILT_IN_PATTERNS.map(\n (p) => p.name,\n);\n\n/** Default pattern name for a new pattern fill. */\nexport const DEFAULT_HATCH_PATTERN = \"ANSI31\";\n\n/** Resolve a fill pattern name to its definition (case- and punctuation-insensitive). */\nexport const getHatchPattern = (name: string): HatchPattern | undefined =>\n BUILT_IN_BY_NAME.get(normalizeName(name));\n\n/**\n * AutoCAD MaxHatch-style ceiling: a hatch whose pattern would emit more\n * segments than this paints as a translucent solid instead (paintHatch).\n * Denser than this is sub-pixel/sub-print-resolution anyway — it reads as\n * tone, and generating millions of segments stalls rendering and export.\n */\nexport const MAX_HATCH_SEGMENTS = 100_000;\n\n/**\n * Cheap upper bound on the segment count computePatternGeometry would emit,\n * from the rings' bounding-box diagonal (no generation, no clipping). Used\n * to decide the solid fallback BEFORE paying for the real geometry.\n */\nexport const estimatePatternSegments = (\n rings: Vec2[][],\n pattern: HatchPattern,\n scale: number,\n): number => {\n if (scale <= 0) return 0;\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n for (const ring of rings)\n for (const p of ring) {\n if (p.x < minX) minX = p.x;\n if (p.x > maxX) maxX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.y > maxY) maxY = p.y;\n }\n if (minX > maxX) return 0;\n const diag = Math.hypot(maxX - minX, maxY - minY);\n let count = 0;\n for (const fam of pattern.lines) {\n const perp = Math.abs(fam.deltaY) * scale;\n if (perp <= 1e-9) continue;\n const lines = diag / perp + 1;\n const period =\n (fam.dashesMm?.reduce((a, b) => a + Math.abs(b), 0) ?? 0) * scale;\n const perLine = period > 1e-9 ? diag / period + 1 : 1;\n count += lines * perLine;\n }\n return count;\n};\n\n/**\n * Every clipped (and dashed) segment for a pattern fill: iterate the families,\n * fold the fill's rotation + world-mm scale into each, and clip via\n * computeHatchFamily. Pure geometry — canvas, PDF, and SVG stroke the same\n * segments.\n */\nexport const computePatternGeometry = (\n rings: Vec2[][],\n pattern: HatchPattern,\n angle: number,\n scale: number,\n): { a: Vec2; b: Vec2 }[] => {\n const out: { a: Vec2; b: Vec2 }[] = [];\n if (scale <= 0) return out;\n const c = Math.cos(angle);\n const s = Math.sin(angle);\n for (const fam of pattern.lines) {\n if (Math.abs(fam.deltaY) * scale <= 1e-9) continue;\n // Map the family's pattern-space origin into world: scale, then rotate by\n // the fill angle (deltas rotate with `angle + fam.angle` inside the family).\n const ox = fam.origin.x * scale;\n const oy = fam.origin.y * scale;\n // No spread: a large boundary with fine spacing yields 100k+ segments,\n // and push(...segs) overflows the call stack (one argument per segment).\n const segs = computeHatchFamily(rings, {\n angle: angle + fam.angle,\n origin: { x: ox * c - oy * s, y: ox * s + oy * c },\n deltaAlong: fam.deltaX * scale,\n deltaPerp: fam.deltaY * scale,\n dashesMm: fam.dashesMm?.map((d) => d * scale),\n });\n for (const seg of segs) out.push(seg);\n }\n return out;\n};\n","import { z } from \"zod\";\nimport { ColorSchema } from \"./common\";\nimport {\n DEFAULT_DIM_STYLE,\n DEFAULT_TEXT_STYLE,\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n} from \"./objects\";\nimport { PaperLayoutSchema } from \"./paperLayout\";\nimport { CURRENT_DOCUMENT_VERSION, migrateDocument } from \"./migrations\";\n\nexport const LayerSchema = z.object({\n id: z.string().default(() => crypto.randomUUID()),\n name: z.string().default(\"Layer\"),\n color: ColorSchema.default(\"#e8e8e8\"),\n /** Default line type for objects on this layer. */\n lineType: z.string().default(\"continuous\"),\n /** Default lineweight in mm for objects on this layer. */\n lineWidth: z.number().positive().default(0.25),\n /** Default paint opacity for objects on this layer (objects without their\n * own `opacity` inherit it, like color/lineWidth). */\n opacity: z.number().min(0).max(1).default(1),\n visible: z.boolean().default(true),\n locked: z.boolean().default(false),\n /** Plot flag (AutoCAD-style): false = shown on screen but excluded from\n * PDF/print output. */\n print: z.boolean().default(true),\n});\nexport type Layer = z.infer<typeof LayerSchema>;\n\n/** What hosts call a drawing that has no file (and no name) yet. A\n * document carries no name of its own: the file name IS the name (hosts own\n * it — desktop: the file path, web: the project record). Files that still\n * hold a legacy `name` key parse fine; it is dropped. */\nexport const DEFAULT_DOCUMENT_NAME = \"Untitled project\";\n\nexport const LineaDocumentSchema = z.preprocess(\n migrateDocument,\n z.object({\n /**\n * Stable document identity, stored IN the file so re-opening the same\n * file updates the same project record. Files that predate this field\n * get a fresh id on parse (it sticks after the next save). Save As to a\n * NEW file assigns a fresh id, keeping ids 1:1 with files.\n */\n id: z.string().default(() => crypto.randomUUID()),\n type: z.literal(\"lineadraw\").default(\"lineadraw\"),\n version: z.literal(CURRENT_DOCUMENT_VERSION),\n /** Document-wide settings. Currently not used anywhere (inch support is not added) */\n settings: z\n .object({ units: z.enum([\"mm\", \"in\"]).default(\"mm\") })\n .default({ units: \"mm\" }),\n layers: z.array(LayerSchema).min(1),\n currentLayerId: z.string(),\n /** Array order is draw order (bottom to top).\n * Resilient object parsing (calculus pattern): a single corrupt object must\n * not fail the whole document — skip it with a warning instead.\n */\n objects: z.preprocess((raw) => {\n if (!Array.isArray(raw)) return raw;\n return raw.filter((o) => {\n const r = ModelObjectSchema.safeParse(o);\n if (!r.success)\n console.warn(\"Skipping invalid model object:\", o, r.error.message);\n return r.success;\n });\n }, z.array(ModelObjectSchema)),\n layouts: z.array(PaperLayoutSchema).default([]),\n /** Named text styles; objects reference one by styleId (first =\n * default for objects without one). */\n textStyles: z\n .array(TextStyleSchema)\n .min(1)\n .default(() => [{ ...DEFAULT_TEXT_STYLE }]),\n /** Named dimension styles, same referencing model. */\n dimStyles: z\n .array(DimStyleSchema)\n .min(1)\n .default(() => [{ ...DEFAULT_DIM_STYLE }]),\n /**\n * Embedded binary assets for image objects: content hash → data URL.\n * Kept IN the document so the .linea file stays self-contained (the\n * cost is base64 in the JSON). Entries orphaned by deleted images just\n * ride along (no GC — deletion is undoable, so eager sweeps would break\n * redo).\n */\n assets: z.record(z.string(), z.string()).default({}),\n /**\n * The block library: raw ES-module sources (JS or TS). Each module\n * exports its own `id`/`name`/`params` metadata plus `draw` (and\n * optionally `place`; the pre-rename `main`/`defineInput` names are\n * frozen aliases) — see blocks/evalBlock.ts.\n */\n blockDefinitions: z.array(z.string()).default([]),\n /**\n * Document-embedded user commands (macro scripts): raw ES-module\n * sources, one `export default defineCommand({...})` per module — see\n * blocks/commandModules.ts. The user's per-device library lives outside\n * the document; these travel with the file.\n */\n commands: z.array(z.string()).default([]),\n }),\n);\nexport type LineaDocument = z.infer<typeof LineaDocumentSchema>;\n","import { z } from \"zod\";\nimport { ModelObjectSchema } from \"./objects\";\n\n/** ISO A-series portrait sizes in mm [width, height]. */\nexport const SHEET_PRESETS = {\n A4: [210, 297],\n A3: [297, 420],\n A2: [420, 594],\n A1: [594, 841],\n A0: [841, 1189],\n} as const satisfies Record<string, readonly [number, number]>;\n\nexport type SheetName = keyof typeof SHEET_PRESETS;\nexport type SheetOrientation = \"portrait\" | \"landscape\";\n/**\n * How callers name a sheet: a bare preset (`\"A3\"` — orientation from\n * context: landscape for a new layout, the current one when patching), a\n * preset with its orientation, or explicit millimetres (orientation baked\n * in).\n */\nexport type SheetSpec =\n | SheetName\n | { name: SheetName; orientation: SheetOrientation }\n | { width: number; height: number };\n\n/**\n * Sheet spec → millimetres. Presets are stored portrait. The ONE place every\n * API (createLayout, updateLayout, tools) resolves sheets; `defaultOrientation`\n * applies to a bare preset name only.\n */\nexport const resolveSheetSize = (\n sheet: SheetSpec = \"A3\",\n defaultOrientation: SheetOrientation = \"landscape\",\n): { width: number; height: number } => {\n if (typeof sheet !== \"string\" && \"width\" in sheet)\n return { width: sheet.width, height: sheet.height };\n const name = typeof sheet === \"string\" ? sheet : sheet.name;\n const orientation =\n typeof sheet === \"string\" ? defaultOrientation : sheet.orientation;\n const preset = SHEET_PRESETS[name];\n if (!preset) throw new Error(`Unknown sheet \"${String(name)}\"`);\n const [w, h] = preset;\n return orientation === \"landscape\"\n ? { width: h, height: w }\n : { width: w, height: h };\n};\n\n/** The orientation a sheet size implies (square counts as portrait). */\nexport const sheetOrientation = (sheet: {\n width: number;\n height: number;\n}): SheetOrientation => (sheet.width > sheet.height ? \"landscape\" : \"portrait\");\n\n/**\n * How authored model colors map to print colors for this layout (paper space\n * previews the same mapping — what you see is what prints):\n * - \"color\": keep colors; near-white neutrals become black (white paper).\n * - \"grayscale\": ink-weight grays — the lighter a color was authored on the\n * dark canvas, the darker it prints.\n * - \"monochrome\": everything black.\n */\nexport const PrintPaletteSchema = z.enum([\"color\", \"grayscale\", \"monochrome\"]);\nexport type PrintPalette = z.infer<typeof PrintPaletteSchema>;\n\nexport const PaperLayoutSchema = z.object({\n id: z.string().default(() => crypto.randomUUID()),\n name: z.string().default(\"Layout\"),\n /** Orientation is baked into width/height at creation. */\n sheet: z\n .object({\n width: z.number().positive(),\n height: z.number().positive(),\n })\n .default({ width: 210, height: 297 }), // A4 portrait\n printPalette: PrintPaletteSchema.default(\"color\"),\n /**\n * Sheet-space objects reuse model primitives (drawn in sheet mm).\n * Viewports live here too, as \"viewport\" objects.\n */\n objects: z.array(ModelObjectSchema).default([]),\n});\nexport type PaperLayout = z.infer<typeof PaperLayoutSchema>;\n","/**\n * Drawing scale → the stored 1:N denominator (model mm per paper mm):\n * `\"1:50\"` → 50, `\"2:1\"` → 0.5; numbers pass through (50 means 1:50).\n */\nexport const parseScale = (scale: number | string): number => {\n if (typeof scale === \"number\") {\n if (!Number.isFinite(scale) || scale <= 0)\n throw new Error(`Invalid scale ${scale}`);\n return scale;\n }\n const m = /^\\s*(\\d+(?:\\.\\d+)?)\\s*:\\s*(\\d+(?:\\.\\d+)?)\\s*$/.exec(scale);\n const paper = m ? Number(m[1]) : NaN;\n const model = m ? Number(m[2]) : NaN;\n if (!(paper > 0) || !(model > 0))\n throw new Error(\n `Invalid scale \"${scale}\" (use \"1:50\", \"2:1\", or a number)`,\n );\n return model / paper;\n};\n","import { LineaDocumentSchema, type LineaDocument } from \"./document\";\nimport { CURRENT_DOCUMENT_VERSION } from \"./migrations\";\n\nexport function emptyDocument(): LineaDocument {\n const layerId = crypto.randomUUID();\n\n return LineaDocumentSchema.parse({\n version: CURRENT_DOCUMENT_VERSION,\n layers: [\n {\n id: layerId,\n name: \"Layer 0\",\n color: \"#e8e8e8\",\n lineWidth: 0.25,\n visible: true,\n locked: false,\n },\n ],\n currentLayerId: layerId,\n objects: [],\n // Deliberately layout-less: a hidden default \"Layout 1\" surprises SDK\n // users (blank first PDF page, layouts.length off by one) and the PDF\n // export already falls back to an auto-fitted sheet. Layouts are created\n // explicitly (editor command / createLayout).\n layouts: [],\n });\n}\n","/**\n * djb2 over the data URL, plus its length — the assets-map content key.\n * Content-keyed so re-adding the same pixels reuses the existing entry.\n */\nexport const hashAsset = (data: string): string => {\n let h = 5381;\n for (let i = 0; i < data.length; i++)\n h = ((h << 5) + h + data.charCodeAt(i)) | 0;\n return `${(h >>> 0).toString(16)}-${data.length.toString(16)}`;\n};\n","import { LineaDocumentSchema, type LineaDocument } from \"./model/document\";\n\n/** Pretty JSON — .linea files are meant to be diffable and inspectable. */\nexport const documentToJson = (doc: LineaDocument): string =>\n JSON.stringify(doc, null, 2);\n\n/** Parse + validate + migrate. Throws on unrecoverable input. */\nexport const documentFromJson = (text: string): LineaDocument =>\n LineaDocumentSchema.parse(JSON.parse(text));\n\n/** How long one synchronous slice of `documentToJsonAsync` may run before\n * it yields (ms). */\nconst SLICE_MS = 30;\n/** Array items stringified per call (one call per item is ~3× slower). */\nconst BATCH = 1000;\n\n// Every piece is stringified inside a one-key wrapper so JSON.stringify lays\n// it out at its real depth, then the wrapper's text is cut off:\n// `{⏎ \"k\": [⏎ a,⏎ b⏎ ]⏎}` → `a,⏎ b` (a batch of array items),\n// `{⏎ \"k\": {⏎ \"h\": v⏎ }⏎}` → `\"h\": v` (one record entry).\nconst ITEMS_HEAD = '{\\n \"k\": [\\n '.length;\nconst ITEMS_TAIL = \"\\n ]\\n}\".length;\nconst ENTRY_HEAD = '{\\n \"k\": {\\n '.length;\nconst ENTRY_TAIL = \"\\n }\\n}\".length;\n\n/**\n * `documentToJson` in slices — byte-identical output, but the top-level\n * arrays (objects, layouts…) are stringified in batches and record members\n * (assets: embedded images) entry by entry, yielding the thread between\n * ~30 ms slices so a save can paint its progress. `onProgress` hears the\n * fraction done at each yield (never for a fast save). The document must\n * not change meanwhile — store snapshots never do.\n */\nexport const documentToJsonAsync = async (\n doc: LineaDocument,\n onProgress?: (fraction: number) => void,\n): Promise<string> => {\n const entries = Object.entries(doc as Record<string, unknown>);\n const isRecord = (v: unknown): v is Record<string, unknown> =>\n typeof v === \"object\" && v !== null && !Array.isArray(v);\n const total = entries.reduce(\n (n, [, v]) =>\n n +\n (Array.isArray(v)\n ? v.length\n : isRecord(v)\n ? Object.keys(v).length || 1\n : 1),\n 0,\n );\n let done = 0;\n let sliceStart = Date.now();\n const tick = async (count: number) => {\n done += count;\n if (Date.now() - sliceStart < SLICE_MS) return;\n onProgress?.(done / total);\n await new Promise((resolve) => setTimeout(resolve, 0));\n sliceStart = Date.now();\n };\n\n const members: string[] = [];\n for (const [key, value] of entries) {\n const name = JSON.stringify(key);\n if (Array.isArray(value) && value.length > 0) {\n const batches: string[] = [];\n for (let i = 0; i < value.length; i += BATCH) {\n batches.push(\n JSON.stringify({ k: value.slice(i, i + BATCH) }, null, 2).slice(\n ITEMS_HEAD,\n -ITEMS_TAIL,\n ),\n );\n await tick(Math.min(BATCH, value.length - i));\n }\n members.push(`${name}: [\\n ${batches.join(\",\\n \")}\\n ]`);\n } else if (isRecord(value) && Object.keys(value).length > 0) {\n const parts: string[] = [];\n for (const [k, v] of Object.entries(value)) {\n if (v === undefined) continue;\n parts.push(\n JSON.stringify({ k: { [k]: v } }, null, 2).slice(\n ENTRY_HEAD,\n -ENTRY_TAIL,\n ),\n );\n await tick(1);\n }\n members.push(\n parts.length\n ? `${name}: {\\n ${parts.join(\",\\n \")}\\n }`\n : `${name}: {}`,\n );\n } else {\n const json = JSON.stringify({ [key]: value }, null, 2);\n if (json !== \"{}\") members.push(json.slice(4, -2));\n await tick(1);\n }\n }\n return members.length ? `{\\n ${members.join(\",\\n \")}\\n}` : \"{}\";\n};\n","// A GeometrySink that emits SVG — the headless render target so agents/CLIs\n// can *see* a drawing instead of re-reading JSON (sibling to PdfSink). World\n// is mm, Y-up; SVG is Y-down, so coordinates are emitted with Y negated\n// (world-up renders up) and the viewBox uses -maxY as its top. Curves are\n// decomposed to cubic béziers via the shared helpers, so screen/PDF/SVG\n// output cannot drift.\n//\n// Transforms are baked into coordinates (viewport projection works), and clip\n// rects are honored via <clipPath> groups — so paper-layout viewport content\n// is clipped to its frame, like the canvas/PDF sinks.\n\nimport {\n arcToBeziers,\n ellipseArcToBeziers,\n matApply,\n matIdentity,\n matMultiply,\n signedArcSweep,\n type FillStyle,\n type GeometrySink,\n type Mat2x3,\n type Rect,\n type ImageSpec,\n type StrokeStyle,\n type TextSpec,\n} from \"../../paint/sink\";\nimport { approximateTextMeasurer } from \"../../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../../paint/textMetrics\";\nimport { parseFontFace, resolveFont } from \"../../model/fonts\";\nimport type { Vec2 } from \"../../geometry/vec2\";\n\nconst n = (v: number): string => {\n const r = Math.round(v * 1000) / 1000;\n return Object.is(r, -0) ? \"0\" : String(r);\n};\n\nconst escapeXml = (s: string): string =>\n s.replace(/[&<>\"]/g, (c) =>\n c === \"&\" ? \"&\" : c === \"<\" ? \"<\" : c === \">\" ? \">\" : \""\",\n );\n\nexport interface SvgSinkOptions {\n /** Text width measurement (defaults to the approximate Inter table). */\n measure?: TextMeasurer;\n /**\n * Clamp every stroke to at least this width (world mm). Thumbnails render\n * a whole drawing into a ~256px image, where authored 0.25 mm lineweights\n * become sub-pixel and the picture rasterizes to nothing — clamping at the\n * SINK catches everything (block children and dimension hairlines resolve\n * their own widths past any per-object style override).\n */\n minStrokeWidthMm?: number;\n}\n\nexport class SvgSink implements GeometrySink {\n private els: string[] = [];\n private path: string[] = [];\n private hasCurrent = false;\n private m: Mat2x3 = matIdentity;\n private stack: Mat2x3[] = [];\n private defs: string[] = [];\n private clipId = 0;\n private gradId = 0;\n private measurer: TextMeasurer;\n private objectStart: number | null = null;\n private minStroke: number;\n\n constructor(opts: SvgSinkOptions = {}) {\n this.measurer = opts.measure ?? approximateTextMeasurer;\n this.minStroke = opts.minStrokeWidthMm ?? 0;\n }\n\n /** Transformed + Y-flipped point, as an \"x y\" token. */\n private p(pt: Vec2): string {\n const t = matApply(this.m, pt);\n return `${n(t.x)} ${n(-t.y)}`;\n }\n\n beginPath(): void {\n this.path = [];\n this.hasCurrent = false;\n }\n moveTo(pt: Vec2): void {\n this.path.push(`M${this.p(pt)}`);\n this.hasCurrent = true;\n }\n lineTo(pt: Vec2): void {\n this.path.push(`L${this.p(pt)}`);\n this.hasCurrent = true;\n }\n bezierTo(c1: Vec2, c2: Vec2, end: Vec2): void {\n this.path.push(`C${this.p(c1)} ${this.p(c2)} ${this.p(end)}`);\n this.hasCurrent = true;\n }\n private emitBeziers(\n bs: { start: Vec2; c1: Vec2; c2: Vec2; end: Vec2 }[],\n ): void {\n if (bs.length === 0) return;\n this.path.push(`${this.hasCurrent ? \"L\" : \"M\"}${this.p(bs[0].start)}`);\n for (const b of bs)\n this.path.push(`C${this.p(b.c1)} ${this.p(b.c2)} ${this.p(b.end)}`);\n this.hasCurrent = true;\n }\n arc(\n center: Vec2,\n r: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean,\n ): void {\n this.emitBeziers(\n arcToBeziers(\n center,\n r,\n startAngle,\n signedArcSweep(startAngle, endAngle, ccw),\n ),\n );\n }\n ellipse(\n center: Vec2,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ): void {\n this.emitBeziers(\n ellipseArcToBeziers(\n center,\n rx,\n ry,\n rotation,\n startAngle,\n signedArcSweep(startAngle, endAngle, true),\n ),\n );\n }\n closePath(): void {\n this.path.push(\"Z\");\n }\n stroke(s: StrokeStyle): void {\n if (this.path.length === 0) return;\n const width = Math.max(s.widthMm, this.minStroke);\n // Dash patterns are proportioned to the authored width — rescale them\n // with the clamp so boosted strokes still read as dashed, not solid-ish\n // noise at sub-pixel dash lengths.\n const boost = s.widthMm > 0 ? width / s.widthMm : 1;\n const dash =\n s.dashMm && s.dashMm.length\n ? ` stroke-dasharray=\"${s.dashMm.map((d) => n(d * boost)).join(\",\")}\"`\n : \"\";\n const alpha =\n s.opacity !== undefined && s.opacity < 1\n ? ` stroke-opacity=\"${n(s.opacity)}\"`\n : \"\";\n this.els.push(\n `<path d=\"${this.path.join(\" \")}\" fill=\"none\" stroke=\"${s.color}\" stroke-width=\"${n(width)}\"${dash}${alpha} stroke-linecap=\"round\" stroke-linejoin=\"round\"/>`,\n );\n }\n fill(f: FillStyle): void {\n if (this.path.length === 0) return;\n const alpha =\n f.opacity !== undefined && f.opacity < 1\n ? ` fill-opacity=\"${n(f.opacity)}\"`\n : \"\";\n let paint = f.color;\n if (f.gradient) {\n // Endpoints go through the same transform + Y-flip as path points, in\n // user space so the ramp stays anchored to the geometry.\n const a = matApply(this.m, f.gradient.from);\n const b = matApply(this.m, f.gradient.to);\n const id = `grad${this.gradId++}`;\n const stops =\n `<stop offset=\"0\" stop-color=\"${f.color}\"/>` +\n `<stop offset=\"1\" stop-color=\"${f.gradient.color2}\"/>`;\n this.defs.push(\n f.gradient.shape === \"radial\"\n ? `<radialGradient id=\"${id}\" gradientUnits=\"userSpaceOnUse\" ` +\n `cx=\"${n(a.x)}\" cy=\"${n(-a.y)}\" ` +\n `r=\"${n(Math.hypot(b.x - a.x, b.y - a.y))}\">${stops}</radialGradient>`\n : `<linearGradient id=\"${id}\" gradientUnits=\"userSpaceOnUse\" ` +\n `x1=\"${n(a.x)}\" y1=\"${n(-a.y)}\" x2=\"${n(b.x)}\" y2=\"${n(-b.y)}\">` +\n `${stops}</linearGradient>`,\n );\n paint = `url(#${id})`;\n }\n this.els.push(\n `<path d=\"${this.path.join(\" \")}\" fill=\"${paint}\"${alpha} fill-rule=\"evenodd\" stroke=\"none\"/>`,\n );\n }\n text(t: TextSpec): void {\n const def = resolveFont(t.font);\n const { bold, italic } = parseFontFace(t.font);\n // osifont-italic's TTF family is plain \"osifont\": only font-style lets a\n // TTF-family matcher (resvg) pick the italic file.\n const face =\n (bold ? ` font-weight=\"bold\"` : \"\") +\n (italic || def.id === \"osifont-italic\" ? ` font-style=\"italic\"` : \"\");\n // Model vAlign is in CAP-height terms (bottom = baseline at the anchor;\n // center/top shift the baseline down by half/full cap height). Compute\n // the baseline point in WORLD space so the shift rotates with the text,\n // then let SVG's default alphabetic baseline do the rest.\n const drop =\n t.vAlign === \"center\"\n ? t.heightMm / 2\n : t.vAlign === \"top\"\n ? t.heightMm\n : 0;\n const baselineWorld = {\n x: t.anchor.x + Math.sin(t.rotation) * drop,\n y: t.anchor.y - Math.cos(t.rotation) * drop,\n };\n const tp = matApply(this.m, baselineWorld);\n // The anchor is baked through the transform, so the glyph height must be\n // too — otherwise text inside a scaled viewport (e.g. a 1:50 paper layout)\n // keeps its full world size. Viewport transforms are uniform-scale, so the\n // matrix's x-basis length is the scale factor.\n const scale = Math.hypot(this.m[0], this.m[1]) || 1;\n const anchor =\n t.hAlign === \"left\" ? \"start\" : t.hAlign === \"right\" ? \"end\" : \"middle\";\n // World rotation is CCW (Y-up); with Y negated per point it maps to the\n // negated SVG rotation.\n const deg = (-t.rotation * 180) / Math.PI;\n const w = t.widthFactor ?? 1;\n const transforms: string[] = [];\n if (deg !== 0) transforms.push(`rotate(${n(deg)} ${n(tp.x)} ${n(-tp.y)})`);\n // Width factor: horizontal glyph scale about the anchor (applied before\n // the rotation, so it stretches along the text's own run direction).\n if (w !== 1)\n transforms.push(\n `translate(${n(tp.x)} ${n(-tp.y)}) scale(${n(w)} 1) translate(${n(-tp.x)} ${n(tp.y)})`,\n );\n const rot =\n transforms.length > 0 ? ` transform=\"${transforms.join(\" \")}\"` : \"\";\n const alpha =\n t.opacity !== undefined && t.opacity < 1\n ? ` fill-opacity=\"${n(t.opacity)}\"`\n : \"\";\n // font-size is the em; model heights are cap heights.\n this.els.push(\n `<text x=\"${n(tp.x)}\" y=\"${n(-tp.y)}\" font-size=\"${n((t.heightMm / def.capHeight) * scale)}\" font-family=\"${def.cssStack}\"${face} fill=\"${t.color}\"${alpha} text-anchor=\"${anchor}\"${rot}>${escapeXml(t.text)}</text>`,\n );\n }\n measureText(\n text: string,\n heightMm: number,\n font?: string,\n widthFactor?: number,\n ): { width: number } {\n return {\n width: this.measurer.measureTextWidth(text, heightMm, font, widthFactor),\n };\n }\n image(i: ImageSpec): void {\n // Anchor at the image's TOP-LEFT world corner (SVG images are y-down);\n // sizes bake the (uniform) matrix scale, rotation rides as a transform —\n // the text() approach.\n const topLeft = matApply(this.m, {\n x: i.origin.x - Math.sin(i.rotation) * i.heightMm,\n y: i.origin.y + Math.cos(i.rotation) * i.heightMm,\n });\n const scale = Math.hypot(this.m[0], this.m[1]) || 1;\n const deg = (-i.rotation * 180) / Math.PI;\n const rot =\n deg !== 0\n ? ` transform=\"rotate(${n(deg)} ${n(topLeft.x)} ${n(-topLeft.y)})\"`\n : \"\";\n const opacity = i.opacity < 1 ? ` opacity=\"${n(i.opacity)}\"` : \"\";\n this.els.push(\n `<image x=\"${n(topLeft.x)}\" y=\"${n(-topLeft.y)}\" width=\"${n(i.widthMm * scale)}\" height=\"${n(i.heightMm * scale)}\" preserveAspectRatio=\"none\"${opacity}${rot} href=\"${i.data}\"/>`,\n );\n }\n pushTransform(m: Mat2x3): void {\n this.stack.push(this.m);\n this.m = matMultiply(this.m, m);\n }\n popTransform(): void {\n this.m = this.stack.pop() ?? matIdentity;\n }\n /**\n * Group one object's elements as `<g data-object-id data-layer>` so the\n * SVG is navigable by viewers and agents (locate visually → id →\n * update()). Empty groups (nothing emitted) are dropped.\n */\n beginObject(id: string, layer?: string): void {\n this.objectStart = this.els.length;\n this.els.push(\n `<g data-object-id=\"${escapeXml(id)}\"${layer !== undefined ? ` data-layer=\"${escapeXml(layer)}\"` : \"\"}>`,\n );\n }\n endObject(): void {\n if (this.objectStart === null) return;\n if (this.els.length === this.objectStart + 1) this.els.pop();\n else this.els.push(\"</g>\");\n this.objectStart = null;\n }\n\n pushClipRect(r: Rect): void {\n // Bake the rect's corners through the current transform (+Y-flip) so the\n // clip lives in the same root user space as the content it wraps.\n const id = `clip${this.clipId++}`;\n const corners = [\n { x: r.x, y: r.y },\n { x: r.x + r.w, y: r.y },\n { x: r.x + r.w, y: r.y + r.h },\n { x: r.x, y: r.y + r.h },\n ];\n const d = `M${this.p(corners[0])}L${this.p(corners[1])}L${this.p(corners[2])}L${this.p(corners[3])}Z`;\n this.defs.push(`<clipPath id=\"${id}\"><path d=\"${d}\"/></clipPath>`);\n this.els.push(`<g clip-path=\"url(#${id})\">`);\n }\n popClip(): void {\n this.els.push(\"</g>\");\n }\n\n /** Wrap the accumulated elements in an <svg> with the given world bbox. */\n toSvg(\n bbox: { minX: number; minY: number; maxX: number; maxY: number },\n pad = 5,\n ): string {\n const minX = bbox.minX - pad;\n const w = bbox.maxX - bbox.minX + pad * 2;\n const h = bbox.maxY - bbox.minY + pad * 2;\n // Top of the viewBox is -maxY because we negated Y on every point.\n const minY = -bbox.maxY - pad;\n const defs = this.defs.length ? `<defs>${this.defs.join(\"\")}</defs>` : \"\";\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"${n(minX)} ${n(minY)} ${n(w)} ${n(h)}\">` +\n defs +\n this.els.join(\"\") +\n `</svg>`\n );\n }\n}\n","import type { Line } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintLine = (\n obj: Line,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.moveTo(obj.a);\n sink.lineTo(obj.b);\n sink.stroke(env.style);\n};\n","import type { Point } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\n/**\n * A point paints as a round dot whose diameter IS the stroke width: a\n * near-zero-length segment under the sinks' round line caps. That inherits\n * each sink's lineweight realization (canvas px floor, PDF/SVG verbatim mm,\n * viewport-scale compensation) instead of inventing a second sizing rule.\n * The 0.002 mm nudge keeps the segment non-degenerate everywhere — canvas\n * prunes zero-length subpaths, and the SVG sink rounds to 0.001 mm.\n */\nexport const paintPoint = (\n obj: Point,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.moveTo(obj.p);\n sink.lineTo({ x: obj.p.x + 0.002, y: obj.p.y });\n // Never dashed: a dash gap at phase zero would swallow the dot entirely.\n sink.stroke({ ...env.style, dashMm: undefined });\n};\n","import type { Polyline, PolylineVertex } from \"../../model/objects\";\nimport { bulgeToArc } from \"../../geometry/arcs\";\nimport { angle, sub } from \"../../geometry/vec2\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\n/** Emit one polyline segment (straight or bulged arc) into an open path. */\nconst segmentTo = (\n sink: GeometrySink,\n from: PolylineVertex,\n to: PolylineVertex,\n): void => {\n const a = { x: from.x, y: from.y };\n const b = { x: to.x, y: to.y };\n const arc = bulgeToArc(a, b, from.bulge);\n if (!arc) {\n sink.lineTo(b);\n return;\n }\n // Travel direction matters for path continuity: positive bulge runs CCW\n // (increasing angle) from a to b, negative runs CW.\n const angA = angle(sub(a, arc.center));\n const angB = angle(sub(b, arc.center));\n sink.arc(arc.center, arc.radius, angA, angB, from.bulge > 0);\n};\n\n/**\n * Emit a vertex chain as a subpath (no beginPath — callers compose multiple\n * chains into one even-odd path, e.g. hatch loops).\n */\nexport const emitVertexPath = (\n sink: GeometrySink,\n vertices: PolylineVertex[],\n closed: boolean,\n): void => {\n sink.moveTo({ x: vertices[0].x, y: vertices[0].y });\n for (let i = 1; i < vertices.length; i++) {\n segmentTo(sink, vertices[i - 1], vertices[i]);\n }\n if (closed) {\n segmentTo(sink, vertices[vertices.length - 1], vertices[0]);\n sink.closePath();\n }\n};\n\nconst buildPolylinePath = (obj: Polyline, sink: GeometrySink): void => {\n sink.beginPath();\n emitVertexPath(sink, obj.points, obj.closed);\n};\n\nexport const paintPolyline = (\n obj: Polyline,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n buildPolylinePath(obj, sink);\n sink.stroke(env.style);\n};\n","import type { Circle } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintCircle = (\n obj: Circle,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n sink.beginPath();\n sink.arc(obj.center, obj.radius, 0, Math.PI * 2, true);\n sink.closePath();\n sink.stroke(env.style);\n};\n","import type { Arc } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintArc = (obj: Arc, sink: GeometrySink, env: PaintEnv): void => {\n sink.beginPath();\n sink.arc(obj.center, obj.radius, obj.startAngle, obj.endAngle, true);\n sink.stroke(env.style);\n};\n","import type { Ellipse } from \"../../model/objects\";\nimport { angle, len } from \"../../geometry/vec2\";\nimport { ellipseSweep } from \"../../geometry/ellipse\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintEllipse = (\n obj: Ellipse,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const rx = len(obj.majorAxis);\n if (rx < 1e-12) return;\n const sweep = ellipseSweep(obj);\n sink.beginPath();\n sink.ellipse(\n obj.center,\n rx,\n rx * obj.ratio,\n angle(obj.majorAxis),\n obj.startAngle,\n obj.startAngle + sweep,\n );\n sink.stroke(env.style);\n};\n","import type { Hatch } from \"../../model/objects\";\nimport {\n computePatternGeometry,\n estimatePatternSegments,\n getHatchPattern,\n MAX_HATCH_SEGMENTS,\n} from \"../../model/hatchPatterns\";\nimport { verticesToPolygon } from \"../../geometry/polyline\";\nimport { computeHatchLines, type GeometrySink } from \"../sink\";\nimport { ANSI31_BASE_SPACING } from \"../../export/dxf/hatchPattern\";\nimport type { PaintEnv } from \"./index\";\nimport { emitVertexPath } from \"./polyline\";\n\n/** Stand-in for the single-family fills (\"lines\" / unknown pattern name):\n * deltaY 1 so the estimator's `scale` argument IS the line spacing. */\nconst SINGLE_FAMILY = {\n name: \"\",\n lines: [{ angle: 0, origin: { x: 0, y: 0 }, deltaX: 0, deltaY: 1 }],\n};\n\nconst paintSolid = (obj: Hatch, sink: GeometrySink, env: PaintEnv): void => {\n // All loops as one even-odd path: loop[0] outer, the rest are holes.\n sink.beginPath();\n for (const loop of obj.loops) emitVertexPath(sink, loop.points, true);\n sink.fill({ color: env.style.color, opacity: env.style.opacity });\n};\n\n/** Gradient geometry from the loops' bbox. linear: an axis through the\n * center along the fill angle, spanning the bbox's projection onto that\n * direction — the full color ramp is always visible whatever the region's\n * shape and rotation. radial: color1 at the center fading to color2 at the\n * farthest bbox corner. */\nconst paintGradient = (\n obj: Hatch,\n fill: {\n shape: \"linear\" | \"radial\";\n color1: string;\n color2: string;\n angle: number;\n },\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const loop of obj.loops)\n for (const p of loop.points) {\n if (p.x < minX) minX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.x > maxX) maxX = p.x;\n if (p.y > maxY) maxY = p.y;\n }\n if (minX > maxX) return;\n const c = { x: (minX + maxX) / 2, y: (minY + maxY) / 2 };\n const hw = (maxX - minX) / 2;\n const hh = (maxY - minY) / 2;\n let from: { x: number; y: number };\n let to: { x: number; y: number };\n if (fill.shape === \"radial\") {\n from = c;\n const r = Math.max(Math.hypot(hw, hh), 1e-6);\n to = { x: c.x + r, y: c.y };\n } else {\n const dir = { x: Math.cos(fill.angle), y: Math.sin(fill.angle) };\n const r = Math.max(Math.abs(dir.x) * hw + Math.abs(dir.y) * hh, 1e-6);\n from = { x: c.x - dir.x * r, y: c.y - dir.y * r };\n to = { x: c.x + dir.x * r, y: c.y + dir.y * r };\n }\n sink.beginPath();\n for (const loop of obj.loops) emitVertexPath(sink, loop.points, true);\n sink.fill({\n color: fill.color1,\n opacity: env.style.opacity,\n gradient: { shape: fill.shape, from, to, color2: fill.color2 },\n });\n};\n\nexport const paintHatch = (\n obj: Hatch,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n if (obj.fill.kind === \"solid\") {\n paintSolid(obj, sink, env);\n return;\n }\n if (obj.fill.kind === \"gradient\") {\n paintGradient(obj, obj.fill, sink, env);\n return;\n }\n // Pattern lines clipped to the loops (pure math — no canvas clip needed,\n // and the identical segments feed PDF/DXF export later). The clipping is\n // the expensive part, so it is cached per object when the caller keeps one.\n let lines = env.cache?.hatchLines.get(obj);\n if (!lines) {\n const rings = obj.loops.map((loop) => verticesToPolygon(loop.points));\n // fill.scale × obj.scale is the effective world-mm multiplier (obj.scale\n // is the shared annotation-scale knob, like the \"lines\" fill uses).\n const s =\n obj.fill.kind === \"pattern\" ? obj.fill.scale * obj.scale : obj.scale;\n const pat =\n obj.fill.kind === \"pattern\" ? getHatchPattern(obj.fill.name) : undefined;\n // MaxHatch-style ceiling (estimated BEFORE generating): a pattern this\n // dense reads as tone and its segments would stall paint/export — draw\n // it as a faint solid instead. Estimated per paint, never cached — the\n // estimate is a bbox scan, and caching would need a sentinel type.\n const estimate = pat\n ? estimatePatternSegments(rings, pat, s)\n : estimatePatternSegments(\n rings,\n SINGLE_FAMILY,\n obj.fill.kind === \"pattern\"\n ? s * ANSI31_BASE_SPACING\n : obj.fill.spacing * obj.scale,\n );\n if (estimate > MAX_HATCH_SEGMENTS) {\n paintSolid(obj, sink, {\n ...env,\n style: { ...env.style, opacity: 0.25 * (env.style.opacity ?? 1) },\n });\n return;\n }\n if (obj.fill.kind === \"pattern\") {\n lines = pat\n ? computePatternGeometry(rings, pat, obj.fill.angle, s)\n : // Unknown name: fall back to a single ANSI31-style family.\n computeHatchLines(rings, obj.fill.angle, s * ANSI31_BASE_SPACING);\n } else {\n lines = computeHatchLines(\n rings,\n obj.fill.angle,\n obj.fill.spacing * obj.scale,\n );\n }\n env.cache?.hatchLines.set(obj, lines);\n }\n if (lines.length === 0) return;\n sink.beginPath();\n for (const seg of lines) {\n sink.moveTo(seg.a);\n sink.lineTo(seg.b);\n }\n sink.stroke({\n color: env.style.color,\n widthMm: Math.min(env.style.widthMm, 0.18),\n opacity: env.style.opacity,\n });\n};\n","import type { ArrowType } from \"../../model/objects\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport { add, norm, perp, scale, sub } from \"../../geometry/vec2\";\nimport type { GeometrySink } from \"../sink\";\n\n/**\n * Arrowhead at `tip`, body extending toward `toward`. Styles follow the\n * standard DXF arrowhead blocks: filled (ClosedFilled), open (Open 30°),\n * tick (ArchTick — oblique stroke across the line), dot (filled circle),\n * none.\n */\nexport const paintArrowhead = (\n sink: GeometrySink,\n tip: Vec2,\n toward: Vec2,\n size: number,\n color: string,\n type: ArrowType = \"filled\",\n opacity?: number,\n): void => {\n if (type === \"none\") return;\n const dir = norm(sub(toward, tip));\n if (dir.x === 0 && dir.y === 0) return;\n\n switch (type) {\n case \"filled\": {\n const base = add(tip, scale(dir, size));\n const half = scale(perp(dir), size / 3);\n sink.beginPath();\n sink.moveTo(tip);\n sink.lineTo(add(base, half));\n sink.lineTo(sub(base, half));\n sink.closePath();\n sink.fill({ color, opacity });\n break;\n }\n case \"open\": {\n const base = add(tip, scale(dir, size));\n const half = scale(perp(dir), size / 3);\n sink.beginPath();\n sink.moveTo(add(base, half));\n sink.lineTo(tip);\n sink.lineTo(sub(base, half));\n sink.stroke({ color, widthMm: Math.min(size / 10, 0.25), opacity });\n break;\n }\n case \"tick\": {\n // 45° oblique stroke centered on the tip (architectural tick).\n const diag = scale(norm(add(dir, perp(dir))), size / 2);\n sink.beginPath();\n sink.moveTo(sub(tip, diag));\n sink.lineTo(add(tip, diag));\n sink.stroke({ color, widthMm: Math.min(size / 8, 0.35), opacity });\n break;\n }\n case \"dot\": {\n sink.beginPath();\n sink.arc(tip, size / 4, 0, Math.PI * 2, true);\n sink.fill({ color, opacity });\n break;\n }\n }\n};\n","// Text painter. The alignment involutions and box-corner geometry live in\n// ../textGeometry (shared with snap/hit-testing); this file is the sink\n// drawing pass. Text WIDTH measurement is the one non-geometric input — it is\n// taken from the sink's own `measureText` (canvas-backed on screen,\n// font-metric in a headless/PDF sink), so no DOM leaks into the kernel.\n\nimport type { Text } from \"../../model/objects\";\nimport { effectiveTextFont } from \"../../model/objects\";\nimport { add, fromAngle, perp, scale } from \"../../geometry/vec2\";\nimport { lineSegments, textBlock, type TextMeasurer } from \"../textMetrics\";\nimport { approximateTextMeasurer } from \"../textMeasurer\";\nimport {\n textArrowSize,\n textArrowType,\n textFrameGeometry,\n textHeight,\n textWidth,\n} from \"../textGeometry\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintArrowhead } from \"./arrows\";\nimport { emitVertexPath } from \"./polyline\";\n\nexport const paintText = (\n obj: Text,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n // Bind the object's effective font (own, else document text style) so\n // wrap/frame measurement matches what the sink will draw.\n const { font, widthFactor } = effectiveTextFont(obj, env.textStyles);\n const measure: TextMeasurer = {\n measureTextWidth: (text, heightMm) =>\n sink.measureText(text, heightMm, font, widthFactor).width,\n };\n // Tab-cell advancement uses the DETERMINISTIC approximate measurer, not\n // the sink's: each sink measures with its own font metrics (canvas glyphs,\n // jsPDF Helvetica, the Inter table), and a near-boundary cell would land\n // on a different tab stop per output — columns misaligning between the\n // canvas/PNG and the PDF. With a shared measurer every output picks the\n // same stops by construction; a real glyph run may over/underfill its\n // cell by the approximation error instead.\n const tabStopMeasure: TextMeasurer = {\n measureTextWidth: (text, heightMm) =>\n approximateTextMeasurer.measureTextWidth(\n text,\n heightMm,\n font,\n widthFactor,\n ),\n };\n\n const { color, widthMm, opacity } = env.style;\n\n // Leader lines first (annotative geometry under the glyphs).\n for (const line of obj.leaderLines) {\n sink.beginPath();\n sink.moveTo(line[0]);\n for (let i = 1; i < line.length; i++) sink.lineTo(line[i]);\n sink.stroke({ color, widthMm, opacity });\n\n paintArrowhead(\n sink,\n line[0],\n line[1],\n textArrowSize(obj, env.textStyles),\n color,\n textArrowType(obj, env.textStyles),\n opacity,\n );\n }\n\n // Frame border under the glyphs.\n for (const part of textFrameGeometry(obj, measure, env.textStyles)) {\n sink.beginPath();\n emitVertexPath(sink, part.points, part.closed);\n sink.stroke({ color, widthMm, opacity });\n }\n\n // Wrapping re-measures every word; cache the block per object. The cache\n // is per consumer (PaintEnv.cache), so different measurers never mix. The\n // `base` guard drops entries when the document text style is edited (an\n // inherited-font text rewraps without the object itself changing).\n const height = textHeight(obj, env.textStyles);\n const cached = env.cache?.textBlocks.get(obj);\n let block = cached?.base === env.textStyles ? cached.block : undefined;\n if (!block) {\n block = textBlock(obj.content, height, measure, textWidth(obj));\n env.cache?.textBlocks.set(obj, { base: env.textStyles, block });\n }\n const u = fromAngle(obj.rotation);\n const vUp = perp(u);\n // Shift the first line up so the whole block (not just line 0) honours\n // vAlign: top-aligned blocks grow down, bottom-aligned grow up.\n const vA = obj.vAlign;\n const up =\n vA === \"top\"\n ? 0\n : vA === \"center\"\n ? ((block.lines.length - 1) * block.lineHeight) / 2\n : (block.lines.length - 1) * block.lineHeight;\n const hA = obj.hAlign;\n for (let i = 0; i < block.lines.length; i++) {\n const lineAnchor = add(obj.position, scale(vUp, up - i * block.lineHeight));\n const spec = {\n heightMm: height,\n rotation: obj.rotation,\n vAlign: vA,\n color: env.style.color,\n font,\n widthFactor,\n opacity: env.style.opacity,\n };\n const segs = lineSegments(block.lines[i], height, tabStopMeasure);\n if (segs.length === 1) {\n sink.text({\n ...spec,\n text: segs[0].text,\n anchor: lineAnchor,\n hAlign: hA,\n });\n continue;\n }\n // Tabbed line: one left-anchored run per segment at its tab-stop offset.\n // Offsets measure from the BLOCK's left edge (not the line's own width),\n // so columns stay aligned across rows under every alignment — the MTEXT\n // model, where tabs run from the paragraph box edge.\n const start =\n hA === \"left\" ? 0 : hA === \"center\" ? -block.width / 2 : -block.width;\n for (const seg of segs) {\n if (!seg.text) continue; // consecutive tabs: the stop still advanced\n sink.text({\n ...spec,\n text: seg.text,\n anchor: add(lineAnchor, scale(u, start + seg.x)),\n hAlign: \"left\",\n });\n }\n }\n};\n","// Dimension painter (all kinds). The geometry derivation is shared with\n// snap/hit-testing and DXF explosion — it lives in ../dimensionGeometry so\n// this file is purely the sink drawing pass.\n\nimport type { Dimension } from \"../../model/objects\";\nimport { add, fromAngle, scale } from \"../../geometry/vec2\";\nimport { dimensionGeometry } from \"../dimensionGeometry\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintArrowhead } from \"./arrows\";\n\nexport const paintDimension = (\n obj: Dimension,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n // The derivation is pure in (obj, dimStyles) — both are replaced on edit,\n // so a cached entry is valid exactly while both references match.\n const cached = env.cache?.dimGeometry.get(obj);\n const geom =\n cached && cached.base === env.dimStyles\n ? cached.geom\n : dimensionGeometry(obj, env.dimStyles);\n env.cache?.dimGeometry.set(obj, { base: env.dimStyles, geom });\n if (!geom) return;\n // Dimension linework follows the object/layer linetype (dashMm) like any\n // other stroke; arrowheads and text stay solid. Only the width is capped —\n // annotation linework stays hairline even on heavy layers.\n const stroke = {\n color: env.style.color,\n widthMm: Math.min(env.style.widthMm, 0.18),\n dashMm: env.style.dashMm,\n opacity: env.style.opacity,\n };\n\n sink.beginPath();\n for (const seg of [...geom.extensionLines, ...geom.dimLines]) {\n sink.moveTo(seg.a);\n sink.lineTo(seg.b);\n }\n if (geom.dimArc) {\n const arc = geom.dimArc;\n sink.moveTo(add(arc.center, scale(fromAngle(arc.startAngle), arc.radius)));\n sink.arc(arc.center, arc.radius, arc.startAngle, arc.endAngle, true);\n }\n sink.stroke(stroke);\n\n for (const arrow of geom.arrows) {\n paintArrowhead(\n sink,\n arrow.tip,\n arrow.toward,\n arrow.size,\n env.style.color,\n geom.arrowType,\n env.style.opacity,\n );\n }\n\n for (const text of geom.texts) {\n sink.text({\n text: text.content,\n anchor: text.anchor,\n heightMm: text.height,\n rotation: text.rotation,\n hAlign: \"center\",\n vAlign: \"center\",\n color: env.style.color,\n font: text.font,\n widthFactor: text.widthFactor,\n opacity: env.style.opacity,\n });\n }\n};\n","// Dash resolution for the paint layer. Line-type definitions now live in the\n// named library (model/lineTypes.ts, curated set + embedded built-in catalogue);\n// this module turns a line-type NAME into the mm dash array the sinks consume,\n// so screen output matches print (both use true mm; only overlay chrome is\n// screen-constant). Patterns are defined per 1 mm of line width — callers\n// scale them by resolvedWidth × lineTypeScale (CELTSCALE) via scaleDash.\n\nimport { getLineType, renderDashes } from \"../model/lineTypes\";\n\nexport const dashForLineType = (\n lineType: string | undefined,\n): number[] | undefined => {\n if (!lineType) return undefined;\n const pattern = getLineType(lineType);\n return pattern ? renderDashes(pattern) : undefined;\n};\n\n/** Apply a length multiplier (resolved width × CELTSCALE) to a dash pattern. */\nexport const scaleDash = (\n dash: number[] | undefined,\n multiplier: number | undefined,\n): number[] | undefined =>\n dash && multiplier !== undefined && multiplier !== 1\n ? dash.map((d) => d * multiplier)\n : dash;\n","import { blockPivot, type Block, type ModelObject } from \"../../model/objects\";\nimport {\n getBlockError,\n getEvaluatedWorldChildren,\n} from \"../../extensions/evalBlock\";\nimport { dashForLineType, scaleDash } from \"../lineTypes\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\nimport { paintObject } from \"./index\";\n\nconst ERROR_COLOR = \"#ef4444\";\n\nexport const paintBlockInstance = (\n obj: Block,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const children = getEvaluatedWorldChildren(\n obj,\n env.blockDefinitions,\n env.resolveObject,\n env, // its text / dim styles: what draw's `styles` reads\n );\n const error = getBlockError(obj.id);\n\n if (error) {\n // Dashed red placeholder at the pivot (first point input).\n const pivot = blockPivot(obj);\n const s = 6;\n sink.beginPath();\n sink.moveTo({ x: pivot.x - s, y: pivot.y - s });\n sink.lineTo({ x: pivot.x + s, y: pivot.y - s });\n sink.lineTo({ x: pivot.x + s, y: pivot.y + s });\n sink.lineTo({ x: pivot.x - s, y: pivot.y + s });\n sink.closePath();\n sink.stroke({ color: ERROR_COLOR, widthMm: 0.35, dashMm: [1, 1] });\n sink.text({\n text: \"!\",\n anchor: pivot,\n heightMm: s,\n rotation: 0,\n hAlign: \"center\",\n vAlign: \"center\",\n color: ERROR_COLOR,\n });\n return;\n }\n\n paintChildren(children, sink, env);\n};\n\n/** Paint derived world children (block instances, tables): highlight paints\n * (forceStyle) keep the caller's style so the whole object reads as one\n * silhouette; normal paints resolve style per child over the parent's. */\nexport const paintChildren = (\n children: readonly ModelObject[],\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n for (const child of children) {\n paintObject(\n child,\n sink,\n env.forceStyle\n ? env\n : {\n style: {\n color: child.color ?? env.style.color,\n widthMm: child.lineWidth ?? env.style.widthMm,\n // Same width-proportional dash rule as resolveStyle.\n dashMm:\n scaleDash(\n dashForLineType(child.lineType),\n (child.lineWidth ?? env.style.widthMm) *\n (child.lineTypeScale ?? 1),\n ) ?? env.style.dashMm,\n opacity: child.opacity ?? env.style.opacity,\n },\n dimStyles: env.dimStyles,\n textStyles: env.textStyles,\n blockDefinitions: env.blockDefinitions,\n resolveObject: env.resolveObject,\n assets: env.assets,\n },\n );\n }\n};\n","// Viewport frame outline. This painter serves selection/hover highlights on\n// the overlay; the paper scene draws viewport CONTENT via layoutPaint and its\n// own chrome-colored frame pass, and the frame never reaches print output.\n\nimport type { Viewport } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintViewport = (\n obj: Viewport,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const { x, y, w, h } = obj.rect;\n sink.beginPath();\n sink.moveTo({ x, y });\n sink.lineTo({ x: x + w, y });\n sink.lineTo({ x: x + w, y: y + h });\n sink.lineTo({ x, y: y + h });\n sink.closePath();\n sink.stroke({ color: env.style.color, widthMm: env.style.widthMm });\n};\n","import type { ImageObject } from \"../../model/objects\";\nimport { imageCorners } from \"../../transform\";\nimport type { GeometrySink } from \"../sink\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintImage = (\n obj: ImageObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const data = env.assets?.[obj.assetId];\n // forceStyle = selection/hover highlight: a bitmap can't take a highlight\n // color, so the footprint outline stands in for it.\n if (data !== undefined && !env.forceStyle) {\n sink.image({\n data,\n origin: obj.origin,\n widthMm: obj.width,\n heightMm: obj.height,\n rotation: obj.rotation,\n opacity: env.style.opacity ?? 1,\n });\n return;\n }\n // Frame; crossed diagonals only when the asset is actually missing.\n const [a, b, c, d] = imageCorners(obj);\n sink.beginPath();\n sink.moveTo(a);\n sink.lineTo(b);\n sink.lineTo(c);\n sink.lineTo(d);\n sink.closePath();\n if (data === undefined) {\n sink.moveTo(a);\n sink.lineTo(c);\n sink.moveTo(b);\n sink.lineTo(d);\n }\n sink.stroke(env.style);\n};\n","// Table painter: the derived world children (rules + cell texts) from\n// ../tableLayout, painted like block-instance children.\n\nimport type { Table } from \"../../model/objects\";\nimport type { GeometrySink } from \"../sink\";\nimport { tableLayout } from \"../tableLayout\";\nimport { paintChildren } from \"./block\";\nimport type { PaintEnv } from \"./index\";\n\nexport const paintTable = (\n obj: Table,\n sink: GeometrySink,\n env: PaintEnv,\n): void => paintChildren(tableLayout(obj, env.textStyles).children, sink, env);\n","// A uniform-grid index over one snap entry's primitives (see\n// SnapCacheEntry.near): built on first query, it hands back only what lies\n// in a box — a referenced site plan has 10⁵+ segments, and scanning them all\n// on every pointer move made snapping lag and forced a cap that left most\n// edges unsnappable.\n\nimport { boundsIntersect, isEmptyBounds, type AABB } from \"../geometry/bounds\";\nimport type { SnapCacheEntry } from \"./types\";\n\n/** Cells per side of the grid over the entry's geometry. */\nconst GRID = 256;\n/** An arc/ellipse box spanning more cells than this goes in the\n * always-checked list instead (few curves are that big). Segments never do:\n * they are indexed along the cells they actually cross. */\nconst MAX_CELLS = 64;\n\ntype Kind = 0 | 1 | 2 | 3; // point, segment, arc, ellipse\n\nconst segmentBox = (s: {\n a: { x: number; y: number };\n b: { x: number; y: number };\n}): AABB => ({\n minX: Math.min(s.a.x, s.b.x),\n maxX: Math.max(s.a.x, s.b.x),\n minY: Math.min(s.a.y, s.b.y),\n maxY: Math.max(s.a.y, s.b.y),\n});\n\nexport const withNearIndex = (entry: SnapCacheEntry): SnapCacheEntry => {\n // The grid covers the entry's GEOMETRY bounds, not pointBounds: a\n // reference's insertion point can sit 10¹⁰ mm from its content (a survey\n // file placed back at the origin), which would squash everything into one\n // cell. Primitives outside the grid go in the always-checked list.\n const b = isEmptyBounds(entry.bounds) ? entry.pointBounds : entry.bounds;\n const size = Math.max(b.maxX - b.minX, b.maxY - b.minY, 1e-9) / GRID;\n const cell = (v: number, min: number) =>\n Math.min(GRID - 1, Math.max(0, Math.floor((v - min) / size)));\n const outside = (box: AABB) =>\n box.minX < b.minX ||\n box.maxX > b.maxX ||\n box.minY < b.minY ||\n box.maxY > b.maxY;\n // Packed ids: kind in the low 2 bits.\n const id = (kind: Kind, i: number) => i * 4 + kind;\n\n let index: { cells: Map<number, number[]>; big: number[] } | null = null;\n const build = () => {\n const cells = new Map<number, number[]>();\n const big: number[] = [];\n const add = (k: number, key: number) => {\n const list = cells.get(k);\n if (list) {\n if (list[list.length - 1] !== key) list.push(key);\n } else cells.set(k, [key]);\n };\n const insert = (key: number, box: AABB) => {\n const x0 = cell(box.minX, b.minX);\n const x1 = cell(box.maxX, b.minX);\n const y0 = cell(box.minY, b.minY);\n const y1 = cell(box.maxY, b.minY);\n if (outside(box) || (x1 - x0 + 1) * (y1 - y0 + 1) > MAX_CELLS) {\n big.push(key);\n return;\n }\n for (let x = x0; x <= x1; x++)\n for (let y = y0; y <= y1; y++) add(x * GRID + y, key);\n };\n entry.points.forEach((sp, i) =>\n insert(id(0, i), {\n minX: sp.p.x,\n maxX: sp.p.x,\n minY: sp.p.y,\n maxY: sp.p.y,\n }),\n );\n // Segments go in the cells along them — a site plan's long hatch and\n // boundary lines would otherwise fill whole rows or be scanned always.\n entry.segments.forEach((s, i) => {\n const key = id(1, i);\n if (outside(segmentBox(s))) {\n big.push(key);\n return;\n }\n // ponytail: sampled every quarter cell, so a line clipping a cell\n // corner by less than that can miss it — the query box (pick/snap\n // tolerance) usually overlaps the neighbour; exact grid traversal if\n // that ever shows.\n const n =\n Math.ceil(Math.hypot(s.b.x - s.a.x, s.b.y - s.a.y) / (size / 4)) + 1;\n let last = -1;\n for (let t = 0; t <= n; t++) {\n const k =\n cell(s.a.x + ((s.b.x - s.a.x) * t) / n, b.minX) * GRID +\n cell(s.a.y + ((s.b.y - s.a.y) * t) / n, b.minY);\n if (k !== last) add(k, key);\n last = k;\n }\n });\n entry.arcs.forEach((a, i) =>\n insert(id(2, i), {\n minX: a.center.x - a.radius,\n maxX: a.center.x + a.radius,\n minY: a.center.y - a.radius,\n maxY: a.center.y + a.radius,\n }),\n );\n (entry.ellipses ?? []).forEach((e, i) => {\n const r = Math.hypot(e.majorAxis.x, e.majorAxis.y);\n insert(id(3, i), {\n minX: e.center.x - r,\n maxX: e.center.x + r,\n minY: e.center.y - r,\n maxY: e.center.y + r,\n });\n });\n return { cells, big };\n };\n\n const near = (box: AABB): SnapCacheEntry => {\n const out: SnapCacheEntry = {\n bounds: entry.bounds,\n pointBounds: entry.pointBounds,\n points: [],\n segments: [],\n arcs: [],\n ellipses: [],\n };\n const take = (k: number): void => {\n const i = k >> 2;\n switch ((k & 3) as Kind) {\n case 0:\n out.points.push(entry.points[i]);\n break;\n case 1:\n out.segments.push(entry.segments[i]);\n break;\n case 2:\n out.arcs.push(entry.arcs[i]);\n break;\n case 3:\n out.ellipses!.push(entry.ellipses![i]);\n break;\n }\n };\n if (!boundsIntersect(box, entry.pointBounds)) return out;\n index ??= build();\n // Off the geometry: only the outliers (e.g. a far insertion point).\n if (isEmptyBounds(b) || !boundsIntersect(box, b)) {\n for (const k of index.big) take(k);\n return out;\n }\n const seen = new Set<number>(index.big);\n const x0 = cell(box.minX, b.minX);\n const x1 = cell(box.maxX, b.minX);\n const y0 = cell(box.minY, b.minY);\n const y1 = cell(box.maxY, b.minY);\n for (let x = x0; x <= x1; x++)\n for (let y = y0; y <= y1; y++)\n for (const k of index.cells.get(x * GRID + y) ?? []) seen.add(k);\n for (const k of seen) take(k);\n return out;\n };\n\n return { ...entry, near };\n};\n","// Per-object snap/geometry derivation — the single source of derived geometry\n// for both snapping and hit-testing.\n//\n// KERNEL SEAM: `buildEntry` is PURE. The cache lifecycle (subscription to\n// store invalidation, id→object lookup) stays with the mutation owner; it\n// calls `buildSnapEntry` and memoizes the result. Everything the derivation\n// needs that would otherwise come from a store — the document dim style, the\n// block definitions, and a text measurer — is passed in via `SnapGeometryContext`.\n\nimport type {\n Dimension,\n DimStyle,\n Ellipse,\n Hatch,\n ModelObject,\n Polyline,\n Text,\n TextStyle,\n} from \"../model/objects\";\nimport { blockPivot } from \"../model/objects\";\nimport { imageCenter, imageCorners } from \"../transform\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport { textBoxCorners, textFrameGeometry } from \"../paint/textGeometry\";\nimport { dimensionGeometry } from \"../paint/dimensionGeometry\";\nimport { getEvaluatedWorldChildren } from \"../extensions/evalBlock\";\nimport { verticesToCurves, verticesToPolygon } from \"../geometry/polyline\";\nimport {\n addPointToBounds,\n boundsOfPoints,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../geometry/bounds\";\nimport {\n arcMidPoint,\n arcSweep,\n pointOnArc,\n angleInArc,\n type ArcGeom,\n} from \"../geometry/arcs\";\nimport { mid, normAngle, type Vec2 } from \"../geometry/vec2\";\nimport {\n pointOnEllipse,\n paramInEllipse,\n tessellateEllipse,\n isFullEllipse,\n type EllipseGeom,\n} from \"../geometry/ellipse\";\nimport type { Segment } from \"../geometry/line\";\nimport type { SnapCacheEntry, SnapPoint, SnapSegment } from \"./types\";\nimport { tableLayout } from \"../paint/tableLayout\";\nimport { withNearIndex } from \"./nearIndex\";\nimport type { ReferenceObject } from \"../model/objects\";\nimport {\n applyMat,\n clipSegment,\n placedBounds,\n placedCorners,\n referenceTransform,\n type ReferenceContent,\n} from \"../reference/reference\";\n\n/** Everything the derivation needs that a store would otherwise supply. */\nexport interface SnapGeometryContext {\n /** Document dimension style (dimension geometry resolves overrides on it). */\n dimStyles: readonly DimStyle[];\n /** Document text style (texts without their own font inherit from it). */\n textStyles: readonly TextStyle[];\n /** The document's block module sources, for evaluating instance children. */\n blockDefinitions: readonly string[];\n /**\n * Document-wide object lookup for block object-reference inputs; absent →\n * referenced inputs evaluate as null (see BlockObjectResolver).\n */\n resolveObject?: (id: string) => ModelObject | undefined;\n /** Text width measurement (canvas-backed in editor, font-metric in Node). */\n measure: TextMeasurer;\n /** Loaded reference content (see PaintEnv.resolveReference); absent or\n * null → a reference snaps and picks by its frame only. */\n resolveReference?: (ref: ReferenceObject) => ReferenceContent | null;\n}\n\n/** buildEntry output; `pointBounds` is derived centrally in buildSnapEntry. */\nexport type BuiltEntry = Omit<SnapCacheEntry, \"pointBounds\">;\n\n/** Tight AABB of an arc: endpoints plus axis-crossing extremes within range. */\nconst arcBoundsInto = (a: ArcGeom, b: AABB): void => {\n addPointToBounds(b, pointOnArc(a, a.startAngle));\n addPointToBounds(b, pointOnArc(a, a.endAngle));\n for (const ang of [0, Math.PI / 2, Math.PI, (3 * Math.PI) / 2]) {\n if (angleInArc(a, ang)) addPointToBounds(b, pointOnArc(a, ang));\n }\n};\n\nconst curveBounds = (segments: Segment[], arcs: ArcGeom[]): AABB => {\n const bounds = emptyBounds();\n for (const s of segments) {\n addPointToBounds(bounds, s.a);\n addPointToBounds(bounds, s.b);\n }\n for (const a of arcs) arcBoundsInto(a, bounds);\n return bounds;\n};\n\nconst buildPolyline = (\n obj: Pick<Polyline, \"points\" | \"closed\">,\n): BuiltEntry => {\n const { segments, arcs } = verticesToCurves(obj.points, obj.closed);\n const points: SnapPoint[] = obj.points.map((v) => ({\n p: { x: v.x, y: v.y },\n type: \"endpoint\" as const,\n }));\n for (const s of segments) points.push({ p: mid(s.a, s.b), type: \"midpoint\" });\n for (const a of arcs) {\n points.push({ p: arcMidPoint(a), type: \"midpoint\" });\n points.push({ p: a.center, type: \"center\" });\n }\n return { bounds: curveBounds(segments, arcs), points, segments, arcs };\n};\n\nconst buildEllipse = (obj: Ellipse): BuiltEntry => {\n const pts = tessellateEllipse(obj);\n const segments: SnapSegment[] = [];\n for (let i = 1; i < pts.length; i++)\n segments.push({ a: pts[i - 1], b: pts[i], chord: true });\n const points: SnapPoint[] = [{ p: obj.center, type: \"center\" }];\n // Axis endpoints act as quadrants; range-filtered for partial ellipses.\n for (const t of [0, Math.PI / 2, Math.PI, (3 * Math.PI) / 2]) {\n if (paramInEllipse(obj, t))\n points.push({ p: pointOnEllipse(obj, t), type: \"quadrant\" });\n }\n if (!isFullEllipse(obj)) {\n points.push({ p: pointOnEllipse(obj, obj.startAngle), type: \"endpoint\" });\n points.push({ p: pointOnEllipse(obj, obj.endAngle), type: \"endpoint\" });\n }\n return {\n bounds: boundsOfPoints(pts),\n points,\n segments,\n arcs: [],\n ellipses: [\n {\n center: obj.center,\n majorAxis: obj.majorAxis,\n ratio: obj.ratio,\n startAngle: obj.startAngle,\n endAngle: obj.endAngle,\n },\n ],\n };\n};\n\nconst buildHatch = (obj: Hatch): BuiltEntry => {\n let bounds = emptyBounds();\n const points: SnapPoint[] = [];\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const rings: Vec2[][] = [];\n for (const loop of obj.loops) {\n const curves = verticesToCurves(loop.points, true);\n segments.push(...curves.segments);\n arcs.push(...curves.arcs);\n for (const v of loop.points)\n points.push({ p: { x: v.x, y: v.y }, type: \"endpoint\" });\n rings.push(verticesToPolygon(loop.points));\n bounds = unionBounds(bounds, curveBounds(curves.segments, curves.arcs));\n }\n return { bounds, points, segments, arcs, rings };\n};\n\nconst buildText = (\n obj: Text,\n measure: TextMeasurer,\n textStyles: readonly TextStyle[],\n): BuiltEntry => {\n // The text box: inside-clicks select (ring), edges support crossing select.\n // A visible frame is real, snappable geometry (snaps like a polyline): a\n // closed frame REPLACES the invisible box outline; a rule is added\n // alongside the box.\n const parts = textFrameGeometry(obj, measure, textStyles);\n const closed = parts.find((p) => p.closed);\n const box = textBoxCorners(obj, measure, textStyles);\n const outline = closed ? verticesToPolygon(closed.points) : box;\n const segments: Segment[] = closed\n ? []\n : box.map((c, i) => ({ a: c, b: box[(i + 1) % box.length] }));\n const points: SnapPoint[] = [{ p: obj.position, type: \"endpoint\" }];\n const arcs: ArcGeom[] = [];\n const bounds = boundsOfPoints(outline);\n for (const part of parts) {\n const e = buildPolyline(part);\n segments.push(...e.segments);\n arcs.push(...e.arcs);\n points.push(...e.points);\n addPointToBounds(bounds, { x: e.bounds.minX, y: e.bounds.minY });\n addPointToBounds(bounds, { x: e.bounds.maxX, y: e.bounds.maxY });\n }\n // Leader lines snap and hit-test like polylines.\n for (const line of obj.leaderLines) {\n for (let i = 1; i < line.length; i++) {\n segments.push({ a: line[i - 1], b: line[i] });\n }\n for (const p of line) {\n points.push({ p, type: \"endpoint\" });\n addPointToBounds(bounds, p);\n }\n }\n return {\n bounds,\n points,\n segments,\n arcs,\n rings: [outline],\n };\n};\n\nconst buildDimension = (\n obj: Dimension,\n dimStyles: readonly DimStyle[],\n measure: TextMeasurer,\n textStyles: readonly TextStyle[],\n): BuiltEntry => {\n const geom = dimensionGeometry(obj, dimStyles);\n const points: SnapPoint[] = obj.points.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n if (!geom) {\n return {\n bounds: boundsOfPoints(obj.points),\n points,\n segments: [],\n arcs: [],\n };\n }\n const segments = [...geom.extensionLines, ...geom.dimLines];\n // The measurement text boxes: inside-clicks select the dimension (rings),\n // edges support crossing selection — same treatment as text objects.\n const rings: Vec2[][] = [];\n for (const text of geom.texts) {\n const corners = textBoxCorners(\n {\n type: \"text\",\n id: obj.id,\n layerId: obj.layerId,\n position: text.anchor,\n content: text.content,\n rotation: text.rotation,\n hAlign: \"center\",\n vAlign: \"center\",\n leaderLines: [],\n scale: 1,\n // The dim style's resolved metrics, pinned as overrides so the\n // document TEXT style can't leak into dimension text boxes.\n styleOverride: {\n textHeight: text.height,\n font: text.font,\n widthFactor: text.widthFactor,\n },\n },\n measure,\n textStyles,\n );\n rings.push(corners);\n segments.push(\n ...corners.map((c, i) => ({\n a: c,\n b: corners[(i + 1) % corners.length],\n })),\n );\n }\n const arcs = geom.dimArc\n ? [\n {\n center: geom.dimArc.center,\n radius: geom.dimArc.radius,\n startAngle: geom.dimArc.startAngle,\n endAngle: geom.dimArc.endAngle,\n },\n ]\n : [];\n const bounds = curveBounds(segments, arcs);\n for (const p of obj.points) addPointToBounds(bounds, p);\n for (const seg of geom.dimLines)\n points.push({ p: mid(seg.a, seg.b), type: \"midpoint\" });\n return { bounds, points, segments, arcs, rings };\n};\n\n/**\n * Derived snap/hit-test geometry for one object (without `pointBounds`, which\n * `buildSnapEntry` adds). Pure: pass `ctx` for the store-derived inputs.\n */\nexport const buildEntry = (\n obj: ModelObject,\n ctx: SnapGeometryContext,\n): BuiltEntry => {\n switch (obj.type) {\n case \"line\": {\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.a);\n addPointToBounds(bounds, obj.b);\n return {\n bounds,\n points: [\n { p: obj.a, type: \"endpoint\" },\n { p: obj.b, type: \"endpoint\" },\n { p: mid(obj.a, obj.b), type: \"midpoint\" },\n ],\n segments: [{ a: obj.a, b: obj.b }],\n arcs: [],\n };\n }\n case \"point\": {\n // One snap point (node); the degenerate segment is what makes the dot\n // click-pickable — distanceToObject only measures segments/arcs/rings.\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.p);\n return {\n bounds,\n points: [{ p: obj.p, type: \"endpoint\" }],\n segments: [{ a: obj.p, b: obj.p }],\n arcs: [],\n };\n }\n case \"polyline\":\n return buildPolyline(obj);\n case \"circle\": {\n const { center: center, radius } = obj;\n const bounds: AABB = {\n minX: center.x - radius,\n minY: center.y - radius,\n maxX: center.x + radius,\n maxY: center.y + radius,\n };\n const geom: ArcGeom = {\n center,\n radius,\n startAngle: 0,\n endAngle: Math.PI * 2 - 1e-9,\n };\n const quadrants: SnapPoint[] = [\n 0,\n Math.PI / 2,\n Math.PI,\n (3 * Math.PI) / 2,\n ].map((ang) => ({\n p: pointOnArc(geom, ang),\n type: \"quadrant\" as const,\n }));\n return {\n bounds,\n points: [{ p: center, type: \"center\" }, ...quadrants],\n segments: [],\n arcs: [geom],\n };\n }\n case \"arc\": {\n const geom: ArcGeom = {\n center: obj.center,\n radius: obj.radius,\n startAngle: normAngle(obj.startAngle),\n endAngle: normAngle(obj.endAngle),\n };\n const bounds = emptyBounds();\n arcBoundsInto(geom, bounds);\n return {\n bounds,\n points: [\n { p: pointOnArc(geom, geom.startAngle), type: \"endpoint\" },\n { p: pointOnArc(geom, geom.endAngle), type: \"endpoint\" },\n {\n p: pointOnArc(geom, geom.startAngle + arcSweep(geom) / 2),\n type: \"midpoint\",\n },\n { p: geom.center, type: \"center\" },\n ],\n segments: [],\n arcs: [geom],\n };\n }\n case \"ellipse\":\n return buildEllipse(obj);\n case \"hatch\":\n return buildHatch(obj);\n case \"text\":\n return buildText(obj, ctx.measure, ctx.textStyles);\n case \"dimension\":\n return buildDimension(obj, ctx.dimStyles, ctx.measure, ctx.textStyles);\n case \"viewport\": {\n // Frame corners/edges snap and hit-test; the interior ring makes\n // clicks inside the viewport select it (annotations still win —\n // pickObjectAt prefers non-viewport hits).\n const { x, y, w, h } = obj.rect;\n const corners: Vec2[] = [\n { x, y },\n { x: x + w, y },\n { x: x + w, y: y + h },\n { x, y: y + h },\n ];\n const segments: Segment[] = corners.map((c, i) => ({\n a: c,\n b: corners[(i + 1) % corners.length],\n }));\n const points: SnapPoint[] = corners.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n for (const s of segments)\n points.push({ p: mid(s.a, s.b), type: \"midpoint\" });\n return {\n bounds: { minX: x, minY: y, maxX: x + w, maxY: y + h },\n points,\n segments,\n arcs: [],\n rings: [corners],\n };\n }\n case \"block\": {\n // Merge the entries of the evaluated (world-space) children, so block\n // internals snap and hit-test exactly like native geometry.\n // Every point input snaps as an endpoint — the first one IS the\n // pivot (blockPivot falls back to {0,0} for point-less instances).\n const inputPoints = obj.inputs.filter(\n (v): v is Vec2 => typeof v !== \"string\",\n );\n const points: SnapPoint[] = (\n inputPoints.length > 0 ? inputPoints : [blockPivot(obj)]\n ).map((p) => ({ p, type: \"endpoint\" }));\n const segments: Segment[] = [];\n const arcs: ArcGeom[] = [];\n const ellipses: EllipseGeom[] = [];\n const rings: Vec2[][] = [];\n let bounds = emptyBounds();\n for (const { p } of points) addPointToBounds(bounds, p);\n for (const child of getEvaluatedWorldChildren(\n obj,\n ctx.blockDefinitions,\n ctx.resolveObject,\n ctx, // its text / dim styles: what draw's `styles` reads\n )) {\n const entry = buildEntry(child, ctx);\n points.push(...entry.points);\n segments.push(...entry.segments);\n arcs.push(...entry.arcs);\n if (entry.ellipses) ellipses.push(...entry.ellipses);\n // Text/dimension boxes keep their inside-click hit area. Hatch fills\n // don't: pickObjectAt only deprioritizes TOP-LEVEL hatches, so a\n // hatched block would swallow every click over its region.\n // ponytail: rings merge under even-odd, so overlapping text boxes\n // cancel in the overlap — per-child ring sets if that ever matters.\n if (entry.rings && child.type !== \"hatch\") rings.push(...entry.rings);\n bounds = unionBounds(bounds, entry.bounds);\n }\n return { bounds, points, segments, arcs, ellipses, rings };\n }\n case \"table\": {\n // The rules snap and hit-test like lines (endpoints at the grid\n // crossings they start/end on); the outline ring makes clicks\n // anywhere inside pick the table, like text.\n const { outline, children } = tableLayout(obj, ctx.textStyles);\n const segments: Segment[] = [];\n const points: SnapPoint[] = outline.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n for (const c of children) {\n if (c.type !== \"line\") continue;\n segments.push({ a: c.a, b: c.b });\n points.push({ p: c.a, type: \"endpoint\" }, { p: c.b, type: \"endpoint\" });\n }\n return {\n bounds: boundsOfPoints(outline),\n points,\n segments,\n arcs: [],\n rings: [outline],\n };\n }\n case \"image\": {\n // Corners/edges snap and hit-test. Deliberately NO interior ring:\n // a reference image is picked by its outline frame only, so geometry\n // traced over it stays hoverable everywhere inside.\n const corners = imageCorners(obj);\n const segments: Segment[] = corners.map((c, i) => ({\n a: c,\n b: corners[(i + 1) % corners.length],\n }));\n const points: SnapPoint[] = corners.map((p) => ({\n p,\n type: \"endpoint\" as const,\n }));\n for (const s of segments)\n points.push({ p: mid(s.a, s.b), type: \"midpoint\" });\n points.push({ p: imageCenter(obj), type: \"center\" });\n return {\n bounds: boundsOfPoints(corners),\n points,\n segments,\n arcs: [],\n };\n }\n case \"comment\": {\n // Cache entries are camera-independent; the marker is screen-fixed, so\n // only the pin point lives here (tip snaps as an endpoint, marquees\n // catch the tip). The zoom-scaled bubble hit-test is the editor's\n // pickObjectAt special case.\n const bounds = emptyBounds();\n addPointToBounds(bounds, obj.position);\n return {\n bounds,\n points: [{ p: obj.position, type: \"endpoint\" }],\n segments: [{ a: obj.position, b: obj.position }],\n arcs: [],\n };\n }\n case \"reference\":\n return referenceEntry(obj, ctx);\n default: {\n // Every type has a case (a new one fails typecheck here); at runtime\n // an unknown type gets no snap geometry — empty bounds keeps it out\n // of queries.\n obj satisfies never;\n return { bounds: emptyBounds(), points: [], segments: [], arcs: [] };\n }\n }\n};\n\n/** A safety limit only: snapping and picking query a reference's geometry\n * through a spatial index (withNearIndex), so even a 10⁵–10⁶-segment site\n * plan stays fully snappable. Past this a file still draws, unsnapped. */\nexport const MAX_REFERENCE_SNAP_SEGMENTS = 2_000_000;\n\n/**\n * A reference snaps and picks by its CONTENT's geometry, placed by the\n * reference's transform (rotation + uniform scale + optional mirror keep\n * arcs arcs and ellipses ellipses). Deliberately no interior ring: like an\n * image, geometry drawn over a reference stays hoverable. Not loaded → its\n * frame (last known extent, else a small square at the insertion point).\n */\nconst referenceEntry = (\n obj: ReferenceObject,\n ctx: SnapGeometryContext,\n): BuiltEntry => {\n // Switched off: out of every query (empty bounds), like an empty object.\n if (obj.hidden)\n return { bounds: emptyBounds(), points: [], segments: [], arcs: [] };\n const m = referenceTransform(obj);\n const content = ctx.resolveReference?.(obj) ?? null;\n if (!content) {\n const corners = placedCorners(\n m,\n obj.extent ?? {\n minX: 0,\n minY: 0,\n maxX: 5 / obj.scale,\n maxY: 5 / obj.scale,\n },\n );\n const segments = corners.map((a, i) => ({ a, b: corners[(i + 1) % 4] }));\n return {\n bounds: boundsOfPoints(corners),\n points: [\n ...corners.map((p) => ({ p, type: \"endpoint\" as const })),\n { p: obj.position, type: \"endpoint\" as const },\n ],\n segments,\n arcs: [],\n };\n }\n const s = obj.scale;\n const flip = obj.mirrored ? -1 : 1;\n // A file angle → host angle (mirroring reflects across the file's X axis).\n // A left-right flip maps a file angle t to π − t.\n const ang = (t: number) =>\n normAngle((flip < 0 ? Math.PI - t : t) + obj.rotation);\n const linear = (v: Vec2): Vec2 => {\n const o = applyMat(m, { x: 0, y: 0 });\n const p = applyMat(m, v);\n return { x: p.x - o.x, y: p.y - o.y };\n };\n const childCtx: SnapGeometryContext = {\n dimStyles: content.dimStyles,\n textStyles: content.textStyles,\n blockDefinitions: content.blockDefinitions,\n resolveObject: content.resolveObject,\n resolveReference: content.resolveReference,\n measure: ctx.measure,\n };\n const hidden = new Set(obj.hiddenLayers);\n const shown = new Map(\n content.layers.map((l) => [l.id, l.visible && !hidden.has(l.name)]),\n );\n const points: SnapPoint[] = [{ p: obj.position, type: \"endpoint\" }];\n const segments: SnapSegment[] = [];\n const arcs: ArcGeom[] = [];\n const ellipses: EllipseGeom[] = [];\n // A clip crops snapping like drawing. ponytail: curves snap only when\n // wholly inside the clip (no curve/box clipping) — clipped arcs still draw.\n const clip = obj.clip;\n const inClip = (p: Vec2) =>\n !clip ||\n (p.x >= clip.minX &&\n p.x <= clip.maxX &&\n p.y >= clip.minY &&\n p.y <= clip.maxY);\n const curveInClip = (c: Vec2, r: number) =>\n !clip ||\n (c.x - r >= clip.minX &&\n c.x + r <= clip.maxX &&\n c.y - r >= clip.minY &&\n c.y + r <= clip.maxY);\n /** Add one file-space entry, clipped and placed. */\n const add = (e: {\n points: readonly SnapPoint[];\n segments: readonly SnapSegment[];\n arcs: readonly ArcGeom[];\n ellipses?: readonly EllipseGeom[];\n }): void => {\n for (const sp of e.points)\n if (inClip(sp.p)) points.push({ p: applyMat(m, sp.p), type: sp.type });\n for (const seg of e.segments) {\n const kept = clip ? clipSegment(seg.a, seg.b, clip) : [seg.a, seg.b];\n if (kept)\n segments.push({\n a: applyMat(m, kept[0]),\n b: applyMat(m, kept[1]),\n chord: seg.chord,\n });\n }\n for (const a of e.arcs) {\n if (!curveInClip(a.center, a.radius)) continue;\n // Mirroring reverses the sweep: the CCW range swaps ends.\n const [start, end] =\n flip < 0 ? [a.endAngle, a.startAngle] : [a.startAngle, a.endAngle];\n arcs.push({\n center: applyMat(m, a.center),\n radius: a.radius * s,\n startAngle: ang(start),\n endAngle: ang(end),\n });\n }\n for (const el of e.ellipses ?? []) {\n if (!curveInClip(el.center, Math.hypot(el.majorAxis.x, el.majorAxis.y)))\n continue;\n const [start, end] =\n flip < 0\n ? [-el.endAngle, -el.startAngle]\n : [el.startAngle, el.endAngle];\n ellipses.push({\n center: applyMat(m, el.center),\n majorAxis: linear(el.majorAxis),\n ratio: el.ratio,\n startAngle: normAngle(start),\n endAngle: normAngle(end),\n });\n }\n };\n const layerShown = (layer: string) => shown.get(layer) !== false;\n if (content.snap) {\n // Precomputed off the main thread (and, for a raster PDF, the page's\n // vector lines under the image): filter by layer, clip, place.\n const f = content.snap;\n add({\n points: f.points.filter((p) => layerShown(p.layer)),\n segments: f.segments\n .filter((sg) => layerShown(sg.layer))\n .slice(0, MAX_REFERENCE_SNAP_SEGMENTS),\n arcs: f.arcs.filter((ar) => layerShown(ar.layer)),\n ellipses: f.ellipses.filter((el) => layerShown(el.layer)),\n });\n }\n for (const child of content.objects) {\n if (segments.length >= MAX_REFERENCE_SNAP_SEGMENTS) break;\n if (!layerShown(child.layerId)) continue;\n // With precomputed geometry only nested references are left to build.\n if (content.snap && child.type !== \"reference\") continue;\n add(buildEntry(child, childCtx));\n }\n const shownBounds = clip\n ? {\n minX: Math.max(content.bounds.minX, clip.minX),\n minY: Math.max(content.bounds.minY, clip.minY),\n maxX: Math.min(content.bounds.maxX, clip.maxX),\n maxY: Math.min(content.bounds.maxY, clip.maxY),\n }\n : content.bounds;\n const bounds =\n isEmptyBounds(shownBounds) || shownBounds.minX > shownBounds.maxX\n ? boundsOfPoints(points.map((p) => p.p))\n : placedBounds(m, shownBounds);\n return { bounds, points, segments, arcs, ellipses };\n};\n\n/**\n * Full snap-cache entry for an object: `buildEntry` plus the `pointBounds`\n * query box (bounds unioned with every snap point, so off-curve points like\n * an arc's center still fall inside the candidate box). Pure — the caller\n * owns caching and invalidation.\n */\nexport const buildSnapEntry = (\n obj: ModelObject,\n ctx: SnapGeometryContext,\n): SnapCacheEntry => {\n const built = buildEntry(obj, ctx);\n const pointBounds = { ...built.bounds };\n for (const sp of built.points) addPointToBounds(pointBounds, sp.p);\n // A reference can carry a whole site plan: answer \"near the cursor\" from\n // a spatial index instead of scanning it all (SnapCacheEntry.near).\n return obj.type === \"reference\"\n ? withNearIndex({ ...built, pointBounds })\n : { ...built, pointBounds };\n};\n","// DXF import: parse, scale to mm ($INSUNITS), create missing layers, convert\n// entities, add everything in ONE undoable transaction. Paper space comes\n// back too: *Paper_Space blocks (+ the flat inPaperSpace entities of the\n// active layout) are rebuilt as PaperLayouts, VIEWPORT entities become\n// viewport objects, and LAYOUT objects (parsed from the raw OBJECTS section\n// — dxf-parser skips it) supply names, tab order, and sheet sizes.\n\nimport DxfParser from \"dxf-parser\";\nimport type { IEntity, IDxf, IBlock } from \"dxf-parser\";\nimport type {\n ModelObject,\n ModelObjectDto,\n PolylineVertex,\n} from \"../../model/objects\";\nimport { ModelObjectSchema } from \"../../model/objects\";\nimport { dimensionRawToOffset } from \"../../model/migrations\";\nimport type { Layer } from \"../../model/document\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\nimport { PaperLayoutSchema } from \"../../model/paperLayout\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport { dist } from \"../../geometry/vec2\";\nimport {\n arcEndPoint,\n arcFrom3Points,\n arcMidPoint,\n arcStartPoint,\n bulgeFrom3Points,\n bulgeToArc,\n} from \"../../geometry/arcs\";\nimport { aciToHex, rgbToHex } from \"../../export/dxf/aci\";\nimport { getHatchPattern } from \"../../model/hatchPatterns\";\nimport { getLineType } from \"../../model/lineTypes\";\nimport {\n ViewportHandler,\n HatchHandler,\n AcadTableHandler,\n type AcadTableData,\n LeaderHandler,\n MultiLeaderHandler,\n} from \"./extraEntities\";\nimport { parseLayoutObjects } from \"./objectsSection\";\nimport { referenceFormatOf } from \"../../reference/reference\";\n\nconst DEG2RAD = Math.PI / 180;\n\n/** Zoom-lock bit of the VIEWPORT status flags (group 90). */\nconst VIEWPORT_LOCKED_FLAG = 16384;\n\n/** mm per drawing unit, from $INSUNITS. */\nconst unitFactor = (insunits: unknown): number => {\n switch (insunits) {\n case 1:\n return 25.4; // inches\n case 2:\n return 304.8; // feet\n case 5:\n return 10; // cm\n case 6:\n return 1000; // m\n case 4:\n case 0:\n default:\n return 1; // mm / unspecified\n }\n};\n\n/** Lineweight every imported layer/entity gets (DXF weights aren't read). */\nconst IMPORT_LINE_WIDTH_MM = 0.25;\n\ninterface ImportContext {\n f: number;\n layerIdByName: Map<string, string>;\n /** Layers whose line type dashes — their entities inherit a dash pattern,\n * so group 48 conversion applies even without an entity-level line type. */\n dashedLayerIds: Set<string>;\n defaultLayerId: string;\n skipped: Map<string, number>;\n dimTextHeight: number;\n dimArrowSize: number;\n /** Overall dimension scale ($DIMSCALE); 1 = none. Applied per dimension. */\n dimScale: number;\n /** Exact colors (group 420) by entity handle — see scanTrueColors. */\n trueColorByHandle: Map<string, string>;\n}\n\n/**\n * Pre-scan the raw DXF for true colors (group 420). dxf-parser applies group\n * codes last-wins, so a 62 written AFTER a 420 (our own writer's order)\n * clobbers the exact color with the ACI palette value, and its LAYER table\n * parser ignores 420 entirely — this keeps both exact.\n */\nconst scanTrueColors = (\n text: string,\n): { byHandle: Map<string, string>; byLayerName: Map<string, string> } => {\n const byHandle = new Map<string, string>();\n const byLayerName = new Map<string, string>();\n const lines = text.split(/\\r\\n|\\r|\\n/);\n let recordType = \"\";\n let handle = \"\";\n let name = \"\";\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = lines[i].trim();\n const value = lines[i + 1].trim();\n if (code === \"0\") {\n recordType = value;\n handle = \"\";\n name = \"\";\n } else if (code === \"5\") handle = value;\n else if (code === \"2\") name = value;\n else if (code === \"420\") {\n const v = Number(value);\n if (!Number.isFinite(v)) continue;\n const hex = rgbToHex((v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);\n if (recordType === \"LAYER\" && name) byLayerName.set(name, hex);\n else if (handle) byHandle.set(handle, hex);\n }\n }\n return { byHandle, byLayerName };\n};\n\n// dxf-parser's types are loose; a pragmatic any-view keeps readers readable.\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\nconst pt = (p: { x: number; y: number }, f: number): Vec2 => ({\n x: p.x * f,\n y: p.y * f,\n});\n\n/**\n * Map a DXF linetype name onto our named library. Prefers an exact match\n * (case/punctuation-insensitive — ACAD names, ISO, JIS); the acad `NAME2` /\n * `NAMEX2` scale-variant convention resolves to the BASE type with the\n * variant's factor (0.5 / 2) reported so callers fold it into\n * lineTypeScale — the library stores only base patterns. Unknown names fall\n * back to a substring heuristic onto the curated set.\n * ByLayer / Continuous / unknown → undefined.\n */\nconst lineTypeFromDxf = (\n name: unknown,\n): { name: string; factor: number } | undefined => {\n if (typeof name !== \"string\") return undefined;\n const n = name.trim();\n if (!n || /^(bylayer|byblock|continuous)$/i.test(n)) return undefined;\n const match = getLineType(n);\n if (match) return { name: match.name, factor: 1 };\n // acad scale variants: DASHED2 = half, DASHEDX2 = double.\n const variant = /x2$/i.test(n)\n ? { base: n.slice(0, -2), factor: 2 }\n : /2$/.test(n)\n ? { base: n.slice(0, -1), factor: 0.5 }\n : undefined;\n if (variant) {\n const baseMatch = getLineType(variant.base);\n if (baseMatch) return { name: baseMatch.name, factor: variant.factor };\n }\n const u = n.toUpperCase();\n const heuristic = u.includes(\"PHANTOM\")\n ? \"phantom\"\n : u.includes(\"DASHDOT\") || u.includes(\"DASH_DOT\")\n ? \"dashdot\"\n : u.includes(\"CENTER\") || u.includes(\"CENTRE\")\n ? \"center\"\n : u.includes(\"HIDDEN\")\n ? \"hidden\"\n : u.includes(\"DASH\")\n ? \"dashed\"\n : u.includes(\"DOT\")\n ? \"dotted\"\n : undefined;\n return heuristic ? { name: heuristic, factor: 1 } : undefined;\n};\n\nconst baseFor = (e: IEntity, ctx: ImportContext) => {\n const layerId =\n ctx.layerIdByName.get(e.layer?.toLowerCase()) ?? ctx.defaultLayerId;\n const anyE = e as any;\n // Resolve the entity's own color. dxf-parser resolves built-in entities'\n // ACI/true-color into a 24-bit `color`; our custom handlers (hatch, leader,\n // multileader, viewport) only carry `colorIndex`/`trueColor`, so resolve\n // those too. ByLayer (256) / ByBlock (0) / absent → inherit from the layer.\n const rgb24 = (v: number) =>\n rgbToHex((v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff);\n const ci = anyE.colorIndex;\n const scanned = ctx.trueColorByHandle.get(String(anyE.handle));\n const color =\n typeof anyE.trueColor === \"number\"\n ? rgb24(anyE.trueColor)\n : scanned !== undefined\n ? scanned\n : // ci 0 = ByBlock: dxf-parser pre-resolves it to BLACK in `color`,\n // so it must be excluded like ByLayer. Approximated as inherit-\n // from-layer (exact only when the reference itself has no color —\n // true for tables; an explicitly colored INSERT's ByBlock children\n // would need the reference color threaded through convertInsert).\n typeof anyE.color === \"number\" &&\n ci !== 256 &&\n ci !== 0 &&\n ci !== undefined\n ? rgb24(anyE.color)\n : typeof ci === \"number\"\n ? aciToHex(ci) // undefined for 0/256 (inherit)\n : undefined;\n const resolved = lineTypeFromDxf(anyE.lineType);\n const lineType = resolved?.name;\n // Group 48 (CELTSCALE). We render dashes width-proportionally while DXF\n // consumers render pattern × 48, and everything imported gets the default\n // 0.25 mm lineweight — so divide by it to keep AutoCAD's dash lengths\n // (export multiplies the width back in, so round-trips are exact). A 2/X2\n // scale-variant LTYPE name multiplies on top (the variant resolved to its\n // base pattern). Only entities whose effective line type dashes get the\n // field stamped.\n const raw48 =\n typeof anyE.lineTypeScale === \"number\" && anyE.lineTypeScale > 0\n ? anyE.lineTypeScale\n : 1;\n const scale = (raw48 / IMPORT_LINE_WIDTH_MM) * (resolved?.factor ?? 1);\n const dashed = lineType !== undefined || ctx.dashedLayerIds.has(layerId);\n const lineTypeScale = dashed && scale !== 1 ? scale : undefined;\n return { layerId, color, lineType, lineTypeScale, hidden: false };\n};\n\n/** Decode classic %%-escapes used in TEXT (°, ±, Ø; %%u/%%o toggles drop). */\nconst decodeTextEscapes = (text: string): string =>\n text.replace(/%%([dpcuo%])/gi, (_, ch: string) => {\n switch (ch.toLowerCase()) {\n case \"d\":\n return \"°\";\n case \"p\":\n return \"±\";\n case \"c\":\n return \"Ø\";\n case \"u\":\n case \"o\":\n return \"\";\n default:\n return \"%\";\n }\n });\n\nconst SUPERSCRIPT: Record<string, string> = {\n \"0\": \"⁰\",\n \"1\": \"¹\",\n \"2\": \"²\",\n \"3\": \"³\",\n \"4\": \"⁴\",\n \"5\": \"⁵\",\n \"6\": \"⁶\",\n \"7\": \"⁷\",\n \"8\": \"⁸\",\n \"9\": \"⁹\",\n \"+\": \"⁺\",\n \"-\": \"⁻\",\n \"=\": \"⁼\",\n \"(\": \"⁽\",\n \")\": \"⁾\",\n n: \"ⁿ\",\n i: \"ⁱ\",\n};\nconst SUBSCRIPT: Record<string, string> = {\n \"0\": \"₀\",\n \"1\": \"₁\",\n \"2\": \"₂\",\n \"3\": \"₃\",\n \"4\": \"₄\",\n \"5\": \"₅\",\n \"6\": \"₆\",\n \"7\": \"₇\",\n \"8\": \"₈\",\n \"9\": \"₉\",\n \"+\": \"₊\",\n \"-\": \"₋\",\n \"=\": \"₌\",\n \"(\": \"₍\",\n \")\": \"₎\",\n};\n/** Script form when every character has one, else the plain text. */\nconst toScript = (s: string, map: Record<string, string>): string =>\n [...s].every((c) => map[c]) ? [...s].map((c) => map[c]).join(\"\") : s;\n\n/**\n * MTEXT stack `\\Stop^bottom;` / `\\Stop#bottom;` / `\\Stop/bottom;`. An empty\n * bottom is AutoCAD's superscript (`m\\S2^;` = m²), an empty top its subscript\n * (`λ\\S^D;` = λ with subscript D); both present is a fraction or tolerance\n * stack → \"a/b\".\n */\nconst stackText = (body: string): string => {\n const m = /^(.*?)([\\^#/])(.*)$/s.exec(body);\n if (!m) return body;\n const top = m[1].trim();\n const bottom = m[3].trim();\n if (top && !bottom) return toScript(top, SUPERSCRIPT);\n if (!top && bottom) return toScript(bottom, SUBSCRIPT);\n return `${top}/${bottom}`;\n};\n\n/** Symbol-font (symbol.ttf / \\fSymbol) code points → the glyphs they draw. */\nconst SYMBOL_FONT: Record<string, string> = {\n a: \"α\",\n b: \"β\",\n c: \"χ\",\n d: \"δ\",\n e: \"ε\",\n f: \"φ\",\n g: \"γ\",\n h: \"η\",\n i: \"ι\",\n k: \"κ\",\n l: \"λ\",\n m: \"μ\",\n n: \"ν\",\n p: \"π\",\n q: \"θ\",\n r: \"ρ\",\n s: \"σ\",\n t: \"τ\",\n u: \"υ\",\n w: \"ω\",\n x: \"ξ\",\n y: \"ψ\",\n z: \"ζ\",\n D: \"Δ\",\n F: \"Φ\",\n G: \"Γ\",\n L: \"Λ\",\n P: \"Π\",\n Q: \"Θ\",\n S: \"Σ\",\n W: \"Ω\",\n X: \"Ξ\",\n Y: \"Ψ\",\n \"£\": \"≤\",\n \"³\": \"≥\",\n \"¹\": \"≠\",\n \"»\": \"≈\",\n \"¥\": \"∞\",\n \"´\": \"×\",\n \"¸\": \"÷\",\n Ö: \"√\",\n \"®\": \"→\",\n \"¬\": \"←\",\n Æ: \"∅\",\n Î: \"∈\",\n \"¶\": \"∂\",\n};\n/** True for an inline \\f font code naming the Symbol font (\"Symbol|b0|i0\"). */\nconst isSymbolFont = (fontCode: string): boolean =>\n /^symbol(\\.ttf)?$/i.test(fontCode.split(\"|\")[0].trim());\n\n/** Reduce MTEXT inline formatting codes to plain text (line breaks kept). */\nconst stripMtextCodes = (text: string): string => {\n let out = \"\";\n let i = 0;\n // Symbol-font state per `{…}` scope: an inline \\f code switches it until\n // the enclosing scope closes.\n const symbolStack: boolean[] = [];\n let symbol = false;\n while (i < text.length) {\n const ch = text[i];\n if (ch === \"{\") {\n symbolStack.push(symbol);\n i++;\n } else if (ch === \"}\") {\n symbol = symbolStack.pop() ?? false;\n i++;\n } else if (ch !== \"\\\\\") {\n out += symbol ? (SYMBOL_FONT[ch] ?? ch) : ch;\n i++;\n } else {\n const next = text[i + 1] ?? \"\";\n if (next === \"\\\\\" || next === \"{\" || next === \"}\") {\n out += next; // escaped literal\n i += 2;\n } else if (next === \"P\") {\n out += \"\\n\"; // paragraph break\n i += 2;\n } else if (next === \"~\") {\n out += \" \"; // non-breaking space\n i += 2;\n } else if (\"LlOoKk\".includes(next)) {\n i += 2; // underline/overline/strike toggles (no \";\")\n } else if (next === \"S\") {\n // Stack: fraction \\S1^2; / \\S1#2; → \"1/2\", superscript \\S2^; → \"²\",\n // subscript \\S^2; → \"₂\" (letters without a Unicode form stay plain).\n const end = text.indexOf(\";\", i + 2);\n out += end === -1 ? \"\" : stackText(text.slice(i + 2, end));\n i = end === -1 ? i + 2 : end + 1;\n } else if (\n (next === \"U\" || next === \"u\") &&\n /^\\+[0-9a-fA-F]{4}/.test(text.slice(i + 2, i + 7))\n ) {\n // Unicode escape \\U+2265 → \"≥\". It has no \";\" terminator, so the\n // generic branch below would swallow the text up to the next \";\".\n out += String.fromCodePoint(parseInt(text.slice(i + 3, i + 7), 16));\n i += 7;\n } else if (next === \"f\" || next === \"F\") {\n // Font switch \\fSymbol|b0|i0;… — Symbol glyphs need mapping.\n const end = text.indexOf(\";\", i + 2);\n symbol = isSymbolFont(end === -1 ? \"\" : text.slice(i + 2, end));\n i = end === -1 ? i + 2 : end + 1;\n } else {\n // Other \\X…; formatting codes (\\f… \\H… \\C… \\p…) — skip through \";\".\n const end = text.indexOf(\";\", i + 1);\n i = end === -1 ? i + 2 : end + 1;\n }\n }\n }\n return out;\n};\n\n/** First inline \\W width-factor code, if any (\"\\W0.8;\" -> 0.8). */\nconst mtextWidthFactor = (text: string): number | undefined => {\n const m = /\\\\W([0-9.]+);/.exec(text);\n const v = m ? Number(m[1]) : NaN;\n return Number.isFinite(v) && v > 0 && v !== 1 ? v : undefined;\n};\n\n/** Bold / italic from the first inline \\f font code\n * (\"{\\fArial|b1|i0|c0|p34;…}\" → { bold: true }); only flags that are ON. */\nexport const mtextFontFlags = (\n text: string,\n): { bold?: true; italic?: true } => {\n const m = /\\\\f[^|;]*((?:\\|[a-z]\\d+)*)/.exec(text);\n if (!m) return {};\n return {\n ...(/\\|b1/.test(m[1]) ? { bold: true as const } : {}),\n ...(/\\|i1/.test(m[1]) ? { italic: true as const } : {}),\n };\n};\n\n/**\n * Decode the caret control codes AutoCAD embeds in TEXT/MTEXT: `^I` is a tab,\n * `^J`/`^M` are line breaks. Undecoded, the `^I` shows up as a stray \"^|\" (the\n * capital I reads as a pipe). Literal CR/LF are normalized to \"\\n\" as well.\n */\nconst decodeControlCodes = (text: string): string =>\n text.replace(/\\^I/g, \"\\t\").replace(/\\^M\\^J|\\^J|\\^M|\\r\\n?/g, \"\\n\");\n\n/**\n * Full TEXT/MTEXT content cleanup: MTEXT inline codes (MTEXT only) → classic\n * %%-escapes → caret control codes. Decoded tabs (`^I` → `\\t`) are KEPT:\n * the renderer aligns them at tab stops (paint/textMetrics), so imported\n * tabular text stays tabular. Exported for unit testing.\n */\nexport const cleanText = (raw: string, mtext: boolean): string =>\n decodeControlCodes(decodeTextEscapes(mtext ? stripMtextCodes(raw) : raw));\n\n/** Hatch boundary path (from the custom handler) → polyline loop points. */\nconst hatchLoopPoints = (path: any, f: number): PolylineVertex[] => {\n if (path.isPolyline) {\n return (path.vertices ?? []).map((v: any) => ({\n x: v.x * f,\n y: v.y * f,\n bulge: v.bulge ?? 0,\n }));\n }\n // Edge form: chain edge start points; arcs contribute a bulge, ellipse and\n // spline edges are approximated by sampled points.\n const points: PolylineVertex[] = [];\n for (const edge of path.edges ?? []) {\n switch (edge.kind) {\n case 1: {\n // Line: 10 = start (11 = end, supplied by the next edge's start).\n const p = edge.points[0];\n if (p) points.push({ x: p.x * f, y: p.y * f, bulge: 0 });\n break;\n }\n case 2: {\n // Arc: 10 center, 40 radius, 50/51 angles in degrees.\n const c = edge.points[0];\n if (!c || !(edge.r40 > 0)) break;\n const a0 = (edge.startAngle ?? 0) * DEG2RAD;\n let a1 = (edge.endAngle ?? 360) * DEG2RAD;\n if (a1 <= a0) a1 += Math.PI * 2;\n const sweep = a1 - a0;\n const start = edge.ccw === false ? -a0 : a0;\n points.push({\n x: (c.x + edge.r40 * Math.cos(start)) * f,\n y:\n (c.y + edge.r40 * Math.sin(start) * (edge.ccw === false ? -1 : 1)) *\n f,\n bulge: Math.tan(sweep / 4) * (edge.ccw === false ? -1 : 1),\n });\n break;\n }\n case 3: {\n // Elliptic arc: sample into straight segments.\n const c = edge.points[0];\n const major = edge.end; // 11 = major endpoint relative to center\n if (!c || !major) break;\n const ratio = edge.r40 ?? 1;\n const t0 = (edge.startAngle ?? 0) * DEG2RAD;\n let t1 = (edge.endAngle ?? 360) * DEG2RAD;\n if (t1 <= t0) t1 += Math.PI * 2;\n const steps = 8;\n for (let s = 0; s < steps; s++) {\n const t = t0 + ((t1 - t0) * s) / steps;\n const x = c.x + major.x * Math.cos(t) - major.y * ratio * Math.sin(t);\n const y = c.y + major.y * Math.cos(t) + major.x * ratio * Math.sin(t);\n points.push({ x: x * f, y: y * f, bulge: 0 });\n }\n break;\n }\n case 4: {\n // Spline: fall back to its control points.\n for (const p of edge.points)\n points.push({ x: p.x * f, y: p.y * f, bulge: 0 });\n break;\n }\n }\n }\n return points;\n};\n\nconst convertHatch = (e: IEntity, ctx: ImportContext): ModelObjectDto[] => {\n const anyE = e as any;\n const base = baseFor(e, ctx);\n const loops = (anyE.boundaryPaths ?? [])\n .map((path: any) => ({ points: hatchLoopPoints(path, ctx.f) }))\n .filter((loop: { points: PolylineVertex[] }) => loop.points.length >= 3);\n if (loops.length === 0) return [];\n\n let fill:\n | { kind: \"solid\" }\n | { kind: \"lines\"; angle: number; spacing: number }\n | { kind: \"pattern\"; name: string; angle: number; scale: number };\n const patternMatch =\n typeof anyE.patternName === \"string\"\n ? getHatchPattern(anyE.patternName)\n : undefined;\n if (anyE.solid || anyE.patternName === \"SOLID\") {\n fill = { kind: \"solid\" };\n } else if (patternMatch) {\n // A recognized built-in pattern (including ANSI31) → carry it losslessly as\n // a named pattern fill. The DXF pattern angle (code 52) and scale (code 41)\n // are the pattern's rotation/scale, matching the export mapping.\n fill = {\n kind: \"pattern\",\n name: patternMatch.name,\n angle: (anyE.patternAngle ?? 0) * DEG2RAD,\n scale: (anyE.patternScale || 1) * ctx.f,\n };\n } else {\n // Generic pattern: approximate with the first definition line family.\n const line = anyE.patternLines?.[0];\n const offset = line ? Math.hypot(line.offsetX ?? 0, line.offsetY ?? 0) : 0;\n fill = {\n kind: \"lines\",\n angle: (line?.angle ?? anyE.patternAngle ?? 45) * DEG2RAD,\n spacing: (offset > 0 ? offset : 3) * ctx.f,\n };\n }\n return [{ type: \"hatch\", loops, fill, scale: 1, ...base }];\n};\n\n/** Text placement past a leader's last point (mirror of the painter). */\nconst leaderTextPlacement = (\n line: Vec2[],\n height: number,\n): { position: Vec2; hAlign: \"left\" | \"right\" } => {\n const last = line[line.length - 1];\n const prev = line[line.length - 2] ?? last;\n const rightward = last.x - prev.x >= 0;\n const gap = height * 0.6;\n return {\n position: { x: last.x + (rightward ? gap : -gap), y: last.y },\n // Justification: text right of the leader starts at its point.\n hAlign: rightward ? \"left\" : \"right\",\n };\n};\n\nconst convertLeader = (e: IEntity, ctx: ImportContext): ModelObjectDto[] => {\n const anyE = e as any;\n const points: Vec2[] = (anyE.vertices ?? []).map((p: any) => pt(p, ctx.f));\n if (points.length < 2) return [];\n const placement = leaderTextPlacement(points, ctx.dimTextHeight);\n return [\n {\n type: \"text\",\n position: placement.position,\n content: \"\", // LEADER's annotation is a separate entity\n rotation: 0,\n hAlign: placement.hAlign,\n vAlign: \"center\",\n leaderLines: [points],\n // The source's DIMTXT/DIMASZ are explicit — keep them as overrides so\n // the import renders identically regardless of the document text\n // style.\n styleOverride: {\n textHeight: ctx.dimTextHeight,\n arrowSize: ctx.dimArrowSize,\n },\n scale: 1,\n ...baseFor(e, ctx),\n },\n ];\n};\n\nconst convertMultiLeader = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n const f = ctx.f;\n // Rebuild full lines: each LEADER_LINE's vertices + its LEADER's junction.\n const lines: Vec2[][] = [];\n for (const leader of anyE.leaders ?? []) {\n for (const raw of leader.lines ?? []) {\n const points: Vec2[] = raw.map((p: any) => pt(p, f));\n if (leader.junction) points.push(pt(leader.junction, f));\n if (points.length >= 2) lines.push(points);\n }\n }\n if (lines.length === 0) return [];\n // CONTEXT_DATA sizes are FINAL (already multiplied by the overall scale);\n // un-bake them so height/arrowSize stay base values, like our model's.\n const overall = anyE.overallScale > 0 ? anyE.overallScale : 1;\n const height =\n (anyE.textHeight > 0 ? anyE.textHeight / overall : ctx.dimTextHeight) * f;\n const fallback = leaderTextPlacement(lines[0], height * overall);\n const position = anyE.textLocation\n ? pt(anyE.textLocation, f)\n : fallback.position;\n const junction = lines[0][lines[0].length - 1];\n return [\n {\n type: \"text\",\n position,\n content: cleanText(String(anyE.content ?? \"\"), true),\n rotation: 0,\n hAlign: position.x >= junction.x ? \"left\" : \"right\",\n vAlign: \"center\",\n leaderLines: lines,\n styleOverride: {\n textHeight: height,\n arrowSize:\n (anyE.arrowSize > 0 ? anyE.arrowSize / overall : ctx.dimArrowSize) *\n f,\n },\n // MLEADER's overall scale is a unitless multiplier, like ours.\n scale: overall,\n ...baseFor(e, ctx),\n },\n ];\n};\n\n// DXF dimensions arrive in the legacy linePoint/rotation shape; the shared\n// converter (also used by the v8→v9 migration and block-script DTOs) turns\n// them into the offset form — including projecting axis-locked linear\n// dims onto their measuring axis.\nconst legacyDim = (raw: Record<string, unknown>): ModelObjectDto =>\n dimensionRawToOffset(raw) as unknown as ModelObjectDto;\n\nconst convertDimension = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n const kind = (anyE.dimensionType ?? 0) & 7;\n // Carry the drawing's overall dimension scale onto each dimension.\n const styleScale = ctx.dimScale !== 1 ? { scale: ctx.dimScale } : {};\n const p1 = anyE.linearOrAngularPoint1;\n const p2 = anyE.linearOrAngularPoint2;\n const line = anyE.anchorPoint;\n\n if ((kind === 0 || kind === 1) && p1 && p2 && line) {\n const points = [pt(p1, ctx.f), pt(p2, ctx.f)];\n // Group 1 usually just repeats the measured value — keep it only when it\n // genuinely overrides (so re-imported dimensions stay live).\n const raw = typeof anyE.text === \"string\" ? anyE.text.trim() : \"\";\n const rotation = (anyE.angle ?? 0) * DEG2RAD;\n // Linear dims measure the projection onto the rotation axis.\n const measured =\n kind === 0\n ? Math.abs(\n (points[1].x - points[0].x) * Math.cos(rotation) +\n (points[1].y - points[0].y) * Math.sin(rotation),\n )\n : dist(points[0], points[1]);\n const asNumber = Number(raw.replace(\",\", \".\"));\n const isComputed =\n raw === \"\" ||\n raw === \"<>\" ||\n (Number.isFinite(asNumber) &&\n measured > 0 &&\n Math.abs(asNumber * ctx.f - measured) / measured < 0.01);\n return [\n legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: kind === 0 ? \"linear\" : \"aligned\",\n points,\n linePoint: pt(line, ctx.f),\n rotation: kind === 0 ? rotation : 0,\n ...(isComputed ? {} : { textOverride: decodeTextEscapes(raw) }),\n ...baseFor(e, ctx),\n }),\n ];\n }\n\n // Diameter (3): 10 and 15 are opposite points on the curve.\n if (kind === 3 && line && anyE.diameterOrRadiusPoint) {\n const a = pt(anyE.diameterOrRadiusPoint, ctx.f);\n const b = pt(line, ctx.f);\n return [\n legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"diameter\",\n points: [a, b],\n linePoint: anyE.middleOfText\n ? pt(anyE.middleOfText, ctx.f)\n : { x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 },\n ...baseFor(e, ctx),\n }),\n ];\n }\n\n // Radial (4): 10 = center, 15 = point on the curve.\n if (kind === 4 && line && anyE.diameterOrRadiusPoint) {\n const center = pt(line, ctx.f);\n const p = pt(anyE.diameterOrRadiusPoint, ctx.f);\n return [\n legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"radial\",\n points: [center, p],\n linePoint: anyE.middleOfText ? pt(anyE.middleOfText, ctx.f) : p,\n ...baseFor(e, ctx),\n }),\n ];\n }\n\n // Angular 3-point (5): 15 = vertex, 13/14 = ray points, 10 = arc position.\n if (kind === 5 && p1 && p2 && line && anyE.diameterOrRadiusPoint) {\n return [\n legacyDim({\n type: \"dimension\",\n ...styleScale,\n kind: \"angular\",\n points: [\n pt(anyE.diameterOrRadiusPoint, ctx.f),\n pt(p1, ctx.f),\n pt(p2, ctx.f),\n ],\n linePoint: pt(line, ctx.f),\n ...baseFor(e, ctx),\n }),\n ];\n }\n\n // Two-line angular/ordinate/etc.: fall back to the dimension's rendered\n // geometry block (already in world coordinates).\n const block = anyE.block ? dxf.blocks?.[anyE.block] : undefined;\n if (!block?.entities) return [];\n const result: ModelObjectDto[] = [];\n for (const child of block.entities)\n result.push(...convertEntity(child, dxf, ctx));\n return result;\n};\n\nconst convertEntity = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto[] => {\n const anyE = e as any;\n // Skip entities AutoCAD hides (group 60 = 1) — chiefly the inactive\n // visibility-state geometry inside dynamic blocks, which would otherwise all\n // render on top of each other.\n if (anyE.visible === false) return [];\n const f = ctx.f;\n const base = baseFor(e, ctx);\n\n switch (e.type) {\n case \"LINE\": {\n const [a, b] = anyE.vertices;\n if (!a || !b) return [];\n return [{ type: \"line\", a: pt(a, f), b: pt(b, f), ...base }];\n }\n case \"POINT\": {\n if (!anyE.position) return [];\n return [{ type: \"point\", p: pt(anyE.position, f), ...base }];\n }\n case \"LWPOLYLINE\":\n case \"POLYLINE\": {\n const vertices: PolylineVertex[] = (anyE.vertices ?? []).map(\n (v: any) => ({\n x: v.x * f,\n y: v.y * f,\n bulge: v.bulge ?? 0,\n }),\n );\n if (vertices.length < 2) return [];\n return [\n {\n type: \"polyline\",\n points: vertices,\n closed: anyE.shape === true,\n ...base,\n },\n ];\n }\n case \"CIRCLE\": {\n const radius = anyE.radius * f;\n if (!(radius > 0)) return []; // zero/negative/NaN radius\n return [\n {\n type: \"circle\",\n center: pt(anyE.center, f),\n radius,\n ...base,\n },\n ];\n }\n case \"ARC\": {\n const radius = anyE.radius * f;\n if (!(radius > 0)) return [];\n // dxf-parser converts arc angles to radians.\n return [\n {\n type: \"arc\",\n center: pt(anyE.center, f),\n radius,\n startAngle: anyE.startAngle,\n endAngle: anyE.endAngle,\n ...base,\n },\n ];\n }\n case \"ELLIPSE\": {\n const ratio = Math.min(Math.max(anyE.axisRatio, 1e-3), 1);\n return [\n {\n type: \"ellipse\",\n center: pt(anyE.center, f),\n majorAxis: pt(anyE.majorAxisEndPoint, f), // relative vector\n ratio,\n startAngle: anyE.startAngle ?? 0,\n endAngle: anyE.endAngle ?? Math.PI * 2,\n ...base,\n },\n ];\n }\n case \"TEXT\": {\n const halign = anyE.halign ?? 0;\n const valign = anyE.valign ?? 0;\n // With a non-default alignment the anchor is the SECOND alignment\n // point (codes 11/21). \"Aligned\" (3) and \"fit\" (5) stretch between\n // both points — approximated as plain left/baseline at the first.\n const usesSecondPoint =\n (halign !== 0 && halign !== 3 && halign !== 5) || valign !== 0;\n const anchor =\n usesSecondPoint && anyE.endPoint ? anyE.endPoint : anyE.startPoint;\n // DXF justification = the model's alignment (which edge sits on the\n // point).\n const hAlign =\n halign === 1 || halign === 4\n ? \"center\"\n : halign === 2\n ? \"right\"\n : \"left\";\n // valign: 0 baseline, 1 bottom, 2 middle, 3 top; halign 4 = \"middle\"\n // centers both axes. Baseline maps to bottom (closest anchor we have).\n const vAlign =\n valign === 3\n ? \"top\"\n : valign === 2 || halign === 4\n ? \"center\"\n : \"bottom\";\n return [\n {\n type: \"text\",\n position: pt(anchor, f),\n content: cleanText(anyE.text ?? \"\", false),\n rotation: (anyE.rotation ?? 0) * DEG2RAD,\n hAlign,\n vAlign,\n leaderLines: [],\n scale: 1,\n // The DXF height is explicit — keep it as an override. Group 41:\n // per-entity width factor (style-level 41 is not exposed by\n // dxf-parser; see docs/fonts.md).\n styleOverride: {\n textHeight: (anyE.textHeight > 0 ? anyE.textHeight : 2.5) * f,\n ...(typeof anyE.xScale === \"number\" &&\n anyE.xScale > 0 &&\n anyE.xScale !== 1\n ? { widthFactor: anyE.xScale }\n : {}),\n },\n ...base,\n },\n ];\n }\n case \"MTEXT\": {\n // Attachment point 1–9: TL TC TR / ML MC MR / BL BC BR.\n const ap = anyE.attachmentPoint ?? 1;\n const hAlign = ([\"left\", \"center\", \"right\"] as const)[(ap - 1) % 3];\n const vAlign = ap <= 3 ? \"top\" : ap <= 6 ? \"center\" : \"bottom\";\n // Rotation comes as a degree angle (50) or an X-axis direction\n // vector (11); the vector wins when present.\n const dv = anyE.directionVector;\n const rotation =\n dv && (dv.x !== 0 || dv.y !== 0)\n ? Math.atan2(dv.y, dv.x)\n : (anyE.rotation ?? 0) * DEG2RAD;\n return [\n {\n type: \"text\",\n position: pt(anyE.position, f),\n content: cleanText(anyE.text ?? \"\", true),\n rotation,\n hAlign,\n vAlign,\n leaderLines: [],\n scale: 1,\n // MTEXT reference rectangle width (group 41) → wrap width.\n ...(anyE.width > 0 ? { width: anyE.width * f } : {}),\n // Explicit DXF height + inline \\W code width factor → overrides\n // (cleanText strips the code).\n styleOverride: {\n textHeight: (anyE.height > 0 ? anyE.height : 2.5) * f,\n ...(mtextWidthFactor(anyE.text ?? \"\") !== undefined\n ? { widthFactor: mtextWidthFactor(anyE.text ?? \"\") }\n : {}),\n ...mtextFontFlags(anyE.text ?? \"\"),\n },\n ...base,\n },\n ];\n }\n case \"SPLINE\": {\n const points: any[] = anyE.fitPoints?.length\n ? anyE.fitPoints\n : (anyE.controlPoints ?? []);\n if (points.length < 2) return [];\n ctx.skipped.set(\n \"SPLINE→polyline\",\n (ctx.skipped.get(\"SPLINE→polyline\") ?? 0) + 1,\n );\n return [\n {\n type: \"polyline\",\n points: points.map((p) => ({ x: p.x * f, y: p.y * f, bulge: 0 })),\n closed: anyE.closed === true,\n ...base,\n },\n ];\n }\n case \"SOLID\": {\n const points: any[] = anyE.points ?? [];\n if (points.length < 3) return [];\n // DXF SOLID vertex order is 1,2,4,3.\n const ordered =\n points.length >= 4\n ? [points[0], points[1], points[3], points[2]]\n : points;\n return [\n {\n type: \"hatch\",\n loops: [\n {\n points: ordered.map((p) => ({\n x: p.x * f,\n y: p.y * f,\n bulge: 0,\n })),\n },\n ],\n fill: { kind: \"solid\" },\n scale: 1,\n ...base,\n },\n ];\n }\n case \"HATCH\":\n return convertHatch(e, ctx);\n case \"LEADER\":\n return convertLeader(e, ctx);\n case \"MULTILEADER\":\n return convertMultiLeader(e, ctx);\n case \"DIMENSION\":\n return convertDimension(e, dxf, ctx);\n default:\n return [];\n }\n};\n\n/**\n * Blocks indexed by their owner BLOCK_RECORD handle (group 330), built\n * lazily once per parsed document. ACAD_TABLE via the DWG transcode\n * references its content block by that HANDLE (AutoCAD's native DXF puts\n * the `*T<n>` block NAME in the same field), so the name lookup misses and\n * this resolves the join.\n */\nconst blocksByOwner = new WeakMap<object, Map<string, IBlock>>();\nconst blockByOwnerHandle = (dxf: IDxf, handle: string): IBlock | undefined => {\n let map = blocksByOwner.get(dxf);\n if (!map) {\n map = new Map();\n for (const b of Object.values(dxf.blocks ?? {})) {\n const oh = (b as { ownerHandle?: unknown }).ownerHandle;\n if (oh !== undefined) map.set(String(oh).toUpperCase(), b);\n }\n blocksByOwner.set(dxf, map);\n }\n return map.get(handle.toUpperCase());\n};\n\n/**\n * An INSERT of an XREF block (group-70 bit 4, path in group 1) → a Linea\n * reference to the same file, placed like the insert (docs/references.md):\n * the linked file's content is NOT part of this DXF, so exploding it would\n * yield nothing.\n */\nconst xrefReference = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n const block = dxf.blocks?.[anyE.name] as IBlock | undefined;\n if (!block || !((block.type & 4) !== 0 || block.xrefPath)) return null;\n const path = (block.xrefPath || `${block.name}.dwg`).replace(/\\\\/g, \"/\");\n const sx = anyE.xScale ?? 1;\n const sy = anyE.yScale ?? 1;\n // Linea mirrors left-right (−X); a negative Y scale is that flip turned\n // half a turn.\n const rotation = (anyE.rotation ?? 0) * DEG2RAD + (sy < 0 ? Math.PI : 0);\n return {\n ...baseFor(e, ctx),\n type: \"reference\",\n format: referenceFormatOf(path) ?? \"dwg\",\n name: block.name,\n source: { kind: \"path\", path },\n position: pt(anyE.position ?? { x: 0, y: 0 }, ctx.f),\n rotation,\n scale: Math.abs(sx) || 1,\n ...(sx * sy < 0 ? { mirrored: true } : {}),\n hiddenLayers: [],\n } as ModelObjectDto;\n};\n\n/** Explode INSERTs by converting the block's entities and transforming them. */\n/**\n * ACAD_TABLE → native table, from the legacy AcDbTable payload\n * (AcadTableHandler): grid, row heights (as floors — rows still grow to fit),\n * column widths, merges, per-cell alignment / height / bold-italic and the\n * cleaned MTEXT. Null when the payload is missing, inconsistent or holds a\n * non-text cell — the caller then explodes the *T block as before.\n */\nconst convertAcadTable = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n const t: AcadTableData | undefined = anyE.table;\n if (!t || !anyE.position) return null;\n const { rows, cols, cells } = t;\n if (\n cells.length !== rows * cols ||\n t.rowHeights.length !== rows ||\n t.colWidths.length !== cols ||\n cells.some((c) => c.type !== 1)\n )\n return null;\n const f = ctx.f;\n const H = [\"left\", \"center\", \"right\"] as const;\n const grid = Array.from({ length: rows }, (_, r) =>\n Array.from({ length: cols }, (_, c) => {\n const cell = cells[r * cols + c];\n // Text cells carry group 1; numeric cells only the display string.\n const raw = cell.text || cell.display || \"\";\n const a = cell.alignment;\n return {\n text: cleanText(raw, true),\n ...(cell.cols > 1 || cell.rows > 1\n ? { span: { cols: cell.cols, rows: cell.rows } }\n : {}),\n ...(a !== undefined && a >= 1 && a <= 9\n ? {\n hAlign: H[(a - 1) % 3],\n vAlign:\n a <= 3\n ? (\"top\" as const)\n : a <= 6\n ? (\"center\" as const)\n : (\"bottom\" as const),\n }\n : {}),\n styleOverride: {\n ...(cell.height && cell.height > 0\n ? { textHeight: cell.height * f }\n : {}),\n ...mtextFontFlags(raw),\n },\n };\n }),\n );\n const parsed = ModelObjectSchema.safeParse({\n type: \"table\",\n id: \"acad-table\",\n position: pt(anyE.position, f),\n rotation: (anyE.rotation ?? 0) * DEG2RAD,\n scale: 1,\n columns: t.colWidths.map((w) => w * f),\n // AutoCAD's row heights are the drawn ones: keep them as floors.\n rows: t.rowHeights.map((h) => ({ minHeight: h * f })),\n cells: grid,\n cellMargin: (t.margin ?? 0) * f,\n ...baseFor(e, ctx),\n });\n if (!parsed.success) return null;\n const { id: _id, ...dto } = parsed.data;\n void _id;\n return dto as ModelObjectDto;\n};\n\nconst convertInsert = (\n e: IEntity,\n dxf: IDxf,\n ctx: ImportContext,\n depth = 0,\n): ModelObjectDto[] => {\n const anyE = e as any;\n if (anyE.visible === false) return []; // hidden dynamic-block instance\n if (depth > 16) return []; // guard against self-referential blocks\n // Tables may reference their content block by BLOCK_RECORD handle instead\n // of name (the DWG transcode does); scoped to ACAD_TABLE so an INSERT with\n // a genuinely missing block can't collide with a handle by accident.\n const block =\n dxf.blocks?.[anyE.name] ??\n (e.type === \"ACAD_TABLE\"\n ? blockByOwnerHandle(dxf, String(anyE.name ?? \"\"))\n : undefined);\n if (!block?.entities) return [];\n\n // DXF INSERT carries independent x/y/z scales (groups 41/42/43); a negative\n // scale is a mirror. Build the full affine — scale each axis, rotate, then\n // translate to the insertion point.\n const sx = anyE.xScale ?? 1;\n const sy = anyE.yScale ?? 1;\n const rot = (anyE.rotation ?? 0) * DEG2RAD;\n const insert = pt(anyE.position ?? { x: 0, y: 0 }, ctx.f);\n const cos = Math.cos(rot);\n const sin = Math.sin(rot);\n const reflect = sx * sy < 0;\n const meanScale = Math.sqrt(Math.abs(sx * sy)) || 1e-6;\n const lin = (v: Vec2): Vec2 => ({\n x: cos * (v.x * sx) - sin * (v.y * sy),\n y: sin * (v.x * sx) + cos * (v.y * sy),\n });\n const map = (p: Vec2): Vec2 => {\n const l = lin(p);\n return { x: l.x + insert.x, y: l.y + insert.y };\n };\n\n // Re-fit a bulged vertex list through the affine: map the vertices, then\n // recompute each segment's bulge from the transformed endpoints + arc\n // midpoint (so rotation, per-axis scale, and mirror sign flips are handled).\n const mapBulged = (\n verts: PolylineVertex[],\n closed: boolean,\n ): PolylineVertex[] => {\n const out = verts.map((v) => {\n const m = map(v);\n return { x: m.x, y: m.y, bulge: 0 };\n });\n const n = verts.length;\n const segs = closed ? n : n - 1;\n for (let i = 0; i < segs; i++) {\n const b = verts[i].bulge;\n if (!b) continue;\n const j = (i + 1) % n;\n const arc = bulgeToArc(\n { x: verts[i].x, y: verts[i].y },\n { x: verts[j].x, y: verts[j].y },\n b,\n );\n if (!arc) continue;\n const nb = bulgeFrom3Points(out[i], map(arcMidPoint(arc)), out[j]);\n out[i].bulge = Number.isFinite(nb) ? Math.max(-4, Math.min(4, nb)) : 0;\n }\n return out;\n };\n\n const transform = (dto: ModelObjectDto): ModelObjectDto | null => {\n const t = structuredClone(dto);\n switch (t.type) {\n case \"line\":\n t.a = map(t.a);\n t.b = map(t.b);\n return t;\n case \"polyline\":\n t.points = mapBulged(t.points, t.closed);\n return t;\n case \"circle\": {\n const ax = Math.abs(sx) * t.radius;\n const ay = Math.abs(sy) * t.radius;\n const center = map(t.center);\n if (Math.abs(ax - ay) <= 1e-6 * Math.max(ax, ay, 1)) {\n t.center = center;\n t.radius = Math.max((ax + ay) / 2, 1e-6);\n return t;\n }\n // Anisotropic scale turns the circle into a rotated ellipse.\n const majorLen = Math.max(ax, ay);\n const ang = rot + (ax >= ay ? 0 : Math.PI / 2);\n return {\n type: \"ellipse\",\n center,\n majorAxis: {\n x: majorLen * Math.cos(ang),\n y: majorLen * Math.sin(ang),\n },\n ratio: Math.min(1, Math.max(1e-3, Math.min(ax, ay) / majorLen)),\n startAngle: 0,\n endAngle: Math.PI * 2,\n layerId: t.layerId,\n ...(t.color ? { color: t.color } : {}),\n ...(t.lineType ? { lineType: t.lineType } : {}),\n ...(t.lineTypeScale !== undefined\n ? { lineTypeScale: t.lineTypeScale }\n : {}),\n ...(t.lineWidth !== undefined ? { lineWidth: t.lineWidth } : {}),\n };\n }\n case \"arc\": {\n // Reconstruct through three transformed points — exact for any\n // similarity (rotation / uniform scale / mirror); a circular\n // approximation for the rare anisotropic case.\n const g = {\n center: t.center,\n radius: t.radius,\n startAngle: t.startAngle,\n endAngle: t.endAngle,\n };\n const solved = arcFrom3Points(\n map(arcStartPoint(g)),\n map(arcMidPoint(g)),\n map(arcEndPoint(g)),\n );\n if (!solved) return null;\n t.center = solved.center;\n t.radius = solved.radius;\n t.startAngle = solved.startAngle;\n t.endAngle = solved.endAngle;\n return t;\n }\n case \"ellipse\":\n t.center = map(t.center);\n t.majorAxis = lin(t.majorAxis);\n if (reflect) {\n const s0 = t.startAngle;\n t.startAngle = -t.endAngle;\n t.endAngle = -s0;\n }\n return t;\n case \"hatch\":\n t.loops = t.loops.map((loop: { points: PolylineVertex[] }) => ({\n points: mapBulged(loop.points, true),\n }));\n return t;\n case \"text\":\n t.position = map(t.position);\n t.rotation += rot;\n // Imported texts always carry explicit height/arrow overrides.\n if (t.styleOverride !== undefined)\n t.styleOverride = {\n ...t.styleOverride,\n ...(t.styleOverride.textHeight === undefined\n ? {}\n : { textHeight: t.styleOverride.textHeight * meanScale }),\n ...(t.styleOverride.arrowSize === undefined\n ? {}\n : { arrowSize: t.styleOverride.arrowSize * meanScale }),\n };\n if (t.width !== undefined) t.width *= meanScale;\n t.leaderLines = t.leaderLines.map((l) => l.map(map));\n return t;\n case \"dimension\":\n t.points = t.points.map(map);\n // offset is anchor-relative: only the linear part applies.\n t.offset = lin(t.offset);\n return t;\n }\n return t;\n };\n\n const result: ModelObjectDto[] = [];\n for (const child of block.entities) {\n // Recurse into nested block references, then apply this insert's transform\n // to the exploded children (composing the nested + outer scales/mirrors).\n const childDtos =\n child.type === \"INSERT\" || child.type === \"ACAD_TABLE\"\n ? convertInsert(child, dxf, ctx, depth + 1)\n : convertEntity(child, dxf, ctx);\n for (const dto of childDtos) {\n const t = transform(dto);\n if (t) result.push(t);\n }\n }\n return result;\n};\n\n/** Paper-space VIEWPORT entity → viewport object (null = not importable). */\nconst convertViewport = (\n e: IEntity,\n ctx: ImportContext,\n): ModelObjectDto | null => {\n const anyE = e as any;\n if (!anyE.center || !(anyE.width > 0) || !(anyE.height > 0)) return null;\n if (!(anyE.viewHeight > 0)) return null;\n const f = ctx.f;\n return {\n type: \"viewport\",\n rect: {\n x: (anyE.center.x - anyE.width / 2) * f,\n y: (anyE.center.y - anyE.height / 2) * f,\n w: anyE.width * f,\n h: anyE.height * f,\n },\n modelCenter: anyE.viewCenter ? pt(anyE.viewCenter, f) : { x: 0, y: 0 },\n // Both in the same unit → the ratio is the 1:N denominator (model mm\n // shown per paper mm).\n scale: anyE.viewHeight / anyE.height,\n locked: ((anyE.statusFlags ?? 0) & VIEWPORT_LOCKED_FLAG) !== 0,\n // Frozen-layer references are raw handles; dxf-parser exposes no layer\n // handle table to resolve them against.\n hiddenLayerIds: [],\n ...baseFor(e, ctx),\n };\n};\n\n/** Document state the conversion needs — supplied by the caller (no store). */\nexport interface DxfImportContext {\n /** Existing layers, so DXF layers matched by name reuse the same id. */\n existingLayers: { id: string; name: string }[];\n /** Layer id for entities whose DXF layer has no match. */\n defaultLayerId: string;\n /** Fallback dimension text height / arrow size (from the document dimStyle). */\n dimTextHeight: number;\n dimArrowSize: number;\n /** mm per drawing unit; overrides the file's $INSUNITS when set. */\n unitOverride?: number;\n}\n\n/** What a DXF import yields — the caller adds these to the document. */\nexport interface DxfImportResult {\n /** Model-space objects to add (DTOs — ids assigned by the caller/funnel). */\n objects: ModelObjectDto[];\n /** Layers that must be created (DXF layers with no name match). */\n newLayers: Layer[];\n /** Paper layouts rebuilt from *Paper_Space blocks (ids already assigned). */\n layouts: PaperLayout[];\n /** Per-reason counts of entities that could not be imported. */\n skipped: Map<string, number>;\n}\n\n/**\n * Parse DXF text into model objects, new layers, and paper layouts. Pure and\n * headless — throws on an unparseable file; the editor wraps this with the\n * store read, the undo transaction, zoom-to-fit, and toasts.\n */\nexport const dxfToModel = (\n text: string,\n input: DxfImportContext,\n): DxfImportResult => {\n let dxf: IDxf;\n {\n const parser = new DxfParser();\n parser.registerEntityHandler(ViewportHandler as any);\n parser.registerEntityHandler(HatchHandler as any);\n parser.registerEntityHandler(AcadTableHandler as any);\n parser.registerEntityHandler(LeaderHandler as any);\n parser.registerEntityHandler(MultiLeaderHandler as any);\n const parsed = parser.parseSync(text);\n if (!parsed) throw new Error(\"DXF parse produced no result\");\n dxf = parsed;\n }\n\n const header = dxf.header as Record<string, unknown> | undefined;\n const f =\n input.unitOverride !== undefined && input.unitOverride > 0\n ? input.unitOverride\n : unitFactor(header?.[\"$INSUNITS\"]);\n // Overall dimension scale (DIMSCALE): multiplies text/arrow sizes so a 1:N\n // drawing's dimensions come in at the right size. dxf-parser exposes no\n // DIMSTYLE table or per-dimension style, so the header's current-dimstyle\n // value is the source; carry it onto each dimension's style override.\n const dimScaleRaw = header?.[\"$DIMSCALE\"];\n const dimScale =\n typeof dimScaleRaw === \"number\" && dimScaleRaw > 0 ? dimScaleRaw : 1;\n\n const trueColors = scanTrueColors(text);\n\n // Layers: match by name, create the missing ones. Keys are lowercased:\n // DXF layer names are case-insensitive, and so are Linea's (one layer\n // per name, op layer) — \"Walls\" and \"WALLS\" are the same layer.\n const layerIdByName = new Map<string, string>();\n for (const layer of input.existingLayers)\n layerIdByName.set(layer.name.toLowerCase(), layer.id);\n const newLayers: Layer[] = [];\n const dxfLayers = dxf.tables?.layer?.layers ?? {};\n for (const [name, dxfLayer] of Object.entries(dxfLayers)) {\n if (layerIdByName.has(name.toLowerCase()) || name === \"0\") continue;\n const colorInt = (dxfLayer as { color?: number }).color ?? 0xffffff;\n newLayers.push({\n id: crypto.randomUUID(),\n name,\n color:\n trueColors.byLayerName.get(name) ??\n rgbToHex(\n (colorInt >> 16) & 0xff,\n (colorInt >> 8) & 0xff,\n colorInt & 0xff,\n ),\n // Layers have no lineTypeScale, so a 2/X2 variant's factor is dropped\n // here (base pattern at base scale) — still the closest rendering.\n lineType:\n lineTypeFromDxf((dxfLayer as { lineType?: string }).lineType)?.name ??\n \"continuous\",\n lineWidth: IMPORT_LINE_WIDTH_MM,\n opacity: 1,\n visible: (dxfLayer as { visible?: boolean }).visible !== false,\n locked: false,\n print: true,\n });\n layerIdByName.set(name.toLowerCase(), newLayers[newLayers.length - 1].id);\n }\n const ctx: ImportContext = {\n f,\n layerIdByName,\n // Existing layers ({id,name} only) can't be classified — entity-level\n // line types still gate correctly; byLayer dashes there stay unscaled.\n dashedLayerIds: new Set(\n newLayers\n .filter((l) => (getLineType(l.lineType)?.dashesMm.length ?? 0) > 0)\n .map((l) => l.id),\n ),\n defaultLayerId: input.defaultLayerId,\n skipped: new Map(),\n dimTextHeight: input.dimTextHeight,\n dimArrowSize: input.dimArrowSize,\n dimScale,\n trueColorByHandle: trueColors.byHandle,\n };\n\n // Paper spaces: entities live inside *Paper_Space blocks, EXCEPT the\n // active layout's, which sit flat in ENTITIES with the paper-space flag.\n const paperBlocks = Object.values(dxf.blocks ?? {}).filter((b) =>\n /^\\*paper_space/i.test((b as IBlock).name ?? \"\"),\n ) as IBlock[];\n const primaryPaper =\n paperBlocks.find((b) => b.name.toLowerCase() === \"*paper_space\") ??\n paperBlocks[0];\n const paperEntities = new Map<IBlock, IEntity[]>(\n paperBlocks.map((b) => [b, [...(b.entities ?? [])]]),\n );\n\n const dtos: ModelObjectDto[] = [];\n for (const entity of dxf.entities ?? []) {\n if ((entity as any).inPaperSpace) {\n if (primaryPaper) paperEntities.get(primaryPaper)?.push(entity);\n else\n ctx.skipped.set(\n \"paper-space\",\n (ctx.skipped.get(\"paper-space\") ?? 0) + 1,\n );\n continue;\n }\n if (entity.type === \"VIEWPORT\") continue; // stray model-space viewport\n // ACAD_TABLE is INSERT-shaped: its rendered lines/text live in an\n // anonymous *T block (AcadTableHandler surfaces name + position).\n if (entity.type === \"ACAD_TABLE\") {\n const table = convertAcadTable(entity, ctx);\n if (table) {\n dtos.push(table);\n continue;\n }\n }\n if (entity.type === \"INSERT\") {\n const ref = xrefReference(entity, dxf, ctx);\n if (ref) {\n dtos.push(ref);\n continue;\n }\n }\n if (entity.type === \"INSERT\" || entity.type === \"ACAD_TABLE\") {\n const exploded = convertInsert(entity, dxf, ctx);\n if (exploded.length === 0)\n ctx.skipped.set(entity.type, (ctx.skipped.get(entity.type) ?? 0) + 1);\n dtos.push(...exploded);\n continue;\n }\n const converted = convertEntity(entity, dxf, ctx);\n if (converted.length === 0 && ![\"SPLINE\"].includes(entity.type)) {\n ctx.skipped.set(entity.type, (ctx.skipped.get(entity.type) ?? 0) + 1);\n }\n dtos.push(...converted);\n }\n\n // Rebuild paper layouts. LAYOUT objects (raw OBJECTS scan) supply name,\n // tab order, and sheet size; the layout's own id-1 viewport is the sheet\n // fallback. Empty spaces are skipped.\n const layoutInfos = parseLayoutObjects(text);\n const infoFor = (block: IBlock) =>\n layoutInfos.find(\n (li) =>\n li.blockRecordHandle !== undefined &&\n li.blockRecordHandle === String(block.ownerHandle ?? \"\").toUpperCase(),\n );\n const orderedBlocks = [...paperEntities.keys()].sort(\n (a, b) =>\n (infoFor(a)?.tabOrder ?? Number.MAX_SAFE_INTEGER) -\n (infoFor(b)?.tabOrder ?? Number.MAX_SAFE_INTEGER),\n );\n\n const newLayouts: PaperLayout[] = [];\n for (const block of orderedBlocks) {\n const entities = paperEntities.get(block) ?? [];\n if (entities.length === 0) continue;\n const info = infoFor(block);\n let sheetFallback: { w: number; h: number } | null = null;\n const objects: ModelObject[] = [];\n for (const e of entities) {\n const anyE = e as any;\n if (e.type === \"VIEWPORT\") {\n if (anyE.viewportId === 1) {\n // The layout's own paper view — remember its size for the sheet.\n if (anyE.width > 0 && anyE.height > 0)\n sheetFallback = { w: anyE.width * f, h: anyE.height * f };\n continue;\n }\n const vp = convertViewport(e, ctx);\n if (vp) objects.push({ ...vp, id: crypto.randomUUID() } as ModelObject);\n else\n ctx.skipped.set(\"VIEWPORT\", (ctx.skipped.get(\"VIEWPORT\") ?? 0) + 1);\n continue;\n }\n const table = e.type === \"ACAD_TABLE\" ? convertAcadTable(e, ctx) : null;\n const converted = table\n ? [table]\n : e.type === \"INSERT\" || e.type === \"ACAD_TABLE\"\n ? convertInsert(e, dxf, ctx)\n : convertEntity(e, dxf, ctx);\n for (const dto of converted)\n objects.push({ ...dto, id: crypto.randomUUID() } as ModelObject);\n }\n if (objects.length === 0) continue;\n try {\n newLayouts.push(\n PaperLayoutSchema.parse({\n id: crypto.randomUUID(),\n name: info?.name || `Layout ${newLayouts.length + 1}`,\n sheet: {\n width: info?.paperWidth ?? sheetFallback?.w ?? 297,\n height: info?.paperHeight ?? sheetFallback?.h ?? 210,\n },\n objects,\n }),\n );\n } catch (err) {\n console.error(\"layout import failed\", block.name, err);\n ctx.skipped.set(\"layout\", (ctx.skipped.get(\"layout\") ?? 0) + 1);\n }\n }\n\n // Resilience: drop any object that fails schema validation (counting it as\n // skipped) so a single malformed entity can't abort the whole import — the\n // funnel validates the batch all-or-nothing.\n const validObjects: ModelObjectDto[] = [];\n for (const dto of dtos) {\n if (ModelObjectSchema.safeParse({ ...dto, id: \"_\" }).success) {\n validObjects.push(dto);\n } else {\n const key = `invalid ${dto.type}`;\n ctx.skipped.set(key, (ctx.skipped.get(key) ?? 0) + 1);\n }\n }\n\n return {\n objects: validObjects,\n newLayers,\n layouts: newLayouts,\n skipped: ctx.skipped,\n };\n};\n","// Custom dxf-parser entity handlers for types the library doesn't ship:\n// VIEWPORT, HATCH, LEADER. Each follows the library's handler contract —\n// a class with ForEntityName + parseEntity(scanner, curr) — registered via\n// DxfParser.registerEntityHandler. dxf-parser's helpers aren't exported, so\n// the point/common-code readers are re-implemented here (same semantics).\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\n\ninterface Tag {\n code: number;\n value: any;\n}\n\ninterface Scanner {\n next(): Tag;\n rewind(): void;\n isEOF(): boolean;\n}\n\n/**\n * Read a 2D/3D point whose X group was just consumed (mirror of the\n * library's parsePoint: rewind, re-read X, expect +10 for Y, optional +20).\n */\nconst parsePoint = (scanner: Scanner): { x: number; y: number } => {\n scanner.rewind();\n let curr = scanner.next();\n let code = curr.code;\n const point = { x: curr.value as number, y: 0 };\n code += 10;\n curr = scanner.next();\n if (curr.code !== code)\n throw new Error(`Expected code ${code} for point Y, got ${curr.code}`);\n point.y = curr.value as number;\n curr = scanner.next();\n if (curr.code !== code + 10) scanner.rewind(); // no Z — let caller advance\n return point;\n};\n\n/** Common entity codes (subset of the library's checkCommonEntityProperties). */\nconst commonProp = (entity: any, curr: Tag): void => {\n switch (curr.code) {\n case 5:\n entity.handle = curr.value;\n break;\n case 6:\n entity.lineType = curr.value;\n break;\n case 8:\n entity.layer = curr.value;\n break;\n case 48:\n entity.lineTypeScale = curr.value;\n break;\n case 60:\n // Invisibility flag (1 = hidden) — chiefly dynamic-block visibility\n // states, whose inactive entities import as all-states-at-once\n // otherwise. Same field dxf-parser's built-in handlers set.\n entity.visible = curr.value === 0;\n break;\n case 62:\n entity.colorIndex = curr.value;\n break;\n case 420:\n entity.trueColor = curr.value; // 24-bit RGB (overrides the ACI index)\n break;\n case 67:\n entity.inPaperSpace = curr.value !== 0;\n break;\n }\n};\n\n/** Paper-space VIEWPORT entity (frames a model view on a layout sheet). */\nexport class ViewportHandler {\n ForEntityName = \"VIEWPORT\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, frozenLayerHandles: [] };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 10:\n entity.center = parsePoint(scanner);\n break;\n case 12:\n entity.viewCenter = parsePoint(scanner);\n break;\n case 40:\n entity.width = curr.value;\n break;\n case 41:\n entity.height = curr.value;\n break;\n case 45:\n entity.viewHeight = curr.value;\n break;\n case 68:\n entity.status = curr.value;\n break;\n case 69:\n entity.viewportId = curr.value;\n break;\n case 90:\n entity.statusFlags = curr.value;\n break;\n case 331:\n entity.frozenLayerHandles.push(String(curr.value));\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * HATCH entity. Parses boundary paths (polyline or edge form), the pattern\n * header (name / solid flag / angle / scale), and pattern definition lines.\n * Seed points and gradient data are consumed and ignored.\n */\nexport class HatchHandler {\n ForEntityName = \"HATCH\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = {\n type: curr.value,\n boundaryPaths: [],\n patternLines: [],\n };\n let path: any = null;\n let edge: any = null;\n let patternLine: any = null;\n let mode: \"header\" | \"pattern\" | \"seeds\" = \"header\";\n\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 2:\n entity.patternName = curr.value;\n break;\n case 70:\n entity.solid = curr.value === 1;\n break;\n case 75:\n entity.hatchStyle = curr.value;\n break;\n case 76:\n entity.patternType = curr.value;\n break;\n case 52:\n entity.patternAngle = curr.value;\n break;\n case 41:\n entity.patternScale = curr.value;\n break;\n case 92:\n // New boundary path; bit 2 = polyline form.\n path = {\n flags: curr.value,\n isPolyline: (curr.value & 2) !== 0,\n vertices: [],\n edges: [],\n };\n edge = null;\n entity.boundaryPaths.push(path);\n break;\n case 72:\n if (!path) break;\n if (path.isPolyline) path.hasBulge = curr.value !== 0;\n else {\n // New edge; 1 line, 2 arc, 3 ellipse, 4 spline.\n edge = { kind: curr.value, points: [] };\n path.edges.push(edge);\n }\n break;\n case 73:\n if (path?.isPolyline) path.closed = curr.value !== 0;\n else if (edge) edge.ccw = curr.value !== 0;\n break;\n case 78:\n mode = \"pattern\";\n break;\n case 98:\n mode = \"seeds\";\n break;\n case 53:\n if (mode === \"pattern\") {\n patternLine = { angle: curr.value };\n entity.patternLines.push(patternLine);\n }\n break;\n case 43:\n if (patternLine) patternLine.baseX = curr.value;\n break;\n case 44:\n if (patternLine) patternLine.baseY = curr.value;\n break;\n case 45:\n if (patternLine) patternLine.offsetX = curr.value;\n break;\n case 46:\n if (patternLine) patternLine.offsetY = curr.value;\n break;\n case 10: {\n const p = parsePoint(scanner);\n if (mode === \"seeds\") break; // seed points — ignore\n if (path?.isPolyline) path.vertices.push({ ...p, bulge: 0 });\n else if (edge) edge.points.push(p);\n break;\n }\n case 11: {\n const p = parsePoint(scanner);\n if (edge) edge.end = p;\n break;\n }\n case 42:\n if (path?.isPolyline && path.vertices.length > 0)\n path.vertices[path.vertices.length - 1].bulge = curr.value;\n break;\n case 40:\n if (edge) edge.r40 = curr.value;\n break;\n case 50:\n if (edge) edge.startAngle = curr.value;\n break;\n case 51:\n if (edge) edge.endAngle = curr.value;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/** One cell of an ACAD_TABLE's legacy AcDbTable payload. */\nexport interface AcadTableCell {\n /** 171: 1 = text, 2 = block. */\n type: number;\n /** 175 / 176: merge extent on the anchor cell. */\n cols: number;\n rows: number;\n /** 173: covered by a merge. */\n merged?: boolean;\n /** 170: attachment 1–9 (TL TC TR / ML MC MR / BL BC BR). */\n alignment?: number;\n /** 7: text style name. */\n style?: string;\n /** 140: text height. */\n height?: number;\n /** 145: text rotation (radians). */\n rotation?: number;\n /** 1 (+ 3 chunks): MTEXT content. */\n text?: string;\n /** 302: formatted display string (numeric cells' only text). */\n display?: string;\n}\n\n/** The table structure ACAD_TABLE carries next to its *T block. */\nexport interface AcadTableData {\n rows: number;\n cols: number;\n rowHeights: number[];\n colWidths: number[];\n /** 40: horizontal cell margin. */\n margin?: number;\n cells: AcadTableCell[];\n}\n\n/**\n * ACAD_TABLE entity. A table's rendered geometry (grid lines + cell text)\n * lives in an anonymous *T block named by the AcDbBlockReference subclass\n * (group 2, insertion point 10, optional direction vector 11) — the importer\n * explodes that block like an INSERT. The AcDbTable payload that follows\n * REUSES the same group codes for per-cell data (2 = cell text, 62 = cell\n * color overrides, …), so all capturing stops at its subclass marker and the\n * rest is skimmed to the entity boundary.\n */\nexport class AcadTableHandler {\n ForEntityName = \"ACAD_TABLE\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value };\n let inTableData = false;\n // The legacy AcDbTable payload (still written by current AutoCAD next to\n // its TABLECONTENT objects): table-level groups first, then one run per\n // cell starting at 171. Codes 91/92/140 recur INSIDE cells with other\n // meanings, so table-level values are only read before the first cell.\n const table: AcadTableData = {\n rows: 0,\n cols: 0,\n rowHeights: [],\n colWidths: [],\n cells: [],\n };\n let cell: AcadTableCell | null = null;\n let textChunks = \"\";\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n if (curr.code === 100 && curr.value === \"AcDbTable\") inTableData = true;\n if (inTableData && curr.code !== 100) {\n const num = () => Number(curr.value);\n if (curr.code === 171) {\n cell = { type: num(), cols: 1, rows: 1 };\n table.cells.push(cell);\n textChunks = \"\";\n } else if (!cell) {\n if (curr.code === 91) table.rows = num();\n else if (curr.code === 92) table.cols = num();\n else if (curr.code === 141) table.rowHeights.push(num());\n else if (curr.code === 142) table.colWidths.push(num());\n else if (curr.code === 40) table.margin = num();\n else if (curr.code === 11) {\n // Horizontal direction → rotation (degrees, INSERT-style).\n const dir = parsePoint(scanner);\n if (dir.x !== 0 || dir.y !== 0)\n entity.rotation = (Math.atan2(dir.y, dir.x) * 180) / Math.PI;\n }\n } else if (curr.code === 175) cell.cols = num();\n else if (curr.code === 176) cell.rows = num();\n else if (curr.code === 173) cell.merged = num() !== 0;\n else if (curr.code === 170) cell.alignment = num();\n else if (curr.code === 7) cell.style ??= String(curr.value);\n else if (curr.code === 140) cell.height ??= num();\n else if (curr.code === 145) cell.rotation ??= num();\n // Long cell text arrives as 3-chunks then the final 1 (MTEXT style);\n // later 1s (ACVALUE copies) are ignored.\n else if (curr.code === 3) textChunks += String(curr.value);\n else if (curr.code === 1 && cell.text === undefined)\n cell.text = textChunks + String(curr.value ?? \"\");\n // The formatted display string: the only text a NUMERIC cell has\n // (its value rides as 90 = type / 91 = number, no group 1).\n else if (curr.code === 302 && cell.display === undefined)\n cell.display = String(curr.value ?? \"\");\n }\n if (!inTableData) {\n switch (curr.code) {\n case 2:\n entity.name = curr.value;\n break;\n case 10:\n entity.position = parsePoint(scanner);\n break;\n case 11: {\n // Horizontal direction vector → rotation (degrees, like INSERT's\n // group 50, so convertInsert consumes it unchanged).\n const dir = parsePoint(scanner);\n if (dir.x !== 0 || dir.y !== 0)\n entity.rotation = (Math.atan2(dir.y, dir.x) * 180) / Math.PI;\n break;\n }\n default:\n commonProp(entity, curr);\n break;\n }\n }\n curr = scanner.next();\n }\n if (table.rows > 0 && table.cols > 0) entity.table = table;\n return entity;\n }\n}\n\n/** Plain LEADER entity (arrow polyline; any annotation stays separate). */\nexport class LeaderHandler {\n ForEntityName = \"LEADER\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, vertices: [] };\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 3:\n entity.styleName = curr.value;\n break;\n case 10:\n entity.vertices.push(parsePoint(scanner));\n break;\n case 71:\n entity.arrowheadFlag = curr.value;\n break;\n case 72:\n entity.pathType = curr.value;\n break;\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n\n/**\n * MULTILEADER entity. Parses the CONTEXT_DATA block's mtext content and\n * text/arrow sizes, plus every LEADER node's junction and LEADER_LINE vertex\n * runs. Marker tags: 300/301 context, 302/303 leader, 304/305 leader line\n * (304 doubles as the mtext content code — disambiguated by value).\n */\nexport class MultiLeaderHandler {\n ForEntityName = \"MULTILEADER\";\n\n parseEntity(scanner: Scanner, curr: Tag): any {\n const entity: any = { type: curr.value, leaders: [] };\n let inContext = false;\n let leader: any = null;\n let line: any = null;\n\n curr = scanner.next();\n while (!scanner.isEOF()) {\n if (curr.code === 0) break;\n switch (curr.code) {\n case 300:\n inContext = true;\n break;\n case 301:\n inContext = false;\n break;\n case 302:\n leader = { junction: null, lines: [] };\n entity.leaders.push(leader);\n break;\n case 303:\n leader = null;\n break;\n case 304:\n if (curr.value === \"LEADER_LINE{\" && leader) {\n line = [];\n leader.lines.push(line);\n } else if (inContext && !leader && entity.content === undefined) {\n entity.content = curr.value;\n }\n break;\n case 305:\n line = null;\n break;\n case 40:\n if (inContext && !leader) entity.overallScale = curr.value;\n break;\n case 41:\n if (inContext && !leader) entity.textHeight = curr.value;\n break;\n case 140:\n if (inContext && !leader) entity.arrowSize = curr.value;\n break;\n case 12: {\n const p = parsePoint(scanner);\n if (inContext && !leader) entity.textLocation = p;\n break;\n }\n case 10: {\n const p = parsePoint(scanner);\n if (line) line.push(p);\n else if (leader) leader.junction = p;\n break;\n }\n default:\n commonProp(entity, curr);\n break;\n }\n curr = scanner.next();\n }\n return entity;\n }\n}\n","// Minimal OBJECTS-section reader. dxf-parser skips the whole section, but\n// LAYOUT objects live there — without them imported paper spaces would lose\n// their names, tab order, and sheet sizes. This scans the raw tag stream and\n// extracts just the LAYOUT records.\n\nexport interface DxfLayoutInfo {\n name: string;\n tabOrder: number;\n /** Plot paper size, mm (PlotSettings groups 44/45). */\n paperWidth?: number;\n paperHeight?: number;\n /** BLOCK_RECORD handle of the owning space (uppercased). */\n blockRecordHandle?: string;\n}\n\nexport const parseLayoutObjects = (text: string): DxfLayoutInfo[] => {\n const lines = text.split(/\\r\\n|\\r|\\n/);\n const layouts: DxfLayoutInfo[] = [];\n\n let inObjects = false;\n let prevZeroValue = \"\"; // value of the last (0, …) tag\n let current: DxfLayoutInfo | null = null;\n let subclass = \"\";\n\n const commit = () => {\n if (current && current.name) layouts.push(current);\n current = null;\n subclass = \"\";\n };\n\n for (let i = 0; i + 1 < lines.length; i += 2) {\n const code = parseInt(lines[i], 10);\n if (Number.isNaN(code)) continue;\n const value = lines[i + 1].trim();\n\n if (code === 0) {\n commit();\n if (value === \"ENDSEC\" && inObjects) break;\n if (inObjects && value === \"LAYOUT\") current = { name: \"\", tabOrder: 0 };\n prevZeroValue = value;\n continue;\n }\n if (code === 2 && prevZeroValue === \"SECTION\") {\n inObjects = value === \"OBJECTS\";\n continue;\n }\n if (!current) continue;\n\n if (code === 100) {\n subclass = value;\n continue;\n }\n if (subclass === \"AcDbPlotSettings\") {\n if (code === 44) current.paperWidth = parseFloat(value) || undefined;\n else if (code === 45)\n current.paperHeight = parseFloat(value) || undefined;\n } else if (subclass === \"AcDbLayout\") {\n if (code === 1) current.name = value;\n else if (code === 71) current.tabOrder = parseInt(value, 10) || 0;\n else if (code === 330 && !current.blockRecordHandle)\n current.blockRecordHandle = value.toUpperCase();\n }\n }\n commit();\n\n return layouts.sort((a, b) => a.tabOrder - b.tabOrder);\n};\n","// References: LINKED files drawn in place (docs/references.md). The document\n// holds only the `reference` record (format, placement, `source`); the file's\n// bytes live host-side, reached through `ReferenceFileAccess`. Every format\n// loads into the same shape — a `ReferenceContent`, the file's model space as\n// Linea objects — so painting, snapping and binding never care what the file\n// was. This module is pure: loading bytes and caching content is the host's.\n\nimport type { AABB } from \"../geometry/bounds\";\nimport {\n addPointToBounds,\n emptyBounds,\n isEmptyBounds,\n} from \"../geometry/bounds\";\nimport type { Vec2 } from \"../geometry/vec2\";\nimport type { LineaDocument } from \"../model/document\";\nimport { emptyDocument } from \"../model/defaults\";\nimport { hashAsset } from \"../model/assets\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport type { ArcGeom } from \"../geometry/arcs\";\nimport type { EllipseGeom } from \"../geometry/ellipse\";\nimport type { SnapPointType } from \"../snap/types\";\nimport { unionBounds } from \"../geometry/bounds\";\nimport { dxfToModel } from \"../import/dxf/importDxf\";\nimport {\n mirrorObject,\n rotateObject,\n scaleObjectUniform,\n translateObject,\n} from \"../transform\";\nimport {\n REFERENCE_FORMATS,\n type ModelObject,\n type ReferenceFormat,\n type ReferenceObject,\n type ReferenceSource,\n} from \"../model/objects\";\nimport type { LayoutModelContext } from \"../paint/layoutPaint\";\nimport type { Mat2x3 } from \"../paint/sink\";\n\n/**\n * How a host reaches the files references point at (calculus's seam,\n * verbatim). Desktop: real paths. A browser can't read paths — it keeps a\n * copy of the bytes under `source.cacheKey` instead (editor-side store).\n */\nexport interface ReferenceFileAccess {\n /** Native picker filtered to the reference formats; absolute paths, or\n * null on cancel. */\n pick(): Promise<string[] | null>;\n /** A file's bytes by its STORED path (relative paths resolve against the\n * document's folder). Rejects when missing. */\n read(path: string): Promise<Uint8Array>;\n /** Size + mtime of a stored path (reload detection); null when missing. */\n stat(path: string): Promise<{ size: number; mtimeMs: number } | null>;\n /** The path to store for a picked absolute path: relative (POSIX\n * separators) when inside the document's folder, else absolute. */\n toStoredPath(absolutePath: string): Promise<string>;\n /** Stored path → absolute path (display, cache keys). */\n toAbsolutePath(storedPath: string): Promise<string>;\n}\n\n/** A loaded reference: the file's model space as Linea objects (ids\n * prefixed per reference — see `contentFromDocument`) plus its bounds. */\nexport interface ReferenceContent extends LayoutModelContext {\n /** Content bounds in FILE coordinates (empty for an empty file). */\n bounds: AABB;\n /** PDF: how many pages the file has (the page field's range). */\n pageCount?: number;\n /**\n * Snap geometry precomputed in FILE coordinates (off the main thread —\n * see `referenceSnapOf`); absent → derived from `objects`. A raster PDF\n * carries its page's VECTOR geometry here: it paints the image and snaps\n * to the lines.\n */\n snap?: ReferenceSnap;\n}\n\n/** File-space snap primitives, each tagged with its layer id (so the\n * reference's hidden layers still filter them). */\nexport interface ReferenceSnap {\n points: { p: Vec2; type: SnapPointType; layer: string }[];\n segments: { a: Vec2; b: Vec2; chord?: boolean; layer: string }[];\n arcs: (ArcGeom & { layer: string })[];\n ellipses: (EllipseGeom & { layer: string })[];\n}\n\n/** A document's snap geometry in its own coordinates (references inside it\n * excluded — they resolve per placement). Heavy for big files: hosts run it\n * off the main thread with the file's conversion. */\nexport const referenceSnapOf = (\n doc: Pick<\n LineaDocument,\n \"objects\" | \"dimStyles\" | \"textStyles\" | \"blockDefinitions\"\n >,\n measure: TextMeasurer,\n): ReferenceSnap => {\n const snap: ReferenceSnap = {\n points: [],\n segments: [],\n arcs: [],\n ellipses: [],\n };\n const byId = new Map(doc.objects.map((o) => [o.id, o]));\n const ctx = {\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n blockDefinitions: doc.blockDefinitions,\n resolveObject: (id: string) => byId.get(id),\n measure,\n };\n for (const o of doc.objects) {\n if (o.type === \"reference\") continue;\n const e = buildSnapEntry(o, ctx);\n const layer = o.layerId;\n for (const p of e.points) snap.points.push({ ...p, layer });\n for (const s of e.segments) snap.segments.push({ ...s, layer });\n for (const a of e.arcs) snap.arcs.push({ ...a, layer });\n for (const el of e.ellipses ?? []) snap.ellipses.push({ ...el, layer });\n }\n return snap;\n};\n\n/** A nested reference's source as seen from the HOST document: a relative\n * path inside a referenced file is relative to THAT file's folder. */\nexport const rebaseReferenceSource = (\n child: ReferenceSource,\n parent: ReferenceSource,\n): ReferenceSource => {\n if (child.kind === \"url\" || parent.kind === \"url\") return child;\n if (/^([A-Za-z]:[\\\\/]|[\\\\/])/.test(child.path)) return child;\n const folder = parent.path.replace(/\\\\/g, \"/\").replace(/\\/?[^/]*$/, \"\");\n return { ...child, path: folder ? `${folder}/${child.path}` : child.path };\n};\n\n/** The reference format a file name implies, or null. */\nexport const referenceFormatOf = (fileName: string): ReferenceFormat | null => {\n const ext = /\\.([^./\\\\]+)$/.exec(fileName)?.[1]?.toLowerCase();\n if (ext === \"jpeg\") return \"jpg\";\n if (ext === \"lineadraw\") return \"linea\";\n return REFERENCE_FORMATS.find((f) => f === ext) ?? null;\n};\n\n/** The file-picker `accept` list for references. */\nexport const REFERENCE_ACCEPT = REFERENCE_FORMATS.flatMap((f) =>\n f === \"jpg\"\n ? [\".jpg\", \".jpeg\"]\n : f === \"linea\"\n ? [\".linea\", \".lineadraw\"]\n : [`.${f}`],\n).join(\",\");\n\n/** File coordinates → the host document: rotation + uniform scale about the\n * file origin (mirrored: the file flips LEFT-RIGHT first, x → −x — what\n * \"mirror\" means to a user), then `position`. */\nexport const referenceTransform = (ref: ReferenceObject): Mat2x3 => {\n const s = ref.scale;\n const m = ref.mirrored ? -1 : 1;\n const c = Math.cos(ref.rotation);\n const n = Math.sin(ref.rotation);\n return [m * s * c, m * s * n, -s * n, s * c, ref.position.x, ref.position.y];\n};\n\nexport const applyMat = (m: Mat2x3, p: Vec2): Vec2 => ({\n x: m[0] * p.x + m[2] * p.y + m[4],\n y: m[1] * p.x + m[3] * p.y + m[5],\n});\n\n/** The four corners of a file-space box placed by `m`. */\nexport const placedCorners = (m: Mat2x3, b: AABB): Vec2[] =>\n [\n { x: b.minX, y: b.minY },\n { x: b.maxX, y: b.minY },\n { x: b.maxX, y: b.maxY },\n { x: b.minX, y: b.maxY },\n ].map((p) => applyMat(m, p));\n\n/** The placed (host) bounds of a file-space box. */\nexport const placedBounds = (m: Mat2x3, b: AABB): AABB => {\n const out = emptyBounds();\n if (isEmptyBounds(b)) return out;\n for (const p of placedCorners(m, b)) addPointToBounds(out, p);\n return out;\n};\n\n/**\n * A document's model space as reference content. Object ids are prefixed\n * with the reference's id (and block object-reference inputs with them), so\n * per-id caches — block evaluation, its errors and dependencies — never mix a\n * referenced file's objects with the host's own, even when the file is a\n * copy of the drawing that references it.\n */\nexport const contentFromDocument = (\n doc: LineaDocument,\n refId: string,\n bounds: AABB = emptyBounds(),\n): ReferenceContent => {\n const prefix = `ref:${refId}:`;\n const objects: ModelObject[] = doc.objects.map((o) =>\n o.type === \"block\"\n ? {\n ...o,\n id: prefix + o.id,\n inputs: o.inputs.map((v) => (typeof v === \"string\" ? prefix + v : v)),\n }\n : { ...o, id: prefix + o.id },\n );\n const byId = new Map(objects.map((o) => [o.id, o]));\n return {\n objects,\n layers: doc.layers,\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n blockDefinitions: doc.blockDefinitions,\n assets: doc.assets,\n resolveObject: (id) => byId.get(id),\n bounds,\n };\n};\n\n/** A fresh document holding DTOs (ids assigned) — what non-.linea formats\n * convert into before `contentFromDocument`. */\nexport const documentWithObjects = (\n build: (doc: LineaDocument) => {\n objects: readonly Record<string, unknown>[];\n layers?: LineaDocument[\"layers\"];\n },\n): LineaDocument => {\n const doc = emptyDocument();\n const { objects, layers } = build(doc);\n if (layers) doc.layers = layers;\n doc.objects = objects.map(\n (o) =>\n ({ ...o, id: crypto.randomUUID() }) as LineaDocument[\"objects\"][number],\n );\n return doc;\n};\n\n/** DXF text → a document (units converted to mm by the importer; blocks\n * come exploded, layouts are ignored — a reference shows model space). */\nexport const documentFromDxf = (text: string): LineaDocument =>\n documentWithObjects((doc) => {\n const result = dxfToModel(text, {\n existingLayers: doc.layers.map((l) => ({ id: l.id, name: l.name })),\n defaultLayerId: doc.layers[0].id,\n dimTextHeight: doc.dimStyles[0].textHeight,\n dimArrowSize: doc.dimStyles[0].arrowSize,\n });\n return {\n objects: result.objects,\n layers: [...doc.layers, ...result.newLayers],\n };\n });\n\n/** A content object as native geometry where the reference draws it —\n * Bind's per-object step: mirror (left-right), scale about the file origin,\n * rotate, then move to the insertion point (the order referenceTransform\n * composes). */\nexport const placeReferenceObject = (\n obj: ModelObject,\n ref: ReferenceObject,\n): ModelObject => {\n const origin = { x: 0, y: 0 };\n let o = ref.mirrored ? mirrorObject(obj, origin, { x: 0, y: 1 }) : obj;\n if (ref.scale !== 1) o = scaleObjectUniform(o, ref.scale);\n if (ref.rotation !== 0) o = rotateObject(o, origin, ref.rotation);\n return translateObject(o, ref.position);\n};\n\n/** A document holding one image (bottom-left at the origin) — the content\n * of a PNG/JPEG reference or a raster PDF page. */\nexport const documentFromImage = (\n dataUrl: string,\n widthMm: number,\n heightMm: number,\n): LineaDocument => {\n const doc = emptyDocument();\n const assetId = hashAsset(dataUrl);\n doc.assets = { [assetId]: dataUrl };\n doc.objects = [\n {\n id: \"image\",\n type: \"image\",\n layerId: doc.layers[0].id,\n assetId,\n origin: { x: 0, y: 0 },\n width: widthMm,\n height: heightMm,\n rotation: 0,\n },\n ];\n return doc;\n};\n\n/** A PNG's / JPEG's pixel size from its header (no decoder — Node has\n * none); null when the bytes aren't one. */\nexport const imagePixelSize = (\n b: Uint8Array,\n): { width: number; height: number } | null => {\n const u32 = (i: number) =>\n ((b[i] << 24) | (b[i + 1] << 16) | (b[i + 2] << 8) | b[i + 3]) >>> 0;\n const u16 = (i: number) => (b[i] << 8) | b[i + 1];\n if (b[0] === 0x89 && b[1] === 0x50 && b[2] === 0x4e && b[3] === 0x47)\n return { width: u32(16), height: u32(20) }; // IHDR\n if (b[0] !== 0xff || b[1] !== 0xd8) return null;\n // JPEG: walk the segments to the first start-of-frame (SOF0..SOF15\n // except DHT/JPG/DAC), whose payload holds height then width.\n for (let i = 2; i + 9 < b.length;) {\n if (b[i] !== 0xff) return null;\n const marker = b[i + 1];\n const len = u16(i + 2);\n if (\n marker >= 0xc0 &&\n marker <= 0xcf &&\n marker !== 0xc4 &&\n marker !== 0xc8 &&\n marker !== 0xcc\n )\n return { width: u16(i + 7), height: u16(i + 5) };\n i += 2 + len;\n }\n return null;\n};\n\n/** Content bounds in file coordinates (text measured by `measure`); the\n * origin for an empty file, so a frame still has a corner. */\nexport const measureContentBounds = (\n content: Omit<ReferenceContent, \"bounds\">,\n measure: TextMeasurer,\n): AABB => {\n const ctx = {\n dimStyles: content.dimStyles,\n textStyles: content.textStyles,\n blockDefinitions: content.blockDefinitions,\n resolveObject: content.resolveObject,\n resolveReference: content.resolveReference,\n measure,\n };\n let bounds = emptyBounds();\n for (const o of content.objects) {\n const b = buildSnapEntry(o, ctx).bounds;\n if (!isEmptyBounds(b)) bounds = unionBounds(bounds, b);\n }\n if (isEmptyBounds(bounds)) addPointToBounds(bounds, { x: 0, y: 0 });\n return bounds;\n};\n\n/** Host → file coordinates (the inverse of referenceTransform) — clip\n * rectangles are picked in the drawing and stored in the file's frame. */\nexport const toReferenceCoords = (ref: ReferenceObject, p: Vec2): Vec2 => {\n const dx = p.x - ref.position.x;\n const dy = p.y - ref.position.y;\n const c = Math.cos(-ref.rotation);\n const n = Math.sin(-ref.rotation);\n const x = (c * dx - n * dy) / ref.scale;\n const y = (n * dx + c * dy) / ref.scale;\n return { x: ref.mirrored ? -x : x, y };\n};\n\n/** A segment clipped to a box (Liang–Barsky), or null when outside. */\nexport const clipSegment = (\n a: Vec2,\n b: Vec2,\n box: AABB,\n): [Vec2, Vec2] | null => {\n let t0 = 0;\n let t1 = 1;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const edges: [number, number][] = [\n [-dx, a.x - box.minX],\n [dx, box.maxX - a.x],\n [-dy, a.y - box.minY],\n [dy, box.maxY - a.y],\n ];\n for (const [p, q] of edges) {\n if (p === 0) {\n if (q < 0) return null;\n } else {\n const t = q / p;\n if (p < 0) t0 = Math.max(t0, t);\n else t1 = Math.min(t1, t);\n if (t0 > t1) return null;\n }\n }\n return [\n { x: a.x + t0 * dx, y: a.y + t0 * dy },\n { x: a.x + t1 * dx, y: a.y + t1 * dy },\n ];\n};\n","import type { Layer } from \"../model/document\";\nimport type { ModelObject } from \"../model/objects\";\nimport { dashForLineType, scaleDash } from \"./lineTypes\";\n\nexport interface ResolvedStyle {\n color: string;\n widthMm: number;\n /** Dash pattern in mm (undefined = continuous). */\n dashMm?: number[];\n /** Paint opacity 0..1 (undefined = opaque). */\n opacity?: number;\n}\n\nconst FALLBACK_STYLE: ResolvedStyle = {\n color: \"#e8e8e8\",\n widthMm: 0.25,\n};\n\n/** Resolve byLayer color/lineweight/linetype through the object's layer. */\nexport const resolveStyle = (\n obj: ModelObject,\n layers: Layer[],\n): ResolvedStyle => {\n const layer = layers.find((l) => l.id === obj.layerId);\n const widthMm = obj.lineWidth ?? layer?.lineWidth ?? FALLBACK_STYLE.widthMm;\n return {\n color: obj.color ?? layer?.color ?? FALLBACK_STYLE.color,\n widthMm,\n // Dash patterns are defined per 1 mm of line width (ISO 128 style —\n // pattern legibility tracks stroke weight), so the resolved lineweight\n // scales them; lineTypeScale (CELTSCALE) multiplies on top.\n dashMm: scaleDash(\n dashForLineType(obj.lineType ?? layer?.lineType),\n widthMm * (obj.lineTypeScale ?? 1),\n ),\n opacity: obj.opacity ?? layer?.opacity,\n };\n};\n","// Drawing far from the origin. Survey-grid drawings (a masterplan in\n// ETRS-GK coordinates: ~2·10¹⁰ mm) lose all precision once their coordinates\n// reach a float32 pipeline — the canvas, PDF and SVG viewers — which at that\n// magnitude can only step in metres. `rebaseSink` subtracts a nearby origin\n// in float64 BEFORE anything reaches the sink, so the sink only ever sees\n// small numbers (\"relative to eye\", as CAD/GIS viewers do). The data stays\n// absolute; only what is drawn is shifted.\n//\n// The shift applies at the TOP level only: a pushed transform (a reference's\n// placement, a viewport's projection) maps its own space into the shifted\n// one by having the shift folded into its translation, and coordinates\n// inside it pass through untouched.\n\nimport type { Vec2 } from \"../geometry/vec2\";\nimport type { GeometrySink, Mat2x3 } from \"./sink\";\n\nexport const rebaseSink = (sink: GeometrySink, origin: Vec2): GeometrySink => {\n if (origin.x === 0 && origin.y === 0) return sink;\n let depth = 0;\n const at = (p: Vec2): Vec2 =>\n depth === 0 ? { x: p.x - origin.x, y: p.y - origin.y } : p;\n return {\n beginPath: () => sink.beginPath(),\n moveTo: (p) => sink.moveTo(at(p)),\n lineTo: (p) => sink.lineTo(at(p)),\n bezierTo: (c1, c2, end) => sink.bezierTo(at(c1), at(c2), at(end)),\n arc: (center, r, a0, a1, ccw) => sink.arc(at(center), r, a0, a1, ccw),\n ellipse: (center, rx, ry, rot, a0, a1) =>\n sink.ellipse(at(center), rx, ry, rot, a0, a1),\n closePath: () => sink.closePath(),\n stroke: (s) => sink.stroke(s),\n fill: (f) =>\n sink.fill(\n f.gradient\n ? {\n ...f,\n gradient: {\n ...f.gradient,\n from: at(f.gradient.from),\n to: at(f.gradient.to),\n },\n }\n : f,\n ),\n text: (t) => sink.text({ ...t, anchor: at(t.anchor) }),\n image: (i) => sink.image({ ...i, origin: at(i.origin) }),\n measureText: (text, h, font, wf) => sink.measureText(text, h, font, wf),\n pushTransform: (m: Mat2x3) => {\n sink.pushTransform(\n depth === 0\n ? [m[0], m[1], m[2], m[3], m[4] - origin.x, m[5] - origin.y]\n : m,\n );\n depth++;\n },\n popTransform: () => {\n depth = Math.max(0, depth - 1);\n sink.popTransform();\n },\n pushClipRect: (r) => {\n const p = at({ x: r.x, y: r.y });\n sink.pushClipRect({ ...r, x: p.x, y: p.y });\n },\n popClip: () => sink.popClip(),\n beginObject: sink.beginObject\n ? (id, layer) => sink.beginObject!(id, layer)\n : undefined,\n endObject: sink.endObject ? () => sink.endObject!() : undefined,\n };\n};\n","// A reference paints its file's content (resolved by the host — see\n// PaintEnv.resolveReference) through the reference's placement, each object\n// styled by the FILE's layers; a file that isn't loaded (missing, loading)\n// paints a dashed frame of its last known extent with its name.\n\nimport type { ModelObject, ReferenceObject } from \"../../model/objects\";\nimport { placedCorners, referenceTransform } from \"../../reference/reference\";\nimport { resolveStyle } from \"../style\";\nimport { matMultiply, type GeometrySink } from \"../sink\";\nimport { rebaseSink } from \"../rebaseSink\";\nimport { isEmptyBounds } from \"../../geometry/bounds\";\nimport { paintObject, type PaintEnv } from \"./index\";\n\nexport const paintReference = (\n obj: ReferenceObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n if (obj.hidden) return;\n const content = env.resolveReference?.(obj) ?? null;\n const m = referenceTransform(obj);\n if (!content) {\n paintReferenceFrame(obj, sink, env);\n return;\n }\n const hidden = new Set(obj.hiddenLayers);\n const shown = new Map(\n content.layers.map((l) => [l.id, l.visible && !hidden.has(l.name)]),\n );\n const mapColor = env.mapColor ?? ((c: string) => c);\n const fade = env.style.opacity ?? 1;\n // Draw the content relative to its own centre: a survey-grid file placed\n // back near the origin would otherwise hand the sink its ~10¹⁰-mm file\n // coordinates and a ~−10¹⁰ placement, cancelled in float32 (distortion).\n // The shift is folded into the placement here, in float64 (rebaseSink).\n const b = content.bounds;\n const c = isEmptyBounds(b)\n ? { x: 0, y: 0 }\n : { x: (b.minX + b.maxX) / 2, y: (b.minY + b.maxY) / 2 };\n sink.pushTransform(matMultiply(m, [1, 0, 0, 1, c.x, c.y]));\n const out = rebaseSink(sink, c);\n const clip = obj.clip;\n if (clip)\n out.pushClipRect({\n x: clip.minX,\n y: clip.minY,\n w: clip.maxX - clip.minX,\n h: clip.maxY - clip.minY,\n });\n for (const child of content.objects) {\n if (shown.get(child.layerId) === false) continue;\n const own = resolveStyle(child as ModelObject, content.layers);\n paintObject(child, out, {\n // A highlight paints the whole reference in one style.\n style: env.forceStyle\n ? env.style\n : {\n ...own,\n color: mapColor(own.color),\n opacity: (own.opacity ?? 1) * fade,\n },\n forceStyle: env.forceStyle,\n dimStyles: content.dimStyles,\n textStyles: content.textStyles,\n blockDefinitions: content.blockDefinitions,\n resolveObject: content.resolveObject,\n assets: content.assets,\n cache: env.cache,\n mapColor: env.mapColor,\n // Nested references resolve through the FILE's own resolver (the\n // host loads them relative to that file, depth-limited, cycle-safe).\n resolveReference: content.resolveReference,\n });\n }\n if (clip) sink.popClip();\n sink.popTransform();\n};\n\n/** Not loaded: a dashed frame over the last known extent (or a small square\n * at the insertion point) and the reference's name. */\nconst paintReferenceFrame = (\n obj: ReferenceObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n const s = 5;\n const corners = obj.extent\n ? placedCorners(referenceTransform(obj), obj.extent)\n : [\n { x: obj.position.x, y: obj.position.y },\n { x: obj.position.x + s, y: obj.position.y },\n { x: obj.position.x + s, y: obj.position.y + s },\n { x: obj.position.x, y: obj.position.y + s },\n ];\n sink.beginPath();\n sink.moveTo(corners[0]);\n for (const c of corners.slice(1)) sink.lineTo(c);\n sink.closePath();\n sink.stroke({\n color: env.style.color,\n widthMm: env.style.widthMm,\n dashMm: [1.5, 1],\n opacity: env.style.opacity,\n });\n sink.text({\n text: obj.name,\n anchor: corners[0],\n heightMm: 2.5,\n rotation: obj.rotation,\n hAlign: \"left\",\n vAlign: \"bottom\",\n color: env.style.color,\n opacity: env.style.opacity,\n });\n};\n","import type {\n DimStyle,\n ModelObject,\n ModelObjectType,\n ReferenceObject,\n TextStyle,\n} from \"../../model/objects\";\nimport type { ReferenceContent } from \"../../reference/reference\";\nimport type { GeometrySink } from \"../sink\";\nimport type { ResolvedStyle } from \"../style\";\nimport type { PaintGeometryCache } from \"../paintCache\";\nimport { paintLine } from \"./line\";\nimport { paintPoint } from \"./point\";\nimport { paintPolyline } from \"./polyline\";\nimport { paintCircle } from \"./circle\";\nimport { paintArc } from \"./arc\";\nimport { paintEllipse } from \"./ellipse\";\nimport { paintHatch } from \"./hatch\";\nimport { paintText } from \"./text\";\nimport { paintDimension } from \"./dimension\";\nimport { paintBlockInstance } from \"./block\";\nimport { paintViewport } from \"./viewport\";\nimport { paintImage } from \"./image\";\nimport { paintTable } from \"./table\";\nimport { paintReference } from \"./reference\";\n\n/** Environment passed to painters — style already resolved by the caller. */\nexport interface PaintEnv {\n style: ResolvedStyle;\n /** Document dimension styles — dimensions pick theirs by styleId. */\n dimStyles: readonly DimStyle[];\n /** Document text styles — texts pick theirs by styleId. */\n textStyles: readonly TextStyle[];\n /**\n * The document's block definitions — the block painter evaluates instance\n * children against these. The kernel holds no store, so they are threaded\n * through the paint environment (mirrors buildEntry's SnapGeometryContext).\n */\n blockDefinitions: readonly string[];\n /**\n * Document-wide object lookup for block object-reference inputs (see\n * BlockObjectResolver). Optional: without it, referenced inputs evaluate\n * as null (consumers that cannot reach a document, e.g. style previews).\n */\n resolveObject?: (id: string) => ModelObject | undefined;\n /**\n * The document's embedded assets (hash → data URL) — the image painter\n * resolves `assetId` against these. Optional: consumers that can't show\n * images (or documents without any) paint a crossed placeholder frame.\n */\n assets?: Readonly<Record<string, string>>;\n /**\n * Optional cache for camera-independent derived geometry (hatch lines,\n * dimension geometry, text blocks). Supply one per long-lived consumer\n * (the canvas renderer keeps one across frames); omit for one-shot paints.\n */\n cache?: PaintGeometryCache;\n /**\n * Paint everything in `style` verbatim, ignoring per-child style overrides\n * (block children carrying their own color/lineType). Selection/hover\n * highlights set this so a block highlights as one uniform silhouette.\n */\n forceStyle?: boolean;\n /**\n * A reference's loaded file content (docs/references.md) — the host owns\n * loading and caching. Absent, or null for a file not loaded (yet), → the\n * reference paints as a dashed frame.\n */\n resolveReference?: (ref: ReferenceObject) => ReferenceContent | null;\n /** The output medium's color map (print palettes): content painted with\n * its OWN styles (a reference's file) maps through it too. */\n mapColor?: (color: string) => string;\n}\n\nexport type Painter = (\n obj: ModelObject,\n sink: GeometrySink,\n env: PaintEnv,\n) => void;\n\nconst painters: Record<ModelObjectType, Painter> = {\n line: paintLine as Painter,\n point: paintPoint as Painter,\n polyline: paintPolyline as Painter,\n circle: paintCircle as Painter,\n arc: paintArc as Painter,\n ellipse: paintEllipse as Painter,\n hatch: paintHatch as Painter,\n text: paintText as Painter,\n dimension: paintDimension as Painter,\n block: paintBlockInstance as Painter,\n viewport: paintViewport as Painter,\n image: paintImage as Painter,\n table: paintTable as Painter,\n reference: paintReference as Painter,\n // Screen-fixed editor chrome — painted by the editor's canvas renderer\n // only, never by the shared path (exports don't show it).\n comment: () => {},\n};\n\nexport const paintObject = (\n obj: ModelObject,\n sink: GeometrySink,\n env: PaintEnv,\n): void => {\n painters[obj.type]?.(obj, sink, env);\n};\n","// Headless SVG thumbnail of a block module — the same dry-run render the\n// editor's BlockPreview shows, emitted as a self-contained <svg> for\n// marketplace manifests (`lineadraw manifest` bakes it into thumbnailSvg;\n// the palette/browser display it without running any module code).\n// Deterministic by construction: stand-in picks are fixed, text measures\n// via the approximate table, and the SvgSink rounds coordinates — so\n// manifest generation stays a byte-stable operation.\n\nimport type { Block } from \"../model/objects\";\nimport { DEFAULT_DIM_STYLE, DEFAULT_TEXT_STYLE } from \"../model/objects\";\nimport { isEmptyBounds } from \"../geometry/bounds\";\nimport { SvgSink } from \"../export/svg/svgSink\";\nimport { approximateTextMeasurer } from \"../paint/textMeasurer\";\nimport { paintObject } from \"../paint/painters\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport {\n blockScriptId,\n dryRunBlockInputs,\n dryRunObjectResolver,\n ensureScriptTranspiler,\n getBlockError,\n getBlockMeta,\n} from \"./evalBlock\";\n\nexport interface BlockThumbnailOptions {\n /** Extra module sources nested instances resolve against (the repo's or\n * catalog's other blocks); ids the module itself provides win. */\n definitions?: readonly string[];\n /** Skip (return null) when the SVG exceeds this many characters — a\n * manifest should stay a light index, not an asset bundle. */\n maxChars?: number;\n}\n\n/**\n * Render a block module to a small standalone SVG (viewBox-sized, strokes\n * in `currentColor` so the host UI's theme colors it). Returns null for\n * blocks with nothing visible to draw or oversized output; throws when the\n * module itself fails its dry run (same errors testBlockDefinition\n * reports).\n */\nexport const renderBlockThumbnailSvg = async (\n script: string,\n { definitions = [], maxChars = 20_000 }: BlockThumbnailOptions = {},\n): Promise<string | null> => {\n await ensureScriptTranspiler();\n const defId = getBlockMeta(script).id;\n const inputs = await dryRunBlockInputs(script);\n\n // The module shadows any same-id definition; extras fill remaining ids.\n const defs = [script];\n const present = new Set([defId]);\n for (const extra of definitions) {\n const id = blockScriptId(extra);\n if (id === undefined || present.has(id)) continue;\n present.add(id);\n defs.push(extra);\n }\n\n const instance: Block = {\n type: \"block\",\n id: `thumbnail:${defId}`,\n layerId: \"thumbnail\",\n definitionId: defId,\n rotation: 0,\n scale: 1,\n params: {},\n inputs,\n };\n const env = {\n dimStyles: [DEFAULT_DIM_STYLE],\n textStyles: [DEFAULT_TEXT_STYLE],\n blockDefinitions: defs,\n // Object-reference inputs preview against the dry-run stand-in object.\n resolveObject: dryRunObjectResolver,\n };\n const entry = buildSnapEntry(instance, {\n ...env,\n measure: approximateTextMeasurer,\n });\n const error = getBlockError(instance.id);\n if (error !== undefined && error !== null) throw new Error(error);\n // A no-geometry block collapses to a point at the pivot (buildSnapEntry\n // still yields degenerate 0×0 bounds there) — nothing worth a thumbnail.\n const bw = entry.bounds.maxX - entry.bounds.minX;\n const bh = entry.bounds.maxY - entry.bounds.minY;\n if (isEmptyBounds(entry.bounds) || (bw === 0 && bh === 0)) return null;\n\n const sink = new SvgSink({ measure: approximateTextMeasurer });\n paintObject(instance, sink, {\n ...env,\n // currentColor: the thumbnail inherits the surrounding UI text color,\n // so one render works in light and dark hosts alike. Children with\n // authored colors keep them. Stroke width scales with the extent —\n // thumbnails display at ~icon size, where a fixed mm width would turn\n // a meters-wide block into invisible hairlines.\n style: { color: \"currentColor\", widthMm: Math.max(bw, bh) / 56 },\n });\n const pad = Math.max(((bw + bh) / 2) * 0.06, 1);\n const svg = sink.toSvg(entry.bounds, pad);\n return svg.length > maxChars ? null : svg;\n};\n","// Block-library merging over raw module sources. A \"library file\" is just a\n// `.ts`/`.js` module (one module = one block); moving blocks between\n// documents is moving text. PURE — the browser download, file pickers,\n// toasts, and the store merge stay editor-side; this module owns the\n// collision invariants:\n// · a source already present verbatim is skipped\n// · an id match with DIFFERENT content REPLACES that module in place —\n// the id IS the block's identity, so importing it again is an update\n// (instances keep their definitionId and re-evaluate with the new source)\n// · a name clash with a DIFFERENT block is suffixed \"(imported)\" via a\n// literal rewrite of `export const name` (best-effort — an unrewritable\n// name is left alone)\n// · a module that does not compile/validate is rejected with its error\n// Callers must await `ensureScriptTranspiler()` first — merging compiles.\n\nimport { blockScriptId, getBlockMetaResult, type BlockMeta } from \"./evalBlock\";\n\n/**\n * Replace the string literal of `export const <name> = \"…\"` — or, for a\n * defineBlock module, the `<name>: \"…\"` property at the TOP level of the\n * spec object (nested occurrences like a params entry's `name:` are never\n * touched). Null when neither form has a rewritable literal\n * (dynamic/computed) — callers must treat that as \"don't touch\", never\n * mangle. Also used by the editor's Duplicate.\n */\nexport const rewriteExportString = (\n script: string,\n exportName: string,\n value: string,\n): string | null => {\n const re = new RegExp(\n `(export\\\\s+const\\\\s+${exportName}\\\\s*=\\\\s*)(\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"|'(?:[^'\\\\\\\\]|\\\\\\\\.)*')`,\n );\n if (re.test(script)) return script.replace(re, `$1${JSON.stringify(value)}`);\n return rewriteSpecProperty(script, exportName, value);\n};\n\n/**\n * Rewrite `<prop>: \"…\"` at brace depth 1 of the `defineBlock({...})` /\n * `defineCommand({...})` (or plain default-exported object) spec. A small\n * scanner rather than a bare regex: strings, template literals, and comments\n * are skipped wholesale, and depth tracking keeps nested literals (params\n * entries also have a `name:`) out of reach. Best-effort — anything\n * unrecognized returns null.\n */\nconst rewriteSpecProperty = (\n script: string,\n prop: string,\n value: string,\n): string | null => {\n const call = script.search(\n /define(?:Block|Command)\\s*\\(|export\\s+default\\s*\\{/,\n );\n if (call === -1) return null;\n const open = script.indexOf(\"{\", call);\n if (open === -1) return null;\n const propRe = new RegExp(\n `^${prop}\\\\s*:\\\\s*(\"(?:[^\"\\\\\\\\]|\\\\\\\\.)*\"|'(?:[^'\\\\\\\\]|\\\\\\\\.)*')`,\n );\n let depth = 0;\n for (let i = open; i < script.length; i++) {\n const ch = script[i];\n if (ch === '\"' || ch === \"'\" || ch === \"`\") {\n i++;\n while (i < script.length && script[i] !== ch) {\n if (script[i] === \"\\\\\") i++;\n i++;\n }\n continue;\n }\n if (ch === \"/\" && script[i + 1] === \"/\") {\n while (i < script.length && script[i] !== \"\\n\") i++;\n continue;\n }\n if (ch === \"/\" && script[i + 1] === \"*\") {\n i += 2;\n while (i < script.length && !(script[i] === \"*\" && script[i + 1] === \"/\"))\n i++;\n i++;\n continue;\n }\n if (ch === \"{\" || ch === \"(\" || ch === \"[\") {\n depth++;\n continue;\n }\n if (ch === \"}\" || ch === \")\" || ch === \"]\") {\n depth--;\n if (depth === 0) return null; // spec object ended without the prop\n continue;\n }\n if (depth !== 1 || !/[A-Za-z_$]/.test(ch)) continue;\n const prev = i > 0 ? script[i - 1] : \"\";\n const m = /[A-Za-z0-9_$.]/.test(prev) ? null : propRe.exec(script.slice(i));\n if (m) {\n const start = i + m[0].length - m[1].length;\n return (\n script.slice(0, start) +\n JSON.stringify(value) +\n script.slice(start + m[1].length)\n );\n }\n // Skip the rest of this identifier so mid-word positions aren't tested.\n while (i + 1 < script.length && /[A-Za-z0-9_$]/.test(script[i + 1])) i++;\n }\n return null;\n};\n\nexport interface MergeModulesResult<M> {\n /** The full library to install (replacements in place + new appended). */\n merged: string[];\n /** Modules added as new entries (possibly renamed), with their meta. */\n added: { script: string; meta: M }[];\n /** Modules that replaced an existing entry with the same exported id. */\n replaced: { script: string; meta: M }[];\n /** How many incoming modules were already present verbatim. */\n skipped: number;\n /** Modules that could not be imported, with the reason. */\n rejected: { script: string; error: string }[];\n}\n\nexport type MergeBlockModulesResult = MergeModulesResult<BlockMeta>;\n\n/** How a module family (blocks, commands) derives identity from a source. */\nexport interface ScriptModuleAccess<M extends { id: string; name: string }> {\n /** Best-effort exported id (compiled meta or a source-level scan). */\n idOf(script: string): string | undefined;\n /** Non-throwing compile + meta validation. */\n metaOf(script: string): { ok: true; meta: M } | { ok: false; error: string };\n}\n\n/**\n * Merge incoming module sources into an existing library — the shared\n * engine under block AND command import (same collision invariants for\n * both; see the header comment).\n */\nexport const mergeScriptModules = <M extends { id: string; name: string }>(\n existing: readonly string[],\n incoming: readonly string[],\n access: ScriptModuleAccess<M>,\n): MergeModulesResult<M> => {\n const merged = [...existing];\n const indexById = new Map<string, number>();\n merged.forEach((s, i) => {\n const id = access.idOf(s);\n if (id !== undefined && !indexById.has(id)) indexById.set(id, i);\n });\n // Parallel name list (undefined = module does not compile).\n const names: (string | undefined)[] = merged.map((s) => {\n const r = access.metaOf(s);\n return r.ok ? r.meta.name : undefined;\n });\n const nameTaken = (name: string, except: number | undefined): boolean =>\n names.some((n, i) => n === name && i !== except);\n\n const added: MergeModulesResult<M>[\"added\"] = [];\n const replaced: MergeModulesResult<M>[\"replaced\"] = [];\n const rejected: MergeModulesResult<M>[\"rejected\"] = [];\n let skipped = 0;\n\n for (const original of incoming) {\n if (merged.includes(original)) {\n skipped++; // identical module already present\n continue;\n }\n let script = original;\n let result = access.metaOf(script);\n if (!result.ok) {\n rejected.push({ script: original, error: result.error });\n continue;\n }\n\n // Same exported id → the incoming module replaces that entry (its slot's\n // own name is not a clash, so a same-name update keeps its name).\n const replaceIdx = indexById.get(result.meta.id);\n\n // Name collision with a different block → suffix (best-effort rewrite).\n if (nameTaken(result.meta.name, replaceIdx)) {\n let name = result.meta.name;\n while (nameTaken(name, replaceIdx)) name = `${name} (imported)`;\n const renamed = rewriteExportString(script, \"name\", name);\n if (renamed !== null) script = renamed;\n }\n\n if (script !== original) {\n result = access.metaOf(script);\n if (!result.ok) {\n // A rewrite broke the module — should not happen; keep the original\n // out rather than installing something unparseable.\n rejected.push({ script: original, error: result.error });\n continue;\n }\n }\n\n if (replaceIdx !== undefined) {\n merged[replaceIdx] = script;\n names[replaceIdx] = result.meta.name;\n replaced.push({ script, meta: result.meta });\n } else {\n indexById.set(result.meta.id, merged.length);\n names.push(result.meta.name);\n merged.push(script);\n added.push({ script, meta: result.meta });\n }\n }\n\n return { merged, added, replaced, skipped, rejected };\n};\n\n/** Merge incoming block module sources into an existing library. */\nexport const mergeBlockModules = (\n existing: readonly string[],\n incoming: readonly string[],\n): MergeBlockModulesResult =>\n mergeScriptModules(existing, incoming, {\n idOf: blockScriptId,\n metaOf: getBlockMetaResult,\n });\n","// User commands (macro scripts) as ES modules — the command-side sibling of\n// evalBlock. The document's `commands` array and the editor's per-device\n// library both hold raw module sources; one module = one command, authored\n// as `export default defineCommand({...})` (defineCommand is a runtime\n// identity resolved by the shared require shim). Everything the app knows\n// about a command derives from the compiled module:\n// id → identity (palette entries, hotkey overrides, import merge)\n// name → palette/list label\n// description / version / authors / tags → optional metadata\n// run(ctx) → the macro body. The HOST supplies ctx (document API,\n// pickers, selection, prompt, toast — typed as\n// CommandContext in lineadraw.d.ts) and wraps the whole call\n// in one undo transaction. `run` is interactive, so there is\n// no dry run — save-time validation is compile + meta.\n// Shares the lazy transpiler with blocks: callers that cannot tolerate the\n// transient \"Compiling…\" error await `ensureScriptTranspiler()` first.\n\nimport { z } from \"zod\";\nimport {\n executeScriptModule,\n parseParamsExport,\n scriptTranspilerReady,\n} from \"./evalBlock\";\nimport type { BlockParameter } from \"../model/blockDefinition\";\nimport { mergeScriptModules, type MergeModulesResult } from \"./scriptModules\";\n\n/** Identity + metadata derived from a command module's exports. */\nexport interface CommandMeta {\n id: string;\n name: string;\n description?: string;\n version?: string;\n authors?: string[];\n tags?: string[];\n /** Declared point inputs (labels): picked one by one in the editor before\n * `run`, or supplied up front by a headless/remote caller. */\n inputs?: string[];\n /** Declared parameters (the blocks' ParamDef table): prompted in the\n * editor before `run`, or passed by a headless caller; arrive as\n * `ctx.params`. Absent when the command declares none. */\n params?: BlockParameter[];\n}\n\n/** The compiled `run` — its ctx is host-supplied (CommandContext). */\nexport type CommandRunFn = (ctx: unknown) => unknown;\n\ninterface CompiledCommand {\n meta: CommandMeta;\n run: CommandRunFn;\n}\n\nconst OptionalMetaSchema = z.object({\n description: z.string().optional(),\n version: z.string().optional(),\n authors: z.array(z.string()).optional(),\n tags: z.array(z.string()).optional(),\n inputs: z.array(z.string().min(1)).optional(),\n});\n\n/** Validate a module's identity/metadata exports with author-facing errors. */\nconst extractCommandMeta = (mod: Record<string, unknown>): CommandMeta => {\n if (typeof mod.id !== \"string\" || mod.id.trim() === \"\")\n throw new Error(\"Command script must export a non-empty string `id`\");\n if (typeof mod.name !== \"string\" || mod.name.trim() === \"\")\n throw new Error(\"Command script must export a non-empty string `name`\");\n const parsed = OptionalMetaSchema.safeParse(mod);\n if (!parsed.success) {\n const issue = parsed.error.issues[0];\n throw new Error(\n `Invalid command metadata${\n issue ? ` — ${issue.path.join(\".\")}: ${issue.message}` : \"\"\n }`,\n );\n }\n const params = parseParamsExport(mod.params);\n return {\n id: mod.id,\n name: mod.name,\n ...parsed.data,\n ...(params.length > 0 ? { params } : {}),\n };\n};\n\n/** Compile cache keyed by the raw source (same rationale as evalBlock's). */\nconst compileCache = new Map<string, CompiledCommand>();\nconst COMPILE_CACHE_MAX = 100;\n\nconst compileCommand = (script: string): CompiledCommand => {\n const cached = compileCache.get(script);\n if (cached) {\n // Refresh recency so live-edited drafts don't evict installed commands.\n compileCache.delete(script);\n compileCache.set(script, cached);\n return cached;\n }\n const mod = executeScriptModule(script);\n const meta = extractCommandMeta(mod);\n const run = mod.run;\n if (typeof run !== \"function\")\n throw new Error(\"Command script must export a `run` function\");\n if (compileCache.size >= COMPILE_CACHE_MAX) {\n const oldest = compileCache.keys().next().value;\n if (oldest !== undefined) compileCache.delete(oldest);\n }\n const compiled = { meta, run: run as CommandRunFn };\n compileCache.set(script, compiled);\n return compiled;\n};\n\n/** Non-throwing meta lookup for list UIs. */\nexport type CommandMetaResult =\n | { ok: true; meta: CommandMeta }\n | {\n ok: false;\n error: string;\n /** True while the transient transpiler load is the only problem. */\n loading: boolean;\n };\n\nexport const getCommandMetaResult = (script: string): CommandMetaResult => {\n try {\n return { ok: true, meta: compileCommand(script).meta };\n } catch (e) {\n return {\n ok: false,\n error: e instanceof Error ? e.message : String(e),\n loading: !scriptTranspilerReady(),\n };\n }\n};\n\n/** Meta for each script in a library (invalid entries report their error). */\nexport const listCommandMeta = (\n scripts: readonly string[],\n): CommandMetaResult[] => scripts.map(getCommandMetaResult);\n\n/**\n * The compiled `run` function. Sync; throws the transient\n * \"Compiling script…\" until the lazy transpiler is loaded, and a\n * descriptive error for invalid modules.\n */\nexport const getCommandRun = (script: string): CommandRunFn =>\n compileCommand(script).run;\n\n/** Source-level `export const id = \"…\"` matcher (broken-module fallback). */\nconst ID_EXPORT_RE = /export\\s+const\\s+id\\s*=\\s*[\"']([^\"']+)[\"']/;\n\n/**\n * A module's exported id without requiring it to be valid: compiled meta\n * when possible, a source-level scan (the named-export form, or the first\n * `id: \"…\"` after the spec opener) otherwise — so merge/replace semantics\n * survive a module that no longer compiles (or the transpiler still loading).\n */\nexport const commandScriptId = (script: string): string | undefined => {\n try {\n return compileCommand(script).meta.id;\n } catch {\n const named = ID_EXPORT_RE.exec(script);\n if (named) return named[1];\n const call = script.search(/defineCommand\\s*\\(|export\\s+default\\s*\\{/);\n if (call === -1) return undefined;\n return /\\bid\\s*:\\s*[\"']([^\"']+)[\"']/.exec(script.slice(call))?.[1];\n }\n};\n\nexport type MergeCommandModulesResult = MergeModulesResult<CommandMeta>;\n\n/** Merge incoming command module sources into an existing library (same\n * invariants as blocks: verbatim → skip, id match → replace in place, name\n * clash → suffix). Await `ensureScriptTranspiler()` first — merging compiles. */\nexport const mergeCommandModules = (\n existing: readonly string[],\n incoming: readonly string[],\n): MergeCommandModulesResult =>\n mergeScriptModules(existing, incoming, {\n idOf: commandScriptId,\n metaOf: getCommandMetaResult,\n });\n","// PDF font-coverage checks. The PDF export has two ways to lose characters:\n// a font that renders as base-14 Helvetica (an \"embed\" font whose TTF the\n// host didn't register) encodes WinAnsi only, so Cyrillic becomes mojibake;\n// and an embedded TTF simply missing the glyphs (the handwriting fonts have\n// no Cyrillic) renders tofu. The PdfSink uses these checks to substitute\n// PDF_FALLBACK_FONT per string — on screen the CSS font stacks already fall\n// back natively.\n\nimport {\n ADVANCE_TABLES,\n EXTRACTED_EXTRAS,\n EXTRACTED_RANGES,\n} from \"./advanceTables\";\nimport { resolveFont, type FontId } from \"../model/fonts\";\n\n/** Substitute for text the chosen font cannot render in PDF: the default\n * font — embedded as Liberation Sans with full Cyrillic (model/fonts.ts). */\nexport const PDF_FALLBACK_FONT: FontId = \"arial\";\n\n/** WinAnsi's printable extras above U+00FF — base-14 fonts CAN encode\n * these (curly quotes, dashes, €, …), so they must not trigger fallback. */\nconst WINANSI_EXTRA = new Set(\"€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ\");\n\n/** Can base-14 Helvetica (WinAnsi) encode this text? */\nexport const winAnsiEncodable = (text: string): boolean => {\n for (const ch of text) {\n const code = ch.codePointAt(0)!;\n if (code > 0xff && !WINANSI_EXTRA.has(ch)) return false;\n }\n return true;\n};\n\nconst extracted = (ch: string, code: number): boolean =>\n EXTRACTED_RANGES.some(([a, b]) => code >= a && code <= b) ||\n EXTRACTED_EXTRAS.includes(ch);\n\n/**\n * Can this font's EMBEDDED program render `text`? Checked against the\n * extracted advance tables — a character inside the extracted ranges but\n * absent from the font's table is a REAL coverage gap. Characters outside\n * the extracted ranges are unknown and get the benefit of the doubt (the\n * chosen font is kept). Callers must use `winAnsiEncodable` instead when\n * the font actually renders as base-14 (its TTF was not registered).\n */\nexport const pdfFontCovers = (\n font: string | undefined,\n text: string,\n): boolean => {\n const def = resolveFont(font);\n if (def.pdf !== \"embed\") return winAnsiEncodable(text);\n const table = ADVANCE_TABLES[def.id];\n for (const ch of text) {\n const code = ch.codePointAt(0)!;\n if (code > 0x7e && extracted(ch, code) && table.advances[ch] === undefined)\n return false;\n }\n return true;\n};\n","// Paint a paper layout's CONTENT (viewports into model space + sheet\n// annotations) through any GeometrySink. Shared verbatim by the canvas\n// paper-space renderer and the PDF exporter — what you see is what prints.\n\nimport type { PaperLayout } from \"../model/paperLayout\";\nimport type {\n DimStyle,\n ModelObject,\n TextStyle,\n Viewport,\n} from \"../model/objects\";\nimport type { Layer } from \"../model/document\";\nimport { buildSnapEntry } from \"../snap/buildEntry\";\nimport { boundsIntersect, isEmptyBounds, type AABB } from \"../geometry/bounds\";\nimport type { GeometrySink, Mat2x3 } from \"./sink\";\nimport type { TextMeasurer } from \"./textMetrics\";\nimport { paintObject, type PaintEnv } from \"./painters\";\nimport { rebaseSink } from \"./rebaseSink\";\nimport type { PaintGeometryCache } from \"./paintCache\";\nimport { resolveStyle } from \"./style\";\n\nexport interface LayoutPaintOptions {\n /** Map object colors for the output medium (e.g. light→black for print). */\n mapColor?: (color: string) => string;\n /**\n * Viewport-culling bounds for a model object. Defaults to\n * `buildSnapEntry(obj).bounds`; the editor passes its cached snap-entry\n * bounds instead (avoiding a per-frame recompute). Return `null` to skip\n * culling for that object.\n */\n boundsOf?: (obj: ModelObject) => AABB | null;\n /** Derived-geometry cache forwarded to the painters (see PaintEnv.cache). */\n cache?: PaintGeometryCache;\n}\n\n/**\n * The slice of document state layout painting reads. The kernel holds no\n * store, so it is passed in (the editor sources it from useModel; a headless\n * caller from the loaded document).\n */\nexport interface LayoutModelContext {\n objects: ModelObject[];\n layers: Layer[];\n dimStyles: readonly DimStyle[];\n textStyles: readonly TextStyle[];\n blockDefinitions: readonly string[];\n /**\n * Document-wide object lookup for block object-reference inputs; absent →\n * referenced inputs evaluate as null (see BlockObjectResolver).\n */\n resolveObject?: (id: string) => ModelObject | undefined;\n /** Embedded image assets (hash → data URL); absent = placeholder frames. */\n assets?: Readonly<Record<string, string>>;\n /** Loaded reference content (see PaintEnv.resolveReference). */\n resolveReference?: PaintEnv[\"resolveReference\"];\n}\n\n/** The viewport objects of a layout (in draw order). */\nexport const layoutViewports = (layout: PaperLayout): Viewport[] =>\n layout.objects.filter((o): o is Viewport => o.type === \"viewport\");\n\n/** Paper mm per model mm (`scale` stores the 1:N denominator). */\nconst viewportPaperPerModel = (vp: Viewport): number => 1 / vp.scale;\n\n/** Model-space window visible through a viewport. */\nexport const viewportWorldBounds = (vp: Viewport): AABB => {\n const halfW = (vp.rect.w / 2) * vp.scale;\n const halfH = (vp.rect.h / 2) * vp.scale;\n return {\n minX: vp.modelCenter.x - halfW,\n minY: vp.modelCenter.y - halfH,\n maxX: vp.modelCenter.x + halfW,\n maxY: vp.modelCenter.y + halfH,\n };\n};\n\n/** Sheet ← model transform of a viewport, for coordinates RELATIVE TO its\n * model centre (paint through `rebaseSink(sink, vp.modelCenter)`): a\n * survey-grid model (~10¹⁰ mm) would otherwise reach the canvas/PDF as huge\n * numbers and lose its precision there. */\nconst viewportTransform = (vp: Viewport): Mat2x3 => {\n const k = viewportPaperPerModel(vp);\n return [k, 0, 0, k, vp.rect.x + vp.rect.w / 2, vp.rect.y + vp.rect.h / 2];\n};\n\nconst resolveBoundsOf = (\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions,\n): ((obj: ModelObject) => AABB | null) => {\n if (opts.boundsOf) return opts.boundsOf;\n // Bounds culling reuses the pure snap-entry geometry; text/dimension bounds\n // need measurement, taken from the sink (no DOM).\n const measure: TextMeasurer = {\n measureTextWidth: (t, h) => sink.measureText(t, h).width,\n };\n return (obj) =>\n buildSnapEntry(obj, {\n dimStyles: model.dimStyles,\n textStyles: model.textStyles,\n blockDefinitions: model.blockDefinitions,\n resolveObject: model.resolveObject,\n resolveReference: model.resolveReference,\n measure,\n }).bounds;\n};\n\n/**\n * ONE viewport's clipped, transformed model projection. The sink must be in\n * sheet-mm coordinates (the same space `paintLayoutContent` paints in), so a\n * caller can also point it at an offscreen bitmap of just the rect.\n */\nexport const paintViewportContent = (\n vp: Viewport,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n const { objects, layers, dimStyles, textStyles, blockDefinitions } = model;\n const layerVisible = new Map(layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(layers.map((l) => [l.id, l.name]));\n const mapColor = opts.mapColor ?? ((c: string) => c);\n const boundsOf = resolveBoundsOf(sink, model, opts);\n\n sink.pushClipRect(vp.rect);\n sink.pushTransform(viewportTransform(vp));\n const content = rebaseSink(sink, vp.modelCenter);\n const visible = viewportWorldBounds(vp);\n const hiddenLayers = new Set(vp.hiddenLayerIds);\n\n for (const obj of objects) {\n if (layerVisible.get(obj.layerId) === false) continue;\n if (hiddenLayers.has(obj.layerId)) continue;\n const bounds = boundsOf(obj);\n if (bounds && !isEmptyBounds(bounds) && !boundsIntersect(bounds, visible))\n continue;\n const style = resolveStyle(obj, layers);\n sink.beginObject?.(obj.id, layerName.get(obj.layerId));\n paintObject(obj, content, {\n style: { ...style, color: mapColor(style.color) },\n dimStyles,\n textStyles,\n blockDefinitions,\n resolveObject: model.resolveObject,\n assets: model.assets,\n cache: opts.cache,\n resolveReference: model.resolveReference,\n mapColor,\n });\n sink.endObject?.();\n }\n\n sink.popTransform();\n sink.popClip();\n};\n\n/** Sheet-space annotations (drawn in sheet mm). Viewport frames are screen\n * chrome (drawn by the scene renderer), so they never reach print output. */\nexport const paintLayoutAnnotations = (\n layout: PaperLayout,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n const { layers, dimStyles, textStyles, blockDefinitions } = model;\n const layerVisible = new Map(layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(layers.map((l) => [l.id, l.name]));\n const mapColor = opts.mapColor ?? ((c: string) => c);\n for (const obj of layout.objects) {\n if (obj.type === \"viewport\") continue;\n if (layerVisible.get(obj.layerId) === false) continue;\n const style = resolveStyle(obj, layers);\n sink.beginObject?.(obj.id, layerName.get(obj.layerId));\n paintObject(obj, sink, {\n style: { ...style, color: mapColor(style.color) },\n dimStyles,\n textStyles,\n blockDefinitions,\n resolveObject: model.resolveObject,\n assets: model.assets,\n cache: opts.cache,\n resolveReference: model.resolveReference,\n mapColor,\n });\n sink.endObject?.();\n }\n};\n\nexport const paintLayoutContent = (\n layout: PaperLayout,\n sink: GeometrySink,\n model: LayoutModelContext,\n opts: LayoutPaintOptions = {},\n): void => {\n // Viewport content always renders under the sheet annotations, regardless\n // of array position.\n for (const vp of layoutViewports(layout)) {\n paintViewportContent(vp, sink, model, opts);\n }\n paintLayoutAnnotations(layout, sink, model, opts);\n};\n","// Per-layout print color mapping — what authored (dark-canvas) colors become\n// on white paper. Shared by the paper-space canvas renderer and the PDF\n// exporter, so the layout on screen always previews the printed output.\n\nimport type { PrintPalette } from \"../model/paperLayout\";\n\nconst parseHex = (hex: string): [number, number, number] | null => {\n const m = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);\n return m\n ? [parseInt(m[1], 16), parseInt(m[2], 16), parseInt(m[3], 16)]\n : null;\n};\n\nconst luminance = (r: number, g: number, b: number): number =>\n (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n\nconst grayHex = (level: number): string => {\n const v = Math.round(Math.min(Math.max(level, 0), 1) * 255)\n .toString(16)\n .padStart(2, \"0\");\n return `#${v}${v}${v}`;\n};\n\n/** Authored-color → print-color mapper for LayoutPaintOptions.mapColor. */\nexport const printColorMapper =\n (palette: PrintPalette): ((hex: string) => string) =>\n (hex) => {\n const rgb = parseHex(hex);\n if (!rgb) return hex;\n const [r, g, b] = rgb;\n const lum = luminance(r, g, b);\n switch (palette) {\n case \"color\": {\n // Only light NEUTRALS flip to black (white/light-gray lines would\n // vanish on paper); saturated colors — yellow, cyan — keep their hue.\n const saturation = (Math.max(r, g, b) - Math.min(r, g, b)) / 255;\n return lum > 0.75 && saturation < 0.25 ? \"#000000\" : hex;\n }\n case \"grayscale\":\n // Ink weight: colors authored bright on the dark canvas print dark.\n // Clamped so even dark-authored colors keep a visible gray.\n return grayHex(Math.min(1 - lum, 0.75));\n case \"monochrome\":\n return \"#000000\";\n }\n };\n","// DWG support is a byte-level transcode at the file boundary: DWG bytes ↔\n// DXF text via @lineadraw/dwg-wasm (acadrust compiled to WebAssembly, lazy-loaded\n// on first use — instantiation is cached inside the package's loader).\n// Callers compose these with dxfToModel / buildDxf; core's model stays\n// DXF-shaped and never sees acadrust's document.\n\nexport type DwgVersion =\n | \"AC1015\" // AutoCAD 2000\n | \"AC1018\" // AutoCAD 2004\n | \"AC1021\" // AutoCAD 2007\n | \"AC1024\" // AutoCAD 2010\n | \"AC1027\" // AutoCAD 2013\n | \"AC1032\"; // AutoCAD 2018\n\nconst loadDwg = () => import(\"@lineadraw/dwg-wasm\").then((m) => m.loadDwg());\n\n/** DWG bytes → ASCII DXF text (compose with dxfToModel). */\nexport const dwgToDxf = async (data: Uint8Array): Promise<string> => {\n const { dwg_to_dxf } = await loadDwg();\n return dwg_to_dxf(data);\n};\n\n/** DXF text (e.g. buildDxf output) → DWG bytes. Defaults to AC1027 when the\n * DXF carries no usable $ACADVER. */\nexport const dxfToDwg = async (\n dxf: string,\n version?: DwgVersion,\n): Promise<Uint8Array> => {\n const { dxf_to_dwg } = await loadDwg();\n // acadrust cannot parse xdata on STYLE table records — strip the typeface\n // triplets buildDxf injects for CAD font resolution (see exportDxf's\n // injectStyleTypefaces) before transcoding. DWG output keeps the plain\n // file-name reference; lifting this needs xdata support in acadrust.\n return dxf_to_dwg(\n dxf.replace(/\\n1001\\nACAD\\n1000\\n[^\\n]*\\n1071\\n0(?=\\n)/g, \"\"),\n version,\n );\n};\n","// Vector PDF export: one page per layout, rendered through the very same\n// paintLayoutContent (and per-layout print palette) as the on-screen paper\n// space, so what you see is what prints. Pure/headless — the editor wraps\n// this with the store read, file naming, and save/toast.\n\nimport { jsPDF } from \"jspdf\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\nimport type { LineaDocument } from \"../../model/document\";\nimport {\n dimFontFace,\n dimStyleFor,\n effectiveTextFont,\n type ModelObject,\n} from \"../../model/objects\";\nimport { FONTS, REAL_FACES, realFace, resolveFont } from \"../../model/fonts\";\nimport { PDF_FALLBACK_FONT, pdfFontCovers } from \"../../paint/fontCoverage\";\nimport {\n paintLayoutContent,\n type LayoutModelContext,\n} from \"../../paint/layoutPaint\";\nimport { printColorMapper } from \"../../paint/printPalette\";\nimport { PdfSink } from \"./pdfSink\";\nimport { tableLayout } from \"../../paint/tableLayout\";\n\n/** A TTF to embed, registered under its font id (see PaintEnv fonts). */\nexport interface PdfEmbedFont {\n /** Font id from model/fonts.ts — texts reference it via TextSpec.font —\n * or a bundled styled face (\"arial;b\", model/fonts.ts REAL_FACES). */\n id: string;\n /** TrueType (glyf) file as base64 — jsPDF cannot embed CFF/OTF. */\n ttfBase64: string;\n}\n\n/** Embeddable (pdf: \"embed\") font ids the document's text/dimensions\n * actually use — so exports only carry the TTFs they need. Block instances\n * are counted conservatively (their scripts may emit text in any font).\n * When a text's font cannot encode its content in PDF (arial + Cyrillic,\n * a handwriting font's missing glyphs), the sink substitutes\n * PDF_FALLBACK_FONT per string — so its TTF must ride along too. */\nexport const usedEmbedFontIds = (doc: LineaDocument): Set<string> => {\n const ids = new Set<string>();\n let hasBlocks = false;\n const add = (font: string | undefined, content: string) => {\n ids.add(resolveFont(font).id);\n // A bundled bold/italic face embeds as its own TTF.\n const face = realFace(font);\n if (face) ids.add(face);\n if (!pdfFontCovers(font, content)) ids.add(PDF_FALLBACK_FONT);\n };\n const visit = (o: ModelObject) => {\n if (o.type === \"text\")\n add(effectiveTextFont(o, doc.textStyles).font, o.content);\n else if (o.type === \"dimension\")\n add(\n dimFontFace({ ...dimStyleFor(o, doc.dimStyles), ...o.styleOverride }),\n // Computed measurement text is ASCII; only an override can need more.\n o.textOverride ?? \"\",\n );\n else if (o.type === \"table\") {\n // Every cell is a text child (same derivation the painter draws).\n for (const c of tableLayout(o, doc.textStyles).children) {\n if (c.type === \"text\")\n add(effectiveTextFont(c, doc.textStyles).font, c.content);\n }\n } else if (o.type === \"block\") hasBlocks = true;\n };\n doc.objects.forEach(visit);\n for (const layout of doc.layouts) layout.objects.forEach(visit);\n if (hasBlocks)\n for (const id of [...Object.keys(FONTS), ...REAL_FACES]) ids.add(id);\n for (const id of [...ids])\n if (resolveFont(id).pdf !== \"embed\") ids.delete(id);\n return ids;\n};\n\n/**\n * Strip objects on non-print layers (Layer.print === false — the AutoCAD\n * plot flag) from the model and the sheets. Viewports are kept regardless of\n * their layer: they are windows, and their frames never print anyway.\n */\nexport const stripNonPrintLayers = (\n layouts: PaperLayout[],\n model: LayoutModelContext,\n): { layouts: PaperLayout[]; model: LayoutModelContext } => {\n const noPrint = new Set(\n model.layers.filter((l) => l.print === false).map((l) => l.id),\n );\n if (noPrint.size === 0) return { layouts, model };\n return {\n model: {\n ...model,\n objects: model.objects.filter((o) => !noPrint.has(o.layerId)),\n },\n layouts: layouts.map((layout) => ({\n ...layout,\n objects: layout.objects.filter(\n (o) => o.type === \"viewport\" || !noPrint.has(o.layerId),\n ),\n })),\n };\n};\n\n/**\n * Render one or more paper layouts to a vector PDF (one page each).\n * `layouts` must be non-empty (the first sets the initial page size).\n * Fonts with pdf=\"embed\" render as Helvetica unless supplied in `fonts`.\n * Layers with `print: false` are excluded (screen-only layers).\n */\nexport const renderLayoutsToPdf = (\n printLayouts: PaperLayout[],\n printModel: LayoutModelContext,\n fonts: PdfEmbedFont[] = [],\n): jsPDF => {\n const { layouts, model } = stripNonPrintLayers(printLayouts, printModel);\n const first = layouts[0];\n const pdf = new jsPDF({\n unit: \"mm\",\n format: [first.sheet.width, first.sheet.height],\n orientation:\n first.sheet.width >= first.sheet.height ? \"landscape\" : \"portrait\",\n compress: true,\n });\n for (const font of fonts) {\n pdf.addFileToVFS(`${font.id}.ttf`, font.ttfBase64);\n pdf.addFont(`${font.id}.ttf`, font.id, \"normal\");\n }\n // One advancedAPI scope PER PAGE: jsPDF installs its mm→pt change-of-basis\n // matrix only on the page that is current when the mode switches (and\n // writes the balancing restore to the page current when it ends), so\n // adding pages inside a single advanced scope leaves every later page\n // without the matrix — content lands unscaled (pt-sized) in the corner\n // and the state stack unbalances.\n layouts.forEach((layout, index) => {\n if (index > 0) {\n pdf.addPage(\n [layout.sheet.width, layout.sheet.height],\n layout.sheet.width >= layout.sheet.height ? \"landscape\" : \"portrait\",\n );\n }\n pdf.advancedAPI((advanced) => {\n const sink = new PdfSink(advanced, layout.sheet.height);\n paintLayoutContent(layout, sink, model, {\n mapColor: printColorMapper(layout.printPalette),\n });\n });\n });\n return pdf;\n};\n","// GeometrySink over jsPDF. Note: jsPDF's \"advanced\" API mode is NOT\n// PDF-native y-up — it installs a global CTM of [s 0 0 -s 0 pageHeight],\n// so user coordinates are y-DOWN millimeters from the TOP-LEFT (verified\n// against the generated content stream). Our sheet space is y-up from the\n// bottom-left, so the matrix stack bottoms out at a y-flip.\n// Transforms are baked in JS, so clipping and lineweights stay trivially\n// correct.\n\nimport type jsPDF from \"jspdf\";\nimport type {\n FillStyle,\n GeometrySink,\n ImageSpec,\n Mat2x3,\n Rect,\n StrokeStyle,\n TextSpec,\n} from \"../../paint/sink\";\nimport {\n arcToBeziers,\n ellipseArcToBeziers,\n matApply,\n matMultiply,\n signedArcSweep,\n} from \"../../paint/sink\";\nimport { parseFontFace, realFace, resolveFont } from \"../../model/fonts\";\nimport {\n PDF_FALLBACK_FONT,\n pdfFontCovers,\n winAnsiEncodable,\n} from \"../../paint/fontCoverage\";\nimport type { Vec2 } from \"../../geometry/vec2\";\n\nconst PT_PER_MM = 72 / 25.4;\n\n/** Synthesized italic slant (tan of the skew angle, ~14°) — Skia's fake\n * italic, so a synthesized PDF face leans like the canvas one. */\nconst SYNTH_ITALIC_SKEW = 0.25;\n/** Synthesized bold: outline stroke width as a fraction of the cap height. */\nconst SYNTH_BOLD_STROKE = 0.04;\n\n/** #rrggbb → [r, g, b] 0-255 (jsPDF shading stop format). */\nconst hexToRgb255 = (hex: string): number[] => {\n const m = /^#?([0-9a-f]{6})$/i.exec(hex.trim());\n const v = m ? Number.parseInt(m[1], 16) : 0;\n return [(v >> 16) & 0xff, (v >> 8) & 0xff, v & 0xff];\n};\n\nexport class PdfSink implements GeometrySink {\n private readonly doc: jsPDF;\n private matrixStack: Mat2x3[];\n private pathOpen = false;\n private pathStart: Vec2 | null = null;\n private current: Vec2 | null = null;\n private gradId = 0;\n\n constructor(doc: jsPDF, sheetHeightMm: number) {\n this.doc = doc;\n // Base flip: sheet (y-up, origin bottom-left) → jsPDF advanced user\n // space (y-down, origin top-left).\n this.matrixStack = [[1, 0, 0, -1, 0, sheetHeightMm]];\n }\n\n private get matrix(): Mat2x3 {\n return this.matrixStack[this.matrixStack.length - 1];\n }\n\n private map(p: Vec2): Vec2 {\n return matApply(this.matrix, p);\n }\n\n /** Uniform scale of the current transform (for angle-preserving checks). */\n private get scaleFactor(): number {\n const m = this.matrix;\n return Math.hypot(m[0], m[1]);\n }\n\n /**\n * The font DEFINITION a string actually renders with: the requested font,\n * unless it cannot render the text in PDF — an embedded TTF lacking the\n * glyphs (the handwriting fonts + Cyrillic = tofu), or a font degrading to\n * base-14 Helvetica because its TTF was not registered (WinAnsi-only →\n * Cyrillic mojibake) — in which case the fallback substitutes per string\n * when IT can render the text. Size must then use THIS def's capHeight,\n * so callers take the def, not just a name.\n */\n private pdfFontDef(font: string | undefined, text: string) {\n // Coverage of what will ACTUALLY render: an unregistered \"embed\" font\n // becomes base-14 Helvetica, so it is judged by WinAnsi, not its table.\n const usable = (def: ReturnType<typeof resolveFont>) =>\n def.pdf === \"embed\" && this.doc.getFontList()[def.id]\n ? pdfFontCovers(def.id, text)\n : winAnsiEncodable(text);\n const def = resolveFont(font);\n if (usable(def)) return def;\n const fallback = resolveFont(PDF_FALLBACK_FONT);\n return usable(fallback) ? fallback : def;\n }\n\n /**\n * jsPDF font name for a font def: built-ins map directly; \"embed\" fonts\n * must have been registered (addFileToVFS/addFont under the font id) by\n * the exporting host — fall back to helvetica when they weren't.\n */\n private pdfFontName(def: ReturnType<typeof resolveFont>): string {\n if (def.pdf !== \"embed\") return def.pdf;\n return this.doc.getFontList()[def.id] ? def.id : \"helvetica\";\n }\n\n beginPath(): void {\n this.pathOpen = false;\n this.pathStart = null;\n this.current = null;\n }\n\n moveTo(p: Vec2): void {\n const q = this.map(p);\n this.doc.moveTo(q.x, q.y);\n this.pathOpen = true;\n this.pathStart = q;\n this.current = q;\n }\n\n lineTo(p: Vec2): void {\n const q = this.map(p);\n this.doc.lineTo(q.x, q.y);\n this.current = q;\n }\n\n bezierTo(c1: Vec2, c2: Vec2, end: Vec2): void {\n const q1 = this.map(c1);\n const q2 = this.map(c2);\n const qe = this.map(end);\n this.doc.curveTo(q1.x, q1.y, q2.x, q2.y, qe.x, qe.y);\n this.current = qe;\n }\n\n arc(\n center: Vec2,\n r: number,\n startAngle: number,\n endAngle: number,\n ccw: boolean,\n ): void {\n // Emit in the LOCAL frame and map each bezier point — uniform transforms\n // preserve circles as scaled circles, and beziers survive any affine map.\n const beziers = arcToBeziers(\n center,\n r,\n startAngle,\n signedArcSweep(startAngle, endAngle, ccw),\n );\n this.emitBeziers(beziers);\n }\n\n ellipse(\n center: Vec2,\n rx: number,\n ry: number,\n rotation: number,\n startAngle: number,\n endAngle: number,\n ): void {\n this.emitBeziers(\n ellipseArcToBeziers(\n center,\n rx,\n ry,\n rotation,\n startAngle,\n signedArcSweep(startAngle, endAngle, true),\n ),\n );\n }\n\n private emitBeziers(\n beziers: { start: Vec2; c1: Vec2; c2: Vec2; end: Vec2 }[],\n ): void {\n if (beziers.length === 0) return;\n const first = this.map(beziers[0].start);\n if (!this.pathOpen || !this.current) {\n this.doc.moveTo(first.x, first.y);\n this.pathOpen = true;\n this.pathStart = first;\n } else if (\n Math.hypot(this.current.x - first.x, this.current.y - first.y) > 1e-6\n ) {\n this.doc.lineTo(first.x, first.y);\n }\n for (const b of beziers) {\n const q1 = this.map(b.c1);\n const q2 = this.map(b.c2);\n const qe = this.map(b.end);\n this.doc.curveTo(q1.x, q1.y, q2.x, q2.y, qe.x, qe.y);\n this.current = qe;\n }\n }\n\n closePath(): void {\n this.doc.close();\n this.current = this.pathStart;\n }\n\n /**\n * Run `paint` with a per-op transparency GState when opacity < 1. jsPDF\n * buffers path construction until the painting call, so the q/gs pair\n * lands BEFORE the path in the content stream (the image() pattern).\n */\n private withOpacity(opacity: number | undefined, paint: () => void): void {\n const translucent = opacity !== undefined && opacity < 1;\n if (translucent) {\n this.doc.saveGraphicsState();\n this.doc.setGState(\n this.doc.GState({ opacity, \"stroke-opacity\": opacity }),\n );\n }\n paint();\n if (translucent) this.doc.restoreGraphicsState();\n }\n\n stroke(s: StrokeStyle): void {\n if (!this.pathOpen) return;\n this.doc.setDrawColor(s.color);\n this.doc.setLineWidth(Math.max(s.widthMm, 0.05));\n this.doc.setLineCap(\"round\");\n this.doc.setLineJoin(\"round\");\n this.doc.setLineDashPattern(s.dashMm ?? [], 0);\n this.withOpacity(s.opacity, () => this.doc.stroke());\n this.doc.setLineDashPattern([], 0);\n this.beginPath();\n }\n\n fill(f: FillStyle): void {\n if (!this.pathOpen) return;\n if (f.gradient) {\n // Axial/radial shading between the two colors; endpoints go through\n // the same matrix as the path, so the ramp stays anchored to the\n // geometry. Radial radius scales by the (uniform) transform.\n const a = this.map(f.gradient.from);\n const b = this.map(f.gradient.to);\n const key = `linea-grad-${this.gradId++}`;\n const coords =\n f.gradient.shape === \"radial\"\n ? [a.x, a.y, 0, a.x, a.y, Math.hypot(b.x - a.x, b.y - a.y)]\n : [a.x, a.y, b.x, b.y];\n this.doc.addShadingPattern(\n key,\n this.doc.ShadingPattern(\n f.gradient.shape === \"radial\" ? \"radial\" : \"axial\",\n coords,\n [\n { offset: 0, color: hexToRgb255(f.color) },\n { offset: 1, color: hexToRgb255(f.gradient.color2) },\n ],\n ),\n );\n // jsPDF requires a pattern matrix for shading fills (it stringifies\n // it unconditionally); identity keeps coords in path user space.\n this.withOpacity(f.opacity, () =>\n this.doc.fillEvenOdd({ key, matrix: this.doc.unitMatrix }),\n );\n this.beginPath();\n return;\n }\n this.doc.setFillColor(f.color);\n this.withOpacity(f.opacity, () => this.doc.fillEvenOdd());\n this.beginPath();\n }\n\n /**\n * The jsPDF font a face renders with + what must be synthesized: a styled\n * face uses its bundled TTF when the host registered it, otherwise the\n * regular font with fake bold (fill+stroke) / italic (skew). A coverage\n * fallback (pdfFontDef swapped the font) synthesizes too.\n */\n private pdfFace(font: string | undefined, text: string) {\n const def = this.pdfFontDef(font, text);\n const { bold, italic } = parseFontFace(font);\n const face = def.id === resolveFont(font).id ? realFace(font) : null;\n const real = face && this.doc.getFontList()[face] ? face : null;\n return {\n def,\n name: real ?? this.pdfFontName(def),\n synthBold: bold && !real,\n synthItalic: italic && !real,\n };\n }\n\n text(t: TextSpec): void {\n const heightMm = t.heightMm * this.scaleFactor;\n const { def, name, synthBold, synthItalic } = this.pdfFace(t.font, t.text);\n this.doc.setFont(name, \"normal\");\n // Model heights are CAP heights; PDF font size is the em.\n this.doc.setFontSize((heightMm / def.capHeight) * PT_PER_MM);\n this.doc.setTextColor(t.color);\n const widthFactor = t.widthFactor ?? 1;\n // jsPDF's own align/baseline offsets are broken in advanced mode (it\n // divides them by scaleFactor although text space is already mm-scaled),\n // so we place the exact baseline-left anchor ourselves — in cap-height\n // terms, matching canvasSink: bottom = baseline at the anchor, center /\n // top shift the baseline by half / full cap height.\n const width =\n (this.doc.getTextWidth(t.text) / this.scaleFactor) * widthFactor;\n const dx =\n t.hAlign === \"center\" ? -width / 2 : t.hAlign === \"right\" ? -width : 0;\n const dy =\n t.vAlign === \"center\"\n ? t.heightMm / 2\n : t.vAlign === \"top\"\n ? t.heightMm\n : 0;\n // Local text frame (y-up): run along the rotation, baseline dy below.\n const cos = Math.cos(t.rotation);\n const sin = Math.sin(t.rotation);\n const anchor = this.map({\n x: t.anchor.x + cos * dx + sin * dy,\n y: t.anchor.y + sin * dx - cos * dy,\n });\n const m = this.matrix;\n const extraRotation = Math.atan2(m[1], m[0]);\n const draw = () =>\n this.doc.text(t.text, anchor.x, anchor.y, {\n angle: ((t.rotation + extraRotation) * 180) / Math.PI,\n align: \"left\",\n baseline: \"alphabetic\",\n // AutoCAD-style width factor → PDF Tz horizontal scaling. ALWAYS\n // set: Tz is graphics state and persists across BT/ET, so an\n // omitted value inherits whatever the previous text left behind\n // (a 0.8-factor text would silently squeeze every later text).\n horizontalScale: widthFactor,\n // Same reason: Tr persists, so plain text resets it to fill.\n renderingMode: synthBold ? \"fillThenStroke\" : \"fill\",\n });\n if (!synthBold && !synthItalic) {\n this.withOpacity(t.opacity, draw);\n return;\n }\n this.doc.saveGraphicsState();\n if (synthBold) {\n this.doc.setDrawColor(t.color);\n this.doc.setLineWidth(heightMm * SYNTH_BOLD_STROKE);\n }\n if (synthItalic) {\n // Shear about the anchor along the text's page-space baseline: a\n // point h above the baseline moves k·h along it. Directions come from\n // the current transform, so any y-flip in it can't invert the slant.\n const w0 = t.anchor;\n const p0 = this.map(w0);\n const unit = (p: Vec2) => {\n const v = { x: p.x - p0.x, y: p.y - p0.y };\n const l = Math.hypot(v.x, v.y) || 1;\n return { x: v.x / l, y: v.y / l };\n };\n const d = unit(this.map({ x: w0.x + cos, y: w0.y + sin }));\n const u = unit(this.map({ x: w0.x - sin, y: w0.y + cos }));\n const k = SYNTH_ITALIC_SKEW;\n const a = 1 + k * d.x * u.x;\n const b = k * d.y * u.x;\n const c = k * d.x * u.y;\n const e = 1 + k * d.y * u.y;\n this.doc.setCurrentTransformationMatrix(\n this.doc.Matrix(\n a,\n b,\n c,\n e,\n anchor.x - (a * anchor.x + c * anchor.y),\n anchor.y - (b * anchor.x + e * anchor.y),\n ),\n );\n }\n this.withOpacity(t.opacity, draw);\n this.doc.restoreGraphicsState();\n }\n\n measureText(\n text: string,\n heightMm: number,\n font?: string,\n widthFactor = 1,\n ): { width: number } {\n const { def, name } = this.pdfFace(font, text);\n this.doc.setFont(name, \"normal\");\n this.doc.setFontSize((heightMm / def.capHeight) * PT_PER_MM);\n return { width: this.doc.getTextWidth(text) * widthFactor };\n }\n\n image(i: ImageSpec): void {\n // Compose a local frame whose y-DOWN [0..w]×[0..h] box (top-left at the\n // local origin — jsPDF advanced user-space semantics) is exactly the\n // image footprint, and install it as the CTM for one addImage call.\n const cos = Math.cos(i.rotation);\n const sin = Math.sin(i.rotation);\n const place: Mat2x3 = [cos, sin, -sin, cos, i.origin.x, i.origin.y];\n const flip: Mat2x3 = [1, 0, 0, -1, 0, i.heightMm];\n const m = matMultiply(matMultiply(this.matrix, place), flip);\n this.doc.saveGraphicsState();\n if (i.opacity < 1)\n this.doc.setGState(this.doc.GState({ opacity: i.opacity }));\n this.doc.setCurrentTransformationMatrix(\n this.doc.Matrix(m[0], m[1], m[2], m[3], m[4], m[5]),\n );\n const format = i.data.startsWith(\"data:image/png\") ? \"PNG\" : \"JPEG\";\n this.doc.addImage(\n i.data,\n format,\n 0,\n 0,\n i.widthMm,\n i.heightMm,\n undefined,\n \"FAST\",\n );\n this.doc.restoreGraphicsState();\n this.beginPath();\n }\n\n pushTransform(m: Mat2x3): void {\n this.matrixStack.push(matMultiply(this.matrix, m));\n }\n\n popTransform(): void {\n if (this.matrixStack.length > 1) this.matrixStack.pop();\n }\n\n pushClipRect(r: Rect): void {\n const p = this.map({ x: r.x, y: r.y });\n const q = this.map({ x: r.x + r.w, y: r.y + r.h });\n this.doc.saveGraphicsState();\n this.doc.moveTo(Math.min(p.x, q.x), Math.min(p.y, q.y));\n this.doc.lineTo(Math.max(p.x, q.x), Math.min(p.y, q.y));\n this.doc.lineTo(Math.max(p.x, q.x), Math.max(p.y, q.y));\n this.doc.lineTo(Math.min(p.x, q.x), Math.max(p.y, q.y));\n this.doc.close();\n this.doc.clip();\n this.doc.discardPath();\n this.beginPath();\n }\n\n popClip(): void {\n this.doc.restoreGraphicsState();\n }\n}\n","// High-level SVG rendering — the SVG counterpart to renderLayoutsToPdf. Paints\n// through the shared painters into an SvgSink, so SVG output matches screen and\n// PDF. `renderModelToSvg` frames the content bbox; `renderLayoutToSvg` frames a\n// sheet.\n\nimport { SvgSink } from \"./svgSink\";\nimport {\n paintLayoutContent,\n type LayoutModelContext,\n} from \"../../paint/layoutPaint\";\nimport { paintObject } from \"../../paint/painters\";\nimport { rebaseSink } from \"../../paint/rebaseSink\";\nimport { printColorMapper } from \"../../paint/printPalette\";\nimport { resolveStyle } from \"../../paint/style\";\nimport type { PrintPalette } from \"../../model/paperLayout\";\nimport { approximateTextMeasurer } from \"../../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../../paint/textMetrics\";\nimport { buildSnapEntry } from \"../../snap/buildEntry\";\nimport {\n addPointToBounds,\n boundsIntersect,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../../geometry/bounds\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\n\nexport interface SvgRenderOptions {\n /** Frame this world box instead of the content bounds. */\n bbox?: AABB;\n /** Text width measurement (defaults to the approximate Inter table). */\n measure?: TextMeasurer;\n /** Padding around the frame, world mm. */\n padding?: number;\n /**\n * Print-style color remap (same mapper as the PDF export): \"monochrome\"\n * turns every stroke black — the fix for light editor-theme layers\n * vanishing on a white background. Model render default: \"color\" (none);\n * layout render default: the layout's own printPalette.\n */\n palette?: PrintPalette;\n /**\n * Minimum stroke width as a FRACTION of the frame's larger side —\n * for thumbnails, where a fixed-mm lineweight scaled to a ~256px image\n * turns sub-pixel and the render rasterizes to nothing. E.g. a value of\n * 1.5/256 keeps every stroke ≥ ~1.5px when the render is displayed 256px\n * wide, regardless of drawing extents. Model render only.\n */\n minStrokeFrac?: number;\n}\n\n/** Render model space (the given objects) to an SVG string. */\nexport const renderModelToSvg = (\n model: LayoutModelContext,\n opts: SvgRenderOptions = {},\n): string => {\n const measure = opts.measure ?? approximateTextMeasurer;\n // No palette = as-authored colors verbatim: even \"color\" flips light\n // neutrals for paper, which would silently change every existing\n // dark-canvas model render. Mapping is strictly opt-in here.\n const mapColor = opts.palette\n ? printColorMapper(opts.palette)\n : (c: string) => c;\n const layerVisible = new Map(model.layers.map((l) => [l.id, l.visible]));\n const layerName = new Map(model.layers.map((l) => [l.id, l.name]));\n // Pass 1 — the frame: minStrokeFrac needs the final extents before any\n // stroke is emitted, so bounds are collected ahead of painting.\n const toPaint: (typeof model.objects)[number][] = [];\n let bbox = opts.bbox ?? emptyBounds();\n for (const obj of model.objects) {\n if (layerVisible.get(obj.layerId) === false) continue;\n const b = buildSnapEntry(obj, {\n dimStyles: model.dimStyles,\n textStyles: model.textStyles,\n blockDefinitions: model.blockDefinitions,\n resolveObject: model.resolveObject,\n resolveReference: model.resolveReference,\n measure,\n }).bounds;\n if (opts.bbox) {\n // A bbox crop culls, not just frames: off-view geometry must not ride\n // along invisibly in the file (size, and it leaks unshared content).\n if (isEmptyBounds(b) || !boundsIntersect(b, opts.bbox)) continue;\n } else if (!isEmptyBounds(b)) {\n bbox = unionBounds(bbox, b);\n }\n toPaint.push(obj);\n }\n if (isEmptyBounds(bbox)) addPointToBounds(bbox, { x: 0, y: 0 });\n\n // Pass 2 — paint into a sink that clamps hairlines relative to the frame.\n const minStrokeWidthMm = opts.minStrokeFrac\n ? opts.minStrokeFrac *\n Math.max(bbox.maxX - bbox.minX, bbox.maxY - bbox.minY)\n : undefined;\n const sink = new SvgSink({ measure, minStrokeWidthMm });\n // A drawing far from the origin (survey coordinates) is written relative\n // to its frame's corner: SVG viewers render in float32 and would quantize\n // 10¹⁰-mm coordinates to metres. ponytail: below FAR_MM it stays absolute\n // (readers/agents may rely on real coordinates) — always rebase if that\n // ever matters less than consistency.\n const far =\n Math.max(\n Math.abs(bbox.minX),\n Math.abs(bbox.maxX),\n Math.abs(bbox.minY),\n Math.abs(bbox.maxY),\n ) > FAR_MM;\n const origin = far ? { x: bbox.minX, y: bbox.minY } : { x: 0, y: 0 };\n const out = rebaseSink(sink, origin);\n for (const obj of toPaint) {\n const style = resolveStyle(obj, model.layers);\n sink.beginObject(obj.id, layerName.get(obj.layerId));\n paintObject(obj, out, {\n style: { ...style, color: mapColor(style.color) },\n dimStyles: model.dimStyles,\n textStyles: model.textStyles,\n blockDefinitions: model.blockDefinitions,\n resolveObject: model.resolveObject,\n assets: model.assets,\n resolveReference: model.resolveReference,\n mapColor,\n });\n sink.endObject();\n }\n return sink.toSvg(\n {\n minX: bbox.minX - origin.x,\n minY: bbox.minY - origin.y,\n maxX: bbox.maxX - origin.x,\n maxY: bbox.maxY - origin.y,\n },\n opts.padding,\n );\n};\n\n/** Beyond 10 km from the origin an SVG is written relative to its frame. */\nconst FAR_MM = 1e7;\n\n/**\n * Render a paper layout (viewport content + sheet annotations) to SVG, framed\n * to the sheet. Note: viewport clipping is not yet enforced by SvgSink (v1).\n */\nexport const renderLayoutToSvg = (\n layout: PaperLayout,\n model: LayoutModelContext,\n opts: SvgRenderOptions = {},\n): string => {\n const sink = new SvgSink({ measure: opts.measure });\n // Honor the layout's own print palette (like the PDF export) unless the\n // caller overrides it.\n paintLayoutContent(layout, sink, model, {\n mapColor: printColorMapper(opts.palette ?? layout.printPalette),\n });\n const bbox = opts.bbox ?? {\n minX: 0,\n minY: 0,\n maxX: layout.sheet.width,\n maxY: layout.sheet.height,\n };\n return sink.toSvg(bbox, opts.padding ?? 0);\n};\n","// One PDF page → model object DTOs: STROKED paths become lines/polylines,\n// text runs become text objects. Pure — it consumes pdf.js v6\n// getOperatorList()/getTextContent() output with the OPS enum injected, so\n// tests can drive it with the node-safe legacy build.\n//\n// pdf.js v6 fuses path construction with its paint op: constructPath args are\n// [paintOp, [flatPathData], minMax] where the flat data interleaves DrawOPS\n// codes (0 moveTo, 1 lineTo, 2 cubic, 3 quadratic, 4 closePath) with coords.\n// Colors arrive pre-normalized as \"#rrggbb\" strings.\n\nimport type { ModelObjectDto } from \"../../model/objects\";\nimport type { Vec2 } from \"../../geometry/vec2\";\nimport {\n matApply,\n matIdentity,\n matMultiply,\n type Mat2x3,\n} from \"../../paint/sink\";\n\nconst PT2MM = 25.4 / 72;\nconst BEZIER_STEPS = 12;\n\n/**\n * Colors in PDFs are authored for white paper; dark neutrals (black/dark-gray\n * ink) map to byLayer (undefined) so they stay visible on the dark canvas.\n */\nconst importColor = (hex: string): string | undefined => {\n const m = /^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$/i.exec(hex);\n if (!m) return undefined;\n const [r, g, b] = [m[1], m[2], m[3]].map((h) => parseInt(h, 16));\n const lum = (0.2126 * r + 0.7152 * g + 0.0722 * b) / 255;\n const saturation = (Math.max(r, g, b) - Math.min(r, g, b)) / 255;\n return lum < 0.35 && saturation < 0.25 ? undefined : hex.toLowerCase();\n};\n\nexport interface PdfTextItem {\n str: string;\n /** Text matrix in page space (pt, y-up): [a, b, c, d, tx, ty]. */\n transform: number[];\n}\n\nexport interface PdfPageInput {\n fnArray: number[];\n argsArray: unknown[];\n textItems: PdfTextItem[];\n /** MediaBox [x0, y0, x1, y1] in pt. */\n view: number[];\n /** pdf.js OPS enum (injected — differs per build flavor, values stable). */\n ops: Record<string, number>;\n /** The page's /Rotate (degrees CLOCKWISE, a multiple of 90): viewers show\n * the page turned by it, so the import does too. */\n rotate?: number;\n /** Also take FILLED paths, as their outlines (a raster PDF reference's\n * snap geometry — frames and borders are often drawn as fills). */\n fills?: boolean;\n}\n\ntype DistributiveOmit<T, K extends PropertyKey> = T extends unknown\n ? Omit<T, K>\n : never;\n\n/** Object base fields left for the caller: layerId. */\nexport type PdfDto = DistributiveOmit<ModelObjectDto, \"layerId\">;\n\nexport const convertPdfPage = (input: PdfPageInput): PdfDto[] => {\n const { fnArray, argsArray, view, ops } = input;\n const strokeOps = new Set(\n [\n ops.stroke,\n ops.closeStroke,\n ops.fillStroke,\n ops.eoFillStroke,\n ops.closeFillStroke,\n ops.closeEOFillStroke,\n ].filter((v) => v !== undefined),\n );\n\n // Page space → mm with the page's /Rotate applied (clockwise, Y-up), so\n // the result sits upright in the positive quadrant as a viewer shows it.\n const w = (view[2] - view[0]) * PT2MM;\n const h = (view[3] - view[1]) * PT2MM;\n const turn = ((((input.rotate ?? 0) % 360) + 360) % 360) / 90;\n const fillOps = new Set(\n [ops.fill, ops.eoFill].filter((v) => v !== undefined),\n );\n const toMm = (p: Vec2): Vec2 => {\n const x = (p.x - view[0]) * PT2MM;\n const y = (p.y - view[1]) * PT2MM;\n return turn === 1\n ? { x: y, y: w - x }\n : turn === 2\n ? { x: w - x, y: h - y }\n : turn === 3\n ? { x: h - y, y: x }\n : { x, y };\n };\n const turnRad = (-turn * Math.PI) / 2;\n\n const dtos: PdfDto[] = [];\n const stack: Mat2x3[] = [];\n let ctm: Mat2x3 = matIdentity;\n let strokeColor: string | undefined;\n let lineWidth = 1;\n\n const emitSubpath = (points: Vec2[], closed: boolean): void => {\n if (points.length < 2) return;\n const scale = Math.hypot(ctm[0], ctm[1]) || 1;\n const widthMm = Math.max(lineWidth * scale * PT2MM, 0.05);\n const base = {\n color: strokeColor,\n lineWidth: Math.round(widthMm * 100) / 100,\n };\n if (points.length === 2 && !closed) {\n dtos.push({ type: \"line\", a: points[0], b: points[1], ...base });\n return;\n }\n dtos.push({\n type: \"polyline\",\n points: points.map((p) => ({ x: p.x, y: p.y, bulge: 0 })),\n closed,\n ...base,\n });\n };\n\n const flushPath = (data: number[]): void => {\n let current: Vec2 | null = null;\n let subpath: Vec2[] = [];\n let closed = false;\n const flush = () => {\n emitSubpath(subpath, closed);\n subpath = [];\n closed = false;\n };\n const push = (p: Vec2) => {\n current = p;\n subpath.push(toMm(matApply(ctm, p)));\n };\n const sample = (f: (t: number) => Vec2) => {\n for (let s = 1; s <= BEZIER_STEPS; s++) push(f(s / BEZIER_STEPS));\n };\n let i = 0;\n while (i < data.length) {\n switch (data[i]) {\n case 0: // moveTo\n if (subpath.length > 1) flush();\n else subpath = [];\n push({ x: data[i + 1], y: data[i + 2] });\n i += 3;\n break;\n case 1: // lineTo\n push({ x: data[i + 1], y: data[i + 2] });\n i += 3;\n break;\n case 2: {\n // cubic bezier\n const [p0, c1, c2, p1] = [\n current ?? { x: data[i + 1], y: data[i + 2] },\n { x: data[i + 1], y: data[i + 2] },\n { x: data[i + 3], y: data[i + 4] },\n { x: data[i + 5], y: data[i + 6] },\n ];\n sample((t) => {\n const u = 1 - t;\n return {\n x:\n u * u * u * p0.x +\n 3 * u * u * t * c1.x +\n 3 * u * t * t * c2.x +\n t * t * t * p1.x,\n y:\n u * u * u * p0.y +\n 3 * u * u * t * c1.y +\n 3 * u * t * t * c2.y +\n t * t * t * p1.y,\n };\n });\n i += 7;\n break;\n }\n case 3: {\n // quadratic bezier\n const p0 = current ?? { x: data[i + 1], y: data[i + 2] };\n const c = { x: data[i + 1], y: data[i + 2] };\n const p1 = { x: data[i + 3], y: data[i + 4] };\n sample((t) => {\n const u = 1 - t;\n return {\n x: u * u * p0.x + 2 * u * t * c.x + t * t * p1.x,\n y: u * u * p0.y + 2 * u * t * c.y + t * t * p1.y,\n };\n });\n i += 5;\n break;\n }\n case 4: // closePath\n closed = true;\n i += 1;\n break;\n default:\n // Unknown sub-op — bail on this path rather than misparse.\n return flush();\n }\n }\n flush();\n };\n\n for (let i = 0; i < fnArray.length; i++) {\n const fn = fnArray[i];\n const args = argsArray[i] as unknown[] | null;\n if (fn === ops.save) stack.push(ctm);\n else if (fn === ops.restore) ctm = stack.pop() ?? matIdentity;\n else if (fn === ops.transform && args)\n ctm = matMultiply(ctm, args as unknown as Mat2x3);\n else if (fn === ops.setStrokeRGBColor && args)\n strokeColor = importColor(String(args[0]));\n else if (fn === ops.setLineWidth && args) lineWidth = Number(args[0]);\n else if (fn === ops.constructPath && args) {\n const [paintOp, pathData] = args as [\n number,\n ArrayLike<number> | ArrayLike<number>[],\n ];\n // Lines-only import (fills, clips skipped) unless outlines are asked for.\n if (!strokeOps.has(paintOp) && !(input.fills && fillOps.has(paintOp)))\n continue;\n // Path data arrives as Float32Array chunks (or one flat run).\n const flat: number[] =\n typeof (pathData as ArrayLike<number>)[0] === \"number\"\n ? Array.from(pathData as ArrayLike<number>)\n : Array.from(pathData as ArrayLike<ArrayLike<number>>, (part) =>\n Array.from(part),\n ).flat();\n flushPath(flat);\n }\n }\n\n // Text runs: transform = [a, b, c, d, tx, ty] in page space (pt, y-up);\n // the y basis length is the effective font size, (tx, ty) the\n // baseline-left origin → left / bottom justified.\n for (const item of input.textItems) {\n if (!item.str.trim()) continue;\n const [a, b, c, d, tx, ty] = item.transform;\n const height = Math.hypot(c, d) * PT2MM;\n if (!(height > 0)) continue;\n dtos.push({\n type: \"text\",\n position: toMm({ x: tx, y: ty }),\n content: item.str,\n // The PDF glyph size is explicit — keep it as an override.\n styleOverride: { textHeight: Math.round(height * 1000) / 1000 },\n rotation: Math.atan2(b, a) + turnRad,\n // A PDF run starts at its baseline origin: text right of and above it.\n hAlign: \"left\",\n vAlign: \"bottom\",\n leaderLines: [],\n scale: 1,\n });\n }\n\n return dtos;\n};\n","// PDF → model objects. Stroked vector paths become lines/polylines and text\n// runs become text objects — PDFs don't preserve dimensions/leaders as\n// objects, so those arrive as exploded geometry. Multi-page files lay pages\n// out left-to-right.\n//\n// HEADLESS: imports pdf.js's `legacy` build (the main build needs the DOM),\n// which runs in Node with no worker configuration. A browser caller may pass\n// a bundled `workerSrc`. Pure conversion is delegated to convertPdfPage; this\n// module only drives pdf.js. The caller assigns a layer and applies the DTOs.\n\nimport { convertPdfPage, type PdfDto } from \"./convertPage\";\n\nconst PAGE_GAP_MM = 10;\n\n/** Shift a converted page right (multi-page files lay out left-to-right). */\nconst shiftX = (dto: PdfDto, dx: number): PdfDto => {\n switch (dto.type) {\n case \"line\":\n return {\n ...dto,\n a: { x: dto.a.x + dx, y: dto.a.y },\n b: { x: dto.b.x + dx, y: dto.b.y },\n };\n case \"polyline\":\n return {\n ...dto,\n points: dto.points.map((p) => ({ ...p, x: p.x + dx })),\n };\n case \"text\":\n return {\n ...dto,\n position: { x: dto.position.x + dx, y: dto.position.y },\n };\n default:\n return dto;\n }\n};\n\nexport interface PdfImportOptions {\n /**\n * pdf.js worker source. Node needs none (the legacy build runs on a fake\n * worker). In a browser, pass the bundled worker URL. Set only when given.\n */\n workerSrc?: string;\n /** Called before converting each page (1-based), e.g. for a progress UI. */\n onProgress?: (page: number, pageCount: number) => void | Promise<void>;\n /** Convert only this 1-based page, at the origin (a PDF reference). */\n page?: number;\n /** Filled paths too, as outlines (see PdfPageInput.fills). */\n fills?: boolean;\n}\n\nexport interface PdfImportResult {\n /** Converted objects as layer-less DTOs — the caller assigns a layer. */\n objects: PdfDto[];\n pageCount: number;\n}\n\n/**\n * Parse PDF bytes into model-object DTOs. Pure of any store/UI; throws if\n * pdf.js cannot parse the data. The editor/CLI wraps this with the layer\n * assignment, the undo transaction, and toasts.\n */\nexport const pdfToModel = async (\n data: ArrayBuffer | Uint8Array,\n opts: PdfImportOptions = {},\n): Promise<PdfImportResult> => {\n // Lazy: pdfjs is by far the heaviest dependency and only PDF *import*\n // needs it — loaded statically it would weigh on (or, where its native\n // pieces misbehave, take down) every consumer that never touches PDFs.\n const { getDocument, GlobalWorkerOptions, OPS } =\n await import(\"pdfjs-dist/legacy/build/pdf.mjs\");\n if (opts.workerSrc !== undefined)\n GlobalWorkerOptions.workerSrc = opts.workerSrc;\n\n const objects: PdfDto[] = [];\n const doc = await getDocument({ data }).promise;\n const pageCount = doc.numPages;\n let offsetX = 0;\n const pages =\n opts.page !== undefined\n ? [Math.min(Math.max(1, opts.page), pageCount)]\n : Array.from({ length: pageCount }, (_, i) => i + 1);\n for (const n of pages) {\n await opts.onProgress?.(n, pageCount);\n const page = await doc.getPage(n);\n const [list, text] = await Promise.all([\n page.getOperatorList(),\n page.getTextContent(),\n ]);\n const pageDtos = convertPdfPage({\n fnArray: list.fnArray,\n argsArray: list.argsArray,\n textItems: text.items.filter(\n (i): i is Extract<(typeof text.items)[number], { str: string }> =>\n \"str\" in i && \"transform\" in i,\n ),\n view: page.view,\n ops: OPS as unknown as Record<string, number>,\n rotate: page.rotate,\n fills: opts.fills,\n });\n for (const dto of pageDtos) objects.push(shiftX(dto, offsetX));\n // A quarter-turned page is as wide as its box is tall.\n const quarter = page.rotate % 180 !== 0;\n offsetX +=\n (quarter ? page.view[3] - page.view[1] : page.view[2] - page.view[0]) *\n (25.4 / 72) +\n PAGE_GAP_MM;\n }\n await doc.cleanup();\n return { objects, pageCount };\n};\n","// Semantic operation DTOs — the shared mutation contract for the SDK, CLI,\n// MCP tools, and cloud sync (see docs/kernel-op-layer.md). Every op is\n// self-contained, id-based, space-addressed, versioned, and invertible.\n\nimport { z } from \"zod\";\nimport { LayerSchema } from \"../model/document\";\nimport {\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n} from \"../model/objects\";\nimport { PaperLayoutSchema, PrintPaletteSchema } from \"../model/paperLayout\";\n\n// --- document field ops ----------------------------------------------------\n\n// for future\n// const SetDocumentSettingsOpSchema = z.object({\n// type: z.literal(\"set-document-settings\"),\n// });\n\n// --- layer ops -------------------------------------------------------------\n\nconst AddLayerOpSchema = z.object({\n type: z.literal(\"add-layer\"),\n layer: LayerSchema,\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateLayerOpSchema = z.object({\n type: z.literal(\"update-layer\"),\n layer: LayerSchema,\n});\n\nconst RemoveLayerOpSchema = z.object({\n type: z.literal(\"remove-layer\"),\n id: z.string(),\n});\n\n/** Explicit total order — every current layer id exactly once. Ids only, so\n * a concurrent property edit to a layer survives a reorder. */\nconst ReorderLayersOpSchema = z.object({\n type: z.literal(\"reorder-layers\"),\n ids: z.array(z.string()).min(1),\n});\n\nconst SetCurrentLayerOpSchema = z.object({\n type: z.literal(\"set-current-layer\"),\n id: z.string(),\n});\n\n/** LEGACY full layer-list replace — accepted for wire/history compat, no\n * longer emitted (diffLayerOps decomposes into the granular ops + reorder).\n * Validated like the granular ops: the current layer and every layer still\n * in use must survive. */\nconst SetLayersOpSchema = z.object({\n type: z.literal(\"set-layers\"),\n layers: z.array(LayerSchema).min(1),\n});\n\n// --- object ops (the funnel core) -----------------------------------------\n\n/** Target collection of an op: model space or a specific paper layout. */\nexport const OpSpaceSchema = z.union([\n z.literal(\"model\"),\n z.object({ layoutId: z.string() }),\n]);\nexport type OpSpace = z.infer<typeof OpSpaceSchema>;\n\nconst AddObjectsOpSchema = z.object({\n type: z.literal(\"add-objects\"),\n space: OpSpaceSchema,\n /** Ids are pre-assigned by the caller (never stamped here). */\n objects: z.array(ModelObjectSchema).min(1),\n /**\n * Optional insertion indices into the space's draw order, matched 1:1 to\n * `objects` and referring to positions in the FINAL array (ascending).\n * Omitted = append. Carried by remove-objects inverses so undoing a delete\n * restores exact draw order.\n */\n indices: z.array(z.number().int().nonnegative()).optional(),\n});\n\nconst UpdateObjectsOpSchema = z.object({\n type: z.literal(\"update-objects\"),\n space: OpSpaceSchema,\n /** Full replacement states, matched to existing objects by id. */\n objects: z.array(ModelObjectSchema).min(1),\n});\n\nconst RemoveObjectsOpSchema = z.object({\n type: z.literal(\"remove-objects\"),\n space: OpSpaceSchema,\n ids: z.array(z.string()).min(1),\n});\n\n/**\n * Where a reorder places the moved objects: the top/bottom of the space's\n * draw order, or immediately above/below a reference object (by id).\n */\nconst ReorderPlacementSchema = z.union([\n z.literal(\"front\"),\n z.literal(\"back\"),\n z.object({ above: z.string() }),\n z.object({ below: z.string() }),\n]);\nexport type ReorderPlacement = z.infer<typeof ReorderPlacementSchema>;\n\nconst ReorderObjectsOpSchema = z.object({\n type: z.literal(\"reorder-objects\"),\n space: OpSpaceSchema,\n /**\n * Moved as one contiguous run in the order GIVEN here (bottom → top).\n * Passing every id of the space with placement \"back\" therefore sets an\n * explicit total order — which is how inverses restore exactly.\n */\n ids: z.array(z.string()).min(1),\n placement: ReorderPlacementSchema,\n});\n\n// --- layout ops ------------------------------------------------------------\n\nconst AddLayoutOpSchema = z.object({\n type: z.literal(\"add-layout\"),\n layout: PaperLayoutSchema,\n index: z.number().int().nonnegative().optional(),\n});\n\n/** Sheet metadata only — layout CONTENT is edited via object ops on its space. */\nconst UpdateLayoutMetaOpSchema = z.object({\n type: z.literal(\"update-layout-meta\"),\n id: z.string(),\n name: z.string().optional(),\n sheet: z.object({ width: z.number(), height: z.number() }).optional(),\n printPalette: PrintPaletteSchema.optional(),\n});\n\nconst RemoveLayoutOpSchema = z.object({\n type: z.literal(\"remove-layout\"),\n id: z.string(),\n});\n\n/** Explicit total order — every current layout id exactly once. Layout\n * order is semantic: it is the sheet order of multi-page PDF export. */\nconst ReorderLayoutsOpSchema = z.object({\n type: z.literal(\"reorder-layouts\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** Full layout replace by id (sheet AND content — page setup, bulk edits).\n * The granular path (update-layout-meta + object ops on the layout's space)\n * stays preferred; this mirrors the editor's coarse updateLayouts. */\nconst UpdateLayoutsOpSchema = z.object({\n type: z.literal(\"update-layouts\"),\n layouts: z.array(PaperLayoutSchema).min(1),\n});\n\n// --- text style ops ---------------------------------------------------------------\n\nconst AddTextStyleOpSchema = z.object({\n type: z.literal(\"add-text-style\"),\n style: TextStyleSchema,\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateTextStyleOpSchema = z.object({\n type: z.literal(\"update-text-style\"),\n /** Full replacement state, matched by id. */\n style: TextStyleSchema,\n});\n\nconst RemoveTextStyleOpSchema = z.object({\n type: z.literal(\"remove-text-style\"),\n id: z.string(),\n});\n\n/** Explicit total order of style ids (first style = the document default,\n * so order is semantic, not just display). */\nconst ReorderTextStylesOpSchema = z.object({\n type: z.literal(\"reorder-text-styles\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — accepted for wire/history compat, no longer\n * emitted; edits decompose into the granular trio + reorder. */\nconst SetTextStylesOpSchema = z.object({\n type: z.literal(\"set-text-styles\"),\n textStyles: z.array(TextStyleSchema),\n});\n\n// --- dim style ops ---------------------------------------------------------------\n\nconst AddDimStyleOpSchema = z.object({\n type: z.literal(\"add-dim-style\"),\n style: DimStyleSchema,\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateDimStyleOpSchema = z.object({\n type: z.literal(\"update-dim-style\"),\n style: DimStyleSchema,\n});\n\nconst RemoveDimStyleOpSchema = z.object({\n type: z.literal(\"remove-dim-style\"),\n id: z.string(),\n});\n\nconst ReorderDimStylesOpSchema = z.object({\n type: z.literal(\"reorder-dim-styles\"),\n ids: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — same role as set-text-styles. */\nconst SetDimStylesOpSchema = z.object({\n type: z.literal(\"set-dim-styles\"),\n dimStyles: z.array(DimStyleSchema),\n});\n\n// --- asset ops ---------------------------------------------------------------\n\nconst SetAssetOpSchema = z.object({\n type: z.literal(\"set-asset\"),\n /** Content key (hashAsset of the data URL, by convention). */\n id: z.string(),\n dataUrl: z.string(),\n});\n\nconst RemoveAssetOpSchema = z.object({\n type: z.literal(\"remove-asset\"),\n id: z.string(),\n});\n\n// --- block definition ops ---------------------------------------------------------------\n//\n// Module ops (blocks and document commands) are CONTENT-addressed: a module\n// is an opaque source string whose semantic id only exists after compiling,\n// which pure op validation cannot do — and identical strings are genuinely\n// indistinguishable, so exact-source addressing is precise. A stale\n// `prevSource`/`source` no longer in the document REJECTS (unknown-module)\n// instead of silently clobbering a concurrent edit. See docs/granular-ops.md.\n\nconst AddBlockDefinitionOpSchema = z.object({\n type: z.literal(\"add-block-definition\"),\n source: z.string(),\n /** Insertion index (defaults to append); carried so undo restores order. */\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateBlockDefinitionOpSchema = z.object({\n type: z.literal(\"update-block-definition\"),\n /** The exact current source this edit was computed against. */\n prevSource: z.string(),\n source: z.string(),\n});\n\nconst RemoveBlockDefinitionOpSchema = z.object({\n type: z.literal(\"remove-block-definition\"),\n source: z.string(),\n});\n\n/** Explicit total order of the current sources. Same payload size as the\n * set op, but SAME-SET validated: a stale reorder rejects instead of\n * deleting a module a peer added concurrently. */\nconst ReorderBlockDefinitionsOpSchema = z.object({\n type: z.literal(\"reorder-block-definitions\"),\n sources: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — accepted for wire/history compat and as the only\n * op that can express duplicate sources; no longer emitted otherwise. */\nconst SetBlockDefinitionsOpSchema = z.object({\n type: z.literal(\"set-block-definitions\"),\n /** Raw block module sources (semantic validation happens at compile). */\n blockDefinitions: z.array(z.string()),\n});\n\n// --- document command ops ----------------------------------------------------\n\nconst AddDocumentCommandOpSchema = z.object({\n type: z.literal(\"add-document-command\"),\n source: z.string(),\n index: z.number().int().nonnegative().optional(),\n});\n\nconst UpdateDocumentCommandOpSchema = z.object({\n type: z.literal(\"update-document-command\"),\n prevSource: z.string(),\n source: z.string(),\n});\n\nconst RemoveDocumentCommandOpSchema = z.object({\n type: z.literal(\"remove-document-command\"),\n source: z.string(),\n});\n\nconst ReorderDocumentCommandsOpSchema = z.object({\n type: z.literal(\"reorder-document-commands\"),\n sources: z.array(z.string()).min(1),\n});\n\n/** LEGACY full replace — same role as set-block-definitions. */\nconst SetDocumentCommandsOpSchema = z.object({\n type: z.literal(\"set-document-commands\"),\n /** Raw user-command module sources (document scope). */\n commands: z.array(z.string()),\n});\n\nexport const OperationSchema = z.discriminatedUnion(\"type\", [\n // document\n // objects\n AddObjectsOpSchema,\n UpdateObjectsOpSchema,\n RemoveObjectsOpSchema,\n ReorderObjectsOpSchema,\n // layers\n AddLayerOpSchema,\n UpdateLayerOpSchema,\n RemoveLayerOpSchema,\n ReorderLayersOpSchema,\n SetLayersOpSchema,\n SetCurrentLayerOpSchema,\n // layouts\n AddLayoutOpSchema,\n UpdateLayoutMetaOpSchema,\n RemoveLayoutOpSchema,\n ReorderLayoutsOpSchema,\n UpdateLayoutsOpSchema,\n // text styles\n AddTextStyleOpSchema,\n UpdateTextStyleOpSchema,\n RemoveTextStyleOpSchema,\n ReorderTextStylesOpSchema,\n SetTextStylesOpSchema,\n // dim styles\n AddDimStyleOpSchema,\n UpdateDimStyleOpSchema,\n RemoveDimStyleOpSchema,\n ReorderDimStylesOpSchema,\n SetDimStylesOpSchema,\n // assets\n SetAssetOpSchema,\n RemoveAssetOpSchema,\n // block definitions\n AddBlockDefinitionOpSchema,\n UpdateBlockDefinitionOpSchema,\n RemoveBlockDefinitionOpSchema,\n ReorderBlockDefinitionsOpSchema,\n SetBlockDefinitionsOpSchema,\n // commands\n AddDocumentCommandOpSchema,\n UpdateDocumentCommandOpSchema,\n RemoveDocumentCommandOpSchema,\n ReorderDocumentCommandsOpSchema,\n SetDocumentCommandsOpSchema,\n]);\n\nexport type Operation = z.infer<typeof OperationSchema>;\n\n/** An op batch from outside the kernel's own code (scripts, agents, the\n * SDK): schema-checked so a malformed op fails here with a readable message\n * instead of being saved and failing the document schema on reopen. */\nexport const parseOperations = (ops: readonly unknown[]): Operation[] => {\n const result = z.array(OperationSchema).safeParse(ops);\n if (!result.success)\n throw new Error(`applyOps(): invalid operation\n${z.prettifyError(result.error)}`);\n return result.data;\n};\n","// Pure operation applier + validator. `applyOperation(doc, op)` validates the\n// op against full document state (referential integrity), returns the next\n// document and the INVERSE op. No store, no indexes, no invalidation — the\n// cloud server runs this against authoritative state; DocumentKernel wraps it\n// with indexes + invalidation. See docs/kernel-op-layer.md.\n\nimport {\n blockDefinitionExists,\n blockScriptId,\n getBlockMetaResult,\n} from \"../extensions/evalBlock\";\nimport type { LineaDocument } from \"../model/document\";\nimport { dimStyleFor, textStyleFor, type ModelObject } from \"../model/objects\";\nimport type { PaperLayout } from \"../model/paperLayout\";\nimport type { OpSpace, Operation } from \"./types\";\n\n/** Machine-readable validation/apply failure. */\nexport type OpErrorCode =\n | \"unknown-space\"\n | \"unknown-object\"\n | \"duplicate-id\"\n | \"missing-layer\"\n | \"missing-definition\"\n | \"viewport-in-model\"\n | \"invalid-reorder\"\n | \"unknown-layer\"\n | \"layer-in-use\"\n | \"last-layer\"\n | \"current-layer\"\n | \"unknown-layout\"\n | \"duplicate-layout\"\n | \"invalid-dimension\"\n | \"unknown-asset\"\n | \"asset-in-use\"\n | \"unknown-style\"\n | \"last-style\"\n | \"style-in-use\"\n | \"unknown-module\"\n | \"definition-in-use\"\n | \"duplicate-name\";\n\nexport class OpError extends Error {\n readonly code: OpErrorCode;\n constructor(code: OpErrorCode, message: string) {\n super(message);\n this.name = \"OpError\";\n this.code = code;\n }\n}\n\nexport interface ApplyResult {\n document: LineaDocument;\n /** The op that undoes this one exactly. */\n inverse: Operation;\n}\n\n// --- space helpers ---------------------------------------------------------\n\nconst spaceLabel = (s: OpSpace): string =>\n s === \"model\" ? \"model\" : `layout ${s.layoutId}`;\n\nconst getSpaceObjects = (doc: LineaDocument, space: OpSpace): ModelObject[] => {\n if (space === \"model\") return doc.objects;\n const layout = doc.layouts.find((l) => l.id === space.layoutId);\n if (!layout)\n throw new OpError(\"unknown-space\", `No layout ${space.layoutId}`);\n return layout.objects;\n};\n\nconst setSpaceObjects = (\n doc: LineaDocument,\n space: OpSpace,\n objects: ModelObject[],\n): LineaDocument =>\n space === \"model\"\n ? { ...doc, objects }\n : {\n ...doc,\n layouts: doc.layouts.map((l) =>\n l.id === space.layoutId ? { ...l, objects } : l,\n ),\n };\n\n// --- referential integrity -------------------------------------------------\n\nconst assertObjectRefs = (\n doc: LineaDocument,\n obj: ModelObject,\n space: OpSpace,\n): void => {\n if (!doc.layers.some((l) => l.id === obj.layerId))\n throw new OpError(\n \"missing-layer\",\n `Object ${obj.id} references unknown layer ${obj.layerId}`,\n );\n // Definition ids are module exports — the check compiles (cached) and is\n // PERMISSIVE while the lazy transpiler is still loading; evaluation reports\n // the definitive per-instance error either way.\n if (\n obj.type === \"block\" &&\n !blockDefinitionExists(doc.blockDefinitions, obj.definitionId)\n )\n throw new OpError(\n \"missing-definition\",\n `Block ${obj.id} references unknown definition ${obj.definitionId}`,\n );\n if (obj.type === \"viewport\" && space === \"model\")\n throw new OpError(\n \"viewport-in-model\",\n `Viewport ${obj.id} cannot live in model space`,\n );\n if (obj.type === \"dimension\") {\n // What each kind's geometry derivation actually needs (fewer points\n // renders as nothing, which hides authoring bugs).\n const min = { linear: 2, angular: 3, radial: 2, diameter: 2 }[obj.kind];\n if (obj.points.length < min)\n throw new OpError(\n \"invalid-dimension\",\n `Dimension ${obj.id}: a ${obj.kind} dimension needs at least ${min} points, got ${obj.points.length}`,\n );\n }\n};\n\n// --- object ops ------------------------------------------------------------\n\nconst applyAddObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const ids = new Set(existing.map((o) => o.id));\n for (const obj of op.objects) {\n if (ids.has(obj.id))\n throw new OpError(\n \"duplicate-id\",\n `Object ${obj.id} already exists in ${spaceLabel(op.space)}`,\n );\n assertObjectRefs(doc, obj, op.space);\n }\n let next: ModelObject[];\n if (op.indices && op.indices.length === op.objects.length) {\n // Positional insert: indices refer to the FINAL array, ascending —\n // exactly what a remove-objects inverse recorded. Out-of-range indices\n // clamp to append so a stale inverse still lands every object.\n next = [...existing];\n op.objects\n .map((obj, i) => ({ obj, at: op.indices![i] }))\n .sort((a, b) => a.at - b.at)\n .forEach(({ obj, at }) => next.splice(Math.min(at, next.length), 0, obj));\n } else {\n next = [...existing, ...op.objects];\n }\n return {\n document: setSpaceObjects(doc, op.space, next),\n inverse: {\n type: \"remove-objects\",\n space: op.space,\n ids: op.objects.map((o) => o.id),\n },\n };\n};\n\nconst applyUpdateObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n const previous: ModelObject[] = [];\n for (const obj of op.objects) {\n const prev = byId.get(obj.id);\n if (!prev)\n throw new OpError(\n \"unknown-object\",\n `Object ${obj.id} not found in ${spaceLabel(op.space)}`,\n );\n previous.push(prev);\n assertObjectRefs(doc, obj, op.space);\n }\n const patch = new Map(op.objects.map((o) => [o.id, o]));\n return {\n document: setSpaceObjects(\n doc,\n op.space,\n existing.map((o) => patch.get(o.id) ?? o),\n ),\n inverse: { type: \"update-objects\", space: op.space, objects: previous },\n };\n};\n\nconst applyRemoveObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n for (const id of op.ids) {\n if (!byId.has(id))\n throw new OpError(\n \"unknown-object\",\n `Object ${id} not found in ${spaceLabel(op.space)}`,\n );\n }\n const drop = new Set(op.ids);\n // Record removed objects with their ORIGINAL indices so the inverse\n // restores exact draw order (positional insert into the final array).\n const removed: ModelObject[] = [];\n const indices: number[] = [];\n existing.forEach((o, i) => {\n if (drop.has(o.id)) {\n removed.push(o);\n indices.push(i);\n }\n });\n return {\n document: setSpaceObjects(\n doc,\n op.space,\n existing.filter((o) => !drop.has(o.id)),\n ),\n inverse: {\n type: \"add-objects\",\n space: op.space,\n objects: removed,\n indices,\n },\n };\n};\n\nconst applyReorderObjects = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-objects\" }>,\n): ApplyResult => {\n const existing = getSpaceObjects(doc, op.space);\n const byId = new Map(existing.map((o) => [o.id, o]));\n const moving = new Set(op.ids);\n if (moving.size !== op.ids.length)\n throw new OpError(\"invalid-reorder\", `Duplicate ids in reorder`);\n const moved: ModelObject[] = op.ids.map((id) => {\n const obj = byId.get(id);\n if (!obj)\n throw new OpError(\n \"unknown-object\",\n `Object ${id} not found in ${spaceLabel(op.space)}`,\n );\n return obj;\n });\n const rest = existing.filter((o) => !moving.has(o.id));\n let at: number;\n const p = op.placement;\n if (p === \"back\") at = 0;\n else if (p === \"front\") at = rest.length;\n else {\n const refId = \"above\" in p ? p.above : p.below;\n if (moving.has(refId))\n throw new OpError(\n \"invalid-reorder\",\n `Reference object ${refId} is part of the moved set`,\n );\n const refIndex = rest.findIndex((o) => o.id === refId);\n if (refIndex === -1)\n throw new OpError(\n \"unknown-object\",\n `Reference object ${refId} not found in ${spaceLabel(op.space)}`,\n );\n at = \"above\" in p ? refIndex + 1 : refIndex;\n }\n return {\n document: setSpaceObjects(doc, op.space, [\n ...rest.slice(0, at),\n ...moved,\n ...rest.slice(at),\n ]),\n // Full previous order + \"back\" = explicit total order — exact restore.\n inverse: {\n type: \"reorder-objects\",\n space: op.space,\n ids: existing.map((o) => o.id),\n placement: \"back\",\n },\n };\n};\n\n// --- layer ops -------------------------------------------------------------\n\n/** Layer names are addressed by name (scripts, DXF) and DXF treats them\n * case-insensitively — no two layers may share one. Only new names are\n * checked: documents that already hold duplicates still load and edit. */\nconst assertLayerNameFree = (\n doc: LineaDocument,\n name: string,\n exceptId: string,\n): void => {\n const clash = doc.layers.find(\n (l) => l.id !== exceptId && l.name.toLowerCase() === name.toLowerCase(),\n );\n if (clash)\n throw new OpError(\n \"duplicate-name\",\n `A layer named \"${clash.name}\" already exists`,\n );\n};\n\nconst applyAddLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-layer\" }>,\n): ApplyResult => {\n if (doc.layers.some((l) => l.id === op.layer.id))\n throw new OpError(\"duplicate-id\", `Layer ${op.layer.id} already exists`);\n assertLayerNameFree(doc, op.layer.name, op.layer.id);\n const layers = [...doc.layers];\n layers.splice(op.index ?? layers.length, 0, op.layer);\n return {\n document: { ...doc, layers },\n inverse: { type: \"remove-layer\", id: op.layer.id },\n };\n};\n\nconst applyUpdateLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layer\" }>,\n): ApplyResult => {\n const prev = doc.layers.find((l) => l.id === op.layer.id);\n if (!prev)\n throw new OpError(\"unknown-layer\", `Layer ${op.layer.id} not found`);\n if (op.layer.name !== prev.name)\n assertLayerNameFree(doc, op.layer.name, op.layer.id);\n return {\n document: {\n ...doc,\n layers: doc.layers.map((l) => (l.id === op.layer.id ? op.layer : l)),\n },\n inverse: { type: \"update-layer\", layer: prev },\n };\n};\n\n/** How many objects, in every space, `match` accepts. */\nconst countObjects = (\n doc: LineaDocument,\n match: (o: ModelObject) => boolean,\n): number =>\n [doc.objects, ...doc.layouts.map((l) => l.objects)].reduce(\n (n, objs) => n + objs.filter(match).length,\n 0,\n );\n\nconst plural = (n: number, word: string) => `${n} ${word}${n === 1 ? \"\" : \"s\"}`;\n\nconst applyRemoveLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-layer\" }>,\n): ApplyResult => {\n const index = doc.layers.findIndex((l) => l.id === op.id);\n if (index === -1)\n throw new OpError(\"unknown-layer\", `Layer ${op.id} not found`);\n const prev = doc.layers[index];\n if (doc.layers.length === 1)\n throw new OpError(\"last-layer\", `Cannot remove the last layer`);\n if (doc.currentLayerId === op.id)\n throw new OpError(\n \"current-layer\",\n `Layer \"${prev.name}\" is the current layer — switch to another first`,\n );\n const users = countObjects(doc, (o) => o.layerId === op.id);\n if (users > 0)\n throw new OpError(\n \"layer-in-use\",\n `Layer \"${prev.name}\" still has ${plural(users, \"object\")} on it`,\n );\n return {\n document: { ...doc, layers: doc.layers.filter((l) => l.id !== op.id) },\n inverse: { type: \"add-layer\", layer: prev, index },\n };\n};\n\nconst applySetLayers = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-layers\" }>,\n): ApplyResult => {\n const ids = new Set(op.layers.map((l) => l.id));\n if (ids.size !== op.layers.length)\n throw new OpError(\"duplicate-id\", `Duplicate layer ids in set-layers`);\n if (!ids.has(doc.currentLayerId))\n throw new OpError(\n \"current-layer\",\n `set-layers would drop the current layer ${doc.currentLayerId}`,\n );\n const used = (objs: ModelObject[]) => objs.find((o) => !ids.has(o.layerId));\n const orphan =\n used(doc.objects) ?? doc.layouts.map((l) => used(l.objects)).find(Boolean);\n if (orphan)\n throw new OpError(\n \"layer-in-use\",\n `set-layers would orphan object ${orphan.id} (layer ${orphan.layerId})`,\n );\n return {\n document: { ...doc, layers: op.layers },\n inverse: { type: \"set-layers\", layers: doc.layers },\n };\n};\n\n/** Reorder an id-keyed collection to an explicit total order (same-set\n * validated: every current id exactly once, nothing added or dropped). */\nconst reorderById = <T extends { id: string }>(\n arr: T[],\n ids: string[],\n what: string,\n): T[] => {\n const byId = new Map(arr.map((x) => [x.id, x]));\n if (ids.length !== arr.length || new Set(ids).size !== ids.length)\n throw new OpError(\n \"invalid-reorder\",\n `Reorder must list every current ${what} id exactly once`,\n );\n return ids.map((id) => {\n const item = byId.get(id);\n if (!item) throw new OpError(\"invalid-reorder\", `Unknown ${what} id ${id}`);\n return item;\n });\n};\n\nconst applyReorderLayers = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-layers\" }>,\n): ApplyResult => ({\n document: { ...doc, layers: reorderById(doc.layers, op.ids, \"layer\") },\n inverse: { type: \"reorder-layers\", ids: doc.layers.map((l) => l.id) },\n});\n\nconst applySetCurrentLayer = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-current-layer\" }>,\n): ApplyResult => {\n if (!doc.layers.some((l) => l.id === op.id))\n throw new OpError(\"unknown-layer\", `Layer ${op.id} not found`);\n return {\n document: { ...doc, currentLayerId: op.id },\n inverse: { type: \"set-current-layer\", id: doc.currentLayerId },\n };\n};\n\n// --- document field ops ----------------------------------------------------\n\nconst applySetDimStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-dim-styles\" }>,\n): ApplyResult => ({\n document: { ...doc, dimStyles: op.dimStyles },\n inverse: { type: \"set-dim-styles\", dimStyles: doc.dimStyles },\n});\n\nconst applySetTextStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-text-styles\" }>,\n): ApplyResult => ({\n document: { ...doc, textStyles: op.textStyles },\n inverse: { type: \"set-text-styles\", textStyles: doc.textStyles },\n});\n\n// Shared array plumbing for the granular text/dim style trios. Dangling\n// styleId references are LEGAL by design (they resolve to the first style),\n// so remove needs no in-use check — only the schema's min-1 invariant.\n\nconst addStyleIn = <T extends { id: string }>(\n arr: T[],\n style: T,\n index: number | undefined,\n): T[] => {\n if (arr.some((s) => s.id === style.id))\n throw new OpError(\"duplicate-id\", `Style ${style.id} already exists`);\n const next = [...arr];\n // Out-of-range indices clamp to append so a stale inverse still lands.\n next.splice(Math.min(index ?? next.length, next.length), 0, style);\n return next;\n};\n\nconst updateStyleIn = <T extends { id: string }>(\n arr: T[],\n style: T,\n): { next: T[]; prev: T } => {\n const prev = arr.find((s) => s.id === style.id);\n if (!prev) throw new OpError(\"unknown-style\", `Style ${style.id} not found`);\n return { next: arr.map((s) => (s.id === style.id ? style : s)), prev };\n};\n\nconst removeStyleIn = <T extends { id: string }>(\n arr: T[],\n id: string,\n): { next: T[]; prev: T; index: number } => {\n const index = arr.findIndex((s) => s.id === id);\n if (index === -1) throw new OpError(\"unknown-style\", `Style ${id} not found`);\n if (arr.length === 1)\n throw new OpError(\"last-style\", `Cannot remove the last style`);\n return { next: arr.filter((s) => s.id !== id), prev: arr[index], index };\n};\n\nconst applyAddTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-text-style\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n textStyles: addStyleIn(doc.textStyles, op.style, op.index),\n },\n inverse: { type: \"remove-text-style\", id: op.style.id },\n});\n\nconst applyUpdateTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-text-style\" }>,\n): ApplyResult => {\n const { next, prev } = updateStyleIn(doc.textStyles, op.style);\n return {\n document: { ...doc, textStyles: next },\n inverse: { type: \"update-text-style\", style: prev },\n };\n};\n\n/** Refuse removing a style objects resolve to — by `styleId`, or as the\n * first style that unstyled (and dangling) references fall back to. */\nconst assertStyleUnused = (users: number, name: string): void => {\n if (users > 0)\n throw new OpError(\n \"style-in-use\",\n `Style \"${name}\" is used by ${plural(users, \"object\")} — restyle them first`,\n );\n};\n\n/** Objects (every space) whose text style resolves to `id`. */\nexport const textStyleUsers = (doc: LineaDocument, id: string): number =>\n countObjects(doc, (o) => {\n if (o.type === \"text\") return textStyleFor(o, doc.textStyles).id === id;\n if (o.type !== \"table\") return false;\n return (\n textStyleFor(o, doc.textStyles).id === id ||\n o.cells.some((row) => row.some((c) => c.styleId === id))\n );\n });\n\nconst applyRemoveTextStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-text-style\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeStyleIn(doc.textStyles, op.id);\n assertStyleUnused(textStyleUsers(doc, op.id), prev.name);\n return {\n document: { ...doc, textStyles: next },\n inverse: { type: \"add-text-style\", style: prev, index },\n };\n};\n\nconst applyReorderTextStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-text-styles\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n textStyles: reorderById(doc.textStyles, op.ids, \"text style\"),\n },\n inverse: {\n type: \"reorder-text-styles\",\n ids: doc.textStyles.map((s) => s.id),\n },\n});\n\nconst applyReorderDimStyles = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-dim-styles\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n dimStyles: reorderById(doc.dimStyles, op.ids, \"dim style\"),\n },\n inverse: { type: \"reorder-dim-styles\", ids: doc.dimStyles.map((s) => s.id) },\n});\n\nconst applyAddDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-dim-style\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n dimStyles: addStyleIn(doc.dimStyles, op.style, op.index),\n },\n inverse: { type: \"remove-dim-style\", id: op.style.id },\n});\n\nconst applyUpdateDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-dim-style\" }>,\n): ApplyResult => {\n const { next, prev } = updateStyleIn(doc.dimStyles, op.style);\n return {\n document: { ...doc, dimStyles: next },\n inverse: { type: \"update-dim-style\", style: prev },\n };\n};\n\n/** Dimensions (every space) whose dim style resolves to `id`. */\nexport const dimStyleUsers = (doc: LineaDocument, id: string): number =>\n countObjects(\n doc,\n (o) => o.type === \"dimension\" && dimStyleFor(o, doc.dimStyles).id === id,\n );\n\nconst applyRemoveDimStyle = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-dim-style\" }>,\n): ApplyResult => {\n const { next, prev, index } = removeStyleIn(doc.dimStyles, op.id);\n assertStyleUnused(dimStyleUsers(doc, op.id), prev.name);\n return {\n document: { ...doc, dimStyles: next },\n inverse: { type: \"add-dim-style\", style: prev, index },\n };\n};\n\nconst applySetDocumentCommands = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-document-commands\" }>,\n): ApplyResult => ({\n document: { ...doc, commands: op.commands },\n inverse: { type: \"set-document-commands\", commands: doc.commands },\n});\n\nconst applySetBlockDefinitions = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-block-definitions\" }>,\n): ApplyResult => ({\n document: { ...doc, blockDefinitions: op.blockDefinitions },\n inverse: {\n type: \"set-block-definitions\",\n blockDefinitions: doc.blockDefinitions,\n },\n});\n\n// Shared array plumbing for the content-addressed module trios (block\n// definitions and document commands — both opaque source-string arrays; see\n// the addressing rationale in types.ts).\n\nconst addModuleIn = (\n arr: string[],\n source: string,\n index: number | undefined,\n what: string,\n): string[] => {\n if (arr.includes(source))\n throw new OpError(\n \"duplicate-id\",\n `This exact ${what} module is already in the document`,\n );\n const next = [...arr];\n next.splice(Math.min(index ?? next.length, next.length), 0, source);\n return next;\n};\n\nconst updateModuleIn = (\n arr: string[],\n prevSource: string,\n source: string,\n what: string,\n): string[] => {\n const at = arr.indexOf(prevSource);\n if (at === -1)\n throw new OpError(\n \"unknown-module\",\n `The ${what} module targeted by this update is not in the document (stale source)`,\n );\n if (source !== prevSource && arr.includes(source))\n throw new OpError(\n \"duplicate-id\",\n `This exact ${what} module is already in the document`,\n );\n return arr.map((s, i) => (i === at ? source : s));\n};\n\nconst removeModuleIn = (\n arr: string[],\n source: string,\n what: string,\n): { next: string[]; index: number } => {\n const index = arr.indexOf(source);\n if (index === -1)\n throw new OpError(\n \"unknown-module\",\n `The ${what} module to remove is not in the document (stale source)`,\n );\n return { next: arr.filter((_, i) => i !== index), index };\n};\n\n/** Same-multiset reorder for module sources: identical strings are\n * interchangeable, so sorted-equality is an exact check. */\nconst reorderModulesIn = (\n arr: string[],\n sources: string[],\n what: string,\n): string[] => {\n if (\n sources.length !== arr.length ||\n [...sources].sort().join(\"\") !== [...arr].sort().join(\"\")\n )\n throw new OpError(\n \"invalid-reorder\",\n `Reorder must list every current ${what} module source exactly once (stale set)`,\n );\n return sources;\n};\n\nconst applyReorderBlockDefinitions = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-block-definitions\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: reorderModulesIn(\n doc.blockDefinitions,\n op.sources,\n \"block\",\n ),\n },\n inverse: {\n type: \"reorder-block-definitions\",\n sources: doc.blockDefinitions,\n },\n});\n\nconst applyReorderDocumentCommands = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-document-commands\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: reorderModulesIn(doc.commands, op.sources, \"command\"),\n },\n inverse: { type: \"reorder-document-commands\", sources: doc.commands },\n});\n\nconst applyAddBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-block-definition\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: addModuleIn(\n doc.blockDefinitions,\n op.source,\n op.index,\n \"block\",\n ),\n },\n inverse: { type: \"remove-block-definition\", source: op.source },\n});\n\nconst applyUpdateBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-block-definition\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n blockDefinitions: updateModuleIn(\n doc.blockDefinitions,\n op.prevSource,\n op.source,\n \"block\",\n ),\n },\n inverse: {\n type: \"update-block-definition\",\n prevSource: op.source,\n source: op.prevSource,\n },\n});\n\n/** Why a block module can't go: placed instances (model or any layout) or\n * another module declaring it as a dependency — the Library's rule, here so\n * scripts, agents and the SDK can't orphan instances either. A module whose\n * id another module in the document still defines is free to go. */\nconst assertBlockRemovable = (doc: LineaDocument, source: string): void => {\n const id = blockScriptId(source);\n if (id === undefined) return;\n const others = doc.blockDefinitions.filter((s) => s !== source);\n if (others.some((s) => blockScriptId(s) === id)) return;\n const placed = countObjects(\n doc,\n (o) => o.type === \"block\" && o.definitionId === id,\n );\n if (placed > 0)\n throw new OpError(\n \"definition-in-use\",\n `Block \"${id}\" still has ${plural(placed, \"placed instance\")} — explode or delete them first`,\n );\n for (const s of others) {\n const m = getBlockMetaResult(s);\n if (m.ok && (m.meta.dependencies ?? []).includes(id))\n throw new OpError(\n \"definition-in-use\",\n `Block \"${id}\" is required by block \"${m.meta.id}\" (its dependencies)`,\n );\n }\n};\n\nconst applyRemoveBlockDefinition = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-block-definition\" }>,\n): ApplyResult => {\n assertBlockRemovable(doc, op.source);\n const { next, index } = removeModuleIn(\n doc.blockDefinitions,\n op.source,\n \"block\",\n );\n return {\n document: { ...doc, blockDefinitions: next },\n inverse: { type: \"add-block-definition\", source: op.source, index },\n };\n};\n\nconst applyAddDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-document-command\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: addModuleIn(doc.commands, op.source, op.index, \"command\"),\n },\n inverse: { type: \"remove-document-command\", source: op.source },\n});\n\nconst applyUpdateDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-document-command\" }>,\n): ApplyResult => ({\n document: {\n ...doc,\n commands: updateModuleIn(doc.commands, op.prevSource, op.source, \"command\"),\n },\n inverse: {\n type: \"update-document-command\",\n prevSource: op.source,\n source: op.prevSource,\n },\n});\n\nconst applyRemoveDocumentCommand = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-document-command\" }>,\n): ApplyResult => {\n const { next, index } = removeModuleIn(doc.commands, op.source, \"command\");\n return {\n document: { ...doc, commands: next },\n inverse: { type: \"add-document-command\", source: op.source, index },\n };\n};\n\n// --- asset ops ---------------------------------------------------------------\n\nconst applySetAsset = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"set-asset\" }>,\n): ApplyResult => {\n const prev = doc.assets[op.id];\n return {\n document: { ...doc, assets: { ...doc.assets, [op.id]: op.dataUrl } },\n inverse:\n prev !== undefined\n ? { type: \"set-asset\", id: op.id, dataUrl: prev }\n : { type: \"remove-asset\", id: op.id },\n };\n};\n\nconst assetInUse = (doc: LineaDocument, id: string): boolean => {\n const used = (objs: ModelObject[]) =>\n objs.some((o) => o.type === \"image\" && o.assetId === id);\n return used(doc.objects) || doc.layouts.some((l) => used(l.objects));\n};\n\nconst applyRemoveAsset = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-asset\" }>,\n): ApplyResult => {\n const prev = doc.assets[op.id];\n if (prev === undefined)\n throw new OpError(\"unknown-asset\", `Asset ${op.id} not found`);\n if (assetInUse(doc, op.id))\n throw new OpError(\n \"asset-in-use\",\n `Asset ${op.id} is still referenced by an image object`,\n );\n const assets = { ...doc.assets };\n delete assets[op.id];\n return {\n document: { ...doc, assets },\n inverse: { type: \"set-asset\", id: op.id, dataUrl: prev },\n };\n};\n\n// --- layout ops ------------------------------------------------------------\n\nconst applyAddLayout = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"add-layout\" }>,\n): ApplyResult => {\n if (doc.layouts.some((l) => l.id === op.layout.id))\n throw new OpError(\"duplicate-layout\", `Layout ${op.layout.id} exists`);\n const layouts = [...doc.layouts];\n layouts.splice(op.index ?? layouts.length, 0, op.layout);\n return {\n document: { ...doc, layouts },\n inverse: { type: \"remove-layout\", id: op.layout.id },\n };\n};\n\nconst applyRemoveLayout = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"remove-layout\" }>,\n): ApplyResult => {\n const index = doc.layouts.findIndex((l) => l.id === op.id);\n if (index === -1)\n throw new OpError(\"unknown-layout\", `Layout ${op.id} not found`);\n const prev = doc.layouts[index];\n return {\n document: { ...doc, layouts: doc.layouts.filter((l) => l.id !== op.id) },\n inverse: { type: \"add-layout\", layout: prev, index },\n };\n};\n\nconst applyReorderLayouts = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"reorder-layouts\" }>,\n): ApplyResult => ({\n document: { ...doc, layouts: reorderById(doc.layouts, op.ids, \"layout\") },\n inverse: { type: \"reorder-layouts\", ids: doc.layouts.map((l) => l.id) },\n});\n\nconst applyUpdateLayoutMeta = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layout-meta\" }>,\n): ApplyResult => {\n const prev = doc.layouts.find((l) => l.id === op.id);\n if (!prev) throw new OpError(\"unknown-layout\", `Layout ${op.id} not found`);\n const next: PaperLayout = {\n ...prev,\n ...(op.name !== undefined ? { name: op.name } : {}),\n ...(op.sheet !== undefined ? { sheet: op.sheet } : {}),\n ...(op.printPalette !== undefined ? { printPalette: op.printPalette } : {}),\n };\n return {\n document: {\n ...doc,\n layouts: doc.layouts.map((l) => (l.id === op.id ? next : l)),\n },\n inverse: {\n type: \"update-layout-meta\",\n id: op.id,\n name: prev.name,\n sheet: prev.sheet,\n printPalette: prev.printPalette,\n },\n };\n};\n\nconst applyUpdateLayouts = (\n doc: LineaDocument,\n op: Extract<Operation, { type: \"update-layouts\" }>,\n): ApplyResult => {\n const previous: PaperLayout[] = [];\n for (const layout of op.layouts) {\n const prev = doc.layouts.find((l) => l.id === layout.id);\n if (!prev)\n throw new OpError(\"unknown-layout\", `Layout ${layout.id} not found`);\n previous.push(prev);\n for (const obj of layout.objects)\n assertObjectRefs(doc, obj, { layoutId: layout.id });\n }\n const byId = new Map(op.layouts.map((l) => [l.id, l]));\n return {\n document: {\n ...doc,\n layouts: doc.layouts.map((l) => byId.get(l.id) ?? l),\n },\n inverse: { type: \"update-layouts\", layouts: previous },\n };\n};\n\n/**\n * Validate + apply one operation against full document state. Returns the\n * next document and the inverse op. Throws `OpError` on any integrity\n * violation, leaving `doc` untouched (it is never mutated).\n */\nexport const applyOperation = (\n doc: LineaDocument,\n op: Operation,\n): ApplyResult => {\n switch (op.type) {\n case \"add-objects\":\n return applyAddObjects(doc, op);\n case \"update-objects\":\n return applyUpdateObjects(doc, op);\n case \"remove-objects\":\n return applyRemoveObjects(doc, op);\n case \"reorder-objects\":\n return applyReorderObjects(doc, op);\n case \"add-layer\":\n return applyAddLayer(doc, op);\n case \"update-layer\":\n return applyUpdateLayer(doc, op);\n case \"remove-layer\":\n return applyRemoveLayer(doc, op);\n case \"set-layers\":\n return applySetLayers(doc, op);\n case \"reorder-layers\":\n return applyReorderLayers(doc, op);\n case \"set-current-layer\":\n return applySetCurrentLayer(doc, op);\n case \"set-dim-styles\":\n return applySetDimStyles(doc, op);\n case \"add-dim-style\":\n return applyAddDimStyle(doc, op);\n case \"update-dim-style\":\n return applyUpdateDimStyle(doc, op);\n case \"remove-dim-style\":\n return applyRemoveDimStyle(doc, op);\n case \"reorder-dim-styles\":\n return applyReorderDimStyles(doc, op);\n case \"set-text-styles\":\n return applySetTextStyles(doc, op);\n case \"add-text-style\":\n return applyAddTextStyle(doc, op);\n case \"update-text-style\":\n return applyUpdateTextStyle(doc, op);\n case \"remove-text-style\":\n return applyRemoveTextStyle(doc, op);\n case \"reorder-text-styles\":\n return applyReorderTextStyles(doc, op);\n case \"set-block-definitions\":\n return applySetBlockDefinitions(doc, op);\n case \"add-block-definition\":\n return applyAddBlockDefinition(doc, op);\n case \"update-block-definition\":\n return applyUpdateBlockDefinition(doc, op);\n case \"remove-block-definition\":\n return applyRemoveBlockDefinition(doc, op);\n case \"reorder-block-definitions\":\n return applyReorderBlockDefinitions(doc, op);\n case \"set-document-commands\":\n return applySetDocumentCommands(doc, op);\n case \"add-document-command\":\n return applyAddDocumentCommand(doc, op);\n case \"update-document-command\":\n return applyUpdateDocumentCommand(doc, op);\n case \"remove-document-command\":\n return applyRemoveDocumentCommand(doc, op);\n case \"reorder-document-commands\":\n return applyReorderDocumentCommands(doc, op);\n case \"set-asset\":\n return applySetAsset(doc, op);\n case \"remove-asset\":\n return applyRemoveAsset(doc, op);\n case \"add-layout\":\n return applyAddLayout(doc, op);\n case \"remove-layout\":\n return applyRemoveLayout(doc, op);\n case \"reorder-layouts\":\n return applyReorderLayouts(doc, op);\n case \"update-layout-meta\":\n return applyUpdateLayoutMeta(doc, op);\n case \"update-layouts\":\n return applyUpdateLayouts(doc, op);\n }\n};\n\n/** Which object ids an op invalidates (`null` = everything; `[]` = nothing). */\nexport const invalidationIds = (op: Operation): string[] | null => {\n switch (op.type) {\n case \"add-objects\":\n case \"update-objects\":\n return op.objects.map((o) => o.id);\n case \"remove-objects\":\n return op.ids;\n case \"set-current-layer\":\n case \"set-document-commands\":\n case \"add-document-command\":\n case \"update-document-command\":\n case \"remove-document-command\":\n case \"reorder-document-commands\":\n return []; // no rendered change\n case \"add-layer\": // fresh id — validation guarantees nothing references it\n case \"remove-layer\": // validation guarantees the layer had no members\n case \"reorder-layers\": // layer order is panel display order only\n case \"reorder-block-definitions\": // library display order only\n case \"reorder-layouts\": // PDF page order — no per-object cache depends on it\n return [];\n case \"reorder-objects\":\n // Z-order only: per-object caches (snap entries, block eval) don't\n // depend on order; repaint comes from the document change itself.\n return [];\n default:\n // layer/style/blockDefs/layout changes affect everything. Style ADDS\n // included: a dangling styleId legally resolves to the first style, so\n // adding the missing style can restyle existing text/dimensions.\n return null;\n }\n};\n","// Diff whole-collection replacements into granular operations. The editor's\n// and SDK's \"set the whole array\" surfaces stay ergonomic for callers, but\n// what goes on the wire (and into undo history) are precise per-item ops —\n// a concurrent edit to a DIFFERENT item of the same collection survives,\n// where a coarse set-op would silently clobber it. The decomposition is\n// total: updates → removes → reorder of the survivors (when their relative\n// order changed) → indexed adds reconstruct `next` exactly. The legacy\n// set-* ops are only emitted for arrays with duplicate ids/sources, which\n// nothing granular can express. See docs/granular-ops.md.\n\nimport { blockScriptId } from \"../extensions/evalBlock\";\nimport type { Layer, LineaDocument } from \"../model/document\";\nimport type { DimStyle, ModelObject, TextStyle } from \"../model/objects\";\nimport type { OpSpace, Operation } from \"./types\";\n\nconst sameJson = (a: unknown, b: unknown): boolean =>\n a === b || JSON.stringify(a) === JSON.stringify(b);\n\n/** Id-keyed collection diff. `added` indices refer to the FINAL array. */\nconst diffById = <T extends { id: string }>(\n prev: readonly T[],\n next: readonly T[],\n) => {\n const prevById = new Map(prev.map((x) => [x.id, x]));\n const nextIds = new Set(next.map((x) => x.id));\n const removed = prev.filter((x) => !nextIds.has(x.id));\n const added: { item: T; index: number }[] = [];\n const updated: T[] = [];\n next.forEach((x, i) => {\n const p = prevById.get(x.id);\n if (!p) added.push({ item: x, index: i });\n else if (!sameJson(p, x)) updated.push(x);\n });\n const surviving = (arr: readonly T[], has: (id: string) => boolean) =>\n arr.filter((x) => has(x.id)).map((x) => x.id);\n /** Survivor ids in `next` order — the reorder payload when it changed. */\n const survivorOrder = surviving(next, (id) => prevById.has(id));\n const orderChanged =\n surviving(prev, (id) => nextIds.has(id)).join(\" \") !==\n survivorOrder.join(\" \");\n const duplicateIds =\n prevById.size !== prev.length || nextIds.size !== next.length;\n return { added, updated, removed, orderChanged, survivorOrder, duplicateIds };\n};\n\nexport const diffLayerOps = (\n prev: readonly Layer[],\n next: readonly Layer[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return [{ type: \"set-layers\", layers: [...next] }];\n const ops: Operation[] = d.updated.map((layer) => ({\n type: \"update-layer\",\n layer,\n }));\n for (const l of d.removed) ops.push({ type: \"remove-layer\", id: l.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-layers\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-layer\", layer: item, index });\n return ops;\n};\n\nexport const diffTextStyleOps = (\n prev: readonly TextStyle[],\n next: readonly TextStyle[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds)\n return [{ type: \"set-text-styles\", textStyles: [...next] }];\n const ops: Operation[] = d.updated.map((style) => ({\n type: \"update-text-style\",\n style,\n }));\n for (const s of d.removed) ops.push({ type: \"remove-text-style\", id: s.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-text-styles\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-text-style\", style: item, index });\n return ops;\n};\n\nexport const diffDimStyleOps = (\n prev: readonly DimStyle[],\n next: readonly DimStyle[],\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return [{ type: \"set-dim-styles\", dimStyles: [...next] }];\n const ops: Operation[] = d.updated.map((style) => ({\n type: \"update-dim-style\",\n style,\n }));\n for (const s of d.removed) ops.push({ type: \"remove-dim-style\", id: s.id });\n if (d.orderChanged)\n ops.push({ type: \"reorder-dim-styles\", ids: d.survivorOrder });\n for (const { item, index } of d.added)\n ops.push({ type: \"add-dim-style\", style: item, index });\n return ops;\n};\n\n/**\n * Diff two module-source arrays (block definitions or document commands)\n * into content-addressed ops. The single in-place edit — one source replaced\n * at the same slot, everything else untouched — becomes ONE update op (the\n * Monaco-save / marketplace-upgrade hot path). Everything else decomposes\n * into removes → survivor reorder (when needed) → indexed adds. Arrays with\n * duplicate sources (which content addressing cannot tell apart) fall back\n * to the legacy set op.\n */\nexport const diffModuleOps = (\n prev: readonly string[],\n next: readonly string[],\n field: \"blockDefinitions\" | \"commands\",\n): Operation[] => {\n const block = field === \"blockDefinitions\";\n const prevSet = new Set(prev);\n const nextSet = new Set(next);\n if (prevSet.size !== prev.length || nextSet.size !== next.length)\n return [\n block\n ? { type: \"set-block-definitions\", blockDefinitions: [...next] }\n : { type: \"set-document-commands\", commands: [...next] },\n ];\n if (block) {\n // A removed and an added module with the same block id is an in-place\n // REPLACE (edit, import by id), not delete + add: as an update it keeps\n // its slot and never trips remove-block-definition's in-use rule.\n const addedById = new Map<string, string>();\n for (const s of next)\n if (!prevSet.has(s)) {\n const id = blockScriptId(s);\n if (id !== undefined && !addedById.has(id)) addedById.set(id, s);\n }\n const updates: Operation[] = [];\n const replaced = prev.map((s) => {\n if (nextSet.has(s)) return s;\n const id = blockScriptId(s);\n const to = id === undefined ? undefined : addedById.get(id);\n if (to === undefined || id === undefined) return s;\n addedById.delete(id);\n updates.push({\n type: \"update-block-definition\",\n prevSource: s,\n source: to,\n });\n return to;\n });\n if (updates.length > 0)\n return [...updates, ...diffModuleOps(replaced, next, field)];\n }\n const removed = prev.filter((s) => !nextSet.has(s));\n const added: { source: string; index: number }[] = [];\n next.forEach((s, i) => {\n if (!prevSet.has(s)) added.push({ source: s, index: i });\n });\n const survivorOrder = next.filter((s) => prevSet.has(s));\n const orderChanged =\n prev.filter((s) => nextSet.has(s)).join(\" \") !== survivorOrder.join(\" \");\n if (\n !orderChanged &&\n removed.length === 1 &&\n added.length === 1 &&\n added[0].index === prev.indexOf(removed[0])\n )\n return [\n block\n ? {\n type: \"update-block-definition\",\n prevSource: removed[0],\n source: added[0].source,\n }\n : {\n type: \"update-document-command\",\n prevSource: removed[0],\n source: added[0].source,\n },\n ];\n const ops: Operation[] = removed.map((source) =>\n block\n ? { type: \"remove-block-definition\", source }\n : { type: \"remove-document-command\", source },\n );\n if (orderChanged)\n ops.push(\n block\n ? { type: \"reorder-block-definitions\", sources: survivorOrder }\n : { type: \"reorder-document-commands\", sources: survivorOrder },\n );\n for (const { source, index } of added)\n ops.push(\n block\n ? { type: \"add-block-definition\", source, index }\n : { type: \"add-document-command\", source, index },\n );\n return ops;\n};\n\n/**\n * Diff one space's object array into granular object ops: updates →\n * removes → a reorder of the survivors (when their relative order changed)\n * → indexed adds. Arrays with duplicate ids fall back to a remove-all +\n * add-all pair (nothing granular can express them).\n */\nexport const diffObjectOps = (\n prev: readonly ModelObject[],\n next: readonly ModelObject[],\n space: OpSpace,\n): Operation[] => {\n const d = diffById(prev, next);\n if (d.duplicateIds) {\n const ops: Operation[] = [];\n if (prev.length > 0)\n ops.push({ type: \"remove-objects\", space, ids: prev.map((o) => o.id) });\n if (next.length > 0)\n ops.push({ type: \"add-objects\", space, objects: [...next] });\n return ops;\n }\n const ops: Operation[] = [];\n if (d.updated.length > 0)\n ops.push({ type: \"update-objects\", space, objects: d.updated });\n if (d.removed.length > 0)\n ops.push({\n type: \"remove-objects\",\n space,\n ids: d.removed.map((o) => o.id),\n });\n if (d.orderChanged && d.survivorOrder.length > 0)\n ops.push({\n type: \"reorder-objects\",\n space,\n ids: d.survivorOrder,\n placement: \"back\",\n });\n if (d.added.length > 0)\n ops.push({\n type: \"add-objects\",\n space,\n objects: d.added.map((a) => a.item),\n indices: d.added.map((a) => a.index),\n });\n return ops;\n};\n\n/**\n * Granular ops for an id-keyed resource collection (layers, styles), split\n * into the phase that must run BEFORE dependents change (updates + adds —\n * objects may start referencing the new items) and the phase that must run\n * AFTER (removes — nothing references them any more — plus one reorder when\n * the order the two phases leave behind differs from `next`).\n */\nconst phasedResourceOps = <T extends { id: string }>(\n prev: readonly T[],\n next: readonly T[],\n make: {\n update(item: T): Operation;\n add(item: T, index: number): Operation;\n remove(id: string): Operation;\n reorder(ids: string[]): Operation;\n /** Legacy whole-array op for arrays with duplicate ids. */\n set(items: T[]): Operation;\n },\n): { before: Operation[]; after: Operation[] } => {\n const d = diffById(prev, next);\n if (d.duplicateIds) return { before: [], after: [make.set([...next])] };\n const before: Operation[] = d.updated.map((item) => make.update(item));\n for (const { item, index } of d.added) before.push(make.add(item, index));\n const after: Operation[] = d.removed.map((r) => make.remove(r.id));\n // Adds land at their FINAL index while removed items are still present, so\n // simulate what the two phases leave behind and fix the order if needed.\n const order = prev.map((x) => x.id);\n for (const { item, index } of d.added) order.splice(index, 0, item.id);\n const gone = new Set(d.removed.map((r) => r.id));\n const left = order.filter((id) => !gone.has(id)).join(\" \");\n const target = next.map((x) => x.id);\n if (left !== target.join(\" \")) after.push(make.reorder(target));\n return { before, after };\n};\n\n/**\n * Diff two whole documents into ONE op batch that turns `prev` into `next`\n * — the wire/history-shaped replacement for a wholesale document load. Ops\n * are ordered so referential integrity holds at every step: resources\n * (layers, styles, modules, assets) are added before the objects that use\n * them and removed after; existing layouts are patched by meta + a\n * per-space object diff, missing ones removed, new ones added whole. The\n * document id is NOT an op (identity is the sync scope itself) and must\n * match.\n */\nexport const diffDocumentOps = (\n prev: LineaDocument,\n next: LineaDocument,\n): Operation[] => {\n if (prev.id !== next.id)\n throw new Error(\n `diffDocumentOps: document id mismatch (\"${prev.id}\" vs \"${next.id}\")`,\n );\n const layers = phasedResourceOps(prev.layers, next.layers, {\n update: (layer) => ({ type: \"update-layer\", layer }),\n add: (layer, index) => ({ type: \"add-layer\", layer, index }),\n remove: (id) => ({ type: \"remove-layer\", id }),\n reorder: (ids) => ({ type: \"reorder-layers\", ids }),\n set: (layers) => ({ type: \"set-layers\", layers }),\n });\n const textStyles = phasedResourceOps(prev.textStyles, next.textStyles, {\n update: (style) => ({ type: \"update-text-style\", style }),\n add: (style, index) => ({ type: \"add-text-style\", style, index }),\n remove: (id) => ({ type: \"remove-text-style\", id }),\n reorder: (ids) => ({ type: \"reorder-text-styles\", ids }),\n set: (textStyles) => ({ type: \"set-text-styles\", textStyles }),\n });\n const dimStyles = phasedResourceOps(prev.dimStyles, next.dimStyles, {\n update: (style) => ({ type: \"update-dim-style\", style }),\n add: (style, index) => ({ type: \"add-dim-style\", style, index }),\n remove: (id) => ({ type: \"remove-dim-style\", id }),\n reorder: (ids) => ({ type: \"reorder-dim-styles\", ids }),\n set: (dimStyles) => ({ type: \"set-dim-styles\", dimStyles }),\n });\n\n const ops: Operation[] = [];\n ops.push(...layers.before, ...textStyles.before, ...dimStyles.before);\n ops.push(\n ...diffModuleOps(\n prev.blockDefinitions,\n next.blockDefinitions,\n \"blockDefinitions\",\n ),\n ...diffModuleOps(prev.commands, next.commands, \"commands\"),\n );\n for (const [id, dataUrl] of Object.entries(next.assets))\n if (prev.assets[id] !== dataUrl)\n ops.push({ type: \"set-asset\", id, dataUrl });\n\n // Layouts: survivors by meta patch + object diff on their own space, then\n // removes → survivor reorder → indexed adds (the same decomposition as\n // diffObjectOps, so the result is exactly `next`).\n const prevLayouts = new Map(prev.layouts.map((l) => [l.id, l]));\n const nextLayoutIds = new Set(next.layouts.map((l) => l.id));\n for (const layout of next.layouts) {\n const before = prevLayouts.get(layout.id);\n if (!before) continue;\n const patch: Record<string, unknown> = {};\n if (before.name !== layout.name) patch.name = layout.name;\n if (!sameJson(before.sheet, layout.sheet)) patch.sheet = layout.sheet;\n if (before.printPalette !== layout.printPalette)\n patch.printPalette = layout.printPalette;\n if (Object.keys(patch).length > 0)\n ops.push({ type: \"update-layout-meta\", id: layout.id, ...patch });\n ops.push(\n ...diffObjectOps(before.objects, layout.objects, {\n layoutId: layout.id,\n }),\n );\n }\n ops.push(...diffObjectOps(prev.objects, next.objects, \"model\"));\n for (const l of prev.layouts)\n if (!nextLayoutIds.has(l.id)) ops.push({ type: \"remove-layout\", id: l.id });\n const survivors = next.layouts.filter((l) => prevLayouts.has(l.id));\n if (\n survivors.length > 0 &&\n prev.layouts\n .filter((l) => nextLayoutIds.has(l.id))\n .map((l) => l.id)\n .join(\" \") !== survivors.map((l) => l.id).join(\" \")\n )\n ops.push({ type: \"reorder-layouts\", ids: survivors.map((l) => l.id) });\n next.layouts.forEach((layout, index) => {\n if (!prevLayouts.has(layout.id))\n ops.push({ type: \"add-layout\", layout, index });\n });\n\n // Removals, now that nothing references them.\n for (const id of Object.keys(prev.assets))\n if (!(id in next.assets)) ops.push({ type: \"remove-asset\", id });\n if (prev.currentLayerId !== next.currentLayerId)\n ops.push({ type: \"set-current-layer\", id: next.currentLayerId });\n ops.push(...dimStyles.after, ...textStyles.after, ...layers.after);\n return ops;\n};\n","// DocumentKernel — the stateful wrapper around applyOperation. Holds a\n// LineaDocument plus the id/type indexes for the active space, fires cache\n// invalidation (block eval + any subscriber), and returns inverse ops. This\n// is what the editor's modelStore will delegate to; the cloud server uses the\n// pure applyOperation directly. See docs/kernel-op-layer.md.\n\nimport type { Layer, LineaDocument } from \"../model/document\";\nimport type { ModelObject, ModelObjectType } from \"../model/objects\";\nimport {\n expandWithBlockDependents,\n invalidateBlockCache,\n} from \"../extensions/evalBlock\";\nimport { applyOperation, invalidationIds } from \"./apply\";\nimport type { OpSpace, Operation } from \"./types\";\n\nexport type InvalidationListener = (ids: string[] | null) => void;\n\nexport class DocumentKernel {\n private doc: LineaDocument;\n private activeSpace: OpSpace = \"model\";\n private idIndex = new Map<string, ModelObject>();\n private typeIndex = new Map<ModelObjectType, Set<string>>();\n private listeners = new Set<InvalidationListener>();\n\n constructor(doc: LineaDocument) {\n this.doc = doc;\n this.rebuildIndexes();\n }\n\n get document(): LineaDocument {\n return this.doc;\n }\n\n get space(): OpSpace {\n return this.activeSpace;\n }\n\n /** Replace the whole document (file open / new). Rebuilds, invalidates all. */\n load(doc: LineaDocument): void {\n this.doc = doc;\n this.rebuildIndexes();\n this.invalidate(null);\n }\n\n /** Switch the active space the indexes target (model or a layout). */\n setActiveSpace(space: OpSpace): void {\n this.activeSpace = space;\n this.rebuildIndexes();\n this.invalidate(null);\n }\n\n onInvalidate(fn: InvalidationListener): () => void {\n this.listeners.add(fn);\n return () => this.listeners.delete(fn);\n }\n\n getObject(id: string): ModelObject | undefined {\n return this.idIndex.get(id);\n }\n\n getObjectsByType<T extends ModelObjectType>(\n type: T,\n ): Extract<ModelObject, { type: T }>[] {\n const ids = this.typeIndex.get(type);\n if (!ids) return [];\n const out: Extract<ModelObject, { type: T }>[] = [];\n for (const id of ids) {\n const obj = this.idIndex.get(id);\n if (obj) out.push(obj as Extract<ModelObject, { type: T }>);\n }\n return out;\n }\n\n getLayer(id: string): Layer | undefined {\n return this.doc.layers.find((l) => l.id === id);\n }\n\n /** Objects of the active space (the index source). */\n activeObjects(): ModelObject[] {\n const space = this.activeSpace;\n if (space === \"model\") return this.doc.objects;\n return this.doc.layouts.find((l) => l.id === space.layoutId)?.objects ?? [];\n }\n\n /**\n * Validate + apply one op, refresh indexes/caches, return the INVERSE op.\n * Throws `OpError` (document untouched) on an integrity violation.\n */\n apply(op: Operation): Operation {\n const { document, inverse } = applyOperation(this.doc, op);\n this.doc = document;\n this.reindexForOp(op);\n this.invalidate(invalidationIds(op));\n return inverse;\n }\n\n /**\n * Apply a batch: validates + applies in order; on any `OpError` rolls the\n * document back to the pre-batch snapshot and rethrows (nothing partially\n * applied). Returns inverse ops in REVERSE order, so applying them in turn\n * undoes the whole batch.\n */\n applyMany(ops: Operation[]): Operation[] {\n const snapshot = this.doc;\n const inverses: Operation[] = [];\n try {\n for (const op of ops) inverses.push(this.apply(op));\n } catch (e) {\n this.doc = snapshot;\n this.rebuildIndexes();\n this.invalidate(null);\n throw e;\n }\n return inverses.reverse();\n }\n\n private rebuildIndexes(): void {\n this.idIndex.clear();\n this.typeIndex.clear();\n for (const obj of this.activeObjects()) this.indexAdd(obj);\n }\n\n private indexAdd(obj: ModelObject): void {\n this.idIndex.set(obj.id, obj);\n let bucket = this.typeIndex.get(obj.type);\n if (!bucket) {\n bucket = new Set();\n this.typeIndex.set(obj.type, bucket);\n }\n bucket.add(obj.id);\n }\n\n private indexRemoveById(id: string): void {\n const prev = this.idIndex.get(id);\n if (!prev) return;\n this.idIndex.delete(id);\n this.typeIndex.get(prev.type)?.delete(id);\n }\n\n private opTargetsActiveSpace(op: Operation): boolean {\n if (!(\"space\" in op)) return false;\n const s = op.space;\n return s === \"model\"\n ? this.activeSpace === \"model\"\n : this.activeSpace !== \"model\" &&\n this.activeSpace.layoutId === s.layoutId;\n }\n\n /**\n * Incrementally maintain the active-space index after an op — O(changed)\n * for object ops (the interactive hot path) rather than a full rebuild.\n */\n private reindexForOp(op: Operation): void {\n switch (op.type) {\n case \"add-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const o of op.objects) this.indexAdd(o);\n return;\n case \"remove-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const id of op.ids) this.indexRemoveById(id);\n return;\n case \"update-objects\":\n if (this.opTargetsActiveSpace(op))\n for (const o of op.objects) {\n this.indexRemoveById(o.id);\n this.indexAdd(o);\n }\n return;\n case \"reorder-objects\":\n // Same object set, new order — the indexes are order-independent.\n return;\n case \"add-layout\":\n case \"remove-layout\":\n case \"update-layouts\":\n // Could change which objects the active space exposes (e.g. the\n // active layout was removed or its content replaced) — rebuild.\n this.rebuildIndexes();\n return;\n default:\n // layer / dim-style / name / current-layer / block-defs / layout-meta:\n // no change to the active-space object set.\n return;\n }\n }\n\n private invalidate(ids: string[] | null): void {\n // Instances whose inputs reference a mutated object are stale too —\n // expand BEFORE dropping caches so listeners see the same id list.\n const expanded = ids === null ? null : expandWithBlockDependents(ids);\n invalidateBlockCache(expanded);\n for (const fn of this.listeners) fn(expanded);\n }\n}\n","// The in-process `Drawing` — its ONE implementation: mutations mapped 1:1 to\n// validated ops, reads and renders through the headless paint paths. The\n// document lives in a DocumentKernel with op-based undo stacks, or — given\n// DrawingHooks — in a host's stores (the editor's subclass routes ops through\n// its mutation funnel and history). Browser-safe (no Node imports); hosts\n// subclass it for their I/O: the SDK (files, PNG/PDF, imports), the editor\n// (PDF/PNG). Ergonomics only (layer-by-name, array points via the schema,\n// batching) — never new semantics.\n\nimport { z } from \"zod\";\nimport { arcSweep, distToArc } from \"../geometry/arcs\";\nimport {\n boundsIntersect,\n emptyBounds,\n isEmptyBounds,\n unionBounds,\n type AABB,\n} from \"../geometry/bounds\";\nimport { closestPointOnSegment } from \"../geometry/line\";\nimport { chainLength, hatchArea, polylineArea } from \"../geometry/polyline\";\nimport { dist, type Vec2 } from \"../geometry/vec2\";\nimport { hashAsset } from \"../model/assets\";\nimport { Vec2Schema } from \"../model/common\";\nimport {\n DEFAULT_DOCUMENT_NAME,\n LayerSchema,\n type Layer,\n type LineaDocument,\n} from \"../model/document\";\nimport {\n documentObjectResolver,\n resolveDocumentObject,\n} from \"../model/objectLookup\";\nimport {\n assertKnownStyleOverrideKeys,\n DimStyleSchema,\n ModelObjectSchema,\n TextStyleSchema,\n type DimStyle,\n type ModelObject,\n type ReferenceObject,\n type TextStyle,\n} from \"../model/objects\";\nimport type { ReferenceContent } from \"../reference/reference\";\nimport {\n PaperLayoutSchema,\n resolveSheetSize,\n sheetOrientation,\n type PaperLayout,\n} from \"../model/paperLayout\";\nimport { parseScale } from \"../model/scale\";\nimport { approximateTextMeasurer } from \"../paint/textMeasurer\";\nimport type { TextMeasurer } from \"../paint/textMetrics\";\nimport { buildSnapEntry, type SnapGeometryContext } from \"../snap/buildEntry\";\nimport type { SnapCacheEntry } from \"../snap/types\";\nimport { renderLayoutToSvg, renderModelToSvg } from \"../export/svg/renderSvg\";\nimport { dwgToDxf, dxfToDwg, type DwgVersion } from \"../dwg\";\nimport { dxfToModel } from \"../import/dxf/importDxf\";\nimport { pdfToModel } from \"../import/pdf/importPdf\";\nimport { documentToJson } from \"../serialize\";\nimport {\n mirrorObject,\n remapBlockInputRefs,\n rotateObject,\n scaleObjectUniform,\n translateObject,\n} from \"../transform\";\nimport { listBlockMeta, type BlockMeta } from \"../extensions/evalBlock\";\nimport {\n listCommandMeta,\n mergeCommandModules,\n type CommandMeta,\n} from \"../extensions/commandModules\";\nimport { mergeBlockModules } from \"../extensions/scriptModules\";\nimport { ensureScriptTranspiler } from \"../extensions/scriptRuntime\";\nimport {\n diffDimStyleOps,\n diffModuleOps,\n diffTextStyleOps,\n} from \"../operations/diff\";\nimport { DocumentKernel } from \"../operations/kernel\";\nimport {\n parseOperations,\n type Operation,\n type OpSpace,\n type ReorderPlacement,\n} from \"../operations/types\";\nimport type {\n AddOptions,\n DocumentSummary,\n Drawing,\n LayerInfo,\n LayoutOptions,\n LayoutPatch,\n Measurement,\n MergeReport,\n ObjectInput,\n PointInput,\n QueryFilter,\n RenderPdfOptions,\n RenderSvgOptions,\n} from \"./types\";\n\nconst toVec = (p: PointInput): Vec2 => Vec2Schema.parse(p);\n\n/** Zod issues → one readable error, prefixed with the failing call/object. */\nconst wrapZod = (e: unknown, context: string): Error => {\n if (!(e instanceof z.ZodError))\n return e instanceof Error ? e : new Error(String(e));\n return new Error(`${context}: ${z.prettifyError(e)}`);\n};\n\nexport interface DxfImportOptions {\n /** mm per drawing unit; overrides the file's $INSUNITS header. */\n unitOverride?: number;\n}\n\nexport interface DxfImportReport {\n objects: number;\n layers: number;\n layouts: number;\n objectIds: string[];\n layoutIds: string[];\n}\n\nexport interface PdfImportReport {\n objects: number;\n pageCount: number;\n objectIds: string[];\n}\n\nexport interface PdfImportOptions {\n /** \"vectors\" (default): lines and text runs. \"image\": every page\n * rasterized and placed as an image at true page scale — a host\n * capability (`rasterizePdf`), refused where it is missing. */\n as?: \"vectors\" | \"image\";\n /** Bottom-left corner of the first page (image mode; default 0,0). Pages\n * line up to the right. */\n origin?: PointInput;\n}\n\n/** One PDF page rasterized: PNG pixels plus its true size in mm. */\nexport interface RasterPdfPage {\n dataUrl: string;\n widthMm: number;\n heightMm: number;\n}\n\n/** An embedded image asset as `listAssets` reports it. */\nexport interface AssetInfo {\n id: string;\n /** From the data URL, e.g. \"image/png\". */\n mimeType: string;\n /** Decoded size in bytes. */\n bytes: number;\n /** Image objects (every space) that show it. */\n users: number;\n}\n\n/** Gap between PDF pages placed side by side (image import), mm. */\nconst PDF_PAGE_GAP_MM = 50;\n\ntype Step = { forwards: Operation[]; inverses: Operation[] };\n\n/**\n * Which layouts a PDF render prints (shared by every renderPdf host): the\n * named ones in the order given, else every layout in document order, else\n * — for a layout-less document — one ephemeral fitted sheet from `fallback`\n * (the document itself gains no layout). `palette` overrides each page's.\n */\nexport const selectPdfLayouts = (\n layouts: readonly PaperLayout[],\n opts: RenderPdfOptions,\n fallback: () => PaperLayout,\n): PaperLayout[] => {\n const byRef = (ref: string) => {\n const l = layouts.find((x) => x.name === ref || x.id === ref);\n if (!l) throw new Error(`Unknown layout \"${ref}\"`);\n return l;\n };\n let selected =\n opts.layouts !== undefined\n ? opts.layouts.map(byRef)\n : layouts.length > 0\n ? [...layouts]\n : [fallback()];\n if (opts.palette)\n selected = selected.map((l) => ({ ...l, printPalette: opts.palette! }));\n if (selected.length === 0) throw new Error(\"No layouts selected\");\n return selected;\n};\n\n/** Reject duplicate ids in a whole-array style replace, so the diff always\n * decomposes into granular per-item ops and never falls back to the legacy\n * coarse set-* op (docs/granular-ops.md). */\nconst assertUniqueIds = (\n items: readonly { id: string }[],\n where: string,\n): void => {\n const seen = new Set<string>();\n for (const { id } of items) {\n if (seen.has(id))\n throw new Error(`${where}: duplicate style id ${JSON.stringify(id)}`);\n seen.add(id);\n }\n};\n\n/**\n * Where a LocalDrawing's document lives and how its edits are recorded. Absent\n * (constructed from a document), LocalDrawing owns a kernel and its own undo\n * stacks; the editor passes hooks over its live stores so agent and script\n * edits go through the mutation funnel and the user's history.\n */\nexport interface DrawingHooks {\n /** The live document — read only, never handed out. */\n document(): LineaDocument;\n /** Apply one validated op (throws when refused). */\n apply(op: Operation): void;\n /** One undo step for everything `fn` applies; a throw (or rejection)\n * rolls it back and rethrows. Nested calls join the outer step. */\n transaction<T>(fn: () => T): T;\n inTransaction(): boolean;\n undo(): boolean;\n redo(): boolean;\n canUndo(): boolean;\n canRedo(): boolean;\n /** Bumped by every change the drawing should report (agents poll it). */\n revision(): number;\n /** Text metrics for bounds and DXF (default: approximate font metrics). */\n measure?: TextMeasurer;\n /** Document-wide object lookup for block reference inputs. */\n resolveObject?: (id: string) => ModelObject | undefined;\n /** Loaded reference content (default: the drawing's referenceContent). */\n resolveReference?: (ref: ReferenceObject) => ReferenceContent | null;\n /** Snap/hit-test geometry, e.g. from a cache (default: built per call). */\n snapEntry?: (obj: ModelObject) => SnapCacheEntry;\n}\n\n/** The headless hooks: one DocumentKernel plus op-based undo stacks. */\nconst kernelHooks = (doc: LineaDocument): DrawingHooks => {\n const kernel = new DocumentKernel(doc);\n const undoStack: Step[] = [];\n const redoStack: Step[] = [];\n let txn: Step | null = null;\n let rev = 0;\n const replay = (ops: readonly Operation[]) => {\n for (const op of ops) kernel.apply(op);\n rev++;\n };\n return {\n document: () => kernel.document,\n apply(op) {\n const inverse = kernel.apply(op);\n rev++;\n if (txn) {\n txn.forwards.push(op);\n txn.inverses.push(inverse);\n } else {\n undoStack.push({ forwards: [op], inverses: [inverse] });\n redoStack.length = 0;\n }\n },\n transaction<T>(fn: () => T): T {\n if (txn) return fn(); // nested → part of the outer step\n const step: Step = { forwards: [], inverses: [] };\n txn = step;\n const commit = () => {\n txn = null;\n if (step.forwards.length > 0) {\n undoStack.push(step);\n redoStack.length = 0;\n }\n };\n const rollback = () => {\n txn = null;\n if (step.forwards.length > 0) replay([...step.inverses].reverse());\n };\n let result: T;\n try {\n result = fn();\n } catch (e) {\n rollback();\n throw e;\n }\n if (result instanceof Promise) {\n return result.then(\n (v) => {\n commit();\n return v;\n },\n (e: unknown) => {\n rollback();\n throw e;\n },\n ) as T;\n }\n commit();\n return result;\n },\n inTransaction: () => txn !== null,\n undo() {\n const step = undoStack.pop();\n if (!step) return false;\n replay([...step.inverses].reverse());\n redoStack.push(step);\n return true;\n },\n redo() {\n const step = redoStack.pop();\n if (!step) return false;\n replay(step.forwards);\n undoStack.push(step);\n return true;\n },\n canUndo: () => undoStack.length > 0,\n canRedo: () => redoStack.length > 0,\n revision: () => rev,\n };\n};\n\nexport class LocalDrawing implements Drawing {\n private hooks: DrawingHooks;\n /** Schema-version migration applied on open; null when none was needed. */\n readonly migration: { from: number; to: number } | null;\n /** Display name (summary, default export names). Host state — a document\n * carries no name: the SDK keeps it in step with the file name. */\n name = DEFAULT_DOCUMENT_NAME;\n /** Loaded reference content by reference id. Hosts that can read files\n * fill it (the Node SDK, in `ready()`); empty → references paint and\n * snap as frames. docs/references.md. */\n protected referenceContent = new Map<string, ReferenceContent>();\n private resolveReference = (ref: ReferenceObject): ReferenceContent | null =>\n this.hooks.resolveReference\n ? this.hooks.resolveReference(ref)\n : (this.referenceContent.get(ref.id) ?? null);\n\n /** A document (owned here: kernel + undo stacks), or hooks over a document\n * that lives elsewhere (the editor's stores). */\n constructor(\n source: LineaDocument | DrawingHooks,\n migration: { from: number; to: number } | null = null,\n ) {\n this.hooks = \"apply\" in source ? source : kernelHooks(source);\n this.migration = migration;\n // Block identity/metadata are module exports — start the (lazy)\n // transpiler now so meta-dependent paths (ops validation, evaluation,\n // rendering) go definitive as early as possible. Until it lands the\n // checks are permissive, never wrong.\n if (this.state.blockDefinitions.length > 0) void ensureScriptTranspiler();\n }\n\n /** The live document — internal reads only; NEVER handed out. */\n protected get state(): LineaDocument {\n return this.hooks.document();\n }\n\n get id(): string {\n return this.state.id;\n }\n\n get revision(): number {\n return this.hooks.revision();\n }\n\n // Public reads return detached deep clones: mutating them cannot corrupt\n // the document (all edits must go through the validated ops, which also\n // keep undo history and the block caches correct).\n get document(): LineaDocument {\n return structuredClone(this.state);\n }\n get layers(): Layer[] {\n return structuredClone(this.state.layers);\n }\n get objects(): ModelObject[] {\n return structuredClone(this.state.objects);\n }\n get layouts(): PaperLayout[] {\n return structuredClone(this.state.layouts);\n }\n\n listLayouts(): PaperLayout[] {\n return this.layouts;\n }\n\n /** Look up an object in ANY space (model or a layout's sheet objects). */\n getObject(id: string): ModelObject | undefined {\n const obj = resolveDocumentObject(this.state, id);\n return obj && structuredClone(obj);\n }\n\n private findObject(id: string): { obj: ModelObject; space: OpSpace } {\n const doc = this.state;\n const obj = resolveDocumentObject(doc, id);\n if (!obj) throw new Error(`Unknown object \"${id}\"`);\n // ponytail: linear scan of layout sheets (few, small); index if it shows.\n const layout = doc.layouts.find((l) => l.objects.includes(obj));\n return { obj, space: layout ? { layoutId: layout.id } : \"model\" };\n }\n\n private groupBySpace<T>(\n entries: { space: OpSpace; item: T }[],\n ): { space: OpSpace; items: T[] }[] {\n const groups = new Map<string, { space: OpSpace; items: T[] }>();\n for (const { space, item } of entries) {\n const key = space === \"model\" ? \"model\" : space.layoutId;\n const group = groups.get(key) ?? { space, items: [] };\n group.items.push(item);\n groups.set(key, group);\n }\n return [...groups.values()];\n }\n\n /** One op per space, all in one undo step. */\n private applyBySpace(\n entries: { space: OpSpace; obj: ModelObject }[],\n make: (space: OpSpace, objects: ModelObject[]) => Operation,\n ): void {\n const groups = this.groupBySpace(\n entries.map(({ space, obj }) => ({ space, item: obj })),\n );\n this.transaction(() => {\n for (const g of groups) this.applyForward(make(g.space, g.items));\n });\n }\n\n // --- op plumbing ---------------------------------------------------------\n\n private applyForward(op: Operation): void {\n this.hooks.apply(op);\n }\n\n /** Emit an op list as one undo step. */\n private applyForwardAll(ops: readonly Operation[]): void {\n this.transaction(() => {\n for (const op of ops) this.applyForward(op);\n });\n }\n\n /** Escape hatch: a raw op batch — schema-checked (parseOperations), then\n * applied atomically as one step (the kernel checks references). */\n applyOps(ops: readonly Operation[]): void {\n this.applyForwardAll(parseOperations(ops));\n }\n\n /**\n * Group mutations into ONE undo step. A throw (sync, or an async fn's\n * rejection) rolls back everything the transaction applied and rethrows.\n * Nested calls join the outer step.\n */\n transaction<T>(fn: () => T): T {\n return this.hooks.transaction(fn);\n }\n\n private assertNoTransaction(what: string): void {\n if (this.hooks.inTransaction())\n throw new Error(\n `${what}() inside a transaction — return or throw to roll back instead`,\n );\n }\n\n undo(): boolean {\n this.assertNoTransaction(\"undo\");\n return this.hooks.undo();\n }\n redo(): boolean {\n this.assertNoTransaction(\"redo\");\n return this.hooks.redo();\n }\n get canUndo(): boolean {\n return this.hooks.canUndo();\n }\n get canRedo(): boolean {\n return this.hooks.canRedo();\n }\n\n // --- layers --------------------------------------------------------------\n\n private resolveLayerId(layerName?: string, layerId?: string): string {\n if (layerId) return layerId;\n if (layerName) return this.resolveLayer(layerName).id;\n return this.state.currentLayerId;\n }\n\n listLayers(): LayerInfo[] {\n const current = this.state.currentLayerId;\n return this.layers.map((l) => ({ ...l, current: l.id === current }));\n }\n\n /** Create a layer; returns its id. */\n addLayer(layer: Partial<Layer> & { name: string }): string {\n // Names are how layers are addressed everywhere (layer-by-name in add,\n // query filters) — a silent duplicate would resolve to the first match.\n const clash = this.state.layers.find(\n (l) => l.name.toLowerCase() === layer.name.toLowerCase(),\n );\n if (clash)\n throw new Error(`addLayer(): layer \"${clash.name}\" already exists`);\n const full = LayerSchema.parse(layer);\n this.applyForward({ type: \"add-layer\", layer: full });\n return full.id;\n }\n\n private resolveLayer(nameOrId: string): Layer {\n const l = this.state.layers.find(\n (x) => x.id === nameOrId || x.name === nameOrId,\n );\n if (!l) throw new Error(`Unknown layer \"${nameOrId}\"`);\n return l;\n }\n\n /** Patch a layer (rename, color, lineWidth, visible, locked) by name or id. */\n updateLayer(nameOrId: string, patch: Partial<Omit<Layer, \"id\">>): void {\n const cur = this.resolveLayer(nameOrId);\n if (\n patch.name !== undefined &&\n patch.name.toLowerCase() !== cur.name.toLowerCase()\n ) {\n const clash = this.state.layers.find(\n (l) => l.name.toLowerCase() === patch.name!.toLowerCase(),\n );\n if (clash)\n throw new Error(`updateLayer(): layer \"${clash.name}\" already exists`);\n }\n this.applyForward({\n type: \"update-layer\",\n layer: LayerSchema.parse({ ...cur, ...patch, id: cur.id }),\n });\n }\n\n /** Remove an EMPTY, non-current layer (the kernel refuses otherwise). */\n removeLayer(nameOrId: string): void {\n this.applyForward({\n type: \"remove-layer\",\n id: this.resolveLayer(nameOrId).id,\n });\n }\n\n /** Reorder the layers (names or ids, every layer exactly once). */\n reorderLayers(order: readonly string[]): void {\n this.applyForward({\n type: \"reorder-layers\",\n ids: order.map((l) => this.resolveLayer(l).id),\n });\n }\n\n /** The layer newly added objects default to. */\n setCurrentLayer(nameOrId: string): void {\n this.applyForward({\n type: \"set-current-layer\",\n id: this.resolveLayer(nameOrId).id,\n });\n }\n\n // --- document meta / assets ------------------------------------------------\n\n /**\n * Embed image pixels (a data URL) and return the assetId that `image`\n * objects reference. Content-keyed: the same data reuses one entry.\n */\n addAsset(dataUrl: string): string {\n const id = hashAsset(dataUrl);\n if (this.state.assets[id] !== dataUrl)\n this.applyForward({ type: \"set-asset\", id, dataUrl });\n return id;\n }\n\n /** Remove an asset (the kernel refuses while an image references it). */\n removeAsset(id: string): void {\n this.applyForward({ type: \"remove-asset\", id });\n }\n\n listAssets(): AssetInfo[] {\n const users = new Map<string, number>();\n for (const objs of [\n this.state.objects,\n ...this.state.layouts.map((l) => l.objects),\n ])\n for (const o of objs)\n if (o.type === \"image\")\n users.set(o.assetId, (users.get(o.assetId) ?? 0) + 1);\n return Object.entries(this.state.assets).map(([id, dataUrl]) => {\n const comma = dataUrl.indexOf(\",\");\n const base64 = dataUrl.slice(comma + 1);\n return {\n id,\n mimeType: /^data:([^;,]+)/.exec(dataUrl)?.[1] ?? \"\",\n bytes:\n Math.floor((base64.length * 3) / 4) -\n (base64.match(/=+$/)?.[0].length ?? 0),\n users: users.get(id) ?? 0,\n };\n });\n }\n\n // --- import (merge into this document) -------------------------------------\n\n /** Merge DXF text into the document (new layers, objects, layouts). */\n importDxfText(text: string, opts: DxfImportOptions = {}): DxfImportReport {\n const doc = this.state;\n const result = dxfToModel(text, {\n existingLayers: doc.layers.map((l) => ({ id: l.id, name: l.name })),\n defaultLayerId: doc.currentLayerId,\n dimTextHeight: doc.dimStyles[0].textHeight,\n dimArrowSize: doc.dimStyles[0].arrowSize,\n unitOverride: opts.unitOverride,\n });\n const objects = result.objects.map((o) =>\n ModelObjectSchema.parse({ ...o, id: crypto.randomUUID() }),\n );\n this.applyOps([\n ...result.newLayers.map((layer) => ({\n type: \"add-layer\" as const,\n layer,\n })),\n ...(objects.length > 0\n ? [{ type: \"add-objects\" as const, space: \"model\" as const, objects }]\n : []),\n ...result.layouts.map((layout) => ({\n type: \"add-layout\" as const,\n layout,\n })),\n ]);\n return {\n objects: objects.length,\n layers: result.newLayers.length,\n layouts: result.layouts.length,\n objectIds: objects.map((o) => o.id),\n layoutIds: result.layouts.map((l) => l.id),\n };\n }\n\n /** Merge DWG bytes into the document (wasm transcode → the DXF path). */\n async importDwgData(\n data: Uint8Array,\n opts?: DxfImportOptions,\n ): Promise<DxfImportReport> {\n return this.importDxfText(await dwgToDxf(data), opts);\n }\n\n /** Merge a PDF: its vector/text content onto the current layer, or\n * (`as: \"image\"`) every page as an image at true page scale. */\n async importPdfData(\n data: ArrayBuffer | Uint8Array,\n opts: PdfImportOptions = {},\n ): Promise<PdfImportReport> {\n if (opts.as === \"image\") {\n if (!this.rasterizePdf)\n throw new Error(\n 'PDF as image is not available on this host yet; import it with as: \"vectors\"',\n );\n const pages = await this.rasterizePdf(data);\n const at = toVec(opts.origin ?? [0, 0]);\n const layerId = this.state.currentLayerId;\n let x = at.x;\n const placed = pages.map((p) => {\n const object = {\n type: \"image\",\n layerId,\n assetId: this.addAsset(p.dataUrl),\n origin: { x, y: at.y },\n width: p.widthMm,\n height: p.heightMm,\n } as ObjectInput;\n x += p.widthMm + PDF_PAGE_GAP_MM;\n return object;\n });\n const objectIds = placed.length > 0 ? this.add(placed) : [];\n return { objects: objectIds.length, pageCount: pages.length, objectIds };\n }\n const result = await pdfToModel(data, { workerSrc: this.pdfWorkerSrc });\n const layerId = this.state.currentLayerId;\n const objectIds =\n result.objects.length > 0\n ? this.add(\n result.objects.map((o) => ({ ...o, layerId }) as ObjectInput),\n )\n : [];\n return {\n objects: result.objects.length,\n pageCount: result.pageCount,\n objectIds,\n };\n }\n\n /** Host capability: every PDF page rasterized. Absent → PDF-as-image\n * import is refused (headless Node, until it has a rasterizer). */\n rasterizePdf?(data: ArrayBuffer | Uint8Array): Promise<RasterPdfPage[]>;\n\n /** pdf.js worker URL for hosts that need one (the browser). */\n protected pdfWorkerSrc?: string;\n\n // --- styles ----------------------------------------------------------------\n\n // Styles are addressed by name or id, like layers, so names stay unique\n // (case-insensitive) on add and rename.\n private resolveStyle<T extends { id: string; name: string }>(\n styles: readonly T[],\n nameOrId: string,\n what: string,\n ): T {\n const s = styles.find((x) => x.id === nameOrId || x.name === nameOrId);\n if (!s) throw new Error(`Unknown ${what} \"${nameOrId}\"`);\n return s;\n }\n\n private assertStyleName(\n styles: readonly { id: string; name: string }[],\n name: string,\n context: string,\n except?: string,\n ): void {\n const clash = styles.find(\n (s) => s.id !== except && s.name.toLowerCase() === name.toLowerCase(),\n );\n if (clash)\n throw new Error(`${context}: style \"${clash.name}\" already exists`);\n }\n\n listTextStyles(): TextStyle[] {\n return this.state.textStyles.map((s) => ({ ...s }));\n }\n\n listDimStyles(): DimStyle[] {\n return this.state.dimStyles.map((s) => ({ ...s }));\n }\n\n /** Create a text style (unique name; unset fields take the defaults);\n * returns its id. */\n addTextStyle(\n props: { name: string } & Partial<Omit<TextStyle, \"id\">>,\n ): string {\n this.assertStyleName(this.state.textStyles, props.name, \"addTextStyle()\");\n const style = TextStyleSchema.parse(props);\n this.applyForward({ type: \"add-text-style\", style });\n return style.id;\n }\n\n updateTextStyle(\n nameOrId: string,\n patch: Partial<Omit<TextStyle, \"id\">>,\n ): void {\n const cur = this.resolveStyle(\n this.state.textStyles,\n nameOrId,\n \"text style\",\n );\n if (patch.name !== undefined)\n this.assertStyleName(\n this.state.textStyles,\n patch.name,\n \"updateTextStyle()\",\n cur.id,\n );\n this.applyForward({\n type: \"update-text-style\",\n style: TextStyleSchema.parse({ ...cur, ...patch, id: cur.id }),\n });\n }\n\n /** Remove a text style no object uses (the kernel refuses otherwise). */\n removeTextStyle(nameOrId: string): void {\n this.applyForward({\n type: \"remove-text-style\",\n id: this.resolveStyle(this.state.textStyles, nameOrId, \"text style\").id,\n });\n }\n\n /** Create a dimension style (unique name; unset fields take the\n * defaults); returns its id. */\n addDimStyle(props: { name: string } & Partial<Omit<DimStyle, \"id\">>): string {\n this.assertStyleName(this.state.dimStyles, props.name, \"addDimStyle()\");\n const style = DimStyleSchema.parse(props);\n this.applyForward({ type: \"add-dim-style\", style });\n return style.id;\n }\n\n updateDimStyle(nameOrId: string, patch: Partial<Omit<DimStyle, \"id\">>): void {\n const cur = this.resolveStyle(this.state.dimStyles, nameOrId, \"dim style\");\n if (patch.name !== undefined)\n this.assertStyleName(\n this.state.dimStyles,\n patch.name,\n \"updateDimStyle()\",\n cur.id,\n );\n this.applyForward({\n type: \"update-dim-style\",\n style: DimStyleSchema.parse({ ...cur, ...patch, id: cur.id }),\n });\n }\n\n /** Remove a dimension style no dimension uses (the kernel refuses\n * otherwise). */\n removeDimStyle(nameOrId: string): void {\n this.applyForward({\n type: \"remove-dim-style\",\n id: this.resolveStyle(this.state.dimStyles, nameOrId, \"dim style\").id,\n });\n }\n\n /** @deprecated Use updateDimStyle (default here: the first style). */\n setDimStyle(patch: Partial<DimStyle>, styleId?: string): void {\n this.updateDimStyle(styleId ?? this.state.dimStyles[0].id, patch);\n }\n\n /** Replace the document's dimension styles (min 1; objects reference by\n * id). Diffed into granular per-style ops. */\n setDimStyles(styles: DimStyle[]): void {\n const parsed = styles.map((s) => DimStyleSchema.parse(s));\n assertUniqueIds(parsed, \"setDimStyles()\");\n this.applyForwardAll(diffDimStyleOps(this.state.dimStyles, parsed));\n }\n\n /** @deprecated Use updateTextStyle (default here: the first style). */\n setTextStyle(patch: Partial<TextStyle>, styleId?: string): void {\n this.updateTextStyle(styleId ?? this.state.textStyles[0].id, patch);\n }\n\n /** Replace the document's text styles (min 1; objects reference by id).\n * Diffed into granular per-style ops. */\n setTextStyles(styles: TextStyle[]): void {\n const parsed = styles.map((s) => TextStyleSchema.parse(s));\n assertUniqueIds(parsed, \"setTextStyles()\");\n this.applyForwardAll(diffTextStyleOps(this.state.textStyles, parsed));\n }\n\n // --- modules (blocks + commands) -------------------------------------------\n\n private assertModuleSources(\n defs: readonly unknown[],\n where: string,\n ): string[] {\n const sources = defs.map((d) => {\n if (typeof d !== \"string\")\n throw new Error(\n `${where}: modules are ES-module SOURCES (strings) — each exports its own id/name`,\n );\n return d;\n });\n if (new Set(sources).size !== sources.length)\n throw new Error(\n `${where}: duplicate module source — modules are content-addressed (two identical sources are indistinguishable); deduplicate before setting`,\n );\n return sources;\n }\n\n /**\n * Replace the block library (raw module sources — each exports its own\n * id/name/params; semantic validation happens at compile). Async: awaits\n * the lazy transpiler, so block evaluation (bboxOf, renders, exports) is\n * definitive as soon as this resolves — never silently placeholder.\n */\n async setBlockDefinitions(defs: unknown[]): Promise<void> {\n const sources = this.assertModuleSources(defs, \"setBlockDefinitions()\");\n if (sources.length > 0) await ensureScriptTranspiler();\n this.applyForwardAll(\n diffModuleOps(this.state.blockDefinitions, sources, \"blockDefinitions\"),\n );\n }\n\n /** Replace the document's command modules (same rules as blocks). */\n async setCommands(defs: unknown[]): Promise<void> {\n const sources = this.assertModuleSources(defs, \"setCommands()\");\n if (sources.length > 0) await ensureScriptTranspiler();\n this.applyForwardAll(\n diffModuleOps(this.state.commands, sources, \"commands\"),\n );\n }\n\n /** Compilable block definitions (broken modules are skipped). */\n listBlockDefinitions(): BlockMeta[] {\n return listBlockMeta(this.state.blockDefinitions).flatMap((r) =>\n r.ok ? [r.meta] : [],\n );\n }\n\n /** Compilable document commands (broken modules are skipped). */\n listUserCommands(): CommandMeta[] {\n return listCommandMeta(this.state.commands).flatMap((r) =>\n r.ok ? [r.meta] : [],\n );\n }\n\n async addBlockDefinitions(sources: readonly string[]): Promise<MergeReport> {\n await ensureScriptTranspiler();\n const report = mergeBlockModules(this.state.blockDefinitions, sources);\n this.applyForwardAll(\n diffModuleOps(\n this.state.blockDefinitions,\n report.merged,\n \"blockDefinitions\",\n ),\n );\n return report;\n }\n\n async addUserCommands(sources: readonly string[]): Promise<MergeReport> {\n await ensureScriptTranspiler();\n const report = mergeCommandModules(this.state.commands, sources);\n this.applyForwardAll(\n diffModuleOps(this.state.commands, report.merged, \"commands\"),\n );\n return report;\n }\n\n /** Remove a block module by its exported id (unknown id → error). */\n removeBlockDefinition(id: string): void {\n const source = this.state.blockDefinitions.find((s) =>\n listBlockMeta([s]).some((r) => r.ok && r.meta.id === id),\n );\n if (source === undefined) throw new Error(`Unknown block \"${id}\"`);\n this.applyForward({ type: \"remove-block-definition\", source });\n }\n\n /** Remove a command module by its exported id (unknown id → error). */\n removeUserCommand(id: string): void {\n const source = this.state.commands.find((s) =>\n listCommandMeta([s]).some((r) => r.ok && r.meta.id === id),\n );\n if (source === undefined) throw new Error(`Unknown command \"${id}\"`);\n this.applyForward({ type: \"remove-document-command\", source });\n }\n\n /**\n * Resolves when block scripts evaluate definitively (the transpiler is\n * loaded). Await this before sync reads/renders of a document that was\n * constructed with block definitions (file opens and the module setters\n * already wait).\n */\n async ready(): Promise<void> {\n if (this.state.blockDefinitions.length > 0) await ensureScriptTranspiler();\n }\n\n // --- layouts ---------------------------------------------------------------\n\n private modelExtents(): AABB {\n let bbox = emptyBounds();\n for (const o of this.state.objects) {\n const b = this.boundsOf(o);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return bbox;\n }\n\n /** Fitted scale + center for a viewport frame (editor createLayout rules). */\n private fitViewport(rect: { w: number; h: number }): {\n scale: number;\n modelCenter: Vec2;\n } {\n const bbox = this.modelExtents();\n if (isEmptyBounds(bbox)) return { scale: 50, modelCenter: { x: 0, y: 0 } };\n const presets = [1, 2, 5, 10, 20, 50, 100, 200, 500, 1000];\n const needed = Math.max(\n (bbox.maxX - bbox.minX) / (rect.w * 0.9),\n (bbox.maxY - bbox.minY) / (rect.h * 0.9),\n );\n return {\n scale: presets.find((s) => s >= needed) ?? presets[presets.length - 1],\n modelCenter: {\n x: (bbox.minX + bbox.maxX) / 2,\n y: (bbox.minY + bbox.maxY) / 2,\n },\n };\n }\n\n protected makeLayout(name: string, opts: LayoutOptions = {}): PaperLayout {\n const { width, height } = resolveSheetSize(opts.sheet);\n\n const objects: unknown[] = [];\n if (opts.viewport !== false) {\n const vp = opts.viewport ?? {};\n const scale = vp.scale ?? opts.scale;\n const margin = 20;\n const rect = vp.rect ?? {\n x: margin,\n y: margin,\n w: width - margin * 2,\n h: height - margin * 2,\n };\n const fitted = this.fitViewport(rect);\n objects.push({\n id: crypto.randomUUID(),\n type: \"viewport\",\n layerId: this.state.currentLayerId,\n rect,\n modelCenter: vp.center ? toVec(vp.center) : fitted.modelCenter,\n scale: scale !== undefined ? parseScale(scale) : fitted.scale,\n locked: false,\n hiddenLayerIds: [],\n });\n }\n\n return PaperLayoutSchema.parse({\n id: crypto.randomUUID(),\n name,\n sheet: { width, height },\n printPalette: \"color\",\n objects,\n });\n }\n\n /**\n * Create a paper layout — by default A3 landscape with one viewport fitted\n * to the model extents. Returns the layout id.\n */\n addLayout(name: string, opts: LayoutOptions = {}): string {\n const layout = this.makeLayout(name, opts);\n this.applyForward({ type: \"add-layout\", layout, index: opts.index });\n return layout.id;\n }\n\n /** Remove a layout by name or id. */\n removeLayout(nameOrId: string): void {\n this.applyForward({\n type: \"remove-layout\",\n id: this.resolveLayout(nameOrId).id,\n });\n }\n\n /** Reorder the layouts (names or ids, every layout exactly once). Layout\n * order is the sheet order of multi-page PDF export. */\n reorderLayouts(order: readonly string[]): void {\n this.applyForward({\n type: \"reorder-layouts\",\n ids: order.map((l) => this.resolveLayout(l).id),\n });\n }\n\n /** Patch a layout's name / sheet (preset or mm) / print palette. */\n updateLayout(nameOrId: string, patch: LayoutPatch): void {\n const layout = this.resolveLayout(nameOrId);\n const { sheet, ...rest } = patch;\n this.applyForward({\n type: \"update-layout-meta\",\n id: layout.id,\n ...rest,\n ...(sheet !== undefined\n ? { sheet: resolveSheetSize(sheet, sheetOrientation(layout.sheet)) }\n : {}),\n });\n }\n\n // --- object mutations ----------------------------------------------------\n\n private normalize(input: ObjectInput, index?: number): ModelObject {\n const { layer, layerId, id, ...rest } = input as ObjectInput & {\n layer?: string;\n layerId?: string;\n id?: string;\n };\n assertKnownStyleOverrideKeys(\n input as Record<string, unknown>,\n `add(): objects[${index ?? 0}] (${String(input.type ?? \"?\")})`,\n );\n try {\n return ModelObjectSchema.parse({\n ...rest,\n layerId: this.resolveLayerId(layer, layerId),\n id: id ?? crypto.randomUUID(),\n });\n } catch (e) {\n throw wrapZod(\n e,\n `add(): objects[${index ?? 0}] (${String(input.type ?? \"?\")})`,\n );\n }\n }\n\n /**\n * Add objects (points may be `[x, y]`; `layer` resolves by name) to model\n * space, or to a paper layout's sheet via `{ layout }`. Returns ids.\n */\n add(objects: readonly ObjectInput[], opts: AddOptions = {}): string[] {\n if (objects.length === 0) return [];\n const space: OpSpace =\n opts.layout !== undefined\n ? { layoutId: this.resolveLayout(opts.layout).id }\n : \"model\";\n const created = objects.map((o, i) => this.normalize(o, i));\n this.applyForward({ type: \"add-objects\", space, objects: created });\n return created.map((o) => o.id);\n }\n\n private patched(\n id: string,\n patch: Record<string, unknown>,\n ): { space: OpSpace; obj: ModelObject } {\n const { layer, layerId, ...rest } = patch as Record<string, unknown> & {\n layer?: string;\n layerId?: string;\n };\n const { obj: cur, space } = this.findObject(id);\n assertKnownStyleOverrideKeys(\n { type: cur.type, styleOverride: rest.styleOverride },\n `update(): \"${id}\" (${cur.type})`,\n );\n const resolvedLayerId =\n layer !== undefined || layerId !== undefined\n ? this.resolveLayerId(layer, layerId)\n : undefined;\n try {\n return {\n space,\n obj: ModelObjectSchema.parse({\n ...cur,\n ...rest,\n ...(resolvedLayerId ? { layerId: resolvedLayerId } : {}),\n id,\n }),\n };\n } catch (e) {\n throw wrapZod(e, `update(): \"${id}\" (${cur.type})`);\n }\n }\n\n /** Apply one patch to several ids. */\n update(ids: readonly string[], patch: Record<string, unknown>): void;\n /** Apply per-object patches (`{id, ...fields}`) in one undo step. */\n update(entries: readonly ({ id: string } & Record<string, unknown>)[]): void;\n update(\n idsOrEntries:\n readonly string[] | readonly ({ id: string } & Record<string, unknown>)[],\n patch?: Record<string, unknown>,\n ): void {\n if (idsOrEntries.length === 0) return;\n const next =\n typeof idsOrEntries[0] === \"string\"\n ? (idsOrEntries as readonly string[]).map((id) =>\n this.patched(id, patch ?? {}),\n )\n : (\n idsOrEntries as readonly ({ id: string } & Record<\n string,\n unknown\n >)[]\n ).map(({ id, ...fields }) => this.patched(id, fields));\n this.applyBySpace(next, (space, objects) => ({\n type: \"update-objects\",\n space,\n objects,\n }));\n }\n\n /** Delete objects by id (unknown ids are skipped); returns how many went. */\n remove(ids: readonly string[]): number {\n const entries: { space: OpSpace; item: string }[] = [];\n for (const id of ids) {\n try {\n entries.push({ space: this.findObject(id).space, item: id });\n } catch {\n continue;\n }\n }\n const groups = this.groupBySpace(entries);\n if (groups.length === 0) return 0;\n this.transaction(() => {\n for (const g of groups)\n this.applyForward({\n type: \"remove-objects\",\n space: g.space,\n ids: g.items,\n });\n });\n return entries.length;\n }\n\n /** Draw order: move the given objects (bottom → top) to a placement. */\n reorder(ids: readonly string[], placement: ReorderPlacement): void {\n const entries = ids.map((id) => ({\n space: this.findObject(id).space,\n item: id,\n }));\n const groups = this.groupBySpace(entries);\n if (groups.length === 0) return;\n this.transaction(() => {\n for (const g of groups)\n this.applyForward({\n type: \"reorder-objects\",\n space: g.space,\n ids: g.items,\n placement,\n });\n });\n }\n\n // --- transforms ------------------------------------------------------------\n\n private transformEach(\n ids: readonly string[],\n fn: (o: ModelObject) => ModelObject,\n ): void {\n if (ids.length === 0) return;\n const next = ids.map((id) => {\n const { obj, space } = this.findObject(id);\n return { space, obj: ModelObjectSchema.parse(fn(obj)) };\n });\n this.applyBySpace(next, (space, objects) => ({\n type: \"update-objects\",\n space,\n objects,\n }));\n }\n\n /** Selection bbox center — the default pivot for rotate/scale. */\n private pivotOf(ids: readonly string[], center?: PointInput): Vec2 {\n if (center) return toVec(center);\n const bbox = this.bboxOf(ids);\n if (!bbox)\n throw new Error(\"No default pivot (empty bounds) — pass a center\");\n return { x: (bbox.minX + bbox.maxX) / 2, y: (bbox.minY + bbox.maxY) / 2 };\n }\n\n /** Translate objects by a world-mm delta. */\n move(ids: readonly string[], delta: PointInput): void {\n const d = toVec(delta);\n this.transformEach(ids, (o) => translateObject(o, d));\n }\n\n /** Rotate objects by `angle` radians CCW about `center` (default: selection bbox center). */\n rotate(ids: readonly string[], angle: number, center?: PointInput): void {\n const c = this.pivotOf(ids, center);\n this.transformEach(ids, (o) => rotateObject(o, c, angle));\n }\n\n /** Uniformly scale objects about `center` (default: selection bbox center). */\n scale(ids: readonly string[], factor: number, center?: PointInput): void {\n if (!Number.isFinite(factor) || factor <= 0)\n throw new Error(`Invalid scale factor ${factor}`);\n const c = this.pivotOf(ids, center);\n this.transformEach(ids, (o) =>\n translateObject(\n scaleObjectUniform(translateObject(o, { x: -c.x, y: -c.y }), factor),\n c,\n ),\n );\n }\n\n /** Mirror objects across the line a → b. */\n mirror(ids: readonly string[], a: PointInput, b: PointInput): void {\n const pa = toVec(a);\n const pb = toVec(b);\n this.transformEach(ids, (o) => mirrorObject(o, pa, pb));\n }\n\n /** Duplicate objects (into their own space) displaced by `delta`. */\n copy(ids: readonly string[], delta: PointInput): string[] {\n if (ids.length === 0) return [];\n const d = toVec(delta);\n // Fresh ids first, so block object-reference inputs pointing INSIDE the\n // copied set can follow to the clones (outside refs keep the originals).\n const idMap = new Map(ids.map((id) => [id, crypto.randomUUID()]));\n const clones = ids.map((id) => {\n const { obj, space } = this.findObject(id);\n return {\n space,\n obj: ModelObjectSchema.parse({\n ...remapBlockInputRefs(translateObject(obj, d), idMap),\n id: idMap.get(id),\n }),\n };\n });\n this.applyBySpace(clones, (space, objects) => ({\n type: \"add-objects\",\n space,\n objects,\n }));\n return clones.map((c) => c.obj.id);\n }\n\n /**\n * Linear array: `count` TOTAL instances (including the originals) stepped\n * by `delta`. Returns the new ids, one batch per step, in one undo step.\n */\n array(ids: readonly string[], count: number, delta: PointInput): string[] {\n if (!Number.isInteger(count) || count < 1)\n throw new Error(`Invalid array count ${count}`);\n const d = toVec(delta);\n return this.transaction(() => {\n const created: string[] = [];\n for (let i = 1; i < count; i++)\n created.push(...this.copy(ids, { x: d.x * i, y: d.y * i }));\n return created;\n });\n }\n\n // --- reads ---------------------------------------------------------------\n\n private get measurer(): TextMeasurer {\n return this.hooks.measure ?? approximateTextMeasurer;\n }\n\n private resolveObject(): (id: string) => ModelObject | undefined {\n return this.hooks.resolveObject ?? documentObjectResolver(this.state);\n }\n\n private ctx(): SnapGeometryContext {\n return {\n dimStyles: this.state.dimStyles,\n textStyles: this.state.textStyles,\n blockDefinitions: this.state.blockDefinitions,\n resolveObject: this.resolveObject(),\n resolveReference: this.resolveReference,\n measure: this.measurer,\n };\n }\n\n private entryOf(obj: ModelObject): SnapCacheEntry {\n return this.hooks.snapEntry\n ? this.hooks.snapEntry(obj)\n : buildSnapEntry(obj, this.ctx());\n }\n\n private boundsOf(obj: ModelObject): AABB {\n return this.entryOf(obj).bounds;\n }\n\n /** Union bounds of the given objects; null when nothing has bounds. */\n bboxOf(ids: readonly string[]): AABB | null {\n let bbox = emptyBounds();\n for (const id of ids) {\n const b = this.boundsOf(this.findObject(id).obj);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return isEmptyBounds(bbox) ? null : bbox;\n }\n\n /**\n * Curve length in mm (bulge-exact for polylines); null for object types\n * without a natural length (text, dimensions, hatches, blocks, partial\n * ellipses).\n */\n length(id: string): number | null {\n const o = this.findObject(id).obj;\n switch (o.type) {\n case \"line\":\n return dist(o.a, o.b);\n case \"circle\":\n return 2 * Math.PI * o.radius;\n case \"arc\":\n return o.radius * arcSweep(o);\n case \"polyline\":\n return chainLength(o.points, o.closed);\n default:\n return null;\n }\n }\n\n /**\n * Enclosed area in mm² (bulge arcs tessellated): circles, closed\n * polylines, and hatches (outer loop minus holes); null otherwise.\n */\n area(id: string): number | null {\n const o = this.findObject(id).obj;\n switch (o.type) {\n case \"circle\":\n return Math.PI * o.radius * o.radius;\n case \"polyline\":\n return o.closed ? polylineArea(o.points) : null;\n case \"hatch\":\n return hatchArea(o.loops);\n default:\n return null;\n }\n }\n\n measure(id: string): Measurement {\n return {\n bbox: this.bboxOf([id]),\n length: this.length(id),\n area: this.area(id),\n };\n }\n\n /** Min distance from a point to the object's geometry (bounds fallback). */\n private distanceTo(obj: ModelObject, p: Vec2): number {\n const entry = this.entryOf(obj);\n let best = Infinity;\n for (const s of entry.segments)\n best = Math.min(best, dist(p, closestPointOnSegment(p, s.a, s.b)));\n for (const a of entry.arcs) best = Math.min(best, distToArc(a, p));\n if (best !== Infinity) return best;\n const b = entry.bounds;\n if (isEmptyBounds(b)) return Infinity;\n const cx = Math.max(b.minX, Math.min(p.x, b.maxX));\n const cy = Math.max(b.minY, Math.min(p.y, b.maxY));\n return Math.hypot(p.x - cx, p.y - cy);\n }\n\n /** Query model-space objects — or one paper layout's sheet objects\n * (viewports, annotations) via `filter.layout`. */\n listObjects(filter: QueryFilter = {}): ModelObject[] {\n const layerId =\n filter.layer !== undefined\n ? this.resolveLayerId(filter.layer)\n : undefined;\n const nearP = filter.near ? toVec(filter.near.point) : null;\n const wanted = filter.ids ? new Set(filter.ids) : null;\n const pool =\n filter.layout !== undefined\n ? structuredClone(this.resolveLayout(filter.layout).objects)\n : this.objects;\n return pool.filter((o) => {\n if (wanted && !wanted.has(o.id)) return false;\n if (filter.type && o.type !== filter.type) return false;\n if (layerId && o.layerId !== layerId) return false;\n if (filter.color !== undefined && o.color !== filter.color) return false;\n if (filter.lineType !== undefined && o.lineType !== filter.lineType)\n return false;\n if (\n filter.content !== undefined &&\n !(o.type === \"text\" && o.content.includes(filter.content))\n )\n return false;\n if (filter.bbox) {\n const b = this.boundsOf(o);\n if (isEmptyBounds(b) || !boundsIntersect(b, filter.bbox)) return false;\n }\n if (filter.inside) {\n const b = this.boundsOf(o);\n const box = filter.inside;\n if (\n isEmptyBounds(b) ||\n b.minX < box.minX ||\n b.maxX > box.maxX ||\n b.minY < box.minY ||\n b.maxY > box.maxY\n )\n return false;\n }\n if (nearP && filter.near && this.distanceTo(o, nearP) > filter.near.tol)\n return false;\n return true;\n });\n }\n\n summary(): DocumentSummary {\n const doc = this.state;\n const layerName = new Map(doc.layers.map((l) => [l.id, l.name]));\n const byType: Record<string, number> = {};\n const byLayer: Record<string, number> = {};\n let bbox = emptyBounds();\n for (const o of doc.objects) {\n byType[o.type] = (byType[o.type] ?? 0) + 1;\n const ln = layerName.get(o.layerId) ?? o.layerId;\n byLayer[ln] = (byLayer[ln] ?? 0) + 1;\n const b = this.boundsOf(o);\n if (!isEmptyBounds(b)) bbox = unionBounds(bbox, b);\n }\n return {\n name: this.name,\n objectCount: doc.objects.length,\n byType,\n byLayer,\n bbox: isEmptyBounds(bbox) ? null : bbox,\n layers: doc.layers.map((l) => l.name),\n layouts: doc.layouts.map((l) => ({\n name: l.name,\n objectCount: l.objects.length,\n })),\n };\n }\n\n // --- render / export (browser-safe) ----------------------------------------\n\n protected paintContext() {\n const doc = this.state;\n return {\n objects: doc.objects,\n layers: doc.layers,\n dimStyles: doc.dimStyles,\n textStyles: doc.textStyles,\n blockDefinitions: doc.blockDefinitions,\n resolveObject: this.resolveObject(),\n resolveReference: this.resolveReference,\n };\n }\n\n protected resolveLayout(nameOrId: string): PaperLayout {\n const layout = this.state.layouts.find(\n (l) => l.name === nameOrId || l.id === nameOrId,\n );\n if (!layout) throw new Error(`Unknown layout \"${nameOrId}\"`);\n return layout;\n }\n\n /** Render model space (or a paper layout via `layout`) to an SVG string. */\n renderSvg(opts: RenderSvgOptions = {}): string {\n if (opts.layout !== undefined)\n return renderLayoutToSvg(\n this.resolveLayout(opts.layout),\n this.paintContext(),\n opts,\n );\n return renderModelToSvg(this.paintContext(), opts);\n }\n\n /** Export the document to a DXF string. */\n async toDxf(): Promise<string> {\n const { buildDxf } = await import(\"../export/dxf/exportDxf\");\n return buildDxf(this.state, this.measurer).content;\n }\n\n /** Export the document to DWG bytes (the DXF content, wasm-transcoded).\n * Defaults to AC1027 (AutoCAD 2013) — readable by every current CAD tool.\n * Dimensions transcode as real DIMENSION objects; leaders are exploded to\n * plain geometry (acadrust's MULTILEADER DWG output is unproven in real\n * CADs — exploded geometry always displays). */\n async toDwg(opts?: { version?: DwgVersion }): Promise<Uint8Array> {\n const { buildDxf } = await import(\"../export/dxf/exportDxf\");\n const dxf = buildDxf(this.state, this.measurer, {\n explodeLeaders: true,\n }).content;\n return dxfToDwg(dxf, opts?.version ?? \"AC1027\");\n }\n\n toLinea(): string {\n return documentToJson(this.state);\n }\n}\n","// Run one command module (`export default defineCommand({...})`) against a\n// Drawing — the ONE runner behind the editor palette, the SDK's\n// `runScript`/`runCommand`, and the `linea_run_script` tool. Declared\n// `inputs` are acquired first (picked through the EditorSurface when there\n// is one, otherwise they must be supplied), then the whole `run` executes\n// inside ONE `document.transaction`: mutations apply live (later picks can\n// snap to earlier edits) and a throw — the user pressing Escape in a pick,\n// or any error — rolls everything back. Scripts run unsandboxed in-process\n// (`new Function`, same as blocks); the host's trust toggle is the boundary.\n\nimport { Vec2Schema } from \"../model/common\";\nimport type { Vec2 } from \"../geometry/vec2\";\nimport {\n getCommandMetaResult,\n getCommandRun,\n type CommandMeta,\n} from \"../extensions/commandModules\";\nimport { ensureScriptTranspiler } from \"../extensions/scriptRuntime\";\nimport {\n HEX_COLOR,\n valueParams,\n type ValueParameter,\n} from \"../model/blockDefinition\";\nimport type { Drawing, EditorSurface, PointInput } from \"./types\";\n\nexport interface RunCommandOptions {\n document: Drawing;\n /** The interactive surface; absent for headless runs. */\n editor?: EditorSurface;\n /** Values for the command's declared `inputs` (label order). Missing\n * ones are picked in the editor, or the run fails without one. */\n inputs?: readonly PointInput[];\n /** Values for the command's declared `params` by name; omitted ones take\n * their defaults. Unknown names or wrong types are an error. */\n params?: Readonly<Record<string, unknown>>;\n}\n\nconst needsEditor = (what: string) => (): never => {\n throw new Error(`${what} needs an editor (this command runs headlessly)`);\n};\n\n/** The `ctx` handed to `run` — mirrors CommandContext in lineadraw.d.ts. */\nconst makeContext = (\n opts: RunCommandOptions,\n inputs: readonly Vec2[],\n params: Record<string, unknown>,\n): Record<string, unknown> => {\n const { document, editor } = opts;\n return {\n document,\n editor,\n inputs,\n params,\n // Deprecated shorthands (pre-`editor` wire form) — one release.\n pickPoint: editor\n ? (label?: string) => editor.pickPoint({ label })\n : needsEditor(\"pickPoint\"),\n pickObject: editor\n ? (label?: string) => editor.pickObject({ label })\n : needsEditor(\"pickObject\"),\n selection: editor\n ? () => editor.state().selectedIds\n : needsEditor(\"selection\"),\n setSelection: editor\n ? (ids: readonly string[]) => editor.setSelection(ids)\n : needsEditor(\"setSelection\"),\n prompt: editor\n ? (message: string, o?: { initial?: string; placeholder?: string }) =>\n editor.prompt(message, o)\n : needsEditor(\"prompt\"),\n showToast: editor\n ? (message: string, kind?: \"info\" | \"success\" | \"error\") =>\n editor.toast(message, kind)\n : () => {},\n };\n};\n\n/** Why `value` doesn't fit `def`, or null when it does. */\nconst paramMismatch = (def: ValueParameter, value: unknown): string | null => {\n switch (def.type) {\n case \"number\":\n if (typeof value !== \"number\" || !Number.isFinite(value))\n return \"expected a number\";\n if (def.integer && !Number.isInteger(value))\n return \"expected a whole number\";\n if (def.min !== undefined && value < def.min)\n return `below the minimum ${def.min}`;\n if (def.max !== undefined && value > def.max)\n return `above the maximum ${def.max}`;\n return null;\n case \"string\":\n case \"textStyle\":\n case \"dimStyle\":\n case \"font\":\n case \"lineType\":\n case \"hatchPattern\":\n // Resource ids / names: an unknown one falls back where it's used\n // (first style, default font…), like a stored object's would.\n return typeof value === \"string\" ? null : \"expected a string\";\n case \"boolean\":\n return typeof value === \"boolean\" ? null : \"expected true or false\";\n case \"numberList\": {\n if (\n !Array.isArray(value) ||\n !value.every((v) => typeof v === \"number\" && Number.isFinite(v))\n )\n return \"expected an array of numbers\";\n const low = value.find((v) => def.min !== undefined && v < def.min);\n if (low !== undefined) return `${low} is below the minimum ${def.min}`;\n const high = value.find((v) => def.max !== undefined && v > def.max);\n if (high !== undefined) return `${high} is above the maximum ${def.max}`;\n return null;\n }\n case \"color\":\n return typeof value === \"string\" && HEX_COLOR.test(value)\n ? null\n : 'expected a \"#rrggbb\" color';\n case \"stringList\":\n return Array.isArray(value) && value.every((v) => typeof v === \"string\")\n ? null\n : \"expected an array of strings\";\n case \"enum\":\n return def.options.some((o) => o.value === value)\n ? null\n : `expected one of ${def.options.map((o) => JSON.stringify(o.value)).join(\", \")}`;\n default:\n return \"a label carries no value\";\n }\n};\n\n/**\n * The `params` record `run` receives: each declared parameter's default,\n * overridden by `given` — which is checked strictly (an unknown name or a\n * value of the wrong type throws, naming the command and parameter), so a\n * headless or agent caller can't silently run with a typo.\n */\nexport const resolveCommandParams = (\n meta: CommandMeta,\n given: Readonly<Record<string, unknown>> = {},\n): Record<string, unknown> => {\n const defs = valueParams(meta.params ?? []);\n // Null prototype: a param named `constructor` stays a plain property.\n const params: Record<string, unknown> = Object.create(null);\n for (const def of defs) params[def.name] = def.default;\n for (const [name, value] of Object.entries(given)) {\n const def = defs.find((d) => d.name === name);\n if (!def)\n throw new Error(\n `${meta.name}: unknown parameter \"${name}\"${\n defs.length ? ` (declares ${defs.map((d) => d.name).join(\", \")})` : \"\"\n }`,\n );\n const mismatch = paramMismatch(def, value);\n if (mismatch)\n throw new Error(`${meta.name}: parameter \"${name}\" — ${mismatch}`);\n params[name] = value;\n }\n return params;\n};\n\n/**\n * Resolve a command's declared inputs: supplied values first (validated as\n * points), then editor picks for the rest (rubber-band from the previous\n * point). Without an editor, missing inputs are an error naming them.\n */\nexport const acquireCommandInputs = async (\n meta: CommandMeta,\n opts: RunCommandOptions,\n): Promise<Vec2[]> => {\n const labels = meta.inputs ?? [];\n const given = (opts.inputs ?? []).map((p, i) => {\n try {\n return Vec2Schema.parse(p);\n } catch {\n throw new Error(\n `${meta.name}: inputs[${i}] (${labels[i] ?? \"extra\"}) is not a point`,\n );\n }\n });\n if (given.length > labels.length)\n throw new Error(\n `${meta.name}: ${given.length} inputs supplied, declares ${labels.length}`,\n );\n const missing = labels.slice(given.length);\n if (missing.length === 0) return given;\n if (!opts.editor)\n throw new Error(\n `${meta.name} needs an editor for: ${missing.join(\", \")} — supply inputs`,\n );\n const points = [...given];\n for (const label of missing) {\n const referencePoint = points[points.length - 1];\n points.push(await opts.editor.pickPoint({ label, referencePoint }));\n }\n return points;\n};\n\n/**\n * Compile + run a command module source against a Drawing as ONE undo step.\n * Resolves with the script's return value; rejects with the script's error\n * (or the pick cancellation) after the transaction rolled back. Compile\n * errors reject before anything runs.\n */\nexport const runCommandModule = async (\n source: string,\n opts: RunCommandOptions,\n): Promise<unknown> => {\n await ensureScriptTranspiler();\n const result = getCommandMetaResult(source);\n if (!result.ok) throw new Error(`Command failed to compile: ${result.error}`);\n const run = getCommandRun(source);\n // Params before inputs: a bad value fails before the user picks anything.\n const params = resolveCommandParams(result.meta, opts.params);\n const inputs = await acquireCommandInputs(result.meta, opts);\n return opts.document.transaction(\n () => run(makeContext(opts, inputs, params)),\n result.meta.name,\n );\n};\n\n/** Run a DOCUMENT command (a module in `document.commands`) by exported id. */\nexport const runDocumentCommand = async (\n id: string,\n opts: RunCommandOptions,\n): Promise<unknown> => {\n await ensureScriptTranspiler();\n const source = opts.document.document.commands.find((s) => {\n const r = getCommandMetaResult(s);\n return r.ok && r.meta.id === id;\n });\n if (source === undefined) throw new Error(`Unknown document command \"${id}\"`);\n return runCommandModule(source, opts);\n};\n","// PNG rendering = SVG (renderSvg) rasterized with resvg. The rasterizer is a\n// NATIVE Node addon, so it is imported LAZILY: a static import would poison\n// the editor's browser bundle (which also consumes @lineadraw/core). This module\n// is therefore Node-only — call it from the SDK/CLI/server, never the editor.\n\nimport {\n renderLayoutToSvg,\n renderModelToSvg,\n type SvgRenderOptions,\n} from \"../svg/renderSvg\";\nimport type { LayoutModelContext } from \"../../paint/layoutPaint\";\nimport type { PaperLayout } from \"../../model/paperLayout\";\n\nexport interface PngRenderOptions extends SvgRenderOptions {\n /** Output width in px (height follows the aspect ratio). Default 1024. */\n width?: number;\n /** Background fill (SVG has none). Default matches the dark canvas so\n * as-authored colors stay visible; pass \"#ffffff\" / \"transparent\" to change. */\n background?: string;\n}\n\nconst rasterize = async (\n svg: string,\n width: number,\n background: string,\n): Promise<Uint8Array> => {\n // Lazy: keeps the native addon out of any browser bundle of @lineadraw/core.\n const { Resvg } = await import(\"@resvg/resvg-js\");\n const { embeddedFontFiles } = await import(\"../../fonts/embedded\");\n const resvg = new Resvg(svg, {\n fitTo: { mode: \"width\", value: Math.max(1, Math.round(width)) },\n background,\n // Bundled fonts (osifont & co. are not system fonts); system fonts stay\n // loaded so the Arial default still resolves.\n font: { fontFiles: embeddedFontFiles(), loadSystemFonts: true },\n });\n return resvg.render().asPng();\n};\n\n/** Render model space to a PNG (Node only). */\nexport const renderModelToPng = async (\n model: LayoutModelContext,\n opts: PngRenderOptions = {},\n): Promise<Uint8Array> =>\n rasterize(\n renderModelToSvg(model, opts),\n opts.width ?? 1024,\n opts.background ?? \"#1e1e1e\",\n );\n\n/** Render a paper layout to a PNG (Node only); white sheet background. */\nexport const renderLayoutToPng = async (\n layout: PaperLayout,\n model: LayoutModelContext,\n opts: PngRenderOptions = {},\n): Promise<Uint8Array> =>\n rasterize(\n renderLayoutToSvg(layout, model, opts),\n opts.width ?? 1024,\n opts.background ?? \"#ffffff\",\n );\n"],"mappings":"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AAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;A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","names":["angle","n","n","n","n","angle","len","pt","DEG2RAD","n","angle","scale","perp","angle","z","z","scale","pt","scale","rot","add","n","segments","add","n","scale","_","rot","n","len","rot","c","n","z","z","def","add","scale","n","z","z","n","z","z","layerId","objectIds","scale","angle","embeddedFontFiles"]}
|