PageSourceSearch

https://clawedcode.github.io/assets/CipherWheel-C5knHSKf.js

js clawedcode.github.io collected 2026-10-03 08:49:11 UTC 9,512 bytes, 1 lines download raw bytes

1import{r as o,j as n}from"./index-_Sg_1KT6.js";import{u as be}from"./useCanvas-DRXw8nFR.js";import{E as ve}from"./ExperimentControls-DmwC3FZh.js";import{E as ke}from"./ExperimentMetrics-D-l2z47K.js";import{E as je}from"./ExperimentNav-CPfQyQAJ.js";const c="ABCDEFGHIJKLMNOPQRSTUVWXYZ".split(""),A=Math.PI*2,k=c.map((g,d)=>d/c.length*A-Math.PI/2),we=[{id:"encode",label:"mode.encode()"},{id:"decode",label:"mode.decode()"}],_=g=>{const d=c.length;return(g%d+d)%d},J=()=>{const g=[...c];for(let d=g.length-1;d>0;d--){const S=Math.floor(Math.random()*(d+1)),t=g[d];g[d]=g[S],g[S]=t}return g},Se=({category:g,experiment:d})=>{const{canvasRef:S,ctx:t,dimensions:N}=be(),[v,Q]=o.useState("encode"),[R,F]=o.useState(""),[Z,V]=o.useState(""),[O,j]=o.useState("∴ align cipher rings • press transmit() to weave text ∴"),[P,ee]=o.useState(!0),[y,te]=o.useState(0),[z,D]=o.useState(0),[K,W]=o.useState(0),[X,se]=o.useState(0),[Y,B]=o.useState([]),[ne,$]=o.useState("∅"),C=o.useRef(0),w=o.useRef(J()),M=o.useRef([]),E=o.useCallback(e=>{const r=_(e);C.current=r,te(r)},[]);o.useEffect(()=>{const e=w.current;let r=0;for(let l=0;l<c.length;l++)e[(l+C.current)%c.length]===c[l]&&r++;se(r)},[y,K]);const oe=o.useCallback(()=>{ee(e=>(j(e?"∴ auto advance muted ∴":"∴ auto advance engaged ∴"),!e))},[]),re=o.useCallback(()=>{const e=[...w.current],r=Math.floor(Math.random()*e.length);let l=Math.floor(Math.random()*e.length);r===l&&(l=(l+5)%e.length);const f=e[r];e[r]=e[l],e[l]=f,w.current=e,W(a=>a+1),j(`∴ swapped ${e[r]} ↔ ${e[l]} ∴`)},[]),ae=o.useCallback(()=>{w.current=J(),W(e=>e+1),j("∴ outer ring re scrambled • sigils anew ∴")},[]),le=o.useCallback(()=>{M.current=[],D(0),F(""),V(""),B([]),$("∅"),j("∴ slate wiped • awaiting next transmission ∴")},[]),L=o.useCallback(e=>{B(r=>[e,...r].slice(0,6))},[]),ie=o.useCallback(e=>{F(e.target.value)},[]),q=o.useCallback(e=>{E(C.current+e),j(e>0?"∴ rotor advanced clockwise ∴":"∴ rotor drifted counterclockwise ∴")},[E]),I=o.useCallback(()=>{const e=R;if(!e.trim()){j("∴ provide glyphs before transmit() ∴");return}const r=w.current;let l=C.current,f="";const a=[],u=performance.now();for(let p=0;p<e.length;p++){const s=e[p],m=s.toUpperCase(),h=c.indexOf(m);if(h===-1){f+=s;continue}if(v==="encode"){const i=h,x=(i+l)%c.length,b=r[x];f+=b,a.push({id:`${u}-${p}`,slot:i,patternIndex:x,slotAngle:k[i],patternAngle:k[x],direction:"encode",char:m,output:b,time:u+p*6})}else{const i=r.indexOf(m);if(i===-1){f+=s;continue}const x=_(i-l),b=c[x];f+=b,a.push({id:`${u}-${p}`,slot:x,patternIndex:i,slotAngle:k[x],patternAngle:k[i],direction:"decode",char:m,output:b,time:u+p*6})}P&&(l=(l+1)%c.length)}if(a.length>0){const p=M.current.slice(Math.max(0,M.current.length-40+a.length));M.current=[...p,...a],D(M.current.length);const s=a[a.length-1];$(`${s.char}→${s.output}`)}else $("∅");V(f),L({id:u,input:e,output:f,mode:v}),E(l),j(`∴ ${v==="encode"?"ciphered":"decoded"} ${a.length} glyphs ∴`)},[P,R,L,v,E]),ce=o.useCallback(e=>{e.key==="Enter"&&(e.metaKey||e.ctrlKey)&&(e.preventDefault(),I())},[I]),de=o.useMemo(()=>[{label:"rotor",value:`${c[y]} · ${y.toString().padStart(2,"0")}`},{label:"links",value:z},{label:"align",value:X},{label:"mode",value:v==="encode"?"encode":"decode",color:v==="encode"?"#66ffcc":"#ff9bd5"}],[y,z,X,v]),me=[{id:"shift-back",label:"shift(-1)",onClick:()=>q(-1)},{id:"shift-forward",label:"shift(+1)",onClick:()=>q(1)},{id:"mutate",label:"ring.swap()",onClick:re},{id:"scramble",label:"ring.scramble()",onClick:ae},{id:"auto",label:"auto.advance()",onClick:oe,active:P},{id:"clear",label:"clear()",onClick:le,variant:"reset"}],H=o.useCallback(()=>{if(!t||N.width===0)return;const{width:e,height:r,centerX:l,centerY:f}=N;t.fillStyle="rgba(0, 3, 9, 0.25)",t.fillRect(0,0,e,r);const a=Math.min(e,r)*.36,u=a*.64;t.save(),t.translate(l,f),t.strokeStyle="rgba(102, 255, 204, 0.12)",t.lineWidth=1,t.beginPath(),t.arc(0,0,a+24,0,A),t.stroke(),t.beginPath(),t.arc(0,0,u-36,0,A),t.stroke();for(let s=0;s<k.length;s++){const m=k[s],h=Math.cos(m),i=Math.sin(m);t.strokeStyle=s%2===0?"rgba(102, 255, 204, 0.04)":"rgba(102, 255, 204, 0.06)",t.beginPath(),t.moveTo(h*(u-40),i*(u-40)),t.lineTo(h*(a+20),i*(a+20)),t.stroke()}const p=performance.now();M.current.forEach(s=>{const m=p-s.time,h=Math.max(0,1-m/9e3);if(h<=0)return;const i=s.direction==="encode"?s.slotAngle:s.patternAngle,x=s.direction==="encode"?s.patternAngle:s.slotAngle,b=s.direction==="encode"?u:a,T=s.direction==="encode"?a:u,xe=Math.cos(i)*b,ue=Math.sin(i)*b,he=Math.cos(x)*T,ge=Math.sin(x)*T,U=(i+x)/2,G=(b
1+T)/2+(s.direction==="encode"?30:-30),pe=Math.cos(U)*G,fe=Math.sin(U)*G;t.strokeStyle=`hsla(${s.patternIndex*13%360}, 80%, 70%, ${.4*h})`,t.lineWidth=1+h,t.beginPath(),t.moveTo(xe,ue),t.quadraticCurveTo(pe,fe,he,ge),t.stroke()}),t.strokeStyle="rgba(102, 255, 204, 0.3)",t.lineWidth=1.5,t.beginPath(),t.arc(0,0,a,0,A),t.stroke(),t.beginPath(),t.arc(0,0,u,0,A),t.stroke(),t.font='11px "SF Mono", Monaco, monospace',t.textAlign="center",t.textBaseline="middle";for(let s=0;s<c.length;s++){const m=k[s],h=Math.cos(m),i=Math.sin(m),x=w.current[(s+C.current)%c.length]===c[s];t.fillStyle=x?"rgba(255, 214, 102, 0.9)":"rgba(102, 255, 204, 0.75)",t.fillText(c[s],h*(u-16),i*(u-16))}for(let s=0;s<c.length;s++){const m=k[s],h=Math.cos(m),i=Math.sin(m),x=w.current[(s+C.current)%c.length];t.fillStyle="rgba(102, 255, 204, 0.8)",t.fillText(x,h*(a+8),i*(a+8))}t.restore()},[t,N,K,y]);return o.useEffect(()=>{if(!t||N.width===0)return;let e;const r=()=>{H(),e=requestAnimationFrame(r)};return e=requestAnimationFrame(r),()=>cancelAnimationFrame(e)},[t,N.width,H]),n.jsxs("div",{className:"fixed inset-0 flex flex-col",children:[n.jsxs("header",{className:"relative z-50 flex items-center justify-between p-2 sm:p-4 border-b border-void-green/20 bg-void-dark/80 backdrop-blur-sm",children:[n.jsxs("div",{className:"flex items-center gap-2 sm:gap-4",children:[n.jsx(je,{currentCategory:g.slug,currentExperiment:d.slug}),n.jsx("h1",{className:"text-base sm:text-xl text-glow hidden sm:block",style:{color:d.color},children:d.name})]}),n.jsx(ke,{metrics:de})]}),n.jsxs("div",{className:"flex flex-col gap-2 sm:gap-3 p-2 sm:p-4 border-b border-void-green/10 bg-void-dark/60 backdrop-blur-sm",children:[n.jsxs("div",{className:"flex flex-col sm:flex-row items-start sm:items-center justify-between gap-2 sm:gap-3",children:[n.jsx(ve,{modes:we,currentMode:v,onModeChange:Q,controls:me}),n.jsx("p",{className:"text-void-green/50 text-[10px] sm:text-xs sm:text-right max-w-lg hidden sm:block",children:O})]}),n.jsxs("div",{className:"flex flex-col sm:flex-row gap-2 sm:gap-3 text-xs font-mono",children:[n.jsxs("div",{className:"flex-1 flex flex-col gap-1 sm:gap-2",children:[n.jsx("label",{className:"text-void-green/50 text-[10px] sm:text-xs",children:"input.glyphs()"}),n.jsx("textarea",{value:R,onChange:ie,onKeyDown:ce,placeholder:"type plaintext or cipher text...",className:"min-h-[60
1px] sm:min-h-[80px] bg-void-dark/70 border border-void-green/30 px-2 sm:px-3 py-2 text-sm sm:text-xs text-void-green/80 focus:border-void-green/60 focus:outline-none resize-none","data-testid":"cipher-input"}),n.jsxs("div",{className:"flex gap-2 items-center",children:[n.jsx("button",{onClick:I,className:"min-h-[44px] px-4 sm:px-3 py-2 sm:py-1 bg-void-green/10 border border-void-green/30 text-void-green hover:bg-void-green/20 active:bg-void-green/30 transition-colors text-sm sm:text-xs","data-testid":"cipher-transmit",children:"transmit()"}),n.jsx("div",{className:"text-void-green/40 flex items-center text-[10px] sm:text-[11px] hidden sm:flex",children:"⌘↵ / ctrl↵"})]})]}),n.jsxs("div",{className:"flex-1 flex flex-col gap-1 sm:gap-2",children:[n.jsx("label",{className:"text-void-green/50 text-[10px] sm:text-xs",children:"output.stream()"}),n.jsx("textarea",{value:Z,readOnly:!0,className:"min-h-[60px] sm:min-h-[80px] bg-void-dark/40 border border-void-green/30 px-2 sm:px-3 py-2 text-sm sm:text-xs text-void-cyan/80 focus:outline-none resize-none","data-testid":"cipher-output"}),n.jsxs("div",{className:"text-void-green/40 text-[10px] sm:text-[11px] flex items-center justify-between",children:[n.jsxs("span",{children:["last: ",ne]}),n.jsxs("span",{className:"sm:hidden text-void-green/30",children:[O.slice(0,30),"..."]})]})]}),n.jsxs("div",{className:"hidden lg:block lg:w-48 border border-void-green/20 bg-void-dark/80 p-3 space-y-2 max-h-[140px] overflow-y-auto",children:[n.jsx("div",{className:"text-void-green/50",children:"// transmit.log()"}),Y.length===0&&n.jsx("div",{className:"text-void-green/30",children:"awaiting first signal..."}),Y.map(e=>n.jsxs("div",{className:"text-void-green/70",children:[n.jsx("div",{className:"text-[10px] uppercase tracking-widest text-void-green/40",children:e.mode}),n.jsx("div",{children:e.output})]},e.id))]})]})]}),n.jsxs("div",{className:"flex-1 min-h-0 relative bg-void-dark",children:[n.jsx("canvas",{ref:S,className:"absolute inset-0 w-full h-full touch-none","data-testid":"cipher-wheel-canvas"}),n.jsxs("div",{className:"absolute bottom-2 sm:bottom-4 left-2 sm:left-4 right-2 sm:right-auto text-void-green/60 text-[10px] sm:text-xs font-mono bg-void-dark/80 border border-void-green/20 rounded px-2 sm:px-3 py-1 text-center sm:text-left",children:[n.jsx("span",{className:"hidden sm:inline",children:"slot alignment shifts with rotor • watch the arcs braid modes"}),n.jsx("span",{className:"sm:hidden",children:"tap controls above • rotate the cipher wheel"})]})]})]})};export{Se as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.