// Open Interest — live chrome (clock, fleet pulse, ticker from baked data) (async function () { const $ = (s) => document.querySelector(s); let data = { fleet: { online: null, enrolled: null }, events: [], updated: null }; try { data = await (await fetch("/data.json?x=" + Date.now())).json(); } catch (e) { try { data = await (await fetch("data.json?x=" + Date.now())).json(); } catch (e2) {} } // ticker from baked OI events const tin = $(".ticker-in"); if (tin && data.events && data.events.length) { const spans = data.events.map((t) => `${t}`).join(""); tin.innerHTML = spans + spans; } // live fleet pulse: the one CORS-open endpoint, else baked numbers let online = data.fleet.online; try { const r = await fetch("https://api.imd.fun/steps/hourly"); if (r.ok) { const d = await r.json(); if (d && d.online) online = d.online; } } catch (e) {} // ticking meta line let synced = 0; const meta = $("#livemeta"); function render() { if (!meta) return; const o = online ? Number(online).toLocaleString("en-US") : "—"; meta.innerHTML = `swarm ${o} online · synced ${synced === 0 ? "just now" : synced + "s ago"}▮`; } render(); setInterval(() => { synced++; if (synced > 9 + Math.random() * 4) synced = 0; render(); }, 1000); })(); document.addEventListener('click', function (e) { const el = e.target.closest('[data-soon]'); if (!el) return; e.preventDefault(); const old = document.querySelector('.oi-toast'); if (old) old.remove(); const t = document.createElement('div'); t.className = 'oi-toast'; t.innerHTML = 'coming soon · ' + el.getAttribute('data-soon'); document.body.appendChild(t); setTimeout(() => t.remove(), 3500); });