diff --git a/src/app.js b/src/app.js index db4f777..1beee36 100644 --- a/src/app.js +++ b/src/app.js @@ -2458,6 +2458,7 @@ const pedTree = document.getElementById("pedigree-tree"); const pedBtn = document.getElementById("pedigree-btn"); const pedRefresh = document.getElementById("pedigree-refresh"); + const pedRepeatNote = document.getElementById("pedigree-repeat-note"); const PED_OPEN_DEPTH = 3; // show 3 generations expanded by default; deeper collapses let pedPollTimer = null; @@ -2580,20 +2581,24 @@ // fills many positions); "generations back" is the depth of the deepest // position (floor(log2(pos)), since sire = 2·pos and dam = 2·pos+1). function pedCounts() { - const seen = new Set(); + const counts = new Map(); let maxPos = 1; for (const k in pedNodes) { const n = pedNodes[k]; const key = n.reg || n.name; - if (key) seen.add(key); + if (key) counts.set(key, (counts.get(key) || 0) + 1); const p = Number(k); if (p > maxPos) maxPos = p; } - return { distinct: seen.size, gens: Math.floor(Math.log2(maxPos)) }; + let repeated = 0; + counts.forEach((c) => { if (c > 1) repeated++; }); + return { distinct: counts.size, repeated, gens: Math.floor(Math.log2(maxPos)) }; } function pedCountText() { - const { distinct: a, gens: g } = pedCounts(); - return `${a} ancestor${a === 1 ? "" : "s"} back ${g} generation${g === 1 ? "" : "s"}`; + const { distinct: a, repeated: r, gens: g } = pedCounts(); + let s = `${a} ancestor${a === 1 ? "" : "s"} back ${g} generation${g === 1 ? "" : "s"}`; + if (r > 0) s += `, ${r} appearing more than once`; + return s; } function setPedDone() { setPedStatus(`Traced ${pedCountText()}.`, "done"); } function setPedStatus(text, kind) { @@ -2649,9 +2654,29 @@ // 2n+1. We render it top-down like a family tree — the dog on top, parents // branching below — as a nested