// Basic Markdown renderer function renderMarkdown(md) { let html = md .replace(/&/g, "&") .replace(//g, ">") .replace(/^### (.*$)/gim, "

$1

") .replace(/^## (.*$)/gim, "

$1

") .replace(/^# (.*$)/gim, "

$1

") .replace(/\*\*\*(.*?)\*\*\*/g, "$1") .replace(/\*\*(.*?)\*\*/g, "$1") .replace(/\*(.*?)\*/g, "$1") .replace(/___(.*?)___/g, "$1") .replace(/__(.*?)__/g, "$1") .replace(/_(.*?)_/g, "$1") .replace(/```([\s\S]*?)```/g, "
$1
") .replace(/`([^`]+)`/g, "$1") .replace(/^> (.*$)/gim, "
$1
") .replace(/^\s*-\s+(.*$)/gim, "
  • $1
  • ") .replace(/^\s*\d+\.\s+(.*$)/gim, "
  • $1
  • ") .replace( /\[([^\]]+)\]\(([^)]+)\)/g, '$1', ) .replace(/!\[([^\]]*)\]\(([^)]+)\)/g, '$1') .replace(/^---$/gim, "
    ") .replace(/\n/g, "
    "); html = html.replace(/(
  • .*?<\/li>(?:
  • .*?<\/li>)*)/gs, (match) => { const clean = match.replace(/
    /g, ""); return ``; }); return html; } // Parallax for post hero function initPostParallax() { const hero = document.getElementById("post-hero"); if (!hero) return; function update() { const rect = hero.getBoundingClientRect(); const yPos = -(rect.top * 0.4); hero.style.backgroundPositionY = `${yPos}px`; } window.addEventListener("scroll", update, { passive: true }); update(); } // Load post hero image from posts.json head_img, fallback to random backdrop async function loadPostHero(filename) { try { // Try to find the post metadata const response = await fetch("/api/posts.json"); const posts = await response.json(); const post = posts.find((p) => p.file === filename); const hero = document.getElementById("post-hero"); if (!hero) return; if (post && post.head_img) { hero.style.backgroundImage = `url('/assets/${post.head_img}')`; } else { // Fallback to random backdrop const bdResponse = await fetch("/api/backdrops.json"); const backdrops = await response.json(); const random = backdrops[Math.floor(Math.random() * backdrops.length)]; hero.style.backgroundImage = `url('/assets/${random.name}.png')`; } initPostParallax(); } catch (err) { console.error("Failed to load post hero:", err); } } // Load post content async function loadPostContent() { const pathParts = window.location.pathname.split("/"); const filename = pathParts[pathParts.length - 1]; if (!filename) return; loadPostHero(filename); try { const response = await fetch(`/api/post/${filename}`); const md = await response.text(); let contentMd = md; const titleMatch = md.match(/^#\s+(.+)$/m); if (titleMatch) { document.title = `${titleMatch[1]} - Anarchy Phase`; const titleEl = document.getElementById("post-title"); if (titleEl) titleEl.textContent = titleMatch[1]; contentMd = md.replace(/^#\s+.+$/m, "").trim(); } const container = document.getElementById("post-body"); if (container) { container.innerHTML = renderMarkdown(contentMd); } } catch (err) { console.error("Failed to load post:", err); const container = document.getElementById("post-body"); if (container) container.innerHTML = '

    Failed to load post content.

    '; } } document.addEventListener("DOMContentLoaded", () => { loadPostContent(); });