diff --git a/js/nodes_stats.js b/js/nodes_stats.js
index 43a6b67..0c066e5 100644
--- a/js/nodes_stats.js
+++ b/js/nodes_stats.js
@@ -92,7 +92,7 @@ async function showStatsDialog() {
${unusedNew.length}
unused <1 month
-
+
${used.length}
used
@@ -144,6 +144,25 @@ async function showStatsDialog() {
}
});
});
+
+ // Easter egg: click "used" badge 5 times to show podium
+ let eggClicks = 0;
+ let eggTimer = null;
+ const usedBadge = document.getElementById("nodes-stats-used-badge");
+ if (usedBadge) {
+ usedBadge.addEventListener("click", () => {
+ eggClicks++;
+ clearTimeout(eggTimer);
+ eggTimer = setTimeout(() => (eggClicks = 0), 1500);
+ if (eggClicks >= 5) {
+ eggClicks = 0;
+ const allNodes = custom
+ .flatMap((p) => p.nodes.map((n) => ({ ...n, pkg: p.package })))
+ .sort((a, b) => b.count - a.count);
+ showPodium(allNodes.slice(0, 3), overlay);
+ }
+ });
+ }
}
function sectionHeader(title, subtitle, color) {
@@ -211,6 +230,126 @@ function buildTable(packages, status) {
return html;
}
+// Internal: builds celebratory overlay for top contributors
+function showPodium(top3, overlay) {
+ const existing = document.getElementById("nodes-stats-podium");
+ if (existing) { existing.remove(); return; }
+
+ const colors = ["#FFD700", "#C0C0C0", "#CD7F32"];
+ const heights = [160, 120, 90];
+ const order = [1, 0, 2];
+
+ // SVG characters: champion with cape, cool runner-up, happy bronze
+ const characters = [
+ // Gold: flexing champion with crown and cape
+ `
`,
+ // Silver: sunglasses dude, arms crossed
+ `
`,
+ // Bronze: happy little guy waving
+ `
`,
+ ];
+
+ const podium = document.createElement("div");
+ podium.id = "nodes-stats-podium";
+ podium.style.cssText =
+ "position:absolute;top:0;left:0;width:100%;height:100%;background:radial-gradient(ellipse at center,#1a1a2e 0%,#0a0a12 100%);display:flex;flex-direction:column;align-items:center;justify-content:center;border-radius:8px;z-index:1;cursor:pointer;overflow:hidden;";
+ podium.addEventListener("click", () => podium.remove());
+
+ // Sparkle particles
+ let sparkles = "";
+ for (let i = 0; i < 20; i++) {
+ const x = Math.random() * 100;
+ const y = Math.random() * 60;
+ const d = (1 + Math.random() * 2).toFixed(1);
+ const o = (0.3 + Math.random() * 0.7).toFixed(2);
+ sparkles += `
`;
+ }
+
+ let html = ``;
+ html += sparkles;
+
+ // Trophy title
+ html += `
+
+
Hall of Fame
+
`;
+
+ // Podium blocks
+ html += `
`;
+
+ for (const i of order) {
+ const node = top3[i];
+ if (!node) continue;
+ const isGold = i === 0;
+ const w = isGold ? 170 : 140;
+ const floatDelay = [0, 0.3, 0.6][i];
+
+ html += `
+
${characters[i]}
+
${escapeHtml(node.class_type)}
+
${escapeHtml(node.pkg)}
+
+
${i + 1}${["st","nd","rd"][i]}
+
${node.count.toLocaleString()}x
+
+
`;
+ }
+
+ html += `
`;
+ html += `
click to dismiss
`;
+
+ podium.innerHTML = html;
+ overlay.querySelector("div").style.position = "relative";
+ overlay.querySelector("div").appendChild(podium);
+}
+
function escapeHtml(str) {
const div = document.createElement("div");
div.textContent = str;