File indexing completed on 2026-10-20 08:47:05
0001 const esc = s => String(s ?? "").replace(/[&<>"]/g, c => ({"&":"&","<":"<",">":">",'"':"""}[c]));
0002 const link = u => /^https?:\/\//.test(u || "") ? `<a href="${esc(u)}">${esc(u)}</a>` : "";
0003 let pkgs = [];
0004 const $ = id => document.getElementById(id);
0005
0006 function card(p) {
0007 const vs = p.versions.slice(0, 8).map(v => v.version + (v.deprecated ? " (deprecated)" : "")).join(", ");
0008 const variants = Object.entries(p.variants).map(([n, v]) =>
0009 `<tr><td><code>${esc(n)}</code></td><td>${esc(v.default)}</td><td>${esc(v.description)}</td></tr>`).join("");
0010 return `<div class="card" id="${esc(p.name)}"><h3>${esc(p.name)}</h3>
0011 <div class="muted">${esc(p.description)}</div>
0012 <div>${p.tags.map(t => `<span class="tag">${esc(t)}</span>`).join("")}</div>
0013 <div class="muted">Versions: ${esc(vs) || "none"}${p.versions.length > 8 ? ", …" : ""}</div>
0014 <details><summary>Details</summary>
0015 ${p.homepage ? `<p>Homepage: ${link(p.homepage)}</p>` : ""}
0016 ${p.maintainers.length ? `<p>Maintainers: ${p.maintainers.map(m => `<a href="https://github.com/${esc(m)}">@${esc(m)}</a>`).join(", ")}</p>` : ""}
0017 ${p.builtin_base ? `<p class="muted">Extends builtin package ${esc(p.builtin_base)}.</p>` : ""}
0018 ${variants ? `<table><tr><th>Variant</th><th>Default</th><th>Description</th></tr>${variants}</table>` : ""}
0019 ${p.dependencies.length ? `<p>Depends on: ${p.dependencies.map(esc).join(", ")}</p>` : ""}
0020 </details></div>`;
0021 }
0022
0023 function render() {
0024 const q = $("q").value.toLowerCase(), tag = $("tag").value;
0025 const hits = pkgs.filter(p => (!tag || p.tags.includes(tag)) &&
0026 (!q || [p.name, p.description, ...p.maintainers, ...Object.keys(p.variants)].join(" ").toLowerCase().includes(q)));
0027 $("status").textContent = `${hits.length} of ${pkgs.length} packages`;
0028 $("list").innerHTML = hits.map(card).join("");
0029 }
0030
0031 fetch("data/packages.json").then(r => r.json()).then(d => {
0032 pkgs = d.packages;
0033 const tags = [...new Set(pkgs.flatMap(p => p.tags))].sort();
0034 $("tag").innerHTML += tags.map(t => `<option>${esc(t)}</option>`).join("");
0035 $("q").addEventListener("input", render);
0036 $("tag").addEventListener("change", render);
0037 render();
0038 if (location.hash) document.getElementById(decodeURIComponent(location.hash.slice(1)))?.querySelector("details")?.setAttribute("open", "");
0039 }).catch(() => { $("status").textContent = "Could not load package data."; });