@beehexa/hexasync-template-report-render 2608.20.18 → 2608.20.32

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.
@@ -0,0 +1,449 @@
1
+ import { collapseDiff } from './diffCollapse.js';
2
+ import { buildMermaid } from './flowChart.js';
3
+ const STATUS = {
4
+ added: { label: '+ added', cls: 'added' },
5
+ inherited: { label: '= inherited', cls: 'inherited' },
6
+ customized: { label: '✏ customized', cls: 'customized' },
7
+ excluded: { label: '✂ excluded', cls: 'removed' },
8
+ lost: { label: '⚠ LOST', cls: 'lost' },
9
+ };
10
+ export function esc(text) {
11
+ return (String(text ?? '')
12
+ .replace(/&/g, '&')
13
+ .replace(/</g, '&lt;')
14
+ .replace(/>/g, '&gt;')
15
+ .replace(/"/g, '&quot;')
16
+ // Neutralize `$` so a math (KaTeX) viewer doesn't parse JSONata like `$.x` as LaTeX.
17
+ .replace(/\$/g, '&#36;'));
18
+ }
19
+ function pill(s) {
20
+ return `<span class="pill ${STATUS[s].cls}">${esc(STATUS[s].label)}</span>`;
21
+ }
22
+ /** Display priority: changes first (LOST, customized, removed, added), inherited last. */
23
+ const STATUS_RANK = {
24
+ lost: 0,
25
+ customized: 1,
26
+ excluded: 2,
27
+ added: 3,
28
+ inherited: 4,
29
+ };
30
+ function byStatusThenName(a, b) {
31
+ return (STATUS_RANK[a.status] - STATUS_RANK[b.status] ||
32
+ a.parentKey.localeCompare(b.parentKey) ||
33
+ a.idOrKey.localeCompare(b.idOrKey));
34
+ }
35
+ /** Group components by type (parentKey); groups with changes sort first and open
36
+ * by default, all-inherited groups sort last and stay collapsed. */
37
+ function groupByType(components) {
38
+ const groups = new Map();
39
+ for (const c of components) {
40
+ if (!groups.has(c.parentKey))
41
+ groups.set(c.parentKey, []);
42
+ groups.get(c.parentKey).push(c);
43
+ }
44
+ return [...groups.entries()]
45
+ .map(([type, comps]) => {
46
+ const sorted = comps.slice().sort(byStatusThenName);
47
+ const minRank = Math.min(...sorted.map((c) => STATUS_RANK[c.status]));
48
+ return {
49
+ type,
50
+ comps: sorted,
51
+ minRank,
52
+ hasChanges: sorted.some((c) => c.status !== 'inherited'),
53
+ };
54
+ })
55
+ .sort((a, b) => a.minRank - b.minRank || a.type.localeCompare(b.type));
56
+ }
57
+ /** Per-type status breakdown for a group's `<summary>` (priority order, colored pills). */
58
+ function groupSummary(type, comps) {
59
+ const counts = {
60
+ lost: 0,
61
+ customized: 0,
62
+ excluded: 0,
63
+ added: 0,
64
+ inherited: 0,
65
+ };
66
+ for (const c of comps)
67
+ counts[c.status]++;
68
+ const parts = Object.keys(counts)
69
+ .filter((s) => counts[s] > 0)
70
+ .map((s) => `${counts[s]} ${pill(s)}`);
71
+ return `<strong class="group-type">${esc(type)}</strong> <span class="group-count">${comps.length} component${comps.length === 1 ? '' : 's'}</span> ${parts.join(' ')}`;
72
+ }
73
+ function diffLineHtml(l) {
74
+ const cls = l.startsWith('+ ') ? 'add' : l.startsWith('- ') ? 'del' : 'ctx';
75
+ return `<div class="dl ${cls}">${esc(l)}</div>`;
76
+ }
77
+ /** Colored diff container; long unchanged runs collapse behind an expandable ellipsis. */
78
+ function diffHtml(diffText) {
79
+ const rows = collapseDiff(diffText)
80
+ .map((seg) => {
81
+ const body = seg.lines.map(diffLineHtml).join('');
82
+ return seg.collapsed
83
+ ? `<details class="fold"><summary>⋯ ${seg.lines.length} unchanged lines ⋯</summary>${body}</details>`
84
+ : body;
85
+ })
86
+ .join('');
87
+ return `<div class="diff">${rows}</div>`;
88
+ }
89
+ /** Customized-component diff block (open by default). */
90
+ function diffBlock(diffText) {
91
+ const changes = diffText
92
+ .split('\n')
93
+ .filter((l) => l.startsWith('+ ') || l.startsWith('- ')).length;
94
+ return `<details open><summary>customization diff — ${changes} change${changes === 1 ? '' : 's'} (inherited → final)</summary>${diffHtml(diffText)}</details>`;
95
+ }
96
+ /** Compact counts rollup for high-cardinality sub-collections (e.g. metrics). */
97
+ function subComponentsRowHtml(subs, colspan) {
98
+ const lines = subs
99
+ .filter((s) => s.added || s.removed || s.customized)
100
+ .map((s) => {
101
+ const parts = [];
102
+ if (s.added)
103
+ parts.push(`+${s.added} added`);
104
+ if (s.removed)
105
+ parts.push(`−${s.removed} removed`);
106
+ if (s.customized)
107
+ parts.push(`~${s.customized} customized`);
108
+ return `<div class="hint"><strong>${esc(s.title)}:</strong> ${parts.join(' · ')}</div>`;
109
+ })
110
+ .join('');
111
+ if (!lines)
112
+ return '';
113
+ return `<tr class="diff-row"><td colspan="${colspan}">${lines}</td></tr>`;
114
+ }
115
+ function hierarchy(h) {
116
+ return h
117
+ .map((x) => x.link
118
+ ? `<a href="${esc(x.link)}">${esc(x.label)}</a>`
119
+ : `<strong>${esc(x.label)}</strong>`)
120
+ .join(' <span class="arrow">&rarr;</span> ');
121
+ }
122
+ const STYLE = `
123
+ :root { color-scheme: light dark; }
124
+ body { font-family: -apple-system, Segoe UI, Roboto, Helvetica, Arial, sans-serif; margin: 2rem auto; max-width: 1100px; padding: 0 1rem; line-height: 1.45; color: #24292f; }
125
+ h1 { font-size: 1.6rem; } h2 { margin-top: 2rem; border-bottom: 1px solid #d0d7de; padding-bottom: .3rem; }
126
+ table { border-collapse: collapse; width: 100%; font-size: .9rem; }
127
+ th, td { border: 1px solid #d0d7de; padding: .4rem .55rem; text-align: left; vertical-align: top; }
128
+ th { background: #f6f8fa; position: sticky; top: 0; }
129
+ tr:nth-child(even) td { background: #fafbfc; }
130
+ code { background: #eff1f3; padding: .1rem .3rem; border-radius: 4px; font-size: .85em; }
131
+ .pill { display: inline-block; padding: .1rem .5rem; border-radius: 999px; font-weight: 600; font-size: .8rem; white-space: nowrap; }
132
+ .added { background: #dafbe1; color: #116329; }
133
+ .inherited { background: #eaeef2; color: #57606a; }
134
+ .customized { background: #ddf4ff; color: #0550ae; }
135
+ .removed { background: #ffebe9; color: #a40e26; }
136
+ .lost { background: #cf222e; color: #fff; }
137
+ .summary-cards { display: flex; gap: .6rem; flex-wrap: wrap; margin: 1rem 0; }
138
+ .card { border: 1px solid #d0d7de; border-radius: 8px; padding: .6rem 1rem; min-width: 90px; }
139
+ .card .n { font-size: 1.5rem; font-weight: 700; } .card .l { font-size: .8rem; }
140
+ .warn { background: #fff8c5; border: 1px solid #d4a72c; border-radius: 6px; padding: .5rem .8rem; margin: .4rem 0; }
141
+ .warn.lost { background: #ffebe9; border-color: #cf222e; color: #a40e26; }
142
+ .last-wins { background: #dafbe1; font-weight: 700; }
143
+ .arrow { color: #6e7781; }
144
+ details { margin: .2rem 0; } summary { cursor: pointer; color: #0969da; }
145
+ .diff { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: .82rem; border: 1px solid #d0d7de; border-radius: 6px; overflow-x: auto; margin-top: .3rem; }
146
+ .dl { white-space: pre-wrap; padding: 0 .5rem; }
147
+ .dl.add { background: #e6ffec; color: #116329; } .dl.del { background: #ffebe9; color: #a40e26; } .dl.ctx { color: #57606a; }
148
+ .diff-row td { background: #f6f8fa; }
149
+ .diff details.fold > summary { color: #57606a; padding: 0 .5rem; }
150
+ .flow-chart { overflow-x: auto; padding: .4rem; background: #fff; border: 1px solid #d0d7de; border-radius: 6px; margin-top: .3rem; }
151
+ .flow-chart svg { max-width: 100%; height: auto; }
152
+ .hint { color: #6e7781; font-size: .85rem; margin: .3rem 0 .6rem; }
153
+ details.type-group { border: 1px solid #d0d7de; border-radius: 8px; margin: .5rem 0; padding: .1rem .7rem; }
154
+ details.type-group > summary { padding: .4rem 0; font-size: .95rem; }
155
+ details.type-group[open] > summary { border-bottom: 1px solid #eaecef; margin-bottom: .4rem; }
156
+ .group-type { font-size: 1.05rem; text-transform: capitalize; }
157
+ .group-count { color: #6e7781; margin: 0 .5rem 0 .3rem; font-size: .85rem; }
158
+ .tabset { margin-top: .3rem; }
159
+ .tab-caption { font-size: .78rem; color: #6e7781; margin-bottom: .25rem; }
160
+ .tabs { display: flex; flex-wrap: wrap; gap: .15rem; border-bottom: 1px solid #d0d7de; }
161
+ .tab-btn { border: 1px solid transparent; border-bottom: none; background: none; padding: .25rem .6rem; cursor: pointer; font-size: .8rem; border-radius: 6px 6px 0 0; color: #0969da; font-family: inherit; }
162
+ .tab-btn.active { background: #fff; border-color: #d0d7de; color: #24292f; font-weight: 600; }
163
+ .tab-count { background: #eaeef2; border-radius: 999px; padding: 0 .35rem; margin-left: .25rem; font-size: .72rem; color: #57606a; }
164
+ .tab-panel { display: none; }
165
+ .tab-panel.active { display: block; }
166
+ @media (prefers-color-scheme: dark) {
167
+ .tab-btn.active { background: #0d1117; border-color: #30363d; color: #c9d1d9; }
168
+ .tab-count { background: #21262d; color: #8b949e; }
169
+ }
170
+ @media (prefers-color-scheme: dark) {
171
+ body { color: #c9d1d9; background: #0d1117; }
172
+ th { background: #161b22; } tr:nth-child(even) td { background: #0d1117; } td, th { border-color: #30363d; }
173
+ code { background: #161b22; } h2 { border-color: #30363d; }
174
+ .card { border-color: #30363d; } .diff { border-color: #30363d; }
175
+ .dl.add { background: #0f2d1a; color: #56d364; } .dl.del { background: #3a1418; color: #f85149; } .dl.ctx { color: #8b949e; }
176
+ .last-wins { background: #0f2d1a; }
177
+ .diff-row td { background: #161b22; }
178
+ .flow-chart { background: #0d1117; border-color: #30363d; }
179
+ details.type-group { border-color: #30363d; }
180
+ details.type-group[open] > summary { border-color: #21262d; }
181
+ }
182
+ `;
183
+ /** Render the Merge Integrity Report as a self-contained, styled HTML document. */
184
+ export function renderReportHtml(model) {
185
+ const p = [];
186
+ // Mermaid definitions collected as rows are emitted; rendered by the trailing
187
+ // module script into their matching `#mmd-<i>` placeholders (final/winner flow only).
188
+ const charts = [];
189
+ const flowRow = (flow, colspan) => {
190
+ const i = charts.length;
191
+ charts.push(buildMermaid(flow));
192
+ const phaseCount = flow.phases.length;
193
+ const stepCount = flow.phases.reduce((n, ph) => n + ph.steps.length, 0);
194
+ const summary = flow.kind === 'creation'
195
+ ? `creation workflow — ${stepCount} step(s)`
196
+ : `${flow.kind} flow — ${phaseCount} phase(s), ${stepCount} step(s)`;
197
+ return (`<tr class="diff-row"><td colspan="${colspan}">` +
198
+ `<details open><summary>${summary}</summary>` +
199
+ `<div class="flow-chart" id="mmd-${i}"></div></details></td></tr>`);
200
+ };
201
+ // Nested sub-table (metrics / webhook targets / map entries). Customized items get
202
+ // a diff; items with a step-flow (webhook target pullSteps) get a live Mermaid chart.
203
+ const subTableRow = (subTable, colspan) => {
204
+ const items = subTable.items
205
+ .slice()
206
+ .sort((a, b) => STATUS_RANK[a.status] - STATUS_RANK[b.status] ||
207
+ a.idOrKey.localeCompare(b.idOrKey));
208
+ const counts = {
209
+ lost: 0,
210
+ customized: 0,
211
+ excluded: 0,
212
+ added: 0,
213
+ inherited: 0,
214
+ };
215
+ for (const it of subTable.items)
216
+ counts[it.status]++;
217
+ const parts = Object.keys(counts)
218
+ .filter((s) => counts[s] > 0)
219
+ .map((s) => `${counts[s]} ${pill(s)}`);
220
+ const hasChanges = subTable.items.some((it) => it.status !== 'inherited');
221
+ const rows = items
222
+ .map((it) => {
223
+ let r = `<tr><td><code>${esc(it.label)}</code></td><td>${pill(it.status)}</td></tr>`;
224
+ if (it.status === 'customized' && it.diffText) {
225
+ r += `<tr class="diff-row"><td colspan="2">${diffBlock(it.diffText)}</td></tr>`;
226
+ }
227
+ if (it.flow) {
228
+ const i = charts.length;
229
+ charts.push(buildMermaid(it.flow));
230
+ const stepCount = it.flow.phases.reduce((n, ph) => n + ph.steps.length, 0);
231
+ r +=
232
+ `<tr class="diff-row"><td colspan="2">` +
233
+ `<details open><summary>${it.flow.kind} flow — ${stepCount} step(s)</summary>` +
234
+ `<div class="flow-chart" id="mmd-${i}"></div></details></td></tr>`;
235
+ }
236
+ return r;
237
+ })
238
+ .join('');
239
+ return (`<tr class="diff-row"><td colspan="${colspan}">` +
240
+ `<details class="type-group"${hasChanges ? ' open' : ''}><summary><strong class="group-type">${esc(subTable.title)}</strong> <span class="group-count">${subTable.items.length}</span> ${parts.join(' ')}</summary>` +
241
+ `<table><thead><tr><th>${esc(subTable.title)}</th><th>Status</th></tr></thead><tbody>${rows}</tbody></table></details></td></tr>`);
242
+ };
243
+ // Diff cell: per-generation "overwrite history" tabs (D→C, C→B, B→A — last is
244
+ // THIS's real override) when the component crossed >1 generation hop; otherwise
245
+ // the single inherited→final diff block.
246
+ let tabSeq = 0;
247
+ const diffCell = (c) => {
248
+ if (c.diffPhases && c.diffPhases.length > 1) {
249
+ const gid = tabSeq++;
250
+ const last = c.diffPhases.length - 1;
251
+ const btns = c.diffPhases
252
+ .map((ph, i) => `<button class="tab-btn${i === last ? ' active' : ''}" data-tab="${gid}" data-i="${i}">${esc(ph.fromLabel)} &rarr; ${esc(ph.toLabel)}<span class="tab-count">${ph.changeCount}</span></button>`)
253
+ .join('');
254
+ const panels = c.diffPhases
255
+ .map((ph, i) => `<div class="tab-panel${i === last ? ' active' : ''}" data-tab="${gid}" data-i="${i}">${diffHtml(ph.diffText)}</div>`)
256
+ .join('');
257
+ return `<div class="tabset"><div class="tab-caption">Overwrite history — ${c.diffPhases.length} project hops (lowest → highest precedence; the last tab is the winner)</div><div class="tabs">${btns}</div><div class="tab-panels">${panels}</div></div>`;
258
+ }
259
+ if (c.diffPhases && c.diffPhases.length === 1) {
260
+ const ph = c.diffPhases[0];
261
+ return `<details open><summary>overwritten: ${esc(ph.fromLabel)} &rarr; ${esc(ph.toLabel)} — ${ph.changeCount} change${ph.changeCount === 1 ? '' : 's'}</summary>${diffHtml(ph.diffText)}</details>`;
262
+ }
263
+ return diffBlock(c.diffText ?? '');
264
+ };
265
+ p.push('<!doctype html><html lang="en"><head><meta charset="utf-8">');
266
+ p.push(`<meta name="viewport" content="width=device-width, initial-scale=1">`);
267
+ p.push(`<title>Merge Integrity Report — ${esc(model.projectTitle)}</title>`);
268
+ p.push(`<style>${STYLE}</style></head><body>`);
269
+ p.push(`<h1>Merge Integrity Report — ${esc(model.projectTitle)}</h1>`);
270
+ // Summary cards (priority order)
271
+ p.push('<div class="summary-cards">');
272
+ Object.keys(model.counts)
273
+ .sort((a, b) => STATUS_RANK[a] - STATUS_RANK[b])
274
+ .forEach((s) => {
275
+ p.push(`<div class="card"><div class="n">${model.counts[s]}</div><div class="l">${pill(s)}</div></div>`);
276
+ });
277
+ p.push('</div>');
278
+ // Warnings
279
+ for (const w of model.warnings) {
280
+ const cls = w.includes('LOST') ? 'warn lost' : 'warn';
281
+ p.push(`<div class="${cls}">${esc(w)}</div>`);
282
+ }
283
+ // Composed projects
284
+ p.push('<h2>Composed projects (resolved merge order)</h2>');
285
+ p.push('<table><thead><tr><th>#</th><th>Project</th><th>Generation</th><th>Weight</th><th>Merged</th></tr></thead><tbody>');
286
+ // Resolved merge order (CAP-7): deepest generation first, then ascending weight
287
+ // (higher weight merges later/wins), then declaration/BFS order — matching linearize.
288
+ const w = (x) => Number.isFinite(x.weight) ? x.weight : 0;
289
+ const ordered = model.composedProjects
290
+ .slice()
291
+ .sort((a, b) => b.generation - a.generation || w(a) - w(b) || a.order - b.order);
292
+ ordered.forEach((row, i, arr) => {
293
+ const isLastWins = i === arr.length - 1;
294
+ const weight = Number.isFinite(row.weight) ? String(row.weight) : '—';
295
+ const gen = row.generation === 0
296
+ ? '0 (current)'
297
+ : row.generation === 1
298
+ ? '1 (parent)'
299
+ : `${row.generation} (ancestor)`;
300
+ const when = isLastWins ? 'last (wins)' : i === 0 ? 'first' : '';
301
+ p.push(`<tr class="${isLastWins ? 'last-wins' : ''}"><td>${i + 1}</td><td>${esc(row.project)}</td><td>${gen}</td><td>${weight}</td><td>${when}</td></tr>`);
302
+ });
303
+ p.push('</tbody></table>');
304
+ // Global provenance — one collapsible group per type (expand just what you review).
305
+ p.push('<h2>Global component provenance</h2>');
306
+ p.push('<p class="hint">Grouped by type — click a type to expand/collapse. Types with changes are expanded; unchanged types are collapsed.</p>');
307
+ for (const g of groupByType(model.components)) {
308
+ p.push(`<details class="type-group"${g.hasChanges ? ' open' : ''}><summary>${groupSummary(g.type, g.comps)}</summary>`);
309
+ p.push('<table><thead><tr><th>Component</th><th>Status</th><th>Winner</th><th>Weight</th><th>Hierarchy path</th></tr></thead><tbody>');
310
+ for (const c of g.comps) {
311
+ const weight = c.weight !== undefined ? String(c.weight) : '—';
312
+ p.push(`<tr><td><code>${esc(c.idOrKey)}</code></td><td>${pill(c.status)}</td><td>${esc(c.winner) || '—'}</td><td>${weight}</td><td>${hierarchy(c.hierarchy)}</td></tr>`);
313
+ // Customized → full-width diff row directly beneath (inherited → final,
314
+ // or per-generation overwrite-history tabs when multi-hop).
315
+ if (c.status === 'customized' && (c.diffText || c.diffPhases)) {
316
+ p.push(`<tr class="diff-row"><td colspan="5">${diffCell(c)}</td></tr>`);
317
+ }
318
+ // Puller/pusher → live Mermaid flow chart row directly beneath (any status).
319
+ if (c.flow)
320
+ p.push(flowRow(c.flow, 5));
321
+ // Object/task → nested metrics sub-table row.
322
+ if (c.subTable)
323
+ p.push(subTableRow(c.subTable, 5));
324
+ if (c.subComponents) {
325
+ const r = subComponentsRowHtml(c.subComponents, 5);
326
+ if (r)
327
+ p.push(r);
328
+ }
329
+ }
330
+ p.push('</tbody></table></details>');
331
+ }
332
+ // Wholesale overwrites that dropped id/key components (accidental-loss signal).
333
+ if (model.wholesaleLosses.length > 0) {
334
+ p.push('<h2>⚠ Wholesale overwrites (dropped components)</h2>');
335
+ p.push('<p class="hint">A later source replaced these arrays wholesale with items that have no <code>id</code>/<code>key</code>, dropping the components listed. Not an explicit <code>!</code> removal — verify each is intended.</p>');
336
+ for (const wl of model.wholesaleLosses) {
337
+ const fileName = wl.sourceFile.split(/[\\/]/).filter(Boolean).pop() ?? '';
338
+ const fileLink = wl.sourceLink
339
+ ? `<a href="${esc(wl.sourceLink)}"><code>${esc(fileName)}</code></a>`
340
+ : `<code>${esc(fileName)}</code>`;
341
+ p.push(`<details open><summary>⚠ <code>${esc(wl.parentKey)}</code> — dropped ${wl.droppedIds.length} component(s): ${wl.droppedIds.map((d) => `<code>${esc(d)}</code>`).join(', ')} (replaced by ${fileLink})</summary>`);
342
+ p.push(diffHtml(wl.diffText));
343
+ p.push('</details>');
344
+ }
345
+ }
346
+ // Variables (added / changed) — wrapped in one collapsible group so it can fold.
347
+ if (model.variableChanges.length > 0) {
348
+ p.push('<h2>Variables (added / changed)</h2>');
349
+ p.push('<p class="hint">Variables this project adds or changes vs. inherited (unchanged omitted).</p>');
350
+ const added = model.variableChanges.filter((v) => v.status === 'added').length;
351
+ const customized = model.variableChanges.length - added;
352
+ const parts = [];
353
+ if (added > 0)
354
+ parts.push(`${added} ${pill('added')}`);
355
+ if (customized > 0)
356
+ parts.push(`${customized} ${pill('customized')}`);
357
+ p.push(`<details class="type-group" open><summary><strong class="group-type">variables</strong> <span class="group-count">${model.variableChanges.length} changed</span> ${parts.join(' ')}</summary>`);
358
+ for (const v of model.variableChanges) {
359
+ p.push(`<details open><summary>${pill(v.status)} <code>${esc(v.key)}</code></summary>`);
360
+ p.push(diffHtml(v.diffText));
361
+ p.push('</details>');
362
+ }
363
+ p.push('</details>');
364
+ }
365
+ // Per-project contribution
366
+ const byProject = new Map();
367
+ for (const c of model.components) {
368
+ const key = c.winner || '—';
369
+ if (!byProject.has(key))
370
+ byProject.set(key, []);
371
+ byProject.get(key).push(c);
372
+ }
373
+ if (byProject.size > 0) {
374
+ p.push('<h2>Per-project contribution</h2>');
375
+ for (const [proj, comps] of byProject) {
376
+ p.push(`<h3>${esc(proj)}</h3>`);
377
+ // Group this project's components by type, collapsible (same as global).
378
+ for (const g of groupByType(comps)) {
379
+ p.push(`<details class="type-group"${g.hasChanges ? ' open' : ''}><summary>${groupSummary(g.type, g.comps)}</summary>`);
380
+ p.push('<table><thead><tr><th>Component</th><th>Fate</th></tr></thead><tbody>');
381
+ for (const c of g.comps) {
382
+ p.push(`<tr><td><code>${esc(c.idOrKey)}</code></td><td>${pill(c.status)}</td></tr>`);
383
+ if (c.status === 'customized' && (c.diffText || c.diffPhases)) {
384
+ p.push(`<tr class="diff-row"><td colspan="2">${diffCell(c)}</td></tr>`);
385
+ }
386
+ if (c.flow)
387
+ p.push(flowRow(c.flow, 2));
388
+ if (c.subTable)
389
+ p.push(subTableRow(c.subTable, 2));
390
+ if (c.subComponents) {
391
+ const r = subComponentsRowHtml(c.subComponents, 2);
392
+ if (r)
393
+ p.push(r);
394
+ }
395
+ }
396
+ p.push('</tbody></table></details>');
397
+ }
398
+ }
399
+ }
400
+ // Render collected puller/pusher flows with Mermaid (loaded from CDN; needs a
401
+ // network connection). Definitions carry pre-escaped labels, so mermaid.render
402
+ // interprets them directly rather than relying on DOM entity decoding.
403
+ if (charts.length > 0) {
404
+ p.push('<script type="module">');
405
+ p.push("import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';");
406
+ p.push("const dark = matchMedia('(prefers-color-scheme: dark)').matches;");
407
+ // securityLevel 'strict' makes Mermaid sanitize HTML inside labels (DOMPurify),
408
+ // so a step name like `<img onerror=…>` can't execute on render.
409
+ p.push("mermaid.initialize({ startOnLoad: false, theme: dark ? 'dark' : 'default', securityLevel: 'strict' });");
410
+ // Escape `<` so a chart string containing `</script>` cannot close this inline
411
+ // module script early (JSON.stringify does not escape `/`). < is valid JSON.
412
+ p.push(`const defs = ${JSON.stringify(charts)
413
+ .replace(/</g, '\\u003c')
414
+ .replace(/\u2028/g, '\\u2028')
415
+ .replace(/\u2029/g, '\\u2029')};`);
416
+ p.push('for (let i = 0; i < defs.length; i++) {');
417
+ p.push(" const el = document.getElementById('mmd-' + i);");
418
+ p.push(' if (!el) continue;');
419
+ p.push(' try {');
420
+ p.push(" const { svg } = await mermaid.render('mmdsvg-' + i, defs[i]);");
421
+ p.push(' el.innerHTML = svg;');
422
+ p.push(' } catch (e) {');
423
+ // Build the error node with textContent (NOT innerHTML): Mermaid error messages
424
+ // echo the diagram source, which is derived from user-controlled step names —
425
+ // innerHTML here would re-open the XSS the strict/escape fixes close.
426
+ p.push(" const pre = document.createElement('pre');");
427
+ p.push(" pre.style.color = '#a40e26';");
428
+ p.push(" pre.textContent = 'Mermaid render error: ' + String((e && e.message) || e);");
429
+ p.push(' el.replaceChildren(pre);');
430
+ p.push(' }');
431
+ p.push('}');
432
+ p.push('</script>');
433
+ }
434
+ // Overwrite-history tab switching (no dependency on Mermaid; may exist alone).
435
+ if (tabSeq > 0) {
436
+ p.push('<script>');
437
+ p.push("document.querySelectorAll('.tab-btn').forEach(function (btn) {");
438
+ p.push(" btn.addEventListener('click', function () {");
439
+ p.push(" var t = btn.getAttribute('data-tab'), i = btn.getAttribute('data-i');");
440
+ p.push(" document.querySelectorAll('.tab-btn[data-tab=\"' + t + '\"]').forEach(function (b) { b.classList.toggle('active', b.getAttribute('data-i') === i); });");
441
+ p.push(" document.querySelectorAll('.tab-panel[data-tab=\"' + t + '\"]').forEach(function (pnl) { pnl.classList.toggle('active', pnl.getAttribute('data-i') === i); });");
442
+ p.push(' });');
443
+ p.push('});');
444
+ p.push('</script>');
445
+ }
446
+ p.push('</body></html>');
447
+ return p.join('\n');
448
+ }
449
+ //# sourceMappingURL=renderHtml.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderHtml.js","sourceRoot":"","sources":["../src/renderHtml.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { ReportModel } from '@beehexa/hexasync-template-report-model';
2
+ /** Escape text for inline HTML inside a Markdown table cell. Also neutralizes
3
+ * `|` (breaks cells) and `$` (a math-extension delimiter — JSONata like `$.x`
4
+ * would otherwise be parsed as LaTeX and throw a KaTeX error in the viewer). */
5
+ export declare function escHtml(text: string): string;
6
+ /**
7
+ * Render the Merge Integrity Report (AD-6). Warnings/errors are surfaced at the
8
+ * TOP so a LOST row can never be buried. Pure string formatting — no I/O.
9
+ */
10
+ export declare function renderReport(model: ReportModel): string;
11
+ //# sourceMappingURL=renderMarkdown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"renderMarkdown.d.ts","sourceRoot":"","sources":["../src/renderMarkdown.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAGZ,MAAM,yCAAyC,CAAC;AAgFjD;;iFAEiF;AACjF,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ5C;AA0JD;;;GAGG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CA+OvD"}