compasso 0.1.0 → 0.2.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 +63 -8
- package/dist/{chunk-E456YKAJ.js → chunk-5B453C4P.js} +40 -10
- package/dist/chunk-5B453C4P.js.map +1 -0
- package/dist/{chunk-5RRRE2GF.js → chunk-5PGOL2KR.js} +3 -3
- package/dist/{chunk-5RRRE2GF.js.map → chunk-5PGOL2KR.js.map} +1 -1
- package/dist/{chunk-L5CYESBI.js → chunk-EHQMKVDM.js} +3 -3
- package/dist/{chunk-L5CYESBI.js.map → chunk-EHQMKVDM.js.map} +1 -1
- package/dist/chunk-P2S7AUOL.js +703 -0
- package/dist/chunk-P2S7AUOL.js.map +1 -0
- package/dist/chunk-TP3JOOJW.js +252 -0
- package/dist/chunk-TP3JOOJW.js.map +1 -0
- package/dist/core/index.cjs +44 -7
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +30 -30
- package/dist/core/index.d.ts +30 -30
- package/dist/core/index.js +1 -1
- package/dist/ecomap/index.cjs +11 -7
- package/dist/ecomap/index.cjs.map +1 -1
- package/dist/ecomap/index.js +2 -2
- package/dist/fault-tree/index.cjs +782 -0
- package/dist/fault-tree/index.cjs.map +1 -0
- package/dist/fault-tree/index.d.cts +148 -0
- package/dist/fault-tree/index.d.ts +148 -0
- package/dist/fault-tree/index.js +4 -0
- package/dist/fault-tree/index.js.map +1 -0
- package/dist/fishbone/index.cjs +314 -0
- package/dist/fishbone/index.cjs.map +1 -0
- package/dist/fishbone/index.d.cts +91 -0
- package/dist/fishbone/index.d.ts +91 -0
- package/dist/fishbone/index.js +4 -0
- package/dist/fishbone/index.js.map +1 -0
- package/dist/genogram/index.cjs +11 -7
- package/dist/genogram/index.cjs.map +1 -1
- package/dist/genogram/index.d.cts +3 -2
- package/dist/genogram/index.d.ts +3 -2
- package/dist/genogram/index.js +2 -2
- package/dist/index.cjs +1040 -36
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +5 -3
- package/dist/labels-CYbM5XV7.d.cts +83 -0
- package/dist/labels-CYbM5XV7.d.ts +83 -0
- package/dist/locales/pt-br.cjs +36 -0
- package/dist/locales/pt-br.cjs.map +1 -1
- package/dist/locales/pt-br.d.cts +6 -1
- package/dist/locales/pt-br.d.ts +6 -1
- package/dist/locales/pt-br.js +34 -1
- package/dist/locales/pt-br.js.map +1 -1
- package/dist/text-DuO_PwYw.d.cts +45 -0
- package/dist/text-DuO_PwYw.d.ts +45 -0
- package/dist/xml-DDae1eUr.d.cts +4 -0
- package/dist/xml-DDae1eUr.d.ts +4 -0
- package/package.json +70 -18
- package/dist/chunk-E456YKAJ.js.map +0 -1
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/core/xml.ts","../src/core/geometry.ts","../src/core/text.ts","../src/core/stroke.ts","../src/genogram/types.ts","../src/genogram/labels.ts","../src/genogram/kinship.ts","../src/genogram/layout.ts","../src/genogram/svg.ts","../src/genogram/render.ts","../src/ecomap/render.ts"],"names":["clampLabel","pathData","PADDING","EDGE_INK","LEGEND_ROW_H","LEGEND_PAD","LEGEND_SWATCH_W","LEGEND_GAP","LEGEND_FONT","w","h"],"mappings":"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","file":"index.cjs","sourcesContent":["// XML/SVG escaping — every interpolated text in an emitted SVG MUST pass through\n// this. Diagram labels are typically user/author-controlled, and the SVG string may\n// be injected via innerHTML in a browser or embedded as vectors in a PDF — an\n// unescaped label is an XSS / `</svg>`-breakout vector on every surface at once.\n\n/** Escapes a string for use in SVG/XML text content AND attribute values. */\nexport function xmlEscape(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","// Shared geometry primitives.\n\nexport interface Point {\n x: number;\n y: number;\n}\n\n/** \"M x y L x y …\" path data from a polyline. */\nexport function pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n","// Pure, deterministic text metrics — no DOM, no canvas, no font files. Every layout\n// in this library reserves space from these estimates and every emitter draws with\n// the same constants, so what is proven collision-free is what is drawn.\n\n/**\n * Conservative per-character advance, as a fraction of the font size. The pure module\n * can't measure real glyphs (no DOM/canvas), so it estimates width = chars * font *\n * CHAR_W. It is deliberately a touch WIDER than Helvetica's ~0.5 average advance: a\n * layout reserves slightly more room than the text needs, so the real render always\n * fits inside its reserved box.\n */\nexport const CHAR_W = 0.6;\n\n/** Pure, deterministic width estimate for a single line of text at `fontPx`. */\nexport function estimateTextWidth(text: string, fontPx: number): number {\n return text.length * fontPx * CHAR_W;\n}\n\n/**\n * Wraps a label onto up to TWO lines so long labels don't sprawl. Greedy word fill;\n * each line capped at `perLine` chars (…-truncated only if a single word overflows).\n * Pure + shared so every renderer wraps identically. The full text is always kept\n * elsewhere (the node's `label`, an SVG <title>, or a side list), so nothing is\n * silently lost.\n */\nexport function wrapLabel(label: string, perLine: number): string[] {\n if (label.length <= perLine) return [label];\n const cap = (s: string): string =>\n s.length > perLine ? s.slice(0, Math.max(1, perLine - 1)) + \"…\" : s;\n let line1 = \"\";\n let line2 = \"\";\n for (const word of label.split(/\\s+/)) {\n if (line2 === \"\" && (line1 === \"\" || (line1 + \" \" + word).length <= perLine)) {\n line1 = line1 === \"\" ? word : `${line1} ${word}`;\n } else {\n line2 = line2 === \"\" ? word : `${line2} ${word}`;\n }\n }\n return line2 === \"\" ? [cap(line1)] : [cap(line1), cap(line2)];\n}\n\n/** Caps a verbatim label for a COMPACT render (preview); full text kept by the caller. */\nexport function clampLabel(label: string, maxChars: number | undefined): string {\n if (maxChars === undefined || label.length <= maxChars) return label;\n return label.slice(0, Math.max(1, maxChars - 1)) + \"…\";\n}\n\n/** Font stack shared by every emitter; PDF embedders typically map it onto Helvetica. */\nexport const FONT_FAMILY = \"Helvetica, Arial, sans-serif\";\n","// Edge line styles — a neutral, presentation-only style for a relationship line.\n// NOT a judgment: a deterministic, lexical hint derived from the author's own quality\n// word. The literal word always rides the element's <title>, so a style never replaces\n// what was said. Unknown/ambiguous quality → \"plain\".\n\nexport type EdgeLineStyle = \"plain\" | \"close\" | \"distant\" | \"conflict\" | \"cutoff\";\n\n/** Stroke attributes per style — shared by every renderer so SVG and PDF match. */\nexport interface EdgeStroke {\n width: number;\n /** SVG dash array / PDF dash pattern as [dash, gap]; null = solid. */\n dash: [number, number] | null;\n opacity: number;\n}\n\nexport const EDGE_STROKE: Record<EdgeLineStyle, EdgeStroke> = {\n plain: { width: 1.5, dash: null, opacity: 0.6 },\n close: { width: 3, dash: null, opacity: 0.85 },\n distant: { width: 1.5, dash: [4, 4], opacity: 0.55 },\n conflict: { width: 2, dash: [2, 2], opacity: 0.75 },\n cutoff: { width: 1.5, dash: [6, 5], opacity: 0.4 },\n};\n\n/**\n * A pluggable lexicon mapping free-text quality words onto line styles. Needles are\n * diacritic-free, lowercase substrings of the author's own words; `negations` are\n * whole words that flip the meaning of the very word a needle would match (\"not\n * close\"), so their presence makes the matcher abstain to \"plain\" rather than risk\n * an inverted visual. Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface QualityLexicon {\n buckets: readonly { style: Exclude<EdgeLineStyle, \"plain\">; needles: readonly string[] }[];\n negations: readonly string[];\n}\n\n// English default. Conservative stems: each needle is a substring match on the\n// normalized text, and the SINGLE-BUCKET rule below keeps competing signals honest.\n// \"no\" alone is deliberately NOT a negation: \"no contact\" is a genuine cutoff signal.\nexport const QUALITY_LEXICON_EN: QualityLexicon = {\n buckets: [\n {\n style: \"close\",\n needles: [\"close\", \"warm\", \"support\", \"lov\", \"affection\", \"caring\", \"tight\", \"harmon\", \"healthy\"],\n },\n {\n style: \"distant\",\n needles: [\"distant\", \"detach\", \"absent\", \"cold\", \"drift\"],\n },\n {\n style: \"conflict\",\n needles: [\"conflict\", \"fight\", \"tens\", \"difficult\", \"hostil\", \"violen\", \"abus\", \"aggress\", \"complicat\", \"toxic\", \"argu\"],\n },\n {\n style: \"cutoff\",\n needles: [\"estrang\", \"cut off\", \"cutoff\", \"no contact\", \"broken off\", \"sever\"],\n },\n ],\n negations: [\"not\", \"never\", \"no longer\", \"hardly\"],\n};\n\n/** Lowercase + strip diacritics so matching ignores accents. */\nexport function normalizeText(text: string): string {\n return text.normalize(\"NFD\").replace(/[̀-ͯ]/g, \"\").toLowerCase();\n}\n\nconst escapeRegExp = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * Maps a free-text relationship quality to a neutral line style. Deterministic and\n * conservative: returns a specific style ONLY when exactly one lexical bucket matches;\n * null/empty/ambiguous/negated/unknown all fall back to \"plain\". The caller still\n * keeps the verbatim quality word, so nothing the author said is ever lost.\n */\nexport function qualityLineStyle(\n quality: string | null,\n lexicon: QualityLexicon = QUALITY_LEXICON_EN,\n): EdgeLineStyle {\n if (quality === null) return \"plain\";\n const haystack = normalizeText(quality);\n if (haystack.trim() === \"\") return \"plain\";\n\n if (lexicon.negations.length > 0) {\n const negation = new RegExp(`\\\\b(${lexicon.negations.map(escapeRegExp).join(\"|\")})\\\\b`);\n if (negation.test(haystack)) return \"plain\";\n }\n\n const matched: EdgeLineStyle[] = [];\n for (const { style, needles } of lexicon.buckets) {\n if (needles.some((n) => haystack.includes(n))) matched.push(style);\n }\n return matched.length === 1 ? matched[0]! : \"plain\";\n}\n","// Genogram input model — declared facts only. compasso draws EXACTLY what the caller\n// declares and NEVER synthesizes structure: two declared parents without a declared\n// union never merge into a couple; a \"coparental\" union draws no couple element; a\n// free-text relationship never silently becomes kinship. Collection doctrine (who may\n// assert a fact, how it was captured) is the caller's concern — this is a renderer.\n\n/** Sex marker for a genogram node (standard notation: square/circle/diamond). */\nexport type PersonSex = \"male\" | \"female\" | \"unknown\";\n\n/** A genogram node. `generation` is relative (0 = index person; negative = older). */\nexport interface Person {\n id: number;\n label: string;\n sex: PersonSex;\n deceased: boolean;\n generation: number | null;\n}\n\n/**\n * CLOSED status vocabulary for a declared union. Notable semantics:\n * - \"coparental\": the two were NEVER a couple and have child(ren) together;\n * - \"unknown\": a union was declared, but its type was not;\n * - widowhood is NOT a status — death lives on Person.deceased and never\n * alters the declared status;\n * - no value for \"not stated\": the union simply is not passed in.\n */\nexport const UNION_STATUSES = [\n \"married\",\n \"cohabiting\",\n \"dating\",\n \"separated\",\n \"divorced\",\n \"coparental\",\n \"unknown\",\n] as const;\n\nexport type UnionStatus = (typeof UNION_STATUSES)[number];\n\n/**\n * A declared couple bond between two people. The pair is unordered and expected\n * normalized to personAId < personBId with ONE union per pair (duplicates are the\n * caller's to resolve). `quality` is the author's verbatim wording about the bond.\n */\nexport interface Union {\n id: number;\n /** Always the smaller person id (normalized pair). */\n personAId: number;\n personBId: number;\n status: UnionStatus;\n quality: string | null;\n}\n\n/**\n * A declared parentage link: parent → child, one row PER DECLARED genitor (two\n * genitors = two links, each individually stated — never promoted from a union).\n */\nexport interface ParentLink {\n id: number;\n parentId: number;\n childId: number;\n quality: string | null;\n}\n\n/**\n * A typed free-text edge between two people. `type` and `quality` are verbatim\n * labels. This carries NON-STRUCTURAL ties only (closeness, conflict…) — unions\n * and parentage are first-class above.\n */\nexport interface Relationship {\n id: number;\n fromPersonId: number;\n toPersonId: number;\n type: string;\n quality: string | null;\n}\n\n/** Input to the genogram render pipeline. */\nexport interface GenogramInput {\n people: Person[];\n unions: Union[];\n parentLinks: ParentLink[];\n relationships: Relationship[];\n}\n\n/** Node glyph shapes (standard notation: square = male, circle = female, diamond = unknown). */\nexport type NodeShape = \"square\" | \"circle\" | \"diamond\";\n","// Display vocabularies — every human-readable string the genogram emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n\nimport type { EdgeLineStyle } from \"../core\";\nimport type { NodeShape, UnionStatus } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface GenogramTitleLabels {\n unionStatus: Record<UnionStatus, string>;\n /** Title prefix for a parent→child descent (\"parent of\"). */\n parentage: string;\n}\n\nexport const GENOGRAM_TITLE_LABELS_EN: GenogramTitleLabels = {\n unionStatus: {\n married: \"married\",\n cohabiting: \"cohabiting\",\n dating: \"dating\",\n separated: \"separated\",\n divorced: \"divorced\",\n coparental: \"co-parents (never a couple)\",\n unknown: \"union (type not stated)\",\n },\n parentage: \"parent of\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface GenogramSvgLabels {\n shapes: Record<NodeShape, string>;\n deceased: string;\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the group of people with no drawn connection. */\n isolated: string;\n ariaLabel: string;\n}\n\nexport const GENOGRAM_SVG_LABELS_EN: GenogramSvgLabels = {\n shapes: {\n square: \"Man\",\n circle: \"Woman\",\n diamond: \"Sex not stated\",\n },\n deceased: \"Deceased\",\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n isolated: \"No recorded ancestry\",\n ariaLabel: \"Family map (genogram)\",\n};\n","// Relationship → MAP class (presentation only). A genogram draws only the structural\n// SKELETON: declared unions + parent links. A free-text `relationship` becomes a map\n// LINE only when it is NON-parentage. Kinship that is READ FROM THE TREE (grandparent/\n// sibling/uncle/cousin/nephew…) draws NOTHING — it is already implied by the descent/\n// union structure, so a dedicated line would only duplicate and clutter. A DIRECT\n// parentage word (mother/father/child) with no declared parent link is PROMOTED to a\n// descent (oriented by declared generation) so the person is not orphaned. NOTHING here\n// synthesizes undeclared structure: derived kinship draws nothing at all, and promotion\n// only ORIENTS an already-declared parent-child word. The verbatim \"type · quality\" of\n// EVERY relationship is the caller's to keep showing in its own lists.\n\nimport { normalizeText } from \"../core\";\n\nexport type RelationshipMapClass = \"derived\" | \"parentage\" | \"bond\";\n\n/**\n * A pluggable kinship vocabulary. Tokens are diacritic-free, lowercase, matched WHOLE\n * (so a token never matches inside another word) after splitting the type on\n * non-alphanumerics (\"half-brother\" → [\"half\",\"brother\"]). Checked DERIVED-first, so\n * \"brother on my father's side\" reads as a sibling, never as a parent. These lists are\n * closed and conservative — an unrecognized word stays a non-structural bond (the\n * honest default). Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface KinshipLexicon {\n /** Kinship read from the tree (sibling/grandparent/uncle/cousin…): never a line. */\n derived: ReadonlySet<string>;\n /** Direct parentage words (mother/father/son…): promotable to a descent. */\n parentage: ReadonlySet<string>;\n /** Parentage words whose FROM endpoint is the CHILD — used only to orient a\n * promotion when declared generations do not decide it. */\n childWords: ReadonlySet<string>;\n}\n\nexport const KINSHIP_EN: KinshipLexicon = {\n derived: new Set([\n \"brother\", \"brothers\", \"sister\", \"sisters\", \"sibling\", \"siblings\",\n \"grandmother\", \"grandfather\", \"grandma\", \"grandpa\", \"granny\", \"grandad\",\n \"granddad\", \"grandparent\", \"grandparents\",\n \"grandson\", \"granddaughter\", \"grandchild\", \"grandchildren\",\n \"uncle\", \"uncles\", \"aunt\", \"aunts\", \"auntie\",\n \"cousin\", \"cousins\",\n \"nephew\", \"nephews\", \"niece\", \"nieces\",\n ]),\n parentage: new Set([\n \"mother\", \"mothers\", \"mom\", \"mum\", \"father\", \"fathers\", \"dad\",\n \"parent\", \"parents\",\n \"son\", \"sons\", \"daughter\", \"daughters\",\n ]),\n childWords: new Set([\"son\", \"sons\", \"daughter\", \"daughters\"]),\n};\n\n/** Lowercase + accent-stripped tokens of a free-text relationship type. */\nexport function relationshipTypeTokens(type: string): string[] {\n return normalizeText(type).split(/[^a-z0-9]+/).filter((t) => t !== \"\");\n}\n\n/**\n * Classifies a free-text relationship `type` for the MAP. Pure + deterministic.\n * Derived kinship is checked first so a compound like \"brother on my father's side\"\n * is read as a sibling (derived), never promoted as a parent. The verbatim word is\n * unaffected — this decides only whether the tie becomes a line, and which kind.\n */\nexport function classifyRelationshipType(\n type: string,\n kinship: KinshipLexicon = KINSHIP_EN,\n): RelationshipMapClass {\n const toks = relationshipTypeTokens(type);\n if (toks.some((t) => kinship.derived.has(t))) return \"derived\";\n if (toks.some((t) => kinship.parentage.has(t))) return \"parentage\";\n return \"bond\";\n}\n","// PURE genogram layout — the single source of truth for positioning and glyph/edge\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so it loads\n// identically in browsers, server runtimes and test environments, and the same input\n// always yields the same layout. Anything with a side effect belongs elsewhere.\n//\n// HONESTY RULE: this module only POSITIONS and ROUTES the facts the caller declared. It\n// computes NO score, interpretation, prognosis or diagnosis, and it NEVER synthesizes\n// undeclared structure: a `coparental` union draws no couple element; two declared\n// parents WITHOUT a declared union never merge into a couple-bar descent (each gets its\n// own descent); free-text `relationships` stay non-structural bonds. Shapes follow the\n// standard genogram convention (square = male, circle = female, diamond = unknown; a\n// diagonal stroke marks deceased). The verbatim \"type · quality\" / status label is\n// ALWAYS kept on every routed element's <title>, so a style never replaces what was said.\n//\n// LAYOUT — orthogonal (McGoldrick) and overlap-proof BY CONSTRUCTION (not by luck). The\n// diagram is a grid: people sit in COLUMNS inside generation ROWS; the empty bands\n// BETWEEN columns (GUTTERS) and BETWEEN rows (CORRIDORS) are the only places routing\n// segments live, each in a numbered LANE allocated by interval-overlap so two segments\n// in the same lane can never overlap. Every consecutive pair of waypoints is axis-aligned\n// (horizontal or vertical) — there are NO diagonals and NO text on map edges (the\n// verbatim text rides the <title> and the caller's side lists). Glyphs and their labels\n// live entirely inside their columns; gutters and corridors are content-free by\n// construction, so a routed segment can never cross a glyph or a label box.\n//\n// PROVENANCE: descends from the production genogram renderer the author wrote for the\n// Ventory project (same copyright holder); developed independently of any third-party\n// diagram engine.\nimport {\n CHAR_W,\n estimateTextWidth,\n qualityLineStyle,\n wrapLabel,\n EDGE_STROKE,\n type EdgeLineStyle,\n type EdgeStroke,\n type Point,\n type QualityLexicon,\n} from \"../core\";\nimport { GENOGRAM_TITLE_LABELS_EN, type GenogramTitleLabels } from \"./labels\";\nimport {\n classifyRelationshipType,\n relationshipTypeTokens,\n KINSHIP_EN,\n type KinshipLexicon,\n type RelationshipMapClass,\n} from \"./kinship\";\nimport type {\n NodeShape,\n ParentLink,\n Person,\n PersonSex,\n Relationship,\n Union,\n} from \"./types\";\n\n// Re-exports so callers (and the emitter) can reach the full vocabulary through this\n// module, mirroring the original single-file layout.\nexport { CHAR_W, estimateTextWidth, qualityLineStyle, wrapLabel, EDGE_STROKE };\nexport type { EdgeLineStyle, EdgeStroke, Point, QualityLexicon };\nexport { classifyRelationshipType, relationshipTypeTokens, KINSHIP_EN };\nexport type { KinshipLexicon, RelationshipMapClass };\nexport type { NodeShape };\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\nexport const NODE_SIZE = 56;\nconst PADDING = 32;\n/** Min horizontal gap between two adjacent columns' content boxes (a gutter's base). */\nconst COL_PAD = 30;\n/** Gap from a glyph's bottom to the top of its first label line. */\nconst LABEL_GAP_TOP = 8;\n/** Base height of a routing corridor (before lanes widen it). */\nconst CORRIDOR_BASE = 24;\n/** Vertical/horizontal spacing between two routing lanes in a corridor/gutter. */\nconst LANE_H = 8;\n/** Vertical drop between successive serial-union (remarriage) bars below the glyph row,\n * so 2+ unions on one person never read as one continuous rail (McGoldrick, FIX B). */\nconst UNION_STAGGER = 12;\n/** Horizontal offset (from glyph center, toward the partner) of a dipped union-bar's stub,\n * so a person in two serial unions gets two distinct stub columns (FIX B). < NODE_SIZE/2. */\nconst STUB_X_OFF = 14;\n/** Extra horizontal separation placed before an isolated-people group (SPEC). */\nconst ISOLATED_GUTTER_EXTRA = 2 * COL_PAD;\n\n// ── Type metrics (shared by layout AND both renderers, so geometry == render) ──\n/** Node label font size (px). The live SVG renders at this size; the PDF scales it. */\nexport const LABEL_FONT = 12;\n/** Line height for stacked node-label lines (px). */\nexport const LABEL_LINE_H = 14;\n/** Edge label font size (px) — kept for the shared metrics contract (invariant #9). */\nexport const EDGE_FONT = 11;\n// CHAR_W / estimateTextWidth live in ../core (re-exported above): the overlap-proof\n// guarantee depends on layout and emitters sharing these exact metrics.\n\n// ── Namespaced element ids (kept stable so data-edge-id stays traceable, §7.2) ──\n// relationships keep their own id; unions live at 1_000_000+id; parent links at\n// 2_000_000+id; PROMOTED descents (a direct-parentage free-text relationship drawn as a\n// descent — see classifyRelationshipType) at 3_000_000+rel id. Four disjoint blocks, so a\n// promoted descent never collides with a real parent link and every edge stays traceable\n// to its source. Deterministic, and visible in the overlap harness / data-edge-id.\nexport const UNION_REL_ID_BASE = 1_000_000;\nexport const PARENT_REL_ID_BASE = 2_000_000;\nexport const PROMOTED_REL_ID_BASE = 3_000_000;\n\n// ── Node glyphs ──────────────────────────────────────────────────────────────\nfunction shapeForSex(sex: PersonSex): NodeShape {\n if (sex === \"male\") return \"square\";\n if (sex === \"female\") return \"circle\";\n return \"diamond\";\n}\n\n// ── Edge line styles ─────────────────────────────────────────────────────────\n// EdgeLineStyle / EDGE_STROKE / qualityLineStyle live in ../core (re-exported above):\n// a neutral, presentation-only style for a NON-STRUCTURAL bond line, lexically hinted\n// from the author's own quality word — never a judgment, verbatim word always kept.\n\n/**\n * Per-edge VISUAL union style applied at emission (§7.2 / FIX 3) — the McGoldrick\n * notation for a declared union TYPE, WITHOUT touching the layout or the patient's\n * words. `coparental` never gets one (it draws no edge). Defined here (not in\n * fallback-svg) so a routed element can carry it and the emitter stays free of layout\n * cycles; fallback-svg re-exports it for the existing call sites.\n */\nexport interface UnionEdgeStyle {\n /** Inline stroke-dasharray [dash, gap] on the bar; absent = solid (e.g. casado). */\n dash?: readonly [number, number];\n /** Diagonal status slashes at the midpoint: 1 = separação, 2 = divórcio. */\n slashes?: 0 | 1 | 2;\n}\n\n// ── Relationship → MAP class ───────────────────────────────────────────────────\n// classifyRelationshipType / relationshipTypeTokens / KinshipLexicon live in ./kinship\n// (re-exported above): derived kinship draws NOTHING, direct parentage may be PROMOTED\n// to a descent, everything else stays a non-structural bond. wrapLabel lives in ../core.\n\n/** Wrap policy: split a label into roughly-balanced lines bounded to a sane width. */\nfunction wrapNodeLabel(displayLabel: string): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n/** Caps a verbatim label for a COMPACT render (preview); full text kept in `label`. */\nfunction clampLabel(label: string, maxChars: number | undefined): string {\n if (maxChars === undefined || label.length <= maxChars) return label;\n return label.slice(0, Math.max(1, maxChars - 1)) + \"…\";\n}\n\n// ── Positioned layout ────────────────────────────────────────────────────────\n\nexport interface GenogramNode {\n personId: number;\n /** Full, verbatim label (used for tooltips/aria — never truncated). */\n label: string;\n shape: NodeShape;\n deceased: boolean;\n /** Center of the node. */\n cx: number;\n cy: number;\n /** Side length (square) / diameter (circle) / width (diamond). */\n size: number;\n /** Pre-wrapped display lines (already capped for the requested density). */\n labelLines: string[];\n /** Y of the TOP of the first label line's box (each next line is +LABEL_LINE_H). */\n labelTop: number;\n}\n\n/** A routed map element — the orthogonal replacement for the old straight `GenogramEdge`. */\nexport type GenogramElementKind =\n | \"union-bar\" // adjacent same-row partners: straight H bar, glyph-edge to glyph-edge\n | \"union-elbow\" // non-adjacent / cross-row partners: orthogonal route\n | \"descent\" // parent(s) → child plumbing segment(s)\n | \"sibling-bar\" // one shared H bar per union child-group (≥1 children)\n | \"bond\"; // non-structural relationship, orthogonal route\n\nexport interface GenogramElement {\n kind: GenogramElementKind;\n /** Source row ids for traceability; merged bonds carry every merged rel id. */\n relIds: number[];\n /** data-edge-id value: highest relId (matches latestUnionPerPair's highest-wins). */\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n /** Polyline; EVERY consecutive pair is axis-aligned (H or V). */\n points: Point[];\n /** Verbatim titles (one per source row), joined for the <title>. */\n titles: string[];\n lineStyle: EdgeLineStyle; // bonds only; structural elements are \"plain\"\n unionStyle?: UnionEdgeStyle; // union-bar / union-elbow: dash + slashes\n dotted?: boolean; // lone-parent / coparental descents\n}\n\nexport interface GenogramLayout {\n width: number;\n height: number;\n nodes: GenogramNode[];\n elements: GenogramElement[];\n /** People with NO drawn structural/bond connection — grouped to the side and labeled\n * \"Sem ascendência registrada\" so a loose glyph is never left unexplained. */\n isolatedPersonIds: number[];\n}\n\n// ── Internal working types ─────────────────────────────────────────────────────\n\n/**\n * A parent→child descent to draw — either a DECLARED parent_link (real) or a PROMOTED\n * direct-parentage relationship (no declared link existed for the pair). `edgeId` is\n * pre-namespaced (real: PARENT_REL_ID_BASE+link id; promoted: PROMOTED_REL_ID_BASE+rel id),\n * so both flow through the same descent machinery and stay traceable in data-edge-id.\n */\ninterface LayoutLink {\n parentId: number;\n childId: number;\n quality: string | null;\n edgeId: number;\n}\n\ninterface Measured {\n person: Person;\n lines: string[];\n /** max(NODE_SIZE, widest wrapped line) — the horizontal footprint. */\n contentW: number;\n}\n\n/** A vertical segment living in a gutter, awaiting a lane. */\ninterface GutterReq {\n gutter: number; // gutter index g in [-1, colCount-1]\n side: -1 | 0 | 1; // -1 hug left column, +1 hug right column, 0 center (union spine)\n rowLo: number; // continuous row coordinate (row r → r; corridor k → k+0.5)\n rowHi: number;\n lane: number; // filled by the allocator\n}\n\n/** A horizontal segment living in a corridor, awaiting a lane. Its pixel x-interval is\n * resolved AFTER the column/gutter geometry is fixed, so the lane allocator can use the\n * EXACT extent (a u-index proxy collapses for within-one-gutter spans). */\ninterface CorridorReq {\n corridor: number; // corridor index k in [0, rowCount-1] (k = below row k)\n xRange: () => [number, number]; // pixel [xMin, xMax], resolved post-column-geometry\n lane: number;\n}\n\n/** A sideways glyph departure stub, awaiting a height slot. */\ninterface StubReq {\n personId: number;\n side: -1 | 1;\n slot: number; // height slot index, filled below\n}\n\n/** An arrival into a glyph TOP, awaiting an x-offset slot. */\ninterface ArrivalReq {\n personId: number;\n slot: number;\n}\n\n/** A planned element: its kind/metadata + a builder that resolves to pixel points. */\ninterface PlannedElement {\n kind: GenogramElementKind;\n relIds: number[];\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n titles: string[];\n lineStyle: EdgeLineStyle;\n unionStyle?: UnionEdgeStyle;\n dotted?: boolean;\n build: () => Point[];\n}\n\n// Height slots for stacked departures from one glyph side (avoid y=cy so a union bar at\n// cy is never crossed). Within ±(NODE_SIZE/2 − 4) so the stub stays on the glyph edge.\nconst STUB_OFFSETS = [9, -9, 18, -18, 26, -26] as const;\n/** Max |x-offset| for an arrival into a glyph TOP (kept inside the top edge half-width). */\nconst ARRIVAL_HALF = NODE_SIZE / 2 - 8;\n\nfunction stubOffset(slot: number): number {\n return STUB_OFFSETS[Math.min(slot, STUB_OFFSETS.length - 1)]!;\n}\n/** Spread arrivals across a glyph TOP so each lands on a distinct x — slot 0 stays\n * CENTERED (the primary descent), later arrivals alternate to either side. For any\n * fan-in count, no two verticals share a column (overlap-proof). */\nfunction arrivalOffset(slot: number, total: number): number {\n if (slot === 0 || total <= 1) return 0;\n const step = Math.min(12, ARRIVAL_HALF / Math.max(1, Math.ceil((total - 1) / 2)));\n const sign = slot % 2 === 1 ? -1 : 1;\n return sign * Math.ceil(slot / 2) * step;\n}\n\n/** Allocate lanes for a set of intervals: each takes the lowest lane free over its span\n * (touching at an endpoint does NOT count as overlap, so collinear segments may abut). */\nfunction allocateLanes(items: { lo: number; hi: number; set: (lane: number) => void }[]): number {\n const lanes: { lo: number; hi: number }[][] = [];\n for (const it of items) {\n let chosen = -1;\n for (let l = 0; l < lanes.length; l++) {\n if (lanes[l]!.every((o) => it.hi <= o.lo || it.lo >= o.hi)) {\n chosen = l;\n break;\n }\n }\n if (chosen === -1) {\n chosen = lanes.length;\n lanes.push([]);\n }\n lanes[chosen]!.push({ lo: it.lo, hi: it.hi });\n it.set(chosen);\n }\n return lanes.length;\n}\n\n/**\n * Deterministic, overlap-proof ORTHOGONAL layout (pure function of the inputs — same\n * data always yields the same geometry). People are grouped by `generation` (null trails\n * as a bottom row), rows ordered oldest-on-top. Declared structure is drawn as McGoldrick\n * elements: same-row adjacent unions as straight bars, couples-with-children as a shared\n * sibling bar, lone/co-parental genitors as dotted descents, and free-text relationships\n * as orthogonally-routed bonds — NEVER promoting a bond into structure.\n *\n * @param unions caller-deduped (one per pair) declared couple bonds.\n * @param parentLinks declared parent→child links (one row per declared genitor).\n * @param relationships non-structural ties (drawn as bonds).\n * @param opts.maxLabelChars cap each node's DISPLAY label to this many chars (compact\n * preview); the full verbatim text is still exposed on `node.label`.\n * @param opts.kinship / opts.qualityLexicon / opts.titleLabels — locale packs (English\n * defaults; see `compasso/locales/pt-br`).\n */\nexport interface GenogramLayoutOptions {\n maxLabelChars?: number;\n kinship?: KinshipLexicon;\n qualityLexicon?: QualityLexicon;\n titleLabels?: GenogramTitleLabels;\n}\n\nexport function computeGenogramLayout(\n people: Person[],\n unions: Union[],\n parentLinks: ParentLink[],\n relationships: Relationship[],\n opts: GenogramLayoutOptions = {},\n): GenogramLayout {\n const kinship = opts.kinship ?? KINSHIP_EN;\n const titleLabels = opts.titleLabels ?? GENOGRAM_TITLE_LABELS_EN;\n if (people.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], elements: [], isolatedPersonIds: [] };\n }\n\n const ids = new Set(people.map((p) => p.id));\n const pairKey = (a: number, b: number): string => `${Math.min(a, b)}|${Math.max(a, b)}`;\n const genById = new Map<number, number | null>(people.map((p) => [p.id, p.generation]));\n\n // Sanitize structural inputs (drop self/missing endpoints — keep declared facts only).\n const validUnions = unions\n .filter((u) => ids.has(u.personAId) && ids.has(u.personBId) && u.personAId !== u.personBId)\n .sort((a, b) => a.id - b.id);\n const coupleUnions = validUnions.filter((u) => u.status !== \"coparental\");\n const validLinks = parentLinks\n .filter((l) => ids.has(l.parentId) && ids.has(l.childId) && l.parentId !== l.childId)\n .sort((a, b) => a.id - b.id);\n const validRels = relationships\n .filter((r) => ids.has(r.fromPersonId) && ids.has(r.toPersonId) && r.fromPersonId !== r.toPersonId)\n .sort((a, b) => a.id - b.id);\n\n // ── SKELETON-ONLY (presentation): classify each free-text relationship for the MAP ─────\n // - \"derived\" (avó/irmão/tio/…): READ from the tree → draws NOTHING here.\n // - \"parentage\" (mãe/pai/filho/…): a declared parent-child word → PROMOTED to a descent\n // when no parent_link already declares the pair (else a duplicate, dropped\n // from the map); never a bond.\n // - \"bond\" (everything else): a non-structural tie → drawn as a bond, as before.\n // The verbatim \"type · quality\" of EVERY relationship still rides the dossier side lists.\n const relClass = new Map<number, RelationshipMapClass>(\n validRels.map((r) => [r.id, classifyRelationshipType(r.type, kinship)]),\n );\n const bondRels = validRels.filter((r) => relClass.get(r.id) === \"bond\");\n const parentageRels = validRels.filter((r) => relClass.get(r.id) === \"parentage\");\n\n // Effective descents = declared parent_links (real) + promoted parentage relationships.\n const realLinks: LayoutLink[] = validLinks.map((l) => ({\n parentId: l.parentId,\n childId: l.childId,\n quality: l.quality,\n edgeId: PARENT_REL_ID_BASE + l.id,\n }));\n const declaredPairs = new Set(validLinks.map((l) => pairKey(l.parentId, l.childId)));\n const promotedByPair = new Map<string, LayoutLink>();\n for (const r of parentageRels) {\n const key = pairKey(r.fromPersonId, r.toPersonId);\n if (declaredPairs.has(key)) continue; // already a declared parent_link → no double-draw\n if (promotedByPair.has(key)) continue; // same pair stated twice → one descent (id-order)\n // Orient parent→child by DECLARED generation (older = parent). When generations do not\n // decide (equal or null), fall back to the parentage WORD + the declared from/to:\n // mãe/pai → from is the parent; filho/filha → from is the child. Either way nothing is\n // invented — both endpoints and the parent-child nature were declared; only the arrow.\n const ga = genById.get(r.fromPersonId) ?? null;\n const gb = genById.get(r.toPersonId) ?? null;\n let parentId: number;\n let childId: number;\n if (ga !== null && gb !== null && ga !== gb) {\n [parentId, childId] = ga < gb ? [r.fromPersonId, r.toPersonId] : [r.toPersonId, r.fromPersonId];\n } else {\n const fromIsChild = relationshipTypeTokens(r.type).some((t) => kinship.childWords.has(t));\n [parentId, childId] = fromIsChild ? [r.toPersonId, r.fromPersonId] : [r.fromPersonId, r.toPersonId];\n }\n if (parentId === childId) continue;\n promotedByPair.set(key, { parentId, childId, quality: r.quality, edgeId: PROMOTED_REL_ID_BASE + r.id });\n }\n const allLinks: LayoutLink[] = [...realLinks, ...promotedByPair.values()].sort((a, b) => a.edgeId - b.edgeId);\n\n // Declared (non-coparental) union lookup by unordered pair → union.\n const coupleByPair = new Map<string, Union>();\n for (const u of coupleUnions) coupleByPair.set(pairKey(u.personAId, u.personBId), u);\n\n // Parents per child and links per (parent,child) — real links + promoted descents.\n const parentsOf = new Map<number, number[]>();\n const linkOf = new Map<string, LayoutLink>();\n for (const l of allLinks) {\n const arr = parentsOf.get(l.childId) ?? [];\n if (!arr.includes(l.parentId)) arr.push(l.parentId);\n parentsOf.set(l.childId, arr);\n linkOf.set(`${l.parentId}>${l.childId}`, l);\n }\n\n // A person is ISOLATED when they have NO drawn connection: no union, no descent (real or\n // promoted), and no bond. A relationship suppressed from the map (derived kinship like\n // \"minha tia\", read from the tree) does NOT count as a tie — so such a person is grouped\n // to the side and labeled \"Sem ascendência registrada\", never left as a loose glyph.\n const hasTie = new Set<number>();\n for (const u of validUnions) {\n hasTie.add(u.personAId);\n hasTie.add(u.personBId);\n }\n for (const l of allLinks) {\n hasTie.add(l.parentId);\n hasTie.add(l.childId);\n }\n for (const r of bondRels) {\n hasTie.add(r.fromPersonId);\n hasTie.add(r.toPersonId);\n }\n const isIsolated = (id: number): boolean => !hasTie.has(id);\n\n // ── Pass 1a: rows by declared generation (null last), oldest on top ──────────────\n const byGen = new Map<number | null, Person[]>();\n for (const p of people) {\n const bucket = byGen.get(p.generation);\n if (bucket === undefined) byGen.set(p.generation, [p]);\n else bucket.push(p);\n }\n const genKeys = [...byGen.keys()].sort((a, b) => {\n if (a === null) return 1;\n if (b === null) return -1;\n return a - b;\n });\n const rowCount = genKeys.length;\n const rowOfPerson = new Map<number, number>();\n genKeys.forEach((g, r) => byGen.get(g)!.forEach((p) => rowOfPerson.set(p.id, r)));\n\n // ── Pass 1b: couple BLOCKS per row (connected components of same-row couple unions),\n // linearized so partners land adjacent; then barycenter ordering; isolated rightmost.\n type Block = number[]; // person ids, left-to-right\n const rowBlocks: Block[][] = genKeys.map((g, r) => {\n const members = byGen.get(g)!.map((p) => p.id);\n // adjacency from same-row couple unions\n const adj = new Map<number, number[]>();\n for (const id of members) adj.set(id, []);\n for (const u of coupleUnions) {\n if (rowOfPerson.get(u.personAId) === r && rowOfPerson.get(u.personBId) === r) {\n adj.get(u.personAId)!.push(u.personBId);\n adj.get(u.personBId)!.push(u.personAId);\n }\n }\n for (const id of members) adj.get(id)!.sort((a, b) => a - b);\n // connected components\n const seen = new Set<number>();\n const blocks: Block[] = [];\n for (const start of [...members].sort((a, b) => a - b)) {\n if (seen.has(start)) continue;\n const comp: number[] = [];\n const stack = [start];\n seen.add(start);\n while (stack.length > 0) {\n const n = stack.pop()!;\n comp.push(n);\n for (const m of adj.get(n)!) if (!seen.has(m)) { seen.add(m); stack.push(m); }\n }\n blocks.push(linearizeBlock(comp, adj));\n }\n return blocks;\n });\n\n // Barycenter sweeps (downward then upward), gated on rowCount ≥ 2. Aesthetic only —\n // it reorders blocks to align children under parents; it never moves anyone off a row.\n const flattened = (): Map<number, number> => {\n const pos = new Map<number, number>();\n for (const blocks of rowBlocks) {\n let c = 0;\n for (const b of blocks) for (const id of b) pos.set(id, c++);\n }\n return pos;\n };\n const structuralNeighbors = (id: number): number[] => {\n const out: { id: number; w: number }[] = [];\n // Barycenter ordering uses NON-coparental unions only (SPEC Pass 1 / FIX E): a\n // coparental pair draws no couple bar, so it must exert no ordering attraction either.\n for (const u of coupleUnions) {\n if (u.personAId === id) out.push({ id: u.personBId, w: 1 });\n else if (u.personBId === id) out.push({ id: u.personAId, w: 1 });\n }\n for (const l of allLinks) {\n if (l.childId === id) out.push({ id: l.parentId, w: 1 });\n else if (l.parentId === id) out.push({ id: l.childId, w: 1 });\n }\n for (const rl of bondRels) {\n if (rl.fromPersonId === id) out.push({ id: rl.toPersonId, w: 0.5 });\n else if (rl.toPersonId === id) out.push({ id: rl.fromPersonId, w: 0.5 });\n }\n return out.map((o) => o.id);\n };\n const neighborWeight = (id: number, other: number): number => {\n let w = 0;\n // NON-coparental unions only — same FIX E rationale as structuralNeighbors.\n for (const u of coupleUnions) if ((u.personAId === id && u.personBId === other) || (u.personBId === id && u.personAId === other)) w = Math.max(w, 1);\n for (const l of allLinks) if ((l.childId === id && l.parentId === other) || (l.parentId === id && l.childId === other)) w = Math.max(w, 1);\n for (const rl of bondRels) if ((rl.fromPersonId === id && rl.toPersonId === other) || (rl.toPersonId === id && rl.fromPersonId === other)) w = Math.max(w, 0.5);\n return w;\n };\n const sweep = (r: number, ref: number): void => {\n const pos = flattened();\n const blocks = rowBlocks[r]!;\n const bcOf = (b: Block): number => {\n let sum = 0;\n let wsum = 0;\n for (const id of b) {\n for (const nb of structuralNeighbors(id)) {\n if (rowOfPerson.get(nb) !== ref) continue;\n const w = neighborWeight(id, nb);\n sum += (pos.get(nb) ?? 0) * w;\n wsum += w;\n }\n }\n return wsum === 0 ? Number.POSITIVE_INFINITY : sum / wsum;\n };\n const keyed = blocks.map((b) => ({ b, bc: bcOf(b), minId: Math.min(...b) }));\n keyed.sort((x, y) => (x.bc !== y.bc ? x.bc - y.bc : x.minId - y.minId));\n rowBlocks[r] = keyed.map((k) => k.b);\n };\n if (rowCount >= 2) {\n for (let r = 1; r < rowCount; r++) sweep(r, r - 1);\n for (let r = rowCount - 2; r >= 0; r--) sweep(r, r + 1);\n }\n\n // Isolated people drift fully right: stable-partition each row so isolated singleton\n // blocks trail the connected ones (ordered by id). No connector is ever drawn for them.\n for (let r = 0; r < rowCount; r++) {\n const blocks = rowBlocks[r]!;\n const connected = blocks.filter((b) => !(b.length === 1 && isIsolated(b[0]!)));\n const isolated = blocks.filter((b) => b.length === 1 && isIsolated(b[0]!)).sort((a, b) => a[0]! - b[0]!);\n rowBlocks[r] = [...connected, ...isolated];\n }\n\n // ── Pass 1c: assign (row, col) to every person via the global column grid ─────────\n const colOf = new Map<number, number>();\n let colCount = 0;\n for (let r = 0; r < rowCount; r++) {\n let c = 0;\n for (const b of rowBlocks[r]!) for (const id of b) colOf.set(id, c++);\n colCount = Math.max(colCount, c);\n }\n const colOrThrow = (id: number): number => colOf.get(id)!;\n\n // Column where the isolated-only tail begins (extra gutter sits just before it).\n let isolatedTailCol = colCount; // none by default\n {\n const peopleAtCol: number[][] = Array.from({ length: colCount }, () => []);\n for (const p of people) peopleAtCol[colOrThrow(p.id)]!.push(p.id);\n for (let c = colCount - 1; c >= 1; c--) {\n const all = peopleAtCol[c]!;\n if (all.length > 0 && all.every((id) => isIsolated(id))) isolatedTailCol = c;\n else break;\n }\n }\n\n // ── Pass 2 prep: measure labels; column widths; per-row label heights ─────────────\n const measured = new Map<number, Measured>();\n for (const p of people) {\n const lines = wrapNodeLabel(clampLabel(p.label, opts.maxLabelChars));\n const contentW = Math.max(NODE_SIZE, lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, LABEL_FONT)), 0));\n measured.set(p.id, { person: p, lines, contentW });\n }\n const colWidth: number[] = Array.from({ length: colCount }, () => NODE_SIZE);\n for (const p of people) {\n const c = colOrThrow(p.id);\n colWidth[c] = Math.max(colWidth[c]!, measured.get(p.id)!.contentW);\n }\n const rowMaxLines: number[] = Array.from({ length: rowCount }, () => 1);\n for (const p of people) {\n const r = rowOfPerson.get(p.id)!;\n rowMaxLines[r] = Math.max(rowMaxLines[r]!, measured.get(p.id)!.lines.length);\n }\n\n // ── Pass 2: route every element symbolically and register lane/slot requests ──────\n const planned: PlannedElement[] = [];\n const gutterReqs: GutterReq[] = [];\n const corridorReqs: CorridorReq[] = [];\n const stubCount = new Map<string, number>(); // `${id}:${side}` → slots used\n const arrivalCount = new Map<number, number>(); // id → arrival slots used\n\n const newStub = (personId: number, side: -1 | 1): StubReq => {\n const key = `${personId}:${side}`;\n const slot = stubCount.get(key) ?? 0;\n stubCount.set(key, slot + 1);\n return { personId, side, slot };\n };\n const newArrival = (personId: number): ArrivalReq => {\n const slot = arrivalCount.get(personId) ?? 0;\n arrivalCount.set(personId, slot + 1);\n return { personId, slot };\n };\n const departSide = (srcId: number, dstId: number): -1 | 1 => {\n const sc = colOrThrow(srcId);\n const dc = colOrThrow(dstId);\n if (dc > sc) return 1;\n if (dc < sc) return -1;\n return sc < colCount - 1 ? 1 : -1;\n };\n // The gutter a connector departs INTO, and which side of it the departing column is on.\n const gutterFor = (srcCol: number, side: -1 | 1): { gutter: number; gSide: -1 | 1 } =>\n side === 1\n ? { gutter: srcCol, gSide: -1 } // depart right → gutter to the right; src is its LEFT column\n : { gutter: srcCol - 1, gSide: 1 }; // depart left → gutter to the left; src is its RIGHT column\n\n // A cross-row connector: sideways stub from the UPPER node, gutter drop, corridor cross,\n // arrival into the LOWER glyph TOP. Returns a builder closure over the resolved geo.\n // Robust to either argument order: it routes from whichever node is in the SHALLOWER\n // (upper) declared generation, so a parent declared in a YOUNGER generation than the\n // child (srcRow > dstRow) still gets a valid, non-negative, in-range corridor and an\n // ordered gutter span instead of a negative index (FIX D-1). Normal upper→lower calls\n // are unchanged: the upper node is the source and corridor = lowerRow − 1 as before.\n const planConnector = (\n srcId: number,\n dstId: number,\n arrivalAtCenter: boolean,\n ): (() => Point[]) => {\n const srcRow = rowOfPerson.get(srcId)!;\n const dstRow = rowOfPerson.get(dstId)!;\n // Departure is always from the upper node; arrival into the lower node's TOP edge.\n const [upperId, lowerId] = srcRow <= dstRow ? [srcId, dstId] : [dstId, srcId];\n const upperRow = rowOfPerson.get(upperId)!;\n const lowerRow = rowOfPerson.get(lowerId)!;\n const side = departSide(upperId, lowerId);\n const { gutter, gSide } = gutterFor(colOrThrow(upperId), side);\n const stub = newStub(upperId, side);\n // Corridor just above the lower row, clamped in-range (degenerate same-row → band 0).\n const corridor = Math.max(0, Math.min(rowCount - 1, lowerRow - 1));\n const gReq: GutterReq = {\n gutter,\n side: gSide,\n rowLo: Math.min(upperRow, corridor + 0.5),\n rowHi: Math.max(upperRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(gReq);\n const arrival = arrivalAtCenter ? null : newArrival(lowerId);\n const arrivalX = (): number =>\n geo.cx(colOrThrow(lowerId)) + (arrival ? arrivalOffset(arrival.slot, arrivalCount.get(lowerId) ?? 1) : 0);\n const cReq: CorridorReq = {\n corridor,\n xRange: () => {\n const gx = geo.gutterLaneX(gReq);\n const ax = arrivalX();\n return [Math.min(gx, ax), Math.max(gx, ax)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const sy = geo.cy(upperRow) + stubOffset(stub.slot);\n const sEdge = side === 1 ? geo.glyphRight(upperId) : geo.glyphLeft(upperId);\n const gx = geo.gutterLaneX(gReq);\n const cyCorr = geo.corridorLaneY(cReq);\n const ax = arrivalX();\n const topY = geo.cy(lowerRow) - NODE_SIZE / 2;\n return [\n { x: sEdge, y: sy },\n { x: gx, y: sy },\n { x: gx, y: cyCorr },\n { x: ax, y: cyCorr },\n { x: ax, y: topY },\n ];\n };\n };\n\n // A same-row connector (U under the row): both endpoints leave sideways toward each\n // other, drop into the corridor below the row, and cross there.\n const planUConnector = (aId: number, bId: number): (() => Point[]) => {\n const row = rowOfPerson.get(aId)!;\n const [leftId, rightId] = colOrThrow(aId) <= colOrThrow(bId) ? [aId, bId] : [bId, aId];\n const stubL = newStub(leftId, 1);\n const stubR = newStub(rightId, -1);\n const gL = gutterFor(colOrThrow(leftId), 1);\n const gR = gutterFor(colOrThrow(rightId), -1);\n const gReqL: GutterReq = { gutter: gL.gutter, side: gL.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n const gReqR: GutterReq = { gutter: gR.gutter, side: gR.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n gutterReqs.push(gReqL, gReqR);\n const cReq: CorridorReq = {\n corridor: row,\n xRange: () => {\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n return [Math.min(xL, xR), Math.max(xL, xR)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const yL = geo.cy(row) + stubOffset(stubL.slot);\n const yR = geo.cy(row) + stubOffset(stubR.slot);\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n const cyCorr = geo.corridorLaneY(cReq);\n return [\n { x: geo.glyphRight(leftId), y: yL },\n { x: xL, y: yL },\n { x: xL, y: cyCorr },\n { x: xR, y: cyCorr },\n { x: xR, y: yR },\n { x: geo.glyphLeft(rightId), y: yR },\n ];\n };\n };\n\n const unionTitle = (u: Union): string =>\n u.quality !== null\n ? `${titleLabels.unionStatus[u.status]} · ${u.quality}`\n : titleLabels.unionStatus[u.status];\n const linkTitle = (l: { quality: string | null }): string =>\n l.quality !== null ? `${titleLabels.parentage} · ${l.quality}` : titleLabels.parentage;\n\n // 2a. Unions: same-row adjacent → bar; otherwise → elbow. (coparental drew nothing.)\n // McGoldrick SERIAL-UNION staggering (FIX B): when a person is in 2+ same-row union-bars\n // (remarriage), the bars would all sit at glyph-center cy and read as ONE continuous\n // rail. So within each connected chain of adjacent bars (components sharing a person),\n // the LOWEST union id stays at cy (level 0) and every other bar DIPS to a distinct depth\n // below the row's glyphs (level k → glyph bottom + k·UNION_STAGGER), drawn as a 3-seg\n // elbow (stub-down from each partner's glyph bottom → across → stub-up). The dip depth\n // is reserved in the row band (`rowDipDepth`) so labels never collide.\n const unionIsBar = new Map<number, boolean>();\n const barUnions = coupleUnions.filter(\n (u) =>\n rowOfPerson.get(u.personAId) === rowOfPerson.get(u.personBId) &&\n Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1,\n );\n // Per row, connected components of adjacent bar-unions (sharing a person), each ordered\n // by union id; index 0 → level 0 (cy), index k → dip level k. Deterministic.\n const unionDipLevel = new Map<number, number>(); // union id → dip level (0 = at cy)\n const rowDipLevels: number[] = Array.from({ length: rowCount }, () => 0);\n {\n const byRow = new Map<number, Union[]>();\n for (const u of barUnions) {\n const r = rowOfPerson.get(u.personAId)!;\n (byRow.get(r) ?? byRow.set(r, []).get(r)!).push(u);\n }\n for (const [r, rowUnions] of byRow) {\n // person → adjacent bar-unions on this row\n const unionsOfPerson = new Map<number, Union[]>();\n for (const u of rowUnions) {\n (unionsOfPerson.get(u.personAId) ?? unionsOfPerson.set(u.personAId, []).get(u.personAId)!).push(u);\n (unionsOfPerson.get(u.personBId) ?? unionsOfPerson.set(u.personBId, []).get(u.personBId)!).push(u);\n }\n const seen = new Set<number>();\n // Stable component discovery: walk unions in ascending id; BFS the shared-person graph.\n for (const start of [...rowUnions].sort((a, b) => a.id - b.id)) {\n if (seen.has(start.id)) continue;\n const comp: Union[] = [];\n const stack = [start];\n seen.add(start.id);\n while (stack.length > 0) {\n const u = stack.pop()!;\n comp.push(u);\n for (const pid of [u.personAId, u.personBId]) {\n for (const nb of unionsOfPerson.get(pid) ?? []) {\n if (!seen.has(nb.id)) {\n seen.add(nb.id);\n stack.push(nb);\n }\n }\n }\n }\n comp.sort((a, b) => a.id - b.id);\n comp.forEach((u, i) => unionDipLevel.set(u.id, i));\n rowDipLevels[r] = Math.max(rowDipLevels[r]!, comp.length - 1);\n }\n }\n }\n\n for (const u of coupleUnions) {\n const aRow = rowOfPerson.get(u.personAId)!;\n const bRow = rowOfPerson.get(u.personBId)!;\n const adjacent =\n aRow === bRow && Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1;\n unionIsBar.set(u.id, adjacent);\n const edgeId = UNION_REL_ID_BASE + u.id;\n if (adjacent) {\n const [leftId, rightId] = colOrThrow(u.personAId) < colOrThrow(u.personBId)\n ? [u.personAId, u.personBId]\n : [u.personBId, u.personAId];\n const dipLevel = unionDipLevel.get(u.id) ?? 0;\n planned.push({\n kind: \"union-bar\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n build: () => {\n const cy = geo.cy(rowOfPerson.get(leftId)!);\n if (dipLevel === 0) {\n // First bar of the chain: the classic straight bar at glyph-center cy.\n return [\n { x: geo.glyphRight(leftId), y: cy },\n { x: geo.glyphLeft(rightId), y: cy },\n ];\n }\n // Dipped bar: stub-down from each partner's glyph BOTTOM to the dipped Y, across.\n // The stubs leave the glyph bottom OFFSET toward the partner (left partner →\n // right-of-center, right partner → left-of-center), so a person in two serial\n // unions (one on each side) gets two distinct stub columns that never overlap.\n const y = geo.unionDipY(rowOfPerson.get(leftId)!, dipLevel);\n const bottom = cy + NODE_SIZE / 2;\n const lx = geo.cx(colOrThrow(leftId)) + STUB_X_OFF; // partner is to the right\n const rx = geo.cx(colOrThrow(rightId)) - STUB_X_OFF; // partner is to the left\n return [\n { x: lx, y: bottom },\n { x: lx, y },\n { x: rx, y },\n { x: rx, y: bottom },\n ];\n },\n });\n } else {\n const sameRow = aRow === bRow;\n const build = sameRow\n ? planUConnector(u.personAId, u.personBId)\n : (() => {\n const [up, lo] = aRow < bRow ? [u.personAId, u.personBId] : [u.personBId, u.personAId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"union-elbow\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n build,\n });\n }\n }\n\n // 2b. Descents. Decide, per child, the single declared COUPLE pair (if any) whose\n // union is an adjacent bar; that pair gets the shared sibling-bar descent, every\n // other declared genitor gets a dotted lone descent. No declared couple → all\n // dotted (Caso B / co-parental): each genitor its own descent, never a bar.\n const coupleChildrenByUnion = new Map<number, number[]>(); // union id → children\n const loneLinks: LayoutLink[] = [];\n for (const childId of [...parentsOf.keys()].sort((a, b) => a - b)) {\n const parents = [...parentsOf.get(childId)!].sort((a, b) => a - b);\n const couplePairUnions = parents\n .flatMap((p, i) => parents.slice(i + 1).map((q) => coupleByPair.get(pairKey(p, q))))\n .filter((u): u is Union => u !== undefined && unionIsBar.get(u.id) === true);\n if (couplePairUnions.length === 1) {\n const u = couplePairUnions[0]!;\n const arr = coupleChildrenByUnion.get(u.id) ?? [];\n arr.push(childId);\n coupleChildrenByUnion.set(u.id, arr);\n const couplePeople = new Set([u.personAId, u.personBId]);\n for (const p of parents) if (!couplePeople.has(p)) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n } else {\n for (const p of parents) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n }\n }\n\n // Couple descents (processed first, by union id): one shared sibling-bar per child-row\n // group, a center spine from the bar, and a vertical drop to each child's glyph TOP.\n for (const u of coupleUnions) {\n const children = coupleChildrenByUnion.get(u.id);\n if (children === undefined || children.length === 0) continue;\n const leftId = colOrThrow(u.personAId) < colOrThrow(u.personBId) ? u.personAId : u.personBId;\n const interGutter = colOrThrow(leftId); // gutter between the two adjacent partners\n const parentRow = rowOfPerson.get(u.personAId)!;\n // A couple descent must leave the union BAR, so on a dipped (serial-union) bar the\n // spine starts at the dipped bar's Y, not the glyph-center cy (FIX B).\n const uDipLevel = unionDipLevel.get(u.id) ?? 0;\n const spineStartY = (): number =>\n uDipLevel === 0 ? geo.cy(parentRow) : geo.unionDipY(parentRow, uDipLevel);\n // Group children by their row (almost always one row).\n const byChildRow = new Map<number, number[]>();\n for (const c of children) {\n const cr = rowOfPerson.get(c)!;\n (byChildRow.get(cr) ?? byChildRow.set(cr, []).get(cr)!).push(c);\n }\n for (const childRow of [...byChildRow.keys()].sort((a, b) => a - b)) {\n const groupKids = byChildRow.get(childRow)!.sort((a, b) => colOrThrow(a) - colOrThrow(b));\n // Corridor just above the child row; clamped in-range so a degenerate \"couple + child\n // all on generation 0\" (childRow === 0) routes in band 0 instead of corridor[-1]\n // (undefined) — defensive, no fixture triggers it (FIX D-2).\n const corridor = Math.max(0, Math.min(rowCount - 1, childRow - 1));\n // The descent lives in ONE corridor lane shared by the spine, sibling bar and the\n // child drops, spanning the spine column and every child column.\n const sibSpan = (): number[] => [geo.gutterCenterX(interGutter), ...groupKids.map((c) => geo.cx(colOrThrow(c)))];\n const sibReq: CorridorReq = {\n corridor,\n xRange: () => {\n const xs = sibSpan();\n return [Math.min(...xs), Math.max(...xs)];\n },\n lane: 0,\n };\n corridorReqs.push(sibReq);\n const spineReq: GutterReq = {\n gutter: interGutter,\n side: 0,\n rowLo: Math.min(parentRow, corridor + 0.5), // ordered (FIX D-2): never inverted\n rowHi: Math.max(parentRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(spineReq);\n const aId = (c: number): number => linkOf.get(`${u.personAId}>${c}`)!.edgeId;\n // A child drop represents ONE declared parentage link (the given parent → c). Its\n // data-edge-id AND its <title> both come from THAT link, so the verbatim parentage\n // (incl. any quality word) matches what the drop's id declares (FIX C-1) — never a\n // hardcoded B-side title under an A-side id.\n const childDrop = (c: number, parentId: number): void => {\n const link = linkOf.get(`${parentId}>${c}`)!;\n const edgeId = link.edgeId;\n const arr = newArrival(c); // couples are processed first → claims the CENTER slot\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: null,\n toPersonId: c,\n titles: [linkTitle(link)],\n lineStyle: \"plain\",\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const x = geo.cx(colOrThrow(c)) + arrivalOffset(arr.slot, arrivalCount.get(c) ?? 1);\n return [\n { x, y },\n { x, y: geo.cy(rowOfPerson.get(c)!) - NODE_SIZE / 2 },\n ];\n },\n });\n };\n\n if (groupKids.length === 1) {\n // Single child: spine + bar-to-child is ONE elbow (parent A's link), the drop is\n // the other (parent B's link) — exactly two data-edge-id groups, one per declared\n // parentage (the verify-sweep 1:1 traceability contract), same pixels as a bar.\n const c = groupKids[0]!;\n planned.push({\n kind: \"descent\",\n relIds: [aId(c)],\n edgeId: aId(c),\n fromPersonId: null,\n toPersonId: null,\n titles: [linkTitle(linkOf.get(`${u.personAId}>${c}`)!)],\n lineStyle: \"plain\",\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const sx = geo.gutterCenterX(interGutter);\n const cx = geo.cx(colOrThrow(c));\n return [\n { x: sx, y: spineStartY() },\n { x: sx, y: sy },\n { x: cx, y: sy },\n ];\n },\n });\n childDrop(c, u.personBId);\n } else {\n // ≥2 children: one shared sibling bar + one spine + a drop per child. Each child's\n // drop carries its B-side parentage id; the sibling bar carries A[0] (and traces\n // every remaining A-side link in relIds), the spine carries A[1] — distinct\n // data-edge-id per group, every declared link present in relIds.\n const aLinks = groupKids.map((c) => aId(c));\n // The verbatim A-side parentage title for child c (incl. any quality word).\n const aLinkTitle = (c: number): string => linkTitle(linkOf.get(`${u.personAId}>${c}`)!);\n planned.push({\n kind: \"sibling-bar\",\n relIds: [aLinks[0]!, ...aLinks.slice(2)],\n edgeId: aLinks[0]!,\n fromPersonId: null,\n toPersonId: null,\n // Carry the verbatim title of EVERY A-side link this bar represents, so no\n // declared quality word is dropped from the drawn element (FIX C-2 / SPEC inv #4).\n titles: [aLinkTitle(groupKids[0]!), ...groupKids.slice(2).map(aLinkTitle)],\n lineStyle: \"plain\",\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const xs = sibSpan();\n return [\n { x: Math.min(...xs), y },\n { x: Math.max(...xs), y },\n ];\n },\n });\n planned.push({\n kind: \"descent\",\n relIds: [aLinks[1]!],\n edgeId: aLinks[1]!,\n fromPersonId: null,\n toPersonId: null,\n titles: [aLinkTitle(groupKids[1]!)], // the A-side link this spine carries, verbatim\n lineStyle: \"plain\",\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const x = geo.gutterCenterX(interGutter);\n return [\n { x, y: spineStartY() },\n { x, y: sy },\n ];\n },\n });\n for (const c of groupKids) childDrop(c, u.personBId);\n }\n }\n }\n\n // Lone / co-parental descents (dotted), by edge id (real before promoted, deterministic).\n for (const l of [...loneLinks].sort((a, b) => a.edgeId - b.edgeId)) {\n const edgeId = l.edgeId;\n const pRow = rowOfPerson.get(l.parentId)!;\n const cRow = rowOfPerson.get(l.childId)!;\n const build = pRow === cRow\n ? planUConnector(l.parentId, l.childId)\n : planConnector(l.parentId, l.childId, false);\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: l.parentId,\n toPersonId: l.childId,\n titles: [linkTitle(l)],\n lineStyle: \"plain\",\n dotted: true,\n build,\n });\n }\n\n // 2c. Bonds (free-text relationships), with the honesty-safe merge: same unordered\n // pair AND same computed lineStyle merge into one drawn element; different styles\n // draw separately (merging would have to pick one side's style).\n const bondGroups = new Map<string, { relIds: number[]; titles: string[]; style: EdgeLineStyle; aId: number; bId: number }>();\n for (const r of bondRels) {\n const style = qualityLineStyle(r.quality, opts.qualityLexicon);\n const lo = Math.min(r.fromPersonId, r.toPersonId);\n const hi = Math.max(r.fromPersonId, r.toPersonId);\n const key = `${lo}|${hi}|${style}`;\n const title = r.quality !== null ? `${r.type} · ${r.quality}` : r.type;\n const g = bondGroups.get(key);\n if (g === undefined) {\n bondGroups.set(key, { relIds: [r.id], titles: [title], style, aId: r.fromPersonId, bId: r.toPersonId });\n } else {\n g.relIds.push(r.id);\n g.titles.push(title);\n }\n }\n const bondList = [...bondGroups.values()].sort((a, b) => Math.max(...a.relIds) - Math.max(...b.relIds));\n for (const g of bondList) {\n const aRow = rowOfPerson.get(g.aId)!;\n const bRow = rowOfPerson.get(g.bId)!;\n const build = aRow === bRow\n ? planUConnector(g.aId, g.bId)\n : (() => {\n const [up, lo] = aRow < bRow ? [g.aId, g.bId] : [g.bId, g.aId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"bond\",\n relIds: g.relIds,\n edgeId: Math.max(...g.relIds),\n fromPersonId: g.aId,\n toPersonId: g.bId,\n titles: g.titles,\n lineStyle: g.style,\n build,\n });\n }\n\n // ── Pass 3: staged geometry so corridor lanes are allocated on EXACT pixel x ───────\n // Mutable geometry state, filled stage by stage; the build/xRange closures (created in\n // Pass 2) read it through `geo` at call time only — never before its stage fills it.\n const colCenterX: number[] = [];\n const colLeftX: number[] = [];\n const colRightX: number[] = [];\n const rowCenterY: number[] = [];\n const rowLabelTopY: number[] = [];\n const corridorTopY: number[] = [];\n const dims = { width: 0 };\n const gutterLaneCount = new Map<string, number>(); // `${gutter}:${side}` → count\n const corridorLaneCount: number[] = Array.from({ length: rowCount }, () => 0);\n const laneCount = (gutter: number, side: -1 | 0 | 1): number => gutterLaneCount.get(`${gutter}:${side}`) ?? 0;\n\n const geo = {\n cx: (c: number): number => colCenterX[c]!,\n cy: (r: number): number => rowCenterY[r]!,\n glyphRight: (id: number): number => colCenterX[colOrThrow(id)]! + NODE_SIZE / 2,\n glyphLeft: (id: number): number => colCenterX[colOrThrow(id)]! - NODE_SIZE / 2,\n gutterCenterX: (g: number): number => {\n const left = g < 0 ? PADDING : colRightX[g]!;\n const right = g >= colCount - 1 ? dims.width - PADDING : colLeftX[g + 1]!;\n return (left + right) / 2;\n },\n gutterLaneX: (req: GutterReq): number => {\n const left = req.gutter < 0 ? PADDING : colRightX[req.gutter]!;\n const right = req.gutter >= colCount - 1 ? dims.width - PADDING : colLeftX[req.gutter + 1]!;\n const lCount = laneCount(req.gutter, -1);\n if (req.side === -1) return left + (req.lane + 1) * LANE_H; // hug left, stack rightward\n if (req.side === 0) return left + (lCount + req.lane + 1) * LANE_H; // center group (spine)\n return right - (req.lane + 1) * LANE_H; // hug right, stack leftward\n },\n corridorLaneY: (req: CorridorReq): number =>\n corridorTopY[req.corridor]! + CORRIDOR_BASE / 2 + req.lane * LANE_H,\n /** Y of a dipped serial-union bar (level ≥ 1): below the row's glyph bottom edge. */\n unionDipY: (r: number, level: number): number =>\n rowCenterY[r]! + NODE_SIZE / 2 + level * UNION_STAGGER,\n };\n\n // Stage 1 — gutter lanes: per (gutter, side), by row-span interval. Left-hug and\n // right-hug stacks sit on opposite sides; the center group is the union spine.\n const gutterGroups = new Map<string, GutterReq[]>();\n for (const req of gutterReqs) {\n const k = `${req.gutter}:${req.side}`;\n (gutterGroups.get(k) ?? gutterGroups.set(k, []).get(k)!).push(req);\n }\n for (const [k, reqs] of gutterGroups) {\n gutterLaneCount.set(\n k,\n allocateLanes(reqs.map((req) => ({ lo: req.rowLo, hi: req.rowHi, set: (lane: number) => (req.lane = lane) }))),\n );\n }\n\n // Stage 2 — column geometry from gutter lane counts (+ the isolated extra gutter).\n const gutterWidth = (g: number): number => {\n const lanes = laneCount(g, -1) + laneCount(g, 0) + laneCount(g, 1);\n const extra = g === isolatedTailCol - 1 ? ISOLATED_GUTTER_EXTRA : 0;\n if (g === -1 || g === colCount - 1) return lanes > 0 ? COL_PAD + lanes * LANE_H + extra : extra;\n return COL_PAD + lanes * LANE_H + extra;\n };\n let cursorX = PADDING + gutterWidth(-1);\n for (let c = 0; c < colCount; c++) {\n colLeftX[c] = cursorX;\n colCenterX[c] = cursorX + colWidth[c]! / 2;\n cursorX += colWidth[c]!;\n colRightX[c] = cursorX;\n cursorX += gutterWidth(c);\n }\n dims.width = cursorX + PADDING;\n\n // Stage 3 — corridor lanes on EXACT pixel x-ranges (columns are now placed, so a\n // within-one-gutter span is measured precisely — no collapsing u-index proxy).\n const corridorGroups = new Map<number, CorridorReq[]>();\n for (const req of corridorReqs) (corridorGroups.get(req.corridor) ?? corridorGroups.set(req.corridor, []).get(req.corridor)!).push(req);\n for (const [k, reqs] of corridorGroups) {\n corridorLaneCount[k] = allocateLanes(\n reqs.map((req) => {\n const [lo, hi] = req.xRange();\n return { lo, hi, set: (lane: number) => (req.lane = lane) };\n }),\n );\n }\n\n // Stage 4 — row geometry from corridor lane counts.\n const corridorHeight = (k: number): number => {\n const lanes = corridorLaneCount[k] ?? 0;\n if (lanes > 0) return CORRIDOR_BASE + lanes * LANE_H;\n return k < rowCount - 1 ? CORRIDOR_BASE : 0; // interior rows always keep a gap\n };\n // Reserve a band BELOW each row's glyphs for its dipped serial-union bars (FIX B), so\n // labels sit below the deepest dip and never collide. 0 when the row has no remarriage.\n const rowDipReserve = (r: number): number =>\n rowDipLevels[r]! > 0 ? rowDipLevels[r]! * UNION_STAGGER + 6 : 0;\n let cursorY = PADDING;\n for (let r = 0; r < rowCount; r++) {\n rowCenterY[r] = cursorY + NODE_SIZE / 2;\n rowLabelTopY[r] = cursorY + NODE_SIZE + rowDipReserve(r) + LABEL_GAP_TOP;\n cursorY = rowLabelTopY[r]! + rowMaxLines[r]! * LABEL_LINE_H;\n corridorTopY[r] = cursorY;\n cursorY += corridorHeight(r);\n }\n const width = dims.width;\n const height = cursorY + PADDING;\n\n // ── Build nodes + finalize elements ──────────────────────────────────────────────\n const nodes: GenogramNode[] = [...people]\n .sort((a, b) => a.id - b.id)\n .map((p) => {\n const m = measured.get(p.id)!;\n const r = rowOfPerson.get(p.id)!;\n const c = colOrThrow(p.id);\n return {\n personId: p.id,\n label: p.label,\n shape: shapeForSex(p.sex),\n deceased: p.deceased,\n cx: colCenterX[c]!,\n cy: rowCenterY[r]!,\n size: NODE_SIZE,\n labelLines: m.lines,\n labelTop: rowLabelTopY[r]!,\n };\n });\n\n const elements: GenogramElement[] = planned.map((pl) => ({\n kind: pl.kind,\n relIds: pl.relIds,\n edgeId: pl.edgeId,\n fromPersonId: pl.fromPersonId,\n toPersonId: pl.toPersonId,\n points: pl.build(),\n titles: pl.titles,\n lineStyle: pl.lineStyle,\n ...(pl.unionStyle !== undefined ? { unionStyle: pl.unionStyle } : {}),\n ...(pl.dotted ? { dotted: true } : {}),\n }));\n\n // People with no drawn connection (only-suppressed/derived ties, or none at all).\n const isolatedPersonIds = people\n .filter((p) => isIsolated(p.id))\n .map((p) => p.id)\n .sort((a, b) => a - b);\n\n return { width, height, nodes, elements, isolatedPersonIds };\n}\n\n/** Linearize a connected couple-component so partners land adjacent. A simple path is\n * walked from its lowest-id endpoint (→ a clean chain); anything else is DFS-ordered\n * from the lowest id (hub gets two adjacent partners; the rest become union-elbows). */\nfunction linearizeBlock(comp: number[], adj: Map<number, number[]>): number[] {\n if (comp.length <= 1) return [...comp];\n const inComp = new Set(comp);\n const degree = (id: number): number => adj.get(id)!.filter((n) => inComp.has(n)).length;\n const endpoints = comp.filter((id) => degree(id) === 1).sort((a, b) => a - b);\n const edgeCount = comp.reduce((s, id) => s + degree(id), 0) / 2;\n const isPath = edgeCount === comp.length - 1 && endpoints.length === 2;\n const order: number[] = [];\n const seen = new Set<number>();\n if (isPath) {\n let cur: number | undefined = endpoints[0]!;\n while (cur !== undefined) {\n order.push(cur);\n seen.add(cur);\n cur = adj.get(cur)!.filter((n) => inComp.has(n)).sort((a, b) => a - b).find((n) => !seen.has(n));\n }\n return order;\n }\n const stack = [Math.min(...comp)];\n while (stack.length > 0) {\n const n = stack.pop()!;\n if (seen.has(n)) continue;\n seen.add(n);\n order.push(n);\n for (const m of adj.get(n)!.filter((x) => inComp.has(x)).sort((a, b) => b - a)) {\n if (!seen.has(m)) stack.push(m);\n }\n }\n return order;\n}\n","// Genogram SVG emitter — turns a computed GenogramLayout (./layout.ts, the pure\n// orthogonal declared-generation layout) into a SELF-CONTAINED SVG string.\n//\n// Two hard requirements:\n// - XML-ESCAPING of EVERY interpolated text. Labels are author-controlled and the\n// SVG string may be injected via innerHTML in a browser or embedded as vectors in\n// a PDF — an unescaped label is an XSS/`</svg>`-breakout vector on every surface.\n// - LITERAL presentation attributes (hex colors, inline stroke-dasharray, an explicit\n// font-family). A standalone SVG inside a PDF has no stylesheet, no `currentColor`.\n//\n// It is deliberately PURE (string in, string out) and DETERMINISTIC (same layout → same\n// SVG), and it draws EXACTLY what the layout computed: node centers and the routed\n// orthogonal polylines are consumed verbatim, never recomputed (the overlap harness\n// proves the layout; this emitter is pinned to it). Decoration hooks for callers: one\n// `<g data-individual-id=\"p<id>\">` per person with a direct-child `<title>` and bare\n// rect/circle/polygon glyph; `data-edge-id` on every routed group.\n//\n// HONESTY RULE: presentation only. There is ZERO text on map edges — the verbatim\n// \"type · quality\" / status label lives in each routed group's <title> (and the\n// caller's side lists). The one styling decision the CALLER may make is\n// `unionStyleByRelId`: a per-edge VISUAL override applied at emission — a\n// stroke-dasharray and/or McGoldrick status slashes — giving each declared union TYPE\n// the full notation (married solid, cohabiting/dating dashed, separated one slash,\n// divorced two) without the layout fabricating any quality text.\nimport { FONT_FAMILY, xmlEscape } from \"../core\";\nimport {\n EDGE_STROKE,\n LABEL_FONT,\n LABEL_LINE_H,\n estimateTextWidth,\n type GenogramElement,\n type GenogramLayout,\n type NodeShape,\n type Point,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { GENOGRAM_SVG_LABELS_EN, type GenogramSvgLabels } from \"./labels\";\n\n// Re-export so callers can reach the union-notation type through the emitter module.\nexport type { UnionEdgeStyle } from \"./layout\";\nexport { xmlEscape };\n\n// Literal ink colors (zinc ramp, matching the app shell on white — the PDF page).\nconst GLYPH_STROKE = \"#52525b\";\nconst NODE_LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\n// Structural (union / descent / sibling-bar) stroke — neutral, solid.\nconst STRUCT_WIDTH = 1.5;\nconst STRUCT_OPACITY = 0.75;\n// Dotted descent (lone-parent / co-parental): the visual kin of schematex's secondary.\nconst DOTTED_DASH: readonly [number, number] = [2, 3];\nconst DOTTED_OPACITY = 0.55;\n\n// Legend metrics (own, minimal — pt-BR only).\nconst LEGEND_ROW_H = 18;\nconst LEGEND_PAD = 16;\nconst LEGEND_SWATCH_W = 22;\nconst LEGEND_GAP = 14; // swatch → label gap (the \"Boxo\" fix: was 8, too tight)\nconst LEGEND_FONT = 11;\n\nexport interface GenogramSvgOptions {\n /**\n * Per-edge VISUAL union style (edgeId → {dash?, slashes?}), applied at emission.\n * Gives each declared union TYPE its own McGoldrick notation. Overrides any\n * `unionStyle` already on the element.\n */\n unionStyleByRelId?: ReadonlyMap<number, UnionEdgeStyle>;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: GenogramSvgLabels;\n}\n\n/** Glyph markup for one shape centered at (cx, cy) with the given half-size. */\nfunction glyphSvg(shape: NodeShape, cx: number, cy: number, half: number): string {\n const stroke = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n if (shape === \"square\") {\n return `<rect x=\"${cx - half}\" y=\"${cy - half}\" width=\"${half * 2}\" height=\"${half * 2}\" rx=\"4\" ${stroke}/>`;\n }\n if (shape === \"circle\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${half}\" ${stroke}/>`;\n }\n return `<polygon points=\"${cx},${cy - half} ${cx + half},${cy} ${cx},${cy + half} ${cx - half},${cy}\" ${stroke}/>`;\n}\n\n/** \"M x y L x y …\" path data from an orthogonal polyline. */\nfunction pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n\n/** The longest horizontal segment of a polyline (for placing union-elbow slashes). */\nfunction longestHSegment(points: Point[]): [Point, Point] {\n let best: [Point, Point] = [points[0]!, points[points.length - 1]!];\n let bestLen = -1;\n for (let i = 0; i + 1 < points.length; i++) {\n const a = points[i]!;\n const b = points[i + 1]!;\n if (a.y === b.y) {\n const len = Math.abs(b.x - a.x);\n if (len > bestLen) {\n bestLen = len;\n best = [a, b];\n }\n }\n }\n return best;\n}\n\n/**\n * McGoldrick status slashes at the midpoint of a segment (1 = separação, 2 = divórcio),\n * drawn in screen-space \"/\" orientation and offset along the segment for the two divorce\n * strokes. Same ink/width as the bar so the mark reads as part of it.\n */\nfunction slashMarks(a: Point, b: Point, count: 1 | 2, width: number): string {\n const mx = (a.x + b.x) / 2;\n const my = (a.y + b.y) / 2;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const len = Math.hypot(dx, dy) || 1;\n const ux = dx / len;\n const uy = dy / len;\n const HALF = 7; // slash half-length\n const STEP = 4; // along-segment offset between the two divorce slashes\n const offsets = count === 1 ? [0] : [-STEP, STEP];\n return offsets\n .map((o) => {\n const px = mx + ux * o;\n const py = my + uy * o;\n return `<line x1=\"${px - HALF}\" y1=\"${py + HALF}\" x2=\"${px + HALF}\" y2=\"${py - HALF}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\"/>`;\n })\n .join(\"\");\n}\n\n/** Resolve a union element's effective McGoldrick style (override wins over element). */\nfunction resolveUnionStyle(\n el: GenogramElement,\n override: ReadonlyMap<number, UnionEdgeStyle>,\n): UnionEdgeStyle {\n return override.get(el.edgeId) ?? el.unionStyle ?? {};\n}\n\n/** Emits one routed element as a `<g data-edge-id>` group (≥3 points → path, else line),\n * with the verbatim titles in a <title> and ZERO text. */\nfunction elementSvg(el: GenogramElement, override: ReadonlyMap<number, UnionEdgeStyle>): string {\n const title = `<title>${xmlEscape(el.titles.join(\"\\n\"))}</title>`;\n const pts = el.points;\n const drawLine = (dash: readonly [number, number] | null, width: number, opacity: number): string => {\n const dashAttr = dash === null ? \"\" : ` stroke-dasharray=\"${dash[0]} ${dash[1]}\"`;\n if (pts.length === 2) {\n return `<line x1=\"${pts[0]!.x}\" y1=\"${pts[0]!.y}\" x2=\"${pts[1]!.x}\" y2=\"${pts[1]!.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n }\n return `<path d=\"${pathData(pts)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n };\n\n if (el.kind === \"union-bar\" || el.kind === \"union-elbow\") {\n const style = resolveUnionStyle(el, override);\n const body: string[] = [drawLine(style.dash ?? null, STRUCT_WIDTH, STRUCT_OPACITY)];\n const slashes = style.slashes ?? 0;\n if (slashes === 1 || slashes === 2) {\n // A straight 2-point bar uses its own segment; a dipped serial-union bar (3-seg\n // elbow, FIX B) and any union-elbow ride the LONGEST horizontal segment so the\n // separado/divorciado slashes land on the across part, never on a vertical stub.\n const [a, b] = pts.length === 2 ? [pts[0]!, pts[1]!] : longestHSegment(pts);\n body.push(slashMarks(a, b, slashes, STRUCT_WIDTH));\n }\n return `<g data-edge-id=\"${el.edgeId}\">${title}${body.join(\"\")}</g>`;\n }\n\n if (el.kind === \"descent\" || el.kind === \"sibling-bar\") {\n const dash = el.dotted ? DOTTED_DASH : null;\n const opacity = el.dotted ? DOTTED_OPACITY : STRUCT_OPACITY;\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(dash, STRUCT_WIDTH, opacity)}</g>`;\n }\n\n // bond\n const ink = EDGE_STROKE[el.lineStyle];\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(ink.dash, ink.width, ink.opacity)}</g>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed genogram layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal; there is NO text on map edges.\n */\nexport function genogramLayoutSvg(layout: GenogramLayout, opts: GenogramSvgOptions = {}): string {\n const override = opts.unionStyleByRelId ?? new Map<number, UnionEdgeStyle>();\n const labels = opts.labels ?? GENOGRAM_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // ── Routed elements first so nodes sit on top (same stacking as the JSX render). ───\n for (const el of layout.elements) parts.push(elementSvg(el, override));\n\n // ── Nodes: glyph + deceased mark + wrapped label, hook-compatible with schematex. ─\n for (const node of layout.nodes) {\n const half = node.size / 2;\n const pieces: string[] = [\n `<title>${xmlEscape(node.label)}</title>`,\n glyphSvg(node.shape, node.cx, node.cy, half),\n ];\n if (node.deceased) {\n pieces.push(\n `<line x1=\"${node.cx - half}\" y1=\"${node.cy - half}\" x2=\"${node.cx + half}\" y2=\"${node.cy + half}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n );\n }\n const tspans = node.labelLines\n .map(\n (line, i) =>\n `<tspan x=\"${node.cx}\" y=\"${node.labelTop + 10 + i * LABEL_LINE_H}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${LABEL_FONT}\" fill=\"${NODE_LABEL_FILL}\">${tspans}</text>`,\n );\n parts.push(`<g data-individual-id=\"p${node.personId}\">${pieces.join(\"\")}</g>`);\n }\n\n // ── Minimal pt-BR legend: only entries actually used. ──────────────────────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: { swatch: (x: number, y: number) => string; label: string }[] = [];\n\n const shapesUsed = new Set(layout.nodes.map((n) => n.shape));\n for (const shape of [\"square\", \"circle\", \"diamond\"] as const) {\n if (!shapesUsed.has(shape)) continue;\n entries.push({\n swatch: (x, y) => glyphSvg(shape, x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.shapes[shape],\n });\n }\n if (layout.nodes.some((n) => n.deceased)) {\n entries.push({\n swatch: (x, y) =>\n glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6) +\n `<line x1=\"${x + LEGEND_SWATCH_W / 2 - 6}\" y1=\"${y - 6}\" x2=\"${x + LEGEND_SWATCH_W / 2 + 6}\" y2=\"${y + 6}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n label: labels.deceased,\n });\n }\n\n // NOTE (deliberate, gate-tested): the fallback legend carries NO union-TYPE or\n // dotted-descent entry. Each declared union's type and each co-parenthood fact lives\n // VERBATIM in the element's <title> and in the dossier's structured side lists (the\n // psychologist's authoritative reading) — duplicating it as a legend key is the\n // \"known, documented gap\" pinned by test/verify-pdf.test.ts §(e). The dash/slash\n // notation itself stays on the drawn bars; only the legend stays minimal.\n\n // Bond styles actually used.\n const stylesUsed = new Set(layout.elements.filter((e) => e.kind === \"bond\").map((e) => e.lineStyle));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n\n // Unconnected glyphs (a person whose only declared tie is derived kinship like \"minha\n // tia\" — read from the tree, never a line — or who was mentioned with no tie at all)\n // sit grouped to the side with NO connector. This entry labels that group so a loose\n // glyph is never left unexplained; the verbatim tie still lives in the dossier list.\n if (layout.isolatedPersonIds.length > 0) {\n entries.push({\n swatch: (x, y) => glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.isolated,\n });\n }\n\n if (entries.length > 0) {\n const startY = layout.height;\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${GLYPH_STROKE}\">${xmlEscape(entry.label)}</text>`\n );\n });\n parts.push(`<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`);\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n width = Math.max(width, LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD);\n height = startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2;\n }\n }\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call genogram render: input → self-contained SVG string. Thin, honest wiring:\n// dedupe unions per pair, compute the pure layout, give each declared union TYPE its\n// McGoldrick notation as a per-edge visual override, emit. Callers needing finer\n// control use computeGenogramLayout + genogramLayoutSvg directly.\n\nimport {\n UNION_REL_ID_BASE,\n computeGenogramLayout,\n type GenogramLayout,\n type GenogramLayoutOptions,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { genogramLayoutSvg } from \"./svg\";\nimport type { GenogramSvgLabels } from \"./labels\";\nimport type { GenogramInput, Union, UnionStatus } from \"./types\";\n\n/** Shared 6,4 dash for every cohabiting-flavoured union (cohabiting / dating /\n * type-not-stated), so non-marital couples read consistently. */\nconst COUPLE_DASH = [6, 4] as const;\n\n/**\n * McGoldrick notation per declared union TYPE — a per-edge VISUAL override applied at\n * emission, never a synthesized quality. `coparental` is ABSENT on purpose: it draws\n * NO couple element at all; the co-parenthood shows only on the descents converging\n * on the child(ren).\n */\nexport const UNION_NOTATION: Record<Exclude<UnionStatus, \"coparental\">, UnionEdgeStyle> = {\n married: {}, // solid bar\n cohabiting: { dash: COUPLE_DASH },\n dating: { dash: COUPLE_DASH },\n unknown: { dash: COUPLE_DASH },\n separated: { slashes: 1 }, // solid + one diagonal slash\n divorced: { slashes: 2 }, // solid + two parallel slashes\n};\n\n/**\n * Duplicate unions for the same unordered pair should not exist (callers are expected\n * to normalize), but if they do, the HIGHEST id wins — the most recent statement.\n * NEVER a status-rank heuristic: recency is a fact, ranking would be an interpretation.\n */\nexport function latestUnionPerPair(unions: Union[]): Union[] {\n const byPair = new Map<string, Union>();\n for (const u of [...unions].sort((a, b) => a.id - b.id)) {\n const key = `${Math.min(u.personAId, u.personBId)}|${Math.max(u.personAId, u.personBId)}`;\n byPair.set(key, u);\n }\n return [...byPair.values()].sort((a, b) => a.id - b.id);\n}\n\nexport interface GenogramRenderOptions extends GenogramLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: GenogramSvgLabels;\n}\n\nexport interface GenogramRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: GenogramLayout;\n}\n\n/**\n * Renders a genogram input to a self-contained SVG string. Deterministic: same data →\n * same SVG. Empty `people` yields an empty-but-valid SVG; callers decide their own\n * empty state before calling.\n */\nexport function genogramSvg(\n input: GenogramInput,\n opts: GenogramRenderOptions = {},\n): GenogramRenderResult {\n const ids = new Set(input.people.map((p) => p.id));\n const dedupedUnions = latestUnionPerPair(input.unions).filter(\n (u) => ids.has(u.personAId) && ids.has(u.personBId),\n );\n\n const layout = computeGenogramLayout(\n input.people,\n dedupedUnions,\n input.parentLinks,\n input.relationships,\n opts,\n );\n\n const unionStyleByRelId = new Map<number, UnionEdgeStyle>();\n for (const u of dedupedUnions) {\n if (u.status === \"coparental\") continue; // no element — nothing to style\n unionStyleByRelId.set(UNION_REL_ID_BASE + u.id, UNION_NOTATION[u.status]);\n }\n\n const svg = genogramLayoutSvg(layout, {\n unionStyleByRelId,\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Radial ecomap renderer — center node + declared external ties on 1–2 concentric\n// rings, as a SELF-CONTAINED SVG string. Pure (data in, string out), deterministic\n// (same input → same SVG), no DOM, no dependencies.\n//\n// HONESTY RULE: the diagram presents ONLY what the caller declared. A tie's line style\n// is a conservative lexical hint from the author's own quality word (ambiguous/null →\n// neutral solid line, never a synthesized value); an arrowhead appears ONLY when a\n// direction was declared (null = no arrow, never a default). The verbatim text always\n// rides the element's <title>, so a style never replaces what was said.\n//\n// Ring assignment is a deterministic PRESENTATION rule — by input order (sorted by id),\n// alternating rings when the set is large — never by any reading of the tie's content.\n//\n// Every interpolated text passes xmlEscape (labels are author-controlled; the SVG may\n// be inlined via innerHTML or embedded in a PDF). All presentation attributes are\n// literal: a standalone SVG has no stylesheet. Arrowheads are explicit polygons, NOT\n// <marker> defs — marker support is unreliable in SVG-to-PDF embedders, and inline\n// polygons also avoid def-id collisions when several SVGs share one document.\n\nimport {\n EDGE_STROKE,\n FONT_FAMILY,\n clampLabel,\n estimateTextWidth,\n qualityLineStyle,\n wrapLabel,\n xmlEscape,\n type EdgeLineStyle,\n type QualityLexicon,\n} from \"../core\";\n\n// ── Input model ───────────────────────────────────────────────────────────────\n\n/** Declared flow of the tie, relative to the CENTER: \"in\" = toward the center. */\nexport type EcomapDirection = \"in\" | \"out\" | \"both\";\n\n/**\n * One declared tie between the center (person/household) and an external system\n * (work, faith, friends, healthcare…). `label` is the author's own naming, kept\n * verbatim. `quality` is the author's verbatim wording about the tie (null = not\n * declared = neutral line). `direction` follows the same doctrine: null = no arrow.\n */\nexport interface EcomapTie {\n id: number;\n label: string;\n quality: string | null;\n direction: EcomapDirection | null;\n /** Optional verbatim <title> override (defaults to \"label · quality\"). */\n title?: string;\n}\n\nexport interface EcomapInput {\n /** Center node label (e.g. the person or household the map is about). */\n centerLabel: string;\n ties: EcomapTie[];\n}\n\n// ── Display vocabulary ────────────────────────────────────────────────────────\n\nexport interface EcomapLabels {\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the neutral solid line (a declared tie with no styled quality). */\n neutralTie: string;\n /** Legend label for the arrowhead (declared direction of the tie). */\n direction: string;\n ariaLabel: string;\n}\n\nexport const ECOMAP_LABELS_EN: EcomapLabels = {\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n neutralTie: \"Declared tie\",\n direction: \"Declared direction of the tie\",\n ariaLabel: \"Ecomap\",\n};\n\nexport interface EcomapSvgOptions {\n /** Display clamp per tie label (verbatim text stays in the <title>). */\n maxLabelChars?: number;\n /** Node label font size (px); default 12. */\n fontSize?: number;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Quality-word lexicon — English default; see `compasso/locales/pt-br`. */\n qualityLexicon?: QualityLexicon;\n /** Display vocabulary — English default; see locale packs. */\n labels?: EcomapLabels;\n}\n\n// ── Geometry constants ────────────────────────────────────────────────────────\n\nconst PADDING = 32;\nconst LINE_H = 14;\nconst NODE_PAD_X = 14;\nconst NODE_PAD_Y = 9;\nconst CENTER_MIN_R = 36;\nconst RING_MIN_R = 150;\n/** Min gap between two adjacent node boxes on the same ring. */\nconst NODE_GAP = 24;\n/** Radial gap between the center circle and the inner ring's nearest box edge. */\nconst RADIAL_GAP = 40;\n/** Radial gap between the two rings when the set is large enough to split. */\nconst RING_GAP = 26;\n/** Above this many ties the layout alternates between two rings. */\nconst SINGLE_RING_MAX = 8;\n\n// Ink (zinc ramp on white — matches the genogram emitter).\nconst NODE_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\n// Legend metrics (same vocabulary as the genogram emitter).\nconst LEGEND_ROW_H = 18;\nconst LEGEND_PAD = 16;\nconst LEGEND_SWATCH_W = 22;\nconst LEGEND_GAP = 14;\nconst LEGEND_FONT = 11;\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Internal shapes ───────────────────────────────────────────────────────────\n\ninterface SatNode {\n tie: EcomapTie;\n lines: string[];\n rx: number;\n ry: number;\n /** Filled once ring radii are known. */\n x: number;\n y: number;\n angle: number;\n style: EdgeLineStyle;\n}\n\n/** Wrap policy mirroring the genogram's: roughly-balanced lines, sane width. */\nfunction wrapTieLabel(displayLabel: string): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n/** Arrowhead polygon: tip at (tipX,tipY), pointing along the unit vector (ux,uy). */\nfunction arrowHead(tipX: number, tipY: number, ux: number, uy: number, opacity: number): string {\n const LEN = 9;\n const HALF_W = 4.5;\n const bx = tipX - ux * LEN;\n const by = tipY - uy * LEN;\n const px = -uy;\n const py = ux;\n const points = [\n `${round(tipX)},${round(tipY)}`,\n `${round(bx + px * HALF_W)},${round(by + py * HALF_W)}`,\n `${round(bx - px * HALF_W)},${round(by - py * HALF_W)}`,\n ].join(\" \");\n return `<polygon points=\"${points}\" fill=\"${EDGE_INK}\" fill-opacity=\"${opacity}\"/>`;\n}\n\n/**\n * Renders a declared ecomap to a self-contained SVG string. Deterministic: same data →\n * same SVG. Zero ties yield a valid center-only SVG; callers decide their own empty\n * state before calling. The root keeps numeric width/height attributes plus a matching\n * viewBox (PDF-embedder contract).\n */\nexport function ecomapSvg(input: EcomapInput, opts: EcomapSvgOptions = {}): string {\n const fontSize = opts.fontSize ?? 12;\n const labels = opts.labels ?? ECOMAP_LABELS_EN;\n\n // ── Measure every satellite box (deterministic order: by tie id). ───────────\n const sats: SatNode[] = [...input.ties]\n .sort((a, b) => a.id - b.id)\n .map((tie) => {\n const lines = wrapTieLabel(clampLabel(tie.label, opts.maxLabelChars));\n const w = Math.max(...lines.map((l) => estimateTextWidth(l, fontSize))) + NODE_PAD_X * 2;\n const h = lines.length * LINE_H + NODE_PAD_Y * 2;\n return {\n tie,\n lines,\n rx: Math.max(40, w / 2),\n ry: Math.max(20, h / 2),\n x: 0,\n y: 0,\n angle: 0,\n style: qualityLineStyle(tie.quality, opts.qualityLexicon),\n };\n });\n\n const centerLines = wrapTieLabel(input.centerLabel);\n const centerR = Math.max(\n CENTER_MIN_R,\n Math.max(...centerLines.map((l) => estimateTextWidth(l, fontSize))) / 2 + 12,\n (centerLines.length * LINE_H) / 2 + 12,\n );\n\n // ── Ring radii: wide enough that NO two node boxes can ever touch. The safe\n // center-to-center distance is the diagonal of the worst-case box pair: if the\n // euclidean distance is ≥ hypot(width-sum, height-sum), the axis-aligned boxes\n // cannot overlap in both axes at once. Overlap-proof by construction, not by luck.\n const n = sats.length;\n const maxRx = n > 0 ? Math.max(...sats.map((s) => s.rx)) : 0;\n const maxRy = n > 0 ? Math.max(...sats.map((s) => s.ry)) : 0;\n const twoRings = n > SINGLE_RING_MAX;\n const stepAngle = n > 0 ? (Math.PI * 2) / n : Math.PI;\n const safeDist = Math.hypot(2 * maxRx + NODE_GAP, 2 * maxRy + NODE_GAP);\n /** Min radius so two nodes `steps` angular steps apart on the SAME ring clear safeDist. */\n const sameRingRadius = (steps: number): number => {\n const theta = steps * stepAngle;\n if (n <= 1 || theta >= Math.PI) return 0; // ≤2 nodes on the ring: no chord constraint\n return safeDist / (2 * Math.sin(theta / 2));\n };\n const ringStep = maxRy * 2 + RING_GAP;\n let innerR = Math.max(\n RING_MIN_R,\n centerR + RADIAL_GAP + maxRy,\n sameRingRadius(twoRings ? 2 : 1),\n );\n if (twoRings) {\n // Cross-ring neighbors sit 1 step apart at radii r and r+ringStep. Their distance\n // sqrt(r² + (r+s)² − 2r(r+s)cosΔ) grows monotonically with r — widen the inner ring\n // in fixed increments until it clears safeDist (deterministic, always terminates).\n const crossDist = (r: number): number =>\n Math.sqrt(r * r + (r + ringStep) ** 2 - 2 * r * (r + ringStep) * Math.cos(stepAngle));\n while (crossDist(innerR) < safeDist) innerR += 8;\n }\n const outerR = innerR + ringStep;\n\n for (let i = 0; i < n; i++) {\n const s = sats[i]!;\n s.angle = -Math.PI / 2 + (i * Math.PI * 2) / n;\n const r = twoRings && i % 2 === 1 ? outerR : innerR;\n s.x = r * Math.cos(s.angle);\n s.y = r * Math.sin(s.angle);\n }\n\n // ── Canvas bounds (center at origin until here), then shift positive. ───────\n let minX = -centerR;\n let minY = -centerR;\n let maxX = centerR;\n let maxY = centerR;\n for (const s of sats) {\n minX = Math.min(minX, s.x - s.rx);\n minY = Math.min(minY, s.y - s.ry);\n maxX = Math.max(maxX, s.x + s.rx);\n maxY = Math.max(maxY, s.y + s.ry);\n }\n const dx = PADDING - minX;\n const dy = PADDING - minY;\n const cx = dx;\n const cy = dy;\n for (const s of sats) {\n s.x += dx;\n s.y += dy;\n }\n let width = maxX - minX + PADDING * 2;\n let height = maxY - minY + PADDING * 2;\n\n const parts: string[] = [];\n\n // ── Tie lines first (nodes sit on top), one group per declared tie. ─────────\n for (const s of sats) {\n const ux = (cx - s.x) / Math.hypot(cx - s.x, cy - s.y);\n const uy = (cy - s.y) / Math.hypot(cx - s.x, cy - s.y);\n // Node-edge endpoint: ellipse boundary along the unit vector toward the center.\n const scale = 1 / Math.hypot(ux / s.rx, uy / s.ry);\n const x1 = s.x + ux * scale;\n const y1 = s.y + uy * scale;\n // Center-edge endpoint: circle boundary along the same direction.\n const x2 = cx - ux * centerR;\n const y2 = cy - uy * centerR;\n\n const ink = EDGE_STROKE[s.style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n const title = s.tie.title ?? (s.tie.quality !== null ? `${s.tie.label} · ${s.tie.quality}` : s.tie.label);\n const body: string[] = [\n `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n ];\n // Arrowheads ONLY for a declared direction. \"in\" points at the center, \"out\" at\n // the external system, \"both\" draws both. Tips back off the boundary so the\n // triangle never pokes into the shape.\n if (s.tie.direction === \"in\" || s.tie.direction === \"both\") {\n body.push(arrowHead(x2, y2, ux, uy, ink.opacity)); // tip at the center edge\n }\n if (s.tie.direction === \"out\" || s.tie.direction === \"both\") {\n body.push(arrowHead(x1, y1, -ux, -uy, ink.opacity)); // tip at the system edge\n }\n parts.push(`<g data-edge-id=\"${s.tie.id}\"><title>${xmlEscape(title)}</title>${body.join(\"\")}</g>`);\n }\n\n // ── Center node. ─────────────────────────────────────────────────────────────\n {\n const tspans = centerLines\n .map(\n (line, i) =>\n `<tspan x=\"${round(cx)}\" y=\"${round(cy - ((centerLines.length - 1) * LINE_H) / 2 + i * LINE_H + fontSize * 0.32)}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n parts.push(\n `<g data-individual-id=\"center\"><title>${xmlEscape(input.centerLabel)}</title>` +\n `<circle cx=\"${round(cx)}\" cy=\"${round(cy)}\" r=\"${round(centerR)}\" fill=\"transparent\" stroke=\"${NODE_STROKE}\" stroke-width=\"2\"/>` +\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">${tspans}</text></g>`,\n );\n }\n\n // ── Satellite nodes. ─────────────────────────────────────────────────────────\n for (const s of sats) {\n const tspans = s.lines\n .map(\n (line, i) =>\n `<tspan x=\"${round(s.x)}\" y=\"${round(s.y - ((s.lines.length - 1) * LINE_H) / 2 + i * LINE_H + fontSize * 0.32)}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n parts.push(\n `<g data-individual-id=\"e${s.tie.id}\"><title>${xmlEscape(s.tie.label)}</title>` +\n `<ellipse cx=\"${round(s.x)}\" cy=\"${round(s.y)}\" rx=\"${round(s.rx)}\" ry=\"${round(s.ry)}\" fill=\"transparent\" stroke=\"${NODE_STROKE}\" stroke-width=\"1.5\"/>` +\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">${tspans}</text></g>`,\n );\n }\n\n // ── Minimal legend: only entries actually used. ──────────────────────────────\n if (opts.legend !== false && sats.length > 0) {\n const entries: { swatch: (x: number, y: number) => string; label: string }[] = [];\n\n if (sats.some((s) => s.style === \"plain\")) {\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${EDGE_STROKE.plain.width}\" stroke-opacity=\"${EDGE_STROKE.plain.opacity}\"/>`,\n label: labels.neutralTie,\n });\n }\n const stylesUsed = new Set(sats.map((s) => s.style));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n if (sats.some((s) => s.tie.direction !== null)) {\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W - 8}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>` +\n arrowHead(x + LEGEND_SWATCH_W, y, 1, 0, 0.75),\n label: labels.direction,\n });\n }\n\n if (entries.length > 0) {\n const startY = height;\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${NODE_STROKE}\">${xmlEscape(entry.label)}</text>`\n );\n });\n parts.push(`<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`);\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n width = Math.max(width, LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD);\n height = startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/core/xml.ts","../src/core/geometry.ts","../src/core/text.ts","../src/core/legend.ts","../src/core/stroke.ts","../src/genogram/types.ts","../src/genogram/labels.ts","../src/genogram/kinship.ts","../src/genogram/layout.ts","../src/genogram/svg.ts","../src/genogram/render.ts","../src/ecomap/render.ts","../src/fault-tree/types.ts","../src/fault-tree/labels.ts","../src/fault-tree/validate.ts","../src/fault-tree/layout.ts","../src/fault-tree/svg.ts","../src/fault-tree/render.ts","../src/fishbone/render.ts"],"names":["clampLabel","LEGEND_ROW_H","LEGEND_PAD","LEGEND_SWATCH_W","LEGEND_GAP","LEGEND_FONT","pathData","PADDING","EDGE_INK","w","h","round","lines","last","GLYPH_STROKE","LABEL_FILL","pts","elementSvg","arrowHead"],"mappings":"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","file":"index.cjs","sourcesContent":["// XML/SVG escaping — every interpolated text in an emitted SVG MUST pass through\n// this. Diagram labels are typically user/author-controlled, and the SVG string may\n// be injected via innerHTML in a browser or embedded as vectors in a PDF — an\n// unescaped label is an XSS / `</svg>`-breakout vector on every surface at once.\n\n/** Escapes a string for use in SVG/XML text content AND attribute values. */\nexport function xmlEscape(text: string): string {\n return text\n .replace(/&/g, \"&\")\n .replace(/</g, \"<\")\n .replace(/>/g, \">\")\n .replace(/\"/g, \""\")\n .replace(/'/g, \"'\");\n}\n","// Shared geometry primitives.\n\nexport interface Point {\n x: number;\n y: number;\n}\n\n/** \"M x y L x y …\" path data from a polyline. */\nexport function pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n","// Pure, deterministic text metrics — no DOM, no canvas, no font files. Every layout\n// in this library reserves space from these estimates and every emitter draws with\n// the same constants, so what is proven collision-free is what is drawn.\n\n/**\n * Conservative per-character advance, as a fraction of the font size. The pure module\n * can't measure real glyphs (no DOM/canvas), so it estimates width = chars * font *\n * CHAR_W. It is deliberately a touch WIDER than Helvetica's ~0.5 average advance: a\n * layout reserves slightly more room than the text needs, so the real render always\n * fits inside its reserved box.\n */\nexport const CHAR_W = 0.6;\n\n/** Pure, deterministic width estimate for a single line of text at `fontPx`. */\nexport function estimateTextWidth(text: string, fontPx: number): number {\n return text.length * fontPx * CHAR_W;\n}\n\n/**\n * Wraps a label onto up to `maxLines` lines (default 2) so long labels don't sprawl.\n * Greedy word fill; each line capped at `perLine` chars (…-truncated only if a line\n * still overflows). The LAST allowed line absorbs every remaining word before the cap\n * applies — words are never dropped mid-label, only visibly elided. Pure + shared so\n * every renderer wraps identically. The full text is always kept elsewhere (the\n * node's `label`, an SVG <title>, or a side list), so nothing is silently lost.\n *\n * INVARIANT: with the default `maxLines` the output is byte-identical to the\n * historical two-line implementation (pinned by test/core/text.test.ts) — both\n * shipped renderers wrap through here.\n */\nexport function wrapLabel(label: string, perLine: number, maxLines = 2): string[] {\n if (label.length <= perLine) return [label];\n const cap = (s: string): string =>\n s.length > perLine ? s.slice(0, Math.max(1, perLine - 1)) + \"…\" : s;\n const lines: string[] = [\"\"];\n for (const word of label.split(/\\s+/)) {\n const last = lines.length - 1;\n const current = lines[last]!;\n if (current === \"\" || (current + \" \" + word).length <= perLine) {\n lines[last] = current === \"\" ? word : `${current} ${word}`;\n } else if (lines.length < maxLines) {\n lines.push(word);\n } else {\n lines[last] = `${current} ${word}`;\n }\n }\n // A trailing-whitespace \"word\" (\"a b \".split(/\\s+/) → [\"a\",\"b\",\"\"]) may open a line\n // it never fills; the historical code dropped that empty line, so this does too.\n if (lines.length > 1 && lines[lines.length - 1] === \"\") lines.pop();\n return lines.map(cap);\n}\n\n/**\n * House \"balanced\" wrap policy (extracted verbatim from the ecomap's tie-label wrap,\n * itself mirroring the genogram's): per-line budget `min(26, max(14, ceil(len/2)+2))`\n * splits a medium label into two roughly even lines instead of one long + one short,\n * then the greedy `wrapLabel` fill (and its `maxLines` semantics) applies. The shipped\n * renderers keep their local copies for now — new modules consume this one; migrating\n * them is a separate provably-zero-change refactor.\n */\nexport function wrapLabelBalanced(label: string, maxLines?: number): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(label.length / 2) + 2));\n return wrapLabel(label, perLine, maxLines);\n}\n\n/** Caps a verbatim label for a COMPACT render (preview); full text kept by the caller. */\nexport function clampLabel(label: string, maxChars: number | undefined): string {\n if (maxChars === undefined || label.length <= maxChars) return label;\n return label.slice(0, Math.max(1, maxChars - 1)) + \"…\";\n}\n\n/** Font stack shared by every emitter; PDF embedders typically map it onto Helvetica. */\nexport const FONT_FAMILY = \"Helvetica, Arial, sans-serif\";\n","// Shared legend machinery — the exact row format the genogram and ecomap emitters\n// currently duplicate character-for-character (`<g data-compasso-legend=\"true\">` with\n// swatch-closure rows). Extracted so new diagram modules don't add a third copy;\n// the two shipped emitters keep their local blocks for now (migrating them is a\n// separate, provably-zero-change refactor — pinned byte-for-byte against the ecomap's\n// emitted legend in test/core/legend.test.ts).\n//\n// The caller stays in charge of the HONESTY RULE half: it decides WHICH entries exist\n// (used-keys-only) and what each swatch draws; this module only owns the row geometry,\n// the text emission (xmlEscape — labels may come from caller-supplied packs), and the\n// width/height bookkeeping both renderers compute identically.\n\nimport { FONT_FAMILY, estimateTextWidth } from \"./text\";\nimport { xmlEscape } from \"./xml\";\n\n// Row metrics shared by every legend in the library. Exported because swatch builders\n// need them (a line swatch spans LEGEND_SWATCH_W; a glyph swatch centers on it).\nexport const LEGEND_ROW_H = 18;\nexport const LEGEND_PAD = 16;\nexport const LEGEND_SWATCH_W = 22;\nexport const LEGEND_GAP = 14;\nexport const LEGEND_FONT = 11;\n\n// Legend text ink — the zinc glyph stroke both shipped emitters use for legend labels.\nconst LEGEND_TEXT_FILL = \"#52525b\";\n\nexport interface LegendEntry {\n /**\n * Swatch markup builder, called with the swatch's left x and the row's center y.\n * The builder owns its own escaping/rounding (it typically reuses the module's\n * glyph/line emitters); it should draw within LEGEND_SWATCH_W of x.\n */\n swatch: (x: number, yCenter: number) => string;\n /** Display label (escaped here; verbatim pack text in, escaped SVG out). */\n label: string;\n}\n\nexport interface LegendBlock {\n /** `<g data-compasso-legend=\"true\">…</g>` — empty string when there are no entries. */\n svg: string;\n /** Minimum canvas width the legend needs; callers take `max(width, block.width)`. */\n width: number;\n /** New total canvas height including the legend; callers assign it directly. */\n height: number;\n}\n\n/**\n * Emits the legend group for the given entries below `startY` (the diagram's current\n * height). Pure + deterministic; coordinates are interpolated exactly as the shipped\n * emitters do. Zero entries (used-keys-only found nothing) → no markup, zero width\n * contribution, height unchanged — safe to call unconditionally.\n */\nexport function legendBlock(entries: readonly LegendEntry[], startY: number): LegendBlock {\n if (entries.length === 0) return { svg: \"\", width: 0, height: startY };\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${LEGEND_TEXT_FILL}\">${xmlEscape(entry.label)}</text>`\n );\n });\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n return {\n svg: `<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`,\n width: LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD,\n height: startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2,\n };\n}\n","// Edge line styles — a neutral, presentation-only style for a relationship line.\n// NOT a judgment: a deterministic, lexical hint derived from the author's own quality\n// word. The literal word always rides the element's <title>, so a style never replaces\n// what was said. Unknown/ambiguous quality → \"plain\".\n\nexport type EdgeLineStyle = \"plain\" | \"close\" | \"distant\" | \"conflict\" | \"cutoff\";\n\n/** Stroke attributes per style — shared by every renderer so SVG and PDF match. */\nexport interface EdgeStroke {\n width: number;\n /** SVG dash array / PDF dash pattern as [dash, gap]; null = solid. */\n dash: [number, number] | null;\n opacity: number;\n}\n\nexport const EDGE_STROKE: Record<EdgeLineStyle, EdgeStroke> = {\n plain: { width: 1.5, dash: null, opacity: 0.6 },\n close: { width: 3, dash: null, opacity: 0.85 },\n distant: { width: 1.5, dash: [4, 4], opacity: 0.55 },\n conflict: { width: 2, dash: [2, 2], opacity: 0.75 },\n cutoff: { width: 1.5, dash: [6, 5], opacity: 0.4 },\n};\n\n/**\n * A pluggable lexicon mapping free-text quality words onto line styles. Needles are\n * diacritic-free, lowercase substrings of the author's own words; `negations` are\n * whole words that flip the meaning of the very word a needle would match (\"not\n * close\"), so their presence makes the matcher abstain to \"plain\" rather than risk\n * an inverted visual. Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface QualityLexicon {\n buckets: readonly { style: Exclude<EdgeLineStyle, \"plain\">; needles: readonly string[] }[];\n negations: readonly string[];\n}\n\n// English default. Conservative stems: each needle is a substring match on the\n// normalized text, and the SINGLE-BUCKET rule below keeps competing signals honest.\n// \"no\" alone is deliberately NOT a negation: \"no contact\" is a genuine cutoff signal.\nexport const QUALITY_LEXICON_EN: QualityLexicon = {\n buckets: [\n {\n style: \"close\",\n needles: [\"close\", \"warm\", \"support\", \"lov\", \"affection\", \"caring\", \"tight\", \"harmon\", \"healthy\"],\n },\n {\n style: \"distant\",\n needles: [\"distant\", \"detach\", \"absent\", \"cold\", \"drift\"],\n },\n {\n style: \"conflict\",\n needles: [\"conflict\", \"fight\", \"tens\", \"difficult\", \"hostil\", \"violen\", \"abus\", \"aggress\", \"complicat\", \"toxic\", \"argu\"],\n },\n {\n style: \"cutoff\",\n needles: [\"estrang\", \"cut off\", \"cutoff\", \"no contact\", \"broken off\", \"sever\"],\n },\n ],\n negations: [\"not\", \"never\", \"no longer\", \"hardly\"],\n};\n\n/** Lowercase + strip diacritics so matching ignores accents. */\nexport function normalizeText(text: string): string {\n return text.normalize(\"NFD\").replace(/[̀-ͯ]/g, \"\").toLowerCase();\n}\n\nconst escapeRegExp = (s: string): string => s.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/**\n * Maps a free-text relationship quality to a neutral line style. Deterministic and\n * conservative: returns a specific style ONLY when exactly one lexical bucket matches;\n * null/empty/ambiguous/negated/unknown all fall back to \"plain\". The caller still\n * keeps the verbatim quality word, so nothing the author said is ever lost.\n */\nexport function qualityLineStyle(\n quality: string | null,\n lexicon: QualityLexicon = QUALITY_LEXICON_EN,\n): EdgeLineStyle {\n if (quality === null) return \"plain\";\n const haystack = normalizeText(quality);\n if (haystack.trim() === \"\") return \"plain\";\n\n if (lexicon.negations.length > 0) {\n const negation = new RegExp(`\\\\b(${lexicon.negations.map(escapeRegExp).join(\"|\")})\\\\b`);\n if (negation.test(haystack)) return \"plain\";\n }\n\n const matched: EdgeLineStyle[] = [];\n for (const { style, needles } of lexicon.buckets) {\n if (needles.some((n) => haystack.includes(n))) matched.push(style);\n }\n return matched.length === 1 ? matched[0]! : \"plain\";\n}\n","// Genogram input model — declared facts only. compasso draws EXACTLY what the caller\n// declares and NEVER synthesizes structure: two declared parents without a declared\n// union never merge into a couple; a \"coparental\" union draws no couple element; a\n// free-text relationship never silently becomes kinship. Collection doctrine (who may\n// assert a fact, how it was captured) is the caller's concern — this is a renderer.\n\n/** Sex marker for a genogram node (standard notation: square/circle/diamond). */\nexport type PersonSex = \"male\" | \"female\" | \"unknown\";\n\n/** A genogram node. `generation` is relative (0 = index person; negative = older). */\nexport interface Person {\n id: number;\n label: string;\n sex: PersonSex;\n deceased: boolean;\n generation: number | null;\n}\n\n/**\n * CLOSED status vocabulary for a declared union. Notable semantics:\n * - \"coparental\": the two were NEVER a couple and have child(ren) together;\n * - \"unknown\": a union was declared, but its type was not;\n * - widowhood is NOT a status — death lives on Person.deceased and never\n * alters the declared status;\n * - no value for \"not stated\": the union simply is not passed in.\n */\nexport const UNION_STATUSES = [\n \"married\",\n \"cohabiting\",\n \"dating\",\n \"separated\",\n \"divorced\",\n \"coparental\",\n \"unknown\",\n] as const;\n\nexport type UnionStatus = (typeof UNION_STATUSES)[number];\n\n/**\n * A declared couple bond between two people. The pair is unordered and expected\n * normalized to personAId < personBId with ONE union per pair (duplicates are the\n * caller's to resolve). `quality` is the author's verbatim wording about the bond.\n */\nexport interface Union {\n id: number;\n /** Always the smaller person id (normalized pair). */\n personAId: number;\n personBId: number;\n status: UnionStatus;\n quality: string | null;\n}\n\n/**\n * A declared parentage link: parent → child, one row PER DECLARED genitor (two\n * genitors = two links, each individually stated — never promoted from a union).\n */\nexport interface ParentLink {\n id: number;\n parentId: number;\n childId: number;\n quality: string | null;\n}\n\n/**\n * A typed free-text edge between two people. `type` and `quality` are verbatim\n * labels. This carries NON-STRUCTURAL ties only (closeness, conflict…) — unions\n * and parentage are first-class above.\n */\nexport interface Relationship {\n id: number;\n fromPersonId: number;\n toPersonId: number;\n type: string;\n quality: string | null;\n}\n\n/** Input to the genogram render pipeline. */\nexport interface GenogramInput {\n people: Person[];\n unions: Union[];\n parentLinks: ParentLink[];\n relationships: Relationship[];\n}\n\n/** Node glyph shapes (standard notation: square = male, circle = female, diamond = unknown). */\nexport type NodeShape = \"square\" | \"circle\" | \"diamond\";\n","// Display vocabularies — every human-readable string the genogram emits, gathered in\n// overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n\nimport type { EdgeLineStyle } from \"../core\";\nimport type { NodeShape, UnionStatus } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface GenogramTitleLabels {\n unionStatus: Record<UnionStatus, string>;\n /** Title prefix for a parent→child descent (\"parent of\"). */\n parentage: string;\n}\n\nexport const GENOGRAM_TITLE_LABELS_EN: GenogramTitleLabels = {\n unionStatus: {\n married: \"married\",\n cohabiting: \"cohabiting\",\n dating: \"dating\",\n separated: \"separated\",\n divorced: \"divorced\",\n coparental: \"co-parents (never a couple)\",\n unknown: \"union (type not stated)\",\n },\n parentage: \"parent of\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface GenogramSvgLabels {\n shapes: Record<NodeShape, string>;\n deceased: string;\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the group of people with no drawn connection. */\n isolated: string;\n ariaLabel: string;\n}\n\nexport const GENOGRAM_SVG_LABELS_EN: GenogramSvgLabels = {\n shapes: {\n square: \"Man\",\n circle: \"Woman\",\n diamond: \"Sex not stated\",\n },\n deceased: \"Deceased\",\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n isolated: \"No recorded ancestry\",\n ariaLabel: \"Family map (genogram)\",\n};\n","// Relationship → MAP class (presentation only). A genogram draws only the structural\n// SKELETON: declared unions + parent links. A free-text `relationship` becomes a map\n// LINE only when it is NON-parentage. Kinship that is READ FROM THE TREE (grandparent/\n// sibling/uncle/cousin/nephew…) draws NOTHING — it is already implied by the descent/\n// union structure, so a dedicated line would only duplicate and clutter. A DIRECT\n// parentage word (mother/father/child) with no declared parent link is PROMOTED to a\n// descent (oriented by declared generation) so the person is not orphaned. NOTHING here\n// synthesizes undeclared structure: derived kinship draws nothing at all, and promotion\n// only ORIENTS an already-declared parent-child word. The verbatim \"type · quality\" of\n// EVERY relationship is the caller's to keep showing in its own lists.\n\nimport { normalizeText } from \"../core\";\n\nexport type RelationshipMapClass = \"derived\" | \"parentage\" | \"bond\";\n\n/**\n * A pluggable kinship vocabulary. Tokens are diacritic-free, lowercase, matched WHOLE\n * (so a token never matches inside another word) after splitting the type on\n * non-alphanumerics (\"half-brother\" → [\"half\",\"brother\"]). Checked DERIVED-first, so\n * \"brother on my father's side\" reads as a sibling, never as a parent. These lists are\n * closed and conservative — an unrecognized word stays a non-structural bond (the\n * honest default). Locale packs (e.g. `compasso/locales/pt-br`) ship alternates.\n */\nexport interface KinshipLexicon {\n /** Kinship read from the tree (sibling/grandparent/uncle/cousin…): never a line. */\n derived: ReadonlySet<string>;\n /** Direct parentage words (mother/father/son…): promotable to a descent. */\n parentage: ReadonlySet<string>;\n /** Parentage words whose FROM endpoint is the CHILD — used only to orient a\n * promotion when declared generations do not decide it. */\n childWords: ReadonlySet<string>;\n}\n\nexport const KINSHIP_EN: KinshipLexicon = {\n derived: new Set([\n \"brother\", \"brothers\", \"sister\", \"sisters\", \"sibling\", \"siblings\",\n \"grandmother\", \"grandfather\", \"grandma\", \"grandpa\", \"granny\", \"grandad\",\n \"granddad\", \"grandparent\", \"grandparents\",\n \"grandson\", \"granddaughter\", \"grandchild\", \"grandchildren\",\n \"uncle\", \"uncles\", \"aunt\", \"aunts\", \"auntie\",\n \"cousin\", \"cousins\",\n \"nephew\", \"nephews\", \"niece\", \"nieces\",\n ]),\n parentage: new Set([\n \"mother\", \"mothers\", \"mom\", \"mum\", \"father\", \"fathers\", \"dad\",\n \"parent\", \"parents\",\n \"son\", \"sons\", \"daughter\", \"daughters\",\n ]),\n childWords: new Set([\"son\", \"sons\", \"daughter\", \"daughters\"]),\n};\n\n/** Lowercase + accent-stripped tokens of a free-text relationship type. */\nexport function relationshipTypeTokens(type: string): string[] {\n return normalizeText(type).split(/[^a-z0-9]+/).filter((t) => t !== \"\");\n}\n\n/**\n * Classifies a free-text relationship `type` for the MAP. Pure + deterministic.\n * Derived kinship is checked first so a compound like \"brother on my father's side\"\n * is read as a sibling (derived), never promoted as a parent. The verbatim word is\n * unaffected — this decides only whether the tie becomes a line, and which kind.\n */\nexport function classifyRelationshipType(\n type: string,\n kinship: KinshipLexicon = KINSHIP_EN,\n): RelationshipMapClass {\n const toks = relationshipTypeTokens(type);\n if (toks.some((t) => kinship.derived.has(t))) return \"derived\";\n if (toks.some((t) => kinship.parentage.has(t))) return \"parentage\";\n return \"bond\";\n}\n","// PURE genogram layout — the single source of truth for positioning and glyph/edge\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so it loads\n// identically in browsers, server runtimes and test environments, and the same input\n// always yields the same layout. Anything with a side effect belongs elsewhere.\n//\n// HONESTY RULE: this module only POSITIONS and ROUTES the facts the caller declared. It\n// computes NO score, interpretation, prognosis or diagnosis, and it NEVER synthesizes\n// undeclared structure: a `coparental` union draws no couple element; two declared\n// parents WITHOUT a declared union never merge into a couple-bar descent (each gets its\n// own descent); free-text `relationships` stay non-structural bonds. Shapes follow the\n// standard genogram convention (square = male, circle = female, diamond = unknown; a\n// diagonal stroke marks deceased). The verbatim \"type · quality\" / status label is\n// ALWAYS kept on every routed element's <title>, so a style never replaces what was said.\n//\n// LAYOUT — orthogonal (McGoldrick) and overlap-proof BY CONSTRUCTION (not by luck). The\n// diagram is a grid: people sit in COLUMNS inside generation ROWS; the empty bands\n// BETWEEN columns (GUTTERS) and BETWEEN rows (CORRIDORS) are the only places routing\n// segments live, each in a numbered LANE allocated by interval-overlap so two segments\n// in the same lane can never overlap. Every consecutive pair of waypoints is axis-aligned\n// (horizontal or vertical) — there are NO diagonals and NO text on map edges (the\n// verbatim text rides the <title> and the caller's side lists). Glyphs and their labels\n// live entirely inside their columns; gutters and corridors are content-free by\n// construction, so a routed segment can never cross a glyph or a label box.\n//\n// PROVENANCE: descends from the production genogram renderer the author wrote for the\n// Ventory project (same copyright holder); developed independently of any third-party\n// diagram engine.\nimport {\n CHAR_W,\n estimateTextWidth,\n qualityLineStyle,\n wrapLabel,\n EDGE_STROKE,\n type EdgeLineStyle,\n type EdgeStroke,\n type Point,\n type QualityLexicon,\n} from \"../core\";\nimport { GENOGRAM_TITLE_LABELS_EN, type GenogramTitleLabels } from \"./labels\";\nimport {\n classifyRelationshipType,\n relationshipTypeTokens,\n KINSHIP_EN,\n type KinshipLexicon,\n type RelationshipMapClass,\n} from \"./kinship\";\nimport type {\n NodeShape,\n ParentLink,\n Person,\n PersonSex,\n Relationship,\n Union,\n} from \"./types\";\n\n// Re-exports so callers (and the emitter) can reach the full vocabulary through this\n// module, mirroring the original single-file layout.\nexport { CHAR_W, estimateTextWidth, qualityLineStyle, wrapLabel, EDGE_STROKE };\nexport type { EdgeLineStyle, EdgeStroke, Point, QualityLexicon };\nexport { classifyRelationshipType, relationshipTypeTokens, KINSHIP_EN };\nexport type { KinshipLexicon, RelationshipMapClass };\nexport type { NodeShape };\n\n// ── Geometry ──────────────────────────────────────────────────────────────────\nexport const NODE_SIZE = 56;\nconst PADDING = 32;\n/** Min horizontal gap between two adjacent columns' content boxes (a gutter's base). */\nconst COL_PAD = 30;\n/** Gap from a glyph's bottom to the top of its first label line. */\nconst LABEL_GAP_TOP = 8;\n/** Base height of a routing corridor (before lanes widen it). */\nconst CORRIDOR_BASE = 24;\n/** Vertical/horizontal spacing between two routing lanes in a corridor/gutter. */\nconst LANE_H = 8;\n/** Vertical drop between successive serial-union (remarriage) bars below the glyph row,\n * so 2+ unions on one person never read as one continuous rail (McGoldrick, FIX B). */\nconst UNION_STAGGER = 12;\n/** Horizontal offset (from glyph center, toward the partner) of a dipped union-bar's stub,\n * so a person in two serial unions gets two distinct stub columns (FIX B). < NODE_SIZE/2. */\nconst STUB_X_OFF = 14;\n/** Extra horizontal separation placed before an isolated-people group (SPEC). */\nconst ISOLATED_GUTTER_EXTRA = 2 * COL_PAD;\n\n// ── Type metrics (shared by layout AND both renderers, so geometry == render) ──\n/** Node label font size (px). The live SVG renders at this size; the PDF scales it. */\nexport const LABEL_FONT = 12;\n/** Line height for stacked node-label lines (px). */\nexport const LABEL_LINE_H = 14;\n/** Edge label font size (px) — kept for the shared metrics contract (invariant #9). */\nexport const EDGE_FONT = 11;\n// CHAR_W / estimateTextWidth live in ../core (re-exported above): the overlap-proof\n// guarantee depends on layout and emitters sharing these exact metrics.\n\n// ── Namespaced element ids (kept stable so data-edge-id stays traceable, §7.2) ──\n// relationships keep their own id; unions live at 1_000_000+id; parent links at\n// 2_000_000+id; PROMOTED descents (a direct-parentage free-text relationship drawn as a\n// descent — see classifyRelationshipType) at 3_000_000+rel id. Four disjoint blocks, so a\n// promoted descent never collides with a real parent link and every edge stays traceable\n// to its source. Deterministic, and visible in the overlap harness / data-edge-id.\nexport const UNION_REL_ID_BASE = 1_000_000;\nexport const PARENT_REL_ID_BASE = 2_000_000;\nexport const PROMOTED_REL_ID_BASE = 3_000_000;\n\n// ── Node glyphs ──────────────────────────────────────────────────────────────\nfunction shapeForSex(sex: PersonSex): NodeShape {\n if (sex === \"male\") return \"square\";\n if (sex === \"female\") return \"circle\";\n return \"diamond\";\n}\n\n// ── Edge line styles ─────────────────────────────────────────────────────────\n// EdgeLineStyle / EDGE_STROKE / qualityLineStyle live in ../core (re-exported above):\n// a neutral, presentation-only style for a NON-STRUCTURAL bond line, lexically hinted\n// from the author's own quality word — never a judgment, verbatim word always kept.\n\n/**\n * Per-edge VISUAL union style applied at emission (§7.2 / FIX 3) — the McGoldrick\n * notation for a declared union TYPE, WITHOUT touching the layout or the patient's\n * words. `coparental` never gets one (it draws no edge). Defined here (not in\n * fallback-svg) so a routed element can carry it and the emitter stays free of layout\n * cycles; fallback-svg re-exports it for the existing call sites.\n */\nexport interface UnionEdgeStyle {\n /** Inline stroke-dasharray [dash, gap] on the bar; absent = solid (e.g. casado). */\n dash?: readonly [number, number];\n /** Diagonal status slashes at the midpoint: 1 = separação, 2 = divórcio. */\n slashes?: 0 | 1 | 2;\n}\n\n// ── Relationship → MAP class ───────────────────────────────────────────────────\n// classifyRelationshipType / relationshipTypeTokens / KinshipLexicon live in ./kinship\n// (re-exported above): derived kinship draws NOTHING, direct parentage may be PROMOTED\n// to a descent, everything else stays a non-structural bond. wrapLabel lives in ../core.\n\n/** Wrap policy: split a label into roughly-balanced lines bounded to a sane width. */\nfunction wrapNodeLabel(displayLabel: string): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n/** Caps a verbatim label for a COMPACT render (preview); full text kept in `label`. */\nfunction clampLabel(label: string, maxChars: number | undefined): string {\n if (maxChars === undefined || label.length <= maxChars) return label;\n return label.slice(0, Math.max(1, maxChars - 1)) + \"…\";\n}\n\n// ── Positioned layout ────────────────────────────────────────────────────────\n\nexport interface GenogramNode {\n personId: number;\n /** Full, verbatim label (used for tooltips/aria — never truncated). */\n label: string;\n shape: NodeShape;\n deceased: boolean;\n /** Center of the node. */\n cx: number;\n cy: number;\n /** Side length (square) / diameter (circle) / width (diamond). */\n size: number;\n /** Pre-wrapped display lines (already capped for the requested density). */\n labelLines: string[];\n /** Y of the TOP of the first label line's box (each next line is +LABEL_LINE_H). */\n labelTop: number;\n}\n\n/** A routed map element — the orthogonal replacement for the old straight `GenogramEdge`. */\nexport type GenogramElementKind =\n | \"union-bar\" // adjacent same-row partners: straight H bar, glyph-edge to glyph-edge\n | \"union-elbow\" // non-adjacent / cross-row partners: orthogonal route\n | \"descent\" // parent(s) → child plumbing segment(s)\n | \"sibling-bar\" // one shared H bar per union child-group (≥1 children)\n | \"bond\"; // non-structural relationship, orthogonal route\n\nexport interface GenogramElement {\n kind: GenogramElementKind;\n /** Source row ids for traceability; merged bonds carry every merged rel id. */\n relIds: number[];\n /** data-edge-id value: highest relId (matches latestUnionPerPair's highest-wins). */\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n /** Polyline; EVERY consecutive pair is axis-aligned (H or V). */\n points: Point[];\n /** Verbatim titles (one per source row), joined for the <title>. */\n titles: string[];\n lineStyle: EdgeLineStyle; // bonds only; structural elements are \"plain\"\n unionStyle?: UnionEdgeStyle; // union-bar / union-elbow: dash + slashes\n dotted?: boolean; // lone-parent / coparental descents\n}\n\nexport interface GenogramLayout {\n width: number;\n height: number;\n nodes: GenogramNode[];\n elements: GenogramElement[];\n /** People with NO drawn structural/bond connection — grouped to the side and labeled\n * \"Sem ascendência registrada\" so a loose glyph is never left unexplained. */\n isolatedPersonIds: number[];\n}\n\n// ── Internal working types ─────────────────────────────────────────────────────\n\n/**\n * A parent→child descent to draw — either a DECLARED parent_link (real) or a PROMOTED\n * direct-parentage relationship (no declared link existed for the pair). `edgeId` is\n * pre-namespaced (real: PARENT_REL_ID_BASE+link id; promoted: PROMOTED_REL_ID_BASE+rel id),\n * so both flow through the same descent machinery and stay traceable in data-edge-id.\n */\ninterface LayoutLink {\n parentId: number;\n childId: number;\n quality: string | null;\n edgeId: number;\n}\n\ninterface Measured {\n person: Person;\n lines: string[];\n /** max(NODE_SIZE, widest wrapped line) — the horizontal footprint. */\n contentW: number;\n}\n\n/** A vertical segment living in a gutter, awaiting a lane. */\ninterface GutterReq {\n gutter: number; // gutter index g in [-1, colCount-1]\n side: -1 | 0 | 1; // -1 hug left column, +1 hug right column, 0 center (union spine)\n rowLo: number; // continuous row coordinate (row r → r; corridor k → k+0.5)\n rowHi: number;\n lane: number; // filled by the allocator\n}\n\n/** A horizontal segment living in a corridor, awaiting a lane. Its pixel x-interval is\n * resolved AFTER the column/gutter geometry is fixed, so the lane allocator can use the\n * EXACT extent (a u-index proxy collapses for within-one-gutter spans). */\ninterface CorridorReq {\n corridor: number; // corridor index k in [0, rowCount-1] (k = below row k)\n xRange: () => [number, number]; // pixel [xMin, xMax], resolved post-column-geometry\n lane: number;\n}\n\n/** A sideways glyph departure stub, awaiting a height slot. */\ninterface StubReq {\n personId: number;\n side: -1 | 1;\n slot: number; // height slot index, filled below\n}\n\n/** An arrival into a glyph TOP, awaiting an x-offset slot. */\ninterface ArrivalReq {\n personId: number;\n slot: number;\n}\n\n/** A planned element: its kind/metadata + a builder that resolves to pixel points. */\ninterface PlannedElement {\n kind: GenogramElementKind;\n relIds: number[];\n edgeId: number;\n fromPersonId: number | null;\n toPersonId: number | null;\n titles: string[];\n lineStyle: EdgeLineStyle;\n unionStyle?: UnionEdgeStyle;\n dotted?: boolean;\n build: () => Point[];\n}\n\n// Height slots for stacked departures from one glyph side (avoid y=cy so a union bar at\n// cy is never crossed). Within ±(NODE_SIZE/2 − 4) so the stub stays on the glyph edge.\nconst STUB_OFFSETS = [9, -9, 18, -18, 26, -26] as const;\n/** Max |x-offset| for an arrival into a glyph TOP (kept inside the top edge half-width). */\nconst ARRIVAL_HALF = NODE_SIZE / 2 - 8;\n\nfunction stubOffset(slot: number): number {\n return STUB_OFFSETS[Math.min(slot, STUB_OFFSETS.length - 1)]!;\n}\n/** Spread arrivals across a glyph TOP so each lands on a distinct x — slot 0 stays\n * CENTERED (the primary descent), later arrivals alternate to either side. For any\n * fan-in count, no two verticals share a column (overlap-proof). */\nfunction arrivalOffset(slot: number, total: number): number {\n if (slot === 0 || total <= 1) return 0;\n const step = Math.min(12, ARRIVAL_HALF / Math.max(1, Math.ceil((total - 1) / 2)));\n const sign = slot % 2 === 1 ? -1 : 1;\n return sign * Math.ceil(slot / 2) * step;\n}\n\n/** Allocate lanes for a set of intervals: each takes the lowest lane free over its span\n * (touching at an endpoint does NOT count as overlap, so collinear segments may abut). */\nfunction allocateLanes(items: { lo: number; hi: number; set: (lane: number) => void }[]): number {\n const lanes: { lo: number; hi: number }[][] = [];\n for (const it of items) {\n let chosen = -1;\n for (let l = 0; l < lanes.length; l++) {\n if (lanes[l]!.every((o) => it.hi <= o.lo || it.lo >= o.hi)) {\n chosen = l;\n break;\n }\n }\n if (chosen === -1) {\n chosen = lanes.length;\n lanes.push([]);\n }\n lanes[chosen]!.push({ lo: it.lo, hi: it.hi });\n it.set(chosen);\n }\n return lanes.length;\n}\n\n/**\n * Deterministic, overlap-proof ORTHOGONAL layout (pure function of the inputs — same\n * data always yields the same geometry). People are grouped by `generation` (null trails\n * as a bottom row), rows ordered oldest-on-top. Declared structure is drawn as McGoldrick\n * elements: same-row adjacent unions as straight bars, couples-with-children as a shared\n * sibling bar, lone/co-parental genitors as dotted descents, and free-text relationships\n * as orthogonally-routed bonds — NEVER promoting a bond into structure.\n *\n * @param unions caller-deduped (one per pair) declared couple bonds.\n * @param parentLinks declared parent→child links (one row per declared genitor).\n * @param relationships non-structural ties (drawn as bonds).\n * @param opts.maxLabelChars cap each node's DISPLAY label to this many chars (compact\n * preview); the full verbatim text is still exposed on `node.label`.\n * @param opts.kinship / opts.qualityLexicon / opts.titleLabels — locale packs (English\n * defaults; see `compasso/locales/pt-br`).\n */\nexport interface GenogramLayoutOptions {\n maxLabelChars?: number;\n kinship?: KinshipLexicon;\n qualityLexicon?: QualityLexicon;\n titleLabels?: GenogramTitleLabels;\n}\n\nexport function computeGenogramLayout(\n people: Person[],\n unions: Union[],\n parentLinks: ParentLink[],\n relationships: Relationship[],\n opts: GenogramLayoutOptions = {},\n): GenogramLayout {\n const kinship = opts.kinship ?? KINSHIP_EN;\n const titleLabels = opts.titleLabels ?? GENOGRAM_TITLE_LABELS_EN;\n if (people.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], elements: [], isolatedPersonIds: [] };\n }\n\n const ids = new Set(people.map((p) => p.id));\n const pairKey = (a: number, b: number): string => `${Math.min(a, b)}|${Math.max(a, b)}`;\n const genById = new Map<number, number | null>(people.map((p) => [p.id, p.generation]));\n\n // Sanitize structural inputs (drop self/missing endpoints — keep declared facts only).\n const validUnions = unions\n .filter((u) => ids.has(u.personAId) && ids.has(u.personBId) && u.personAId !== u.personBId)\n .sort((a, b) => a.id - b.id);\n const coupleUnions = validUnions.filter((u) => u.status !== \"coparental\");\n const validLinks = parentLinks\n .filter((l) => ids.has(l.parentId) && ids.has(l.childId) && l.parentId !== l.childId)\n .sort((a, b) => a.id - b.id);\n const validRels = relationships\n .filter((r) => ids.has(r.fromPersonId) && ids.has(r.toPersonId) && r.fromPersonId !== r.toPersonId)\n .sort((a, b) => a.id - b.id);\n\n // ── SKELETON-ONLY (presentation): classify each free-text relationship for the MAP ─────\n // - \"derived\" (avó/irmão/tio/…): READ from the tree → draws NOTHING here.\n // - \"parentage\" (mãe/pai/filho/…): a declared parent-child word → PROMOTED to a descent\n // when no parent_link already declares the pair (else a duplicate, dropped\n // from the map); never a bond.\n // - \"bond\" (everything else): a non-structural tie → drawn as a bond, as before.\n // The verbatim \"type · quality\" of EVERY relationship still rides the dossier side lists.\n const relClass = new Map<number, RelationshipMapClass>(\n validRels.map((r) => [r.id, classifyRelationshipType(r.type, kinship)]),\n );\n const bondRels = validRels.filter((r) => relClass.get(r.id) === \"bond\");\n const parentageRels = validRels.filter((r) => relClass.get(r.id) === \"parentage\");\n\n // Effective descents = declared parent_links (real) + promoted parentage relationships.\n const realLinks: LayoutLink[] = validLinks.map((l) => ({\n parentId: l.parentId,\n childId: l.childId,\n quality: l.quality,\n edgeId: PARENT_REL_ID_BASE + l.id,\n }));\n const declaredPairs = new Set(validLinks.map((l) => pairKey(l.parentId, l.childId)));\n const promotedByPair = new Map<string, LayoutLink>();\n for (const r of parentageRels) {\n const key = pairKey(r.fromPersonId, r.toPersonId);\n if (declaredPairs.has(key)) continue; // already a declared parent_link → no double-draw\n if (promotedByPair.has(key)) continue; // same pair stated twice → one descent (id-order)\n // Orient parent→child by DECLARED generation (older = parent). When generations do not\n // decide (equal or null), fall back to the parentage WORD + the declared from/to:\n // mãe/pai → from is the parent; filho/filha → from is the child. Either way nothing is\n // invented — both endpoints and the parent-child nature were declared; only the arrow.\n const ga = genById.get(r.fromPersonId) ?? null;\n const gb = genById.get(r.toPersonId) ?? null;\n let parentId: number;\n let childId: number;\n if (ga !== null && gb !== null && ga !== gb) {\n [parentId, childId] = ga < gb ? [r.fromPersonId, r.toPersonId] : [r.toPersonId, r.fromPersonId];\n } else {\n const fromIsChild = relationshipTypeTokens(r.type).some((t) => kinship.childWords.has(t));\n [parentId, childId] = fromIsChild ? [r.toPersonId, r.fromPersonId] : [r.fromPersonId, r.toPersonId];\n }\n if (parentId === childId) continue;\n promotedByPair.set(key, { parentId, childId, quality: r.quality, edgeId: PROMOTED_REL_ID_BASE + r.id });\n }\n const allLinks: LayoutLink[] = [...realLinks, ...promotedByPair.values()].sort((a, b) => a.edgeId - b.edgeId);\n\n // Declared (non-coparental) union lookup by unordered pair → union.\n const coupleByPair = new Map<string, Union>();\n for (const u of coupleUnions) coupleByPair.set(pairKey(u.personAId, u.personBId), u);\n\n // Parents per child and links per (parent,child) — real links + promoted descents.\n const parentsOf = new Map<number, number[]>();\n const linkOf = new Map<string, LayoutLink>();\n for (const l of allLinks) {\n const arr = parentsOf.get(l.childId) ?? [];\n if (!arr.includes(l.parentId)) arr.push(l.parentId);\n parentsOf.set(l.childId, arr);\n linkOf.set(`${l.parentId}>${l.childId}`, l);\n }\n\n // A person is ISOLATED when they have NO drawn connection: no union, no descent (real or\n // promoted), and no bond. A relationship suppressed from the map (derived kinship like\n // \"minha tia\", read from the tree) does NOT count as a tie — so such a person is grouped\n // to the side and labeled \"Sem ascendência registrada\", never left as a loose glyph.\n const hasTie = new Set<number>();\n for (const u of validUnions) {\n hasTie.add(u.personAId);\n hasTie.add(u.personBId);\n }\n for (const l of allLinks) {\n hasTie.add(l.parentId);\n hasTie.add(l.childId);\n }\n for (const r of bondRels) {\n hasTie.add(r.fromPersonId);\n hasTie.add(r.toPersonId);\n }\n const isIsolated = (id: number): boolean => !hasTie.has(id);\n\n // ── Pass 1a: rows by declared generation (null last), oldest on top ──────────────\n const byGen = new Map<number | null, Person[]>();\n for (const p of people) {\n const bucket = byGen.get(p.generation);\n if (bucket === undefined) byGen.set(p.generation, [p]);\n else bucket.push(p);\n }\n const genKeys = [...byGen.keys()].sort((a, b) => {\n if (a === null) return 1;\n if (b === null) return -1;\n return a - b;\n });\n const rowCount = genKeys.length;\n const rowOfPerson = new Map<number, number>();\n genKeys.forEach((g, r) => byGen.get(g)!.forEach((p) => rowOfPerson.set(p.id, r)));\n\n // ── Pass 1b: couple BLOCKS per row (connected components of same-row couple unions),\n // linearized so partners land adjacent; then barycenter ordering; isolated rightmost.\n type Block = number[]; // person ids, left-to-right\n const rowBlocks: Block[][] = genKeys.map((g, r) => {\n const members = byGen.get(g)!.map((p) => p.id);\n // adjacency from same-row couple unions\n const adj = new Map<number, number[]>();\n for (const id of members) adj.set(id, []);\n for (const u of coupleUnions) {\n if (rowOfPerson.get(u.personAId) === r && rowOfPerson.get(u.personBId) === r) {\n adj.get(u.personAId)!.push(u.personBId);\n adj.get(u.personBId)!.push(u.personAId);\n }\n }\n for (const id of members) adj.get(id)!.sort((a, b) => a - b);\n // connected components\n const seen = new Set<number>();\n const blocks: Block[] = [];\n for (const start of [...members].sort((a, b) => a - b)) {\n if (seen.has(start)) continue;\n const comp: number[] = [];\n const stack = [start];\n seen.add(start);\n while (stack.length > 0) {\n const n = stack.pop()!;\n comp.push(n);\n for (const m of adj.get(n)!) if (!seen.has(m)) { seen.add(m); stack.push(m); }\n }\n blocks.push(linearizeBlock(comp, adj));\n }\n return blocks;\n });\n\n // Barycenter sweeps (downward then upward), gated on rowCount ≥ 2. Aesthetic only —\n // it reorders blocks to align children under parents; it never moves anyone off a row.\n const flattened = (): Map<number, number> => {\n const pos = new Map<number, number>();\n for (const blocks of rowBlocks) {\n let c = 0;\n for (const b of blocks) for (const id of b) pos.set(id, c++);\n }\n return pos;\n };\n const structuralNeighbors = (id: number): number[] => {\n const out: { id: number; w: number }[] = [];\n // Barycenter ordering uses NON-coparental unions only (SPEC Pass 1 / FIX E): a\n // coparental pair draws no couple bar, so it must exert no ordering attraction either.\n for (const u of coupleUnions) {\n if (u.personAId === id) out.push({ id: u.personBId, w: 1 });\n else if (u.personBId === id) out.push({ id: u.personAId, w: 1 });\n }\n for (const l of allLinks) {\n if (l.childId === id) out.push({ id: l.parentId, w: 1 });\n else if (l.parentId === id) out.push({ id: l.childId, w: 1 });\n }\n for (const rl of bondRels) {\n if (rl.fromPersonId === id) out.push({ id: rl.toPersonId, w: 0.5 });\n else if (rl.toPersonId === id) out.push({ id: rl.fromPersonId, w: 0.5 });\n }\n return out.map((o) => o.id);\n };\n const neighborWeight = (id: number, other: number): number => {\n let w = 0;\n // NON-coparental unions only — same FIX E rationale as structuralNeighbors.\n for (const u of coupleUnions) if ((u.personAId === id && u.personBId === other) || (u.personBId === id && u.personAId === other)) w = Math.max(w, 1);\n for (const l of allLinks) if ((l.childId === id && l.parentId === other) || (l.parentId === id && l.childId === other)) w = Math.max(w, 1);\n for (const rl of bondRels) if ((rl.fromPersonId === id && rl.toPersonId === other) || (rl.toPersonId === id && rl.fromPersonId === other)) w = Math.max(w, 0.5);\n return w;\n };\n const sweep = (r: number, ref: number): void => {\n const pos = flattened();\n const blocks = rowBlocks[r]!;\n const bcOf = (b: Block): number => {\n let sum = 0;\n let wsum = 0;\n for (const id of b) {\n for (const nb of structuralNeighbors(id)) {\n if (rowOfPerson.get(nb) !== ref) continue;\n const w = neighborWeight(id, nb);\n sum += (pos.get(nb) ?? 0) * w;\n wsum += w;\n }\n }\n return wsum === 0 ? Number.POSITIVE_INFINITY : sum / wsum;\n };\n const keyed = blocks.map((b) => ({ b, bc: bcOf(b), minId: Math.min(...b) }));\n keyed.sort((x, y) => (x.bc !== y.bc ? x.bc - y.bc : x.minId - y.minId));\n rowBlocks[r] = keyed.map((k) => k.b);\n };\n if (rowCount >= 2) {\n for (let r = 1; r < rowCount; r++) sweep(r, r - 1);\n for (let r = rowCount - 2; r >= 0; r--) sweep(r, r + 1);\n }\n\n // Isolated people drift fully right: stable-partition each row so isolated singleton\n // blocks trail the connected ones (ordered by id). No connector is ever drawn for them.\n for (let r = 0; r < rowCount; r++) {\n const blocks = rowBlocks[r]!;\n const connected = blocks.filter((b) => !(b.length === 1 && isIsolated(b[0]!)));\n const isolated = blocks.filter((b) => b.length === 1 && isIsolated(b[0]!)).sort((a, b) => a[0]! - b[0]!);\n rowBlocks[r] = [...connected, ...isolated];\n }\n\n // ── Pass 1c: assign (row, col) to every person via the global column grid ─────────\n const colOf = new Map<number, number>();\n let colCount = 0;\n for (let r = 0; r < rowCount; r++) {\n let c = 0;\n for (const b of rowBlocks[r]!) for (const id of b) colOf.set(id, c++);\n colCount = Math.max(colCount, c);\n }\n const colOrThrow = (id: number): number => colOf.get(id)!;\n\n // Column where the isolated-only tail begins (extra gutter sits just before it).\n let isolatedTailCol = colCount; // none by default\n {\n const peopleAtCol: number[][] = Array.from({ length: colCount }, () => []);\n for (const p of people) peopleAtCol[colOrThrow(p.id)]!.push(p.id);\n for (let c = colCount - 1; c >= 1; c--) {\n const all = peopleAtCol[c]!;\n if (all.length > 0 && all.every((id) => isIsolated(id))) isolatedTailCol = c;\n else break;\n }\n }\n\n // ── Pass 2 prep: measure labels; column widths; per-row label heights ─────────────\n const measured = new Map<number, Measured>();\n for (const p of people) {\n const lines = wrapNodeLabel(clampLabel(p.label, opts.maxLabelChars));\n const contentW = Math.max(NODE_SIZE, lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, LABEL_FONT)), 0));\n measured.set(p.id, { person: p, lines, contentW });\n }\n const colWidth: number[] = Array.from({ length: colCount }, () => NODE_SIZE);\n for (const p of people) {\n const c = colOrThrow(p.id);\n colWidth[c] = Math.max(colWidth[c]!, measured.get(p.id)!.contentW);\n }\n const rowMaxLines: number[] = Array.from({ length: rowCount }, () => 1);\n for (const p of people) {\n const r = rowOfPerson.get(p.id)!;\n rowMaxLines[r] = Math.max(rowMaxLines[r]!, measured.get(p.id)!.lines.length);\n }\n\n // ── Pass 2: route every element symbolically and register lane/slot requests ──────\n const planned: PlannedElement[] = [];\n const gutterReqs: GutterReq[] = [];\n const corridorReqs: CorridorReq[] = [];\n const stubCount = new Map<string, number>(); // `${id}:${side}` → slots used\n const arrivalCount = new Map<number, number>(); // id → arrival slots used\n\n const newStub = (personId: number, side: -1 | 1): StubReq => {\n const key = `${personId}:${side}`;\n const slot = stubCount.get(key) ?? 0;\n stubCount.set(key, slot + 1);\n return { personId, side, slot };\n };\n const newArrival = (personId: number): ArrivalReq => {\n const slot = arrivalCount.get(personId) ?? 0;\n arrivalCount.set(personId, slot + 1);\n return { personId, slot };\n };\n const departSide = (srcId: number, dstId: number): -1 | 1 => {\n const sc = colOrThrow(srcId);\n const dc = colOrThrow(dstId);\n if (dc > sc) return 1;\n if (dc < sc) return -1;\n return sc < colCount - 1 ? 1 : -1;\n };\n // The gutter a connector departs INTO, and which side of it the departing column is on.\n const gutterFor = (srcCol: number, side: -1 | 1): { gutter: number; gSide: -1 | 1 } =>\n side === 1\n ? { gutter: srcCol, gSide: -1 } // depart right → gutter to the right; src is its LEFT column\n : { gutter: srcCol - 1, gSide: 1 }; // depart left → gutter to the left; src is its RIGHT column\n\n // A cross-row connector: sideways stub from the UPPER node, gutter drop, corridor cross,\n // arrival into the LOWER glyph TOP. Returns a builder closure over the resolved geo.\n // Robust to either argument order: it routes from whichever node is in the SHALLOWER\n // (upper) declared generation, so a parent declared in a YOUNGER generation than the\n // child (srcRow > dstRow) still gets a valid, non-negative, in-range corridor and an\n // ordered gutter span instead of a negative index (FIX D-1). Normal upper→lower calls\n // are unchanged: the upper node is the source and corridor = lowerRow − 1 as before.\n const planConnector = (\n srcId: number,\n dstId: number,\n arrivalAtCenter: boolean,\n ): (() => Point[]) => {\n const srcRow = rowOfPerson.get(srcId)!;\n const dstRow = rowOfPerson.get(dstId)!;\n // Departure is always from the upper node; arrival into the lower node's TOP edge.\n const [upperId, lowerId] = srcRow <= dstRow ? [srcId, dstId] : [dstId, srcId];\n const upperRow = rowOfPerson.get(upperId)!;\n const lowerRow = rowOfPerson.get(lowerId)!;\n const side = departSide(upperId, lowerId);\n const { gutter, gSide } = gutterFor(colOrThrow(upperId), side);\n const stub = newStub(upperId, side);\n // Corridor just above the lower row, clamped in-range (degenerate same-row → band 0).\n const corridor = Math.max(0, Math.min(rowCount - 1, lowerRow - 1));\n const gReq: GutterReq = {\n gutter,\n side: gSide,\n rowLo: Math.min(upperRow, corridor + 0.5),\n rowHi: Math.max(upperRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(gReq);\n const arrival = arrivalAtCenter ? null : newArrival(lowerId);\n const arrivalX = (): number =>\n geo.cx(colOrThrow(lowerId)) + (arrival ? arrivalOffset(arrival.slot, arrivalCount.get(lowerId) ?? 1) : 0);\n const cReq: CorridorReq = {\n corridor,\n xRange: () => {\n const gx = geo.gutterLaneX(gReq);\n const ax = arrivalX();\n return [Math.min(gx, ax), Math.max(gx, ax)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const sy = geo.cy(upperRow) + stubOffset(stub.slot);\n const sEdge = side === 1 ? geo.glyphRight(upperId) : geo.glyphLeft(upperId);\n const gx = geo.gutterLaneX(gReq);\n const cyCorr = geo.corridorLaneY(cReq);\n const ax = arrivalX();\n const topY = geo.cy(lowerRow) - NODE_SIZE / 2;\n return [\n { x: sEdge, y: sy },\n { x: gx, y: sy },\n { x: gx, y: cyCorr },\n { x: ax, y: cyCorr },\n { x: ax, y: topY },\n ];\n };\n };\n\n // A same-row connector (U under the row): both endpoints leave sideways toward each\n // other, drop into the corridor below the row, and cross there.\n const planUConnector = (aId: number, bId: number): (() => Point[]) => {\n const row = rowOfPerson.get(aId)!;\n const [leftId, rightId] = colOrThrow(aId) <= colOrThrow(bId) ? [aId, bId] : [bId, aId];\n const stubL = newStub(leftId, 1);\n const stubR = newStub(rightId, -1);\n const gL = gutterFor(colOrThrow(leftId), 1);\n const gR = gutterFor(colOrThrow(rightId), -1);\n const gReqL: GutterReq = { gutter: gL.gutter, side: gL.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n const gReqR: GutterReq = { gutter: gR.gutter, side: gR.gSide, rowLo: row, rowHi: row + 0.5, lane: 0 };\n gutterReqs.push(gReqL, gReqR);\n const cReq: CorridorReq = {\n corridor: row,\n xRange: () => {\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n return [Math.min(xL, xR), Math.max(xL, xR)];\n },\n lane: 0,\n };\n corridorReqs.push(cReq);\n return () => {\n const yL = geo.cy(row) + stubOffset(stubL.slot);\n const yR = geo.cy(row) + stubOffset(stubR.slot);\n const xL = geo.gutterLaneX(gReqL);\n const xR = geo.gutterLaneX(gReqR);\n const cyCorr = geo.corridorLaneY(cReq);\n return [\n { x: geo.glyphRight(leftId), y: yL },\n { x: xL, y: yL },\n { x: xL, y: cyCorr },\n { x: xR, y: cyCorr },\n { x: xR, y: yR },\n { x: geo.glyphLeft(rightId), y: yR },\n ];\n };\n };\n\n const unionTitle = (u: Union): string =>\n u.quality !== null\n ? `${titleLabels.unionStatus[u.status]} · ${u.quality}`\n : titleLabels.unionStatus[u.status];\n const linkTitle = (l: { quality: string | null }): string =>\n l.quality !== null ? `${titleLabels.parentage} · ${l.quality}` : titleLabels.parentage;\n\n // 2a. Unions: same-row adjacent → bar; otherwise → elbow. (coparental drew nothing.)\n // McGoldrick SERIAL-UNION staggering (FIX B): when a person is in 2+ same-row union-bars\n // (remarriage), the bars would all sit at glyph-center cy and read as ONE continuous\n // rail. So within each connected chain of adjacent bars (components sharing a person),\n // the LOWEST union id stays at cy (level 0) and every other bar DIPS to a distinct depth\n // below the row's glyphs (level k → glyph bottom + k·UNION_STAGGER), drawn as a 3-seg\n // elbow (stub-down from each partner's glyph bottom → across → stub-up). The dip depth\n // is reserved in the row band (`rowDipDepth`) so labels never collide.\n const unionIsBar = new Map<number, boolean>();\n const barUnions = coupleUnions.filter(\n (u) =>\n rowOfPerson.get(u.personAId) === rowOfPerson.get(u.personBId) &&\n Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1,\n );\n // Per row, connected components of adjacent bar-unions (sharing a person), each ordered\n // by union id; index 0 → level 0 (cy), index k → dip level k. Deterministic.\n const unionDipLevel = new Map<number, number>(); // union id → dip level (0 = at cy)\n const rowDipLevels: number[] = Array.from({ length: rowCount }, () => 0);\n {\n const byRow = new Map<number, Union[]>();\n for (const u of barUnions) {\n const r = rowOfPerson.get(u.personAId)!;\n (byRow.get(r) ?? byRow.set(r, []).get(r)!).push(u);\n }\n for (const [r, rowUnions] of byRow) {\n // person → adjacent bar-unions on this row\n const unionsOfPerson = new Map<number, Union[]>();\n for (const u of rowUnions) {\n (unionsOfPerson.get(u.personAId) ?? unionsOfPerson.set(u.personAId, []).get(u.personAId)!).push(u);\n (unionsOfPerson.get(u.personBId) ?? unionsOfPerson.set(u.personBId, []).get(u.personBId)!).push(u);\n }\n const seen = new Set<number>();\n // Stable component discovery: walk unions in ascending id; BFS the shared-person graph.\n for (const start of [...rowUnions].sort((a, b) => a.id - b.id)) {\n if (seen.has(start.id)) continue;\n const comp: Union[] = [];\n const stack = [start];\n seen.add(start.id);\n while (stack.length > 0) {\n const u = stack.pop()!;\n comp.push(u);\n for (const pid of [u.personAId, u.personBId]) {\n for (const nb of unionsOfPerson.get(pid) ?? []) {\n if (!seen.has(nb.id)) {\n seen.add(nb.id);\n stack.push(nb);\n }\n }\n }\n }\n comp.sort((a, b) => a.id - b.id);\n comp.forEach((u, i) => unionDipLevel.set(u.id, i));\n rowDipLevels[r] = Math.max(rowDipLevels[r]!, comp.length - 1);\n }\n }\n }\n\n for (const u of coupleUnions) {\n const aRow = rowOfPerson.get(u.personAId)!;\n const bRow = rowOfPerson.get(u.personBId)!;\n const adjacent =\n aRow === bRow && Math.abs(colOrThrow(u.personAId) - colOrThrow(u.personBId)) === 1;\n unionIsBar.set(u.id, adjacent);\n const edgeId = UNION_REL_ID_BASE + u.id;\n if (adjacent) {\n const [leftId, rightId] = colOrThrow(u.personAId) < colOrThrow(u.personBId)\n ? [u.personAId, u.personBId]\n : [u.personBId, u.personAId];\n const dipLevel = unionDipLevel.get(u.id) ?? 0;\n planned.push({\n kind: \"union-bar\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n build: () => {\n const cy = geo.cy(rowOfPerson.get(leftId)!);\n if (dipLevel === 0) {\n // First bar of the chain: the classic straight bar at glyph-center cy.\n return [\n { x: geo.glyphRight(leftId), y: cy },\n { x: geo.glyphLeft(rightId), y: cy },\n ];\n }\n // Dipped bar: stub-down from each partner's glyph BOTTOM to the dipped Y, across.\n // The stubs leave the glyph bottom OFFSET toward the partner (left partner →\n // right-of-center, right partner → left-of-center), so a person in two serial\n // unions (one on each side) gets two distinct stub columns that never overlap.\n const y = geo.unionDipY(rowOfPerson.get(leftId)!, dipLevel);\n const bottom = cy + NODE_SIZE / 2;\n const lx = geo.cx(colOrThrow(leftId)) + STUB_X_OFF; // partner is to the right\n const rx = geo.cx(colOrThrow(rightId)) - STUB_X_OFF; // partner is to the left\n return [\n { x: lx, y: bottom },\n { x: lx, y },\n { x: rx, y },\n { x: rx, y: bottom },\n ];\n },\n });\n } else {\n const sameRow = aRow === bRow;\n const build = sameRow\n ? planUConnector(u.personAId, u.personBId)\n : (() => {\n const [up, lo] = aRow < bRow ? [u.personAId, u.personBId] : [u.personBId, u.personAId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"union-elbow\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: u.personAId,\n toPersonId: u.personBId,\n titles: [unionTitle(u)],\n lineStyle: \"plain\",\n build,\n });\n }\n }\n\n // 2b. Descents. Decide, per child, the single declared COUPLE pair (if any) whose\n // union is an adjacent bar; that pair gets the shared sibling-bar descent, every\n // other declared genitor gets a dotted lone descent. No declared couple → all\n // dotted (Caso B / co-parental): each genitor its own descent, never a bar.\n const coupleChildrenByUnion = new Map<number, number[]>(); // union id → children\n const loneLinks: LayoutLink[] = [];\n for (const childId of [...parentsOf.keys()].sort((a, b) => a - b)) {\n const parents = [...parentsOf.get(childId)!].sort((a, b) => a - b);\n const couplePairUnions = parents\n .flatMap((p, i) => parents.slice(i + 1).map((q) => coupleByPair.get(pairKey(p, q))))\n .filter((u): u is Union => u !== undefined && unionIsBar.get(u.id) === true);\n if (couplePairUnions.length === 1) {\n const u = couplePairUnions[0]!;\n const arr = coupleChildrenByUnion.get(u.id) ?? [];\n arr.push(childId);\n coupleChildrenByUnion.set(u.id, arr);\n const couplePeople = new Set([u.personAId, u.personBId]);\n for (const p of parents) if (!couplePeople.has(p)) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n } else {\n for (const p of parents) loneLinks.push(linkOf.get(`${p}>${childId}`)!);\n }\n }\n\n // Couple descents (processed first, by union id): one shared sibling-bar per child-row\n // group, a center spine from the bar, and a vertical drop to each child's glyph TOP.\n for (const u of coupleUnions) {\n const children = coupleChildrenByUnion.get(u.id);\n if (children === undefined || children.length === 0) continue;\n const leftId = colOrThrow(u.personAId) < colOrThrow(u.personBId) ? u.personAId : u.personBId;\n const interGutter = colOrThrow(leftId); // gutter between the two adjacent partners\n const parentRow = rowOfPerson.get(u.personAId)!;\n // A couple descent must leave the union BAR, so on a dipped (serial-union) bar the\n // spine starts at the dipped bar's Y, not the glyph-center cy (FIX B).\n const uDipLevel = unionDipLevel.get(u.id) ?? 0;\n const spineStartY = (): number =>\n uDipLevel === 0 ? geo.cy(parentRow) : geo.unionDipY(parentRow, uDipLevel);\n // Group children by their row (almost always one row).\n const byChildRow = new Map<number, number[]>();\n for (const c of children) {\n const cr = rowOfPerson.get(c)!;\n (byChildRow.get(cr) ?? byChildRow.set(cr, []).get(cr)!).push(c);\n }\n for (const childRow of [...byChildRow.keys()].sort((a, b) => a - b)) {\n const groupKids = byChildRow.get(childRow)!.sort((a, b) => colOrThrow(a) - colOrThrow(b));\n // Corridor just above the child row; clamped in-range so a degenerate \"couple + child\n // all on generation 0\" (childRow === 0) routes in band 0 instead of corridor[-1]\n // (undefined) — defensive, no fixture triggers it (FIX D-2).\n const corridor = Math.max(0, Math.min(rowCount - 1, childRow - 1));\n // The descent lives in ONE corridor lane shared by the spine, sibling bar and the\n // child drops, spanning the spine column and every child column.\n const sibSpan = (): number[] => [geo.gutterCenterX(interGutter), ...groupKids.map((c) => geo.cx(colOrThrow(c)))];\n const sibReq: CorridorReq = {\n corridor,\n xRange: () => {\n const xs = sibSpan();\n return [Math.min(...xs), Math.max(...xs)];\n },\n lane: 0,\n };\n corridorReqs.push(sibReq);\n const spineReq: GutterReq = {\n gutter: interGutter,\n side: 0,\n rowLo: Math.min(parentRow, corridor + 0.5), // ordered (FIX D-2): never inverted\n rowHi: Math.max(parentRow, corridor + 0.5),\n lane: 0,\n };\n gutterReqs.push(spineReq);\n const aId = (c: number): number => linkOf.get(`${u.personAId}>${c}`)!.edgeId;\n // A child drop represents ONE declared parentage link (the given parent → c). Its\n // data-edge-id AND its <title> both come from THAT link, so the verbatim parentage\n // (incl. any quality word) matches what the drop's id declares (FIX C-1) — never a\n // hardcoded B-side title under an A-side id.\n const childDrop = (c: number, parentId: number): void => {\n const link = linkOf.get(`${parentId}>${c}`)!;\n const edgeId = link.edgeId;\n const arr = newArrival(c); // couples are processed first → claims the CENTER slot\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: null,\n toPersonId: c,\n titles: [linkTitle(link)],\n lineStyle: \"plain\",\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const x = geo.cx(colOrThrow(c)) + arrivalOffset(arr.slot, arrivalCount.get(c) ?? 1);\n return [\n { x, y },\n { x, y: geo.cy(rowOfPerson.get(c)!) - NODE_SIZE / 2 },\n ];\n },\n });\n };\n\n if (groupKids.length === 1) {\n // Single child: spine + bar-to-child is ONE elbow (parent A's link), the drop is\n // the other (parent B's link) — exactly two data-edge-id groups, one per declared\n // parentage (the verify-sweep 1:1 traceability contract), same pixels as a bar.\n const c = groupKids[0]!;\n planned.push({\n kind: \"descent\",\n relIds: [aId(c)],\n edgeId: aId(c),\n fromPersonId: null,\n toPersonId: null,\n titles: [linkTitle(linkOf.get(`${u.personAId}>${c}`)!)],\n lineStyle: \"plain\",\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const sx = geo.gutterCenterX(interGutter);\n const cx = geo.cx(colOrThrow(c));\n return [\n { x: sx, y: spineStartY() },\n { x: sx, y: sy },\n { x: cx, y: sy },\n ];\n },\n });\n childDrop(c, u.personBId);\n } else {\n // ≥2 children: one shared sibling bar + one spine + a drop per child. Each child's\n // drop carries its B-side parentage id; the sibling bar carries A[0] (and traces\n // every remaining A-side link in relIds), the spine carries A[1] — distinct\n // data-edge-id per group, every declared link present in relIds.\n const aLinks = groupKids.map((c) => aId(c));\n // The verbatim A-side parentage title for child c (incl. any quality word).\n const aLinkTitle = (c: number): string => linkTitle(linkOf.get(`${u.personAId}>${c}`)!);\n planned.push({\n kind: \"sibling-bar\",\n relIds: [aLinks[0]!, ...aLinks.slice(2)],\n edgeId: aLinks[0]!,\n fromPersonId: null,\n toPersonId: null,\n // Carry the verbatim title of EVERY A-side link this bar represents, so no\n // declared quality word is dropped from the drawn element (FIX C-2 / SPEC inv #4).\n titles: [aLinkTitle(groupKids[0]!), ...groupKids.slice(2).map(aLinkTitle)],\n lineStyle: \"plain\",\n build: () => {\n const y = geo.corridorLaneY(sibReq);\n const xs = sibSpan();\n return [\n { x: Math.min(...xs), y },\n { x: Math.max(...xs), y },\n ];\n },\n });\n planned.push({\n kind: \"descent\",\n relIds: [aLinks[1]!],\n edgeId: aLinks[1]!,\n fromPersonId: null,\n toPersonId: null,\n titles: [aLinkTitle(groupKids[1]!)], // the A-side link this spine carries, verbatim\n lineStyle: \"plain\",\n build: () => {\n const sy = geo.corridorLaneY(sibReq);\n const x = geo.gutterCenterX(interGutter);\n return [\n { x, y: spineStartY() },\n { x, y: sy },\n ];\n },\n });\n for (const c of groupKids) childDrop(c, u.personBId);\n }\n }\n }\n\n // Lone / co-parental descents (dotted), by edge id (real before promoted, deterministic).\n for (const l of [...loneLinks].sort((a, b) => a.edgeId - b.edgeId)) {\n const edgeId = l.edgeId;\n const pRow = rowOfPerson.get(l.parentId)!;\n const cRow = rowOfPerson.get(l.childId)!;\n const build = pRow === cRow\n ? planUConnector(l.parentId, l.childId)\n : planConnector(l.parentId, l.childId, false);\n planned.push({\n kind: \"descent\",\n relIds: [edgeId],\n edgeId,\n fromPersonId: l.parentId,\n toPersonId: l.childId,\n titles: [linkTitle(l)],\n lineStyle: \"plain\",\n dotted: true,\n build,\n });\n }\n\n // 2c. Bonds (free-text relationships), with the honesty-safe merge: same unordered\n // pair AND same computed lineStyle merge into one drawn element; different styles\n // draw separately (merging would have to pick one side's style).\n const bondGroups = new Map<string, { relIds: number[]; titles: string[]; style: EdgeLineStyle; aId: number; bId: number }>();\n for (const r of bondRels) {\n const style = qualityLineStyle(r.quality, opts.qualityLexicon);\n const lo = Math.min(r.fromPersonId, r.toPersonId);\n const hi = Math.max(r.fromPersonId, r.toPersonId);\n const key = `${lo}|${hi}|${style}`;\n const title = r.quality !== null ? `${r.type} · ${r.quality}` : r.type;\n const g = bondGroups.get(key);\n if (g === undefined) {\n bondGroups.set(key, { relIds: [r.id], titles: [title], style, aId: r.fromPersonId, bId: r.toPersonId });\n } else {\n g.relIds.push(r.id);\n g.titles.push(title);\n }\n }\n const bondList = [...bondGroups.values()].sort((a, b) => Math.max(...a.relIds) - Math.max(...b.relIds));\n for (const g of bondList) {\n const aRow = rowOfPerson.get(g.aId)!;\n const bRow = rowOfPerson.get(g.bId)!;\n const build = aRow === bRow\n ? planUConnector(g.aId, g.bId)\n : (() => {\n const [up, lo] = aRow < bRow ? [g.aId, g.bId] : [g.bId, g.aId];\n return planConnector(up, lo, false);\n })();\n planned.push({\n kind: \"bond\",\n relIds: g.relIds,\n edgeId: Math.max(...g.relIds),\n fromPersonId: g.aId,\n toPersonId: g.bId,\n titles: g.titles,\n lineStyle: g.style,\n build,\n });\n }\n\n // ── Pass 3: staged geometry so corridor lanes are allocated on EXACT pixel x ───────\n // Mutable geometry state, filled stage by stage; the build/xRange closures (created in\n // Pass 2) read it through `geo` at call time only — never before its stage fills it.\n const colCenterX: number[] = [];\n const colLeftX: number[] = [];\n const colRightX: number[] = [];\n const rowCenterY: number[] = [];\n const rowLabelTopY: number[] = [];\n const corridorTopY: number[] = [];\n const dims = { width: 0 };\n const gutterLaneCount = new Map<string, number>(); // `${gutter}:${side}` → count\n const corridorLaneCount: number[] = Array.from({ length: rowCount }, () => 0);\n const laneCount = (gutter: number, side: -1 | 0 | 1): number => gutterLaneCount.get(`${gutter}:${side}`) ?? 0;\n\n const geo = {\n cx: (c: number): number => colCenterX[c]!,\n cy: (r: number): number => rowCenterY[r]!,\n glyphRight: (id: number): number => colCenterX[colOrThrow(id)]! + NODE_SIZE / 2,\n glyphLeft: (id: number): number => colCenterX[colOrThrow(id)]! - NODE_SIZE / 2,\n gutterCenterX: (g: number): number => {\n const left = g < 0 ? PADDING : colRightX[g]!;\n const right = g >= colCount - 1 ? dims.width - PADDING : colLeftX[g + 1]!;\n return (left + right) / 2;\n },\n gutterLaneX: (req: GutterReq): number => {\n const left = req.gutter < 0 ? PADDING : colRightX[req.gutter]!;\n const right = req.gutter >= colCount - 1 ? dims.width - PADDING : colLeftX[req.gutter + 1]!;\n const lCount = laneCount(req.gutter, -1);\n if (req.side === -1) return left + (req.lane + 1) * LANE_H; // hug left, stack rightward\n if (req.side === 0) return left + (lCount + req.lane + 1) * LANE_H; // center group (spine)\n return right - (req.lane + 1) * LANE_H; // hug right, stack leftward\n },\n corridorLaneY: (req: CorridorReq): number =>\n corridorTopY[req.corridor]! + CORRIDOR_BASE / 2 + req.lane * LANE_H,\n /** Y of a dipped serial-union bar (level ≥ 1): below the row's glyph bottom edge. */\n unionDipY: (r: number, level: number): number =>\n rowCenterY[r]! + NODE_SIZE / 2 + level * UNION_STAGGER,\n };\n\n // Stage 1 — gutter lanes: per (gutter, side), by row-span interval. Left-hug and\n // right-hug stacks sit on opposite sides; the center group is the union spine.\n const gutterGroups = new Map<string, GutterReq[]>();\n for (const req of gutterReqs) {\n const k = `${req.gutter}:${req.side}`;\n (gutterGroups.get(k) ?? gutterGroups.set(k, []).get(k)!).push(req);\n }\n for (const [k, reqs] of gutterGroups) {\n gutterLaneCount.set(\n k,\n allocateLanes(reqs.map((req) => ({ lo: req.rowLo, hi: req.rowHi, set: (lane: number) => (req.lane = lane) }))),\n );\n }\n\n // Stage 2 — column geometry from gutter lane counts (+ the isolated extra gutter).\n const gutterWidth = (g: number): number => {\n const lanes = laneCount(g, -1) + laneCount(g, 0) + laneCount(g, 1);\n const extra = g === isolatedTailCol - 1 ? ISOLATED_GUTTER_EXTRA : 0;\n if (g === -1 || g === colCount - 1) return lanes > 0 ? COL_PAD + lanes * LANE_H + extra : extra;\n return COL_PAD + lanes * LANE_H + extra;\n };\n let cursorX = PADDING + gutterWidth(-1);\n for (let c = 0; c < colCount; c++) {\n colLeftX[c] = cursorX;\n colCenterX[c] = cursorX + colWidth[c]! / 2;\n cursorX += colWidth[c]!;\n colRightX[c] = cursorX;\n cursorX += gutterWidth(c);\n }\n dims.width = cursorX + PADDING;\n\n // Stage 3 — corridor lanes on EXACT pixel x-ranges (columns are now placed, so a\n // within-one-gutter span is measured precisely — no collapsing u-index proxy).\n const corridorGroups = new Map<number, CorridorReq[]>();\n for (const req of corridorReqs) (corridorGroups.get(req.corridor) ?? corridorGroups.set(req.corridor, []).get(req.corridor)!).push(req);\n for (const [k, reqs] of corridorGroups) {\n corridorLaneCount[k] = allocateLanes(\n reqs.map((req) => {\n const [lo, hi] = req.xRange();\n return { lo, hi, set: (lane: number) => (req.lane = lane) };\n }),\n );\n }\n\n // Stage 4 — row geometry from corridor lane counts.\n const corridorHeight = (k: number): number => {\n const lanes = corridorLaneCount[k] ?? 0;\n if (lanes > 0) return CORRIDOR_BASE + lanes * LANE_H;\n return k < rowCount - 1 ? CORRIDOR_BASE : 0; // interior rows always keep a gap\n };\n // Reserve a band BELOW each row's glyphs for its dipped serial-union bars (FIX B), so\n // labels sit below the deepest dip and never collide. 0 when the row has no remarriage.\n const rowDipReserve = (r: number): number =>\n rowDipLevels[r]! > 0 ? rowDipLevels[r]! * UNION_STAGGER + 6 : 0;\n let cursorY = PADDING;\n for (let r = 0; r < rowCount; r++) {\n rowCenterY[r] = cursorY + NODE_SIZE / 2;\n rowLabelTopY[r] = cursorY + NODE_SIZE + rowDipReserve(r) + LABEL_GAP_TOP;\n cursorY = rowLabelTopY[r]! + rowMaxLines[r]! * LABEL_LINE_H;\n corridorTopY[r] = cursorY;\n cursorY += corridorHeight(r);\n }\n const width = dims.width;\n const height = cursorY + PADDING;\n\n // ── Build nodes + finalize elements ──────────────────────────────────────────────\n const nodes: GenogramNode[] = [...people]\n .sort((a, b) => a.id - b.id)\n .map((p) => {\n const m = measured.get(p.id)!;\n const r = rowOfPerson.get(p.id)!;\n const c = colOrThrow(p.id);\n return {\n personId: p.id,\n label: p.label,\n shape: shapeForSex(p.sex),\n deceased: p.deceased,\n cx: colCenterX[c]!,\n cy: rowCenterY[r]!,\n size: NODE_SIZE,\n labelLines: m.lines,\n labelTop: rowLabelTopY[r]!,\n };\n });\n\n const elements: GenogramElement[] = planned.map((pl) => ({\n kind: pl.kind,\n relIds: pl.relIds,\n edgeId: pl.edgeId,\n fromPersonId: pl.fromPersonId,\n toPersonId: pl.toPersonId,\n points: pl.build(),\n titles: pl.titles,\n lineStyle: pl.lineStyle,\n ...(pl.unionStyle !== undefined ? { unionStyle: pl.unionStyle } : {}),\n ...(pl.dotted ? { dotted: true } : {}),\n }));\n\n // People with no drawn connection (only-suppressed/derived ties, or none at all).\n const isolatedPersonIds = people\n .filter((p) => isIsolated(p.id))\n .map((p) => p.id)\n .sort((a, b) => a - b);\n\n return { width, height, nodes, elements, isolatedPersonIds };\n}\n\n/** Linearize a connected couple-component so partners land adjacent. A simple path is\n * walked from its lowest-id endpoint (→ a clean chain); anything else is DFS-ordered\n * from the lowest id (hub gets two adjacent partners; the rest become union-elbows). */\nfunction linearizeBlock(comp: number[], adj: Map<number, number[]>): number[] {\n if (comp.length <= 1) return [...comp];\n const inComp = new Set(comp);\n const degree = (id: number): number => adj.get(id)!.filter((n) => inComp.has(n)).length;\n const endpoints = comp.filter((id) => degree(id) === 1).sort((a, b) => a - b);\n const edgeCount = comp.reduce((s, id) => s + degree(id), 0) / 2;\n const isPath = edgeCount === comp.length - 1 && endpoints.length === 2;\n const order: number[] = [];\n const seen = new Set<number>();\n if (isPath) {\n let cur: number | undefined = endpoints[0]!;\n while (cur !== undefined) {\n order.push(cur);\n seen.add(cur);\n cur = adj.get(cur)!.filter((n) => inComp.has(n)).sort((a, b) => a - b).find((n) => !seen.has(n));\n }\n return order;\n }\n const stack = [Math.min(...comp)];\n while (stack.length > 0) {\n const n = stack.pop()!;\n if (seen.has(n)) continue;\n seen.add(n);\n order.push(n);\n for (const m of adj.get(n)!.filter((x) => inComp.has(x)).sort((a, b) => b - a)) {\n if (!seen.has(m)) stack.push(m);\n }\n }\n return order;\n}\n","// Genogram SVG emitter — turns a computed GenogramLayout (./layout.ts, the pure\n// orthogonal declared-generation layout) into a SELF-CONTAINED SVG string.\n//\n// Two hard requirements:\n// - XML-ESCAPING of EVERY interpolated text. Labels are author-controlled and the\n// SVG string may be injected via innerHTML in a browser or embedded as vectors in\n// a PDF — an unescaped label is an XSS/`</svg>`-breakout vector on every surface.\n// - LITERAL presentation attributes (hex colors, inline stroke-dasharray, an explicit\n// font-family). A standalone SVG inside a PDF has no stylesheet, no `currentColor`.\n//\n// It is deliberately PURE (string in, string out) and DETERMINISTIC (same layout → same\n// SVG), and it draws EXACTLY what the layout computed: node centers and the routed\n// orthogonal polylines are consumed verbatim, never recomputed (the overlap harness\n// proves the layout; this emitter is pinned to it). Decoration hooks for callers: one\n// `<g data-individual-id=\"p<id>\">` per person with a direct-child `<title>` and bare\n// rect/circle/polygon glyph; `data-edge-id` on every routed group.\n//\n// HONESTY RULE: presentation only. There is ZERO text on map edges — the verbatim\n// \"type · quality\" / status label lives in each routed group's <title> (and the\n// caller's side lists). The one styling decision the CALLER may make is\n// `unionStyleByRelId`: a per-edge VISUAL override applied at emission — a\n// stroke-dasharray and/or McGoldrick status slashes — giving each declared union TYPE\n// the full notation (married solid, cohabiting/dating dashed, separated one slash,\n// divorced two) without the layout fabricating any quality text.\nimport { FONT_FAMILY, xmlEscape } from \"../core\";\nimport {\n EDGE_STROKE,\n LABEL_FONT,\n LABEL_LINE_H,\n estimateTextWidth,\n type GenogramElement,\n type GenogramLayout,\n type NodeShape,\n type Point,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { GENOGRAM_SVG_LABELS_EN, type GenogramSvgLabels } from \"./labels\";\n\n// Re-export so callers can reach the union-notation type through the emitter module.\nexport type { UnionEdgeStyle } from \"./layout\";\nexport { xmlEscape };\n\n// Literal ink colors (zinc ramp, matching the app shell on white — the PDF page).\nconst GLYPH_STROKE = \"#52525b\";\nconst NODE_LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\n// Structural (union / descent / sibling-bar) stroke — neutral, solid.\nconst STRUCT_WIDTH = 1.5;\nconst STRUCT_OPACITY = 0.75;\n// Dotted descent (lone-parent / co-parental): the visual kin of schematex's secondary.\nconst DOTTED_DASH: readonly [number, number] = [2, 3];\nconst DOTTED_OPACITY = 0.55;\n\n// Legend metrics (own, minimal — pt-BR only).\nconst LEGEND_ROW_H = 18;\nconst LEGEND_PAD = 16;\nconst LEGEND_SWATCH_W = 22;\nconst LEGEND_GAP = 14; // swatch → label gap (the \"Boxo\" fix: was 8, too tight)\nconst LEGEND_FONT = 11;\n\nexport interface GenogramSvgOptions {\n /**\n * Per-edge VISUAL union style (edgeId → {dash?, slashes?}), applied at emission.\n * Gives each declared union TYPE its own McGoldrick notation. Overrides any\n * `unionStyle` already on the element.\n */\n unionStyleByRelId?: ReadonlyMap<number, UnionEdgeStyle>;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: GenogramSvgLabels;\n}\n\n/** Glyph markup for one shape centered at (cx, cy) with the given half-size. */\nfunction glyphSvg(shape: NodeShape, cx: number, cy: number, half: number): string {\n const stroke = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n if (shape === \"square\") {\n return `<rect x=\"${cx - half}\" y=\"${cy - half}\" width=\"${half * 2}\" height=\"${half * 2}\" rx=\"4\" ${stroke}/>`;\n }\n if (shape === \"circle\") {\n return `<circle cx=\"${cx}\" cy=\"${cy}\" r=\"${half}\" ${stroke}/>`;\n }\n return `<polygon points=\"${cx},${cy - half} ${cx + half},${cy} ${cx},${cy + half} ${cx - half},${cy}\" ${stroke}/>`;\n}\n\n/** \"M x y L x y …\" path data from an orthogonal polyline. */\nfunction pathData(points: Point[]): string {\n return points.map((p, i) => `${i === 0 ? \"M\" : \"L\"} ${p.x} ${p.y}`).join(\" \");\n}\n\n/** The longest horizontal segment of a polyline (for placing union-elbow slashes). */\nfunction longestHSegment(points: Point[]): [Point, Point] {\n let best: [Point, Point] = [points[0]!, points[points.length - 1]!];\n let bestLen = -1;\n for (let i = 0; i + 1 < points.length; i++) {\n const a = points[i]!;\n const b = points[i + 1]!;\n if (a.y === b.y) {\n const len = Math.abs(b.x - a.x);\n if (len > bestLen) {\n bestLen = len;\n best = [a, b];\n }\n }\n }\n return best;\n}\n\n/**\n * McGoldrick status slashes at the midpoint of a segment (1 = separação, 2 = divórcio),\n * drawn in screen-space \"/\" orientation and offset along the segment for the two divorce\n * strokes. Same ink/width as the bar so the mark reads as part of it.\n */\nfunction slashMarks(a: Point, b: Point, count: 1 | 2, width: number): string {\n const mx = (a.x + b.x) / 2;\n const my = (a.y + b.y) / 2;\n const dx = b.x - a.x;\n const dy = b.y - a.y;\n const len = Math.hypot(dx, dy) || 1;\n const ux = dx / len;\n const uy = dy / len;\n const HALF = 7; // slash half-length\n const STEP = 4; // along-segment offset between the two divorce slashes\n const offsets = count === 1 ? [0] : [-STEP, STEP];\n return offsets\n .map((o) => {\n const px = mx + ux * o;\n const py = my + uy * o;\n return `<line x1=\"${px - HALF}\" y1=\"${py + HALF}\" x2=\"${px + HALF}\" y2=\"${py - HALF}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\"/>`;\n })\n .join(\"\");\n}\n\n/** Resolve a union element's effective McGoldrick style (override wins over element). */\nfunction resolveUnionStyle(\n el: GenogramElement,\n override: ReadonlyMap<number, UnionEdgeStyle>,\n): UnionEdgeStyle {\n return override.get(el.edgeId) ?? el.unionStyle ?? {};\n}\n\n/** Emits one routed element as a `<g data-edge-id>` group (≥3 points → path, else line),\n * with the verbatim titles in a <title> and ZERO text. */\nfunction elementSvg(el: GenogramElement, override: ReadonlyMap<number, UnionEdgeStyle>): string {\n const title = `<title>${xmlEscape(el.titles.join(\"\\n\"))}</title>`;\n const pts = el.points;\n const drawLine = (dash: readonly [number, number] | null, width: number, opacity: number): string => {\n const dashAttr = dash === null ? \"\" : ` stroke-dasharray=\"${dash[0]} ${dash[1]}\"`;\n if (pts.length === 2) {\n return `<line x1=\"${pts[0]!.x}\" y1=\"${pts[0]!.y}\" x2=\"${pts[1]!.x}\" y2=\"${pts[1]!.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n }\n return `<path d=\"${pathData(pts)}\" fill=\"none\" stroke=\"${EDGE_INK}\" stroke-width=\"${width}\" stroke-opacity=\"${opacity}\"${dashAttr}/>`;\n };\n\n if (el.kind === \"union-bar\" || el.kind === \"union-elbow\") {\n const style = resolveUnionStyle(el, override);\n const body: string[] = [drawLine(style.dash ?? null, STRUCT_WIDTH, STRUCT_OPACITY)];\n const slashes = style.slashes ?? 0;\n if (slashes === 1 || slashes === 2) {\n // A straight 2-point bar uses its own segment; a dipped serial-union bar (3-seg\n // elbow, FIX B) and any union-elbow ride the LONGEST horizontal segment so the\n // separado/divorciado slashes land on the across part, never on a vertical stub.\n const [a, b] = pts.length === 2 ? [pts[0]!, pts[1]!] : longestHSegment(pts);\n body.push(slashMarks(a, b, slashes, STRUCT_WIDTH));\n }\n return `<g data-edge-id=\"${el.edgeId}\">${title}${body.join(\"\")}</g>`;\n }\n\n if (el.kind === \"descent\" || el.kind === \"sibling-bar\") {\n const dash = el.dotted ? DOTTED_DASH : null;\n const opacity = el.dotted ? DOTTED_OPACITY : STRUCT_OPACITY;\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(dash, STRUCT_WIDTH, opacity)}</g>`;\n }\n\n // bond\n const ink = EDGE_STROKE[el.lineStyle];\n return `<g data-edge-id=\"${el.edgeId}\">${title}${drawLine(ink.dash, ink.width, ink.opacity)}</g>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed genogram layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped; all\n * presentation attributes are literal; there is NO text on map edges.\n */\nexport function genogramLayoutSvg(layout: GenogramLayout, opts: GenogramSvgOptions = {}): string {\n const override = opts.unionStyleByRelId ?? new Map<number, UnionEdgeStyle>();\n const labels = opts.labels ?? GENOGRAM_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // ── Routed elements first so nodes sit on top (same stacking as the JSX render). ───\n for (const el of layout.elements) parts.push(elementSvg(el, override));\n\n // ── Nodes: glyph + deceased mark + wrapped label, hook-compatible with schematex. ─\n for (const node of layout.nodes) {\n const half = node.size / 2;\n const pieces: string[] = [\n `<title>${xmlEscape(node.label)}</title>`,\n glyphSvg(node.shape, node.cx, node.cy, half),\n ];\n if (node.deceased) {\n pieces.push(\n `<line x1=\"${node.cx - half}\" y1=\"${node.cy - half}\" x2=\"${node.cx + half}\" y2=\"${node.cy + half}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n );\n }\n const tspans = node.labelLines\n .map(\n (line, i) =>\n `<tspan x=\"${node.cx}\" y=\"${node.labelTop + 10 + i * LABEL_LINE_H}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${LABEL_FONT}\" fill=\"${NODE_LABEL_FILL}\">${tspans}</text>`,\n );\n parts.push(`<g data-individual-id=\"p${node.personId}\">${pieces.join(\"\")}</g>`);\n }\n\n // ── Minimal pt-BR legend: only entries actually used. ──────────────────────────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const entries: { swatch: (x: number, y: number) => string; label: string }[] = [];\n\n const shapesUsed = new Set(layout.nodes.map((n) => n.shape));\n for (const shape of [\"square\", \"circle\", \"diamond\"] as const) {\n if (!shapesUsed.has(shape)) continue;\n entries.push({\n swatch: (x, y) => glyphSvg(shape, x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.shapes[shape],\n });\n }\n if (layout.nodes.some((n) => n.deceased)) {\n entries.push({\n swatch: (x, y) =>\n glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6) +\n `<line x1=\"${x + LEGEND_SWATCH_W / 2 - 6}\" y1=\"${y - 6}\" x2=\"${x + LEGEND_SWATCH_W / 2 + 6}\" y2=\"${y + 6}\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"/>`,\n label: labels.deceased,\n });\n }\n\n // NOTE (deliberate, gate-tested): the fallback legend carries NO union-TYPE or\n // dotted-descent entry. Each declared union's type and each co-parenthood fact lives\n // VERBATIM in the element's <title> and in the dossier's structured side lists (the\n // psychologist's authoritative reading) — duplicating it as a legend key is the\n // \"known, documented gap\" pinned by test/verify-pdf.test.ts §(e). The dash/slash\n // notation itself stays on the drawn bars; only the legend stays minimal.\n\n // Bond styles actually used.\n const stylesUsed = new Set(layout.elements.filter((e) => e.kind === \"bond\").map((e) => e.lineStyle));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n\n // Unconnected glyphs (a person whose only declared tie is derived kinship like \"minha\n // tia\" — read from the tree, never a line — or who was mentioned with no tie at all)\n // sit grouped to the side with NO connector. This entry labels that group so a loose\n // glyph is never left unexplained; the verbatim tie still lives in the dossier list.\n if (layout.isolatedPersonIds.length > 0) {\n entries.push({\n swatch: (x, y) => glyphSvg(\"square\", x + LEGEND_SWATCH_W / 2, y, 6),\n label: labels.isolated,\n });\n }\n\n if (entries.length > 0) {\n const startY = layout.height;\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${GLYPH_STROKE}\">${xmlEscape(entry.label)}</text>`\n );\n });\n parts.push(`<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`);\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n width = Math.max(width, LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD);\n height = startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2;\n }\n }\n\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${width} ${height}\" width=\"${width}\" height=\"${height}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call genogram render: input → self-contained SVG string. Thin, honest wiring:\n// dedupe unions per pair, compute the pure layout, give each declared union TYPE its\n// McGoldrick notation as a per-edge visual override, emit. Callers needing finer\n// control use computeGenogramLayout + genogramLayoutSvg directly.\n\nimport {\n UNION_REL_ID_BASE,\n computeGenogramLayout,\n type GenogramLayout,\n type GenogramLayoutOptions,\n type UnionEdgeStyle,\n} from \"./layout\";\nimport { genogramLayoutSvg } from \"./svg\";\nimport type { GenogramSvgLabels } from \"./labels\";\nimport type { GenogramInput, Union, UnionStatus } from \"./types\";\n\n/** Shared 6,4 dash for every cohabiting-flavoured union (cohabiting / dating /\n * type-not-stated), so non-marital couples read consistently. */\nconst COUPLE_DASH = [6, 4] as const;\n\n/**\n * McGoldrick notation per declared union TYPE — a per-edge VISUAL override applied at\n * emission, never a synthesized quality. `coparental` is ABSENT on purpose: it draws\n * NO couple element at all; the co-parenthood shows only on the descents converging\n * on the child(ren).\n */\nexport const UNION_NOTATION: Record<Exclude<UnionStatus, \"coparental\">, UnionEdgeStyle> = {\n married: {}, // solid bar\n cohabiting: { dash: COUPLE_DASH },\n dating: { dash: COUPLE_DASH },\n unknown: { dash: COUPLE_DASH },\n separated: { slashes: 1 }, // solid + one diagonal slash\n divorced: { slashes: 2 }, // solid + two parallel slashes\n};\n\n/**\n * Duplicate unions for the same unordered pair should not exist (callers are expected\n * to normalize), but if they do, the HIGHEST id wins — the most recent statement.\n * NEVER a status-rank heuristic: recency is a fact, ranking would be an interpretation.\n */\nexport function latestUnionPerPair(unions: Union[]): Union[] {\n const byPair = new Map<string, Union>();\n for (const u of [...unions].sort((a, b) => a.id - b.id)) {\n const key = `${Math.min(u.personAId, u.personBId)}|${Math.max(u.personAId, u.personBId)}`;\n byPair.set(key, u);\n }\n return [...byPair.values()].sort((a, b) => a.id - b.id);\n}\n\nexport interface GenogramRenderOptions extends GenogramLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: GenogramSvgLabels;\n}\n\nexport interface GenogramRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: GenogramLayout;\n}\n\n/**\n * Renders a genogram input to a self-contained SVG string. Deterministic: same data →\n * same SVG. Empty `people` yields an empty-but-valid SVG; callers decide their own\n * empty state before calling.\n */\nexport function genogramSvg(\n input: GenogramInput,\n opts: GenogramRenderOptions = {},\n): GenogramRenderResult {\n const ids = new Set(input.people.map((p) => p.id));\n const dedupedUnions = latestUnionPerPair(input.unions).filter(\n (u) => ids.has(u.personAId) && ids.has(u.personBId),\n );\n\n const layout = computeGenogramLayout(\n input.people,\n dedupedUnions,\n input.parentLinks,\n input.relationships,\n opts,\n );\n\n const unionStyleByRelId = new Map<number, UnionEdgeStyle>();\n for (const u of dedupedUnions) {\n if (u.status === \"coparental\") continue; // no element — nothing to style\n unionStyleByRelId.set(UNION_REL_ID_BASE + u.id, UNION_NOTATION[u.status]);\n }\n\n const svg = genogramLayoutSvg(layout, {\n unionStyleByRelId,\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Radial ecomap renderer — center node + declared external ties on 1–2 concentric\n// rings, as a SELF-CONTAINED SVG string. Pure (data in, string out), deterministic\n// (same input → same SVG), no DOM, no dependencies.\n//\n// HONESTY RULE: the diagram presents ONLY what the caller declared. A tie's line style\n// is a conservative lexical hint from the author's own quality word (ambiguous/null →\n// neutral solid line, never a synthesized value); an arrowhead appears ONLY when a\n// direction was declared (null = no arrow, never a default). The verbatim text always\n// rides the element's <title>, so a style never replaces what was said.\n//\n// Ring assignment is a deterministic PRESENTATION rule — by input order (sorted by id),\n// alternating rings when the set is large — never by any reading of the tie's content.\n//\n// Every interpolated text passes xmlEscape (labels are author-controlled; the SVG may\n// be inlined via innerHTML or embedded in a PDF). All presentation attributes are\n// literal: a standalone SVG has no stylesheet. Arrowheads are explicit polygons, NOT\n// <marker> defs — marker support is unreliable in SVG-to-PDF embedders, and inline\n// polygons also avoid def-id collisions when several SVGs share one document.\n\nimport {\n EDGE_STROKE,\n FONT_FAMILY,\n clampLabel,\n estimateTextWidth,\n qualityLineStyle,\n wrapLabel,\n xmlEscape,\n type EdgeLineStyle,\n type QualityLexicon,\n} from \"../core\";\n\n// ── Input model ───────────────────────────────────────────────────────────────\n\n/** Declared flow of the tie, relative to the CENTER: \"in\" = toward the center. */\nexport type EcomapDirection = \"in\" | \"out\" | \"both\";\n\n/**\n * One declared tie between the center (person/household) and an external system\n * (work, faith, friends, healthcare…). `label` is the author's own naming, kept\n * verbatim. `quality` is the author's verbatim wording about the tie (null = not\n * declared = neutral line). `direction` follows the same doctrine: null = no arrow.\n */\nexport interface EcomapTie {\n id: number;\n label: string;\n quality: string | null;\n direction: EcomapDirection | null;\n /** Optional verbatim <title> override (defaults to \"label · quality\"). */\n title?: string;\n}\n\nexport interface EcomapInput {\n /** Center node label (e.g. the person or household the map is about). */\n centerLabel: string;\n ties: EcomapTie[];\n}\n\n// ── Display vocabulary ────────────────────────────────────────────────────────\n\nexport interface EcomapLabels {\n bondStyles: Record<Exclude<EdgeLineStyle, \"plain\">, string>;\n /** Legend label for the neutral solid line (a declared tie with no styled quality). */\n neutralTie: string;\n /** Legend label for the arrowhead (declared direction of the tie). */\n direction: string;\n ariaLabel: string;\n}\n\nexport const ECOMAP_LABELS_EN: EcomapLabels = {\n bondStyles: {\n close: \"Close\",\n distant: \"Distant\",\n conflict: \"Conflictual\",\n cutoff: \"Cut off (no contact)\",\n },\n neutralTie: \"Declared tie\",\n direction: \"Declared direction of the tie\",\n ariaLabel: \"Ecomap\",\n};\n\nexport interface EcomapSvgOptions {\n /** Display clamp per tie label (verbatim text stays in the <title>). */\n maxLabelChars?: number;\n /** Node label font size (px); default 12. */\n fontSize?: number;\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Quality-word lexicon — English default; see `compasso/locales/pt-br`. */\n qualityLexicon?: QualityLexicon;\n /** Display vocabulary — English default; see locale packs. */\n labels?: EcomapLabels;\n}\n\n// ── Geometry constants ────────────────────────────────────────────────────────\n\nconst PADDING = 32;\nconst LINE_H = 14;\nconst NODE_PAD_X = 14;\nconst NODE_PAD_Y = 9;\nconst CENTER_MIN_R = 36;\nconst RING_MIN_R = 150;\n/** Min gap between two adjacent node boxes on the same ring. */\nconst NODE_GAP = 24;\n/** Radial gap between the center circle and the inner ring's nearest box edge. */\nconst RADIAL_GAP = 40;\n/** Radial gap between the two rings when the set is large enough to split. */\nconst RING_GAP = 26;\n/** Above this many ties the layout alternates between two rings. */\nconst SINGLE_RING_MAX = 8;\n\n// Ink (zinc ramp on white — matches the genogram emitter).\nconst NODE_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\n\n// Legend metrics (same vocabulary as the genogram emitter).\nconst LEGEND_ROW_H = 18;\nconst LEGEND_PAD = 16;\nconst LEGEND_SWATCH_W = 22;\nconst LEGEND_GAP = 14;\nconst LEGEND_FONT = 11;\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Internal shapes ───────────────────────────────────────────────────────────\n\ninterface SatNode {\n tie: EcomapTie;\n lines: string[];\n rx: number;\n ry: number;\n /** Filled once ring radii are known. */\n x: number;\n y: number;\n angle: number;\n style: EdgeLineStyle;\n}\n\n/** Wrap policy mirroring the genogram's: roughly-balanced lines, sane width. */\nfunction wrapTieLabel(displayLabel: string): string[] {\n const perLine = Math.min(26, Math.max(14, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n/** Arrowhead polygon: tip at (tipX,tipY), pointing along the unit vector (ux,uy). */\nfunction arrowHead(tipX: number, tipY: number, ux: number, uy: number, opacity: number): string {\n const LEN = 9;\n const HALF_W = 4.5;\n const bx = tipX - ux * LEN;\n const by = tipY - uy * LEN;\n const px = -uy;\n const py = ux;\n const points = [\n `${round(tipX)},${round(tipY)}`,\n `${round(bx + px * HALF_W)},${round(by + py * HALF_W)}`,\n `${round(bx - px * HALF_W)},${round(by - py * HALF_W)}`,\n ].join(\" \");\n return `<polygon points=\"${points}\" fill=\"${EDGE_INK}\" fill-opacity=\"${opacity}\"/>`;\n}\n\n/**\n * Renders a declared ecomap to a self-contained SVG string. Deterministic: same data →\n * same SVG. Zero ties yield a valid center-only SVG; callers decide their own empty\n * state before calling. The root keeps numeric width/height attributes plus a matching\n * viewBox (PDF-embedder contract).\n */\nexport function ecomapSvg(input: EcomapInput, opts: EcomapSvgOptions = {}): string {\n const fontSize = opts.fontSize ?? 12;\n const labels = opts.labels ?? ECOMAP_LABELS_EN;\n\n // ── Measure every satellite box (deterministic order: by tie id). ───────────\n const sats: SatNode[] = [...input.ties]\n .sort((a, b) => a.id - b.id)\n .map((tie) => {\n const lines = wrapTieLabel(clampLabel(tie.label, opts.maxLabelChars));\n const w = Math.max(...lines.map((l) => estimateTextWidth(l, fontSize))) + NODE_PAD_X * 2;\n const h = lines.length * LINE_H + NODE_PAD_Y * 2;\n return {\n tie,\n lines,\n rx: Math.max(40, w / 2),\n ry: Math.max(20, h / 2),\n x: 0,\n y: 0,\n angle: 0,\n style: qualityLineStyle(tie.quality, opts.qualityLexicon),\n };\n });\n\n const centerLines = wrapTieLabel(input.centerLabel);\n const centerR = Math.max(\n CENTER_MIN_R,\n Math.max(...centerLines.map((l) => estimateTextWidth(l, fontSize))) / 2 + 12,\n (centerLines.length * LINE_H) / 2 + 12,\n );\n\n // ── Ring radii: wide enough that NO two node boxes can ever touch. The safe\n // center-to-center distance is the diagonal of the worst-case box pair: if the\n // euclidean distance is ≥ hypot(width-sum, height-sum), the axis-aligned boxes\n // cannot overlap in both axes at once. Overlap-proof by construction, not by luck.\n const n = sats.length;\n const maxRx = n > 0 ? Math.max(...sats.map((s) => s.rx)) : 0;\n const maxRy = n > 0 ? Math.max(...sats.map((s) => s.ry)) : 0;\n const twoRings = n > SINGLE_RING_MAX;\n const stepAngle = n > 0 ? (Math.PI * 2) / n : Math.PI;\n const safeDist = Math.hypot(2 * maxRx + NODE_GAP, 2 * maxRy + NODE_GAP);\n /** Min radius so two nodes `steps` angular steps apart on the SAME ring clear safeDist. */\n const sameRingRadius = (steps: number): number => {\n const theta = steps * stepAngle;\n if (n <= 1 || theta >= Math.PI) return 0; // ≤2 nodes on the ring: no chord constraint\n return safeDist / (2 * Math.sin(theta / 2));\n };\n const ringStep = maxRy * 2 + RING_GAP;\n let innerR = Math.max(\n RING_MIN_R,\n centerR + RADIAL_GAP + maxRy,\n sameRingRadius(twoRings ? 2 : 1),\n );\n if (twoRings) {\n // Cross-ring neighbors sit 1 step apart at radii r and r+ringStep. Their distance\n // sqrt(r² + (r+s)² − 2r(r+s)cosΔ) grows monotonically with r — widen the inner ring\n // in fixed increments until it clears safeDist (deterministic, always terminates).\n const crossDist = (r: number): number =>\n Math.sqrt(r * r + (r + ringStep) ** 2 - 2 * r * (r + ringStep) * Math.cos(stepAngle));\n while (crossDist(innerR) < safeDist) innerR += 8;\n }\n const outerR = innerR + ringStep;\n\n for (let i = 0; i < n; i++) {\n const s = sats[i]!;\n s.angle = -Math.PI / 2 + (i * Math.PI * 2) / n;\n const r = twoRings && i % 2 === 1 ? outerR : innerR;\n s.x = r * Math.cos(s.angle);\n s.y = r * Math.sin(s.angle);\n }\n\n // ── Canvas bounds (center at origin until here), then shift positive. ───────\n let minX = -centerR;\n let minY = -centerR;\n let maxX = centerR;\n let maxY = centerR;\n for (const s of sats) {\n minX = Math.min(minX, s.x - s.rx);\n minY = Math.min(minY, s.y - s.ry);\n maxX = Math.max(maxX, s.x + s.rx);\n maxY = Math.max(maxY, s.y + s.ry);\n }\n const dx = PADDING - minX;\n const dy = PADDING - minY;\n const cx = dx;\n const cy = dy;\n for (const s of sats) {\n s.x += dx;\n s.y += dy;\n }\n let width = maxX - minX + PADDING * 2;\n let height = maxY - minY + PADDING * 2;\n\n const parts: string[] = [];\n\n // ── Tie lines first (nodes sit on top), one group per declared tie. ─────────\n for (const s of sats) {\n const ux = (cx - s.x) / Math.hypot(cx - s.x, cy - s.y);\n const uy = (cy - s.y) / Math.hypot(cx - s.x, cy - s.y);\n // Node-edge endpoint: ellipse boundary along the unit vector toward the center.\n const scale = 1 / Math.hypot(ux / s.rx, uy / s.ry);\n const x1 = s.x + ux * scale;\n const y1 = s.y + uy * scale;\n // Center-edge endpoint: circle boundary along the same direction.\n const x2 = cx - ux * centerR;\n const y2 = cy - uy * centerR;\n\n const ink = EDGE_STROKE[s.style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n const title = s.tie.title ?? (s.tie.quality !== null ? `${s.tie.label} · ${s.tie.quality}` : s.tie.label);\n const body: string[] = [\n `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n ];\n // Arrowheads ONLY for a declared direction. \"in\" points at the center, \"out\" at\n // the external system, \"both\" draws both. Tips back off the boundary so the\n // triangle never pokes into the shape.\n if (s.tie.direction === \"in\" || s.tie.direction === \"both\") {\n body.push(arrowHead(x2, y2, ux, uy, ink.opacity)); // tip at the center edge\n }\n if (s.tie.direction === \"out\" || s.tie.direction === \"both\") {\n body.push(arrowHead(x1, y1, -ux, -uy, ink.opacity)); // tip at the system edge\n }\n parts.push(`<g data-edge-id=\"${s.tie.id}\"><title>${xmlEscape(title)}</title>${body.join(\"\")}</g>`);\n }\n\n // ── Center node. ─────────────────────────────────────────────────────────────\n {\n const tspans = centerLines\n .map(\n (line, i) =>\n `<tspan x=\"${round(cx)}\" y=\"${round(cy - ((centerLines.length - 1) * LINE_H) / 2 + i * LINE_H + fontSize * 0.32)}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n parts.push(\n `<g data-individual-id=\"center\"><title>${xmlEscape(input.centerLabel)}</title>` +\n `<circle cx=\"${round(cx)}\" cy=\"${round(cy)}\" r=\"${round(centerR)}\" fill=\"transparent\" stroke=\"${NODE_STROKE}\" stroke-width=\"2\"/>` +\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">${tspans}</text></g>`,\n );\n }\n\n // ── Satellite nodes. ─────────────────────────────────────────────────────────\n for (const s of sats) {\n const tspans = s.lines\n .map(\n (line, i) =>\n `<tspan x=\"${round(s.x)}\" y=\"${round(s.y - ((s.lines.length - 1) * LINE_H) / 2 + i * LINE_H + fontSize * 0.32)}\">${xmlEscape(line)}</tspan>`,\n )\n .join(\"\");\n parts.push(\n `<g data-individual-id=\"e${s.tie.id}\"><title>${xmlEscape(s.tie.label)}</title>` +\n `<ellipse cx=\"${round(s.x)}\" cy=\"${round(s.y)}\" rx=\"${round(s.rx)}\" ry=\"${round(s.ry)}\" fill=\"transparent\" stroke=\"${NODE_STROKE}\" stroke-width=\"1.5\"/>` +\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">${tspans}</text></g>`,\n );\n }\n\n // ── Minimal legend: only entries actually used. ──────────────────────────────\n if (opts.legend !== false && sats.length > 0) {\n const entries: { swatch: (x: number, y: number) => string; label: string }[] = [];\n\n if (sats.some((s) => s.style === \"plain\")) {\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${EDGE_STROKE.plain.width}\" stroke-opacity=\"${EDGE_STROKE.plain.opacity}\"/>`,\n label: labels.neutralTie,\n });\n }\n const stylesUsed = new Set(sats.map((s) => s.style));\n for (const style of [\"close\", \"distant\", \"conflict\", \"cutoff\"] as const) {\n if (!stylesUsed.has(style)) continue;\n const ink = EDGE_STROKE[style];\n const dashAttr = ink.dash === null ? \"\" : ` stroke-dasharray=\"${ink.dash[0]} ${ink.dash[1]}\"`;\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"${ink.width}\" stroke-opacity=\"${ink.opacity}\"${dashAttr}/>`,\n label: labels.bondStyles[style],\n });\n }\n if (sats.some((s) => s.tie.direction !== null)) {\n entries.push({\n swatch: (x, y) =>\n `<line x1=\"${x}\" y1=\"${y}\" x2=\"${x + LEGEND_SWATCH_W - 8}\" y2=\"${y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/>` +\n arrowHead(x + LEGEND_SWATCH_W, y, 1, 0, 0.75),\n label: labels.direction,\n });\n }\n\n if (entries.length > 0) {\n const startY = height;\n const rows = entries.map((entry, i) => {\n const rowCenterY = startY + i * LEGEND_ROW_H + LEGEND_ROW_H / 2;\n const textX = LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP;\n return (\n entry.swatch(LEGEND_PAD, rowCenterY) +\n `<text x=\"${textX}\" y=\"${rowCenterY + LEGEND_FONT * 0.32}\" font-family=\"${FONT_FAMILY}\" font-size=\"${LEGEND_FONT}\" fill=\"${NODE_STROKE}\">${xmlEscape(entry.label)}</text>`\n );\n });\n parts.push(`<g data-compasso-legend=\"true\">${rows.join(\"\")}</g>`);\n const widestLabel = entries.reduce((m, e) => Math.max(m, estimateTextWidth(e.label, LEGEND_FONT)), 0);\n width = Math.max(width, LEGEND_PAD + LEGEND_SWATCH_W + LEGEND_GAP + widestLabel + LEGEND_PAD);\n height = startY + entries.length * LEGEND_ROW_H + LEGEND_PAD / 2;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// Fault-tree input model — declared facts only. compasso draws EXACTLY what the\n// caller declares: every event carries its declared kind (the standard symbol is a\n// semantic claim only the author may make), gates are first-class rows with a declared\n// type and a declared left-to-right input order, and the top event is DECLARED, never\n// derived. Symbol lineage: NUREG-0492 (Fault Tree Handbook, US NRC 1981) distinctive\n// shapes, as permitted by IEC 61025:2006 — the rectangular IEC 60617 family is\n// rejected because its gates would be visually indistinguishable from event rectangles.\n\n/**\n * CLOSED event-kind vocabulary (NUREG-0492 Fig. IV-1):\n * - \"intermediate\": fault event from a logic combination → rectangle (incl. the top);\n * - \"basic\": basic initiating fault, no further development → circle;\n * - \"undeveloped\": not developed further (insufficient consequence/info) → diamond;\n * - \"house\": event normally expected to occur (external/boundary) → house;\n * - \"conditioning\": condition/restriction on an INHIBIT gate → oval (never a tree node);\n * - \"transfer\": transfer-in, subtree developed elsewhere → triangle (a leaf).\n */\nexport const FAULT_TREE_EVENT_KINDS = [\n \"intermediate\",\n \"basic\",\n \"undeveloped\",\n \"house\",\n \"conditioning\",\n \"transfer\",\n] as const;\nexport type FaultTreeEventKind = (typeof FAULT_TREE_EVENT_KINDS)[number];\n\n/**\n * A declared fault-tree event. `label` is verbatim (always kept in the <title>);\n * `code` is a short identifier drawn inside primary-event glyphs (null = none) —\n * matching FTA practice, where primary-event symbols carry identifiers and the\n * descriptions live beside them.\n */\nexport interface FaultTreeEvent {\n id: number;\n kind: FaultTreeEventKind;\n label: string;\n code: string | null;\n /** Optional verbatim <title> override (defaults to \"code · label\"). */\n title?: string;\n}\n\n/**\n * CLOSED gate vocabulary. NOT/NAND/NOR and PRIORITY-AND are deliberately\n * unrepresentable — an unsupported gate is a compile error, never a silent visual\n * fallback (the NOT bubble-triangle would also collide with the transfer triangle).\n */\nexport const GATE_TYPES = [\"and\", \"or\", \"xor\", \"inhibit\", \"vote\"] as const;\nexport type GateType = (typeof GATE_TYPES)[number];\n\ninterface FaultTreeGateBase {\n id: number;\n /** The intermediate event this gate resolves (drawn directly above the gate). */\n eventId: number;\n /** Declared left-to-right reading order — presentation data, honored as given. */\n inputIds: number[];\n}\n\nexport interface AndGate extends FaultTreeGateBase {\n type: \"and\";\n}\nexport interface OrGate extends FaultTreeGateBase {\n type: \"or\";\n}\nexport interface XorGate extends FaultTreeGateBase {\n type: \"xor\";\n}\nexport interface InhibitGate extends FaultTreeGateBase {\n type: \"inhibit\";\n /** Must reference a kind:\"conditioning\" event (drawn as the side oval). */\n conditionId: number;\n}\nexport interface VoteGate extends FaultTreeGateBase {\n type: \"vote\";\n /** Output occurs if ≥ k of the n inputs occur; 1 ≤ k ≤ inputIds.length. */\n k: number;\n}\nexport type FaultTreeGate = AndGate | OrGate | XorGate | InhibitGate | VoteGate;\n\n/** Input to the fault-tree render pipeline. */\nexport interface FaultTreeInput {\n /** Declared top event (must be kind \"intermediate\", never a gate input). */\n topId: number;\n events: FaultTreeEvent[];\n gates: FaultTreeGate[];\n}\n","// Display vocabularies — every human-readable string the fault tree emits, gathered\n// in overridable packs so the diagram localizes without touching the engine. English\n// defaults here; `compasso/locales/pt-br` ships a Brazilian Portuguese pack.\n//\n// Gate titles carry the standard gate NAME only (a vote title appends its declared\n// \"k/n\") — the gate's semantics belong to the standard's text, not the SVG.\n\nimport type { FaultTreeEventKind, GateType } from \"./types\";\n\n/** Labels woven into element <title>s by the LAYOUT (verbatim-preserving). */\nexport interface FaultTreeTitleLabels {\n gates: Record<GateType, string>;\n /** Title of the inhibit-gate → conditioning-oval attachment line. */\n condition: string;\n}\n\nexport const FAULT_TREE_TITLE_LABELS_EN: FaultTreeTitleLabels = {\n gates: {\n and: \"AND gate\",\n or: \"OR gate\",\n xor: \"Exclusive-OR gate\",\n inhibit: \"Inhibit gate\",\n vote: \"Voting gate\",\n },\n condition: \"condition\",\n};\n\n/** Labels drawn by the SVG EMITTER (legend entries, accessibility text). */\nexport interface FaultTreeSvgLabels {\n events: Record<FaultTreeEventKind, string>;\n gates: Record<GateType, string>;\n ariaLabel: string;\n}\n\nexport const FAULT_TREE_SVG_LABELS_EN: FaultTreeSvgLabels = {\n events: {\n intermediate: \"Intermediate event\",\n basic: \"Basic event\",\n undeveloped: \"Undeveloped event\",\n house: \"External event (normally occurs)\",\n conditioning: \"Conditioning event\",\n transfer: \"Transfer (developed elsewhere)\",\n },\n gates: {\n and: \"AND gate (all inputs)\",\n or: \"OR gate (any input)\",\n xor: \"Exclusive-OR gate (exactly one input)\",\n inhibit: \"INHIBIT gate (input under condition)\",\n vote: \"Voting gate (k of n)\",\n },\n ariaLabel: \"Fault tree\",\n};\n","// Fault-tree validation — REJECT, never repair. The genogram silently filters\n// dangling references because a family map is elicited incrementally; a fault tree is\n// a safety artifact whose meaning lives in its logic structure, so drawing a\n// structurally invalid tree (or silently altering its logic) is worse than refusing.\n// The standard itself has a notation for \"honestly incomplete\" — the diamond\n// (undeveloped event) and the transfer triangle — and the error messages point there.\n//\n// Every problem is reported, not just the first: issues are aggregated, deduplicated\n// and sorted deterministically (by code, then message), each carrying a STABLE\n// kebab-case machine-readable `code`. Validation runs in THREE phases, each gated on\n// the previous being clean ENOUGH for the next to be meaningful — not on \"zero issues\n// so far\", so a defect in one phase never silently hides an honest issue from a later\n// one (the throw must carry ALL real issues, not just the first phase's):\n// (0) duplicate ids. The lookup maps are first-occurrence-wins, so EVERY reference\n// rule below would validate whichever duplicate row was declared first — making\n// the issue list depend on array order, violating this function's documented\n// order-invariance. When any duplicate-id issue exists we report ONLY those and\n// stop (the duplicate already forces a throw, present in every permutation).\n// (1) reference / semantic rules (R2–R7, R10–R14): top, per-gate references, arity,\n// vote threshold, gate ownership. Always evaluated once ids are unambiguous.\n// (2) graph rules (R8 reachability, R9 cycles) — gated ONLY on the reference-INTEGRITY\n// subset that genuinely makes traversal meaningless, NOT on every phase-1 issue.\n// The traversal walks `gateOf(eventId)` → gate.inputIds (+ inhibit conditionId)\n// seeded at topId, so it is corrupted by: duplicate-id (ambiguous first-wins\n// node), unknown-input (walks a phantom node), gate-on-non-intermediate /\n// transfer-with-gate (attaches a gate to a leaf, fabricating descent),\n// event-with-two-gates (gateOf's first-match silently picks one), inhibit-\n// condition (a non-conditioning conditionId is queued as a phantom node), and\n// top-not-intermediate (the BFS frontier is rooted at a non-node). Defects that\n// do NOT impair traversal — vote-threshold, gate-arity (k/arity are never read),\n// top-as-input, conditioning-as-input, event-without-gate, intermediate-reused\n// (all reference real, walkable nodes) — do NOT suppress the graph phase, so e.g.\n// a bad vote k alongside an unreachable event reports BOTH in one throw.\n//\n// Tolerated, by design (drawn as declared, never converted):\n// - repeated LEAF events (basic/undeveloped/house/transfer) in several gates' inputs\n// — that IS the standard repeated-event notation (drawn once per reference; hooks\n// are disambiguated with data-instance, see ./layout.ts);\n// - a conditioning event attached to more than one inhibit gate (one oval per gate);\n// - vote gates with k=1 or k=n (logically OR/AND — converting would be interpretation);\n// - empty labels (drawn empty; the <title> is still present).\n\nimport type { FaultTreeEvent, FaultTreeGate, FaultTreeInput } from \"./types\";\n\n/** Stable machine-readable issue codes (kebab-case; part of the public contract). */\nexport type FaultTreeIssueCode =\n | \"duplicate-id\"\n | \"top-not-intermediate\"\n | \"top-as-input\"\n | \"gate-on-non-intermediate\"\n | \"transfer-with-gate\"\n | \"event-with-two-gates\"\n | \"event-without-gate\"\n | \"intermediate-reused\"\n | \"unknown-input\"\n | \"conditioning-as-input\"\n | \"inhibit-condition\"\n | \"gate-arity\"\n | \"vote-threshold\"\n | \"unreachable-event\"\n | \"cycle\";\n\nexport interface FaultTreeIssue {\n code: FaultTreeIssueCode;\n message: string;\n}\n\n/** Thrown by computeFaultTreeLayout / faultTreeSvg on a structurally invalid tree. */\nexport class FaultTreeValidationError extends Error {\n readonly issues: readonly FaultTreeIssue[];\n\n constructor(issues: readonly FaultTreeIssue[]) {\n super(`invalid fault tree: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"FaultTreeValidationError\";\n this.issues = issues;\n }\n}\n\n/** \"1 and 3\" / \"1, 2 and 3\" — deterministic listing for issue messages. */\nfunction listIds(ids: readonly number[]): string {\n if (ids.length === 1) return String(ids[0]);\n return `${ids.slice(0, -1).join(\", \")} and ${ids[ids.length - 1]}`;\n}\n\n/**\n * Deduplicate + deterministic order: by code, then message (byte comparison — stable\n * across engines; no locale-dependent collation). Shared by every phase that returns.\n */\nfunction sortIssues(issues: readonly FaultTreeIssue[]): readonly FaultTreeIssue[] {\n const unique = new Map<string, FaultTreeIssue>();\n for (const issue of issues) unique.set(`${issue.code} ${issue.message}`, issue);\n return [...unique.values()].sort((a, b) =>\n a.code !== b.code ? (a.code < b.code ? -1 : 1) : a.message < b.message ? -1 : a.message > b.message ? 1 : 0,\n );\n}\n\n/**\n * Computes ALL validation issues for the input, deduplicated and deterministically\n * sorted (code, then message) — array order of `events`/`gates` never changes the\n * result. Empty input (no events AND no gates) is valid by definition (the renderer's\n * empty-but-valid SVG case) and reports no issues.\n */\nexport function faultTreeIssues(input: FaultTreeInput): readonly FaultTreeIssue[] {\n if (input.events.length === 0 && input.gates.length === 0) return [];\n\n const issues: FaultTreeIssue[] = [];\n const push = (code: FaultTreeIssueCode, message: string): void => {\n issues.push({ code, message });\n };\n\n // ── R1: duplicate ids (per namespace — hooks must be unique). Any duplicate makes\n // the structure ambiguous, so this is phase 0 and short-circuits the rest (below). ─\n const eventById = new Map<number, FaultTreeEvent>();\n const dupEventIds = new Set<number>();\n for (const e of input.events) {\n if (eventById.has(e.id)) dupEventIds.add(e.id);\n else eventById.set(e.id, e);\n }\n for (const id of [...dupEventIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate event id ${id}`);\n }\n const gateById = new Map<number, FaultTreeGate>();\n const dupGateIds = new Set<number>();\n for (const g of input.gates) {\n if (gateById.has(g.id)) dupGateIds.add(g.id);\n else gateById.set(g.id, g);\n }\n for (const id of [...dupGateIds].sort((a, b) => a - b)) {\n push(\"duplicate-id\", `duplicate gate id ${id}`);\n }\n\n // ── Phase 0: duplicate ids short-circuit everything else. The lookup maps below are\n // first-occurrence-wins, so every downstream reference rule would validate whichever\n // duplicate row happened to be declared first — making the issue list depend on the\n // `events`/`gates` ARRAY ORDER, in direct violation of this function's documented\n // order-invariance. Rules evaluated over an ambiguous first-wins structure are as\n // meaningless as the graph rules over dangling references, so we report ONLY the\n // duplicate-id issues and stop (the structural defect already forces a throw). This\n // extends the existing phase doctrine one level up: duplicate ids → reference rules →\n // graph rules, each phase gated on the prior being clean enough to be meaningful. ──\n if (issues.length > 0) {\n return sortIssues(issues);\n }\n\n const gates = [...gateById.values()].sort((a, b) => a.id - b.id);\n\n // ── R2: the declared top must be an existing intermediate event. ─────────────────\n const top = eventById.get(input.topId);\n if (top === undefined || top.kind !== \"intermediate\") {\n push(\"top-not-intermediate\", `topId ${input.topId} is not an intermediate event`);\n }\n\n // ── Per-gate reference/arity rules (R3, R4, R10–R14). ───────────────────────────\n const conditioningAsInput = new Set<number>();\n for (const g of gates) {\n const out = eventById.get(g.eventId);\n if (out !== undefined && out.kind === \"transfer\") {\n // R13 — transfer-in marks \"developed elsewhere\": a leaf by definition.\n push(\"transfer-with-gate\", `transfer event ${g.eventId} cannot have a gate`);\n } else if (out === undefined || out.kind !== \"intermediate\") {\n // R4 — only rectangles are developed through a gate.\n push(\"gate-on-non-intermediate\", `gate ${g.id} resolves non-intermediate event ${g.eventId}`);\n }\n\n // R10 — a gate IS a logic combination; INHIBIT is single-input-plus-condition.\n if (g.type === \"inhibit\") {\n if (g.inputIds.length !== 1) push(\"gate-arity\", `inhibit gate ${g.id} needs exactly 1 input`);\n } else if (g.inputIds.length < 2) {\n push(\"gate-arity\", `${g.type} gate ${g.id} needs ≥2 inputs`);\n }\n\n // R12 — a voting threshold outside the integers 1..n is meaningless. Number.isInteger\n // also rejects NaN/±Infinity and fractional k (k is a plain `number`, so JSON can\n // carry those) — drawing \"NaN/2\" or \"1.5/2\" would repair a meaningless threshold by\n // rendering it, which the reject-never-repair doctrine forbids.\n if (g.type === \"vote\" && (!Number.isInteger(g.k) || g.k < 1 || g.k > g.inputIds.length)) {\n push(\"vote-threshold\", `vote gate ${g.id}: k=${g.k} of ${g.inputIds.length}`);\n }\n\n // R11a — the oval attaches to a gate; inhibit must reference a conditioning event.\n if (g.type === \"inhibit\") {\n const cond = eventById.get(g.conditionId);\n if (cond === undefined || cond.kind !== \"conditioning\") {\n push(\"inhibit-condition\", `inhibit gate ${g.id} conditionId ${g.conditionId} is not a conditioning event`);\n }\n }\n\n for (const inputId of g.inputIds) {\n const child = eventById.get(inputId);\n if (child === undefined) {\n // Dangling input — silently dropping it would alter the declared logic.\n push(\"unknown-input\", `gate ${g.id} input ${inputId} is not a declared event`);\n continue;\n }\n // R3 — the top is the tree apex, never an input.\n if (inputId === input.topId) push(\"top-as-input\", `top event ${input.topId} is used as a gate input`);\n // R11b — a conditioning event is never a tree node (NUREG-0492: it restricts a gate).\n if (child.kind === \"conditioning\") conditioningAsInput.add(inputId);\n }\n }\n for (const id of [...conditioningAsInput].sort((a, b) => a - b)) {\n push(\"conditioning-as-input\", `conditioning event ${id} used as a gate input`);\n }\n\n // ── R5/R6: exactly one gate per intermediate event. ─────────────────────────────\n const gatesByEvent = new Map<number, number[]>();\n for (const g of gates) {\n const arr = gatesByEvent.get(g.eventId) ?? [];\n arr.push(g.id);\n gatesByEvent.set(g.eventId, arr);\n }\n for (const [eventId, gateIds] of [...gatesByEvent.entries()].sort((a, b) => a[0] - b[0])) {\n if (gateIds.length > 1) {\n push(\"event-with-two-gates\", `event ${eventId} is resolved by gates ${listIds(gateIds.sort((a, b) => a - b))}`);\n }\n }\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if (e.kind === \"intermediate\" && !gatesByEvent.has(e.id)) {\n // R6 — a rectangle without a gate falsely claims development; the diamond\n // (undeveloped) is the standard's own symbol for \"not developed further\".\n push(\"event-without-gate\", `intermediate event ${e.id} has no gate — declare it kind \"undeveloped\" instead`);\n }\n }\n\n // ── R7: an intermediate may feed only ONE gate input — duplicating whole subtrees\n // silently is synthesis; the standard's answer is the transfer triangle. ───────\n const intermediateRefs = new Map<number, number[]>(); // event id → referencing gate ids\n for (const g of gates) {\n for (const inputId of g.inputIds) {\n if (eventById.get(inputId)?.kind !== \"intermediate\") continue;\n const arr = intermediateRefs.get(inputId) ?? [];\n arr.push(g.id);\n intermediateRefs.set(inputId, arr);\n }\n }\n for (const [eventId, gateIds] of [...intermediateRefs.entries()].sort((a, b) => a[0] - b[0])) {\n if (gateIds.length > 1) {\n push(\n \"intermediate-reused\",\n `intermediate event ${eventId} feeds gates ${listIds(gateIds.sort((a, b) => a - b))} — repeat it via a \"transfer\" event`,\n );\n }\n }\n\n // ── Graph rules (R8 reachability, R9 cycles) — phase 2. Gated ONLY on the reference-\n // INTEGRITY codes that corrupt the traversal itself (see the module header for the\n // per-code justification), NOT on every phase-1 issue: a meaningless vote k or wrong\n // arity leaves the graph fully walkable, so suppressing R8/R9 for them would hide an\n // honest issue and break the \"throw with ALL issues\" doctrine. ─────────────────────\n const GRAPH_BLOCKING: ReadonlySet<FaultTreeIssueCode> = new Set([\n \"duplicate-id\",\n \"unknown-input\",\n \"gate-on-non-intermediate\",\n \"transfer-with-gate\",\n \"event-with-two-gates\",\n \"inhibit-condition\",\n \"top-not-intermediate\",\n ]);\n if (!issues.some((i) => GRAPH_BLOCKING.has(i.code))) {\n const gateOf = (eventId: number): FaultTreeGate | undefined => gates.find((g) => g.eventId === eventId);\n\n // R8 — every declared event must be reachable from the top (silently dropping\n // declared data violates honesty). Conditioning events reach through their gate.\n const reachable = new Set<number>();\n const queue: number[] = [input.topId];\n while (queue.length > 0) {\n const id = queue.shift()!;\n if (reachable.has(id)) continue;\n reachable.add(id);\n const g = gateOf(id);\n if (g === undefined) continue;\n queue.push(...g.inputIds);\n if (g.type === \"inhibit\") queue.push(g.conditionId);\n }\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if (!reachable.has(e.id)) push(\"unreachable-event\", `event ${e.id} is declared but unreachable from the top`);\n }\n\n // R9 — cycle detection over the whole event graph (event → its gate's inputs).\n // Iterative coloring DFS, start nodes ascending, children in declared order; each\n // distinct cycle is reported once, rotated to start at its smallest event id so\n // the message is identical for any array order of the same input.\n const color = new Map<number, 0 | 1 | 2>(); // 0/absent=white, 1=gray, 2=black\n const seenCycles = new Set<string>();\n const dfs = (start: number): void => {\n const stack: { id: number; nextChild: number }[] = [{ id: start, nextChild: 0 }];\n color.set(start, 1);\n while (stack.length > 0) {\n const frame = stack[stack.length - 1]!;\n const children = gateOf(frame.id)?.inputIds ?? [];\n if (frame.nextChild >= children.length) {\n color.set(frame.id, 2);\n stack.pop();\n continue;\n }\n const child = children[frame.nextChild]!;\n frame.nextChild += 1;\n const c = color.get(child) ?? 0;\n if (c === 1) {\n // Back edge: the cycle is the stack slice from `child` down to the current frame.\n const from = stack.findIndex((f) => f.id === child);\n const cycle = stack.slice(from).map((f) => f.id);\n const minIdx = cycle.indexOf(Math.min(...cycle));\n const rotated = [...cycle.slice(minIdx), ...cycle.slice(0, minIdx)];\n const key = rotated.join(\">\");\n if (!seenCycles.has(key)) {\n seenCycles.add(key);\n push(\"cycle\", `cycle: ${[...rotated, rotated[0]!].join(\" → \")}`);\n }\n } else if (c === 0) {\n color.set(child, 1);\n stack.push({ id: child, nextChild: 0 });\n }\n }\n };\n for (const e of [...eventById.values()].sort((a, b) => a.id - b.id)) {\n if ((color.get(e.id) ?? 0) === 0) dfs(e.id);\n }\n }\n\n return sortIssues(issues);\n}\n\n/** Throws FaultTreeValidationError (carrying ALL issues) when the input is invalid. */\nexport function validateFaultTree(input: FaultTreeInput): void {\n const issues = faultTreeIssues(input);\n if (issues.length > 0) throw new FaultTreeValidationError(issues);\n}\n","// PURE fault-tree layout — the single source of truth for positioning and connector\n// routing. The emitter (./svg.ts) draws EXACTLY what this computes, so any number of\n// surfaces (web, PDF, image pipelines) can never drift from each other.\n//\n// It is deliberately PURE — no DOM, no Node APIs, no clock, no randomness — so the\n// same input always yields the same layout, byte for byte.\n//\n// HONESTY RULE: this module only POSITIONS what the caller declared. Validation\n// (./validate.ts) THROWS on a structurally invalid tree instead of repairing it —\n// a fault tree is a safety artifact and silently altering its logic is synthesis.\n// Tolerated repetition is the standard's own notation: a repeated LEAF event\n// (basic/undeveloped/house/transfer in several gates' inputs) is drawn once per\n// reference, exactly as hand-drawn FTA repeats the same circle at each site; hooks\n// are disambiguated with a 0-based `instance` index in deterministic DFS pre-order\n// (event, then inhibit condition, then inputs in declared order). This is also the\n// forward answer for DAG-shaped trees: model the shared subtree as a `transfer` leaf.\n//\n// LAYOUT — top-down levels, exactly as every NUREG-0492 / IEC 61025 figure draws it:\n// event rectangle, short stem, gate beneath, orthogonal connector rake to children.\n// Horizontal placement is NAIVE SUBTREE-SPAN PACKING (not Reingold–Tilford contours):\n// every node carries asymmetric half-extents {spanL, spanR} covering its ENTIRE\n// subtree drawing (glyphs, labels, gate, conditioning oval, its own buses); siblings\n// are placed with disjoint intervals H_GAP apart, and the recursion makes the\n// guarantee global — a 5-line inductive overlap proof, re-verified by the test\n// harness, at the cost of some width on unbalanced trees. Label widths reserve real\n// space because nodeW comes from estimateTextWidth over the wrapped lines and the\n// emitter draws with the same core metrics: what is proven is what is drawn.\n//\n// GATE-CLEARANCE INVARIANT (directly asserted in test/fault-tree/layout.test.ts):\n// every gate glyph bottom at depth d sits strictly ABOVE the child bus y, because\n// rowTop(d+1) = rowTop(d) + rowH(d) + gateZone(d) + CORRIDOR reserves the full gate\n// zone and busY = rowTop(d+1) − CORRIDOR/2 leaves CORRIDOR/2 of air below it.\n\nimport { CHAR_W, clampLabel, estimateTextWidth, wrapLabel, wrapLabelBalanced, type Point } from \"../core\";\nimport { FAULT_TREE_TITLE_LABELS_EN, type FaultTreeTitleLabels } from \"./labels\";\nimport { validateFaultTree } from \"./validate\";\nimport type { FaultTreeEvent, FaultTreeEventKind, FaultTreeGate, FaultTreeInput, GateType } from \"./types\";\n\nexport { FaultTreeValidationError, faultTreeIssues, validateFaultTree, type FaultTreeIssue, type FaultTreeIssueCode } from \"./validate\";\n// Re-exported so the overlap harness (and decorating callers) measure with the EXACT\n// metrics the layout reserved space with — the shared-metrics contract.\nexport { estimateTextWidth };\nexport type { Point };\n\n// ── Type metrics (shared by layout AND the emitter, so geometry == render) ──────\n/** Node label font size (px). */\nexport const FT_LABEL_FONT = 12;\n/** Line height for stacked label lines (px). */\nexport const FT_LABEL_LINE_H = 14;\n/** Short-code font size (px) — drawn inside primary-event glyphs. */\nexport const CODE_FONT = 10;\n/** Gap from a leaf glyph's bottom to the top of its first label line. */\nexport const LABEL_GAP = 6;\n\n// ── Geometry constants ───────────────────────────────────────────────────────────\nconst PADDING = 32;\n/** Min horizontal air between two sibling subtree intervals. */\nconst H_GAP = 28;\n/** Vertical band between a row's gate zone and the next row (the bus lives mid-way). */\nconst CORRIDOR = 30;\n/** Vertical stem from an event's bottom edge to its gate's top. */\nconst STEM = 10;\n/** Horizontal gap between an inhibit gate's right vertex and its conditioning node. */\nconst COND_GAP = 14;\n\n// Gate glyph boxes (NUREG-0492 distinctive shapes, drawn pointing up).\nconst GATE_W = 44;\nconst GATE_H = 36;\n/** XOR = the OR shape + a detached concave arc 5px below the base (ANSI/IEEE 91). */\nconst XOR_H = GATE_H + 5;\nconst INHIBIT_W = 36;\nconst INHIBIT_H = 46;\n/** Y of the inhibit hexagon's side-vertex midpoint (the condition line's anchor). */\nconst INHIBIT_CY = 23;\n\n// ── Namespaced element ids (one element kind per numeric block, extending the\n// genogram convention) — every data-edge-id stays traceable to its source row. ──\nexport const FT_STEM_ID_BASE = 1_000_000; // + gate id\nexport const FT_DROP_ID_BASE = 2_000_000; // + gate id\nexport const FT_BUS_ID_BASE = 3_000_000; // + gate id\nexport const FT_RISER_ID_BASE = 4_000_000; // + child event id\nexport const FT_CONDITION_ID_BASE = 5_000_000; // + gate id\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n// ── Positioned layout ─────────────────────────────────────────────────────────────\n\nexport interface FaultTreeNode {\n eventId: number;\n kind: FaultTreeEventKind;\n /** 0-based DFS pre-order instance index; null when the event is drawn once. */\n instance: number | null;\n /** Glyph center x. */\n cx: number;\n /** Glyph top y (leaf labels hang below the glyph; the rect IS the glyph). */\n top: number;\n /** Full node box (glyph + label block) — the packing reserved exactly this. */\n nodeW: number;\n nodeH: number;\n glyphW: number;\n glyphH: number;\n /** Wrapped display lines — inside the rect (intermediate) or below the glyph. */\n labelLines: string[];\n /** Top of the first label line's box; null when the label sits inside the rect. */\n labelTop: number | null;\n /** Clamped display code drawn inside a non-rect glyph; null = none. */\n code: string | null;\n /** Depth of the row this node lives in (a conditioning node: its gate's row). */\n depth: number;\n /** Verbatim <title> text (event.title ?? \"code · label\" ?? label). */\n title: string;\n}\n\nexport interface FaultTreeGateNode {\n gateId: number;\n type: GateType;\n cx: number;\n /** Glyph top y (all gates of a row are top-aligned at rowBottom + STEM). */\n top: number;\n glyphW: number;\n /** Full glyph height incl. the XOR's detached arc — top + glyphH = connector bottom. */\n glyphH: number;\n /** Localized gate name (vote: name + \" k/n\"). */\n title: string;\n /** \"k/n\" drawn inside a vote gate; null otherwise. */\n voteText: string | null;\n}\n\nexport type FaultTreeElementKind = \"stem\" | \"drop\" | \"bus\" | \"riser\" | \"condition\";\n\nexport interface FaultTreeElement {\n /** Namespaced id (FT_*_ID_BASE + gate id / child event id). */\n edgeId: number;\n kind: FaultTreeElementKind;\n /** Two waypoints, always axis-aligned (H or V). */\n points: Point[];\n /** Riser into a repeated-leaf instance: that instance index; else null. */\n instance: number | null;\n /** Localized gate name (condition elements: titleLabels.condition). */\n title: string;\n}\n\nexport interface FaultTreeLayout {\n width: number;\n height: number;\n /** DFS pre-order (event, condition, inputs) — repeated leaves appear per instance. */\n nodes: FaultTreeNode[];\n gates: FaultTreeGateNode[];\n elements: FaultTreeElement[];\n}\n\nexport interface FaultTreeLayoutOptions {\n /** Cap each node's DISPLAY label (compact preview); verbatim text stays in `title`. */\n maxLabelChars?: number;\n /** Locale pack for gate/condition <title>s — English default; see locale packs. */\n titleLabels?: FaultTreeTitleLabels;\n}\n\n// ── Measurement ───────────────────────────────────────────────────────────────────\n\ninterface Measured {\n nodeW: number;\n nodeH: number;\n glyphW: number;\n glyphH: number;\n labelLines: string[];\n code: string | null;\n}\n\n/** Leaf-label wrap: tighter budget than the rect's (glyphs don't grow with text). */\nfunction wrapLeafLabel(displayLabel: string): string[] {\n const perLine = Math.min(20, Math.max(12, Math.ceil(displayLabel.length / 2) + 2));\n return wrapLabel(displayLabel, perLine);\n}\n\n// ── Per-glyph code-char clamp — guarantees the code sits INSIDE its fixed-size\n// glyph (the design doc's \"code drawn inside the glyph\" claim), DERIVED from THIS\n// module's own metrics rather than eyeballed. Only the conditioning OVAL is\n// excluded: it GROWS to the measured code width (`rx = max(30, codeW/2 + 8)`), so\n// it never clamps — see measureEvent. The full verbatim code always survives in\n// the <title> (eventTitle), so clamping is presentation-only, never data loss.\n//\n// Geometry. The emitter (svg.ts) draws the code centered at `cx`, `text-anchor\n// \"middle\"`, its baseline (the literal `<text y>`, i.e. the code's ACTUAL drawn\n// y-position) at `top + glyphH/2 + CODE_FONT*0.32`. N chars span ±estimateTextWidth\n// (N)/2 = ±(N·CODE_FONT·CHAR_W)/2 about cx. The clamp keeps that half-span inside\n// the glyph's half-width AT THAT BASELINE Y (`codeBaselineHalfWidth` below), with a\n// couple px margin AND real-font headroom: real Helvetica caps run wider than the\n// deliberately-light CHAR_W=0.6 estimate at these small extremes (the review\n// measured ~20.3px real vs 18px estimated for a 6-char code, ≈1.13×), so we reserve\n// CODE_REAL_HEADROOM on top of the estimate. Solving for the largest integer N in\n// N·(CODE_FONT·CHAR_W·CODE_REAL_HEADROOM)/2 + CODE_MARGIN ≤ half(baseline)\n// yields (recomputed by maxCodeChars, not hand-copied): basic 5, undeveloped 5,\n// house 5, transfer 3 — the apex-up triangle is narrowest at the code's height.\nconst CODE_REAL_HEADROOM = 1.15;\nconst CODE_MARGIN = 2;\n\n/** Glyph half-width at vertical offset `y` below the glyph top, per non-rect kind. */\nfunction codeGlyphHalfAt(kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">, y: number): number {\n if (kind === \"basic\") {\n // circle r 22, center at top+22\n const dy = y - 22;\n return Math.sqrt(Math.max(0, 22 * 22 - dy * dy));\n }\n if (kind === \"undeveloped\") {\n // diamond half 24, center at top+24, linear taper to the apex/bottom\n return 24 * Math.max(0, 1 - Math.abs(y - 24) / 24);\n }\n if (kind === \"house\") {\n // walls ±22 below the eave (top+16); roof tapers linearly above it to the apex\n return y >= 16 ? 22 : (22 * y) / 16;\n }\n // transfer — apex-up triangle, base ±22 at top+35; half grows linearly from the apex\n return (22 * Math.max(0, Math.min(35, y))) / 35;\n}\n\n/** Glyph half-width at the code text's baseline (its actual drawn `<text y>`). */\nfunction codeBaselineHalfWidth(\n kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">,\n glyphH: number,\n): number {\n return codeGlyphHalfAt(kind, glyphH / 2 + CODE_FONT * 0.32);\n}\n\n/** Largest code length that, drawn, stays inside the glyph (estimator + headroom + margin). */\nexport function maxCodeChars(\n kind: Exclude<FaultTreeEventKind, \"intermediate\" | \"conditioning\">,\n glyphH: number,\n): number {\n const half = codeBaselineHalfWidth(kind, glyphH);\n const perChar = (CODE_FONT * CHAR_W * CODE_REAL_HEADROOM) / 2; // half-advance with headroom\n return Math.max(1, Math.floor((half - CODE_MARGIN) / perChar));\n}\n\nfunction measureEvent(event: FaultTreeEvent, maxLabelChars: number | undefined): Measured {\n if (event.kind === \"intermediate\") {\n // The rectangle IS a text panel (the standard writes the description inside it).\n const lines = event.label === \"\" ? [] : wrapLabelBalanced(clampLabel(event.label, maxLabelChars), 3);\n const maxLineW = lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, FT_LABEL_FONT)), 0);\n const w = Math.max(96, maxLineW + 24);\n const h = lines.length * FT_LABEL_LINE_H + 18;\n return { nodeW: w, nodeH: h, glyphW: w, glyphH: h, labelLines: lines, code: null };\n }\n const rawCode = event.code === null || event.code === \"\" ? null : event.code;\n const lines = event.label === \"\" ? [] : wrapLeafLabel(clampLabel(event.label, maxLabelChars));\n const labelW = lines.reduce((m, l) => Math.max(m, estimateTextWidth(l, FT_LABEL_FONT)), 0);\n let glyphW: number;\n let glyphH: number;\n // Fixed-size glyphs clamp the code to what their outline can hold (CODE_MAX_CHARS,\n // derived above); the conditioning OVAL instead grows to the measured code width.\n let code = rawCode;\n if (event.kind === \"basic\") {\n glyphW = 44; // circle r 22\n glyphH = 44;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"basic\", glyphH));\n } else if (event.kind === \"undeveloped\") {\n glyphW = 48; // rotated square, half 24\n glyphH = 48;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"undeveloped\", glyphH));\n } else if (event.kind === \"house\") {\n glyphW = 44; // pentagon: 24px walls + 16px roof\n glyphH = 40;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"house\", glyphH));\n } else if (event.kind === \"conditioning\") {\n // The oval reserves the FULL (only globally-capped) code width — no glyph clamp.\n code = rawCode === null ? null : clampLabel(rawCode, 6);\n const rx = Math.max(30, estimateTextWidth(code ?? \"\", CODE_FONT) / 2 + 8);\n glyphW = rx * 2;\n glyphH = 32; // ellipse ry 16\n } else {\n glyphW = 44; // transfer triangle, apex up\n glyphH = 35;\n code = rawCode === null ? null : clampLabel(rawCode, maxCodeChars(\"transfer\", glyphH));\n }\n const nodeW = Math.max(glyphW, labelW);\n const nodeH = glyphH + (lines.length > 0 ? LABEL_GAP + lines.length * FT_LABEL_LINE_H : 0);\n return { nodeW, nodeH, glyphW, glyphH, labelLines: lines, code };\n}\n\nfunction eventTitle(event: FaultTreeEvent): string {\n if (event.title !== undefined) return event.title;\n return event.code !== null && event.code !== \"\" ? `${event.code} · ${event.label}` : event.label;\n}\n\n// ── Internal working tree (one node per drawn INSTANCE) ───────────────────────────\n\ninterface Inst {\n event: FaultTreeEvent;\n gate: FaultTreeGate | null;\n children: Inst[];\n /** Conditioning instance attached to an inhibit gate; positioned in the gate zone. */\n cond: Inst | null;\n depth: number;\n m: Measured;\n title: string;\n /** Per-event-id DFS pre-order sequence (becomes `instance` when the event repeats). */\n seq: number;\n // Subtree half-extents (cover the ENTIRE subtree drawing) and resolved positions.\n spanL: number;\n spanR: number;\n /** Center offset relative to the parent's center (root: unused). */\n offset: number;\n cx: number;\n}\n\n/**\n * Deterministic, overlap-proof fault-tree layout (pure function of the inputs).\n * Validates first and THROWS FaultTreeValidationError on a structurally invalid\n * tree — never sanitizes. Empty input (no events, no gates) yields an empty,\n * padded layout; `topId` is ignored in that one case.\n */\nexport function computeFaultTreeLayout(\n input: FaultTreeInput,\n opts: FaultTreeLayoutOptions = {},\n): FaultTreeLayout {\n if (input.events.length === 0 && input.gates.length === 0) {\n return { width: PADDING * 2, height: PADDING * 2, nodes: [], gates: [], elements: [] };\n }\n validateFaultTree(input);\n\n const titleLabels = opts.titleLabels ?? FAULT_TREE_TITLE_LABELS_EN;\n const eventById = new Map(input.events.map((e) => [e.id, e]));\n const gateByEvent = new Map(input.gates.map((g) => [g.eventId, g]));\n\n // ── Build the instance tree by DFS from the top (event → condition → inputs in\n // declared order). Validation guarantees: intermediates form a tree, leaves may\n // repeat, conditioning events never have gates or children. ───────────────────\n const allInsts: Inst[] = [];\n const seqByEvent = new Map<number, number>();\n const newInst = (event: FaultTreeEvent, gate: FaultTreeGate | null, depth: number): Inst => {\n const seq = seqByEvent.get(event.id) ?? 0;\n seqByEvent.set(event.id, seq + 1);\n const inst: Inst = {\n event,\n gate,\n children: [],\n cond: null,\n depth,\n m: measureEvent(event, opts.maxLabelChars),\n title: eventTitle(event),\n seq,\n spanL: 0,\n spanR: 0,\n offset: 0,\n cx: 0,\n };\n allInsts.push(inst);\n return inst;\n };\n const build = (eventId: number, depth: number): Inst => {\n const event = eventById.get(eventId)!;\n const gate = gateByEvent.get(eventId) ?? null;\n const inst = newInst(event, gate, depth);\n if (gate !== null) {\n if (gate.type === \"inhibit\") {\n inst.cond = newInst(eventById.get(gate.conditionId)!, null, depth);\n }\n for (const childId of gate.inputIds) inst.children.push(build(childId, depth + 1));\n }\n return inst;\n };\n const root = build(input.topId, 0);\n\n // ── Horizontal: subtree-span packing (post-order). The conditioning oval reserves\n // REAL width on the right of an inhibit-developed node — never overlaps a sibling.\n const pack = (inst: Inst): void => {\n for (const c of inst.children) pack(c);\n const condW = inst.cond !== null ? COND_GAP + inst.cond.m.nodeW : 0;\n const selfL = inst.m.nodeW / 2;\n const selfR = inst.m.nodeW / 2 + condW;\n if (inst.children.length === 0) {\n inst.spanL = selfL;\n inst.spanR = selfR;\n return;\n }\n const xs: number[] = [0];\n for (let i = 1; i < inst.children.length; i++) {\n xs.push(xs[i - 1]! + inst.children[i - 1]!.spanR + H_GAP + inst.children[i]!.spanL);\n }\n const first = inst.children[0]!;\n const last = inst.children[inst.children.length - 1]!;\n const px = (xs[0]! + xs[xs.length - 1]!) / 2;\n inst.children.forEach((c, i) => (c.offset = xs[i]! - px));\n inst.spanL = Math.max(selfL, px - (xs[0]! - first.spanL));\n inst.spanR = Math.max(selfR, xs[xs.length - 1]! + last.spanR - px);\n };\n pack(root);\n\n // Absolute centers, top-down; the root's left extent sits at PADDING.\n root.cx = PADDING + root.spanL;\n const placeX = (inst: Inst): void => {\n for (const c of inst.children) {\n c.cx = inst.cx + c.offset;\n placeX(c);\n }\n };\n placeX(root);\n\n // ── Vertical: rows by depth (per drawn instance), top-aligned; each row reserves\n // a gate zone sized to its tallest gate assembly (incl. conditioning nodes). ───\n const rowInsts: Inst[][] = [];\n const visitRows = (inst: Inst): void => {\n (rowInsts[inst.depth] ??= []).push(inst);\n for (const c of inst.children) visitRows(c);\n };\n visitRows(root);\n const depthCount = rowInsts.length;\n\n /** Vertical extent of a gate assembly below the gate's top (glyph and/or oval+label). */\n const gateExtent = (inst: Inst): number => {\n const g = inst.gate!;\n if (g.type === \"xor\") return XOR_H;\n if (g.type === \"inhibit\") {\n // Oval vertically centered on the hexagon's side vertex (INHIBIT_CY); the\n // condition node's label may extend below the hexagon bottom.\n const condBottom = INHIBIT_CY - 16 + inst.cond!.m.nodeH;\n return Math.max(INHIBIT_H, condBottom);\n }\n return GATE_H;\n };\n const rowH: number[] = [];\n const gateZone: number[] = [];\n for (let d = 0; d < depthCount; d++) {\n const insts = rowInsts[d]!;\n rowH.push(insts.reduce((m, i) => Math.max(m, i.m.nodeH), 0));\n const gated = insts.filter((i) => i.gate !== null);\n gateZone.push(gated.length === 0 ? 0 : STEM + gated.reduce((m, i) => Math.max(m, gateExtent(i)), 0));\n }\n const rowTop: number[] = [PADDING];\n for (let d = 0; d < depthCount - 1; d++) {\n rowTop.push(rowTop[d]! + rowH[d]! + gateZone[d]! + CORRIDOR);\n }\n const busY = (d: number): number => rowTop[d + 1]! - CORRIDOR / 2;\n\n const width = Math.ceil(PADDING * 2 + root.spanL + root.spanR);\n const last = depthCount - 1;\n const height = Math.ceil(rowTop[last]! + rowH[last]! + gateZone[last]! + PADDING);\n\n // ── Instance finalization: only events drawn more than once carry an index. ──────\n const instanceOf = (inst: Inst): number | null =>\n (seqByEvent.get(inst.event.id) ?? 0) > 1 ? inst.seq : null;\n\n // ── Emit nodes / gates / elements in DFS order. ───────────────────────────────────\n const nodes: FaultTreeNode[] = [];\n const gates: FaultTreeGateNode[] = [];\n const elements: FaultTreeElement[] = [];\n\n const gateTitle = (g: FaultTreeGate): string =>\n g.type === \"vote\" ? `${titleLabels.gates.vote} ${g.k}/${g.inputIds.length}` : titleLabels.gates[g.type];\n\n const pushNode = (inst: Inst, top: number): void => {\n const isRect = inst.event.kind === \"intermediate\";\n const labelTop = !isRect && inst.m.labelLines.length > 0 ? top + inst.m.glyphH + LABEL_GAP : null;\n nodes.push({\n eventId: inst.event.id,\n kind: inst.event.kind,\n instance: instanceOf(inst),\n cx: round(inst.cx),\n top: round(top),\n nodeW: round(inst.m.nodeW),\n nodeH: round(inst.m.nodeH),\n glyphW: round(inst.m.glyphW),\n glyphH: round(inst.m.glyphH),\n labelLines: inst.m.labelLines,\n labelTop: labelTop === null ? null : round(labelTop),\n code: inst.m.code,\n depth: inst.depth,\n title: inst.title,\n });\n };\n\n const emit = (inst: Inst): void => {\n const d = inst.depth;\n pushNode(inst, rowTop[d]!);\n const g = inst.gate;\n if (g === null) return;\n\n const gateTop = rowTop[d]! + rowH[d]! + STEM;\n const glyphW = g.type === \"inhibit\" ? INHIBIT_W : GATE_W;\n const glyphH = g.type === \"xor\" ? XOR_H : g.type === \"inhibit\" ? INHIBIT_H : GATE_H;\n const title = gateTitle(g);\n gates.push({\n gateId: g.id,\n type: g.type,\n cx: round(inst.cx),\n top: round(gateTop),\n glyphW,\n glyphH,\n title,\n voteText: g.type === \"vote\" ? `${g.k}/${g.inputIds.length}` : null,\n });\n\n // Conditioning node: oval centered on the hexagon's side vertex, the whole node\n // box starting COND_GAP right of the vertex so the label can never reach the gate.\n if (inst.cond !== null) {\n const cond = inst.cond;\n const nodeLeft = inst.cx + INHIBIT_W / 2 + COND_GAP;\n cond.cx = nodeLeft + cond.m.nodeW / 2;\n const condTop = gateTop + INHIBIT_CY - 16;\n pushNode(cond, condTop);\n const ovalLeft = cond.cx - cond.m.glyphW / 2;\n elements.push({\n edgeId: FT_CONDITION_ID_BASE + g.id,\n kind: \"condition\",\n points: [\n { x: round(inst.cx + INHIBIT_W / 2), y: round(gateTop + INHIBIT_CY) },\n { x: round(ovalLeft), y: round(gateTop + INHIBIT_CY) },\n ],\n instance: null,\n title: titleLabels.condition,\n });\n }\n\n // Output stem: event bottom → gate top (longer than STEM when the event is\n // shorter than its row — rows are top-aligned).\n elements.push({\n edgeId: FT_STEM_ID_BASE + g.id,\n kind: \"stem\",\n points: [\n { x: round(inst.cx), y: round(rowTop[d]! + inst.m.nodeH) },\n { x: round(inst.cx), y: round(gateTop) },\n ],\n instance: null,\n title,\n });\n // Gate drop: gate connector bottom → bus.\n const by = busY(d);\n elements.push({\n edgeId: FT_DROP_ID_BASE + g.id,\n kind: \"drop\",\n points: [\n { x: round(inst.cx), y: round(gateTop + glyphH) },\n { x: round(inst.cx), y: round(by) },\n ],\n instance: null,\n title,\n });\n // Bus: spans min→max child centers; a single-input gate degenerates to the\n // straight drop + riser (no bus element).\n if (inst.children.length > 1) {\n const xs = inst.children.map((c) => c.cx);\n elements.push({\n edgeId: FT_BUS_ID_BASE + g.id,\n kind: \"bus\",\n points: [\n { x: round(Math.min(...xs)), y: round(by) },\n { x: round(Math.max(...xs)), y: round(by) },\n ],\n instance: null,\n title,\n });\n }\n // One riser per child: bus → child glyph top (the transfer triangle's apex IS\n // its glyph top). Risers into a repeated leaf carry that instance index, since\n // their edge id (FT_RISER_ID_BASE + child event id) repeats with the leaf.\n for (const c of inst.children) {\n elements.push({\n edgeId: FT_RISER_ID_BASE + c.event.id,\n kind: \"riser\",\n points: [\n { x: round(c.cx), y: round(by) },\n { x: round(c.cx), y: round(rowTop[d + 1]!) },\n ],\n instance: instanceOf(c),\n title,\n });\n }\n for (const c of inst.children) emit(c);\n };\n emit(root);\n\n return { width, height, nodes, gates, elements };\n}\n","// Fault-tree SVG emitter — turns a computed FaultTreeLayout (./layout.ts) into a\n// SELF-CONTAINED SVG string. Pure (layout in, string out) and deterministic; it draws\n// EXACTLY what the layout computed (the overlap harness proves the layout; this\n// emitter is pinned to it).\n//\n// Hard requirements (house rules):\n// - XML-ESCAPING of EVERY interpolated text — labels/codes/titles are\n// author-controlled and the SVG may be injected via innerHTML or embedded in PDFs;\n// - LITERAL presentation attributes only (hex colors, explicit font-family): a\n// standalone SVG has no stylesheet, no currentColor, no <defs>/<marker>;\n// - every coordinate goes through round() — 2-decimal, byte-deterministic output.\n//\n// Symbol fidelity (NUREG-0492 distinctive shapes): rectangle / circle / diamond /\n// house / oval / transfer-triangle events; AND dome, OR shield, XOR (OR + detached\n// second input curve — the ANSI/IEEE 91 distinctive shape; the legend entry\n// disambiguates), INHIBIT hexagon, VOTE (OR shield with \"k/n\" inside). Gates carry no\n// label text — the shape IS the semantics; the localized gate name rides the <title>.\n//\n// Hooks: `<g data-node-id=\"e<id>\">` per event instance and `<g data-node-id=\"g<id>\">`\n// per gate (direct-child verbatim <title>); `<g data-edge-id=\"<n>\">` per connector\n// element (namespaced ids, see ./layout.ts). Repeated-leaf instances (and their\n// risers) carry `data-instance=\"k\"` so every hook stays unambiguous.\n\nimport { FONT_FAMILY, legendBlock, xmlEscape, LEGEND_SWATCH_W, type LegendEntry } from \"../core\";\nimport { FT_LABEL_FONT, FT_LABEL_LINE_H, CODE_FONT, type FaultTreeElement, type FaultTreeGateNode, type FaultTreeLayout, type FaultTreeNode } from \"./layout\";\nimport { FAULT_TREE_SVG_LABELS_EN, type FaultTreeSvgLabels } from \"./labels\";\nimport { FAULT_TREE_EVENT_KINDS, GATE_TYPES, type FaultTreeEventKind, type GateType } from \"./types\";\n\n// Literal ink colors (zinc ramp on white — matches the genogram/ecomap emitters).\nconst GLYPH_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst EDGE_INK = \"#71717a\";\nconst GLYPH_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"2\"`;\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\nexport interface FaultTreeSvgOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary (legend/accessibility) — English default; see locale packs. */\n labels?: FaultTreeSvgLabels;\n}\n\n// ── Event glyphs ──────────────────────────────────────────────────────────────────\n\nfunction eventGlyph(n: FaultTreeNode): string {\n const cx = n.cx;\n const top = n.top;\n if (n.kind === \"intermediate\") {\n return `<rect x=\"${round(cx - n.nodeW / 2)}\" y=\"${top}\" width=\"${n.nodeW}\" height=\"${n.nodeH}\" rx=\"2\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"basic\") {\n return `<circle cx=\"${cx}\" cy=\"${round(top + 22)}\" r=\"22\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"undeveloped\") {\n const pts = `${cx},${top} ${round(cx + 24)},${round(top + 24)} ${cx},${round(top + 48)} ${round(cx - 24)},${round(top + 24)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"house\") {\n const yB = round(top + 40);\n const eave = round(top + 16);\n const pts = `${round(cx - 22)},${yB} ${round(cx - 22)},${eave} ${cx},${top} ${round(cx + 22)},${eave} ${round(cx + 22)},${yB}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n if (n.kind === \"conditioning\") {\n return `<ellipse cx=\"${cx}\" cy=\"${round(top + 16)}\" rx=\"${round(n.glyphW / 2)}\" ry=\"16\" ${GLYPH_ATTRS}/>`;\n }\n // transfer — triangle, line-to-apex (the riser ends exactly at the apex).\n const pts = `${cx},${top} ${round(cx + 22)},${round(top + 35)} ${round(cx - 22)},${round(top + 35)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n}\n\nfunction nodeSvg(n: FaultTreeNode): string {\n const pieces: string[] = [`<title>${xmlEscape(n.title)}</title>`, eventGlyph(n)];\n if (n.code !== null && n.kind !== \"intermediate\") {\n pieces.push(\n `<text x=\"${n.cx}\" y=\"${round(n.top + n.glyphH / 2 + CODE_FONT * 0.32)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${CODE_FONT}\" fill=\"${LABEL_FILL}\">${xmlEscape(n.code)}</text>`,\n );\n }\n if (n.labelLines.length > 0) {\n // Inside the rect (vertically centered block) or below the glyph (labelTop).\n const firstBaseline = n.labelTop === null ? round(n.top + 19) : round(n.labelTop + 10);\n const tspans = n.labelLines\n .map((line, i) => `<tspan x=\"${n.cx}\" y=\"${round(firstBaseline + i * FT_LABEL_LINE_H)}\">${xmlEscape(line)}</tspan>`)\n .join(\"\");\n pieces.push(\n `<text text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"${FT_LABEL_FONT}\" fill=\"${LABEL_FILL}\">${tspans}</text>`,\n );\n }\n const instance = n.instance === null ? \"\" : ` data-instance=\"${n.instance}\"`;\n return `<g data-node-id=\"e${n.eventId}\"${instance}>${pieces.join(\"\")}</g>`;\n}\n\n// ── Gate glyphs (distinctive shapes, drawn pointing up — output on top) ───────────\n\nfunction orBodyPath(cx: number, top: number, yB: number): string {\n return `M ${round(cx - 22)} ${yB} Q ${cx} ${round(yB - 14)} ${round(cx + 22)} ${yB} Q ${round(cx + 22)} ${round(top + 14)} ${cx} ${top} Q ${round(cx - 22)} ${round(top + 14)} ${round(cx - 22)} ${yB} Z`;\n}\n\nfunction gateGlyph(g: FaultTreeGateNode): string {\n const cx = g.cx;\n const top = g.top;\n const yB = round(top + 36);\n if (g.type === \"and\") {\n const d = `M ${round(cx - 22)} ${yB} L ${round(cx - 22)} ${round(yB - 14)} A 22 22 0 0 1 ${round(cx + 22)} ${round(yB - 14)} L ${round(cx + 22)} ${yB} Z`;\n return `<path d=\"${d}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"or\") {\n return `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"xor\") {\n const arc = `M ${round(cx - 22)} ${round(yB + 5)} Q ${cx} ${round(yB - 9)} ${round(cx + 22)} ${round(yB + 5)}`;\n return `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/><path d=\"${arc}\" ${GLYPH_ATTRS}/>`;\n }\n if (g.type === \"inhibit\") {\n const pts = `${cx},${top} ${round(cx + 18)},${round(top + 12)} ${round(cx + 18)},${round(top + 34)} ${cx},${round(top + 46)} ${round(cx - 18)},${round(top + 34)} ${round(cx - 18)},${round(top + 12)}`;\n return `<polygon points=\"${pts}\" ${GLYPH_ATTRS}/>`;\n }\n // vote — the OR distinctive shape with the declared \"k/n\" written inside.\n return (\n `<path d=\"${orBodyPath(cx, top, yB)}\" ${GLYPH_ATTRS}/>` +\n `<text x=\"${cx}\" y=\"${round(yB - 10)}\" text-anchor=\"middle\" font-family=\"${FONT_FAMILY}\" font-size=\"9\" fill=\"${LABEL_FILL}\">${xmlEscape(g.voteText ?? \"\")}</text>`\n );\n}\n\nfunction gateSvg(g: FaultTreeGateNode): string {\n return `<g data-node-id=\"g${g.gateId}\"><title>${xmlEscape(g.title)}</title>${gateGlyph(g)}</g>`;\n}\n\n// ── Connector elements ─────────────────────────────────────────────────────────────\n\nfunction elementSvg(el: FaultTreeElement): string {\n const a = el.points[0]!;\n const b = el.points[1]!;\n const instance = el.instance === null ? \"\" : ` data-instance=\"${el.instance}\"`;\n return (\n `<g data-edge-id=\"${el.edgeId}\"${instance}><title>${xmlEscape(el.title)}</title>` +\n `<line x1=\"${a.x}\" y1=\"${a.y}\" x2=\"${b.x}\" y2=\"${b.y}\" stroke=\"${EDGE_INK}\" stroke-width=\"1.5\" stroke-opacity=\"0.75\"/></g>`\n );\n}\n\n// ── Legend mini-glyph swatches (scaled into the 22px swatch box) ──────────────────\n\nconst MINI_ATTRS = `fill=\"transparent\" stroke=\"${GLYPH_STROKE}\" stroke-width=\"1.5\"`;\n\nfunction miniEventSwatch(kind: FaultTreeEventKind, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n if (kind === \"intermediate\") {\n return `<rect x=\"${round(cx - 7)}\" y=\"${round(y - 4.5)}\" width=\"14\" height=\"9\" rx=\"1\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"basic\") return `<circle cx=\"${cx}\" cy=\"${y}\" r=\"6\" ${MINI_ATTRS}/>`;\n if (kind === \"undeveloped\") {\n return `<polygon points=\"${cx},${round(y - 7)} ${round(cx + 7)},${y} ${cx},${round(y + 7)} ${round(cx - 7)},${y}\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"house\") {\n return `<polygon points=\"${round(cx - 6)},${round(y + 5.5)} ${round(cx - 6)},${round(y - 1)} ${cx},${round(y - 5.5)} ${round(cx + 6)},${round(y - 1)} ${round(cx + 6)},${round(y + 5.5)}\" ${MINI_ATTRS}/>`;\n }\n if (kind === \"conditioning\") return `<ellipse cx=\"${cx}\" cy=\"${y}\" rx=\"9\" ry=\"5.5\" ${MINI_ATTRS}/>`;\n return `<polygon points=\"${cx},${round(y - 5)} ${round(cx + 6)},${round(y + 5)} ${round(cx - 6)},${round(y + 5)}\" ${MINI_ATTRS}/>`;\n}\n\nfunction miniOrPath(cx: number, y: number): string {\n return `M ${round(cx - 7)} ${round(y + 5.5)} Q ${cx} ${round(y + 1)} ${round(cx + 7)} ${round(y + 5.5)} Q ${round(cx + 7)} ${round(y - 1.5)} ${cx} ${round(y - 5.5)} Q ${round(cx - 7)} ${round(y - 1.5)} ${round(cx - 7)} ${round(y + 5.5)} Z`;\n}\n\nfunction miniGateSwatch(type: GateType, x: number, y: number): string {\n const cx = round(x + LEGEND_SWATCH_W / 2);\n if (type === \"and\") {\n const d = `M ${round(cx - 7)} ${round(y + 5.5)} L ${round(cx - 7)} ${round(y + 1.5)} A 7 7 0 0 1 ${round(cx + 7)} ${round(y + 1.5)} L ${round(cx + 7)} ${round(y + 5.5)} Z`;\n return `<path d=\"${d}\" ${MINI_ATTRS}/>`;\n }\n if (type === \"xor\") {\n return `<path d=\"${miniOrPath(cx, y)}\" ${MINI_ATTRS}/><path d=\"M ${round(cx - 7)} ${round(y + 7.5)} Q ${cx} ${round(y + 3)} ${round(cx + 7)} ${round(y + 7.5)}\" ${MINI_ATTRS}/>`;\n }\n if (type === \"inhibit\") {\n return `<polygon points=\"${cx},${round(y - 5.5)} ${round(cx + 4.5)},${round(y - 2.5)} ${round(cx + 4.5)},${round(y + 2.5)} ${cx},${round(y + 5.5)} ${round(cx - 4.5)},${round(y + 2.5)} ${round(cx - 4.5)},${round(y - 2.5)}\" ${MINI_ATTRS}/>`;\n }\n // or / vote share the OR shield mini — the legend label disambiguates the vote.\n return `<path d=\"${miniOrPath(cx, y)}\" ${MINI_ATTRS}/>`;\n}\n\n/**\n * Emits a self-contained SVG for a computed fault-tree layout. Pure + deterministic.\n * Coordinates come straight from the layout; all interpolated text is XML-escaped;\n * all presentation attributes are literal. The legend lists ONLY the event kinds and\n * gate types actually present, in canonical declaration order.\n */\nexport function faultTreeLayoutSvg(layout: FaultTreeLayout, opts: FaultTreeSvgOptions = {}): string {\n const labels = opts.labels ?? FAULT_TREE_SVG_LABELS_EN;\n const parts: string[] = [];\n\n // Connectors first, then gates, then event nodes — nodes sit on top.\n for (const el of layout.elements) parts.push(elementSvg(el));\n for (const g of layout.gates) parts.push(gateSvg(g));\n for (const n of layout.nodes) parts.push(nodeSvg(n));\n\n // ── Used-keys-only legend (core legendBlock; `legend:false` suppresses). ─────────\n let width = layout.width;\n let height = layout.height;\n if (opts.legend !== false && layout.nodes.length > 0) {\n const kindsUsed = new Set(layout.nodes.map((n) => n.kind));\n const typesUsed = new Set(layout.gates.map((g) => g.type));\n const entries: LegendEntry[] = [];\n for (const kind of FAULT_TREE_EVENT_KINDS) {\n if (!kindsUsed.has(kind)) continue;\n entries.push({ swatch: (x, y) => miniEventSwatch(kind, x, y), label: labels.events[kind] });\n }\n for (const type of GATE_TYPES) {\n if (!typesUsed.has(type)) continue;\n entries.push({ swatch: (x, y) => miniGateSwatch(type, x, y), label: labels.gates[type] });\n }\n const block = legendBlock(entries, layout.height);\n if (block.svg !== \"\") {\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n","// One-call fault-tree render: input → { svg, layout }. Thin, honest wiring: validate\n// (throw on a structurally invalid tree — never repair), compute the pure layout,\n// emit. Callers needing finer control use computeFaultTreeLayout + faultTreeLayoutSvg\n// directly (the layout result supports hit-testing / decorating the diagram).\n\nimport { computeFaultTreeLayout, type FaultTreeLayout, type FaultTreeLayoutOptions } from \"./layout\";\nimport { faultTreeLayoutSvg } from \"./svg\";\nimport type { FaultTreeSvgLabels } from \"./labels\";\nimport type { FaultTreeInput } from \"./types\";\n\nexport interface FaultTreeRenderOptions extends FaultTreeLayoutOptions {\n /** Set false to suppress the legend (compact preview); default true. */\n legend?: boolean;\n /** Display vocabulary for the emitter (legend/accessibility) — English default. */\n svgLabels?: FaultTreeSvgLabels;\n}\n\nexport interface FaultTreeRenderResult {\n /** Self-contained SVG (numeric width/height + matching viewBox — PDF-embedder safe). */\n svg: string;\n /** The computed layout, for callers that decorate or hit-test the diagram. */\n layout: FaultTreeLayout;\n}\n\n/**\n * Renders a fault-tree input to a self-contained SVG string. Deterministic: same\n * data → same SVG (array order never matters; a gate's `inputIds` order is honored\n * as the declared left-to-right reading order). Throws FaultTreeValidationError —\n * carrying EVERY issue, deterministically sorted — on a structurally invalid tree.\n * Empty input yields an empty-but-valid SVG; callers decide their own empty state.\n */\nexport function faultTreeSvg(input: FaultTreeInput, opts: FaultTreeRenderOptions = {}): FaultTreeRenderResult {\n const layout = computeFaultTreeLayout(input, {\n ...(opts.maxLabelChars !== undefined ? { maxLabelChars: opts.maxLabelChars } : {}),\n ...(opts.titleLabels !== undefined ? { titleLabels: opts.titleLabels } : {}),\n });\n const svg = faultTreeLayoutSvg(layout, {\n ...(opts.legend === false ? { legend: false } : {}),\n ...(opts.svgLabels !== undefined ? { labels: opts.svgLabels } : {}),\n });\n return { svg, layout };\n}\n","// Ishikawa (fishbone / cause-and-effect) renderer — a horizontal spine running into\n// the effect head, category bones at 60°, horizontal cause twigs and ONE level of\n// diagonal sub-cause twigs — as a SELF-CONTAINED SVG string. Pure (data in, string\n// out), deterministic (same input → same SVG), no DOM, no dependencies.\n//\n// Notation (Ishikawa, *Guide to Quality Control*, JUSE 1976; ASQ template lineage):\n// the effect (\"characteristic\") is written in a box at the head of the central arrow;\n// big bones are diagonal, medium bones (causes) horizontal, small bones (sub-causes)\n// parallel to the big bone — every level drawn as an arrow converging on the effect.\n// The cartoon fish head is template folklore, not the standard, so the head is a\n// plain rectangle. Bones are at EXACTLY 60° to the spine (\"about 60°\" in the\n// literature): the angle is a constant, not an option, because every label-clearance\n// inequality below is derived from it. Beyond small bones the JUSE method itself\n// moves to why-why tables, so sub-sub-causes are typed away.\n//\n// DECLARED ORDER IS HONORED — the documented exception to the library's id-sorting\n// (ecomap) doctrine: the analyst's ordering is declared data (significant categories\n// nearest the head, alternating top/bottom; causes outward from the spine; sub-causes\n// from the bone outward). Numeric ids are still required — unique per namespace\n// (categories / causes / sub-causes), enforced by FishboneValidationError — because\n// the decoration hooks (`data-node-id`) must be unambiguous.\n//\n// HONESTY RULE: one declared category = one bone — no default 5M/6M skeleton, no\n// inferred grouping. Arrowheads are uniform notation (the diagram IS arrows\n// converging on the effect), so `arrowheads:false` toggles presentation, never data.\n//\n// Trig values are HARD-CODED literals: Math.tan/sin at runtime would make\n// byte-determinism hostage to engine-specific transcendental ulps.\n\nimport {\n FONT_FAMILY,\n LEGEND_SWATCH_W,\n clampLabel,\n estimateTextWidth,\n legendBlock,\n wrapLabel,\n wrapLabelBalanced,\n xmlEscape,\n type LegendEntry,\n} from \"../core\";\n\n// ── Input model ───────────────────────────────────────────────────────────────\n\nexport interface FishboneSubCause {\n id: number;\n /** Verbatim sub-cause text (drawn as one clamped line; full text in the <title>). */\n label: string;\n}\n\nexport interface FishboneCause {\n id: number;\n label: string;\n /** Exactly one sub-level is in scope (JUSE small bones); deeper nesting is typed away. */\n subCauses: FishboneSubCause[];\n /** Optional verbatim <title> override (defaults to the label). */\n title?: string;\n}\n\nexport interface FishboneCategory {\n id: number;\n label: string;\n causes: FishboneCause[];\n /** Optional verbatim <title> override (defaults to the label). */\n title?: string;\n}\n\nexport interface FishboneInput {\n /** The effect, written in the head box (verbatim). */\n effectLabel: string;\n /** Declared order is honored: first category nearest the head, alternating top/bottom. */\n categories: FishboneCategory[];\n}\n\n// ── Display vocabulary ────────────────────────────────────────────────────────\n\nexport interface FishboneLabels {\n /** Legend label for the cause-twig stroke (emitted only when sub-causes exist). */\n cause: string;\n /** Legend label for the sub-cause-twig stroke. */\n subCause: string;\n ariaLabel: string;\n}\n\nexport const FISHBONE_LABELS_EN: FishboneLabels = {\n cause: \"Cause\",\n subCause: \"Sub-cause\",\n ariaLabel: \"Cause-and-effect diagram (Ishikawa)\",\n};\n\n// ── Validation ────────────────────────────────────────────────────────────────\n\nexport type FishboneValidationCode = \"duplicate-id\";\n\nexport interface FishboneValidationIssue {\n /** Stable, machine-readable kebab-case code. */\n code: FishboneValidationCode;\n message: string;\n}\n\n/**\n * Thrown when ids collide within a namespace (categories / causes / sub-causes) —\n * the decoration hooks would be ambiguous. Carries ALL issues, deterministically\n * sorted (namespace order, then ascending id), never just the first. Everything\n * else (empty labels, zero causes, zero categories) is tolerated and drawn as\n * declared. The message mirrors the fault-tree shape (`invalid fishbone: …; …`)\n * so message-only logging keeps the diagram context for both modules.\n */\nexport class FishboneValidationError extends Error {\n readonly issues: readonly FishboneValidationIssue[];\n\n constructor(issues: readonly FishboneValidationIssue[]) {\n super(`invalid fishbone: ${issues.map((i) => i.message).join(\"; \")}`);\n this.name = \"FishboneValidationError\";\n this.issues = issues;\n }\n}\n\nfunction duplicateIds(ids: readonly number[]): number[] {\n const seen = new Set<number>();\n const dups = new Set<number>();\n for (const id of ids) {\n if (seen.has(id)) dups.add(id);\n seen.add(id);\n }\n return [...dups].sort((a, b) => a - b);\n}\n\nfunction validateIds(input: FishboneInput): void {\n const issues: FishboneValidationIssue[] = [];\n const collect = (noun: string, ids: readonly number[]): void => {\n for (const id of duplicateIds(ids)) {\n issues.push({ code: \"duplicate-id\", message: `duplicate ${noun} id ${id}` });\n }\n };\n collect(\"category\", input.categories.map((c) => c.id));\n collect(\"cause\", input.categories.flatMap((c) => c.causes.map((k) => k.id)));\n collect(\n \"sub-cause\",\n input.categories.flatMap((c) => c.causes.flatMap((k) => k.subCauses.map((s) => s.id))),\n );\n if (issues.length > 0) throw new FishboneValidationError(issues);\n}\n\n// ── Options ───────────────────────────────────────────────────────────────────\n\nexport interface FishboneSvgOptions {\n /** Display clamp per label (verbatim text stays in the <title>). */\n maxLabelChars?: number;\n /** Label font size (px); default 12. */\n fontSize?: number;\n /** Set false to suppress the legend; default true (emits only when sub-causes exist). */\n legend?: boolean;\n /** Arrowheads on spine/bones/twigs (classic Ishikawa); default true. */\n arrowheads?: boolean;\n /** Display vocabulary — English default; see `compasso/locales/pt-br`. */\n labels?: FishboneLabels;\n}\n\n// ── Geometry constants ────────────────────────────────────────────────────────\n\n// Hard-coded trig literals for the 60° bone angle (see module header).\nconst TAN60 = 1.7320508075688772;\nconst SIN60 = 0.8660254037844386;\nconst COS60 = 0.5;\n\nconst PADDING = 32;\nconst ROW_GAP = 12;\n/** Min horizontal air between adjacent same-side bone content AABBs. */\nconst BONE_GAP = 36;\nconst CAT_PAD_X = 12;\nconst CAT_PAD_Y = 8;\n/** Air between the bone's outer tip and the category box. */\nconst CAT_GAP = 12;\nconst TAIL_EXTRA = 44;\nconst HEAD_GAP = 24;\nconst HEAD_PAD_X = 14;\nconst HEAD_PAD_Y = 10;\n/** Sub-cause labels are ONE clamped line at this per-line budget (band invariant). */\nconst SUB_PER_LINE = 18;\n/** Helvetica-like glyph box at the 12px reference: ascent 11 above the baseline,\n * descent 3 below. EVERY fontSize-dependent vertical reserve is derived from these\n * (see verticalMetrics) — never used directly, so no 12px-only constant can leak\n * into the layout. */\nconst ASCENT_12 = 11;\nconst DESCENT_12 = 3;\n\n// ── fontSize-derived vertical metrics ─────────────────────────────────────────\n\ninterface VerticalMetrics {\n /** Baseline-to-glyph-top reserve (mirrors outward-stacked text on bottom bones). */\n ascent: number;\n /** Stacked-line pitch: EXACTLY ascent + descent, so consecutive baselines one\n * lineH apart give glyph bands that touch without overlapping, at any fontSize. */\n lineH: number;\n /** Innermost baseline offset from its twig: descent + 1 keeps the glyph ink 1px\n * clear of the twig stroke at any fontSize (4 at the default 12). */\n twigGap: number;\n /** Sub-twig vertical rise. blockH ≤ 2·lineH = sV − twigGap − 8 < sV, so within one\n * band the cause-label strip and the sub-label strip occupy disjoint y-slabs with\n * ≥ 8px air, and a sub-twig stays spine-ward of its label's center while crossing\n * the cause strip (both by construction, at any fontSize). */\n sV: number;\n /** First cause band starts |y| ≥ spineClear from the spine (the cross-side slab);\n * tied to the 2-line strip height so the slab tracks the type scale — anything\n * beyond the fixed ~10px bone-arrowhead reach preserves the guarantee. */\n spineClear: number;\n /** Twig length beyond its content: the bone's horizontal run across a 2-line cause\n * strip plus 25px of air — strictly above the (2·lineH + twigGap)/TAN60 + 10\n * floor the label-vs-bone clearance needs, by construction at any fontSize. */\n boneClear: number;\n /** Min horizontal air between adjacent ×1.2-padded sub-label boxes on one twig\n * (one line-height, so the air scales with the type; see the station packing). */\n subGap: number;\n}\n\n/** Derives the vertical reserves from the glyph metrics at the requested size, so\n * the slab/clearance inequalities in fishboneSvg hold BY CONSTRUCTION at any\n * fontSize. At the default 12 they reduce exactly to the original constants\n * (lineH 14, twigGap 4, sV 40, spineClear 32, boneClear 44, subGap 14), keeping\n * default output byte-stable (pinned by test/fishbone/render.test.ts). */\nfunction verticalMetrics(fontSize: number): VerticalMetrics {\n // Ceil-scaled so a reserve never rounds below the true em-scaled glyph extent.\n const ascent = Math.ceil((ASCENT_12 * fontSize) / 12);\n const descent = Math.ceil((DESCENT_12 * fontSize) / 12);\n const lineH = ascent + descent;\n const twigGap = descent + 1;\n return {\n ascent,\n lineH,\n twigGap,\n sV: 2 * lineH + twigGap + 8,\n spineClear: 2 * lineH + twigGap,\n boneClear: Math.ceil((2 * lineH + twigGap) / TAN60) + 25,\n subGap: lineH,\n };\n}\n\n// Ink (zinc ramp on white — matches the genogram/ecomap emitters). The four line\n// levels carry a decreasing stroke hierarchy (the only styled distinction a reader\n// could miss — exactly what the conditional legend names).\nconst EDGE_INK = \"#71717a\";\nconst BOX_STROKE = \"#52525b\";\nconst LABEL_FILL = \"#3f3f46\";\nconst SPINE_W = 2.5;\nconst SPINE_OP = 0.85;\nconst BONE_W = 2;\nconst BONE_OP = 0.8;\nconst TWIG_W = 1.5;\nconst TWIG_OP = 0.75;\nconst SUB_W = 1.2;\nconst SUB_OP = 0.7;\n\nconst round = (n: number): number => Math.round(n * 100) / 100;\n\n/** Arrowhead polygon: tip at (tipX,tipY), pointing along the unit vector (ux,uy). */\nfunction arrowHead(tipX: number, tipY: number, ux: number, uy: number, opacity: number): string {\n const LEN = 9;\n const HALF_W = 4.5;\n const bx = tipX - ux * LEN;\n const by = tipY - uy * LEN;\n const px = -uy;\n const py = ux;\n const points = [\n `${round(tipX)},${round(tipY)}`,\n `${round(bx + px * HALF_W)},${round(by + py * HALF_W)}`,\n `${round(bx - px * HALF_W)},${round(by - py * HALF_W)}`,\n ].join(\" \");\n return `<polygon points=\"${points}\" fill=\"${EDGE_INK}\" fill-opacity=\"${opacity}\"/>`;\n}\n\nfunction lineEl(x1: number, y1: number, x2: number, y2: number, w: number, op: number): string {\n return `<line x1=\"${round(x1)}\" y1=\"${round(y1)}\" x2=\"${round(x2)}\" y2=\"${round(y2)}\" stroke=\"${EDGE_INK}\" stroke-width=\"${w}\" stroke-opacity=\"${op}\"/>`;\n}\n\n// ── Internal measured shapes ──────────────────────────────────────────────────\n// All x positions below are relative to the bone's spine attachment; all vertical\n// positions are MAGNITUDES (distance from the spine) — the bottom side mirrors y.\n\ninterface SubBand {\n sub: FishboneSubCause;\n line: string;\n w: number;\n /** Station x on the cause twig. */\n sx: number;\n /** Outer end x of the diagonal sub-twig (= the label's center x). */\n outerX: number;\n}\n\ninterface CauseBand {\n cause: FishboneCause;\n lines: string[];\n labelW: number;\n blockH: number;\n /** Twig magnitude from the spine (the band's spine-side edge). */\n offset: number;\n bandH: number;\n /** Bone crossing at the twig's magnitude (≤ 0). */\n bx: number;\n /** Twig free end (tail-ward). */\n freeEnd: number;\n subs: SubBand[];\n}\n\ninterface Bone {\n category: FishboneCategory;\n up: boolean;\n bands: CauseBand[];\n /** Bone vertical magnitude (attach at the spine, outer end at −B / +B). */\n B: number;\n catLines: string[];\n boxW: number;\n boxH: number;\n /** Content extents relative to the attach: [ax − relL, ax + relR] contains ALL ink. */\n relL: number;\n relR: number;\n /** Absolute attach x (assigned by per-side packing). */\n ax: number;\n}\n\n/**\n * Renders a declared Ishikawa diagram to a self-contained SVG string. Deterministic:\n * same data → same SVG. Zero categories yield a valid spine+head-only SVG. Throws\n * FishboneValidationError on duplicate ids within a namespace (all issues listed).\n * The root keeps numeric width/height attributes plus a matching viewBox.\n *\n * Collision guarantee, by construction from MEASURED label widths (asserted by\n * test/fishbone/geometry.test.ts, including at non-default font sizes). Every\n * vertical reserve is derived from the glyph metrics at opts.fontSize (see\n * verticalMetrics), so the inequalities hold at ANY fontSize, not only the default:\n * 1. within a band: the cause-label strip and the sub-label strip occupy disjoint\n * y-slabs (blockH ≤ 2·lineH = sV − twigGap − 8 < sV); sub labels are x-disjoint\n * by station packing over ×1.2-padded estimates (absorbs the estimator's\n * Helvetica-caps deficit); both strips clear the slanted bone by the\n * station/boneClear inequalities;\n * 2. across bands of one bone: bands are stacked disjoint y-intervals of measured\n * heights (ROW_GAP included), and the bone crosses each slab only at its own\n * clearance-checked x;\n * 3. across bones of one side: disjoint content AABBs packed with BONE_GAP;\n * 4. across sides: open half-planes separated by the |y| < spineClear spine slab;\n * 5. head/tail: the head box sits beyond every bone's right extent + HEAD_GAP.\n * Every reserved width comes from estimateTextWidth (deliberately wide, core\n * doctrine) and the emitter draws at the same font metrics — reserved ⊇ drawn.\n */\nexport function fishboneSvg(input: FishboneInput, opts: FishboneSvgOptions = {}): string {\n validateIds(input);\n\n const fontSize = opts.fontSize ?? 12;\n const { ascent, lineH, twigGap, sV, spineClear, boneClear, subGap } = verticalMetrics(fontSize);\n const labels = opts.labels ?? FISHBONE_LABELS_EN;\n const arrows = opts.arrowheads !== false;\n\n // ── Measure every bone (declared order; even index → top, odd → bottom). ─────\n const bones: Bone[] = input.categories.map((category, idx) => {\n let cursor = spineClear;\n const bands: CauseBand[] = category.causes.map((cause) => {\n const lines = wrapLabelBalanced(clampLabel(cause.label, opts.maxLabelChars));\n const labelW = Math.max(...lines.map((l) => estimateTextWidth(l, fontSize)));\n const blockH = lines.length * lineH;\n const offset = cursor;\n const bx = -offset / TAN60;\n\n // Sub stations right→left in declared order. The first inequality keeps the\n // bone-nearest label clear of the slanted bone at the sub strip's outer edge\n // ((sV − twigGap)/TAN60 + 10 of air, which dwarfs the estimator's half-label\n // caps deficit at any fontSize). Successive stations keep the label boxes\n // disjoint with subGap air between ×1.2-PADDED estimates: CHAR_W 0.6 under-\n // reads Helvetica CAPS (≈ 0.72 em/char average), so padding each estimated\n // width by 20% restores reserved ⊇ drawn for caps-heavy labels — runs wider\n // than that (M/W walls) remain core-estimator doctrine, as everywhere else.\n const subs: SubBand[] = [];\n for (const sub of cause.subCauses) {\n const line = wrapLabel(clampLabel(sub.label, opts.maxLabelChars), SUB_PER_LINE, 1)[0]!;\n const w = estimateTextWidth(line, fontSize);\n const prev = subs.length > 0 ? subs[subs.length - 1]! : null;\n const sx =\n prev === null\n ? bx - (sV + lineH) / TAN60 - 10 - w / 2\n : prev.sx - (prev.w + w) * 0.6 - subGap;\n subs.push({ sub, line, w, sx, outerX: sx - sV / TAN60 });\n }\n\n const last = subs.length > 0 ? subs[subs.length - 1]! : null;\n const subSpan = last === null ? 0 : bx - (last.outerX - last.w / 2);\n // Twig length reserves, beyond the boneClear terms, a third term when subs\n // exist: the cause label must end BEFORE the leftmost sub-twig's outer x —\n // the diagonal sub-twigs descend through the cause-label y-slab, so a long\n // cause label hugging the free end could otherwise sit under them. (The\n // band-disjointness argument covers label strips, not the sub LINES.)\n const twigLen =\n last === null\n ? labelW + boneClear\n : Math.max(labelW + boneClear, subSpan + boneClear, labelW + (bx - last.outerX) + 10);\n\n const bandH = Math.max(blockH + twigGap, subs.length > 0 ? sV + lineH + twigGap : 0) + ROW_GAP;\n cursor += bandH;\n return { cause, lines, labelW, blockH, offset, bandH, bx, freeEnd: bx - twigLen, subs };\n });\n\n const B = cursor + 16;\n const catLines = wrapLabelBalanced(clampLabel(category.label, opts.maxLabelChars));\n const boxW = Math.max(...catLines.map((l) => estimateTextWidth(l, fontSize))) + CAT_PAD_X * 2;\n const boxH = catLines.length * lineH + CAT_PAD_Y * 2;\n const tipX = -B / TAN60;\n return {\n category,\n up: idx % 2 === 0,\n bands,\n B,\n catLines,\n boxW,\n boxH,\n // Left extent: the category box's left edge or the deepest twig free end —\n // every label sits AT or right of its twig's free end, every sub label sits\n // right of the free end too (twigLen ≥ subSpan + boneClear).\n relL: Math.max(B / TAN60 + boxW / 2, ...bands.map((b) => -b.freeEnd)),\n // Right extent: a wide category box on a short bone may overhang the attach.\n relR: Math.max(0, boxW / 2 + tipX),\n ax: 0,\n };\n });\n\n // ── Pack each side independently, right→left in declared order. ──────────────\n const cursors = { top: 0, bottom: 0 };\n for (const bone of bones) {\n const side = bone.up ? \"top\" : \"bottom\";\n bone.ax = cursors[side] - bone.relR;\n cursors[side] = bone.ax - bone.relL - BONE_GAP;\n }\n\n // ── Head box + spine extents (working coords: spine y = 0). ──────────────────\n const effLines = wrapLabelBalanced(clampLabel(input.effectLabel, opts.maxLabelChars));\n const headW = Math.max(...effLines.map((l) => estimateTextWidth(l, fontSize))) + HEAD_PAD_X * 2;\n const headH = effLines.length * lineH + HEAD_PAD_Y * 2;\n // Every bone's right extent is ≤ 0 by packing, so the head clears all of them.\n const headLeft = bones.length > 0 ? HEAD_GAP : 0;\n const tailX =\n bones.length > 0\n ? Math.min(...bones.map((b) => b.ax - b.relL)) - TAIL_EXTRA\n : headLeft - (TAIL_EXTRA + HEAD_GAP);\n\n // ── Bounds → shift positive (ecomap pattern). ────────────────────────────────\n let minY = -headH / 2;\n let maxY = headH / 2;\n for (const bone of bones) {\n const reach = bone.B + CAT_GAP + bone.boxH;\n if (bone.up) minY = Math.min(minY, -reach);\n else maxY = Math.max(maxY, reach);\n }\n const dx = PADDING - tailX;\n const dy = PADDING - minY;\n let width = headLeft + headW - tailX + PADDING * 2;\n let height = maxY - minY + PADDING * 2;\n const spineY = dy;\n\n const centeredYs = (cy: number, n: number): number[] =>\n Array.from({ length: n }, (_, i) => cy - ((n - 1) * lineH) / 2 + i * lineH + fontSize * 0.32);\n\n // Band text stacks OUTWARD from its strip's spine-side edge (magnitude e): on top\n // bones the innermost line's baseline sits twigGap beyond the edge (= descent + 1,\n // ink 1px clear of the twig at any fontSize); the bottom side mirrors with the\n // ascent so the glyphs occupy the mirrored strip.\n const bandBaselines = (e: number, n: number, up: boolean): number[] =>\n Array.from({ length: n }, (_, k) =>\n up ? spineY - (e + twigGap + (n - 1 - k) * lineH) : spineY + e + twigGap + ascent + k * lineH,\n );\n\n const textBlock = (anchor: \"start\" | \"middle\", x: number, ys: number[], lines: string[]): string =>\n `<text text-anchor=\"${anchor}\" font-family=\"${FONT_FAMILY}\" font-size=\"${fontSize}\" fill=\"${LABEL_FILL}\">` +\n lines.map((line, i) => `<tspan x=\"${round(x)}\" y=\"${round(ys[i]!)}\">${xmlEscape(line)}</tspan>`).join(\"\") +\n `</text>`;\n\n const parts: string[] = [];\n\n // ── Spine (under everything), arrow into the head's left edge. ───────────────\n {\n const body = [lineEl(tailX + dx, spineY, headLeft + dx, spineY, SPINE_W, SPINE_OP)];\n if (arrows) body.push(arrowHead(headLeft + dx, spineY, 1, 0, SPINE_OP));\n parts.push(`<g data-edge-id=\"spine\"><title>${xmlEscape(labels.ariaLabel)}</title>${body.join(\"\")}</g>`);\n }\n\n // ── Bones, twigs, sub-twigs — declared order. ────────────────────────────────\n for (const bone of bones) {\n const sgn = bone.up ? -1 : 1;\n const ax = bone.ax + dx;\n const tipX = ax - bone.B / TAN60;\n\n const body = [lineEl(tipX, spineY + sgn * bone.B, ax, spineY, BONE_W, BONE_OP)];\n // The bone runs from the outer tip INTO the spine: on a top bone that direction\n // is down-right (+y), on a bottom bone up-right (−y) — opposite the side sign.\n if (arrows) body.push(arrowHead(ax, spineY, COS60, -sgn * SIN60, BONE_OP));\n const boxTop = bone.up ? spineY - bone.B - CAT_GAP - bone.boxH : spineY + bone.B + CAT_GAP;\n body.push(\n `<rect x=\"${round(tipX - bone.boxW / 2)}\" y=\"${round(boxTop)}\" width=\"${round(bone.boxW)}\" height=\"${round(bone.boxH)}\" rx=\"2\" fill=\"transparent\" stroke=\"${BOX_STROKE}\" stroke-width=\"1.5\"/>`,\n );\n body.push(textBlock(\"middle\", tipX, centeredYs(boxTop + bone.boxH / 2, bone.catLines.length), bone.catLines));\n parts.push(\n `<g data-node-id=\"b${bone.category.id}\"><title>${xmlEscape(bone.category.title ?? bone.category.label)}</title>${body.join(\"\")}</g>`,\n );\n\n for (const band of bone.bands) {\n const ty = spineY + sgn * band.offset;\n const bx = ax + band.bx;\n const freeEnd = ax + band.freeEnd;\n const cbody = [lineEl(freeEnd, ty, bx, ty, TWIG_W, TWIG_OP)];\n if (arrows) cbody.push(arrowHead(bx, ty, 1, 0, TWIG_OP));\n cbody.push(textBlock(\"start\", freeEnd + 2, bandBaselines(band.offset, band.lines.length, bone.up), band.lines));\n parts.push(\n `<g data-node-id=\"c${band.cause.id}\"><title>${xmlEscape(band.cause.title ?? band.cause.label)}</title>${cbody.join(\"\")}</g>`,\n );\n\n for (const s of band.subs) {\n const sx = ax + s.sx;\n const ox = ax + s.outerX;\n const sbody = [lineEl(ox, spineY + sgn * (band.offset + sV), sx, ty, SUB_W, SUB_OP)];\n // Parallel to the bone, pointing into the twig — same spine-ward direction.\n if (arrows) sbody.push(arrowHead(sx, ty, COS60, -sgn * SIN60, SUB_OP));\n const baseline = bone.up\n ? spineY - (band.offset + sV + twigGap)\n : spineY + band.offset + sV + twigGap + ascent;\n sbody.push(textBlock(\"middle\", ox, [baseline], [s.line]));\n parts.push(`<g data-node-id=\"s${s.sub.id}\"><title>${xmlEscape(s.sub.label)}</title>${sbody.join(\"\")}</g>`);\n }\n }\n }\n\n // ── Effect head (on top), vertically centered on the spine. ──────────────────\n {\n const x = headLeft + dx;\n parts.push(\n `<g data-node-id=\"head\"><title>${xmlEscape(input.effectLabel)}</title>` +\n `<rect x=\"${round(x)}\" y=\"${round(spineY - headH / 2)}\" width=\"${round(headW)}\" height=\"${round(headH)}\" rx=\"2\" fill=\"transparent\" stroke=\"${BOX_STROKE}\" stroke-width=\"2\"/>` +\n textBlock(\"middle\", x + headW / 2, centeredYs(spineY, effLines.length), effLines) +\n `</g>`,\n );\n }\n\n // ── Conditional legend: the fishbone is fully labeled inline — the only styled\n // distinction a reader could miss is the cause vs sub-cause stroke hierarchy,\n // so used-keys-only means: both entries when at least one sub-cause exists,\n // otherwise no legend at all. ────────────────────────────────────────────────\n const anySubs = input.categories.some((c) => c.causes.some((k) => k.subCauses.length > 0));\n if (opts.legend !== false && anySubs) {\n const entries: LegendEntry[] = [\n {\n swatch: (x, y) => lineEl(x, y, x + LEGEND_SWATCH_W, y, TWIG_W, TWIG_OP),\n label: labels.cause,\n },\n {\n swatch: (x, y) => lineEl(x, y + 5, x + LEGEND_SWATCH_W, y - 5, SUB_W, SUB_OP),\n label: labels.subCause,\n },\n ];\n const block = legendBlock(entries, height);\n parts.push(block.svg);\n width = Math.max(width, block.width);\n height = block.height;\n }\n\n const w = Math.ceil(width);\n const h = Math.ceil(height);\n return (\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 ${w} ${h}\" width=\"${w}\" height=\"${h}\" role=\"img\" aria-label=\"${xmlEscape(labels.ariaLabel)}\">` +\n parts.join(\"\") +\n `</svg>`\n );\n}\n"]}
|