File size: 108,600 Bytes
f6f0269
1
2
(()=>{var _e=class{actions=0;started;endElapsed=null;end="";now;constructor(n=()=>performance.now()){this.now=n,this.started=n()}elapsed(){return this.endElapsed??Math.max(0,(this.now()-this.started)/1e3)}remaining(){return Math.max(0,720-this.elapsed())}ending(){return!this.end&&this.elapsed()>=720&&this.finish("time_budget",720),this.end}recordAction(n){return this.ending()?!1:(this.actions++,n>=6?this.finish("won"):this.actions>=512&&this.finish("action_budget"),!0)}finish(n,t=this.elapsed()){this.end=n,this.endElapsed=t}};function g(e){return structuredClone(e)}function ke(e){let n=e>>>0;return()=>{n+=1831565813;let t=n;return t=Math.imul(t^t>>>15,t|1),t^=t+Math.imul(t^t>>>7,t|61),((t^t>>>14)>>>0)/4294967296}}function C(e,n,t=0){return Array.from({length:n},()=>Array(e).fill(t))}function f(e,n,t){return{x:n,y:t,button:e}}var P=[{x:0,y:-1},{x:1,y:0},{x:0,y:1},{x:-1,y:0}],M=(e,n)=>(e%n+n)%n,O=(e,n)=>e.x>=0&&e.y>=0&&e.x<n&&e.y<n,qe=(e,n)=>JSON.stringify(e)===JSON.stringify(n),Z=e=>e.x+","+e.y,x=(e,n)=>e.x===n.x&&e.y===n.y,T=(e,n)=>f(6,e+1,n+1),pe=e=>({x:(e.x??-100)-1,y:(e.y??-100)-1}),I=e=>e.map(n=>f(n));function w(e,n,t){e[n.y]&&n.x>=0&&n.x<e[0].length&&(e[n.y][n.x]=t)}function Kt(e,n){let t=Math.max(e.length,n.length)+2,r=e[0].length+n[0].length+5,o=C(r,t);for(let a=0;a<t;a++)for(let i=0;i<r;i++)(a===0||a===t-1||i===0||i===e[0].length+1||i===e[0].length+3||i===r-1)&&(o[a][i]=1);for(let a=0;a<e.length;a++)for(let i=0;i<e[0].length;i++)o[a+1][i+1]=e[a][i];for(let a=0;a<n.length;a++)for(let i=0;i<n[0].length;i++)o[a+1][i+e[0].length+4]=n[a][i];return o}function B(e,n){let t=e.map(r=>r.slice());return t.push(Array(e[0].length).fill(0)),t.push(Array.from({length:e[0].length},(r,o)=>n[o]??0)),t}function $(e){let n=e.objective??e.view,t=(o,a,i)=>{let l=g(o);return e.move(l,a,i),l},r={id:e.id,name:e.name,family:"spatial",version:"1.0.0",levels:6,mechanics:e.mechanics,stateVariables:e.variables,novelty:e.novelty,init(o,a){if(!Number.isInteger(o)||o<1||o>6)throw Error("level must be 1..6");let i=ke((a^Number(e.id.slice(1))*7919^o*104729)>>>0);for(let l=0;l<24;l++){let c=e.initial(o,i),s=g(c),u=[];if(e.recipe)for(let E of e.recipe(s,o,i))s=t(s,E,o),u.push(E);else for(let E=0;E<9+o*4;E++){let re=e.choices(s,o).filter(Le=>Le.button!==e.undo),we=Math.floor(i()*re.length),nt;for(let Le=0;Le<re.length;Le++){let ht=re[(we+Le)%re.length],gt=t(s,ht,o);if(!qe(s,gt)){nt=ht,s=gt;break}}nt&&u.push(nt)}let h=n(s,o);if(!qe(n(c,o),h)&&(!e.targetValid||e.targetValid(c,s,o))){let E=g(c),re=u.length;for(let we=0;we<u.length;we++)if(E=t(E,u[we],o),qe(n(E,o),h)){re=we+1;break}return{state:{level:o,d:c,goal:h,past:[]},witness:u.slice(0,re)}}}throw Error(e.id+" failed constructive generation")},observe(o){return{pixels:Kt(e.view(o.d,o.level),o.goal),actions:e.controls?.(o.level)??[1,2,3,4,5,6],level:o.level,status:r.solved(o)?"won":"playing"}},step(o,a){if(r.solved(o))return g(o);if(!(e.controls?.(o.level)??[1,2,3,4,5,6]).includes(a.button)||a.button===6&&(a.x!==void 0&&!Number.isInteger(a.x)||a.y!==void 0&&!Number.isInteger(a.y)))return g(o);let l=g(o);if(a.button===e.undo){let s=l.past.pop();return s&&(l.d=s),l}let c=t(l.d,a,l.level);return qe(c,l.d)||(e.undo&&l.past.push(g(l.d)),l.d=c),l},solved(o){return qe(n(o.d,o.level),o.goal)}};return r}function Zt(e,n=9){return e<3?[]:e<5?[{x:4,y:4}]:[{x:4,y:4},{x:2,y:5},{x:6,y:3}]}function Ae(e,n){let t=C(e,e);return n.forEach(r=>w(t,r,1)),t}function De(e,n,t,r="sel"){if(n.button===6){let o=pe(n),a=t.findIndex(i=>x(o,i));a>=0&&(e[r]=a)}}function Ge(e){return e.shape.map(t=>{let r=t.x,o=t.y;for(let a=0;a<e.r;a++)[r,o]=[-o,r];return{x:e.x+r,y:e.y+o}})}function pt(e){let n=Ae(9,e.walls);return e.pieces.forEach((t,r)=>Ge(t).forEach(o=>w(n,o,3+r*3))),n}var en=$({id:"a001",name:"Pivot cargo",mechanics:["rigid translation","pivot rotation","obstacle collision","multiple-body blocking"],variables:["piece poses","selected body","fixed obstacles"],novelty:"Rotating a non-point body changes its occupied cells and the routes available to other bodies.",initial(e,n){return{sel:0,walls:Zt(e),pieces:[{x:2,y:2,r:Math.floor(n()*4),shape:e<2?[{x:0,y:0},{x:1,y:0}]:[{x:0,y:0},{x:1,y:0},{x:0,y:1}]},...e>=4?[{x:6,y:6,r:0,shape:e<6?[{x:0,y:0},{x:0,y:1}]:[{x:0,y:0},{x:1,y:0},{x:1,y:1}]}]:[]]}},move(e,n,t){if(n.button===6){let i=pe(n),l=e.pieces.findIndex(c=>Ge(c).some(s=>x(s,i)));l>=0&&(e.sel=l);return}let r=e.pieces[e.sel],o=g(r);n.button<=4?(r.x+=P[n.button-1].x,r.y+=P[n.button-1].y):n.button===5&&t>=2&&(r.r=M(r.r+1,4));let a=[...e.walls,...e.pieces.flatMap((i,l)=>l===e.sel?[]:Ge(i))];Ge(r).some(i=>!O(i,9)||a.some(l=>x(i,l)))&&(e.pieces[e.sel]=o)},objective:pt,view(e){return B(pt(e),[3+e.sel*3])},choices(e,n){return[...I(n<2?[1,2,3,4]:[1,2,3,4,5]),...e.pieces.map(t=>T(t.x,t.y))]},controls:e=>e<2?[1,2,3,4,6]:[1,2,3,4,5,6]});function vt(e){let n=Ae(9,e.walls);return e.points.forEach((t,r)=>w(n,t,3+r*4)),x(e.points[0],e.points[1])&&w(n,e.points[0],12),n}var tn=$({id:"a002",name:"Mirrored twins",mechanics:["reflected coupled displacement","movable reference axis","independent collision cancellation","active twin selection"],variables:["two positions","reflection axis","selected twin","obstacles"],novelty:"One input causes opposite signed displacement in another body; later the two motions may be independently blocked.",initial(e){return{points:[{x:2,y:2},{x:6,y:6}],axis:e===1?0:1,sel:0,walls:e>=3?[{x:3,y:4},{x:5,y:4},...e>=5?[{x:4,y:2},{x:4,y:6}]:[]]:[]}},move(e,n,t){if(n.button===6&&t>=4){De(e,n,e.points);return}if(n.button===5&&t>=2){e.axis=M(e.axis+1,t>=6?4:2);return}if(n.button>4)return;let r=P[n.button-1],o=e.axis===0?{x:-r.x,y:r.y}:e.axis===1?{x:r.x,y:-r.y}:e.axis===2?{x:r.y,y:r.x}:{x:-r.y,y:-r.x},a=e.sel===0?[r,o]:[o,r],i=e.points.map((c,s)=>({x:c.x+a[s].x,y:c.y+a[s].y})),l=i.map(c=>O(c,9)&&!e.walls.some(s=>x(c,s)));if(!(t<3&&!l.every(Boolean)))for(let c=0;c<2;c++)l[c]&&(e.points[c]=i[c])},objective:vt,view(e){let n=vt(e);return x(e.points[0],e.points[1])&&w(n,e.points[0],12),B(n,[3+e.sel*4,0,...[0,1,2,3].map(t=>e.axis===t?9:1)])},choices(e,n){return[...I(n>=2?[1,2,3,4,5]:[1,2,3,4]),...n>=4?e.points.map(t=>T(t.x,t.y)):[]]},controls:e=>e===1?[1,2,3,4]:e<4?[1,2,3,4,5]:[1,2,3,4,5,6]});function bt(e){return e.cells.map(n=>n.slice())}var nn=$({id:"a003",name:"Row column loom",mechanics:["cyclic row shift","cyclic column shift","whole-board transpose","checkerboard anchored cells","linked neighboring strips"],variables:["colored matrix","selected intersection","anchor mask"],novelty:"A row operation changes future column membership; high levels add fixed cells and opposite neighboring-strip motion.",initial(e,n){let r=C(5,5);for(let o=0;o<5;o++)for(let a=0;a<5;a++)r[o][a]=2+Math.floor(n()*5);return{cells:r,sel:{x:2,y:2},anchors:e>=4?[{x:0,y:0},{x:4,y:4}]:[]}},move(e,n,t){if(n.button===6){let l=pe(n);O(l,5)&&(e.sel=l);return}if(n.button===5&&t>=3){e.cells=e.cells[0].map((l,c)=>e.cells.map(s=>s[c]));return}if(n.button>4)return;let r=n.button<=2,o=r?e.sel.y:e.sel.x,a=n.button===1||n.button===3?-1:1,i=(l,c)=>{let s=Array.from({length:5},(h,E)=>r?{x:E,y:l}:{x:l,y:E}).filter(h=>!e.anchors.some(E=>x(h,E))),u=s.map(h=>e.cells[h.y][h.x]);s.forEach((h,E)=>e.cells[h.y][h.x]=u[M(E-c,s.length)])};i(o,a),t>=5&&i(M(o+(t===6?2:1),5),-a)},objective:bt,view(e){return B(bt(e),[e.sel.x+2,e.sel.y+2,...e.anchors.map(()=>1)])},choices(e,n){return[...I(n>=3?[1,2,3,4,5]:n===1?[1,2]:[1,2,3,4]),...Array.from({length:5},(t,r)=>T(r,M(r+2,5)))]},controls:e=>e===1?[1,2,6]:e===2?[1,2,3,4,6]:[1,2,3,4,5,6]});function Pe(e,n,t,r,o){let a=Array.from({length:r},(i,l)=>e[t+l].slice(n,n+r));for(let i=0;i<r;i++)for(let l=0;l<r;l++)e[t+i][n+l]=o>0?a[r-1-l][i]:a[l][r-1-i]}var rn=$({id:"a004",name:"Overlapping turntables",mechanics:["overlapping sub-board rotations","opposite rotation direction","linked opposite window","central interleaving rotation"],variables:["mosaic","rotation direction","linked mode"],novelty:"Rotating intersecting windows moves tiles across both axes and creates noncommuting local permutations.",initial(e,n){return{cells:Array.from({length:7},()=>Array.from({length:7},()=>2+Math.floor(n()*5))),sign:1,linked:!1}},move(e,n,t){if(n.button===5&&t>=2){e.sign=-e.sign;return}if(n.button===6){if(t===6&&n.x===void 0){Pe(e.cells,2,2,3,e.sign);return}t>=4&&(e.linked=!e.linked);return}if(n.button>4||n.button>2&&t===1)return;let r=[[0,0],[3,0],[3,3],[0,3]],o=n.button-1;Pe(e.cells,...r[o],4,e.sign),t>=4&&e.linked&&Pe(e.cells,...r[(o+2)%4],4,t>=5?-e.sign:e.sign)},objective:e=>e.cells,view(e){return B(e.cells,[e.sign>0?8:9,e.linked?11:1])},choices(e,n){return[...I(n===1?[1,2]:n<3?[1,2,5]:n<4?[1,2,3,4,5]:[1,2,3,4,5,6]),...n===6?[T(0,0)]:[]]},controls:e=>e===1?[1,2]:e===2?[1,2,5]:e===3?[1,2,3,4,5]:[1,2,3,4,5,6]});function yt(e){let n=Ae(9,e.walls);e.pads.forEach(r=>w(n,r,r.kind===1?10:11)),w(n,e.p,3);let t=P[e.dir];return w(n,{x:e.p.x+t.x,y:e.p.y+t.y},e.hand===1?6:7),e.cargo.forEach(r=>w(n,r,12)),n}var on=$({id:"a005",name:"Local frame rover",mechanics:["egocentric forward reverse","heading rotation","turntable floor","reflection floor","trail cargo exchange"],variables:["rover position","heading","handedness","cargo","floor transformations"],novelty:"The same forward input has different world displacement after rotation/reflection pads; cargo can only be exchanged from the body-relative rear.",initial(e){return{p:{x:2,y:2},dir:1,hand:1,walls:e>=3?[{x:4,y:3},{x:4,y:5}]:[],pads:e>=2?[{x:4,y:2,kind:1},...e>=4?[{x:2,y:4,kind:2}]:[]]:[],cargo:e>=5?[{x:1,y:2},...e>=6?[{x:6,y:6}]:[]]:[]}},move(e,n,t){if(n.button===3||n.button===4){e.dir=M(e.dir+(n.button===3?-1:1)*e.hand,4);return}if(n.button===5&&t>=5){let l=P[e.dir],c={x:e.p.x-l.x,y:e.p.y-l.y};if(!O(c,9)||e.walls.some(u=>x(u,c)))return;let s=e.cargo.findIndex(u=>x(u,c));s>=0&&(e.cargo.splice(s,1),e.cargo.push({...e.p}),e.p=c);return}if(n.button===6&&t>=6){e.hand=-e.hand;return}if(n.button>2)return;let r=P[e.dir],o=n.button===1?1:-1,a={x:e.p.x+r.x*o,y:e.p.y+r.y*o};if(!O(a,9)||e.walls.some(l=>x(a,l))||e.cargo.some(l=>x(a,l)))return;e.p=a;let i=e.pads.find(l=>x(a,l));i?.kind===1&&(e.dir=M(e.dir+1,4)),i?.kind===2&&(e.hand=-e.hand,e.dir=M(-e.dir,4))},objective:yt,view(e){return B(yt(e),[e.hand===1?6:7])},choices(e,n){return I(n<5?[1,2,3,4]:n<6?[1,2,3,4,5]:[1,2,3,4,5,6])},controls:e=>e<5?[1,2,3,4]:e<6?[1,2,3,4,5]:[1,2,3,4,5,6]});function xt(e,n){return(n===1?[{x:0,y:0}]:n<4?[{x:0,y:0},{x:1,y:0}]:[{x:0,y:0},{x:1,y:0},{x:0,y:1}]).map(r=>{let o=r.x,a=r.y;for(let i=0;i<e.r;i++)[o,a]=[-a,o];return{x:M(e.p.x+o,7),y:M(e.p.y+a,7)}})}var an=$({id:"a006",name:"Parity stencil",mechanics:["XOR stamping","stencil translation","stencil rotation","wrapped support","two-channel ink"],variables:["ink board","stencil location","rotation","active ink channel"],novelty:"A second overlapping stamp erases existing ink; matching a target requires reasoning about parity rather than transporting objects.",initial(){return{cells:C(7,7),p:{x:3,y:3},r:0,ink:2}},move(e,n,t){if(n.button<=4){let r=P[n.button-1],o={x:e.p.x+r.x,y:e.p.y+r.y};t>=3&&(o.x=M(o.x,7),o.y=M(o.y,7)),O(o,7)&&(e.p=o)}else n.button===5?xt(e,t).forEach(r=>{e.cells[r.y][r.x]^=e.ink,t===6&&(e.cells[6-r.y][6-r.x]^=e.ink===2?4:2)}):n.button===6&&(t>=5&&n.x!==void 0?e.ink=e.ink===2?4:2:t>=2&&(e.r=M(e.r+1,4)))},objective:e=>e.cells.map(n=>n.map(t=>t===0?0:t===2?3:t===4?6:9)),view(e,n){let t=e.cells.map(r=>r.map(o=>o===0?0:o===2?3:o===4?6:9));return xt(e,n).forEach(r=>{t[r.y][r.x]===0&&(t[r.y][r.x]=1)}),B(t,[e.ink===2?3:6,e.r+2])},choices(e,n){return[...I(n===1?[1,2,3,4,5]:[1,2,3,4,5,6]),...n>=5?[T(e.p.x,e.p.y)]:[]]},controls:e=>e===1?[1,2,3,4,5]:[1,2,3,4,5,6]});function wt(e){let n=Ae(9,e.walls);return e.brakes.forEach(t=>w(n,t,10)),e.tokens.forEach((t,r)=>w(n,t,3+r*3)),n}var ln=$({id:"a007",name:"Inertial docks",mechanics:["slide until collision","movable token as stopper","brake cells","wrapped edge lanes","undo"],variables:["token positions","selection","walls","brakes"],novelty:"A token can stop only at collisions/brakes; arranging another token creates a new stopping location.",initial(e){return{tokens:[{x:2,y:2},...e>=2?[{x:6,y:6}]:[],...e>=5?[{x:2,y:6}]:[]],sel:0,walls:[{x:4,y:4},...e>=3?[{x:4,y:1},{x:4,y:7}]:[]],brakes:e>=4?[{x:2,y:4},{x:6,y:4}]:[]}},move(e,n,t){if(n.button===6){De(e,n,e.tokens);return}if(n.button>4)return;let r=P[n.button-1],o=e.tokens[e.sel],a={...o},i=new Set([Z(o)]);for(let l=0;l<18;l++){let c={x:o.x+r.x,y:o.y+r.y};if(t===6&&(c={x:M(c.x,9),y:M(c.y,9)}),i.has(Z(c))){Object.assign(o,a);break}if(!O(c,9)||e.walls.some(s=>x(c,s))||e.tokens.some((s,u)=>u!==e.sel&&x(c,s))||(Object.assign(o,c),i.add(Z(c)),e.brakes.some(s=>x(o,s))))break}},objective:wt,view(e){return B(wt(e),[3+e.sel*3])},choices:e=>[...I([1,2,3,4]),...e.tokens.map(n=>T(n.x,n.y))],undo:5});function kt(e){let n=Ae(8,e.walls);return e.gateOpen?e.gates.forEach(t=>w(n,t,1)):e.gates.forEach(t=>w(n,t,11)),e.tokens.forEach(t=>w(n,t,t.c)),n}var cn=$({id:"a008",name:"Split gravity",mechanics:["global simultaneous settling","particle collision","opposed material gravity","switchable shutter","sticky floor","undo"],variables:["colored particles","gate state","fixed walls","sticky cells"],novelty:"Every particle moves under a global field; later materials fall in opposite directions and gates change their joint packing.",initial(e){return{tokens:[{x:2,y:2,c:3},{x:5,y:4,c:6},...e>=2?[{x:2,y:5,c:3}]:[],...e>=5?[{x:5,y:2,c:6}]:[]],walls:e>=2?[{x:3,y:3},{x:4,y:3}]:[],gates:e>=4?[{x:3,y:5},{x:4,y:5}]:[],gateOpen:!1,sticky:e>=6?[{x:1,y:1},{x:6,y:6}]:[]}},move(e,n,t){if(n.button===6&&t>=4){if(e.gates.some(o=>e.tokens.some(a=>x(a,o))))return;e.gateOpen=!e.gateOpen;return}if(n.button>4)return;let r=P[n.button-1];for(let o=0;o<16;o++){let a=!1,i=e.tokens.map((l,c)=>({p:l,i:c})).sort((l,c)=>c.p.x*r.x+c.p.y*r.y-(l.p.x*r.x+l.p.y*r.y));for(let{p:l}of i){if(e.sticky.some(u=>x(l,u)))continue;let c=t>=3&&l.c===6?-1:1,s={x:l.x+r.x*c,y:l.y+r.y*c};!O(s,8)||e.walls.some(u=>x(s,u))||!e.gateOpen&&e.gates.some(u=>x(s,u))||e.tokens.some(u=>u!==l&&x(s,u))||(Object.assign(l,s),a=!0)}if(!a)break}},objective:kt,view(e){let n=kt(e);return e.sticky.forEach(t=>{n[t.y][t.x]===0&&w(n,t,10)}),B(n,[e.gateOpen?11:1])},choices:(e,n)=>I(n>=4?[1,2,3,4,6]:[1,2,3,4]),undo:5,controls:e=>e<4?[1,2,3,4,5]:[1,2,3,4,5,6]});function At(e,n){let t=n===1?1:n===6?3:2,r=C(t*6-1,4);for(let o=0;o<t;o++)for(let a=0;a<5;a++)for(let i=1;i<=3;i++){let c=Array.from({length:5},(s,u)=>o===0?{x:a,y:u}:o===1?{x:u,y:a}:{x:a,y:4-u}).find(s=>e.heights[s.y][s.x]>=i);c&&(r[3-i][o*6+a]=n>=4?e.material[c.y][c.x]:3)}return r}var sn=$({id:"a009",name:"Orthogonal silhouettes",mechanics:["finite cube inventory","height editing","two orthogonal projections","view rotation","colored occlusion","supported construction"],variables:["height field","material field","cube bank","selection"],novelty:"Completion is equality of occluding projections, not equality of the underlying sculpture; depth and inventory create underdetermined spatial constraints.",initial(e){return{heights:[[0,0,0,0,0],[0,1,0,0,0],[0,0,2,0,0],[0,0,0,1,0],[0,0,0,0,0]],material:Array.from({length:5},(n,t)=>Array.from({length:5},(r,o)=>e>=4&&(o+t)%2?6:3)),bank:9,sel:{x:2,y:2}}},move(e,n,t){if(n.button===6){let a=pe(n);O(a,5)&&(e.sel=a);return}if((n.button===1||n.button===2)&&t>=3){Pe(e.heights,0,0,5,n.button===1?1:-1),Pe(e.material,0,0,5,n.button===1?1:-1);return}let{x:r,y:o}=e.sel;if(n.button===3&&e.bank>0&&e.heights[o][r]<3){let a=e.heights[o][r];if(t>=5&&a>0&&!P.some(i=>O({x:r+i.x,y:o+i.y},5)&&e.heights[o+i.y][r+i.x]>=a))return;e.heights[o][r]++,e.bank--}n.button===4&&e.heights[o][r]>0&&(e.heights[o][r]--,e.bank++),n.button===5&&t>=4&&(e.material[o][r]=e.material[o][r]===3?6:3,t===6&&(e.material[4-o][4-r]=e.material[4-o][4-r]===3?6:3))},objective:At,view(e,n){let t=C(11,8);for(let r=0;r<5;r++)for(let o=0;o<5;o++)t[r][o]=e.heights[r][o]===0?0:2+e.heights[r][o],t[r][o+6]=e.material[r][o];for(let r=0;r<e.bank;r++)t[6+Math.floor(r/11)][r%11]=8;return B(t,[e.sel.x+2,e.sel.y+2,0,...At(e,n)[0].slice(0,5)])},choices(e,n){return[...I(n<3?[3,4]:n<4?[1,2,3,4]:[1,2,3,4,5]),...Array.from({length:25},(t,r)=>T(r%5,Math.floor(r/5)))]},controls:e=>e<3?[3,4,6]:e===3?[1,2,3,4,6]:[1,2,3,4,5,6]}),rt=(e,n)=>Math.abs(e.x-n.x)+Math.abs(e.y-n.y);function $e(e){return e.routed?rt(e.nodes[0],e.peg)+rt(e.nodes[1],e.peg):rt(e.nodes[0],e.nodes[1])}function St(e){let n=Ae(9,e.walls),t=(r,o)=>{let a={...r};for(let i=0;i<18&&!x(a,o);i++)a.x!==o.x?a.x+=Math.sign(o.x-a.x):a.y+=Math.sign(o.y-a.y),n[a.y][a.x]===0&&w(n,a,2)};return e.routed?(t(e.nodes[0],e.peg),t(e.nodes[1],e.peg)):t(e.nodes[0],e.nodes[1]),e.peg&&w(n,e.peg,e.routed?10:11),e.nodes.forEach((r,o)=>w(n,r,3+o*3)),n}var un=$({id:"a010",name:"Tension and pulley",mechanics:["slack cable","passive endpoint dragging","fixed pulley routing","route disengagement","movable pulley","undo"],variables:["two endpoints","cable capacity","pulley position","route engagement","selection"],novelty:"Pulling one endpoint can move a different object; routing through a pulley changes the direction of that transferred motion.",initial(e){return{nodes:[{x:2,y:4},{x:6,y:4}],sel:0,length:e<3?4:6,peg:e>=3?{x:4,y:4}:null,routed:e>=3,walls:e>=5?[{x:3,y:2},{x:5,y:6}]:[]}},move(e,n,t){if(n.button===6){let i=pe(n);if(e.peg&&x(i,e.peg)){t>=6?e.sel=2:t>=4&&(e.routed=!e.routed,$e(e)>e.length&&(e.routed=!e.routed));return}t>=2&&De(e,n,e.nodes);return}if(n.button>4)return;let r=g(e),o=P[n.button-1],a=e.sel===2?e.peg:e.nodes[e.sel];if(a.x+=o.x,a.y+=o.y,!O(a,9)||e.walls.some(i=>x(a,i))){Object.assign(e,r);return}for(let i=0;i<20&&$e(e)>e.length;i++){let l=e.nodes[e.sel===0?1:0],c=e.routed?e.peg:e.nodes[e.sel],s=c.x-l.x,u=c.y-l.y;if(Math.abs(s)>=Math.abs(u)&&s)l.x+=Math.sign(s);else if(u)l.y+=Math.sign(u);else break;if(e.walls.some(h=>x(l,h))){Object.assign(e,r);return}}($e(e)>e.length||x(e.nodes[0],e.nodes[1]))&&Object.assign(e,r)},objective:St,view(e){return B(St(e),[e.sel===2?10:3+e.sel*3,...Array(e.length-$e(e)).fill(8)])},choices(e,n){return[...I([1,2,3,4]),...n>=2?e.nodes.map(t=>T(t.x,t.y)):[],...n>=4?[T(e.peg.x,e.peg.y)]:[]]},undo:5}),dn=(e,n)=>Z(e)<Z(n)?Z(e)+"|"+Z(n):Z(n)+"|"+Z(e);function ot(e){return e.split("|").map(n=>{let[t,r]=n.split(",").map(Number);return{x:t,y:r}})}function Mt(e){let n=C(8,8);for(let t=0;t<2;t++){let r=Object.keys(e.edges[t]),o={};if(r.forEach(a=>ot(a).forEach(i=>o[Z(i)]=(o[Z(i)]??0)+1)),!Object.values(o).some(a=>a%2))for(let a=0;a<8;a++)for(let i=0;i<8;i++)r.filter(c=>{let[s,u]=ot(c);return s.x===u.x&&s.x>i&&Math.min(s.y,u.y)===a}).length%2&&(n[a][i]|=t===0?1:2)}return n.map(t=>t.map(r=>[0,3,6,9][r]))}var fn=$({id:"a011",name:"Enclosed regions",mechanics:["edge drawing and erasure","closed-loop interior","pen lifting","reflected dual pen","two-layer region overlap"],variables:["edge sets","pen position","pen engagement","reflection mode","ink layer","blocked vertices"],novelty:"The goal concerns the regions enclosed by a planar edge graph; arbitrary open strokes cannot satisfy it, even when they pass through target cells.",initial(e){return{p:{x:1,y:1},down:!0,mirror:e>=4,ink:0,edges:[{},{}],blocked:e>=3?[{x:4,y:4}]:[]}},move(e,n,t){if(n.button===5&&t>=2){e.down=!e.down;return}if(n.button===6&&t>=4){t===6&&n.x!==void 0?e.ink=1-e.ink:e.mirror=!e.mirror;return}if(n.button>4)return;let r=P[n.button-1],o={x:e.p.x+r.x,y:e.p.y+r.y};if(!O(o,9)||e.blocked.some(i=>x(i,o)))return;let a=[[e.p,o]];if(e.mirror&&a.push([{x:8-e.p.x,y:e.p.y},{x:8-o.x,y:o.y}]),e.down)for(let[i,l]of a){let c=dn(i,l);e.edges[e.ink][c]?delete e.edges[e.ink][c]:e.edges[e.ink][c]=1}e.p=o},objective:Mt,view(e){let n=C(17,17),t=Mt(e);for(let r=0;r<8;r++)for(let o=0;o<8;o++)n[2*r+1][2*o+1]=t[r][o];for(let r=0;r<2;r++)for(let o of Object.keys(e.edges[r])){let[a,i]=ot(o);n[a.y+i.y][a.x+i.x]=r===0?3:6,n[a.y*2][a.x*2]=r===0?3:6,n[i.y*2][i.x*2]=r===0?3:6}return e.blocked.forEach(r=>w(n,{x:r.x*2,y:r.y*2},1)),w(n,{x:e.p.x*2,y:e.p.y*2},12),B(n,[e.down?3:1,e.mirror?10:1,e.ink===0?3:6])},choices:()=>I([1,2,3,4,5,6]),recipe(e,n,t){let r=[],o=(l,c)=>{for(let s=0;s<c;s++)r.push(f(l))},a=n>=3?2:2+Math.floor(t()*3),i=2+Math.floor(t()*3);return o(2,a),o(3,i),o(4,a),o(1,i),n>=5&&(r.push(f(5)),o(3,5),r.push(f(5)),o(2,2),o(3,1),o(4,2),o(1,1)),n===6&&(r.push(f(5)),o(1,4),r.push(f(5),T(0,0)),o(2,2),o(3,2),o(4,2),o(1,2)),r},controls:e=>e===1?[1,2,3,4]:e<4?[1,2,3,4,5]:[1,2,3,4,5,6]});function Et(e){let n=C(9,9),t=e.sources.map(o=>({...o})),r=new Set;for(let o=0;t.length&&o<600;o++){let a=t.shift(),i=[a.x,a.y,a.dir,a.c].join(",");if(r.has(i)||!O(a,9)||e.walls.some(u=>x(a,u)))continue;r.add(i),n[a.y][a.x]=n[a.y][a.x]&&n[a.y][a.x]!==a.c?9:a.c,e.filters.find(u=>x(a,u))&&(a.c=a.c===3?6:3);let c=e.mirrors.find(u=>x(a,u));if(c){let u=c.r===0?[1,0,3,2][a.dir]:[3,2,1,0][a.dir];if(c.split){let h=P[a.dir];t.push({...a,x:a.x+h.x,y:a.y+h.y})}a.dir=u}let s=P[a.dir];t.push({...a,x:a.x+s.x,y:a.y+s.y})}return n}var mn=$({id:"a012",name:"Reflected light field",mechanics:["ray reflection","mirror transport","reflection orientation","beam splitting","color filter","two-source interference"],variables:["mirror positions and orientations","source poses","filters","fixed absorbers","selection"],novelty:"Moving or flipping one mirror changes an entire downstream light path, with branching and color mixing at higher levels.",initial(e,n){let t=e===1?1:e<4?2:3,r=3+Math.floor(n()*2);return{mirrors:[{x:r,y:5,r:0,split:e>=4},{x:r,y:2,r:0,split:!1},{x:7,y:2,r:1,split:!1}].slice(0,t),sel:0,sources:[{x:0,y:4,dir:1,c:3},...e===6?[{x:8,y:1,dir:3,c:6}]:[]],filters:e>=5?[{x:6,y:4}]:[],walls:e>=3?[{x:7,y:1}]:[]}},move(e,n){if(n.button===6){De(e,n,e.mirrors);return}let t=e.mirrors[e.sel];if(n.button===5){t.r=1-t.r;return}if(n.button>4)return;let r=P[n.button-1],o={x:t.x+r.x,y:t.y+r.y};!O(o,9)||e.walls.some(a=>x(a,o))||e.mirrors.some((a,i)=>i!==e.sel&&x(a,o))||e.sources.some(a=>x(a,o))||e.filters.some(a=>x(a,o))||Object.assign(t,o)},objective:Et,view(e){let n=Et(e);return e.walls.forEach(t=>w(n,t,1)),e.mirrors.forEach(t=>w(n,t,t.split?12:t.r===0?10:11)),e.filters.forEach(t=>w(n,t,14)),B(n,[e.sel+2,e.mirrors[e.sel].r===0?10:11])},choices:e=>[...I([1,2,3,4,5]),...e.mirrors.map(n=>T(n.x,n.y))],recipe(e){return e.mirrors.flatMap(n=>[T(n.x,n.y),f(4),f(1)])}});function Be(e){return Ge(e)}function Lt(e,n){let t=C(9,9);for(let r of e.order)for(let o of Be(e.layers[r]))e.blend?t[o.y][o.x]^=1<<r:t[o.y][o.x]=3+r*3;return e.blend?t.map(r=>r.map(o=>o?2+o:0)):t}var hn=$({id:"a013",name:"Transparent depth layers",mechanics:["transparent masks","planar translation","mask rotation","depth ordering","additive bit-plane compositing"],variables:["mask poses","depth permutation","selected layer","compositing mode"],novelty:"Only the visible composite is constrained; the same mask arrangement can change its result solely by changing which layer is in front.",initial(e){let n=e===1?1:e<3?2:3;return{layers:[{x:2,y:2,r:0,shape:[{x:0,y:0},{x:1,y:0},{x:0,y:1}]},{x:3,y:3,r:0,shape:[{x:0,y:0},{x:1,y:0},{x:1,y:1}]},{x:4,y:4,r:0,shape:e>=5?[{x:-1,y:0},{x:1,y:0},{x:0,y:-1},{x:0,y:1}]:[{x:0,y:0},{x:1,y:0},{x:0,y:1}]}].slice(0,n),order:Array.from({length:n},(t,r)=>r),sel:0,blend:!1}},move(e,n,t){if(n.button===6){let a=pe(n);if(t===6&&a.y===10&&a.x<9){e.blend=!e.blend;return}if(a.x>=10){let i=Math.floor((a.x-10)/10);if(i<e.layers.length){if(i===e.sel&&t>=4){let l=e.order.indexOf(i);e.order.splice(l,1),e.order.unshift(i)}e.sel=i}}else{let i=[...e.order].reverse().find(l=>Be(e.layers[l]).some(c=>x(c,a)));i!==void 0&&(e.sel=i)}return}let r=e.layers[e.sel],o=g(r);n.button<=4?(r.x+=P[n.button-1].x,r.y+=P[n.button-1].y):n.button===5&&t>=3&&(r.r=M(r.r+1,4)),Be(r).some(a=>!O(a,9))&&(e.layers[e.sel]=o)},objective:Lt,view(e,n){let t=C(10*(e.layers.length+1)-1,11),r=Lt(e,n);for(let o=0;o<9;o++)for(let a=0;a<9;a++)t[o][a]=r[o][a];return e.layers.forEach((o,a)=>Be(o).forEach(i=>w(t,{x:i.x+10*(a+1),y:i.y},3+a*3))),e.order.forEach((o,a)=>t[10][10+a]=3+o*3),t[10][0]=e.blend?13:1,t[10][3]=3+e.sel*3,t},choices(e,n){return[...I(n>=3?[1,2,3,4,5]:[1,2,3,4]),...e.layers.map((t,r)=>T(10*(r+1)+t.x,t.y)),...n===6?[T(0,10)]:[]]},controls:e=>e<3?[1,2,3,4,6]:[1,2,3,4,5,6]}),Ne=[{x:0,y:-1},{x:1,y:-1},{x:1,y:0},{x:1,y:1},{x:0,y:1},{x:-1,y:1},{x:-1,y:0},{x:-1,y:-1}];function _t(e,n){let t=C(13,13);for(let r=0;r<3;r++){let o=2+r*2;for(let i=0;i<8;i++)w(t,{x:6+Ne[i].x*o,y:6+Ne[i].y*o},1);let a=Ne[e.phases[r]];if(w(t,{x:6+a.x*o,y:6+a.y*o},3+r*3),n>=5){let i=Ne[M(e.phases[r]+3+r,8)];w(t,{x:6+i.x*o,y:6+i.y*o},4+r*3)}}return n>=4&&w(t,{x:6,y:12},11),t}var gn=$({id:"a014",name:"Orbital clutch",mechanics:["ring phase rotation","clutched counterrotation","independent ring drive","blocked detent","intermittent tooth engagement","variable gear ratio"],variables:["three phases","clutch mode","detent location"],novelty:"Inputs act on coupled cyclic coordinates, with gearing, disengagement, and intermittent teeth changing the motion transferred to other rings.",targetValid:(e,n,t)=>t<6||n.phases.filter((r,o)=>r!==e.phases[o]).length>=2,initial(){return{phases:[0,2,6],clutch:0}},move(e,n,t){if(n.button===5&&t>=2){e.clutch=M(e.clutch+1,t===6?3:2);return}let r=e.phases.slice(),o=n.button<=2?0:n.button<=4?1:n.button===6?2:-1;if(o<0||o===1&&t<3||o===2&&t<4)return;let a=n.button===2||n.button===4||n.button===6&&n.x!==void 0?-1:1;e.phases[o]=M(e.phases[o]+a,8),e.clutch&&o<2&&((t<5||Math.min(r[o],e.phases[o])%2===0)&&(e.phases[o+1]=M(e.phases[o+1]-a*(e.clutch===2?2:1),8)),o===0&&t>=3&&e.clutch===2&&(e.phases[2]=M(e.phases[2]+a,8))),t>=4&&e.phases[2]===4&&(e.phases=r)},objective:_t,view(e,n){return B(_t(e,n),[e.clutch===0?1:e.clutch===1?10:14])},choices(e,n){return[...I(n===1?[1,2]:n===2?[1,2,5]:n===3?[1,2,3,4,5]:[1,2,3,4,5,6]),...n>=4?[T(0,0)]:[]]},controls:e=>e===1?[1,2]:e===2?[1,2,5]:e===3?[1,2,3,4,5]:[1,2,3,4,5,6]});function qt(e){let n=C(21,21);return e.walls.forEach(t=>{for(let r=0;r<3;r++)for(let o=0;o<3;o++)w(n,{x:t.x*3+o,y:t.y*3+r},1)}),e.units.forEach((t,r)=>{let o={x:t.x*3+1,y:t.y*3+1},a=P[t.dir];w(n,o,3+r*3),w(n,{x:o.x+a.x,y:o.y+a.y},3+r*3),w(n,{x:o.x+a.y*t.hand,y:o.y-a.x*t.hand},8+r)}),n}var pn=$({id:"a015",name:"Twisted seams",mechanics:["periodic horizontal boundary","reflected seam coordinates","handedness reversal","alternative seam gluing","quarter-turn vertical seam","seam-coupled companion"],variables:["oriented unit poses","handedness","active chart","selected unit","obstacles"],novelty:"Crossing an edge changes both position and the reference frame; the board has glued boundaries rather than ordinary Euclidean adjacency.",initial(e){return{units:[{x:3,y:3,dir:1,hand:1},...e>=5?[{x:5,y:5,dir:3,hand:1}]:[]],sel:0,chart:0,walls:e>=5?[{x:2,y:2},{x:4,y:4}]:[]}},move(e,n,t){if(n.button===5&&t>=3){e.chart=1-e.chart;return}if(n.button===6&&t>=5){let l=pe(n),c=e.units.findIndex(s=>Math.floor(l.x/3)===s.x&&Math.floor(l.y/3)===s.y);c>=0&&(e.sel=c);return}if(n.button>4)return;let r=g(e.units),o=e.units[e.sel],a=P[n.button-1];o.x+=a.x,o.y+=a.y*o.hand,o.dir=n.button-1;let i=!1;if((o.x<0||o.x>6)&&(o.x=M(o.x,7),i=!0,t>=2&&(e.chart===0?(o.y=6-o.y,o.hand=-o.hand,o.dir=M(2-o.dir,4)):o.y=M(o.y+3,7))),o.y<0||o.y>6){if(t<4){e.units=r;return}let l=o.y;o.y=M(o.x,7),o.x=l<0?6:0,o.dir=M(o.dir+1,4),i=!0}if(t===6&&i){let l=e.units[1-e.sel];l.x=M(l.x+1,7),l.y=6-l.y,l.hand=-l.hand,l.dir=M(2-l.dir,4)}(e.units.some(l=>e.walls.some(c=>x(l,c)))||e.units.length>1&&x(e.units[0],e.units[1]))&&(e.units=r)},objective:qt,view(e){return B(qt(e),[e.chart===0?10:11,3+e.sel*3])},choices(e,n){return[...I(n<3?[1,2,3,4]:[1,2,3,4,5]),...n>=5?e.units.map(t=>T(t.x*3+1,t.y*3+1)):[]]},controls:e=>e<3?[1,2,3,4]:e<5?[1,2,3,4,5]:[1,2,3,4,5,6]}),Gt=[en,tn,nn,rn,on,an,ln,cn,sn,un,fn,mn,hn,gn,pn];var at=48,it=48,v=(e,n)=>(e%n+n)%n,U=(e,n)=>JSON.stringify(e)===JSON.stringify(n);function q(e,n,t,r){Number.isInteger(n)&&Number.isInteger(t)&&n>=0&&t>=0&&n<at&&t<it&&(e[t][n]=r)}function y(e,n,t,r,o,a,i=!1){for(let l=0;l<o;l++)for(let c=0;c<r;c++)(i||!c||!l||c===r-1||l===o-1)&&q(e,n+c,t+l,a)}function j(e,n,t,r,o,a=1){let i=Math.max(Math.abs(r-n),Math.abs(o-t));for(let l=0;l<=i;l++)q(e,Math.round(n+(r-n)*l/(i||1)),Math.round(t+(o-t)*l/(i||1)),a)}function p(e,n,t,r,o=!0,a=!1){y(e,n-2,t-2,5,5,a?15:1),y(e,n-1,t-1,3,3,o?r:0,!0),o||q(e,n,t,2)}function L(e,n,t,r,o,a=3){for(let i=0;i<o;i++)y(e,n+i*2,t,1,3,i<r?a:1,!0)}function me(e,n,t,r,o,a=6){for(let i=0;i<o;i++){let l=i*2*Math.PI/o-Math.PI/2,c=n+Math.round(Math.cos(l)*4),s=t+Math.round(Math.sin(l)*4);q(e,c,s,i===r?a:1),i===r&&j(e,n,t,c,s,a)}q(e,n,t,15)}function z(e,n,t,r=2){return e.button===6&&e.x!==void 0&&e.y!==void 0&&Math.abs(e.x-n)<=r&&Math.abs(e.y-t)<=r}var _=(e,n)=>f(6,e,n);function d(e,n,t,r){r(e,t),n.push(t)}function k(e,n,t,r,o){for(let a=0;a<r;a++)d(e,n,f(t),o)}function vn(e){return{id:e.id,name:e.name,family:"temporal-causality",version:"1.0.0",levels:6,mechanics:e.mechanics,stateVariables:e.vars,novelty:e.novelty,init:(n,t)=>e.build(Number.isFinite(n)?Math.max(1,Math.min(6,Math.trunc(n))):1,t),step(n,t){if(!t||!e.buttons.includes(t.button)||e.won(n))return g(n);if(t.button===6&&(!Number.isInteger(t.x)||!Number.isInteger(t.y)||t.x<0||t.y<0||t.x>=at||t.y>=it))return g(n);let r=g(n);return e.apply(r,t),r},observe(n){let t=C(at,it);return e.draw(n,t),y(t,44,1,3,3,e.won(n)?3:1,!0),{pixels:t,actions:[...e.buttons],level:n.level,status:e.won(n)?"won":"playing"}},solved:e.won}}function bn(e,n,t,r,o,a=3e4){let i=[g(e)],l=[-1],c=[-1],s=new Set([o(e)]);for(let u=0;u<i.length&&u<a;u++){if(r(i[u])){let h=[];for(let E=u;l[E]>=0;E=l[E])h.push(n[c[E]]);return h.reverse()}for(let h=0;h<n.length;h++){let E=g(i[u]);t(E,n[h]);let re=o(E);s.has(re)||(s.add(re),i.push(E),l.push(u),c.push(h))}}throw Error("Temporal witness search exhausted")}function je(e,n){for(let t=0;t<e.n;t++)z(n,4,10+t*11)&&(e.sel=t);if(n.button===3&&e.level>=5&&(e.tint^=1),n.button===1&&e.pos[e.sel]<0&&!e.cool&&(e.pos[e.sel]=0,e.color[e.sel]=e.tint,e.cool=e.level>=6?1:0),n.button===2){e.phase=v(e.phase+1,e.period),e.cool=Math.max(0,e.cool-1);for(let t=0;t<e.n;t++)e.bank[t]=Math.max(0,e.bank[t]-1),!(e.pos[t]<0)&&(e.pos[t]++,e.level>=5&&e.pos[t]===Math.floor(e.len[t]/2)&&(e.color[t]^=1),e.pos[t]>=e.len[t]&&((e.level<4||e.phase===e.gate)&&e.color[t]===e.target[t]&&(e.bank[t]=e.level===1?3:1),e.pos[t]=-1))}}var yn={id:"d001",name:"Arrival Basin",buttons:[1,2,3,6],mechanics:["L1 delayed physical transport","L2 unequal arrival distances with one-tick storage","L3 three-way rendezvous","L4 periodically receptive basin","L5 in-flight pigment inversion","L6 shared refractory emitter"],vars:["courier positions and pigments","path lengths","basin lifetimes","receptive phase","source pigment and recovery"],novelty:"Schedule actual couriers of different flight times so their short-lived deposits coexist.",build(e,n){let t=ke(n),r=e>=3?3:2,o=e===1?[2,2]:e>=6?[2,4,6]:Array.from({length:r},(s,u)=>2+u*(e===2?2:1)),a={level:e,n:r,len:o,pos:Array(r).fill(-1),color:Array(r).fill(0),bank:Array(r).fill(0),target:Array.from({length:r},()=>e>=5?+(t()<.5):0),sel:0,tint:0,cool:0,period:e>=4?3:1,phase:0,gate:Math.floor(t()*3)},i=g(a),l=[],c=Math.max(...o)+1;for(;e>=4&&c%3!==a.gate;)c++;for(let s=0;s<c;s++){for(let u=0;u<r;u++)if(s===c-o[u]){d(i,l,_(4,10+u*11),je);let h=a.target[u]^(e>=5?1:0);i.tint!==h&&d(i,l,f(3),je),d(i,l,f(1),je)}d(i,l,f(2),je)}return{state:a,witness:l}},apply:je,won:e=>e.bank.every(n=>n>0),draw(e,n){p(n,4,3,e.tint?4:3,!0),L(n,12,2,e.cool,1,8),e.level>=4&&(me(n,35,5,e.phase,e.period),q(n,40,2+e.gate*2,10));for(let t=0;t<e.n;t++){let r=10+t*11;p(n,4,r,6,!0,e.sel===t);for(let o=0;o<=e.len[t];o++)q(n,9+o*4,r,1),e.pos[t]===o&&p(n,9+o*4,r,e.color[t]?4:3);e.level>=5&&y(n,8+Math.floor(e.len[t]/2)*4,r-3,3,7,6),y(n,39,r-3,7,7,e.target[t]?4:3),p(n,42,r,e.target[t]?4:3,e.bank[t]>0),L(n,38,r+5,e.bank[t],3,10)}}};function Se(e,n){for(let t=0;t<e.n;t++)z(n,8+t*14,18)&&(e.sel=t);if(n.button===1&&(e.level<6||e.water>0)&&(e.moist[e.sel]=3,e.level>=6&&e.water--),n.button===3&&e.level>=5&&(e.cover^=1),n.button===4)if(e.level<3)for(let t=0;t<e.n;t++)e.growth[t]===e.need[t]&&(e.fruit[t]=1);else e.growth.every((t,r)=>t===e.need[r])&&e.fruit.fill(1);if(n.button===5&&(e.growth[e.sel]=0,e.age[e.sel]=0,e.moist[e.sel]=0),n.button===2){e.phase=v(e.phase+1,4),e.water=2;for(let t=0;t<e.n;t++)e.fruit[t]||(e.level>=5&&e.phase===0&&!e.cover&&(e.growth[t]=0,e.age[t]=0),e.growth[t]===e.need[t]?(e.age[t]++,e.level>=2&&e.age[t]>5&&(e.growth[t]=0,e.age[t]=0)):e.moist[t]>0&&!e.cover&&(e.level<4||e.phase%2===t%2)&&e.growth[t]++,e.moist[t]=Math.max(0,e.moist[t]-1))}}var xn={id:"d002",name:"Seasonal Pollination",buttons:[1,2,3,4,5,6],mechanics:["L1 watered growth","L2 blossoms expire after maturity","L3 simultaneous cross-pollination","L4 alternating photoperiods","L5 frost protection blocks growth","L6 shared two-dose replenishing water"],vars:["growth","blossom age","soil moisture","photoperiod","frost cover","water reserve","pollinated fruit"],novelty:"Keep plants alive through different growth schedules and obtain a real overlap of viable blossoms.",build(e,n){let t=e>=3?3:2,r={level:e,n:t,need:Array.from({length:t},(i,l)=>1+v(n+l,3)),growth:Array(t).fill(0),age:Array(t).fill(0),moist:Array(t).fill(0),fruit:Array(t).fill(0),phase:0,cover:0,water:2,sel:0},o=g(r),a=[];for(let i=0;i<14&&!o.fruit.every(Boolean);i++){let l=Array.from({length:t},(s,u)=>u).sort((s,u)=>o.moist[s]-o.moist[u]);for(let s of l.slice(0,e>=6?2:t))o.moist[s]<2&&(d(o,a,_(8+s*14,18),Se),d(o,a,f(1),Se));let c=e>=5&&v(o.phase+1,4)===0;o.cover!==Number(c)&&d(o,a,f(3),Se),d(o,a,f(2),Se),d(o,a,f(4),Se)}if(!o.fruit.every(Boolean))throw Error("Garden schedule failed");return{state:r,witness:a}},apply:Se,won:e=>e.fruit.every(Boolean),draw(e,n){me(n,23,6,e.phase,4),e.level>=5&&y(n,2,11,42,3,e.cover?6:1,!!e.cover),e.level>=6&&L(n,3,3,e.water,2,4);for(let t=0;t<e.n;t++){let r=8+t*14;p(n,r,18,e.fruit[t]?10:3,!!e.fruit[t],e.sel===t),j(n,r,23,r,34,3),L(n,r-4,26,e.growth[t],e.need[t]),L(n,r-4,32,e.moist[t],3,4),e.growth[t]===e.need[t]&&(y(n,r-3,16,7,5,10),L(n,r-4,37,6-e.age[t],6,10)),y(n,r-5,41,11,3,e.fruit[t]?10:1)}}};function ve(e,n){for(let o=0;o<e.n;o++)z(n,8+o*14,18)&&(e.sel=o);let t=e.sel;if(n.button===1&&e.stage[t]===0&&(e.level<6||t===0||e.stage[t-1]===3)&&(e.stage[t]=1,e.temp[t]=6),n.button===2&&e.stage[t]===1&&(e.level<2||e.coolant>0)&&(e.level>=2&&e.coolant--,e.temp[t]===e.target[t]?(e.stage[t]=e.level>=5?2:3,e.delay[t]=e.level>=5?2:0):(e.stage[t]=0,e.delay[t]=0),e.temp[t]=0),n.button===4&&!e.stage.includes(1)&&(e.coolant=2),n.button===5&&e.stage[t]!==3&&(e.stage[t]=0,e.temp[t]=0,e.delay[t]=0),n.button!==3)return;let r=e.temp.slice();for(let o=0;o<e.n;o++)e.temp[o]=Math.max(0,e.temp[o]-1),e.level>=4&&e.stage[o]===1&&r.some((a,i)=>i!==o&&a>r[o]+1)&&(e.temp[o]=Math.min(6,e.temp[o]+1)),e.stage[o]===1&&e.temp[o]===0&&(e.stage[o]=0),e.stage[o]===2&&--e.delay[o]<=0&&(e.stage[o]=3)}var wn={id:"d003",name:"Quench Window",buttons:[1,2,3,4,5,6],mechanics:["L1 delayed cooling into a quench window","L2 finite recoverable coolant","L3 pieces require different thermal endpoints","L4 hot pieces radiate into cooler pieces","L5 post-quench annealing delay","L6 finished predecessor unlocks the next blank"],vars:["material stage","temperature","required quench temperature","annealing timer","coolant"],novelty:"Transform persistent material at a transient thermal state, with recoverable failed quenches and delayed completion.",build(e,n){let t=e>=6?3:e>=3?2:1,r={level:e,n:t,stage:Array(t).fill(0),temp:Array(t).fill(0),delay:Array(t).fill(0),target:Array.from({length:t},(i,l)=>2+v(n+l,2)),coolant:2,sel:0},o=g(r),a=[];for(let i=0;i<t;i++)d(o,a,_(8+i*14,18),ve),o.coolant||d(o,a,f(4),ve),d(o,a,f(1),ve),k(o,a,3,6-o.target[i],ve),d(o,a,f(2),ve),e>=5&&k(o,a,3,2,ve);return{state:r,witness:a}},apply:ve,won:e=>e.stage.every(n=>n===3)&&e.temp.every(n=>n===0),draw(e,n){e.level>=2&&L(n,3,3,e.coolant,2,4);for(let t=0;t<e.n;t++){let r=8+t*14;e.level>=6&&t&&j(n,r-14,9,r,9,e.stage[t-1]===3?3:1),p(n,r,18,[2,9,6,3][e.stage[t]],!0,e.sel===t),L(n,r-5,26,e.temp[t],6,9),q(n,r-5+(e.target[t]-1)*2,24,15),L(n,r-3,34,e.delay[t],2,6),y(n,r-3,40,7,4,e.stage[t]===3?3:1)}e.level>=4&&j(n,8,22,8+(e.n-1)*14,22,9)}};function Xt(e,n=e.time){let t=[2+(v(n+e.offset[0],3)===0?0:1)];return e.level>=2&&t.push(v(n+e.offset[1],4)<2?5:6),e.level>=3&&t.push(v(n+e.offset[2],5)<2?7:6),t}function Pt(e,n){if(n.button===4){e.level>=5&&e.pos===4&&(e.lease=6);return}if(n.button===5){e.level>=6&&e.pos===5&&(e.load^=1);return}if(![1,2,3].includes(n.button))return;let t=n.button===1?1:n.button===3?-1:0,r=Math.max(0,Math.min(8,e.pos+t)),o=e.level>=6&&e.load&&t?2:1;for(let a=0;a<o;a++){e.time=v(e.time+1,60),e.lease=Math.max(0,e.lease-1);let i=a===o-1?r:e.pos;if(Xt(e).includes(i)){e.pos=0,e.load=0;return}if(a===o-1){if(i===6&&e.level>=5&&!e.lease||i===8&&e.level>=4&&!e.key)return;e.pos=i,e.level>=4&&i===1&&(e.key=1)}}}var kn={id:"d004",name:"Transit Windows",buttons:[1,2,3,4,5],mechanics:["L1 moving periodic obstruction","L2 independent obstacle periods","L3 a second dwell pattern shares a corridor","L4 retain a key before the exit","L5 a local switch grants an expiring bridge lease","L6 a carried load makes motion take two ticks"],vars:["traveller location","obstacle phases","key","bridge lease","load"],novelty:"Plan movement against future obstacle occupancy; waiting and loaded travel advance the same causal clock differently.",build(e,n){let t={level:e,pos:0,time:0,key:0,lease:0,load:0,offset:[v(n,3),v(n+1,4),v(n+2,5)]},r=bn(t,[f(1),f(2),f(3),f(4),f(5)],Pt,o=>o.pos===8&&(o.level<6||o.load===1),o=>[o.pos,o.time,o.key,o.lease,o.load].join(),18e3);return{state:t,witness:r}},apply:Pt,won:e=>e.pos===8&&(e.level<6||e.load===1),draw(e,n){let t=Xt(e);for(let r=0;r<9;r++){let o=4+r*5;y(n,o-2,22,5,7,1),t.includes(r)&&y(n,o-1,23,3,3,8,!0),e.pos===r&&p(n,o,27,e.load?10:3),r===8&&y(n,o-2,32,5,5,3)}me(n,10,8,v(e.time+e.offset[0],3),3,8),e.level>=2&&me(n,24,8,v(e.time+e.offset[1],4),4,8),e.level>=3&&me(n,38,8,v(e.time+e.offset[2],5),5,8),e.level>=4&&p(n,9,17,10,!e.key),e.level>=5&&(p(n,24,17,6,e.lease>0),L(n,19,36,e.lease,6,6)),e.level>=6&&y(n,27,17,4,3,e.load?1:10,!0)}},oe=[[7,10],[20,20],[35,10],[36,34]];function ie(e,n){for(let r=0;r<e.n;r++)if(z(n,oe[r][0],oe[r][1])&&(e.sel=r,!e.run[r]&&e.parents[r].every(o=>e.stamp[o]>0)&&e.run.filter(Boolean).length<e.workers)){if(e.level>=6&&e.stamp[r]){let o=new Set([r]);for(let a=0;a<e.n;a++)e.parents[a].some(i=>o.has(i))&&(o.add(a),e.stamp[a]=0)}e.stamp[r]=0,e.run[r]=e.duration[r]}if(n.button===2&&(e.run[e.sel]=0),n.button!==1)return;for(let r=0;r<e.n;r++)e.level>=4&&e.stamp[r]>0&&e.stamp[r]--;let t=[];for(let r=0;r<e.n;r++)if(e.run[r]){if(e.level>=5&&!e.parents[r].every(o=>e.stamp[o]>0)){e.run[r]=0;continue}e.run[r]--,e.run[r]||t.push(r)}for(let r of t)e.stamp[r]=e.level>=4?5:1}var An={id:"d005",name:"Leased Workshop",buttons:[1,2,6],mechanics:["L1 task completion enables a dependent task","L2 parallel fork and join","L3 unequal operation durations","L4 completed permissions expire","L5 prerequisites must remain valid during execution","L6 renewing a cause invalidates its completed descendants"],vars:["dependency graph","completion leases","running task timers","worker capacity","selected task"],novelty:"Schedule a causal dependency graph whose enabling facts have lifetimes, rather than static Boolean availability.",build(e,n){let t=e===1?3:4,r=e===1?[[],[0],[1]]:[[],[0],[0],e>=6?[0,1,2]:[1,2]],o={level:e,n:t,parents:r,stamp:Array(t).fill(0),run:Array(t).fill(0),duration:Array.from({length:t},(l,c)=>e>=3&&(c===1||e>=6&&c===t-1)?2:1),workers:e===1?1:2,sel:0},a=g(o),i=[];if(d(a,i,_(...oe[0]),ie),k(a,i,1,1,ie),e===1)for(let l=1;l<3;l++)d(a,i,_(...oe[l]),ie),k(a,i,1,1,ie);else{for(let l of[1,2])d(a,i,_(...oe[l]),ie);k(a,i,1,Math.max(a.duration[1],a.duration[2]),ie),d(a,i,_(...oe[3]),ie),k(a,i,1,a.duration[3],ie)}return{state:o,witness:i}},apply:ie,won:e=>e.stamp[e.n-1]>0&&e.run.every(n=>n===0),draw(e,n){for(let t=0;t<e.n;t++){let[r,o]=oe[t];for(let a of e.parents[t])j(n,oe[a][0],oe[a][1],r,o,e.stamp[a]?3:1)}for(let t=0;t<e.n;t++){let[r,o]=oe[t];p(n,r,o,e.run[t]?10:3,!!(e.run[t]||e.stamp[t]),e.sel===t),L(n,r-4,o+4,e.run[t],e.duration[t],10),e.level>=4&&L(n,r-4,o+8,e.stamp[t],5,3),t===e.n-1&&y(n,r-4,o-4,9,9,10)}L(n,3,42,e.workers-e.run.filter(Boolean).length,e.workers,6)}};function Ve(e){return e.index<e.tape.length?e.tape[e.index]:e.hold?e.tape[e.tape.length-1]:-1}function Yt(e,n){if(n!==4&&!(e.level>=3&&n===7))return!0;let t=n===4?1:5;return e.ghosts.some(r=>Ve(r)===t&&(e.level<4||r.prev===t))}function ee(e,n){if(n.button===5){e.record^=1,e.record&&(e.tape=[e.pos]);return}if(n.button===4&&e.tape.length>1){e.ghosts.push({tape:e.tape.slice(),index:0,prev:-1,hold:e.level===1}),e.ghosts.length>3&&e.ghosts.shift(),e.pos=0,e.record=0,e.phase=0;return}if(![1,2,3].includes(n.button))return;e.phase^=1;for(let o of e.ghosts)o.prev=Ve(o),(e.level<6||e.phase===0)&&(o.index=Math.min(o.tape.length,o.index+1));let t=n.button===1?1:n.button===2?-1:0,r=Math.max(0,Math.min(8,e.pos+t));if(Yt(e,r)){let o=e.level>=5&&r!==0&&r!==1&&r!==5&&e.ghosts.some(a=>Ve(a)===r);e.pos=o?0:r}e.level>=6&&e.pos===2&&(e.token=1),e.record&&e.tape.length<32&&e.tape.push(e.pos)}var Sn={id:"d006",name:"Borrowed Footsteps",buttons:[1,2,3,4,5],mechanics:["L1 record and replay a physical shadow holding a plate","L2 finite-lived replay traces","L3 two gates require shadows at separate plates","L4 plates require two consecutive samples","L5 solid and shadow bodies collide away from plates","L6 half-speed shadow time and a retained physical token"],vars:["live position","recorded position trace","shadow playback cursors","previous shadow positions","clock ratio","token"],novelty:"Use a recorded causal history as a simultaneous second actor; the history physically replays rather than transforming a pixel board.",build(e,n){let t={level:e,pos:0,record:0,tape:[],ghosts:[],phase:0,token:0},r=g(t),o=[];return d(r,o,f(5),ee),d(r,o,f(1),ee),k(r,o,3,20,ee),d(r,o,f(4),ee),e>=3&&(d(r,o,f(5),ee),k(r,o,1,5,ee),k(r,o,3,8,ee),d(r,o,f(4),ee)),k(r,o,3,e>=6?10:e>=5?2:0,ee),k(r,o,1,8,ee),{state:t,witness:o}},apply:ee,won:e=>e.pos===8&&!e.record&&(e.level<6||!!e.token),draw(e,n){for(let t=0;t<9;t++){let r=4+t*5;y(n,r-2,23,5,6,1),(t===1||e.level>=3&&t===5)&&y(n,r-2,30,5,2,6,!0),(t===4||e.level>=3&&t===7)&&y(n,r-1,21,3,10,Yt(e,t)?3:8),e.pos===t&&p(n,r,26,3),t===8&&y(n,r-2,34,5,5,3)}e.ghosts.forEach((t,r)=>{let o=Ve(t);o>=0&&p(n,4+o*5,14-r*5,6);for(let a=0;a<t.tape.length;a++)q(n,3+a,40+r*2,a===t.index?15:6)});for(let t=0;t<e.tape.length;t++)q(n,3+t,3,6);p(n,39,5,8,!!e.record),e.level>=6&&(p(n,14,18,10,!e.token),p(n,41,14,6,!!e.phase))}};function Xe(e,n){return n<e.roots||e.snap[n].length===e.parents[n].length&&e.parents[n].every((t,r)=>Xe(e,t)&&e.snap[n][r]===e.rev[t])}function lt(e,n){let t=e.parents[n].map(r=>e.value[r]);return e.op[n]?Number(t.every(Boolean)):t.reduce((r,o)=>r^o,0)}function He(e,n){for(let t=0;t<e.n;t++)z(n,6+t*9,18)&&(e.sel=t,t<e.roots?(e.value[t]^=1,e.rev[t]++):!e.run[t]&&(e.level>=6||e.parents[t].every(r=>Xe(e,r)))&&(e.level<5||!e.run.some(Boolean))&&(e.pending[t]=lt(e,t),e.snapPending[t]=e.parents[t].map(r=>e.rev[r]),e.run[t]=e.level>=3?2:1,e.level<3&&(e.value[t]=e.pending[t],e.snap[t]=e.snapPending[t],e.rev[t]++,e.run[t]=0)));if(n.button===2&&(e.run[e.sel]=0),n.button===1){for(let t=e.roots;t<e.n;t++)if(e.run[t]&&!--e.run[t]){let r=e.parents[t].every((o,a)=>e.rev[o]===e.snapPending[t][a]);if(e.level>=4&&!r){e.run[t]=0;continue}e.value[t]=e.pending[t],e.snap[t]=e.snapPending[t].slice(),e.rev[t]++}}}var Mn={id:"d007",name:"Causal Revisions",buttons:[1,2,6],mechanics:["L1 cached results retain old causes","L2 shared parents create a dependency diamond","L3 computation captures inputs before delayed completion","L4 changed input invalidates an in-flight result","L5 a shared executor serializes rebuilds","L6 dirty reads can create transitively stale descendants"],vars:["root values and targets","cache values","parent revision snapshots","dependency graph","in-flight snapshot and timer"],novelty:"Repair persistent derived artifacts after their causes change; correctness includes causal freshness, not just matching color.",build(e,n){let t=e===1?1:2,r=e===1?3:5,o=e===1?[[],[0],[1]]:[[],[],[0,1],[0],[2,3]],a=Array.from({length:t},(u,h)=>v(n+h,2));a.some(Boolean)||(a[0]=1);let i={level:e,n:r,roots:t,parents:o,goal:a,op:Array.from({length:r},(u,h)=>e>=2&&h===r-1?1:0),value:Array(r).fill(0),rev:Array(r).fill(0),snap:Array.from({length:r},()=>[]),run:Array(r).fill(0),pending:Array(r).fill(0),snapPending:Array.from({length:r},()=>[]),sel:0,target:[]};for(let u=0;u<t;u++)i.value[u]=1-a[u];for(let u=t;u<r;u++)i.value[u]=lt(i,u),i.snap[u]=o[u].map(()=>0);let l=g(i);for(let u=0;u<t;u++)l.value[u]=a[u];for(let u=t;u<r;u++)l.value[u]=lt(l,u);i.target=l.value;let c=g(i),s=[];for(let u=0;u<t;u++)d(c,s,_(6+u*9,18),He);for(let u=t;u<r;u++)d(c,s,_(6+u*9,18),He),e>=3&&k(c,s,1,2,He);return{state:i,witness:s}},apply:He,won:e=>U(e.value,e.target)&&e.run.every(n=>n===0)&&Array.from({length:e.n},(n,t)=>Xe(e,t)).every(Boolean),draw(e,n){for(let t=e.roots;t<e.n;t++)for(let r of e.parents[t])j(n,6+r*9,10,6+t*9,10,Xe(e,r)?6:8),j(n,6+r*9,10,6+r*9,16,6);for(let t=0;t<e.n;t++){let r=6+t*9;p(n,r,18,e.value[t]?3:4,!0,e.sel===t),p(n,r,35,e.target[t]?3:4),t>=e.roots&&(L(n,r-2,25,e.run[t],2,10),y(n,r-2,29,5,2,Xe(e,t)?3:8,!0),e.op[t]?y(n,r-1,5,3,3,10):(q(n,r-1,5,10),q(n,r+1,7,10)))}}};function Fe(e){return e.route[e.index]}function be(e,n){for(let i=0;i<e.boats.length;i++)z(n,12+i*24,9)&&(e.sel=i);n.button===3&&(e.item=v(e.item+1,e.cargo.length));let t=e.boats[e.sel],r=e.cargo[e.item],o=Fe(t),a=e.level<6||e.time%3!==2;if(n.button===1&&a&&r.loc===o&&o!==2&&e.cargo.filter(i=>i.loc===-1-e.sel).reduce((i,l)=>i+l.weight,0)+r.weight<=t.cap&&(r.loc=-1-e.sel),n.button===2&&a&&r.loc===-1-e.sel&&(r.loc=o,o===2&&(r.done=1)),n.button===4&&e.level>=5&&r.loc===1&&(r.ice=1,r.age=0),n.button===5){e.time=v(e.time+1,6);for(let i of e.boats)i.index=v(i.index+1,i.route.length);for(let i of e.cargo)!i.done&&i.loc<0&&(i.age++,e.level>=5&&i.age>(i.ice?14:8)&&(i.loc=0,i.age=0,i.ice=0))}}var En={id:"d008",name:"Tidal Transfer",buttons:[1,2,3,4,5,6],mechanics:["L1 boarding a periodic ferry","L2 independent persistent cargos","L3 weight-limited boat capacity","L4 transfer between disjoint ferry routes","L5 perishable cargo and an intermediate ice station","L6 tide phase blocks dock service"],vars:["boat route positions","cargo location and weight","cargo age","ice protection","tide phase","selected boat and cargo"],novelty:"Schedule the transfer of persistent goods between moving carriers and a temporary intermediate store.",build(e,n){let t=e>=3?3:2,r=e>=4?[{route:[0,1],index:v(n,2),cap:2},{route:[1,2],index:v(n+1,2),cap:2}]:[{route:[0,1,2,1],index:v(n,4),cap:2}],o={level:e,boats:r,cargo:Array.from({length:t},(c,s)=>({loc:0,weight:e>=3&&s===t-1?2:1,age:0,ice:0,done:0})),sel:0,item:0,time:0},a=g(o),i=[],l=(c,s)=>{let u=0;for(;(Fe(a.boats[c])!==s||e>=6&&a.time%3===2)&&u++<20;)d(a,i,f(5),be)};for(let c=0;c<t;c++){for(;a.item!==c;)d(a,i,f(3),be);let s=e>=4?[[0,0,1],[1,1,2]]:[[0,0,2]];for(let[u,h,E]of s)d(a,i,_(12+u*24,9),be),e>=5&&h===1&&d(a,i,f(4),be),l(u,h),d(a,i,f(1),be),l(u,E),d(a,i,f(2),be)}return{state:o,witness:i}},apply:be,won:e=>e.cargo.every(n=>n.done&&n.loc===2),draw(e,n){j(n,6,27,42,27,4);for(let t=0;t<3;t++)y(n,4+t*18,23,5,12,t===2?3:1);e.boats.forEach((t,r)=>{p(n,12+r*24,9,6,!0,e.sel===r);let o=6+Fe(t)*18;y(n,o-3,29+r*6,7,4,6,!0),L(n,8+r*24,14,t.cap,2,10)}),e.cargo.forEach((t,r)=>{let o=5+r*14;p(n,o,42,3+r,!0,e.item===r),L(n,o-2,45,t.weight,2,10);let a=t.loc>=0?t.loc:Fe(e.boats[-1-t.loc]);y(n,4+a*18+r*2,18,2,3,3+r,!0),e.level>=5&&(L(n,o-2,3,Math.min(t.age,6),6,t.ice?4:9),t.ice&&q(n,o,6,4))}),e.level>=6&&me(n,24,19,e.time%3,3,e.time%3===2?8:6)}};function N(e,n){for(let a=0;a<e.owner.length;a++){let i=6+a*7;z(n,i,11)&&(e.sel=a)}if(n.button===1&&(e.dest=v(e.dest+1,3)),n.button===5&&e.level>=5&&(e.batch^=1),n.button===2){let a=e.sel;(e.level>=3||e.pending.length===0)&&!e.pending.some(i=>i.id===a)&&e.owner[a]!==e.dest&&e.pending.push({id:a,from:e.owner[a],to:e.dest,eta:e.level>=2?1+v(a,3):1})}if(n.button===4){let a=e.pending.findIndex(i=>i.id===e.sel);if(a>=0)e.pending.splice(a,1);else if(e.level>=6){let i=e.last[e.sel];i!==void 0&&i!==e.owner[e.sel]&&e.pending.push({id:e.sel,from:e.owner[e.sel],to:i,eta:2})}}if(n.button!==3)return;for(let a of e.pending)a.eta=Math.max(0,a.eta-1);let t=e.pending.filter(a=>a.eta===0),r=[0,0,0];for(let a of e.owner)r[a]++;let o=[];if(e.batch&&e.level>=5){let a=r.slice();for(let i of t)a[i.from]--,a[i.to]++;a.every(i=>i<=e.cap)&&o.push(...t)}else for(let a of t)(e.level<4||r[a.to]<e.cap)&&(r[a.from]--,r[a.to]++,o.push(a));for(let a of o)e.last[a.id]=e.owner[a.id],e.owner[a.id]=a.to;e.pending=e.pending.filter(a=>!o.includes(a))}var Ln={id:"d009",name:"Escrow Cycle",buttons:[1,2,3,4,5,6],mechanics:["L1 delayed settlement","L2 transfers have unequal settlement latencies","L3 reservations prevent duplicate spending","L4 full destinations hold ready transfers","L5 atomic batch netting clears a capacity cycle","L6 compensating transfers undo completed moves after a new delay"],vars:["token owners","reserved transfers","remaining settlement time","account capacity","batch mode","previous ownership"],novelty:"Move colored assets through delayed reservations and capacity-constrained settlement; simultaneous netting can unblock a cycle.",build(e,n){let t=e>=5?[0,0,1,1,2,2]:[0,0,1,2],r={level:e,owner:t,sel:0,dest:0,pending:[],last:Array(t.length).fill(void 0),cap:e>=5?2:3,batch:0,target:[]},o=g(r),a=[];e>=5&&d(o,a,f(5),N);let i=e>=5?[[0,1],[2,2],[4,0]]:[[0,1],[2,2],[3,0]];for(let[l,c]of i){for(d(o,a,_(6+l*7,11),N);o.dest!==c;)d(o,a,f(1),N);d(o,a,f(2),N),e<5&&k(o,a,3,3,N)}if(e>=5){if(k(o,a,3,3,N),e>=6){for(let l of[0,2,4])d(o,a,_(6+l*7,11),N),d(o,a,f(4),N);k(o,a,3,2,N);for(let[l,c]of i){for(d(o,a,_(6+l*7,11),N);o.dest!==c;)d(o,a,f(1),N);d(o,a,f(2),N)}k(o,a,3,3,N)}d(o,a,f(5),N)}return r.target=o.owner.slice(),{state:r,witness:a}},apply:N,won:e=>U(e.owner,e.target)&&e.pending.length===0&&!e.batch,draw(e,n){for(let t=0;t<e.owner.length;t++){let r=6+t*7;p(n,r,11,3+t,!0,e.sel===t),y(n,r-2,18+e.owner[t]*6,5,4,3+t,!0),y(n,r-2,39+e.target[t]*2,5,1,3+t,!0);let o=e.pending.find(a=>a.id===t);o&&(j(n,r,20+o.from*6,r,20+o.to*6,10),L(n,r-2,5,o.eta,3,10))}for(let t=0;t<3;t++)j(n,2,22+t*6,45,22+t*6,t===e.dest?15:1);p(n,40,3,6,!!e.batch),e.level>=4&&L(n,3,2,e.cap,3,10)}};function ye(e,n){for(let r=0;r<e.n;r++)z(n,8+r*14,8)&&(e.sel=r);if(n.button===1&&(e.where[e.sel]===1?(e.queue=e.queue.filter(r=>r!==e.sel),e.where[e.sel]=0,e.age[e.sel]=0,e.cure[e.sel]=0):e.where[e.sel]===0&&e.queue.length<e.cap&&(e.queue.push(e.sel),e.where[e.sel]=1,e.age[e.sel]=0,e.cure[e.sel]=0)),n.button===3&&e.queue.length){let r=e.queue[0];e.age[r]>=e.need[r]&&(e.level<6||e.cure[r]>=e.cureNeed[r])&&(e.where[r]=2,e.queue.shift())}if(n.button===4&&e.level>=3&&e.queue.length>1&&e.queue.push(e.queue.shift()),n.button===5&&e.level>=6&&(e.cold^=1),n.button!==2)return;let t=e.queue.slice();for(let r of t){let o=t.indexOf(r),a=[t[o-1],t[o+1]].filter(c=>c!==void 0),i=e.level<4||a.some(c=>e.type[c]!==e.type[r])||t.length===1;e.level>=6&&e.cold?e.age[r]>=e.need[r]&&(e.cure[r]=Math.min(e.cureNeed[r],e.cure[r]+1)):i&&e.age[r]++;let l=e.need[r]+(e.level>=5?3:5);e.level>=2&&!e.cold&&e.age[r]>l&&(e.where[r]=0,e.age[r]=0,e.cure[r]=0,e.queue=e.queue.filter(c=>c!==r))}}var _n={id:"d010",name:"Maturing Queue",buttons:[1,2,3,4,5,6],mechanics:["L1 age before FIFO dispatch","L2 over-age material is recycled","L3 rotate the live FIFO order","L4 adjacent complementary material enables maturation","L5 narrow freshness windows","L6 a shared cold phase performs a second maturation stage"],vars:["FIFO order","material age","freshness windows","complementary types","cold-stage progress","pending and finished goods"],novelty:"Ordering changes which materials can mature together, and dispatch must respect both age and a physical queue.",build(e,n){let t=e>=3?3:2,r={level:e,n:t,where:Array(t).fill(0),queue:[],age:Array(t).fill(0),cure:Array(t).fill(0),need:Array.from({length:t},(i,l)=>e>=3?[3,1,2][l]:2+l),cureNeed:Array.from({length:t},(i,l)=>1+v(n+l,2)),type:Array.from({length:t},(i,l)=>l%2),cap:3,cold:0,sel:0},o=g(r),a=[];for(let i=0;i<t;i++)d(o,a,_(8+i*14,8),ye),d(o,a,f(1),ye);return k(o,a,2,3,ye),e>=6&&(d(o,a,f(5),ye),k(o,a,2,2,ye)),k(o,a,3,t,ye),{state:r,witness:a}},apply:ye,won:e=>e.where.every(n=>n===2)&&e.queue.length===0,draw(e,n){for(let t=0;t<e.n;t++){let r=8+t*14;p(n,r,8,e.type[t]?4:9,e.where[t]===0,e.sel===t),L(n,r-4,13,e.need[t],3,e.type[t]?4:9),p(n,r,40,3,e.where[t]===2)}y(n,2,20,43,13,e.cold?4:1),e.queue.forEach((t,r)=>{let o=8+r*14;p(n,o,24,e.type[t]?4:9),L(n,o-4,29,e.age[t],6,10),e.level>=6&&L(n,o-2,35,e.cure[t],e.cureNeed[t],4)}),j(n,3,18,11,18,6),e.level>=6&&p(n,41,3,4,!!e.cold)}};function X(e,n){for(let r=0;r<e.n;r++)z(n,9+r*26,11)&&(e.sel=r);if(n.button===3&&(e.source^=1),n.button===4&&e.level>=2&&(e.gate^=1),n.button===1&&e.active.length<4&&(e.level<6||!e.active.some(r=>r.origin===e.sel))){e.seq++;let r=e.level>=5?e.sel===0?4:2:3;e.active.push({origin:e.sel,lane:e.sel,eta:r,duration:r,stamp:e.source,seq:e.seq,routed:!1})}if(n.button===5&&e.level>=6&&(e.active=e.active.filter(r=>r.origin!==e.sel)),n.button!==2)return;for(let r of e.acks)r.eta--;e.acks.filter(r=>r.eta===0).length%2&&(e.source^=1),e.acks=e.acks.filter(r=>r.eta>0);for(let r of e.active)if(r.eta--,e.level>=3&&r.eta===1&&!r.routed&&(r.lane^=e.gate,r.routed=!0),r.eta===0){let o=(e.level>=2?r.stamp:e.source)^(e.level>=2?e.gate:0);(e.level<5||r.seq>e.latest[r.lane])&&(e.received[r.lane]=o,e.done[r.lane]=1,e.latest[r.lane]=r.seq),e.level>=4&&e.acks.push({eta:2})}e.active=e.active.filter(r=>r.eta>0)}var qn={id:"d011",name:"In-flight Postmarks",buttons:[1,2,3,4,5,6],mechanics:["L1 delayed receiver sampling","L2 capture sender state at departure","L3 sample a route switch halfway through transit","L4 delayed acknowledgements change the sender","L5 reject out-of-order stale deliveries","L6 per-origin in-flight exclusion and cancellation"],vars:["sender pigment","route/arrival gate","messages with captured pigment and progress","receiver colors","delivery order","acknowledgement timers"],novelty:"A single transported object samples different causes at departure, in transit, and arrival; changes between those times have different effects.",build(e,n){let t=e===1?1:2,r={level:e,n:t,source:0,gate:0,sel:0,seq:0,active:[],acks:[],received:Array(t).fill(0),done:Array(t).fill(0),latest:Array(t).fill(-1),target:e===1?[1]:[v(n,2),1-v(n,2)]},o=g(r),a=[];e>=5&&(d(o,a,f(1),X),d(o,a,f(2),X),d(o,a,f(3),X),d(o,a,_(35,11),X),d(o,a,f(1),X),d(o,a,f(4),X),d(o,a,f(2),X),d(o,a,f(4),X),k(o,a,2,4,X));for(let i=0;i<t;i++){d(o,a,_(9+(i^(e>=3?1:0))*26,11),X),o.source!==o.target[i]&&d(o,a,f(3),X),d(o,a,f(1),X);let l=o.active[o.active.length-1].duration;e>=3&&d(o,a,f(4),X),k(o,a,2,l-1,X),e>=3&&d(o,a,f(4),X),d(o,a,f(2),X),e>=4&&k(o,a,2,2,X)}return{state:r,witness:a}},apply:X,won:e=>e.done.every(Boolean)&&U(e.received,e.target)&&!e.active.length&&!e.acks.length,draw(e,n){p(n,22,4,e.source?4:3),p(n,22,22,e.gate?4:3);for(let t=0;t<e.n;t++){let r=9+t*26;p(n,r,11,6,!0,e.sel===t),j(n,r,14,r,33,1),p(n,r,35,e.received[t]?4:3,!!e.done[t]),y(n,r-2,41,5,4,e.target[t]?4:3)}for(let t of e.active){let r=9+t.lane*26,o=15+Math.round((t.duration-t.eta)*18/t.duration);p(n,r,o,t.stamp?4:3),t.routed&&q(n,r+3,o,6),e.level>=5&&q(n,r-3,o,t.seq>e.latest[t.lane]?10:8)}e.acks.forEach((t,r)=>p(n,18+r*5,8+t.eta*4,10)),e.level>=3&&(j(n,9,22,35,29,6),j(n,35,22,9,29,6))}};function jt(e,n,t){t&&(e.level>=6&&t===1&&e.coat[n]||(e.q[n][t-1]=Math.min(4,e.q[n][t-1]+1),e.level>=6&&(e.coat[n]=t===1?1:0)))}function V(e,n){for(let t=0;t<4;t++)z(n,9+t*10,15)&&(e.sel=t,e.mask[t]^=1,e.level>=4&&(e.mask[(t+1)%4]^=1));if(n.button===1&&(e.lamp=v(e.lamp+1,3)),n.button===3&&e.level>=3&&(e.q[e.sel]=[0,0],e.coat[e.sel]=0,e.after[e.sel]=0),n.button===2){e.phase=v(e.phase+1,3);for(let t=0;t<4;t++)e.level>=5?(jt(e,t,e.after[t]),e.after[t]=e.mask[t]?e.lamp:0):e.mask[t]&&jt(e,t,e.lamp),e.level>=2&&e.phase===0&&!e.mask[t]&&(e.q[t]=e.q[t].map(r=>Math.max(0,r-1)))}}var Gn={id:"d012",name:"Latent Plates",buttons:[1,2,3,6],mechanics:["L1 cumulative colored exposure","L2 closed plates periodically fade","L3 bleaching repairs saturated exposure","L4 aperture controls overlap neighboring plates","L5 exposure develops one tick later","L6 red exposure leaves a blocking coat that blue light removes"],vars:["two-channel plate density","aperture mask","lamp spectrum","latent exposure","inhibitor coating","fade phase","target developed plates"],novelty:"Compose a physical developed image from cumulative, delayed, fading and chemically inhibited exposures.",build(e,n){let t={level:e,q:Array.from({length:4},()=>[0,0]),mask:[0,0,0,0],after:[0,0,0,0],coat:[0,0,0,0],lamp:0,phase:0,sel:0,target:[]},r=g(t),o=[],a=[],i=c=>{d(r,o,_(9+c*10,15),V),a.push(c)},l=v(n,4);if(i(l),d(r,o,f(1),V),k(r,o,2,2,V),e>=4)i((l+2)%4);else for(let c=0;c<4;c++)r.mask[c]||i(c);d(r,o,f(1),V),k(r,o,2,2,V),k(r,o,1,2,V),k(r,o,2,2,V),d(r,o,f(1),V),k(r,o,2,2,V);for(let c of a.reverse())d(r,o,_(9+c*10,15),V);for(;r.lamp;)d(r,o,f(1),V);return k(r,o,2,1,V),t.target=g(r.q),{state:t,witness:o}},apply:V,won:e=>U(e.q,e.target)&&e.mask.every(n=>n===0)&&e.after.every(n=>n===0)&&e.lamp===0,draw(e,n){p(n,5,4,e.lamp===1?9:4,!!e.lamp),me(n,34,5,e.phase,3);for(let t=0;t<4;t++){let r=9+t*10;p(n,r,15,10,!!e.mask[t],e.sel===t),e.level>=4&&j(n,r,10,9+(t+1)%4*10,10,6);for(let o=0;o<2;o++)L(n,r-3,23+o*4,e.q[t][o],4,o?4:9),L(n,r-3,38+o*4,e.target[t][o],4,o?4:9);e.level>=5&&p(n,r,32,e.after[t]===1?9:4,!!e.after[t]),e.level>=6&&e.coat[t]&&y(n,r-4,20,9,10,6)}}};function Ct(e,n){return e.level<5||e.seen[n].filter(t=>t===e.rev[n]).length>=2}function Pn(e,n){if(e.isolated[n])return;let t=e.level>=3?[v(n+1,e.n)]:Array.from({length:e.n},(r,o)=>o).filter(r=>r!==n);for(let r of t)e.queue.length<16&&e.queue.push({from:n,to:r,rev:e.rev[n],value:e.value[n],eta:e.level>=2?1+v(n+r+e.offset,3):1,ack:!1})}function Y(e,n){for(let a=0;a<e.n;a++)z(n,8+a*15,19)&&(e.sel=a);let t=e.sel;if(n.button===1||n.button===5&&e.level>=6){let a=e.value[t];e.value[t]=n.button===5?e.previous[t]:1-e.value[t],e.previous[t]=a,e.rev[t]=++e.counter,e.seen[t].fill(-1),e.seen[t][t]=e.rev[t]}if(n.button===2&&Pn(e,t),n.button===4&&e.level>=4&&(e.isolated[t]^=1),n.button!==3)return;let r=[],o=[];for(let a of e.queue)a.eta=Math.max(0,a.eta-1),!a.eta&&!e.isolated[a.to]?r.push(a):o.push(a);e.queue=o;for(let a of r){if(a.ack){e.rev[a.to]===a.rev&&(e.seen[a.to][a.from]=a.rev);continue}(e.level===1||a.rev>=e.rev[a.to])&&(e.value[a.to]=a.value,e.rev[a.to]=a.rev,e.seen[a.to][a.to]=a.rev,e.level>=5&&e.queue.length<16&&e.queue.push({from:a.to,to:a.from,rev:a.rev,value:a.value,eta:2,ack:!0}))}}var jn={id:"d013",name:"Asynchronous Agreement",buttons:[1,2,3,4,5,6],mechanics:["L1 propagation of a local proposal","L2 reject older delayed revisions","L3 forward a revision around a directed ring","L4 reversible partitions hold arriving messages","L5 acknowledgement quorum confirms each replica","L6 undo is a newer compensating revision"],vars:["replica values and revision order","pending proposals and acknowledgements","partitions","local previous value","quorum evidence"],novelty:"Reach confirmed distributed agreement despite transit delay and stale messages; a later undo is another causal event.",build(e,n){let t=e===1?2:3,r={level:e,n:t,value:Array.from({length:t},(i,l)=>l%2),previous:Array(t).fill(0),rev:Array(t).fill(0),counter:0,seen:Array.from({length:t},(i,l)=>Array.from({length:t},(c,s)=>l===s?0:-1)),queue:[],isolated:Array(t).fill(0),sel:0,offset:v(n,3),target:1},o=g(r),a=[];if(d(o,a,f(1),Y),e>=6&&(d(o,a,f(5),Y),d(o,a,f(1),Y)),e>=4&&(d(o,a,_(23,19),Y),d(o,a,f(4),Y),d(o,a,_(8,19),Y)),d(o,a,f(2),Y),k(o,a,3,3,Y),e>=4&&(d(o,a,_(23,19),Y),d(o,a,f(4),Y),k(o,a,3,3,Y)),e>=3)for(let i=1;i<t;i++)d(o,a,_(8+i*15,19),Y),d(o,a,f(2),Y),k(o,a,3,5,Y);if(e>=5){for(let i=0;i<t;i++)d(o,a,_(8+i*15,19),Y),d(o,a,f(2),Y);k(o,a,3,6,Y)}return{state:r,witness:a}},apply:Y,won:e=>e.value.every(n=>n===e.target)&&e.rev.every(n=>n===e.rev[0])&&!e.queue.length&&e.isolated.every(n=>!n)&&Array.from({length:e.n},(n,t)=>Ct(e,t)).every(Boolean),draw(e,n){let t=[...new Set([...e.rev,...e.queue.map(o=>o.rev)])].sort((o,a)=>o-a),r=o=>t.indexOf(o)+1;for(let o=0;o<e.n;o++){let a=8+o*15;j(n,a,12,8+v(o+1,e.n)*15,12,e.isolated[o]?8:1),p(n,a,19,e.value[o]?3:4,!0,e.sel===o),e.isolated[o]&&y(n,a-4,15,9,9,8),L(n,a-4,25,r(e.rev[o]),Math.min(10,t.length),6),p(n,a,32,10,Ct(e,o)),y(n,a-2,41,5,4,3)}e.queue.forEach((o,a)=>{let i=3+a%8*5,l=3+Math.floor(a/8)*4;y(n,i,l,3,3,o.ack?10:o.value?3:4),q(n,i+1,l+1,o.eta?6:8)})}},fe=Array.from({length:12},(e,n)=>{let t=n*Math.PI/6-Math.PI/2;return[24+Math.round(Math.cos(t)*16),23+Math.round(Math.sin(t)*16)]});function Ce(e,n){for(let a=0;a<e.n;a++)z(n,7+a*15,43)&&(e.sel=a);if(n.button===1&&(e.vel[e.sel]*=-1),n.button===3&&(e.hold[e.sel]^=1),n.button===4&&e.hold.fill(0),n.button!==2)return;e.phase=v(e.phase+1,4);let t=e.pos.map((a,i)=>e.hold[i]||e.level>=4&&i===e.n-1&&e.phase%2?a:v(a+e.vel[i],12));if(e.level>=5)for(let a=0;a<e.n;a++)t[a]===0&&e.phase!==0&&(t[a]=e.pos[a],e.vel[a]*=-1);let r=new Set,o=new Set;for(let a=0;a<e.n;a++)for(let i=0;i<e.n;i++)for(let l=i+1;l<e.n;l++)t[i]!==t[l]&&!(t[i]===e.pos[l]&&t[l]===e.pos[i])||(r.add(i),r.add(l),o.add(i+":"+l),t[i]=e.pos[i],t[l]=e.pos[l]);for(let a of[...o].sort()){let[i,l]=a.split(":").map(Number);[e.color[i],e.color[l]]=[e.color[l],e.color[i]],e.level>=6&&(e.charge[i]^=1,e.charge[l]^=1)}for(let a of r)e.vel[a]*=-1;e.pos=t}var Cn={id:"d014",name:"Collision Order",buttons:[1,2,3,4,6],mechanics:["L1 free motion around a ring","L2 collisions reverse velocity and exchange pigment","L3 three bodies create order-dependent encounters","L4 a heavy body moves on alternate ticks","L5 a periodic barrier reflects arrivals","L6 collisions also change dock charge"],vars:["body positions","velocities","pigments","held bodies","barrier phase","collision charge","target positions and properties"],novelty:"Manipulate the order of actual collision events; an encounter changes the participants and therefore their future interactions.",build(e,n){let t=e===1?1:e===2?2:3,r={level:e,n:t,pos:Array.from({length:t},(i,l)=>l*4),vel:Array.from({length:t},(i,l)=>l%2?-1:1),color:Array.from({length:t},(i,l)=>3+l),charge:Array(t).fill(0),hold:Array(t).fill(0),phase:v(n,4),sel:0,target:[]},o=g(r),a=[];for(let i=0;i<10;i++)(i===3||i===6)&&(d(o,a,_(7+v(n+i,t)*15,43),Ce),d(o,a,f(1),Ce)),d(o,a,f(2),Ce);return r.target={pos:o.pos.slice(),vel:o.vel.slice(),color:o.color.slice(),charge:o.charge.slice()},U(r.pos,o.pos)&&U(r.vel,o.vel)&&U(r.color,o.color)&&U(r.charge,o.charge)&&(d(o,a,f(1),Ce),r.target={pos:o.pos.slice(),vel:o.vel.slice(),color:o.color.slice(),charge:o.charge.slice()}),{state:r,witness:a}},apply:Ce,won:e=>U(e.pos,e.target.pos)&&U(e.vel,e.target.vel)&&U(e.color,e.target.color)&&U(e.charge,e.target.charge)&&e.hold.every(n=>!n),draw(e,n){for(let t=0;t<12;t++){j(n,fe[t][0],fe[t][1],fe[(t+1)%12][0],fe[(t+1)%12][1],1);let r=24+Math.round((fe[t][0]-24)*.625),o=23+Math.round((fe[t][1]-23)*.625);q(n,r,o,1)}for(let t=0;t<e.n;t++){let[r,o]=fe[e.target.pos[t]];r=24+Math.round((r-24)*.625),o=23+Math.round((o-23)*.625),y(n,r-2,o-2,5,5,10+t),q(n,r,o,e.target.color[t]),q(n,r+e.target.vel[t]*3,o,15),e.level>=6&&q(n,r,o-3,e.target.charge[t]?10:2),[r,o]=fe[e.pos[t]],p(n,r,o,e.color[t]),y(n,r-2,o-2,5,5,10+t),q(n,r+e.vel[t]*3,o,15),e.level>=6&&q(n,r,o+3,e.charge[t]?10:2),p(n,7+t*15,43,e.color[t],!e.hold[t],e.sel===t),q(n,7+t*15,46,10+t)}e.level>=5&&y(n,21,4,7,6,e.phase===0?3:8),e.level>=4&&me(n,24,23,e.phase,4,6)}},le=[[6,10],[19,10],[33,7],[22,29],[40,31]];function xe(e,n){for(let o=0;o<e.n;o++)z(n,le[o][0],le[o][1])&&(e.sel=o);if(n.button===1&&(e.cut[e.sel]^=1,e.cut[e.sel]&&(e.active[e.sel]=0,e.refractory[e.sel]=0)),n.button===3&&!e.active[0]&&!e.refractory[0]&&!e.cut[0]&&(e.active[0]=1),n.button!==2)return;let t=e.active.slice(),r=e.refractory.slice();for(let o=0;o<e.n;o++){if(e.cut[o])continue;if(t[o]>0){e.active[o]--,e.active[o]||(e.refractory[o]=e.level>=3?2:1);continue}if(r[o]){e.refractory[o]--;continue}let a=e.parents[o].map(c=>t[c]>0),i=e.level>=5&&o===4?a.length>0&&a.every(Boolean):a.some(Boolean),l=e.level>=6&&o===2&&t[3]>0;i&&!l&&(e.active[o]=e.level>=4&&o===3?2:1)}for(let o=0;o<e.n;o++)e.active[o]&&e.targets.includes(o)&&(e.visited[o]=1)}var Xn={id:"d015",name:"Refractory Trails",buttons:[1,2,3,6],mechanics:["L1 traveling excitation","L2 branched waves reach separate destinations","L3 refractory nodes block immediate re-excitation in a cycle","L4 one node retains excitation for an extra tick","L5 a join needs simultaneous parent activity","L6 an inhibitory edge cancels excitation"],vars:["directed excitation graph","active lifetimes","refractory lifetimes","temporary cuts","visited destinations"],novelty:"Guide transient propagating fronts and extinguish them after delivery; propagation depends on causal history and recovery time.",build(e,n){let t=e===1?3:5,r=e===1?[[],[0],[1]]:[[],e>=3?[0,4]:[0],[1],[1],e>=5?[2,3]:[3]],o={level:e,n:t,parents:r,active:Array(t).fill(0),refractory:Array(t).fill(0),cut:Array(t).fill(0),visited:Array(t).fill(0),targets:e===1?[2]:[2,4],sel:0},a=g(o),i=[];d(a,i,f(3),xe);for(let l=0;l<10&&!a.targets.every(c=>a.visited[c]);l++)d(a,i,f(2),xe);for(let l=0;l<t;l++)d(a,i,_(...le[l]),xe),d(a,i,f(1),xe);for(let l=0;l<t;l++)d(a,i,_(...le[l]),xe),d(a,i,f(1),xe);return{state:o,witness:i}},apply:xe,won:e=>e.targets.every(n=>e.visited[n])&&e.active.every(n=>!n)&&e.refractory.every(n=>!n)&&e.cut.every(n=>!n),draw(e,n){for(let t=0;t<e.n;t++)for(let r of e.parents[t])j(n,...le[r],...le[t],e.active[r]?10:1);e.level>=6&&j(n,...le[3],...le[2],8);for(let t=0;t<e.n;t++){let[r,o]=le[t];p(n,r,o,e.active[t]?10:e.refractory[t]?8:3,!!(e.active[t]||e.refractory[t]),e.sel===t),e.cut[t]&&y(n,r-3,o-3,7,7,8),L(n,r-2,o+4,e.active[t],2,10),L(n,r-2,o+8,e.refractory[t],2,8),e.targets.includes(t)&&y(n,r-4,o-4,9,9,e.visited[t]?3:6)}}},Tt=[yn,xn,wn,kn,An,Sn,Mn,En,Ln,_n,qn,Gn,jn,Cn,Xn].map(vn);var Rt={off:1,line:7,good:11,bad:8},S=(e,n)=>(e%n+n)%n,Q=e=>e.reduce((n,t)=>n+t,0);var D=(e,n)=>Math.floor(e()*n);function he(e,n){for(let t=e.length-1;t>0;t--){let r=D(n,t+1);[e[t],e[r]]=[e[r],e[t]]}return e}var R=(e,n,t={})=>({level:e,n:n.length,v:n,d:t,sel:0,pick:-1}),Te=e=>e.v.map((n,t)=>[5+8*(t%7),6+13*Math.floor(t/7)]);function m(e,n,t,r){t>=0&&t<e.length&&n>=0&&n<e[0].length&&(e[t][n]=S(r,16))}function b(e,n,t,r,o,a,i=!1){for(let l=0;l<o;l++)for(let c=0;c<r;c++)(i||!c||!l||c===r-1||l===o-1)&&m(e,n+c,t+l,a)}function J(e,n,t,r){let o=t[0]-n[0],a=t[1]-n[1],i=Math.max(Math.abs(o),Math.abs(a));for(let l=0;l<=i;l++)m(e,n[0]+Math.round(o*l/(i||1)),n[1]+Math.round(a*l/(i||1)),r)}function A(e,n,t,r,o=7,a=14){for(let i=0;i<Math.min(r,a);i++)m(e,n+i%7,t+Math.floor(i/7)*2,o)}function F(e,n,t,r){b(e,n-2,t-2,5,5,2+S(r,12))}function Yn(e,n,t,r,o){F(e,n[0],n[1],t),b(e,n[0]-1,n[1]-1,3,3,2+S(r,12),!0),o&&b(e,n[0]-3,n[1]-3,7,7,15)}function Me(e,n,t,r){b(e,n,t,2,2,r?Rt.good:Rt.bad,!0)}function Tn(e,n,t,r,o,a,i,l=0){F(e,n+2,t+2,r),F(e,n+20,t+2,o),J(e,[n+5,t+2],[n+17,t+2],7),a===0&&(m(e,n+11,t+1,0),m(e,n+11,t+3,0)),a===1&&(J(e,[n+14,t],[n+17,t+2],7),J(e,[n+14,t+4],[n+17,t+2],7)),a===2&&b(e,n+9,t,5,5,7),a===3&&(J(e,[n+9,t],[n+13,t+4],8),J(e,[n+13,t],[n+9,t+4],8)),l&&A(e,n+7,t+6,l,14,9),Me(e,n+25,t+1,i)}function ne(e,n,t=22){n.slice(0,12).forEach((r,o)=>Tn(e,2+o%2*30,t+Math.floor(o/2)*6,r.a,r.b,r.t,r.ok,r.k))}function Ht(e,n,t=14){n.forEach((r,o)=>r.forEach((a,i)=>m(e,3+8*(o%7)+i,t+Math.floor(o/7)*13,2+a)))}function se(e,n,t=Te(e)){e.v.forEach((r,o)=>Yn(n,t[o],o,r,e.sel===o))}function Ke(e,n,t){return!Number.isInteger(n.x)||!Number.isInteger(n.y)?-1:t.findIndex(([r,o])=>Math.abs(r-n.x)<=3&&Math.abs(o-n.y)<=3)}function Rn(e,n,t){let r=(t.positions??Te)(e);if(t.custom){t.custom(e,n);return}if(n.button===6){let o=Ke(e,n,r);o>=0&&(e.sel=o)}else n.button===1?e.sel=S(e.sel-1,e.n):n.button===2?e.sel=S(e.sel+1,e.n):(n.button===3||n.button===4)&&t.change(e,e.sel,n.button===3?1:-1)}function H(e,n,t){let[r,o]=(n.positions??Te)(e)[t];return f(6,r,o)}function dt(e,n,t){if(!n.goal(e))return;let r,o=g(e);function a(i,l){if(!r){if(!l.length){o.v=i,n.goal(o)||(r=i);return}for(let c=0;c<l.length&&!r;c++)a([...i,l[c]],l.filter((s,u)=>u!==c))}}if(a([],Array.from({length:e.n},(i,l)=>l)),!r)throw Error(n.name+" has no failing permutation");for(let i=0;i<e.n;i++){let l=e.v.indexOf(r[i]);for(;l>i;)n.change(e,l-1,1),t.push(l-1),l--}}function On(e,n){return{id:e,name:n.name,family:"logic",version:"1.0.0",levels:6,mechanics:n.mechanics,stateVariables:["object attributes","visible relations","selection","constraint parameters"],novelty:n.novelty,init(t,r){if(!Number.isInteger(t)||t<1||t>6)throw Error("level");let o=ke(r),a=n.make(t,o),i=[];if(n.seed)i=n.seed(a,o);else{if(!n.goal(a))throw Error(e+" construction");let l=[];for(let c=0;c<5+t*2;c++){let s=D(o,a.n);n.change(a,s,1),l.push([H(a,n,s),f(4)])}for(let c=0;n.goal(a)&&c<a.n*2;c++){let s=c%a.n;n.change(a,s,1),l.push([H(a,n,s),f(4)])}for(let c=0;n.goal(a)&&c<a.n;c++){let s=g(a),u=[];for(let h=0;h<12&&n.goal(a);h++)n.change(a,c,1),u.push([H(a,n,c),f(4)]);n.goal(a)?a=s:l.push(...u)}i=l.reverse().flat()}if(a.sel=0,a.pick=-1,n.goal(a))throw Error(e+" initially solved");return{state:a,witness:i}},step(t,r){let o=g(t);return[1,2,3,4,5,6].includes(r.button)&&Rn(o,r,n),o},observe(t){let r=C(64,64);return n.draw(t,r),{pixels:r,actions:n.custom?[1,2,4,6]:[1,2,3,4,6],level:t.level,status:n.goal(t)?"won":"playing"}},solved:n.goal}}var In={name:"Chromatic relations",mechanics:["vertex recoloring","equality and inequality","color population quotas","local palettes"],novelty:"A relational coloring CSP with equality links and population constraints.",make(e,n){let t=e<3?4:6,r=e===1?2:3,o=Array.from({length:t},(l,c)=>c%r),a=[];for(let l=0;l<t-1;l++)a.push([l,l+1,!1]);e>=3&&a.push([0,3,!0]),e>=5&&a.push([1,5,!1],[0,2,!1]);let i=o.map(l=>e>=6?he([l,S(l+1,r)],n):Array.from({length:r},(c,s)=>s));return R(e,o,{k:r,edges:a,allow:i,quota:e>=4?Array.from({length:r},(l,c)=>o.filter(s=>s===c).length):null})},goal(e){return e.d.edges.every(([n,t,r])=>e.v[n]===e.v[t]===r)&&e.v.every((n,t)=>e.d.allow[t].includes(n))&&(!e.d.quota||e.d.quota.every((n,t)=>e.v.filter(r=>r===t).length===n))},change(e,n,t){e.v[n]=S(e.v[n]+t,e.d.k)},draw(e,n){se(e,n),Ht(n,e.d.allow),ne(n,e.d.edges.map(([t,r,o])=>({a:t,b:r,t:o?0:3,ok:e.v[t]===e.v[r]===o}))),e.d.quota&&e.d.quota.forEach((t,r)=>{b(n,3+r*19,58,3,3,r+2,!0),A(n,8+r*19,57,t,7),A(n,8+r*19,60,e.v.filter(o=>o===r).length,11)})}},Qe={name:"Precedence braid",mechanics:["adjacent transpositions","partial order","distance constraints","fixed positions","alternating lanes"],novelty:"Permutation scheduling combines precedence, adjacency, spacing and anchors.",make(e,n){let t=e<3?5:7,r=he(Array.from({length:t},(a,i)=>i),n),o=[];for(let a=0;a<(e===1?2:t-1);a++)o.push([r[a],r[a+1],0,1]);return e>=3&&o.push([r[1],r[2],1,1]),e>=4&&o.push([r[0],r[t-1],2,t-2]),R(e,r,{rel:o,anchor:e>=5?[r[2],2]:null,parity:e>=6?[r[4],0]:null})},goal(e){let n=t=>e.v.indexOf(t);return e.d.rel.every(([t,r,o,a])=>o===0?n(t)<n(r):o===1?Math.abs(n(t)-n(r))===a:Math.abs(n(t)-n(r))>=a)&&(!e.d.anchor||n(e.d.anchor[0])===e.d.anchor[1])&&(!e.d.parity||n(e.d.parity[0])%2===e.d.parity[1])},change(e,n,t){let r=S(n+(t>0?1:-1),e.n);[e.v[n],e.v[r]]=[e.v[r],e.v[n]]},seed(e,n){let t=[],r=[];for(let o=0;o<8+e.level;o++){let a=D(n,e.n-1);Qe.change(e,a,1),r.push(a)}dt(e,Qe,r);for(let o of r.reverse())t.push(H(e,Qe,o+1),f(4));return t},draw(e,n){if(e.v.forEach((t,r)=>{F(n,5+8*r,6,t),e.sel===r&&b(n,2+8*r,3,7,7,15),m(n,5+8*r,13,7),e.level>=6&&m(n,5+8*r,15,2+r%2)}),ne(n,e.d.rel.map(([t,r,o,a])=>({a:t,b:r,t:o===0?1:o===1?0:2,k:o?a:0,ok:o===0?e.v.indexOf(t)<e.v.indexOf(r):o===1?Math.abs(e.v.indexOf(t)-e.v.indexOf(r))===a:Math.abs(e.v.indexOf(t)-e.v.indexOf(r))>=a}))),e.d.anchor){let[t,r]=e.d.anchor;F(n,7,58,t),b(n,15+r*5,55,5,6,14)}e.d.parity&&(F(n,48,58,e.d.parity[0]),m(n,56,58,2))}},Ue={name:"Exclusive correspondences",mechanics:["bijection-preserving exchange","bipartite eligibility","pair compatibility","resource ordering"],novelty:"Ownership exchange under overlapping eligibility and pair constraints.",make(e,n){let t=e<3?4:6,r=he(Array.from({length:t},(i,l)=>l),n),o=r.map((i,l)=>he(Array.from(new Set([i,S(i+1,t),...e<4?[S(i+2,t)]:[]])),n)),a=[];return e>=2&&a.push([0,1,Math.abs(r[0]-r[1])%2,0]),e>=4&&a.push([2,3,r[2]<r[3]?1:-1,1]),e>=5&&a.push([4,5,Math.abs(r[4]-r[5]),2]),R(e,r,{allow:o,rel:a,quota:e>=6?r.slice(0,3).filter(i=>i<3).length:null})},goal(e){return new Set(e.v).size===e.n&&e.v.every((n,t)=>e.d.allow[t].includes(n))&&e.d.rel.every(([n,t,r,o])=>o===0?Math.abs(e.v[n]-e.v[t])%2===r:o===1?(e.v[n]<e.v[t]?1:-1)===r:Math.abs(e.v[n]-e.v[t])===r)&&(e.d.quota===null||e.v.slice(0,3).filter(n=>n<3).length===e.d.quota)},change(e,n,t){let r=S(n+(t>0?1:-1),e.n);[e.v[n],e.v[r]]=[e.v[r],e.v[n]]},seed(e,n){let t=[];for(let r=0;r<7+e.level;r++){let o=D(n,e.n-1);Ue.change(e,o,1),t.push(o)}return dt(e,Ue,t),t.reverse().flatMap(r=>[H(e,Ue,r+1),f(4)])},draw(e,n){se(e,n),e.d.allow.forEach((t,r)=>t.forEach((o,a)=>b(n,3+8*r,14+a*3,4,2,o+2,!0))),ne(n,e.d.rel.map(([t,r,o,a])=>({a:a===1&&o<0?r:t,b:a===1&&o<0?t:r,k:a===1?0:o,t:a===1?1:a===2?2:0,ok:a===0?Math.abs(e.v[t]-e.v[r])%2===o:a===1?(e.v[t]<e.v[r]?1:-1)===o:Math.abs(e.v[t]-e.v[r])===o})),32),e.d.quota!==null&&(b(n,2,54,23,8,14),[0,1,2].forEach((t,r)=>m(n,32+r*3,56,t+2)),A(n,44,56,e.d.quota,7),A(n,44,59,e.v.slice(0,3).filter(t=>t<3).length,11))}},$n={name:"Coupled balances",mechanics:["weighted partition","simultaneous bucket totals","composition constraints","pair separation"],novelty:"Conserved weighted pieces couple quantity, composition and exclusion.",make(e,n){let t=e>=3?3:2,r=e===1?[1,1,1,1,1,1]:[1,3,1,3,2,2],o=t===2?[0,0,1,1,0,1]:[0,0,1,1,2,2],a=t===2?[0,1,0,1,0,1]:[0,1,0,1,0,1],i=Array.from({length:t},(c,s)=>Q(r.filter((u,h)=>o[h]===s))),l=he([0,1,2,3,4,5],n);return R(e,l.map(c=>o[c]),{k:t,w:l.map(c=>r[c]),color:l.map(c=>a[c]),target:i,heavy:e>=5?Array.from({length:t},(c,s)=>r.filter((u,h)=>o[h]===s&&u>=3).length):null,separate:e>=6?[l.indexOf(0),l.indexOf(2)]:null})},goal(e){return e.d.target.every((n,t)=>Q(e.d.w.filter((r,o)=>e.v[o]===t))===n)&&(e.level<4||Array.from({length:e.d.k},(n,t)=>t).every(n=>[0,1].every(t=>e.v.some((r,o)=>r===n&&e.d.color[o]===t))))&&(!e.d.heavy||e.d.heavy.every((n,t)=>e.v.filter((r,o)=>r===t&&e.d.w[o]>=3).length===n))&&(!e.d.separate||e.v[e.d.separate[0]]!==e.v[e.d.separate[1]])},change(e,n,t){e.v[n]=S(e.v[n]+t,e.d.k)},draw(e,n){se(e,n),e.d.w.forEach((t,r)=>{A(n,3+8*r,13,t,7),e.level>=4&&b(n,3+8*r,17,4,2,12+e.d.color[r],!0)});for(let t=0;t<e.d.k;t++){let r=25+t*10;b(n,2,r,5,7,t+2),A(n,10,r,e.d.target[t],7),A(n,10,r+3,Q(e.d.w.filter((o,a)=>e.v[a]===t)),11),e.d.heavy&&(b(n,32,r,3,3,14),A(n,38,r,e.d.heavy[t],7),A(n,38,r+3,e.v.filter((o,a)=>o===t&&e.d.w[a]>=3).length,11))}e.d.separate&&ne(n,[{a:e.d.separate[0],b:e.d.separate[1],t:3,ok:e.v[e.d.separate[0]]!==e.v[e.d.separate[1]]}],57)}};function Ot(e,n,t){let r=Array.from({length:e},(o,a)=>Array.from({length:e},(i,l)=>a===l?0:99));n.forEach(([o,a],i)=>{t[i]&&(r[o][a]=r[a][o]=1)});for(let o=0;o<e;o++)for(let a=0;a<e;a++)for(let i=0;i<e;i++)r[a][i]=Math.min(r[a][i],r[a][o]+r[o][i]);return r}var Ft={name:"Transitive islands",mechanics:["edge switching","transitive connectivity","separation","acyclic edge budget","path and degree bounds"],novelty:"A reachability puzzle with global consequences from each edge.",positions(e){return e.v.map((n,t)=>[5+t%6*10,25+Math.floor(t/6)*10])},make(e,n){let t=e<3?4:6,r=Array.from({length:t},(l,c)=>e>=2&&c>=t-2?1:0),o=[];for(let l=0;l<t;l++)for(let c=l+1;c<t;c++)o.push([l,c]);let a=o.map(([l,c])=>c===l+1&&r[l]===r[c]?1:0),i=[];for(let l=1;l<t;l++)i.push([l-1,l,r[l-1]===r[l]]);return R(e,a,{nodes:t,e:o,rel:i,limit:e>=3?Q(a):null,path:e>=4?[0,t-3,t-3]:null,degree:e>=5?2:null,bridge:e>=6?[0,2]:null})},goal(e){let n=Ot(e.d.nodes,e.d.e,e.v),t=Array(e.d.nodes).fill(0);return e.d.e.forEach(([r,o],a)=>{e.v[a]&&(t[r]++,t[o]++)}),e.d.rel.every(([r,o,a])=>n[r][o]<99===a)&&(e.d.limit===null||Q(e.v)<=e.d.limit)&&(!e.d.path||n[e.d.path[0]][e.d.path[1]]<=e.d.path[2])&&(e.d.degree===null||t.every(r=>r<=e.d.degree))&&(!e.d.bridge||n[e.d.bridge[0]][e.d.bridge[1]]===2)},change(e,n){e.v[n]=1-e.v[n]},draw(e,n){let t=Array.from({length:e.d.nodes},(a,i)=>[5+9*i,6]);e.d.e.forEach(([a,i],l)=>{e.v[l]&&J(n,t[a],t[i],9)}),t.forEach((a,i)=>F(n,a[0],a[1],i));let r=Ot(e.d.nodes,e.d.e,e.v);e.d.rel.forEach(([a,i,l],c)=>{let s=2+c*10;m(n,s,13,a+2),m(n,s+4,13,i+2),m(n,s+2,12,l?7:8),Me(n,s+1,16,r[a][i]<99===l)});let o=Ft.positions(e);e.v.forEach((a,i)=>{let[l,c]=o[i];b(n,l-3,c-3,7,7,i===e.sel?15:1),m(n,l-2,c,e.d.e[i][0]+2),m(n,l+2,c,e.d.e[i][1]+2),J(n,[l-1,c],[l+1,c],a?11:7)}),e.d.limit!==null&&(A(n,3,58,e.d.limit,7),A(n,3,61,Q(e.v),11)),e.d.path&&(m(n,22,58,e.d.path[0]+2),m(n,32,58,e.d.path[1]+2),A(n,25,61,e.d.path[2],14)),e.d.degree&&b(n,39,56,5,5,14),e.d.bridge&&(m(n,50,58,e.d.bridge[0]+2),m(n,58,58,e.d.bridge[1]+2),m(n,54,58,14))}},Nn={name:"Independent sentinels",mechanics:["neighborhood coverage","selection conflict","weighted budget","redundancy","forbidden nodes"],novelty:"Covering, independence and redundancy pull a shared selection in different directions.",make(e,n){let t=7,r=[];for(let l=0;l<6;l++)r.push([l,l+1]);e>=3&&r.push([0,3],[3,6]);let o=[0,1,0,1,0,1,0],a=Array.from({length:t},()=>1+D(n,3)),i=Array(t).fill(1);return e>=5&&(i[2]=2,i[4]=2),R(e,o,{e:r,cost:a,need:i,budget:e>=3?Q(a.filter((l,c)=>o[c])):null,forbid:e>=6?[0,6]:[],split:e>=4})},goal(e){return e.v.map((t,r)=>t+e.d.e.reduce((o,[a,i])=>o+(a===r?e.v[i]:i===r?e.v[a]:0),0)).every((t,r)=>t>=e.d.need[r])&&(e.level<2||e.d.e.every(([t,r])=>!e.v[t]||!e.v[r]))&&(e.d.budget===null||Q(e.d.cost.filter((t,r)=>e.v[r]))<=e.d.budget)&&e.d.forbid.every(t=>!e.v[t])&&(!e.d.split||e.v.slice(0,3).some(Boolean)&&e.v.slice(4).some(Boolean))},change(e,n){e.v[n]=1-e.v[n]},draw(e,n){let t=Te(e);e.d.e.forEach(([r,o])=>J(n,[t[r][0],20],[t[o][0],20],7)),se(e,n),e.v.forEach((r,o)=>{A(n,3+8*o,13,e.d.cost[o],14),A(n,3+8*o,16,e.d.need[o],7);let a=r+e.d.e.reduce((i,[l,c])=>i+(l===o?e.v[c]:c===o?e.v[l]:0),0);Me(n,4+8*o,23,a>=e.d.need[o]),e.d.forbid.includes(o)&&J(n,[2+8*o,3],[8+8*o,9],8)}),ne(n,e.d.e.map(([r,o])=>({a:r,b:o,t:3,ok:e.level<2||!e.v[r]||!e.v[o]})),30),e.d.budget!==null&&(A(n,3,59,e.d.budget,7),A(n,24,59,Q(e.d.cost.filter((r,o)=>e.v[o])),11)),e.d.split&&(b(n,2,27,22,2,14),b(n,34,27,22,2,14))}};function It(e){let n=[];return e.map(t=>(n.includes(t)||n.push(t),n.indexOf(t)))}var st={name:"Equivalence chambers",mechanics:["class union","singleton split","must-link and cannot-link","class capacity","composition diversity"],novelty:"Operations manipulate equivalence classes rather than independent labels.",make(e,n){let t=e<3?4:6,r=e<3?[0,0,1,1]:[0,0,0,1,1,1],o=[[0,1,!0],[t-2,t-1,!0]];return e>=2&&o.push([0,t-1,!1]),e>=3&&o.push([1,2,!0]),e>=4&&o.push([2,3,!1]),R(e,Array.from({length:t},(a,i)=>i),{rel:o,max:e>=3?3:t,diverse:e>=5,color:r.map((a,i)=>i%3),groups:e>=6?2:null,join:r})},goal(e){let n=[...new Set(e.v)];return e.d.rel.every(([t,r,o])=>e.v[t]===e.v[r]===o)&&n.every(t=>e.v.filter(r=>r===t).length<=e.d.max)&&(!e.d.diverse||n.every(t=>new Set(e.d.color.filter((r,o)=>e.v[o]===t)).size>=2))&&(!e.d.groups||n.length===e.d.groups)},change(){},custom(e,n){if(n.button===6){let t=Ke(e,n,Te(e));if(t<0)return;if(e.sel=t,e.pick<0)e.pick=t;else{let r=e.v[t],o=e.v[e.pick];e.v=It(e.v.map(a=>a===r?o:a)),e.pick=-1}}else n.button===4&&e.pick>=0?(e.v[e.pick]=Math.max(...e.v)+1,e.v=It(e.v),e.pick=-1):(n.button===1||n.button===2)&&(e.sel=S(e.sel+(n.button===1?-1:1),e.n),e.pick=e.sel)},seed(e){let n=e.d.join;delete e.d.join;let t=[];for(let r=0;r<e.n;r++){let o=n.indexOf(n[r]);o!==r&&t.push(H(e,st,o),H(e,st,r))}return t},draw(e,n){se(e,n),e.pick>=0&&b(n,1+e.pick*8,2,9,9,14),e.d.diverse&&e.d.color.forEach((r,o)=>m(n,5+o*8,14,r+12)),[...new Set(e.v)].forEach((r,o)=>{let a=18+o*3;e.v.forEach((i,l)=>{i===r&&m(n,5+l*8,a,r+2)})}),ne(n,e.d.rel.map(([r,o,a])=>({a:r,b:o,t:a?0:3,ok:e.v[r]===e.v[o]===a})),39),A(n,3,60,e.d.max,7),e.d.groups&&A(n,25,60,e.d.groups,14)}},$t=e=>e.v.map((n,t)=>[e.d.cols===4?8+t%4*15:10+t%e.d.cols*19,9+Math.floor(t/e.d.cols)*19]);function ae(e,n,t){return e.d.faces[n][S(t-e.v[n],4)]}function Ye(e,n,t){return e.d.poles[n][S(t-e.v[n],4)]}var Bn={name:"Rotating correspondences",mechanics:["oriented edge matching","boundary compatibility","paired gear rotation","counterrotation"],novelty:"Rotational tile matching with geometric coupling, without translation.",positions:$t,make(e,n){let t=e===1?4:3,r=e===1?1:2,o=t*r,a=Array.from({length:o},()=>[0,0,0,0]),i=Array.from({length:o},()=>[0,0,0,0]);for(let l=0;l<o;l++){if(l%t<t-1){let c=1+D(n,2),s=e>=3?D(n,2)?1:-1:0;a[l][1]=c,a[l+1][3]=c,i[l][1]=s,i[l+1][3]=-s}if(l+t<o){let c=1+D(n,2),s=e>=3?D(n,2)?1:-1:0;a[l][2]=c,a[l+t][0]=c,i[l][2]=s,i[l+t][0]=-s}}return R(e,Array(o).fill(0),{cols:t,rows:r,faces:a,poles:i,gears:e>=5?[[0,1,1],...e>=6?[[3,4,-1],[1,4,1]]:[]]:[],boundary:e>=4})},goal(e){for(let n=0;n<e.n;n++)if(n%e.d.cols<e.d.cols-1&&(ae(e,n,1)!==ae(e,n+1,3)||Ye(e,n,1)+Ye(e,n+1,3)!==0)||n+e.d.cols<e.n&&(ae(e,n,2)!==ae(e,n+e.d.cols,0)||Ye(e,n,2)+Ye(e,n+e.d.cols,0)!==0)||e.d.boundary&&(n<e.d.cols&&ae(e,n,0)!==0||n%e.d.cols===0&&ae(e,n,3)!==0||n%e.d.cols===e.d.cols-1&&ae(e,n,1)!==0||n+e.d.cols>=e.n&&ae(e,n,2)!==0))return!1;return!0},change(e,n,t){e.v[n]=S(e.v[n]+t,4);for(let[r,o,a]of e.d.gears)n===r&&(e.v[o]=S(e.v[o]+t*a,4)),n===o&&(e.v[r]=S(e.v[r]+t*a,4))},draw(e,n){let t=$t(e);e.v.forEach((r,o)=>{let[a,i]=t[o];b(n,a-7,i-7,15,15,e.sel===o?15:7),F(n,a,i,o),[[0,-5],[5,0],[0,5],[-5,0]].forEach(([l,c],s)=>{b(n,a+l-1,i+c-1,3,3,ae(e,o,s)?ae(e,o,s)+2:1,!0);let u=Ye(e,o,s);u&&m(n,a+l,i+c,u===1?12:13)})}),e.d.gears.forEach(([r,o,a])=>{let i=t[r],l=t[o],c=Math.round((i[0]+l[0])/2),s=Math.round((i[1]+l[1])/2);b(n,c-1,s-1,3,3,a===1?14:8)}),e.d.boundary&&b(n,1,1,59,e.d.rows*19-1,14)}};function ct(e,n){let t=new Set,r=n,o=0;for(;r>=e.d.sinks;){if(t.has(r))return[-1,99];t.add(r),r=e.v[r],o++}return[r,o]}var Dn={name:"Successor basins",mechanics:["functional graph routing","cycle avoidance","sink ownership","fan-in capacity","depth bounds"],novelty:"Pointer routing requires reasoning about descendants and terminal basins.",make(e,n){let t=6,r=e>=2?2:1,o=r===1?[0,0,1,2,3,4]:[0,1,0,1,2,3],a=o.map((l,c)=>c<r?c:r===1?0:c%2),i=o.map((l,c)=>Array.from({length:t},(s,u)=>u));return e>=6&&(i[4]=[0,2,3,4,5]),R(e,o,{sinks:r,owners:a,allow:i,cap:e>=3?2:null,depth:e>=4?[0,0,1,1,2,2]:null,span:e>=5?Q(o.map((l,c)=>c>=r?Math.abs(c-l):0)):null})},goal(e){let n=e.v.map((r,o)=>ct(e,o)),t=Array(e.n).fill(0);for(let r=e.d.sinks;r<e.n;r++)t[e.v[r]]++;return n.every(([r,o],a)=>r>=0&&(e.level<2||r===e.d.owners[a])&&(!e.d.depth||o<=e.d.depth[a]))&&(!e.d.cap||t.every(r=>r<=e.d.cap))&&e.v.every((r,o)=>e.d.allow[o].includes(r))&&(e.d.span===null||Q(e.v.map((r,o)=>o>=e.d.sinks?Math.abs(o-r):0))<=e.d.span)},change(e,n,t){n>=e.d.sinks&&(e.v[n]=S(e.v[n]+t,e.n))},draw(e,n){se(e,n);for(let t=0;t<e.n;t++)t<e.d.sinks?b(n,1+8*t,2,9,9,14):(m(n,5+8*t,14,e.d.owners[t]+2),e.d.depth&&A(n,3+8*t,17,e.d.depth[t],7),Me(n,4+8*t,21,ct(e,t)[0]===e.d.owners[t]));ne(n,e.v.slice(e.d.sinks).map((t,r)=>({a:r+e.d.sinks,b:t,t:1,ok:ct(e,r+e.d.sinks)[0]>=0})),29),Ht(n,e.d.allow,49),e.d.cap&&A(n,3,60,e.d.cap,14),e.d.span!==null&&A(n,23,60,e.d.span,7)}},Hn=e=>e.v.map((n,t)=>[5,6+t*9]),Fn={name:"Interval concordance",mechanics:["interval placement","resource overlap","precedence","cooldown","coupled shifts","release windows"],novelty:"Temporal resource constraints with linked scheduling controls.",positions:Hn,make(e,n){let t=[0,2,4,6],r=e===1?[1,1,1,1]:[2,1,2,1],o=e>=3?[1,3,2,3]:[1,1,1,1],a=e>=2?[[0,2,0]]:[];return e>=4&&a.push([1,3,1]),R(e,t,{duration:r,resources:o,rel:a,gears:e>=5?[[0,2,1],...e>=6?[[1,3,-1]]:[]]:[],windows:e>=6?[[0,2],[1,4],[3,6],[5,8]]:Array.from({length:4},()=>[0,8])})},goal(e){for(let n=0;n<e.n;n++){if(e.v[n]<e.d.windows[n][0]||e.v[n]>e.d.windows[n][1])return!1;for(let t=n+1;t<e.n;t++)if(e.d.resources[n]&e.d.resources[t]&&e.v[n]<e.v[t]+e.d.duration[t]&&e.v[t]<e.v[n]+e.d.duration[n])return!1}return e.d.rel.every(([n,t,r])=>e.v[n]+e.d.duration[n]+r<=e.v[t])},change(e,n,t){e.v[n]=S(e.v[n]+t,9);for(let[r,o,a]of e.d.gears)n===r&&(e.v[o]=S(e.v[o]+t*a,9)),n===o&&(e.v[r]=S(e.v[r]+t*a,9))},draw(e,n){e.v.forEach((t,r)=>{let o=6+r*9;F(n,5,o,r),e.sel===r&&b(n,2,o-3,7,7,15);for(let a=0;a<11;a++)m(n,12+a*4,o+3,7),a>=e.d.windows[r][0]&&a<=e.d.windows[r][1]&&m(n,12+a*4,o-3,1);b(n,12+t*4,o-1,e.d.duration[r]*4-1,3,2+r,!0),e.d.resources[r]&1&&m(n,9,o-1,12),e.d.resources[r]&2&&m(n,9,o+1,13)}),ne(n,e.d.rel.map(([t,r,o])=>({a:t,b:r,t:1,k:o,ok:e.v[t]+e.d.duration[t]+o<=e.v[r]})),44),e.d.gears.forEach(([t,r,o],a)=>{m(n,5+a*18,59,t+2),m(n,15+a*18,59,r+2),m(n,10+a*18,59,o===1?14:8)})}};function Nt(e){let n=[];for(let t=0;t<e.n;t++)for(let r=0;r<e.n;r++){let o=e.v.indexOf(r);r!==e.v[t]&&e.d.left[t][r]<e.d.left[t][e.v[t]]&&e.d.right[r][t]<e.d.right[r][o]&&n.push([t,r])}return n}function Vn(e,n){let t=e.length,r=Array(t).fill(-1),o=Array(t).fill(-1),a=Array(t).fill(0),i=e.map(l=>Array.from({length:t},(c,s)=>s).sort((c,s)=>l[c]-l[s]));for(;r.includes(-1);){let l=r.indexOf(-1),c=i[l][a[l]++];o[c]<0?(o[c]=l,r[l]=c):n[c][l]<n[c][o[c]]&&(r[o[c]]=-1,o[c]=l,r[l]=c)}return r}var We={name:"Stable reciprocities",mechanics:["two-sided rankings","blocking pairs","preference ties","regional quota","accepted pair constraints"],novelty:"Stability is relational and differs from maximizing individual preference.",make(e,n){let t=e===1?3:e===6?6:4,r=()=>{let l=he(Array.from({length:t},(c,s)=>s),n);return Array.from({length:t},(c,s)=>l.indexOf(s))},o=Array.from({length:t},r),a=Array.from({length:t},r);e>=3&&(o[0]=o[0].map(l=>Math.floor(l/2)),a[1]=a[1].map(l=>Math.floor(l/2)));let i=Vn(o,a);return R(e,i,{left:o,right:a,quota:e>=4?i.slice(0,2).filter(l=>l<2).length:null,anchor:e>=5?[0,i[0]]:null,cost:e>=6?Math.max(...i.map((l,c)=>o[c][l]+a[l][c])):null})},goal(e){return new Set(e.v).size===e.n&&!Nt(e).length&&(e.d.quota===null||e.v.slice(0,2).filter(n=>n<2).length===e.d.quota)&&(!e.d.anchor||e.v[e.d.anchor[0]]===e.d.anchor[1])&&(e.d.cost===null||Math.max(...e.v.map((n,t)=>e.d.left[t][n]+e.d.right[n][t]))<=e.d.cost)},change(e,n,t){let r=S(n+(t>0?1:-1),e.n);[e.v[n],e.v[r]]=[e.v[r],e.v[n]]},seed(e,n){let t=[];for(let r=0;r<9+e.level;r++){let o=D(n,e.n-1);We.change(e,o,1),t.push(o)}return dt(e,We,t),t.reverse().flatMap(r=>[H(e,We,r+1),f(4)])},draw(e,n){se(e,n);for(let t=0;t<2;t++){let r=t?e.d.right:e.d.left,o=t?35:4;b(n,o-2,12,5,3,t?14:7);for(let a=0;a<e.n;a++){let i=19+a*6;F(n,o,i,a);let l=Array.from({length:e.n},(c,s)=>s).sort((c,s)=>r[a][c]-r[a][s]);l.forEach((c,s)=>{m(n,o+7+s*4,i,c+2),s&&r[a][c]===r[a][l[s-1]]&&J(n,[o+3+s*4,i+2],[o+7+s*4,i+2],7)})}}Nt(e).slice(0,5).forEach(([t,r],o)=>{m(n,3+o*10,55,t+2),m(n,7+o*10,55,r+2),Me(n,5+o*10,57,!1)}),e.d.quota!==null&&A(n,2,61,e.d.quota,14),e.d.anchor&&(m(n,25,61,e.d.anchor[0]+2),m(n,29,61,e.d.anchor[1]+2)),e.d.cost!==null&&A(n,40,61,e.d.cost,7)}},ze=e=>e.v.map((n,t)=>[7+t%2*8,6+Math.floor(t/2)*12]),ce={name:"Reciprocal bundles",mechanics:["conserved multiset exchange","bundle demands","diversity","wealth fairness","restricted trading graph"],novelty:"Multi-item ownership introduces conserved inventory and transfer routing.",positions:ze,make(e,n){let t=he([0,1,1,2,2,0,0,2],n),r=Array.from({length:4},(a,i)=>t[2*i]),o=Array.from({length:4},(a,i)=>t[2*i]+t[2*i+1]+2);return R(e,t,{demand:r,variety:e>=2?t.filter((a,i)=>i%2===0).map((a,i)=>a!==t[2*i+1]):null,minimum:e>=3?o.map(a=>Math.max(2,a-1)):null,fair:e>=4?Math.max(...o)-Math.min(...o):null,adjacent:e>=5,paired:e>=6})},goal(e){let n=Array.from({length:4},(r,o)=>e.v.slice(2*o,2*o+2)),t=n.map(r=>Q(r)+2);return n.every((r,o)=>r.includes(e.d.demand[o])&&(!e.d.variety||!e.d.variety[o]||r[0]!==r[1])&&(!e.d.minimum||t[o]>=e.d.minimum[o]))&&(e.d.fair===null||Math.max(...t)-Math.min(...t)<=e.d.fair)},change(){},custom(e,n){if(n.button===6){let t=Ke(e,n,ze(e));if(t<0)return;if(e.sel=t,e.pick<0)e.pick=t;else{let r=e.pick,o=Math.floor(t/2),a=Math.floor(r/2),i=!e.d.adjacent||o===a||Math.abs(o-a)===1||Math.abs(o-a)===3;e.d.paired&&o!==a&&(i=i&&t%2===r%2),i&&([e.v[t],e.v[r]]=[e.v[r],e.v[t]]),e.pick=-1}}else n.button===4?e.pick=-1:(n.button===1||n.button===2)&&(e.sel=S(e.sel+(n.button===1?-1:1),e.n),e.pick=e.sel)},seed(e,n){let t=[];for(let r=0;r<10+e.level;r++){let o=D(n,e.n),a=Math.floor(o/2),i=e.d.adjacent?S(a+1,4):D(n,4),l=e.d.paired?i*2+o%2:i*2+D(n,2);[e.v[o],e.v[l]]=[e.v[l],e.v[o]],t.push([o,l])}if(ce.goal(e)){let r=!1;for(let o=0;o<8&&!r;o++)for(let a=0;a<8&&!r;a++){let i=g(e);ce.custom(i,H(i,ce,o)),ce.custom(i,H(i,ce,a)),ce.goal(i)||(e.v=i.v,t.push([o,a]),r=!0)}}return t.reverse().flatMap(([r,o])=>[H(e,ce,r),H(e,ce,o)])},draw(e,n){e.v.forEach((t,r)=>{let[o,a]=ze(e)[r];b(n,o-2,a-2,5,5,t+2,!0),e.sel===r&&b(n,o-3,a-3,7,7,15)});for(let t=0;t<4;t++){let r=6+t*12;F(n,24,r,t),b(n,31,r-1,3,3,e.d.demand[t]+2,!0),e.d.variety?.[t]&&(m(n,38,r-1,7),m(n,41,r+1,7)),e.d.minimum&&A(n,46,r-1,e.d.minimum[t],7),e.d.adjacent&&t<3&&J(n,[24,r+3],[24,r+9],14)}if(e.pick>=0){let[t,r]=ze(e)[e.pick];b(n,t-4,r-4,9,9,14)}e.d.fair!==null&&A(n,3,60,e.d.fair,14),e.d.paired&&(J(n,[7,49],[7,57],14),J(n,[15,49],[15,57],14))}},zn={name:"Shared bindings",mechanics:["simultaneous substitution","spare symbol","global occurrence coupling","intersecting palettes","relational exclusions"],novelty:"A binding operation affects all occurrences while preserving distinct symbols.",make(e,n){let t=e===1?2:e===2?3:4,r=he(Array.from({length:t},(l,c)=>c),n),o=Array.from({length:e>=4?t*2:t},(l,c)=>c%t),a=o.map((l,c)=>[r[l],S(r[l]+(c<t?1:2),t+1)]),i=[];return e>=3&&i.push([0,1,r[0]<r[1]?1:-1]),e>=5&&i.push([2,3,r[2]<r[3]?1:-1]),R(e,r,{k:t+1,occ:o,allow:a,rel:i,span:e>=6?Math.abs(r[0]-r[3]):null})},goal(e){return new Set(e.v).size===e.n&&e.d.occ.every((n,t)=>e.d.allow[t].includes(e.v[n]))&&e.d.rel.every(([n,t,r])=>(e.v[n]<e.v[t]?1:-1)===r)&&(e.d.span===null||Math.abs(e.v[0]-e.v[3])===e.d.span)},change(e,n){let t=Array.from({length:e.d.k},(r,o)=>o).find(r=>!e.v.includes(r));e.v[n]=t},draw(e,n){se(e,n);let t=Array.from({length:e.d.k},(r,o)=>o).find(r=>!e.v.includes(r));b(n,55,4,7,7,14),b(n,57,6,3,3,t+2,!0),e.d.occ.forEach((r,o)=>{let a=5+o%4*15,i=23+Math.floor(o/4)*13;F(n,a,i,r),b(n,a-1,i-1,3,3,e.v[r]+2,!0),e.d.allow[o].forEach((l,c)=>b(n,a-3+c*4,i+5,3,2,l+2,!0))}),ne(n,e.d.rel.map(([r,o,a])=>({a:a===1?r:o,b:a===1?o:r,t:1,ok:(e.v[r]<e.v[o]?1:-1)===a})),48),e.d.span!==null&&A(n,4,62,e.d.span,14)}};function Bt(e,n){return e.d.influence[n].reduce((t,[r,o])=>t+(e.v[r]===o?1:0),0)}var Jn={name:"Conditional coalitions",mechanics:["guarded binary transition","neighbor thresholds","signed influence","fixed anchors","relational consensus"],novelty:"Reachable transitions depend on local context, making move order causal.",make(e,n){let t=6,r=Array.from({length:t},(l,c)=>e>=4?c%2:1),o=Array.from({length:t},(l,c)=>[[S(c-1,t),r[S(c-1,t)]],[S(c+1,t),r[S(c+1,t)]]]),a=Array.from({length:t},(l,c)=>e>=3&&c%2===0?2:1);e>=5&&(o[2].push([4,1-r[4]]),o[4].push([1,1-r[1]]));let i=Array.from({length:t-1},(l,c)=>[c,c+1,r[c]===r[c+1]]);return R(e,r,{influence:o,threshold:a,rel:i,anchors:e>=2?[[0,r[0]]]:[],protected:e>=6?[0]:[]})},goal(e){return e.d.rel.every(([n,t,r])=>e.v[n]===e.v[t]===r)&&e.d.anchors.every(([n,t])=>e.v[n]===t)},change(e,n){!e.d.protected.includes(n)&&Bt(e,n)>=e.d.threshold[n]&&(e.v[n]=1-e.v[n])},draw(e,n){se(e,n),e.v.forEach((t,r)=>{A(n,3+8*r,13,e.d.threshold[r],7),Me(n,4+8*r,17,!e.d.protected.includes(r)&&Bt(e,r)>=e.d.threshold[r])}),e.d.influence.forEach((t,r)=>t.forEach(([o,a],i)=>{m(n,3+8*r+i*2,22,o+2),m(n,3+8*r+i*2,24,a+2)})),ne(n,e.d.rel.map(([t,r,o])=>({a:t,b:r,t:o?0:3,ok:e.v[t]===e.v[r]===o})),31),e.d.anchors.forEach(([t,r])=>{F(n,5+t*8,57,t),m(n,5+t*8,61,r+2)}),e.d.protected.forEach(t=>b(n,1+8*t,2,9,9,14))}},Dt=e=>e.v.map((n,t)=>[7,5+t*8]);function te(e,n){let t=[],r=e.v[n];for(;r>=0&&!t.includes(r);)t.push(r),r=e.v[r];return t}function Je(e){return e.v.map((n,t)=>Q(e.d.weight.filter((r,o)=>te(e,o).includes(t))))}var ut={name:"Nested jurisdictions",mechanics:["subtree reparenting","ancestry constraints","cycle prevention","capacity","depth","sibling exclusions"],novelty:"Containment has transitive ancestry and subtree weight effects.",positions:Dt,make(e,n){let t=e===1?4:6,r=t===4?[-1,-1,0,1]:[-1,-1,0,0,2,1],o=Array.from({length:t},()=>1+D(n,e>=5?3:1)),a=R(e,r,{weight:o}),i=Je(a).map(c=>Math.max(2,c)),l=[[0,2,0],[1,t-1,0]];return e>=2&&l.push([0,1,2]),e>=3&&l.push([0,4,1]),e>=4&&l.push([2,5,2]),R(e,Array(t).fill(-1),{weight:o,cap:e>=5?i:Array(t).fill(30),rel:l,depth:e>=2?2:t,sibling:e>=6?[3,5]:null,build:r})},goal(e){return e.d.rel.every(([n,t,r])=>r===0?e.v[t]===n:r===1?te(e,t).includes(n):!te(e,n).includes(t)&&!te(e,t).includes(n))&&e.v.every((n,t)=>te(e,t).length<=e.d.depth)&&Je(e).every((n,t)=>n<=e.d.cap[t])&&(!e.d.sibling||e.v[e.d.sibling[0]]!==e.v[e.d.sibling[1]])},change(){},custom(e,n){if(n.button===6){let t=Ke(e,n,Dt(e));if(t<0)return;if(e.sel=t,e.pick<0)e.pick=t;else{let r=e.pick;if(e.pick=-1,t===r||te(e,t).includes(r))return;let o=e.v[r];e.v[r]=t,(e.v.some((a,i)=>te(e,i).length>e.d.depth)||Je(e).some((a,i)=>a>e.d.cap[i]))&&(e.v[r]=o)}}else n.button===4?(e.pick>=0&&(e.v[e.pick]=-1),e.pick=-1):(n.button===1||n.button===2)&&(e.sel=S(e.sel+(n.button===1?-1:1),e.n),e.pick=e.sel)},seed(e){let n=e.d.build;return delete e.d.build,n.flatMap((t,r)=>t<0?[]:[H(e,ut,r),H(e,ut,t)])},draw(e,n){let t=Je(e);e.v.forEach((r,o)=>{let a=5+o*8;F(n,7,a,o),e.sel===o&&b(n,4,a-3,7,7,15),e.pick===o&&b(n,3,a-4,9,9,14),te(e,o).forEach((l,c)=>b(n,16+c*5,a-2,4,5,l+2)),A(n,32,a-1,e.d.weight[o],7),e.level>=5&&(A(n,42,a-2,e.d.cap[o],7),A(n,42,a+1,t[o],11))}),ne(n,e.d.rel.map(([r,o,a])=>({a:r,b:o,t:a===2?3:a===1?2:1,ok:a===0?e.v[o]===r:a===1?te(e,o).includes(r):!te(e,r).includes(o)&&!te(e,o).includes(r)})),51),e.d.sibling&&(m(n,55,45,e.d.sibling[0]+2),m(n,59,45,e.d.sibling[1]+2),m(n,57,43,8)),A(n,52,49,e.d.depth,14)}},Vt=[In,Qe,Ue,$n,Ft,Nn,st,Bn,Dn,Fn,We,ce,zn,Jn,ut].map((e,n)=>On(`e${String(n+1).padStart(3,"0")}`,e));var Ze={models:[{name:"GPT-6 Astra",id:"gpt-6-astra",rank:1,full:135,levels:848,fullRate:90,levelRate:94.22222222222223,time:6,action:9,abandoned:0,depth:[2,2,4,3,1,3,135]},{name:"GPT-5.6 Sol",id:"gpt-5.6-sol",rank:2,full:29,levels:357,fullRate:19.333333333333332,levelRate:39.666666666666664,time:73,action:47,abandoned:1,depth:[50,22,16,12,12,9,29]},{name:"GPT-6 Sol",id:"gpt-6-sol",rank:3,full:22,levels:369,fullRate:14.666666666666666,levelRate:41,time:122,action:6,abandoned:0,depth:[32,27,27,21,12,9,22]},{name:"GPT-5.6 Terra",id:"gpt-5.6-terra",rank:4,full:20,levels:282,fullRate:13.333333333333334,levelRate:31.333333333333332,time:69,action:59,abandoned:2,depth:[68,18,15,11,9,9,20]},{name:"GPT-5.6 Luna",id:"gpt-5.6-luna",rank:5,full:4,levels:160,fullRate:2.6666666666666665,levelRate:17.77777777777778,time:118,action:23,abandoned:5,depth:[83,22,21,12,4,4,4]},{name:"Qwen 3.8 Flash",id:"qwen3.8-flash",rank:6,full:2,levels:114,fullRate:1.3333333333333333,levelRate:12.666666666666666,time:125,action:0,abandoned:23,depth:[95,22,18,9,3,1,2]},{name:"GPT-6 Luna",id:"gpt-6-luna",rank:6,full:2,levels:89,fullRate:1.3333333333333333,levelRate:9.88888888888889,time:143,action:4,abandoned:1,depth:[102,27,9,9,0,1,2]},{name:"Qwen 3.8 Max 0902",id:"qwen3.8-max-0902",rank:8,full:1,levels:88,fullRate:.6666666666666666,levelRate:9.777777777777779,time:149,action:0,abandoned:0,depth:[100,29,10,7,3,0,1]},{name:"DeepSeek V4.1 Flash",id:"deepseek-v4.1-flash",rank:9,full:0,levels:63,fullRate:0,levelRate:7,time:150,action:0,abandoned:0,depth:[111,26,6,4,2,1,0]},{name:"Kimi K3",id:"kimi-k3",rank:9,full:0,levels:38,fullRate:0,levelRate:4.222222222222222,time:150,action:0,abandoned:0,depth:[126,13,9,1,1,0,0]},{name:"GLM 5.3 Flash",id:"ZHIPU/GLM-5.3-Flash",rank:9,full:0,levels:28,fullRate:0,levelRate:3.111111111111111,time:150,action:0,abandoned:0,depth:[128,17,4,1,0,0,0]}],cases:[{id:"a001",seed:503117,initial:"a001-initial.png",entry:"a001-level4-entry.png",panels:[{model:"GPT-6 Astra",file:"a001-astra-terminal.png",levels:6,actions:33,seconds:174.151,end:"won",levelShown:6},{model:"DeepSeek V4.1 Flash",file:"a001-deepseek-terminal.png",levels:5,actions:38,seconds:719.989,end:"time_budget",levelShown:6},{model:"GPT-6 Luna",file:"a001-luna-terminal.png",levels:3,actions:46,seconds:720,end:"time_budget",levelShown:4}]},{id:"a005",seed:526874,initial:"a005-initial.png",panels:[{model:"GPT-6 Astra",file:"a005-astra-terminal.png",levels:6,actions:30,seconds:158.739,end:"won",levelShown:6},{model:"Qwen 3.8 Flash",file:"a005-qwenflash-terminal.png",levels:6,actions:39,seconds:717.969,end:"won",levelShown:6},{model:"GPT-6 Sol",file:"a005-gpt6sol-terminal.png",levels:5,actions:154,seconds:720.002,end:"time_budget",levelShown:6},{model:"GPT-5.6 Sol",file:"a005-gpt56sol-terminal.png",levels:1,actions:512,seconds:483.341,end:"action_budget",levelShown:2}],outcomes:[{actions:30,gameElapsedSeconds:158.739,levelsCompleted:6,model:"gpt-6-astra",termination:"won"},{actions:512,gameElapsedSeconds:483.341,levelsCompleted:1,model:"gpt-5.6-sol",termination:"action_budget"},{actions:69,gameElapsedSeconds:719.997,levelsCompleted:5,model:"gpt-5.6-luna",termination:"time_budget"},{actions:63,gameElapsedSeconds:553.16,levelsCompleted:6,model:"gpt-5.6-terra",termination:"won"},{actions:39,gameElapsedSeconds:717.969,levelsCompleted:6,model:"qwen3.8-flash",termination:"won"},{actions:6,gameElapsedSeconds:719.985,levelsCompleted:0,model:"ZHIPU/GLM-5.3-Flash",termination:"time_budget"},{actions:36,gameElapsedSeconds:719.999,levelsCompleted:4,model:"deepseek-v4.1-flash",termination:"time_budget"},{actions:10,gameElapsedSeconds:720.001,levelsCompleted:2,model:"kimi-k3",termination:"time_budget"},{actions:35,gameElapsedSeconds:720,levelsCompleted:0,model:"qwen3.8-max-0902",termination:"time_budget"},{actions:154,gameElapsedSeconds:720.002,levelsCompleted:5,model:"gpt-6-sol",termination:"time_budget"},{actions:27,gameElapsedSeconds:720.001,levelsCompleted:3,model:"gpt-6-luna",termination:"time_budget"}]},{id:"d009",seed:899067,initial:"d009-initial.png",panels:[{model:"GPT-6 Astra",file:"d009-astra-terminal.png",levels:6,actions:96,seconds:135.827,end:"won",levelShown:6},{model:"GPT-5.6 Sol",file:"d009-gpt56sol-terminal.png",levels:6,actions:115,seconds:661.809,end:"won",levelShown:6},{model:"GPT-6 Sol",file:"d009-gpt6sol-terminal.png",levels:0,actions:45,seconds:720.002,end:"time_budget",levelShown:1},{model:"GPT-5.6 Terra",file:"d009-terra-terminal.png",levels:0,actions:512,seconds:709.718,end:"action_budget",levelShown:1}],outcomes:[{actions:96,gameElapsedSeconds:135.827,levelsCompleted:6,model:"gpt-6-astra",termination:"won"},{actions:115,gameElapsedSeconds:661.809,levelsCompleted:6,model:"gpt-5.6-sol",termination:"won"},{actions:512,gameElapsedSeconds:665.783,levelsCompleted:0,model:"gpt-5.6-luna",termination:"action_budget"},{actions:512,gameElapsedSeconds:709.718,levelsCompleted:0,model:"gpt-5.6-terra",termination:"action_budget"},{actions:39,gameElapsedSeconds:719.987,levelsCompleted:0,model:"qwen3.8-flash",termination:"time_budget"},{actions:0,gameElapsedSeconds:719.986,levelsCompleted:0,model:"ZHIPU/GLM-5.3-Flash",termination:"time_budget"},{actions:19,gameElapsedSeconds:720.001,levelsCompleted:0,model:"deepseek-v4.1-flash",termination:"time_budget"},{actions:5,gameElapsedSeconds:720.003,levelsCompleted:0,model:"kimi-k3",termination:"time_budget"},{actions:19,gameElapsedSeconds:720.006,levelsCompleted:0,model:"qwen3.8-max-0902",termination:"time_budget"},{actions:45,gameElapsedSeconds:720.002,levelsCompleted:0,model:"gpt-6-sol",termination:"time_budget"},{actions:15,gameElapsedSeconds:720.003,levelsCompleted:0,model:"gpt-6-luna",termination:"time_budget"}]},{id:"e005",seed:978257,initial:"e005-initial.png",panels:[{model:"GPT-6 Astra",file:"e005-astra-terminal.png",levels:6,actions:41,seconds:135.514,end:"won",levelShown:6},{model:"GPT-5.6 Sol",file:"e005-gpt56sol-terminal.png",levels:6,actions:101,seconds:676.009,end:"won",levelShown:6},{model:"GPT-6 Sol",file:"e005-gpt6sol-terminal.png",levels:2,actions:67,seconds:720.002,end:"time_budget",levelShown:3},{model:"GPT-6 Luna",file:"e005-luna-terminal.png",levels:0,actions:9,seconds:720.003,end:"time_budget",levelShown:1}],outcomes:[{actions:41,gameElapsedSeconds:135.514,levelsCompleted:6,model:"gpt-6-astra",termination:"won"},{actions:101,gameElapsedSeconds:676.009,levelsCompleted:6,model:"gpt-5.6-sol",termination:"won"},{actions:212,gameElapsedSeconds:719.985,levelsCompleted:2,model:"gpt-5.6-luna",termination:"time_budget"},{actions:512,gameElapsedSeconds:389.674,levelsCompleted:1,model:"gpt-5.6-terra",termination:"action_budget"},{actions:25,gameElapsedSeconds:719.985,levelsCompleted:1,model:"qwen3.8-flash",termination:"time_budget"},{actions:0,gameElapsedSeconds:719.992,levelsCompleted:0,model:"ZHIPU/GLM-5.3-Flash",termination:"time_budget"},{actions:7,gameElapsedSeconds:720,levelsCompleted:1,model:"deepseek-v4.1-flash",termination:"time_budget"},{actions:5,gameElapsedSeconds:720.005,levelsCompleted:0,model:"kimi-k3",termination:"time_budget"},{actions:11,gameElapsedSeconds:720.002,levelsCompleted:1,model:"qwen3.8-max-0902",termination:"time_budget"},{actions:67,gameElapsedSeconds:720.002,levelsCompleted:2,model:"gpt-6-sol",termination:"time_budget"},{actions:9,gameElapsedSeconds:720.003,levelsCompleted:0,model:"gpt-6-luna",termination:"time_budget"}]}]};var G=e=>document.querySelector(e),ue=e=>String(e).replace(/[&<>"']/g,n=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[n]),Un=["#111d25","#344e59","#ecce76","#64b5b0","#dc765a","#8b8fc9","#e0b5c7","#73a773","#e9e5d5","#d8a262","#5d687f","#b7ce9c","#d49ca0","#82a6bb","#9e805e","#f3f0e8"],Wn={a001:"Pivot cargo: translation, rotation and collision across six levels.",a005:"Local frame rover: motion relative to heading, floor transforms and cargo.",d009:"Escrow Cycle: delayed transfers, account capacity and settlement.",e005:"Transitive islands: connected and separated node-pair constraints."},Kn={a001:"Astra completes all six levels; DeepSeek clears five and Luna three before the normal time limit.",a005:"Qwen completes all six near the deadline. GPT-6 Sol clears five, while GPT-5.6 Sol reaches the action cap after one: a task-specific reversal of the overall Sol ordering.",d009:"Astra and GPT-5.6 Sol finish. GPT-6 Sol reaches the time limit and Terra the action limit without a verified first-level win.",e005:"Two full completions, two levels for GPT-6 Sol, and zero for Luna. Different valid edge configurations can satisfy the same graph constraints."},Jt=[...Gt,...Tt,...Vt],K=Jt.find(e=>e.id==="a001"),ft=503117,W=1,de,Qt,Ee=new _e,ge=[];function Ut(){let e=K.init(W,ft);de=structuredClone(e.state),Qt=structuredClone(e.state)}function mt(){return Ee.remaining()}function Re(){let e=K.observe(structuredClone(de));return{pixels:e.pixels.map(n=>n.slice()),actions:[...e.actions],level:W,status:K.solved(structuredClone(de))?"won":"playing"}}function Ie(){return Ee.ending()}function et(){let e=Re(),n=G("#pixels"),t=Math.max(4,Math.min(12,Math.floor(650/Math.max(e.pixels.length,e.pixels[0].length))));n.width=e.pixels[0].length*t,n.height=e.pixels.length*t;let r=n.getContext("2d");r.imageSmoothingEnabled=!1,e.pixels.forEach((i,l)=>i.forEach((c,s)=>{r.fillStyle=Un[c],r.fillRect(s*t,l*t,t,t)}));let o=Ie(),a=e.status==="won";G("#game-label").textContent=`${K.id} \xB7 level ${W} / 6`,G("#game-actions").textContent=`${Ee.actions} / 512 actions`,G("#game-clock").textContent=`${Math.ceil(mt())} s left`,G("#case-description").textContent=Wn[K.id],G("#game-controls").innerHTML=e.actions.map(i=>`<button data-button="${i}" ${o||a?"disabled":""} aria-label="Neutral control ${i}">${i}</button>`).join(""),document.querySelectorAll("[data-button]").forEach(i=>i.onclick=()=>Oe({button:Number(i.dataset.button)})),G("#reset-level").disabled=!!o||a,G("#next-level").hidden=!a||!!o||W>=6,G("#game-status").textContent=o==="time_budget"?`Time limit \xB7 ${ge.length}/6 completed`:o==="action_budget"?`Action limit \xB7 ${ge.length}/6 completed`:a?W===6?"All six levels complete.":`Level ${W} complete.`:`${ge.length}/6 completed \xB7 explore the controls`}function Oe(e){if(Ie()||K.solved(structuredClone(de)))return;let n=Re();if(e.control==="reset")de=structuredClone(Qt);else{if(!n.actions.includes(e.button))return;de=K.step(structuredClone(de),e)}K.solved(structuredClone(de))&&!ge.includes(W)&&ge.push(W),Ee.recordAction(ge.length),et()}function tt(e=K.id){let n=Ze.cases.find(t=>t.id===e);K=Jt.find(t=>t.id===e),ft=n.seed,W=1,Ee=new _e,ge=[],Ut(),et()}G("#environment").onchange=e=>tt(e.target.value);G("#new-practice").onclick=()=>tt();G("#reset-level").onclick=()=>Oe({control:"reset"});G("#next-level").onclick=()=>{!Ie()&&K.solved(structuredClone(de))&&W<6&&(W++,Ut(),et())};G("#pixels").onclick=e=>{let n=e.currentTarget,t=Re();if(!t.actions.includes(6))return;let r=n.getBoundingClientRect();Oe({button:6,x:Math.floor((e.clientX-r.left)*t.pixels[0].length/r.width),y:Math.floor((e.clientY-r.top)*t.pixels.length/r.height)})};document.addEventListener("keydown",e=>{if(e.target instanceof HTMLSelectElement||e.target instanceof HTMLInputElement||e.target instanceof HTMLTextAreaElement)return;let n=Number(e.key);Number.isInteger(n)&&n>=1&&n<=6&&(e.preventDefault(),Oe({button:n})),e.key.toLowerCase()==="r"&&(e.preventDefault(),Oe({control:"reset"}))});setInterval(()=>{let e=Ie();G("#game-clock").textContent=`${Math.ceil(mt())} s left`,e&&!G("#game-status").textContent?.includes("limit")&&et()},250);G("#leaderboard").innerHTML=Ze.models.map(e=>`<tr><td>${e.rank}</td><td>${ue(e.name)}</td><td>${e.full}/150</td><td>${e.fullRate.toFixed(2)}%</td><td>${e.levels}/900</td><td>${e.levelRate.toFixed(2)}%</td><td>${e.time}</td></tr>`).join("");var zt={"fullwins-vs-levels":{alt:"Complete task rates and cleared level rates for eleven configurations",caption:"Exact count columns use 150 tasks and 900 levels as separate denominators."},"completion-depth-0-to-6":{alt:"Episode completion depth from zero through all six levels for eleven configurations",caption:"Every model has 150 episodes. Small segments are retained; the exact depth data accompany the dataset."},"authored-family-heatmap":{alt:"Cleared levels across ten authored task families for eleven configurations",caption:"Each family offers 90 levels. Cell text is the cleared-level count; color encodes its percentage."},"normal-budget-endings":{alt:"Normal completion, time limits, action limits and abandoned endings for eleven configurations",caption:"Ordinary budget exhaustion is a valid unfinished outcome; confirmed engineering exclusions are accounted separately."}};document.querySelectorAll("[data-chart]").forEach(e=>e.addEventListener("click",()=>{let n=e.dataset.chart;document.querySelectorAll("[data-chart]").forEach(t=>t.setAttribute("aria-selected",String(t===e))),G("#result-chart").src=n+".svg",G("#result-chart").alt=zt[n].alt,G("#chart-caption").textContent=zt[n].caption}));function Wt(e){let n=Ze.cases.find(t=>t.id===e);G("#recorded-example").innerHTML=`<div class="example-top"><img src="${ue(n.initial)}" alt="Shared initial observation for ${ue(e)}"><div><strong>${ue(e)} \xB7 seed ${n.seed} \xB7 shared initial observation</strong><p>${ue(Kn[e])}</p><p class="small">These are actual selected episodes, not newly simulated model traces.</p></div></div><div class="snapshot-grid">${n.panels.map(t=>`<article class="snapshot-card"><h3>${ue(t.model)}</h3><div class="snapshot-art"><img src="${ue(t.file)}" alt="Actual terminal observation for ${ue(t.model)} on ${ue(e)}"></div><strong>${t.levels}<span class="small"> / 6 levels</span></strong><p>${t.actions} actions \xB7 ${t.seconds.toFixed(3)} s</p><p>${t.end==="won"?"Full completion":t.end==="time_budget"?"Normal time limit":"Normal action limit"} \xB7 image at level ${t.levelShown}</p></article>`).join("")}</div>`}document.querySelectorAll("[data-example]").forEach(e=>e.addEventListener("click",()=>{document.querySelectorAll("[data-example]").forEach(n=>n.setAttribute("aria-selected",String(n===e))),Wt(e.dataset.example)}));window.recursivePlayDemo={snapshot:()=>({environment:K.id,seed:ft,level:W,spent:Ee.actions,completedLevels:[...ge],status:Ie()||Re().status,pixels:Re().pixels,remainingSeconds:mt()}),newPractice:tt};tt("a001");Wt("a001");})();