SPB Git

spb/modelmap Public License

Internal cartography of local LLMs on Apple Silicon — registered, gated, negative-first. Public atlas at modelmap.io.

Python 66.3% JavaScript 24.5% CSS 8.1% Shell 0.7%
2.2 KB · 59 lines javascript
Raw Blame History
1// ============================================================================2//  Project   : modelmap3//  File      : site/public/app.js4//  Purpose   : Client-side interactivity — mobile menu, chart tooltips5//  Author    : Simon-Pierre Boucher6//  Contact   : contact@spboucher.ai7//  Website   : https://modelmap.io8//  Created   : 2026-08-129//  Modified  : 2026-08-1210//  Platform  : Web (deployed from macOS / Apple Silicon)11//  License   : All rights reserved (research code)12// ============================================================================13"use strict";1415// ---------------------------------------------------------- mobile nav16(function () {17  const btn = document.getElementById("nav-toggle");18  const nav = document.getElementById("site-nav");19  if (!btn || !nav) return;20  btn.addEventListener("click", () => {21    const open = nav.classList.toggle("open");22    btn.setAttribute("aria-expanded", open ? "true" : "false");23  });24  // close when a link is chosen or when tapping outside25  nav.addEventListener("click", (e) => {26    if (e.target.tagName === "A") {27      nav.classList.remove("open");28      btn.setAttribute("aria-expanded", "false");29    }30  });31  document.addEventListener("click", (e) => {32    if (!nav.classList.contains("open")) return;33    if (!nav.contains(e.target) && !btn.contains(e.target)) {34      nav.classList.remove("open");35      btn.setAttribute("aria-expanded", "false");36    }37  });38})();3940// ---------------------------------------------------------- chart tooltips41(function () {42  document.querySelectorAll(".chart-fig").forEach((fig) => {43    const tip = fig.querySelector(".chart-tip");44    if (!tip) return;45    fig.querySelectorAll(".pt").forEach((pt) => {46      pt.addEventListener("mouseenter", () => {47        tip.textContent = pt.getAttribute("data-tip");48        tip.hidden = false;49      });50      pt.addEventListener("mousemove", (ev) => {51        const r = fig.getBoundingClientRect();52        tip.style.left = Math.min(ev.clientX - r.left + 14, r.width - tip.offsetWidth - 4) + "px";53        tip.style.top = ev.clientY - r.top - 34 + "px";54      });55      pt.addEventListener("mouseleave", () => { tip.hidden = true; });56    });57  });58})();59