SPB Git

spb/anomaly-atlas Public License

Systematic discovery & rigorous validation of statistical anomalies in open HF market data (hfmarketdata.io) — pre-registered, artifact-null-driven, fully reproducible. Live atlas: www.anomaly-atlas.io

Python 61.4% JavaScript 28.7% CSS 8.6% Shell 0.7% Makefile 0.5%
8.2 KB · 199 lines javascript
Raw Blame History
1// ============================================================================2//  Project   : anomaly-atlas3//  File      : web/lib/render.js4//  Purpose   : HTML layout, markdown/code rendering for the atlas platform5//  Author    : Simon-Pierre Boucher6//  Contact   : contact@spboucher.ai7//  Data src  : hfmarketdata.io (sole data source)8//  Created   : 2026-08-129//  Modified  : 2026-08-1210//  Platform  : macOS / Apple Silicon (arm64) — Node.js (deployed on MacLustr)11//  License   : All rights reserved (research code)12// ============================================================================13"use strict";1415const { Marked } = require("marked");16const hljs = require("highlight.js");1718function esc(s) {19  return String(s).replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c]));20}2122function slugify(s) {23  return s.toLowerCase().replace(/[^\w\s-]/g, "").trim().replace(/\s+/g, "-").slice(0, 80);24}2526/**27 * Render markdown → { html, toc }. A fresh Marked instance per call (a shared28 * global `marked.use()` would stack walkTokens handlers on every render).29 * Headings get stable anchor ids collected into a table of contents.30 */31function markdownToHtml(md, baseRel) {32  const toc = [];33  const seen = new Set();34  const m = new Marked({35    renderer: {36      code({ text, lang }) {37        const html = lang && hljs.getLanguage(lang)38          ? hljs.highlight(text, { language: lang }).value39          : esc(text);40        return `<pre class="codeblock"><code class="hljs">${html}</code></pre>`;41      },42      heading({ tokens, depth }) {43        const html = this.parser.parseInline(tokens);44        const plain = html.replace(/<[^>]+>/g, "");45        let id = slugify(plain) || "section";46        while (seen.has(id)) id += "-x";47        seen.add(id);48        if (depth >= 2 && depth <= 3) toc.push({ depth, id, text: plain });49        return `<h${depth} id="${id}">${html}<a class="hanchor" href="#${id}" aria-label="Link to section">#</a></h${depth}>\n`;50      },51    },52    walkTokens(token) {53      if (token.type === "link" && token.href && !/^(https?:|mailto:|#|\/)/.test(token.href)) {54        const base = baseRel.includes("/") ? baseRel.slice(0, baseRel.lastIndexOf("/")) : "";55        const joined = (base ? base + "/" : "") + token.href;56        const norm = joined.split("/").reduce((acc, part) => {57          if (part === "..") acc.pop();58          else if (part !== "." && part !== "") acc.push(part);59          return acc;60        }, []).join("/");61        token.href = norm.endsWith(".md") ? "/doc/" + norm : "/file/" + norm;62      }63    },64  });65  return { html: m.parse(md), toc };66}6768/** Sticky table-of-contents sidebar for long documents. */69function tocHtml(toc) {70  if (!toc || toc.length < 3) return "";71  const items = toc72    .map((t) => `<li class="toc-d${t.depth}"><a href="#${t.id}">${esc(t.text)}</a></li>`)73    .join("");74  return `<nav class="toc" aria-label="Table of contents"><span class="toc-title">On this page</span><ul>${items}</ul></nav>`;75}7677/** Professional document header from front matter. */78function docHeader(data, rel) {79  const title = (data.document || rel).split("/").pop().replace(/[_-]/g, " ");80  const status = data.status || "draft";81  const meta = [82    data.created ? `created ${data.created}` : null,83    data.modified ? `updated ${data.modified}` : null,84    data.author || null,85  ].filter(Boolean).join(" · ");86  return `<header class="doc-head">87    <div class="doc-head-row">88      <h1>${esc(title)}</h1>89      <span class="badge badge-${status === "reviewed" || status === "final" ? "done" : "in-progress"}">${esc(status)}</span>90    </div>91    <p class="doc-head-meta">${esc(data.document || rel)}${meta ? " · " + esc(meta) : ""}</p>92  </header>`;93}9495/** Research-log timeline: entries already split by content.parseLogEntries. */96function logTimeline(entries, baseRel) {97  const items = entries98    .slice()99    .reverse()100    .map((e) => {101      const [when, ...rest] = e.title.split(" — ");102      const title = rest.join(" — ") || when;103      const body = markdownToHtml(e.body, baseRel).html;104      return `<article class="tl-entry">105        <div class="tl-rail"><span class="tl-dot"></span></div>106        <div class="tl-card">107          <time class="tl-time">${esc(rest.length ? when : "")}</time>108          <h3>${esc(title)}</h3>109          <div class="md md-compact">${body}</div>110        </div>111      </article>`;112    })113    .join("");114  return `<div class="timeline">${items}</div>`;115}116117function highlightFile(text, filename) {118  const ext = filename.slice(filename.lastIndexOf(".") + 1).toLowerCase();119  const langMap = {120    py: "python", sh: "bash", js: "javascript", css: "css", json: "json",121    toml: "ini", yaml: "yaml", yml: "yaml", cff: "yaml", md: "markdown", sql: "sql",122  };123  const lang = filename === "Makefile" ? "makefile" : langMap[ext];124  if (lang && hljs.getLanguage(lang)) return hljs.highlight(text, { language: lang }).value;125  return esc(text);126}127128/** Confidence-level badge (Levels 0-3, CLAUDE.md §10). */129const LEVEL_LABELS = {130  0: "Level 0 — in-sample only",131  1: "Level 1 — corrected & OOS",132  2: "Level 2 — robust",133  3: "Level 3 — cost-real & held-out",134};135function levelBadge(level) {136  return `<span class="badge badge-level-${level}">${LEVEL_LABELS[level] || "Level ?"}</span>`;137}138139const NAV = [140  ["/", "Home"],141  ["/atlas", "Atlas"],142  ["/publications", "Publications"],143  ["/research", "Research"],144  ["/experiments", "Experiments"],145  ["/results", "Results"],146  ["/code", "Code"],147  ["/comments", "Comments"],148  ["/about", "About"],149];150151function layout({ title, active, body, buildInfo = {} }) {152  const nav = NAV.map(153    ([href, label]) =>154      `<a href="${href}" class="${active === label ? "active" : ""}">${label}</a>`155  ).join("");156  const commit = buildInfo.commit ? buildInfo.commit.slice(0, 7) : "dev";157  const synced = buildInfo.generated ? buildInfo.generated.slice(0, 10) : "";158  return `<!DOCTYPE html>159<html lang="en">160<head>161<meta charset="utf-8">162<meta name="viewport" content="width=device-width, initial-scale=1">163<title>${esc(title)} · anomaly-atlas</title>164<meta name="description" content="anomaly-atlas — systematic discovery & rigorous validation of statistical anomalies in open HF market data (hfmarketdata.io). Research by Simon-Pierre Boucher. Not investment advice.">165<meta name="theme-color" content="#faf8f4">166<link rel="preconnect" href="https://fonts.googleapis.com">167<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>168<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Fraunces:ital,opsz,wght@0,9..144,400..700;1,9..144,400..700&family=Inter:wght@400..700&family=JetBrains+Mono:wght@400..600&display=swap">169<link rel="stylesheet" href="/static/style.css">170<link rel="icon" type="image/svg+xml" href="/static/logo.svg">171<link rel="apple-touch-icon" href="/static/logo.svg">172</head>173<body>174<header class="site-header">175  <div class="wrap header-row">176    <a class="brand" href="/"><img class="brand-mark" src="/static/logo.svg" alt="" width="30" height="30">anomaly<span class="brand-dim">-atlas</span></a>177    <input type="checkbox" id="nav-toggle" class="nav-toggle" aria-label="Open menu">178    <label for="nav-toggle" class="nav-burger" aria-hidden="true"><span></span><span></span><span></span></label>179    <nav class="site-nav">${nav}</nav>180  </div>181</header>182<div class="honesty-banner"><div class="wrap">183  <strong>Honesty doctrine.</strong> Every candidate anomaly is an artifact until proven otherwise;184  in-sample results are never findings; past statistical regularity does not imply future returns.185  This is research on statistical properties of market data — <strong>not investment advice, not a trading system</strong>.186</div></div>187<main class="wrap">${body}</main>188<footer class="site-footer">189  <div class="wrap">190    <span>© 2026 Simon-Pierre Boucher — <a href="mailto:contact@spboucher.ai">contact@spboucher.ai</a> · All rights reserved (research code) · Data source: <a href="https://www.hfmarketdata.io">hfmarketdata.io</a> (sole source)</span>191    <span class="footer-meta">snapshot ${esc(commit)}${synced ? " · synced " + esc(synced) : ""} · not trading advice</span>192  </div>193</footer>194</body>195</html>`;196}197198module.exports = { esc, markdownToHtml, tocHtml, docHeader, logTimeline, highlightFile, layout, levelBadge, LEVEL_LABELS };199