`).join("");
$("cres").style.display="block";
$("ccap").innerHTML=`${d.n_pairs} of your facts stored in ${d.T.toLocaleString()} tokens of your text`+
(d.n_upd?`, ${d.n_upd} overwritten mid-stream`:"")+` · recall ${d.acc} · ${d.us_per_token} μs/token`+
` · key ids: `+Object.entries(d.keymap).slice(0,4).map(([n,k])=>`${esc(n)}=${k}`).join(", ")+`…`;
}catch(e){alert(e)}$("runc").disabled=false;$("runc").textContent="Read, store, overwrite — and answer"};
/* section 02 */
$("np").oninput=e=>$("npv").textContent=e.target.value;
$("fl").oninput=e=>$("flv").textContent=e.target.value;
$("ow").oninput=e=>$("owv").textContent=e.target.value+"%";
function drawLatt(pts,sc){const c=$("latt"),x=c.getContext("2d");
c.width=c.clientWidth*2;c.height=560;x.scale(2,2);const W=c.width/2,H=280;
x.fillStyle="#fff";x.fillRect(0,0,W,H);
x.strokeStyle="#eceef2";for(let i=0;i<=8;i++){const p=i/8;
x.beginPath();x.moveTo(p*W,0);x.lineTo(p*W,H);x.stroke();
x.beginPath();x.moveTo(0,p*H);x.lineTo(W,p*H);x.stroke()}
x.fillStyle="#2547d0";for(const p of pts){const u=(p[0]/sc+1)/2,v=(p[1]/sc+1)/2;
x.beginPath();x.arc(u*W,v*H,1.7,0,7);x.fill()}}
$("run").onclick=async()=>{$("run").disabled=true;$("run").textContent="streaming…";
try{const d=await api("/api/store",{n_pairs:+$("np").value,filler:+$("fl").value,
overwrite_frac:+$("ow").value/100,seed:(Math.random()*1e6)|0});
$("meta").textContent=`capacity8k.pt · scale ${d.scale} · ${d.params.toLocaleString()} params · ${d.device} · run ${d.ts}`;
stats($("st"),d);drawLatt(d.addr_points,d.scale);
$("qr").innerHTML=`
query key
answered
true
`+
d.rows.map(r=>`
${r.key}
${r.pred}
`+
`
${r.gold}
`+
`
${r.updated?'overwritten':""}${r.ok?"":" ✗"}
`).join("");
}catch(e){alert(e)}$("run").disabled=false;$("run").textContent="stream & query"};
/* section 03 */
function drawCC(data){const c=$("cc"),x=c.getContext("2d");c.width=c.clientWidth*2;c.height=600;
x.scale(2,2);const W=c.width/2,H=300,P=48;
const maxT=Math.max(...data.map(d=>d.T)),us=data.map(d=>d.us_per_token),
ce=data.map(d=>d.cells),maxU=Math.max(...us)*1.25,maxC=Math.max(...ce)*1.15,
maxA=Math.max(...data.map(d=>d.flops_attention_equiv));
const X=t=>P+(Math.log(t)/Math.log(maxT))*(W-P-16),
Y=u=>H-30-(u/maxU)*(H-56),Y2=v=>H-30-(v/maxC)*(H-56),YA=v=>H-30-(v/maxA)*(H-56);
x.fillStyle="#fff";x.fillRect(0,0,W,H);x.strokeStyle="#eceef2";x.fillStyle="#6b7280";
x.font="11px -apple-system,sans-serif";
for(let i=0;i<=4;i++){const px=P+(i/4)*(W-P-16);x.beginPath();x.moveTo(px,20);x.lineTo(px,H-30);x.stroke()}
x.strokeStyle="#c2413b";x.setLineDash([6,5]);x.beginPath();let f1=true;
for(const d of data){const px=X(d.T),py=YA(d.flops_attention_equiv);
f1?x.moveTo(px,py):x.lineTo(px,py);f1=false}x.stroke();x.setLineDash([]);
x.strokeStyle="#2547d0";x.lineWidth=2.4;x.beginPath();f1=true;
for(const d of data){const px=X(d.T),py=Y(d.us_per_token);f1?x.moveTo(px,py):x.lineTo(px,py);f1=false}
x.stroke();
x.strokeStyle="#0e8a5f";x.lineWidth=2.4;x.beginPath();f1=true;
for(const d of data){const px=X(d.T),py=Y2(d.cells);f1?x.moveTo(px,py):x.lineTo(px,py);f1=false}
x.stroke();x.lineWidth=1;
for(const d of data){x.fillStyle="#2547d0";x.beginPath();x.arc(X(d.T),Y(d.us_per_token),3.4,0,7);x.fill();
x.fillStyle="#0e8a5f";x.beginPath();x.arc(X(d.T),Y2(d.cells),3.4,0,7);x.fill()}
x.fillStyle="#6b7280";
for(const d of data)x.fillText(d.T.toLocaleString(),X(d.T)-16,H-14);
x.fillText("stream length (tokens, log scale)",W/2-80,H-2);
x.fillText("μs/token (blue, flat = constant) · cells (green) · attention O(T²) (dashed red)",P,16)}
$("cost").onclick=async()=>{$("cost").disabled=true;$("cost").textContent="measuring…";
try{const sizes=[64,256,1024,2048,4096,8192].map(n=>({n_pairs:n,filler:14}));
const d=await api("/api/cost",{sizes});drawCC(d)}catch(e){alert(e)}
$("cost").disabled=false;$("cost").textContent="measure the cost curve"};
/* section 04 */
$("cv").onclick=async()=>{$("cv").disabled=true;
try{const d=await api("/api/cellview",{name:$("cvn").value.trim()||"key",
value:$("cvv").value.trim()||"v1",new_value:$("cvnv").value.trim(),seed:(Math.random()*1e6)|0});
if(d.error){alert(d.error);return}
const inv={[d.vid]:d.value};inv[d.nid]=d.new_value||d.value;
$("cvs").innerHTML=`
(${d.addr[0]}, ${d.addr[1]})learned address
${esc(inv[d.answers.before] ?? "—")}stored & retrieved before
${esc(d.answers.after!==null?inv[d.answers.after]:"—")}after overwrite, same cells
key id ${d.kid} → address on grid scale ${d.scale};
the write lands as W ← αW + β(vnew − αWκ)κT:
the old association is subtracted out, the new one takes its place — nothing is appended.