const els = { body: document.body, menuBtn: document.getElementById("menuBtn"), sectionSelect: document.getElementById("sectionSelect"), sortSelect: document.getElementById("sortSelect"), searchBox: document.getElementById("searchBox"), postList: document.getElementById("postList"), viewer: document.getElementById("viewer"), content: document.getElementById("content") }; const staticPages = new Set(["about", "contact", "legal"]); let indexData = null; let sidebarOpen = false; async function init() { try { indexData = await (await fetch("index.json")).json(); populateSections(); wireUI(); renderList(); handleHash(); window.addEventListener("hashchange", handleHash); } catch (e) { els.viewer.innerHTML = "
Failed to load site data. Please try refreshing.
"; } } function populateSections() { els.sectionSelect.innerHTML = ""; indexData.sections.forEach(s => { const opt = document.createElement("option"); opt.value = s; opt.textContent = s; els.sectionSelect.appendChild(opt); }); } function wireUI() { els.menuBtn.addEventListener("click", () => { sidebarOpen = !sidebarOpen; document.body.classList.toggle("sidebar-open", sidebarOpen); }); els.sectionSelect.addEventListener("change", renderList); els.sortSelect.addEventListener("change", renderList); els.searchBox.addEventListener("input", renderList); els.content.addEventListener("click", () => { if (window.matchMedia("(max-width:1024px)").matches && document.body.classList.contains("sidebar-open")) { document.body.classList.remove("sidebar-open"); sidebarOpen = false; } }); } function renderList() { const section = els.sectionSelect.value; const sort = els.sortSelect.value; const query = els.searchBox.value.toLowerCase(); let posts = indexData.flat.filter(p => p.path.split('/')[0] === section); if (query) posts = posts.filter(p => p.title.toLowerCase().includes(query)); posts.sort((a, b) => sort === "newest" ? b.mtime - a.mtime : a.mtime - b.mtime); els.postList.innerHTML = ""; for (const p of posts) { const li = document.createElement("li"); const pin = p.pinned ? "★ " : ""; li.innerHTML = `${pin}${p.title}No posts in this section yet.
`; } else { const latest = sectionPosts.sort((a, b) => b.mtime - a.mtime)[0]; location.hash = '#/' + latest.path; // Triggers hashchange to load } } else { els.viewer.innerHTML = 'Failed to load the file. Please try another.
'; } } } async function renderMarkdown(rel) { const src = await fetch(rel).then(r => { if (!r.ok) throw new Error(); return r.text(); }); const html = marked.parse(src); els.viewer.innerHTML = `