shreyask commited on
Commit
693b1d8
·
verified ·
1 Parent(s): 9f947ba

Big verdict after each round

Browse files
assets/{index-ADYcWVDE.js → index-BUlVfxYS.js} RENAMED
@@ -1,4 +1,4 @@
1
  (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=[`rock`,`paper`,`scissors`],t={rock:`scissors`,paper:`rock`,scissors:`paper`},n=e=>document.getElementById(e),r=new URLSearchParams(location.search),i=r.get(`models`)===`local`?`/models/`:`hub`,a=Number(r.get(`frame`)??384),o=600,s=Number(r.get(`tokens`)??128),c={vision:r.get(`vision`)??`q8`,decoder:r.get(`decoder`)??`q8`},l=.45,u=.1,d={rock:`✊`,paper:`✋`,scissors:`✌️`,none:`·`},f=new Worker(new URL(new URL(`worker-8R7nd9yW.js`,import.meta.url).href,``+import.meta.url),{type:`module`}),p=1,m=new Map,h=null;f.onmessage=e=>{let t=e.data;t.type===`read`?(m.get(t.id)?.(t),m.delete(t.id)):t.type===`error`?v(`d1 failed: ${t.message.split(`
2
- `)[0]}`,!0):h?.(t)};var g=e=>f.postMessage(e);function _(e){let t=p++;return new Promise(n=>{m.set(t,n),g({type:`read`,id:t,frame:e})})}function v(e,t=!1){n(`status`).textContent=e,n(`status`).className=t?`error`:`muted`}function y(){return new Promise(e=>{n(`progress`).hidden=!1,v(`Downloading d1-3B (about 3.8 GB, cached after the first time)…`),h=t=>{t.type===`progress`&&t.total&&(n(`progress`).firstElementChild.style.width=`${100*t.loaded/t.total}%`),t.type===`loaded`&&(n(`progress`).hidden=!0,v(`d1 is ready (${(t.ms/1e3).toFixed(0)} s to load).`),e())},g({type:`load`,source:i,imageTokens:s,dtype:c})})}var b=n(`video`),x=document.createElement(`canvas`);async function S(){b.srcObject=await navigator.mediaDevices.getUserMedia({video:{width:640,height:480,facingMode:`user`},audio:!1}),await b.play(),n(`cam-off`).hidden=!0}function C(){let e=Math.min(1,a/Math.max(b.videoWidth,b.videoHeight)),t=Math.round(b.videoWidth*e),n=Math.round(b.videoHeight*e);x.width=t,x.height=n;let r=x.getContext(`2d`,{willReadFrequently:!0});return r.setTransform(-1,0,0,1,t,0),r.drawImage(b,0,0,t,n),{data:r.getImageData(0,0,t,n).data,width:t,height:n}}function w(t){let r=[...e,`none`].map(e=>`<div class="bar ${e}"><span>${d[e]} ${e}</span><i style="width:${(100*t.probabilities[e]).toFixed(0)}%"></i><b>${(100*t.probabilities[e]).toFixed(0)}%</b></div>`).join(``);n(`meter`).innerHTML=r,n(`read-info`).textContent=`read in ${Math.round(t.ms)} ms · ${t.tokens} tokens`}var T=e=>{let[[t,n],[,r]]=Object.entries(e.probabilities).sort((e,t)=>t[1]-e[1]);return[t,n,n-r]},E=!1;async function D(){for(E=!0;E;)O?await new Promise(e=>setTimeout(e,100)):w(await _(C()))}var O=!1,k=0,A=0,j=0,M=e=>new Promise(t=>setTimeout(t,e));function N(e){n(`card`).className=e?`card up`:`card down`,n(`card-face`).textContent=e?d[e]:`?`}async function P(){if(O)return;O=!0,n(`play`).disabled=!0,n(`result`).textContent=``;let r=e[Math.floor(Math.random()*3)];N(null);let i=n(`beat`);i.hidden=!1;for(let e of[`Rock…`,`Paper…`,`Scissors…`])i.textContent=e,await M(o);i.textContent=`Shoot!`;let a=_(C());i.textContent=`d1 is looking…`;let s=await a;i.hidden=!0,w(s),N(r);let[c,f,p]=T(s);if(c===`none`||f<l||p<u)n(`result`).textContent=`d1 couldn't tell your gesture (${c} ${(100*f).toFixed(0)}%). Replay the round.`;else{j++;let e=c===r?`Draw`:t[c]===r?`You win the round`:`Bot wins the round`;e.startsWith(`You`)&&k++,e.startsWith(`Bot`)&&A++,n(`score-you`).textContent=String(k),n(`score-bot`).textContent=String(A),n(`result`).textContent=`d1 read ${d[c]} ${c} (${(100*f).toFixed(0)}% sure, ${Math.round(s.ms)} ms) vs ${d[r]} ${r}: ${e}.`,(k===3||A===3)&&(n(`result`).textContent+=k===3?` You win the match! 🎉`:` The bot wins the match.`,k=A=j=0),n(`round`).textContent=j?`Round ${j+1}`:`Best of 5`}O=!1,n(`play`).disabled=!1}n(`start`).addEventListener(`click`,async()=>{if(!(`gpu`in navigator))return v(`This needs WebGPU (desktop Chrome or Edge).`,!0);n(`start`).disabled=!0;try{await Promise.all([S(),y()])}catch(e){return n(`start`).disabled=!1,v(`Could not start: ${e.message}`,!0)}n(`start`).hidden=!0,n(`play`).hidden=!1,v(`Show rock, paper or scissors: the bars are d1 reading your hand live. Press Play when ready.`),D()}),n(`play`).addEventListener(`click`,P),r.has(`bench`)&&(async()=>{await y();let t=[];for(let n of[256,384,512])for(let r of[...e,`none`]){let e=new OffscreenCanvas(n,Math.round(n*.75)),i=e.getContext(`2d`);i.fillStyle=`#d9cfc4`,i.fillRect(0,0,e.width,e.height),r!==`none`&&(i.font=`${Math.round(e.height*.6)}px "Apple Color Emoji", "Segoe UI Emoji", sans-serif`,i.textAlign=`center`,i.textBaseline=`middle`,i.fillText(d[r],e.width/2,e.height/2));let a=await _({data:i.getImageData(0,0,e.width,e.height).data,width:e.width,height:e.height}),[o,s]=T(a);t.push(`${n}px ${r} -> ${o} ${(100*s).toFixed(0)}% · ${Math.round(a.ms)} ms · ${a.tokens} tok`)}window.benchOut=t,v(t.join(` | `)),console.log(`[bench]
3
  `+t.join(`
4
  `))})();
 
1
  (function(){let e=document.createElement(`link`).relList;if(e&&e.supports&&e.supports(`modulepreload`))return;for(let e of document.querySelectorAll(`link[rel="modulepreload"]`))n(e);new MutationObserver(e=>{for(let t of e)if(t.type===`childList`)for(let e of t.addedNodes)e.tagName===`LINK`&&e.rel===`modulepreload`&&n(e)}).observe(document,{childList:!0,subtree:!0});function t(e){let t={};return e.integrity&&(t.integrity=e.integrity),e.referrerPolicy&&(t.referrerPolicy=e.referrerPolicy),t.credentials=e.crossOrigin===`use-credentials`?`include`:e.crossOrigin===`anonymous`?`omit`:`same-origin`,t}function n(e){if(e.ep)return;e.ep=!0;let n=t(e);fetch(e.href,n)}})();var e=[`rock`,`paper`,`scissors`],t={rock:`scissors`,paper:`rock`,scissors:`paper`},n=e=>document.getElementById(e),r=new URLSearchParams(location.search),i=r.get(`models`)===`local`?`/models/`:`hub`,a=Number(r.get(`frame`)??384),o=600,s=Number(r.get(`tokens`)??128),c={vision:r.get(`vision`)??`q8`,decoder:r.get(`decoder`)??`q8`},l=.45,u=.1,d={rock:`✊`,paper:`✋`,scissors:`✌️`,none:`·`},f=new Worker(new URL(new URL(`worker-8R7nd9yW.js`,import.meta.url).href,``+import.meta.url),{type:`module`}),p=1,m=new Map,h=null;f.onmessage=e=>{let t=e.data;t.type===`read`?(m.get(t.id)?.(t),m.delete(t.id)):t.type===`error`?v(`d1 failed: ${t.message.split(`
2
+ `)[0]}`,!0):h?.(t)};var g=e=>f.postMessage(e);function _(e){let t=p++;return new Promise(n=>{m.set(t,n),g({type:`read`,id:t,frame:e})})}function v(e,t=!1){n(`status`).textContent=e,n(`status`).className=t?`error`:`muted`}function y(){return new Promise(e=>{n(`progress`).hidden=!1,v(`Downloading d1-3B (about 3.8 GB, cached after the first time)…`),h=t=>{t.type===`progress`&&t.total&&(n(`progress`).firstElementChild.style.width=`${100*t.loaded/t.total}%`),t.type===`loaded`&&(n(`progress`).hidden=!0,v(`d1 is ready (${(t.ms/1e3).toFixed(0)} s to load).`),e())},g({type:`load`,source:i,imageTokens:s,dtype:c})})}var b=n(`video`),x=document.createElement(`canvas`);async function S(){b.srcObject=await navigator.mediaDevices.getUserMedia({video:{width:640,height:480,facingMode:`user`},audio:!1}),await b.play(),n(`cam-off`).hidden=!0}function C(){let e=Math.min(1,a/Math.max(b.videoWidth,b.videoHeight)),t=Math.round(b.videoWidth*e),n=Math.round(b.videoHeight*e);x.width=t,x.height=n;let r=x.getContext(`2d`,{willReadFrequently:!0});return r.setTransform(-1,0,0,1,t,0),r.drawImage(b,0,0,t,n),{data:r.getImageData(0,0,t,n).data,width:t,height:n}}function w(t){let r=[...e,`none`].map(e=>`<div class="bar ${e}"><span>${d[e]} ${e}</span><i style="width:${(100*t.probabilities[e]).toFixed(0)}%"></i><b>${(100*t.probabilities[e]).toFixed(0)}%</b></div>`).join(``);n(`meter`).innerHTML=r,n(`read-info`).textContent=`read in ${Math.round(t.ms)} ms · ${t.tokens} tokens`}var T=e=>{let[[t,n],[,r]]=Object.entries(e.probabilities).sort((e,t)=>t[1]-e[1]);return[t,n,n-r]},E=!1;async function D(){for(E=!0;E;)O?await new Promise(e=>setTimeout(e,100)):w(await _(C()))}var O=!1,k=0,A=0,j=0,M=e=>new Promise(t=>setTimeout(t,e));function N(e){n(`card`).className=e?`card up`:`card down`,n(`card-face`).textContent=e?d[e]:`?`}async function P(){if(O)return;O=!0,n(`play`).disabled=!0,n(`result`).textContent=``;let r=e[Math.floor(Math.random()*3)];N(null);let i=n(`beat`);i.hidden=!1;for(let e of[`Rock…`,`Paper…`,`Scissors…`])i.textContent=e,await M(o);i.textContent=`Shoot!`;let a=_(C());i.textContent=`d1 is looking…`;let s=await a;w(s),N(r);let[c,f,p]=T(s);if(c===`none`||f<l||p<u)n(`result`).textContent=`d1 couldn't tell your gesture (${c} ${(100*f).toFixed(0)}%). Replay the round.`,i.textContent=`Couldn't see that 🤔`;else{j++;let e=c===r?`Draw`:t[c]===r?`You win the round`:`Bot wins the round`;i.innerHTML=`<span class="verdict">${d[c]} vs ${d[r]}<small>${e.replace(` the round`,``)} · ${Math.round(s.ms)} ms</small></span>`,e.startsWith(`You`)&&k++,e.startsWith(`Bot`)&&A++,n(`score-you`).textContent=String(k),n(`score-bot`).textContent=String(A),n(`result`).textContent=`d1 read ${d[c]} ${c} (${(100*f).toFixed(0)}% sure, ${Math.round(s.ms)} ms) vs ${d[r]} ${r}: ${e}.`,(k===3||A===3)&&(n(`result`).textContent+=k===3?` You win the match! 🎉`:` The bot wins the match.`,k=A=j=0),n(`round`).textContent=j?`Round ${j+1}`:`Best of 5`}await M(2200),i.hidden=!0,O=!1,n(`play`).disabled=!1}n(`start`).addEventListener(`click`,async()=>{if(!(`gpu`in navigator))return v(`This needs WebGPU (desktop Chrome or Edge).`,!0);n(`start`).disabled=!0;try{await Promise.all([S(),y()])}catch(e){return n(`start`).disabled=!1,v(`Could not start: ${e.message}`,!0)}n(`start`).hidden=!0,n(`play`).hidden=!1,v(`Show rock, paper or scissors: the bars are d1 reading your hand live. Press Play when ready.`),D()}),n(`play`).addEventListener(`click`,P),r.has(`bench`)&&(async()=>{await y();let t=[];for(let n of[256,384,512])for(let r of[...e,`none`]){let e=new OffscreenCanvas(n,Math.round(n*.75)),i=e.getContext(`2d`);i.fillStyle=`#d9cfc4`,i.fillRect(0,0,e.width,e.height),r!==`none`&&(i.font=`${Math.round(e.height*.6)}px "Apple Color Emoji", "Segoe UI Emoji", sans-serif`,i.textAlign=`center`,i.textBaseline=`middle`,i.fillText(d[r],e.width/2,e.height/2));let a=await _({data:i.getImageData(0,0,e.width,e.height).data,width:e.width,height:e.height}),[o,s]=T(a);t.push(`${n}px ${r} -> ${o} ${(100*s).toFixed(0)}% · ${Math.round(a.ms)} ms · ${a.tokens} tok`)}window.benchOut=t,v(t.join(` | `)),console.log(`[bench]
3
  `+t.join(`
4
  `))})();
assets/{index-xLHcA447.css → index-BX0GKCoJ.css} RENAMED
@@ -1 +1 @@
1
- [hidden]{display:none!important}:root{--bg:#111216;--panel:#1b1d23;--line:#2c2f38;--ink:#eef0f4;--muted:#9aa1ad;--accent:#b18cff;--you:#ffb547;--red:#ff6b6b;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*{box-sizing:border-box}body{background:var(--bg);color:var(--ink);margin:0;font:15px/1.5 system-ui,-apple-system,sans-serif}a{color:var(--accent)}header,main,footer{max-width:980px;margin:0 auto;padding:0 16px}header{padding-top:28px}h1{letter-spacing:-.02em;margin:0 0 6px;font-size:32px}h1 span{color:var(--accent)}header p{color:var(--muted);max-width:680px;margin:0}.muted{color:var(--muted)}.small{font-size:12.5px}.error{color:var(--red)}.stage{grid-template-columns:minmax(0,1.4fr) auto minmax(0,1fr);align-items:start;gap:20px;margin-top:22px;display:grid}.label{text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin-bottom:8px;font-size:12px}.cam{aspect-ratio:4/3;border:1px solid var(--line);background:#000;border-radius:16px;position:relative;overflow:hidden}.cam video{object-fit:cover;width:100%;height:100%;transform:scaleX(-1)}.cam-off{color:var(--muted);place-items:center;display:grid;position:absolute;inset:0}.beat{color:#fff;text-shadow:0 4px 24px #000000b3;background:#00000040;place-items:center;font-size:56px;font-weight:800;display:grid;position:absolute;inset:0}.vs{color:var(--muted);align-self:center;padding-top:40px;font-weight:700}.card{aspect-ratio:3/4;border:1px solid var(--line);border-radius:16px;place-items:center;font-size:96px;transition:transform .35s;display:grid}.card.down{color:#0000;background:repeating-linear-gradient(45deg,#2a2440,#2a2440 10px,#231f36 10px 20px)}.card.up{background:var(--panel);transform:rotateY(360deg)}.meter{gap:6px;margin-top:12px;display:grid}.bar{grid-template-columns:110px 1fr 44px;align-items:center;gap:8px;font-size:13.5px;display:grid;position:relative}.bar i{background:var(--you);border-radius:6px;height:10px;transition:width .2s;display:block}.bar.none i{background:var(--muted)}.bar b{text-align:right;font-variant-numeric:tabular-nums}.controls{flex-wrap:wrap;align-items:center;gap:12px;margin-top:20px;display:flex}button.primary{font:inherit;color:#15121f;background:var(--accent);cursor:pointer;border:0;border-radius:12px;padding:11px 20px;font-weight:600}button.primary:disabled{opacity:.5;cursor:default}.toggle{color:var(--muted);align-items:center;gap:6px;font-size:13.5px;display:flex}.progress{background:var(--panel);border-radius:6px;flex:200px;height:8px;overflow:hidden}.progress>div{background:var(--accent);width:0;height:100%;transition:width .2s}#status{flex-basis:100%}.score{text-align:center;background:var(--panel);border:1px solid var(--line);border-radius:16px;grid-template-columns:1fr auto 1fr;align-items:center;margin-top:22px;padding:14px;display:grid}.score span{font-variant-numeric:tabular-nums;font-size:40px;font-weight:800;display:block}.score small{color:var(--muted);text-transform:uppercase;letter-spacing:.08em;font-size:11px}.round{color:var(--muted)}.result{min-height:24px;margin:14px 0 0;font-size:16px}footer{margin-top:36px;padding-bottom:32px}@media (width<=720px){.stage{grid-template-columns:minmax(0,1fr)}.vs{display:none}.card{aspect-ratio:auto;height:160px;font-size:72px}}
 
1
+ [hidden]{display:none!important}:root{--bg:#111216;--panel:#1b1d23;--line:#2c2f38;--ink:#eef0f4;--muted:#9aa1ad;--accent:#b18cff;--you:#ffb547;--red:#ff6b6b;--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}*{box-sizing:border-box}body{background:var(--bg);color:var(--ink);margin:0;font:15px/1.5 system-ui,-apple-system,sans-serif}a{color:var(--accent)}header,main,footer{max-width:980px;margin:0 auto;padding:0 16px}header{padding-top:28px}h1{letter-spacing:-.02em;margin:0 0 6px;font-size:32px}h1 span{color:var(--accent)}header p{color:var(--muted);max-width:680px;margin:0}.muted{color:var(--muted)}.small{font-size:12.5px}.error{color:var(--red)}.stage{grid-template-columns:minmax(0,1.4fr) auto minmax(0,1fr);align-items:start;gap:20px;margin-top:22px;display:grid}.label{text-transform:uppercase;letter-spacing:.08em;color:var(--muted);margin-bottom:8px;font-size:12px}.cam{aspect-ratio:4/3;border:1px solid var(--line);background:#000;border-radius:16px;position:relative;overflow:hidden}.cam video{object-fit:cover;width:100%;height:100%;transform:scaleX(-1)}.cam-off{color:var(--muted);place-items:center;display:grid;position:absolute;inset:0}.beat{color:#fff;text-shadow:0 4px 24px #000000b3;background:#00000040;place-items:center;font-size:56px;font-weight:800;display:grid;position:absolute;inset:0}.vs{color:var(--muted);align-self:center;padding-top:40px;font-weight:700}.card{aspect-ratio:3/4;border:1px solid var(--line);border-radius:16px;place-items:center;font-size:96px;transition:transform .35s;display:grid}.card.down{color:#0000;background:repeating-linear-gradient(45deg,#2a2440,#2a2440 10px,#231f36 10px 20px)}.card.up{background:var(--panel);transform:rotateY(360deg)}.meter{gap:6px;margin-top:12px;display:grid}.bar{grid-template-columns:110px 1fr 44px;align-items:center;gap:8px;font-size:13.5px;display:grid;position:relative}.bar i{background:var(--you);border-radius:6px;height:10px;transition:width .2s;display:block}.bar.none i{background:var(--muted)}.bar b{text-align:right;font-variant-numeric:tabular-nums}.controls{flex-wrap:wrap;align-items:center;gap:12px;margin-top:20px;display:flex}button.primary{font:inherit;color:#15121f;background:var(--accent);cursor:pointer;border:0;border-radius:12px;padding:11px 20px;font-weight:600}button.primary:disabled{opacity:.5;cursor:default}.toggle{color:var(--muted);align-items:center;gap:6px;font-size:13.5px;display:flex}.progress{background:var(--panel);border-radius:6px;flex:200px;height:8px;overflow:hidden}.progress>div{background:var(--accent);width:0;height:100%;transition:width .2s}#status{flex-basis:100%}.score{text-align:center;background:var(--panel);border:1px solid var(--line);border-radius:16px;grid-template-columns:1fr auto 1fr;align-items:center;margin-top:22px;padding:14px;display:grid}.score span{font-variant-numeric:tabular-nums;font-size:40px;font-weight:800;display:block}.score small{color:var(--muted);text-transform:uppercase;letter-spacing:.08em;font-size:11px}.round{color:var(--muted)}.result{min-height:24px;margin:14px 0 0;font-size:16px}footer{margin-top:36px;padding-bottom:32px}@media (width<=720px){.stage{grid-template-columns:minmax(0,1fr)}.vs{display:none}.card{aspect-ratio:auto;height:160px;font-size:72px}}.verdict{justify-items:center;gap:6px;font-size:64px;display:grid}.verdict small{font-size:26px;font-weight:700}
index.html CHANGED
@@ -6,8 +6,8 @@
6
  <title>Rock, Paper, d1</title>
7
  <meta name="description" content="Rock, Paper, Scissors where Liquid AI's d1-3B reads your hand from the webcam, on your GPU. Nothing leaves the page." />
8
  <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 16 16%22%3E%3Ctext y=%2213%22 font-size=%2213%22%3E%E2%9C%8A%3C/text%3E%3C/svg%3E" />
9
- <script type="module" crossorigin src="./assets/index-ADYcWVDE.js"></script>
10
- <link rel="stylesheet" crossorigin href="./assets/index-xLHcA447.css">
11
  </head>
12
  <body>
13
  <header>
 
6
  <title>Rock, Paper, d1</title>
7
  <meta name="description" content="Rock, Paper, Scissors where Liquid AI's d1-3B reads your hand from the webcam, on your GPU. Nothing leaves the page." />
8
  <link rel="icon" href="data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 16 16%22%3E%3Ctext y=%2213%22 font-size=%2213%22%3E%E2%9C%8A%3C/text%3E%3C/svg%3E" />
9
+ <script type="module" crossorigin src="./assets/index-BUlVfxYS.js"></script>
10
+ <link rel="stylesheet" crossorigin href="./assets/index-BX0GKCoJ.css">
11
  </head>
12
  <body>
13
  <header>