(async function () { "use strict"; const manifest = await fetch("logbook.json", { cache: "no-store" }).then(r => r.json()); const nodes = [manifest.root].concat(manifest.root.children || []); const nav = document.getElementById("nav"); const content = document.getElementById("content"); function inline(text) { return text .replace(/&/g, "&").replace(//g, ">") .replace(/`([^`]+)`/g, "$1") .replace(/\*\*([^*]+)\*\*/g, "$1"); } function markdown(source) { const lines = source.split("\n"); let html = "", paragraph = [], i = 0; const flush = () => { if (paragraph.length) { html += `

${inline(paragraph.join(" "))}

`; paragraph = []; } }; while (i < lines.length) { const line = lines[i], t = line.trim(); if (!t) { flush(); i++; continue; } if (t.startsWith("```")) { flush(); const body = []; i++; while (i < lines.length && !lines[i].trim().startsWith("```")) body.push(lines[i++]); html += `
${inline(body.join("\n"))}
`; i++; continue; } const h = t.match(/^(#{1,3})\s+(.*)$/); if (h) { flush(); html += `${inline(h[2])}`; i++; continue; } if (t.startsWith("> ")) { flush(); html += `
${inline(t.slice(2))}
`; i++; continue; } if (t.startsWith("- ")) { flush(); const items = []; while (i < lines.length && lines[i].trim().startsWith("- ")) items.push(`
  • ${inline(lines[i++].trim().slice(2))}
  • `); html += ``; continue; } if (t.startsWith("|") && i + 1 < lines.length && lines[i + 1].includes("---")) { flush(); const rows = []; while (i < lines.length && lines[i].trim().startsWith("|")) rows.push(lines[i++].trim().slice(1, -1).split("|").map(x => x.trim())); const head = rows[0], body = rows.slice(2); html += `${head.map(x => ``).join("")}${body.map(row => `${row.map(x => ``).join("")}`).join("")}
    ${inline(x)}
    ${inline(x)}
    `; continue; } paragraph.push(t); i++; } flush(); return html; } async function show(node) { document.querySelectorAll("nav a").forEach(a => a.classList.toggle("active", a.dataset.slug === node.slug)); const text = await fetch(node.file, { cache: "no-store" }).then(r => r.text()); content.innerHTML = markdown(text); history.replaceState(null, "", `#${node.slug}`); window.scrollTo(0, 0); } nodes.forEach(node => { const link = document.createElement("a"); link.href = `#${node.slug}`; link.dataset.slug = node.slug; link.textContent = node.title; link.onclick = event => { event.preventDefault(); show(node); }; nav.appendChild(link); }); const initial = nodes.find(node => `#${node.slug}` === location.hash) || manifest.root; await show(initial); })();