diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..c2658d7
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1 @@
+node_modules/
diff --git a/README.md b/README.md
index 346f012..cd1f243 100644
--- a/README.md
+++ b/README.md
@@ -2,6 +2,24 @@
Open `index.html` in a browser.
+Production uses the committed `dist/game.js` bundle. Edit source files under
+`src/`, then run `npm install` once and `npm run build` after JavaScript
+changes to regenerate the bundle.
+
+## Static server cache setup
+
+Serve `index.html`, the bundled JavaScript, and CSS with cache validation
+instead of import query strings. This prevents stale files while keeping reloads
+fast.
+
+Use the example in `deploy/` for your HTTP server:
+
+- nginx: include `deploy/nginx-cache.conf` inside the server block.
+- Apache: copy or include `deploy/apache-cache.htaccess` from the site root.
+- Caddy: adapt `deploy/Caddyfile-cache`.
+
+After deploying, purge any CDN or reverse-proxy cache once.
+
## Current baseline
- Build, move, box-select, sell, and repair factory equipment during Build phase.
diff --git a/deploy/Caddyfile-cache b/deploy/Caddyfile-cache
new file mode 100644
index 0000000..1b430f3
--- /dev/null
+++ b/deploy/Caddyfile-cache
@@ -0,0 +1,9 @@
+# Adapt these directives inside the Caddy site block that serves this static app.
+
+encode gzip zstd
+
+@html path /index.html
+header @html Cache-Control "no-cache"
+
+@assets path *.js *.css
+header @assets Cache-Control "no-cache"
diff --git a/deploy/apache-cache.htaccess b/deploy/apache-cache.htaccess
new file mode 100644
index 0000000..69d3f75
--- /dev/null
+++ b/deploy/apache-cache.htaccess
@@ -0,0 +1,17 @@
+# Use this from the static site root when served by Apache with .htaccess enabled.
+
+FileETag MTime Size
+
+
+
+ Header set Cache-Control "no-cache"
+
+
+
+ Header set Cache-Control "no-cache"
+
+
+
+
+ AddOutputFilterByType DEFLATE text/css application/javascript text/javascript
+
diff --git a/deploy/nginx-cache.conf b/deploy/nginx-cache.conf
new file mode 100644
index 0000000..82b8614
--- /dev/null
+++ b/deploy/nginx-cache.conf
@@ -0,0 +1,20 @@
+# Include this in the nginx server block that serves this static app.
+#
+# Example:
+# server {
+# root /var/www/zunda-shiwake;
+# include /var/www/zunda-shiwake/deploy/nginx-cache.conf;
+# }
+
+etag on;
+gzip on;
+gzip_types text/css application/javascript text/javascript;
+
+location = /index.html {
+ add_header Cache-Control "no-cache";
+}
+
+location ~* \.(js|css)$ {
+ add_header Cache-Control "no-cache";
+ gzip_static on;
+}
diff --git a/dist/game.js b/dist/game.js
new file mode 100644
index 0000000..6b28b61
--- /dev/null
+++ b/dist/game.js
@@ -0,0 +1,61 @@
+var q={version:"v27.6 direct conveyor chick movement",time:{daySeconds:60,farmShutdownGraceSeconds:10},cash:{starting:250},grid:{x:170,y:78,cols:20,rows:10,cell:46,expansion:{colsPerPurchase:10,rowsPerPurchase:10,costBase:1e3,costMultiplier:1.3333333333333333,truncateUnit:100}},map:{blockedRatio:.075},economy:{income:{mixer:5,truck:10},poopFine:10,zundaTax:{exemption:500,legalWorkExemptionBonus:250,maxRateCash:1e4,stepAmount:500,stepRate:.05,maxRate:.95},fairiesTribute:{perDay:10},incomeUpgradeRate:1.1,explosionDamageDivisor:30,maleTruckFinePerHalfDay:30,shredderBonus:{maxCards:30,probabilityPercentDivisor:2}},production:{poopRate:.08,autoScannerCooldown:3.5,autoScannerUpgradeRate:.95,autoScannerMinCooldown:.5,eggSpawnRanges:[[1.95,4.35],[1.55,3.45],[1.25,2.8],[1.05,2.35]]},conveyor:{baseSpeed:52,maxSpeed:300,bearingSpeedMultiplier:1.075},cards:{definitions:[{id:"upgradeEgg",title:"EGG Improvement",rarity:"common",type:"equipmentUpgrade",target:"eggFarm",description:"Choose one EGG FARM on the map and raise it by 1 level.",tags:["EGG","ACTIVE"]},{id:"upgradeAutoScanner",title:"AUTO SCANNER Improvement",rarity:"common",type:"equipmentUpgrade",target:"autoScanner",description:"Choose one AUTO SCANNER on the map and raise it by 1 level.",tags:["SCANNER","ACTIVE"]},{id:"upgradeMixer",title:"MIXER Improvement",rarity:"common",type:"equipmentUpgrade",target:"mixer",description:"Choose MIXER on the map and raise it by 1 level.",tags:["ECONOMY","ACTIVE"]},{id:"upgradeTruck",title:"TRUCK Improvement",rarity:"common",type:"equipmentUpgrade",target:"truck",description:"Choose TRUCK on the map and raise it by 1 level.",tags:["ECONOMY","ACTIVE"]},{id:"upgradeTrash",title:"SHREDDER Improvement",rarity:"common",type:"equipmentUpgrade",target:"trash",description:"Shred poops for a little money. Max 30 upgrades.",tags:["POOP","ACTIVE"]},{id:"crowdedFarming",title:"Crowded Farming Contract",rarity:"common",type:"instant",description:"EGG production interval -5%. Equipment deterioration +4%. Max 10 cards.",tags:["EGG","RISK","PASSIVE"]},{id:"hatchingFeed",title:"Hatching Feed",rarity:"common",type:"instant",description:"EGG production interval -4%. Poop rate +3%. No card limit.",tags:["EGG","POOP","PASSIVE"]},{id:"safetyCover",title:"Safety Cover",rarity:"common",type:"instant",description:"Explosion damage -5%. No card limit.",tags:["RISK","PASSIVE"]},{id:"preventiveMaintenance",title:"Preventive Maintenance Manual",rarity:"common",type:"instant",description:"All equipment deterioration speed -5%. No card limit.",tags:["MAINTENANCE","PASSIVE"]},{id:"dudFilter",title:"DUD Filter",rarity:"common",type:"instant",description:"DUD chance -5 percentage points. Stacks until DUD chance reaches 0%.",tags:["CARD","PASSIVE"]},{id:"durabilityCoating",title:"Durability Coating",rarity:"common",type:"instant",description:"All equipment maximum durability +3%. No card limit.",tags:["MAINTENANCE","PASSIVE"]},{id:"bearing",title:"High-Quality Bearing",rarity:"common",type:"instant",description:"Conveyor speed +7.5%.",tags:["CONVEYOR","PASSIVE"]},{id:"sparePartsBin",title:"SPARE PARTS BIN",rarity:"common",type:"instant",description:"Restores 2% durability to every machine. A box of almost-compatible parts.",tags:["MAINTENANCE","ACTIVE"],weightBase:100,weightLossPerCopy:2},{id:"dudRefund",title:"DUD REFUND",rarity:"common",type:"instant",description:"DUDs now come with paperwork. Gain JPY 50 per copy when you pick a DUD.",tags:["CARD","ECONOMY","PASSIVE"]},{id:"freeReroll",title:"FREE REROLL",rarity:"common",type:"instant",description:"The first bad ideas are free.",tags:["CARD","PASSIVE"]},{id:"composter",title:"COMPOSTER",rarity:"common",type:"instant",description:"Turns shredder waste into suspicious fertilizer. Gain JPY 3 per copy when SHREDDER processes poop.",tags:["POOP","ECONOMY","PASSIVE"]},{id:"scannerQueueSpacing",title:"Scanner Queue Spacing",rarity:"common",type:"instant",description:"Manual and Auto Scanner queue spacing -15%. No card limit.",tags:["SCANNER","PASSIVE"]},{id:"extraEggOutlet",title:"Extra Egg Outlet",rarity:"rare",type:"equipmentUpgrade",target:"eggOutlet",description:"Choose one EGG FARM and add +1 output port to that EGG. Max +3 per EGG.",tags:["EGG","RARE","ACTIVE"]},{id:"recyclingSubsidy",title:"Recycling Subsidy",rarity:"rare",type:"instant",description:"SELL refund rate +10 points. Max 3 cards; normal SELL can reach 80%.",tags:["ECONOMY","RARE","PASSIVE"]},{id:"dynamite",title:"Dynamite",rarity:"rare",type:"cellAction",target:"blockedCell",description:"Remove any 3 unbuildable cells",tags:["RISK","RARE","ONE-SHOT"]},{id:"usedMachine",title:"Used Machines",rarity:"rare",type:"instant",description:"Future equipment costs half. New purchases have no refund and 60% durability. New Machines cancels it.",tags:["ECONOMY","RISK","RARE"]},{id:"newMachine",title:"New Machines",rarity:"common",type:"instant",description:"Cancel Used Machines and restore normal prices, refunds, and durability.",tags:["ECONOMY","ONE-SHOT"]},{id:"flattery",title:"Flattery",rarity:"rare",type:"instant",description:"Next Fairies tribute -50%.",tags:["ECONOMY","RARE","ONE-SHOT"]},{id:"loan",title:"Loan",rarity:"rare",type:"instant",description:"Gain JPY 300 per elapsed day now. Pay JPY 400 per day for that many days starting tomorrow.",tags:["ECONOMY","RISK","RARE"]},{id:"extraCards",title:"Extra Cards",rarity:"rare",type:"instant",description:"Draw 2 cards now and choose both.",tags:["RARE","ACTIVE"]},{id:"legalWork",title:"Legal Work",rarity:"rare",type:"instant",description:"ZUNDA TAX exemption +\uFFE5250. The 95% cap point also moves up by \uFFE5250.",tags:["ECONOMY","RARE","PASSIVE"]},{id:"chemicalWeaponSubsidy",title:"Chemical Weapons Subsidy",rarity:"ultraRare",type:"instant",description:"Each day, gain JPY 2000 per 100 poop shipped by truck. No card limit.",tags:["POOP","ULTRA RARE","PASSIVE"]},{id:"laborExploitation",title:"Motivational Exploitation",rarity:"ultraRare",type:"instant",description:"Repairman labor cost -30%. The repairman smiles with bloodshot eyes. One time only.",tags:["MAINTENANCE","ULTRA RARE","PASSIVE"]},{id:"rescueLoan",title:"Emergency Loan",rarity:"ultraRare",type:"instant",description:"If cash is below JPY 0 at day-end settlement, gain JPY 500. Consumed on use.",tags:["ECONOMY","ULTRA RARE","ONE-SHOT"]}],defaultEffects:{bearing:0,legalWork:0,fairiesFlatteryNext:0,crowdedFarming:0,extraEggOutlet:0,hatchingFeed:0,safetyCover:0,recyclingSubsidy:0,chemicalWeaponSubsidy:0,preventiveMaintenance:0,dudFilter:0,durabilityCoating:0,sparePartsBin:0,dudRefund:0,freeReroll:0,composter:0,scannerQueueSpacing:0,laborExploitation:0,usedMachineActive:!1,rescueLoanCharges:0,loans:[]},commonWeight:8,rareWeight:2,ultraRareWeight:.45,baseDraftSize:3,maxDudsPerDraft:2,dudChancePerCard:.3,dudChanceReductionPerFilter:.05,extraCardsAddedPicks:2,rerollCost:{dayDivisor:2,multiplier:100}},contracts:{eventChance:.7,firstTurn:8},maintenance:{fullPerformanceUntilWear:.5,minimumPerformance:.5,durability:{conveyor:1300,eggFarm:475,autoScanner:850,mixer:775,trash:950},processingDelayMaxSeconds:{mixer:1.2,trash:1},repairman:{dailyCost:100,secondsPerOnePercent:.5,walkSpeed:90}},facilities:{conveyor:{id:"conveyor",type:"conveyor",name:"Conveyor",shortName:"Belt",price:30,buildable:!0,upgradeable:!1},boostConveyor:{id:"boostConveyor",type:"conveyor",name:"Boost Conveyor",shortName:"BOOST BELT",price:75,buildable:!0,upgradeable:!1,speedMultiplier:2},eggFarm:{id:"eggFarm",type:"eggFarm",name:"Egg Farm",shortName:"EGG",price:250,buildable:!0,upgradeable:!0,maxLevel:4,upgradeCosts:[null,300,720,1600]},manualScanner:{id:"manualScanner",type:"scanner",kind:"manual",name:"Manual Scanner",shortName:"Manual Scanner",price:260,buildable:!0,upgradeable:!1},autoScanner:{id:"autoScanner",type:"scanner",kind:"auto",name:"Auto Scanner",shortName:"Auto Scanner",price:360,buildable:!0,upgradeable:!1},mixer:{id:"mixer",type:"facility",name:"Mixer",shortName:"MIXER",price:450,buildable:!0,upgradeable:!0,incomeKey:"mixer",body:{w:164,h:126}},trash:{id:"trash",type:"facility",name:"Waste Shredder",shortName:"SHREDDER",price:240,buildable:!0,upgradeable:!0,body:{w:180,h:100}},truck:{id:"truck",type:"facility",name:"Truck",shortName:"TRUCK",price:450,buildable:!0,upgradeable:!0,incomeKey:"truck",body:{w:176,h:138}}}};var yn=q.version,Bt=q.time.daySeconds,Jt=q.cash.starting,Ce=q.economy,tr=q.time.farmShutdownGraceSeconds,hn=q.production.autoScannerCooldown,nr=q.production.autoScannerUpgradeRate,eo=q.production.autoScannerMinCooldown,or=q.contracts.eventChance,ft=q.contracts.firstTurn,rr=q.production.poopRate,mn=q.conveyor.baseSpeed,Lt=q.conveyor.maxSpeed,bn=q.conveyor.bearingSpeedMultiplier,Ee=q.cards,ir=q.cards.definitions,to=q.cards.defaultEffects,et=q.production.eggSpawnRanges,y=q.grid,we=q.facilities,no=["conveyor","boostConveyor","eggFarm","autoScanner","manualScanner","mixer","trash","truck"],Zt=["mixer","trash","truck"],sr=["mixer","truck"],pt=Object.fromEntries(Object.entries(we).map(([e,t])=>[e,t.price])),pe=[{name:"right",dc:1,dr:0,angle:0,opposite:"left"},{name:"left",dc:-1,dr:0,angle:Math.PI,opposite:"right"},{name:"down",dc:0,dr:1,angle:Math.PI/2,opposite:"up"},{name:"up",dc:0,dr:-1,angle:-Math.PI/2,opposite:"down"}],f={bg:"#eefbea",ink:"#102015",muted:"#526456",green:"#22b94f",greenSoft:"#b7f5c6",mixerBlue:"#2477ff",truckPink:"#ff6aa8",wasteGreen:"#22b94f",danger:"#c42424",warn:"#f0a020",white:"#ffffff",poop:"#7b4a23",male:"#62a9ff",female:"#ff8bc6"},Se={ambient:0,important:1,critical:2};function S(e){let t=Number(e)||0;return`${t<0?"-":""}\uFFE5${Math.ceil(Math.abs(t)).toLocaleString("ja-JP")}`}function I(e,t){return`${e},${t}`}function J(e){let[t,n]=String(e).split(",").map(Number);return{col:t,row:n}}function jt(e,t,n){return Math.max(t,Math.min(n,e))}function W(e,t){return e+Math.random()*(t-e)}function Pe(e,t){return e>=0&&e=0&&tMath.round(jt(r,0,255)).toString(16).padStart(2,"0");return`#${o(e)}${o(t)}${o(n)}`}function ro(e,t,n){let o=lr(e),r=lr(t);return As(oo(o.r,r.r,n),oo(o.g,r.g,n),oo(o.b,r.b,n))}var re={appTitle:"Chick Sorter",versionTitle:`Chick Sorter ${yn}`,currency:"\uFFE5",phases:{title:"Title",build:"Build",running:"Sorting",clearing:"Clearing",loanDecision:"Emergency Loan",gameover:"Game Over"},actions:{startGame:"Start Game",nextDay:"Next Day",buildPhase:"Build Phase",restart:"Restart",close:"Close",remove:"Remove",refund:"Refund",autoMenu:"Auto Menu"},status:{build:e=>`BUILD: ${(e==="erase"?"SELL":e||"SELECT").toUpperCase()} | Right-drag pan | Hover equipment for info`,sorting:"Sorting: use scanner keys. Build after clearing the day.",allPortsConnected:"Start condition met: one EGG route reaches an exit.",equipmentPanelEmpty:"Hover equipment in Build phase.",eventPanelRunning:"Forced events appear in Build phase."},routeLabels:{mixer:"MIXER",truck:"TRUCK",trash:"WASTE",scanner:"NEXT","scanner-role-1":"NEXT",input:"IN"},fail:{outOfGrid:"Out of grid",cellOccupied:"Cell occupied",notEnoughCash:"Not enough cash",facilityExists:"Facility already exists",facilityOverlap:"Facility overlap",nothingToErase:"Nothing to sell",noUpgrade:"No upgrade available"}};function ht(e){return we[e]?.name||String(e||"").replace(/^[a-z]/,t=>t.toUpperCase())}function $s(e){let t=we[e];return t?e==="conveyor"||e==="boostConveyor"?`${S(t.price)} / tile`:e==="autoScanner"?`${S(t.price)} / ${hn.toFixed(1)}s cooldown`:e==="trash"?S(t.price):S(t.price):""}function Is(e){return{conveyor:"A narrow green belt. Routes decide whether chicks live, ship, or become invoices.",boostConveyor:"Moves chicks twice as fast. Wears down like a normal belt.",eggFarm:"A tiny gatehouse producing questionable eggs on schedule.",autoScanner:"Slower than hands without upgrades.",manualScanner:"A manual checkpoint. The operator is the algorithm.",mixer:"Male chicks become revenue here. Do not feed it poop.",trash:"A polite shredder for poop and other regrets.",truck:"Ships the target cargo. Wrong cargo still leaves a paper trail."}[e]||""}function cr(e){let t=Is(e);return`${ht(e)}${$s(e)}${t?`${t}`:""}`}function ur(e){return re.routeLabels[e]||String(e).toUpperCase()}function dr(e){let t=2166136261;for(let n=0;n>>0}function fr(e){let t=e>>>0;return()=>{t+=1831565813;let n=Math.imul(t^t>>>15,1|t);return n^=n+Math.imul(n^n>>>7,61|n),((n^n>>>14)>>>0)/4294967296}}function vn(){return`RUN-${Date.now().toString(36)}-${Math.floor(Math.random()*1e6).toString(36)}`.toUpperCase()}function pr({seed:e,targetRatio:t=.2,reserved:n=[]}={}){let o=fr(dr(e||vn())),r=new Set(n.map(d=>typeof d=="string"?d:I(d.col,d.row))),s=[];for(let d=0;d0;d-=1){let k=Math.floor(o()*(d+1));[s[d],s[k]]=[s[k],s[d]]}let l=Math.round(y.cols*y.rows*t);return new Set(s.slice(0,Math.min(l,s.length)).map(d=>d.k))}function yr({seed:e,colStart:t=0,colEnd:n=y.cols,rowStart:o=0,rowEnd:r=y.rows,targetRatio:s=.2,reserved:l=[]}={}){let d=fr(dr(e||vn())),k=new Set(l.map(X=>typeof X=="string"?X:I(X.col,X.row))),M=[],D=Math.max(0,Math.floor(t)),L=Math.max(D,Math.floor(n)),F=Math.max(0,Math.floor(o)),z=Math.max(F,Math.floor(r));for(let X=F;X0;X-=1){let ae=Math.floor(d()*(X+1));[M[X],M[ae]]=[M[ae],M[X]]}let oe=Math.round((L-D)*(z-F)*s);return new Set(M.slice(0,Math.min(oe,M.length)).map(X=>X.k))}var Ot=10,hr=2,mr=1;function Nt(e,t){return`${e},${t}`}function Fs(e){let[t,n]=String(e).split(",").map(Number);return{chunkX:t,chunkY:n}}function xn(e){let t=q.grid.expansion||{},n=Math.max(1,(e.gridExpansionPurchases||0)+1),o=(t.costBase||1e3)*n*(t.costMultiplier||4/3),r=Math.max(1,t.truncateUnit||100);return Math.floor(o/r)*r}function br(e){e.ownedCells=new Set,e.ownedChunks=new Set,e.gridChunkOriginY=0,e.gridExpansionPurchases=0,e.gridExpansionPurchasesByDirection={right:0,up:0};for(let t=0;t=0&&t=0&&n0)continue;let M=Nt(k.chunkX,k.chunkY);t.has(M)||n.has(M)||n.set(M,io(e,k.chunkX,k.chunkY,k.direction))}}return[...n.values()].sort((o,r)=>{let s=o.direction===r.direction?0:o.direction==="right"?-1:1;return s||(o.chunkY!==r.chunkY?o.chunkY-r.chunkY:o.chunkX-r.chunkX)})}function xr(e,t="right"){let n=mt(e);return n.find(o=>o.direction===t)||n[0]||null}function bt(e){return{x:y.x+e.colStart*y.cell,y:y.y+e.rowStart*y.cell,w:e.cols*y.cell,h:e.rows*y.cell}}function so(e){let t=bt(e);return{x:t.x+t.w/2-116,y:t.y+t.h/2-36,w:232,h:72,cx:t.x+t.w/2,cy:t.y+t.h/2}}function kr(e,t){let n=so(e);return t.x>=n.x&&t.x<=n.x+n.w&&t.y>=n.y&&t.y<=n.y+n.h}function Cr(e){let t=[];for(let n=e.rowStart;nPe(t.col,t.row))}function _s(e){return[{col:e.col,row:e.row-1},{col:e.col+1,row:e.row-1},{col:e.col,row:e.row},{col:e.col+1,row:e.row},{col:e.col,row:e.row+1},{col:e.col+1,row:e.row+1}].filter(t=>Pe(t.col,t.row))}function Ks(e){return[{col:e.col,row:e.row+1},{col:e.col-1,row:e.row},{col:e.col+1,row:e.row},{col:e.col,row:e.row-1}].filter(t=>Pe(t.col,t.row))}function Pr(e){let t=new Set([...e.conveyorTiles]),n=o=>{o&&Pe(o.col,o.row)&&t.add(I(o.col,o.row))};for(let o of e.scanners){for(let r of _s(o))n(r);for(let r of Ws(o))n(r)}for(let o of e.eggFarms){n(o);for(let r of Ks(o))n(r)}for(let o of Object.values(e.facilities))n(o.entry);return t}function gr(e){let t=Os.map(([n,o])=>({col:n,row:o}));for(let{col:n,row:o}of t)Er(e,n,o);for(let n=0;n({...n,keys:n.keys?{left:{...n.keys.left},right:{...n.keys.right}}:null,queue:[]})),e.eggFarms=Gs.map(n=>{let o=wt(n);return{...n,nextSpawn:o,lastInterval:o}});let t=Pr(e);e.blockedCells=pr({seed:e.runSeed,targetRatio:q.map.blockedRatio,reserved:[...t]}),Hs(e),gr(e),e.routingVersion=(e.routingVersion||0)+1,e.factoryGraph=null,e.factoryGraphCommittedVersion=-1}function xt(e){return e?[{col:e.col,row:e.row-1},{col:e.col+1,row:e.row-1},{col:e.col,row:e.row},{col:e.col+1,row:e.row},{col:e.col,row:e.row+1},{col:e.col+1,row:e.row+1}]:[]}function de(e){let t=$(e.col,e.row);return{x:t.x+y.cell/2,y:t.y}}function kt(e,t,n){return e.eggFarms.find(o=>o.col===t&&o.row===n)||null}function Ct(e,t,n){return e.scanners.find(o=>xt(o).some(r=>r.col===t&&r.row===n))||null}function St(e,t){return e.scanners.find(n=>n.id===t)||null}function fo(e,t){return e.scanners.find(n=>n.kind==="manual"&&n.slot===t)||null}function Mn(e){return e?.baseId||e?.id||""}function po(e,t){return Object.entries(e.facilities||{}).filter(([,n])=>Mn(n)===t)}function Me(e,t){return{inputA:{col:e.col,row:e.row-2},inputB:null,left:{col:e.col-1,row:e.row},right:{col:e.col+2,row:e.row}}[t]}function Ar(e){return e?pe.map(t=>({col:e.col+t.dc,row:e.row+t.dr})).filter(t=>Pe(t.col,t.row)):[]}function $r(e,t,n=[],o=[]){if(!t||!Pe(t.col,t.row))return[];let r=[],s=l=>{!l||!Pe(l.col,l.row)||!e.conveyorTiles.has(I(l.col,l.row))||n.some(d=>d&&wn(l,d))||r.some(d=>wn(d,l))||r.push({...l,viaTolerance:!wn(l,t)})};s(t);for(let l of o)s(l);for(let l of Ar(t))s(l);return r}function Rr(e,t,n=[],o=[]){let r=$r(e,t,n,o),s=r.filter(l=>!l.viaTolerance);return s.length?s:r}function qs(e,t){let n=Me(t,"inputA");return!n||!Pe(n.col,n.row)?[]:e.conveyorTiles.has(I(n.col,n.row))?[{...n,viaTolerance:!1}]:[]}function Ys(e,t,n){let o=Me(t,n);return $r(e,o,xt(t))}function zs(e,t){let n=e.facilities[t]||po(e,t)[0]?.[1];if(!n)return null;if(n.entry)return $(n.entry.col,n.entry.row);let o=Mn(n)||t;return o==="mixer"?{x:n.x+n.w,y:n.y+n.h*.52}:o==="truck"?{x:n.x,y:n.y+n.h*.52}:o==="trash"?{x:n.x+n.w/2,y:n.y+8}:{x:n.x+n.w/2,y:n.y+n.h/2}}function Ir(e,t,n){return n==="inputA"?qs(e,t).length>0:Ys(e,t,n).length>0}function be(e){e.branchCounters?.clear?.(),e.routeCache=null,e.routingVersion=(e.routingVersion||0)+1,e.factoryGraph=null,e.factoryGraphCommittedVersion=-1}function Re(e,t){return I(e,t)}function vt(e){return J(e)}function Vs(e,t){let n=e.conveyorMeta?.get?.(t)||{},o=[];return Array.isArray(n.outDirs)&&o.push(...n.outDirs),n.dir&&o.push(n.dir),[...new Set(o)].filter(r=>pe.some(s=>s.name===r))}function Xs(e,t){let n=vt(t),o=pe.filter(l=>e.conveyorTiles.has(Re(n.col+l.dc,n.row+l.dr))).map(l=>l.name),r=Vs(e,t).filter(l=>o.includes(l)),s=o,d=r.length?r:s,k=e.conveyorMeta?.get?.(t)||{};if(o.length<3)return d;let M=new Set(o.filter(D=>{let L=pe.find(F=>F.name===D);if(!L)return!1;let F=e.conveyorMeta?.get?.(Re(n.col+L.dc,n.row+L.dr));if(!F)return!1;let z=[...new Set([...Array.isArray(F.outDirs)?F.outDirs:[],F.dir].filter(Boolean))];return z.includes(L.opposite)}));if(k.branchMode&&k.branchMode!=="random"&&o.includes(k.branchMode)){let D=new Set(M);D.add(k.branchMode),o.filter(L=>!D.has(L)).length>=2&&M.add(k.branchMode)}let D=o.filter(L=>!M.has(L));if(D.length)return D;let L=d.filter(F=>!M.has(F));return L.length?L:d}function Qs(e){return{version:e.routingVersion||0,cells:new Set,adjacency:new Map,components:new Map,cellToComponent:new Map,scannerInputs:new Map,scannerPorts:new Map,facilityPorts:new Map,farmOutputs:new Map,pathCache:new Map,metrics:{conveyorCells:0,edges:0,components:0,deadEnds:0,crosses:0,scannerPorts:0,connectedScannerPorts:0,facilityPorts:0,connectedFacilityPorts:0,farmOutputs:0},issues:[]}}function Js(e){let t=Qs(e);for(let o of e.conveyorTiles)t.cells.add(o),t.adjacency.set(o,[]);for(let o of t.cells){let r=vt(o),s=Xs(e,o),l=pe.filter(d=>s.includes(d.name));for(let d of l){let k=Re(r.col+d.dc,r.row+d.dr);t.cells.has(k)&&t.adjacency.get(o).push({key:k,dir:d.name})}}let n=0;for(let[o,r]of t.adjacency.entries()){n+=r.length;let s=new Set(r.map(l=>l.dir));r.length===1&&(t.metrics.deadEnds+=1),r.length===4&&s.has("left")&&s.has("right")&&s.has("up")&&s.has("down")&&(t.metrics.crosses+=1)}return t.metrics.conveyorCells=t.cells.size,t.metrics.edges=Math.floor(n/2),Zs(t),js(e,t),t.issues=dl(e,t,{includeRoutes:!1}),t}function Zs(e){let t=1;for(let n of e.cells){if(e.cellToComponent.has(n))continue;let o=t++,r=[n],s=[];for(e.cellToComponent.set(n,o);r.length;){let l=r.shift();s.push(l);for(let d of e.adjacency.get(l)||[])e.cellToComponent.has(d.key)||(e.cellToComponent.set(d.key,o),r.push(d.key))}e.components.set(o,{id:o,cells:s,capacity:Math.max(1,s.length),count:0,ratio:0})}e.metrics.components=e.components.size}function js(e,t){for(let n of e.scanners){let o={};for(let r of["inputA","left","right"]){let s=Me(n,r),l=r==="inputA"?s&&t.cells.has(Re(s.col,s.row))?[{...s}]:[]:Rr(e,s,xt(n)).filter(M=>t.cells.has(Re(M.col,M.row))),d=l.map(M=>Re(M.col,M.row)),k=d.length>0;if(o[r]={type:r,cell:s,cells:l,keys:d,key:d[0]||null,connected:k},t.metrics.scannerPorts+=1,k&&(t.metrics.connectedScannerPorts+=1),r==="inputA")for(let M of d)t.scannerInputs.set(M,n.id)}t.scannerPorts.set(n.id,o)}for(let[n,o]of Object.entries(e.facilities)){if(!o.entry)continue;let r=Rr(e,o.entry).filter(d=>t.cells.has(Re(d.col,d.row))),s=r.map(d=>Re(d.col,d.row)),l=s.length>0;t.facilityPorts.set(n,{id:n,cell:{...o.entry},cells:r,keys:s,key:s[0]||null,connected:l}),t.metrics.facilityPorts+=1,l&&(t.metrics.connectedFacilityPorts+=1)}for(let n of e.eggFarms){let o=Ar({col:n.col,row:n.row}).map(r=>Re(r.col,r.row)).filter(r=>t.cells.has(r));t.farmOutputs.set(n.id,o),t.metrics.farmOutputs+=o.length}}function De(e){let t=e.routingVersion||0;return(!e.factoryGraph||e.factoryGraph.version!==t)&&(e.factoryGraph=Js(e)),e.factoryGraph}function Fr(e){let t=De(e);return e.factoryGraphCommittedVersion=t.version,e.factoryGraphSnapshot=el(t),t}function el(e){return e?{version:e.version,conveyorCells:e.metrics.conveyorCells,edges:e.metrics.edges,components:e.metrics.components,deadEnds:e.metrics.deadEnds,crosses:e.metrics.crosses,scannerPorts:`${e.metrics.connectedScannerPorts}/${e.metrics.scannerPorts}`,facilityPorts:`${e.metrics.connectedFacilityPorts}/${e.metrics.facilityPorts}`,farmOutputs:e.metrics.farmOutputs,issues:[...e.issues||[]]}:null}function Br(e,t,n){let o=De(e),r=Re(t,n);return(o.adjacency.get(r)||[]).map(s=>({...vt(s.key),dir:pe.find(l=>l.name===s.dir)||{name:s.dir,dc:0,dr:0}}))}function tl(e,t){let n=t.col-e.col,o=t.row-e.row;return pe.find(r=>r.dc===n&&r.dr===o)?.name||null}function nl(e,t,n){return!1}function yo(e,t,n){let o=De(e),r=Re(t.col,t.row);if(!o.cells.has(r))return[];let s=`${r}|${n.cacheKey||"dynamic"}`;if(n.cacheKey&&o.pathCache.has(s))return o.pathCache.get(s).map(g=>g.map(_=>({..._})));let l=`${r}|none`,d=[{key:r,col:t.col,row:t.row,incoming:"none",depth:0}],k=new Map([[l,0]]),M=new Map,D=[],L=1/0,F=8,z=24,oe=80;for(;d.length;){let g=d.shift();if(g.depth>L)break;let _=`${g.key}|${g.incoming}`;if(n(g)){if(D.push(_),L=g.depth,D.length>=z)break;continue}for(let U of o.adjacency.get(g.key)||[]){let le=vt(U.key),me=tl(g,le);if(g.incoming!=="none"&&nl(e,o,g.key)&&me!==g.incoming)continue;let fe=g.depth+1;if(fe>L)continue;let E=`${U.key}|${me}`,G=k.get(E);if(G==null)k.set(E,fe),M.set(E,[_]),d.push({key:U.key,col:le.col,row:le.row,incoming:me,depth:fe});else if(G===fe){let w=M.get(E)||[];w.length{if(X.length>=oe)return;let[U]=g.split("|"),le=[vt(U),..._];if(g===l||U===r){X.push(le);return}for(let me of M.get(g)||[])ae(me,le)};for(let g of D)ae(g,[]);let he=[],j=new Set;for(let g of X){let _=g.map(U=>Re(U.col,U.row)).join(">");j.has(_)||(j.add(_),he.push(g))}return n.cacheKey&&o.pathCache.set(s,he.map(g=>g.map(_=>({..._})))),he}function Lr(e){let t=De(e),n=new Map;for(let[o,r]of t.components.entries())n.set(o,{id:o,cells:[...r.cells],capacity:r.capacity,count:0,ratio:0});return{components:n,cellToComponent:new Map(t.cellToComponent)}}function Or(e,t,n){let o=De(e),r=null,s=1/0;for(let l of o.cells){let d=J(l),k=$(d.col,d.row),M=Math.hypot(k.x-t,k.y-n);M$(o.col,o.row));return t&&n.push(t),n}function tt(e,t){t&&(!e.length||ar(e[e.length-1],t)>1)&&e.push(t)}function ol(e,t,n,o=null){let r=[{x:e.x,y:e.y}];tt(r,$(t.col,t.row));for(let s of Tn(n,o))tt(r,s);return r}function rl(e,t){let n=Tn(e),o=Me(t,"inputA");return o&&tt(n,$(o.col,o.row)),tt(n,de(t)),n}function il(e,t,n,o){let r=[{x:e.x,y:e.y}];tt(r,$(t.col,t.row));for(let l of Tn(n))tt(r,l);let s=Me(o,"inputA");return s&&tt(r,$(s.col,s.row)),tt(r,de(o)),r}function sl(e,t,n=0){let o=$(t.col,t.row),r=0;for(let s of e.chicks||[]){if(s.stage==="flying"||s.stage==="queued")continue;Math.hypot(s.x-o.x,s.y-o.y){let L=M.roleBias??0,F=D.roleBias??0;if(L!==F)return L-F;let z=M.cells?.length??M.route?.length??Number.POSITIVE_INFINITY,oe=D.cells?.length??D.route?.length??Number.POSITIVE_INFINITY;if(z!==oe)return z-oe;let X=M.key||JSON.stringify(M.route||M.cells||M),ae=D.key||JSON.stringify(D.route||D.cells||D);return X.localeCompare(ae)});if(!o||r.length===1)return r[0];let s=r[0].roleBias??0,l=r.filter(M=>(M.roleBias??0)===s),d=Math.min(...l.map(M=>Dr(e,M)));l=l.filter(M=>Dr(e,M)===d);let k=e.branchCounters.get(t)||0;return e.branchCounters.set(t,k+1),l[Math.floor(Math.random()*l.length)]}function Nr(e){return e.role===0?{left:{match:"male",destination:"mixer"},right:{match:"default",destination:"scanner-role-1"}}:{left:{match:"poop",destination:"trash"},right:{match:"default",destination:"truck"}}}function ho(e){let t=Nr(e);return{left:t.left.destination,right:t.right.destination}}function mo(e,t){return Nr(e).left.match===t.sex?"left":"right"}function bo(e){return ur(e)}function wo(e){return{mixer:"#2477ff",truck:"#ff6aa8",trash:"#22b94f","scanner-role-1":"#526456",scanner:"#526456",input:"#526456"}[e]||"#102015"}function Mt(e,t,n=!1){let o=De(e),r=(o.farmOutputs.get(t.id)||[]).map(vt),s=[];for(let k of r){let M=L=>o.scannerInputs.has(Re(L.col,L.row));M.cacheKey=`farmInput:${k.col},${k.row}:v${o.version}`;let D=yo(e,k,M);for(let L of D){let F=L[L.length-1],z=o.scannerInputs.get(Re(F.col,F.row)),oe=St(e,z);oe&&s.push({key:`${oe.id}:${F.col},${F.row}:${L.length}`,scanner:oe,cells:L})}}let l=Sn(e,`farm:${t.id}`,s,n);if(l)return{scannerId:l.scanner.id,route:rl(l.cells,l.scanner)};let d=Sn(e,`farm:${t.id}:output`,r.map(k=>({key:I(k.col,k.row),cells:[k]})),n);return d?{scannerId:null,route:Tn(d.cells)}:null}function Gr(e,t,n,o,r=!1){let s=St(e,o);if(!s)return null;let d=De(e).scannerPorts.get(s.id)?.[t],k=Me(s,t),M=d?.connected?(d.keys||[d.key]).filter(Boolean).map(vt):[];if(!k||!M.length)return null;let D=ho(s)[t];return D==="scanner-role-1"?ll(e,s,t,n,k,M,r):al(e,s,t,n,k,M,D,r)}function ll(e,t,n,o,r,s,l){let d=De(e),k=e.scanners.filter(L=>L.id!==t.id&&d.scannerPorts.get(L.id)?.inputA?.connected),M=[];for(let L of s)for(let F of k){let z=d.scannerPorts.get(F.id)?.inputA?.key;if(!z)continue;let oe=(d.scannerPorts.get(F.id)?.inputA?.keys||[z]).filter(Boolean),X=j=>oe.includes(Re(j.col,j.row));X.cacheKey=`toScanner:${L.col},${L.row}:${F.id}:v${d.version}`;let ae=yo(e,L,X),he=F.role===1?0:1;for(let j of ae)M.push({key:`${he}:start${I(L.col,L.row)}:s${F.id}:${j.length}:${I(j[j.length-1].col,j[j.length-1].row)}`,target:F,cells:j,roleBias:he})}let D=Sn(e,`scanner:${t.id}:${n}:toRole1`,M,l);return D?{destination:"scanner",nextScannerId:D.target.id,route:il(o,r,D.cells,D.target)}:null}function al(e,t,n,o,r,s,l,d){let k=De(e),M=[...k.facilityPorts.entries()].filter(([F,z])=>z?.connected&&Mn(e.facilities?.[F])===l);if(!M.length)return null;let D=[];for(let F of s)for(let[z,oe]of M){let X=(oe.keys||[oe.key]).filter(Boolean);if(!X.length)continue;let ae=j=>X.includes(Re(j.col,j.row));ae.cacheKey=`toFacility:${F.col},${F.row}:${z}:v${k.version}`;let he=yo(e,F,ae);for(let j of he)D.push({key:`start${I(F.col,F.row)}:${z}:${j.length}:${I(j[j.length-1].col,j[j.length-1].row)}`,cells:j,facilityId:z})}let L=Sn(e,`scanner:${t.id}:${n}:${l}`,D,d);return L?{destination:l,facilityId:L.facilityId,route:ol(o,r,L.cells,zs(e,L.facilityId))}:null}function Ur(e,t,n=new Set){if(!t||n.has(t.id))return!1;n.add(t.id);for(let o of["left","right"]){let r=Gr(e,o,de(t),t.id,!1);if(r){if(["mixer","trash","truck"].includes(r.destination))return!0;if(r.destination==="scanner"){let s=St(e,r.nextScannerId);if(Ur(e,s,n))return!0}}}return!1}function cl(e,t){return!!Mt(e,t,!1)?.scannerId}function gn(e){if(e.phase!=="build")return[];let t=[];for(let n of e.eggFarms||[])cl(e,n)||t.push({type:"eggFarm",id:n.id,ref:n,message:"This Egg will not produce chicks"});for(let n of Zt)for(let[o,r]of po(e,n))De(e).facilityPorts.get(o)?.connected||t.push({type:"facility",id:o,ref:r,message:"This facility cannot receive items"});return t}function ul(e){let t=De(e);for(let r of e.eggFarms||[]){let s=Mt(e,r,!1);if(!s?.scannerId)continue;let l=St(e,s.scannerId);if(Ur(e,l))return[]}let n=e.eggFarms?.length||0,o=[...t.facilityPorts.entries()].filter(([r,s])=>s?.connected&&["mixer","trash","truck"].includes(Mn(e.facilities?.[r]))).length;return n?t.metrics.farmOutputs?e.scanners?.length?o?["Connect at least one EGG through a scanner to any valid exit."]:["Connect at least one receiver exit: Mixer, Shredder, or Truck."]:["Build at least one scanner and connect it to an EGG route."]:["Connect at least one EGG to a conveyor."]:["Build at least one EGG before starting the next day."]}function Cn(e){return e.kind==="manual"?`S${(e.slot??0)+1}`:`Auto Scanner #${e.id}`}function dl(e,t=De(e),n={}){let o=n.includeRoutes!==!1,r=[],s={mixer:"Mixer",trash:"Shredder",truck:"Truck"};for(let l of Zt){let d=po(e,l);if(!d.length){r.push(`${s[l]||l} is missing`);continue}for(let[k]of d)t.facilityPorts.get(k)?.connected||r.push(`${s[l]||l} receiver has no conveyor`)}for(let l of e.scanners){let d=t.scannerPorts.get(l.id)||{};if(d.inputA?.connected||r.push(`${Cn(l)} input has no conveyor`),d.left?.connected||r.push(`${Cn(l)} left output has no conveyor`),d.right?.connected||r.push(`${Cn(l)} right output has no conveyor`),!!o)for(let k of["left","right"])d[k]?.connected&&!Gr(e,k,de(l),l.id)&&r.push(`${Cn(l)} ${k} route is incomplete`)}if(o)for(let l of e.eggFarms)Mt(e,l)?.scannerId||r.push(`Egg Farm #${l.id} has no scanner route`);else for(let l of e.eggFarms)(t.farmOutputs.get(l.id)||[]).length||r.push(`Egg Farm #${l.id} has no output conveyor`);return[...new Set(r)]}function tn(e){return ul(e)}function Wr(e){return tn(e).length===0}var _r=[{target:"female",title:"Premium Female Shipment",route:"Female -> Truck",note:"Only female chicks are valid truck cargo this turn."},{target:"male",title:"Male Export Trial",route:"Male -> Truck",note:"Male chicks are temporarily valid truck cargo. Male truck fines are suspended for valid male cargo."},{target:"poop",title:"Contaminant Sample Export",route:"Poop -> Truck",note:"Poop is temporarily valid truck cargo. Shipped poop does not soil this contract shipment."}];function vo(e){return[...e.eggFarms.map(t=>t.price||0),...e.scanners.map(t=>t.price||0),...Object.values(e.facilities).map(t=>t.price||0),...[...e.conveyorMeta.values()].map(t=>t.price||0)].reduce((t,n)=>t+n,0)}function fl(e,t=1){return e.eggFarms.reduce((n,o)=>{let[r,s]=en(o),l=Math.max(.1,(r+s)/2);return n+Bt/l*t},0)}function Kr(e){if(e.turn+1or)return null;let n=_r[Math.floor(Math.random()*_r.length)],o=2,r=3,s=fl(e,o),l=Math.max(1,Math.ceil(s*.9)),d=Math.round((.08+Math.random()*.08)*100)/100,k=Math.floor(vo(e)*d),M=Math.floor(Math.max(0,e.cash)*.25),D=Math.max(k,M);return{id:`contract-${e.turn}-${Date.now()}-${Math.floor(Math.random()*9999)}`,...n,forced:!0,productionMultiplier:o,poopMultiplier:r,targetAmount:l,estimatedOutput:Math.round(s),rewardRate:d,reward:D,rewardByFactory:k,rewardByCash:M,createdTurn:e.turn,oneTurnOnly:!0}}function Hr(e){e.contractActive=e.contractOffer?{...e.contractOffer}:null,e.contractOffer=null}function qr(e){e.contractActive=null}function Yr(e){return e.contractActive?.productionMultiplier||1}function zr(e){let t=Math.max(0,Number(e?.cardEffects?.hatchingFeed)||0),n=Math.pow(1.03,t);return Math.min(.95,rr*(e.contractActive?.poopMultiplier||1)*n)}function ze(e){return e.contractActive?.target||"female"}function xo(e,t){return t==="male"?e.truckMale||0:t==="poop"?e.poopTruck||0:e.truckFemale||0}function Vr(e,t){return ze(e)===t}function Xr(e){return ze(e)!=="male"}function Qr(e){let t=e.contractActive;if(!t)return null;let n=xo(e.stats,t.target),o=n>=t.targetAmount,r=o?t.reward:0;r>0?(Ae(e,r),e.stats.contractBonus=r,e.totals.contractBonus+=r,e.totals.contractSuccess+=1):(e.stats.contractBonus=0,e.totals.contractFailed+=1);let s={title:t.title,target:t.target,route:t.route,targetAmount:t.targetAmount,count:n,success:o,bonus:r,reward:t.reward,productionMultiplier:t.productionMultiplier,poopMultiplier:t.poopMultiplier};return e.stats.contractResult=s,s}function ko(e,t){return Math.max(0,Number(e?.cardEffects?.[t])||0)}function pl(e){return!!e?.cardEffects?.usedMachineActive}function yl(e,t){return t?1:Math.min(.8,.5+.1*Math.min(3,ko(e,"recyclingSubsidy")))}function hl(e){return Math.pow(.95,ko(e,"safetyCover"))}function En(e){let t=e?.ref||e||{},n=e?.type||t.type;return n==="conveyor"?t.price||we[t.kind]?.price||we.conveyor.price:n==="eggFarm"?t.price||we.eggFarm.price:n==="scanner"?t.price||(t.kind==="auto"?we.autoScanner.price:we.manualScanner.price):n==="facility"?t.price||we[t.id]?.price||0:we[t.id]?.price||0}function Be(e,t=null){let n=we[e]?.price||0;return pl(t)?Math.ceil(n*.5):n}function ml(e,t){return e?.facilities?Object.values(e.facilities).filter(n=>(n?.baseId||n?.id)===t).reduce((n,o)=>n+Math.max(0,(o.level||1)-1),0):0}function nt(e,t){return sr.includes(t)?Math.pow(Ce.incomeUpgradeRate,ml(e,t)):1}function _e(e){return Math.ceil(Ce.income.mixer*nt(e,"mixer"))}function Le(e){return Math.ceil(Ce.income.truck*nt(e,"truck"))}function nn(e){return Math.ceil(Ce.poopFine*nt(e,"mixer"))}function on(e){return Math.ceil(Ce.poopFine*nt(e,"truck"))}function Co(e){let t=Ce.maleTruckFinePerHalfDay*(e.turn/2);return Math.ceil(t*nt(e,"truck"))}function Tt(e){let t=Math.max(0,(e.facilities?.trash?.level||1)-1);return Math.min(Ce.shredderBonus.maxCards,t)}function Jr(e){return Math.max(0,(e.facilities?.trash?.level||1)-1)}function Gt(){return Ce.shredderBonus.maxCards}function ot(e){let t=typeof e=="number"?e:Tt(e),n=Math.min(Ce.shredderBonus.maxCards,Math.max(0,t)),o=Math.sqrt(n)/Ce.shredderBonus.probabilityPercentDivisor*n;return Math.min(1,o/100)}function bl(e){let t=Tt(e),n=ot(t),o=t>0&&Math.random()0&&(e.stats.shredderBonus=(e.stats.shredderBonus||0)+t.amount,e.totals.shredderBonus=(e.totals.shredderBonus||0)+t.amount,Ae(e,t.amount)),t}function Pn(e,t=null){let n=Ce.zundaTax,o=Math.max(0,t?.cardEffects?.legalWork||0),r=n.exemption+o*n.legalWorkExemptionBonus,s=n.maxRateCash+o*n.legalWorkExemptionBonus,l=Math.max(0,Math.floor(Number(e)||0)),d=Math.max(0,l-r);if(d<=0)return{profit:l,exemption:r,maxRateCash:s,taxable:0,rate:0,ratePercent:0,tax:0,step:0,legalWork:o};let k=Math.max(1,Math.ceil(d/n.stepAmount)),M=Math.min(n.maxRate,k*n.stepRate),D=Math.ceil(d*M);return{profit:l,exemption:r,maxRateCash:s,taxable:d,rate:M,ratePercent:Math.round(M*100),tax:D,step:k,legalWork:o}}function So(e,t=e.turn){let n=Math.max(1,Math.floor(Number(t)||1)),o=Math.ceil(n*Ce.fairiesTribute.perDay),r=Math.max(0,e?.cardEffects?.fairiesFlatteryNext||e?.cardEffects?.flattery||0),s=r>0?Math.pow(.5,r):1,l=Math.max(0,Math.ceil(o*s)),d=Math.max(0,o-l);return{day:n,base:o,flatteryCount:r,perCardReduction:Math.ceil(o*.5),reduction:d,amount:l}}function gt(e,t){let n=e?.ref||e||{},o=e?.type==="conveyor"?t?.conveyorMeta?.get(e.oldKey||n.id):n,r=o?.price||En(e||n),s=o?.builtSession===t?.buildSession;if(o?.noRefund||n?.noRefund)return{amount:0,sameBuild:s,price:r,rate:0,noRefund:!0};let l=yl(t,s);return{amount:Math.max(0,Math.ceil(r*l)),sameBuild:s,price:r,rate:l,noRefund:!1}}function wl(e,t=null){let n=Math.max(1,Math.ceil((Number(e)||0)/Ce.explosionDamageDivisor));return Math.max(1,Math.ceil(n*hl(t)))}function vl(e,t){return Math.max(0,Math.ceil(t))}function jr(e,t){let n=e.cash;e.cash+=t,e.stats.profit+=t,e.totals.profit+=t,t>=0?(e.stats.revenue+=t,e.totals.revenue+=t):(e.stats.penalty+=Math.abs(t),e.totals.penalty+=Math.abs(t)),e.totals.maxCash=Math.max(e.totals.maxCash,e.cash)}function Ae(e,t){let n=Math.max(0,Math.ceil(t));return n>0&&jr(e,n),n}function Ve(e,t){let n=Math.max(0,Math.ceil(t));return n>0&&jr(e,-n),n}function rt(e,t){Ve(e,t)}function ei(e,t){if(t<=0)return;let n=e.cash;e.cash+=t,e.stats.profit+=t,e.totals.profit+=t,e.totals.maxCash=Math.max(e.totals.maxCash,e.cash)}function ti(e){let t=_e(e);return e.stats.mixerRevenue+=t,Ae(e,t),t}function ni(e){let t=nn(e);return e.stats.mixerPoopFine+=t,e.totals.mixerPoopFine+=t,Ve(e,t),t}function oi(e){let t=on(e);return e.stats.truckPoopFine+=t,e.totals.truckPoopFine+=t,Ve(e,t),t}function ri(e){let t=Co(e);return e.stats.maleTruckFine+=t,e.totals.maleTruckFine+=t,Ve(e,t),t}function ii(e,t){let n=wl(t,e);return e.stats.explosionDamage+=n,e.totals.explosionDamage+=n,Ve(e,n),n}function si(e){let t=ze(e),n=xo(e.stats,t),o=Le(e),r=n*o,s=vl(e,r);return e.stats.pendingTruckRevenue=s,e.stats.truckRevenue=s,t==="poop"?e.stats.poopShipmentIncome=s:e.stats.chickShipmentIncome=s,s>0&&Ae(e,s),{base:r,adjusted:s,target:t,targetCount:n,unitPrice:o}}function li(e,t=0){let n=Pn(t,e);return n.tax<=0||(e.totals.zundaTax=(e.totals.zundaTax||0)+n.tax,e.totals.penalty=(e.totals.penalty||0)+n.tax,e.totals.profit=(e.totals.profit||0)-n.tax,e.cash-=n.tax),n}function ai(e,t=e.turn){let n=So(e,t);return e.cardEffects&&(e.cardEffects.fairiesFlatteryNext=0,e.cardEffects.flattery!=null&&delete e.cardEffects.flattery),n.amount<=0||(e.stats.fairiesTribute=(e.stats.fairiesTribute||0)+n.amount,e.totals.fairiesTribute=(e.totals.fairiesTribute||0)+n.amount,Ve(e,n.amount)),n}function ci(e){let t=ko(e,"chemicalWeaponSubsidy"),n=Math.max(0,e?.stats?.poopTruck||0),o=Math.floor(n/100),r=t>0&&o>0?o*2e3*t:0;return r>0&&(e.stats.chemicalWeaponSubsidy=(e.stats.chemicalWeaponSubsidy||0)+r,e.totals.chemicalWeaponSubsidy=(e.totals.chemicalWeaponSubsidy||0)+r,Ae(e,r)),{cards:t,poopTruck:n,blocks:o,amount:r}}function ui(e){let t=e?.cardEffects;if(!t||!Array.isArray(t.loans)||!t.loans.length)return{amount:0,paidLoans:0,remainingLoans:0};let n=0,o=0,r=[];for(let s of t.loans){if((s.daysRemaining||0)<=0)continue;let l=Math.max(0,Math.ceil(s.dailyPayment||400));n+=l,o+=1;let d=Math.max(0,(s.daysRemaining||0)-1);d>0&&r.push({...s,daysRemaining:d})}return t.loans=r,n>0&&(e.stats.loanRepayment=(e.stats.loanRepayment||0)+n,e.totals.loanRepayment=(e.totals.loanRepayment||0)+n,Ve(e,n)),{amount:n,paidLoans:o,remainingLoans:r.length}}function di(e){let t=vo(e),n=Math.max(1,e.totals.turnsCompleted||e.turn||1),o=Math.max(0,e.cash+e.totals.revenue+t*.5+e.totals.contractBonus*.5),r=Math.ceil(o/n),s=Math.floor(n*35+Math.max(0,n-5)*15),l=e.totals.correct*5,d=e.totals.explosionDamage;return{score:Math.max(0,Math.floor(o+r+l-e.totals.penalty-s)),factoryValue:t,base:o,dailyEarned:r,dayPenalty:s,correctBonus:l,explosionPenalty:d,days:n}}function xl(e){return{...e,keys:e.keys?{left:{...e.keys.left},right:{...e.keys.right}}:null,queue:[],cooldown:e.cooldown||0}}function rn(e){return JSON.stringify({cash:e.cash,stats:e.stats,totals:e.totals,nextId:e.nextId,gridX:y.x,gridY:y.y,gridCols:e.gridCols||y.cols,gridRows:e.gridRows||y.rows,gridExpansionPurchases:e.gridExpansionPurchases||0,gridExpansionPurchasesByDirection:e.gridExpansionPurchasesByDirection||{right:0,up:0},gridChunkOriginY:e.gridChunkOriginY||0,ownedCells:[...e.ownedCells||[]],ownedChunks:[...e.ownedChunks||[]],blockedCells:[...e.blockedCells||[]],selected:e.selected,multiSelected:e.multiSelected||[],buildTool:e.buildTool,view:e.view,facilities:e.facilities,eggFarms:e.eggFarms,scanners:e.scanners.map(xl),conveyorTiles:[...e.conveyorTiles],conveyorMeta:[...e.conveyorMeta.entries()],branchCounters:[...e.branchCounters.entries()],cardEffects:e.cardEffects,cardDraft:e.cardDraft,cardTargetPick:e.cardTargetPick})}function fi(e,t){let n=JSON.parse(t);e.cash=n.cash,e.stats=n.stats,e.totals=n.totals,e.nextId=n.nextId,y.x=n.gridX??q.grid.x,y.y=n.gridY??q.grid.y,y.cols=n.gridCols||q.grid.cols,y.rows=n.gridRows||q.grid.rows,e.gridCols=y.cols,e.gridRows=y.rows,e.gridExpansionPurchases=n.gridExpansionPurchases||0,e.gridExpansionPurchasesByDirection=n.gridExpansionPurchasesByDirection||{right:0,up:0},e.gridChunkOriginY=n.gridChunkOriginY||0,e.ownedCells=new Set(n.ownedCells||[]),e.ownedChunks=new Set(n.ownedChunks||[]),e.gridOwnedCells=e.ownedCells.size||y.cols*y.rows,e.blockedCells=new Set(n.blockedCells||[]),e.selected=n.selected,e.multiSelected=n.multiSelected||[],e.buildTool=n.buildTool,e.view=n.view||{x:0,y:0,scale:1},e.view.scale==null&&(e.view.scale=1),e.facilities=n.facilities||{},e.eggFarms=n.eggFarms||[],e.scanners=(n.scanners||[]).map(o=>({...o,queue:[],cooldown:o.cooldown||0})),e.conveyorTiles=new Set(n.conveyorTiles||[]),e.conveyorMeta=new Map(n.conveyorMeta||[]),e.branchCounters=new Map(n.branchCounters||[]),e.cardEffects=n.cardEffects||{bearing:0,legalWork:0,fairiesFlatteryNext:0,scannerQueueSpacing:0},e.cardEffects.drawBonus!=null&&delete e.cardEffects.drawBonus,e.cardDraft=n.cardDraft||{pending:!1,choices:[],rerolls:0,picksRemaining:0},e.cardDraft.picksRemaining==null&&(e.cardDraft.picksRemaining=e.cardDraft.pending?1:0),e.cardDraft.freeRerolls==null&&(e.cardDraft.freeRerolls=0),e.cardTargetPick=n.cardTargetPick||null,e.groupDrag=null,e.selectionBox=null,e.pan=null,e.routingVersion=(e.routingVersion||0)+1,e.factoryGraph=null,e.factoryGraphCommittedVersion=-1}function Oe(e){e.phase==="build"&&(e.undoStack.push(rn(e)),e.undoStack.length>80&&e.undoStack.shift(),e.redoStack=[])}function Mo(e){return e.phase!=="build"||!e.undoStack.length?!1:(e.redoStack.push(rn(e)),fi(e,e.undoStack.pop()),!0)}function To(e){return e.phase!=="build"||!e.redoStack.length?!1:(e.undoStack.push(rn(e)),fi(e,e.redoStack.pop()),!0)}function N(e,t,n,o,r=f.ink){e.floatingTexts.push({x:t,y:n,text:o,color:r,life:1,maxLife:1})}function Et(e,t,n){e.shake.strength=Math.max(e.shake.strength,t),e.shake.time=Math.max(e.shake.time,n)}function pi(e,t,n){e.effects.push({type:"spawn",priority:Se.ambient,x:t,y:n,life:.42,maxLife:.42,size:12})}function yi(e,t,n,o=f.green){e.effects.push({type:"scannerPulse",priority:Se.important,x:t,y:n,color:o,life:.42,maxLife:.42,size:24})}function hi(e,t,n){for(let o=0;o<12;o+=1)e.effects.push({type:"meat",priority:Se.important,x:t+W(-18,18),y:n+W(-12,16),vx:W(-60,60),vy:W(-90,-25),life:W(.45,.85),maxLife:.85,size:W(4,8)})}function mi(e,t,n){for(let o=0;o<16;o+=1)e.effects.push({type:"sludge",priority:Se.important,x:t+W(-18,18),y:n+W(-12,16),vx:W(-46,46),vy:W(-70,-20),life:W(.45,.9),maxLife:.9,size:W(4,8)})}function bi(e,t,n,o){let r=o==="poop"?f.poop:o==="male"?f.male:f.female;for(let s=0;s<22;s+=1)e.effects.push({type:"shred",priority:Se.important,x:t+W(-16,16),y:n+W(-8,8),vx:W(-70,70),vy:W(40,160),color:s%3===0?f.white:r,life:W(.45,.95),maxLife:.95,w:W(3,7),h:W(10,24),rot:W(-Math.PI,Math.PI)});Xe(e,t,n,f.green,34,Se.important)}function wi(e,t,n,o){let r=o==="poop"?f.poop:o==="male"?f.danger:f.green;for(let s=0;s<8;s+=1)e.effects.push({type:"load",priority:Se.important,x:t+W(-18,18),y:n+W(-18,18),vx:W(-42,42),vy:W(-90,-25),color:r,life:W(.35,.65),maxLife:.65,size:8})}function Xe(e,t,n,o=f.danger,r=52,s=Se.critical){e.effects.push({type:"shockwave",priority:s,x:t,y:n,color:o,life:.55,maxLife:.55,size:8,maxSize:r})}function it(e,t,n,o=12,r=f.danger,s=Se.critical){for(let l=0;l0&&(e.shake.time=Math.max(0,e.shake.time-t),e.shake.time<=0&&(e.shake.strength=0));for(let r of e.effects)if(r.life-=t,["meat","sludge","spark","smoke","shred","load","rage"].includes(r.type))r.x+=(r.vx||0)*t,r.y+=(r.vy||0)*t,r.vy=(r.vy||0)+150*t;else if(r.type==="flyingChick"){r.x+=r.vx*t,r.y+=r.vy*t,r.vy+=360*t,r.noDamage||kl(e,r,o);let s=r.x+e.view.x,l=r.y+e.view.y;(s<-100||l<-100||s>n.width+100||l>n.height+100)&&(r.life=0)}e.effects=e.effects.filter(r=>r.life>0);for(let r of e.floatingTexts)r.life-=t,r.y-=34*t;e.floatingTexts=e.floatingTexts.filter(r=>r.life>0)}function kl(e,t,n){t.hit||(t.hit=new Set);for(let o of n()){if(t.hit.has(o.id)||t.xo.x+o.w||t.yo.y+o.h)continue;t.hit.add(o.id);let r=ii(e,o.price);N(e,t.x,t.y-10,`-${S(r)}`,f.danger),Xe(e,t.x,t.y,f.danger,30),it(e,t.x,t.y,5,f.danger),Et(e,5,.18)}}var $e=q.maintenance;function Eo(e,t){return Math.max(0,Number(e?.cardEffects?.[t])||0)}function $n(e){let t=Math.min(1.4,1+.04*Math.min(10,Eo(e,"crowdedFarming"))),n=Math.pow(.95,Eo(e,"preventiveMaintenance"));return t*n}function Cl(e){return Math.pow(1.03,Eo(e,"durabilityCoating"))}function In(e,t,n=1){let o=$e.durability[t]||1e3;return Math.max(1,Math.ceil(o*Math.max(.1,n||1)*Cl(e)))}function Do(e){let t=$e.repairman.dailyCost;return e?.cardEffects?.laborExploitation?Math.ceil(t*.7):t}function ki(e){return Math.max(.1,Number(e?.durabilityBaseMultiplier)||1)}function ye(e){e.repairman||(e.repairman={hiredForNextDay:!1,active:!1,x:y.x+y.cell*.5,y:y.y+y.rows*y.cell+84,target:null,repairedToday:0});for(let[t,n]of e.conveyorMeta||[]){n.uses==null&&(n.uses=0),n.maintenanceType==null&&(n.maintenanceType="conveyor"),n.kind||(n.kind="conveyor"),n.speedMultiplier||(n.speedMultiplier=n.kind==="boostConveyor"?2:1),n.branchMode||(n.branchMode="random");let o=In(e,"conveyor",ki(n));(n.durability==null||n.durability0&&(n.processingCooldown=Math.max(0,n.processingCooldown-t))}function On(e){ye(e);let t=[];for(let[n,o]of e.conveyorMeta||[])t.push({type:"conveyor",key:n,meta:o,label:`${o.kind==="boostConveyor"?"Boost Belt":"Belt"} ${n}`,center:$(J(n).col,J(n).row)});for(let n of e.eggFarms||[])t.push({type:"eggFarm",ref:n,label:`EGG #${n.id}`,center:$(n.col,n.row)});for(let n of(e.scanners||[]).filter(o=>o.kind==="auto"))t.push({type:"autoScanner",ref:n,label:`AUTO #${n.id}`,center:$(n.col,n.row)});for(let n of["mixer","trash"]){let o=e.facilities?.[n];o&&t.push({type:n,ref:o,label:o.shortName||o.name||n,center:{x:o.x+o.w/2,y:o.y+o.h/2}})}return t}function Dn(e){return e.meta?Ut(e):Ut(e.ref)}function sn(e){return e.meta?Po(e):Po(e.ref)}function An(e){return e.meta?Ro(e):Ro(e.ref)}function Ei(e,t){Sl(e.meta?e:e.ref,Math.max(0,sn(e)-t))}function Pi(e){return e.type==="conveyor"?`conveyor:${e.key}`:`${e.type}:${e.ref?.id||e.ref?.type||e.type}`}function Ri(e,t=.02){ye(e);let n=Math.max(0,Number(t)||0),o=0;for(let r of On(e)){let s=sn(r);Ei(r,An(r)*n),o+=Math.max(0,s-sn(r))/An(r)*100}return o}function Di(e){if(ye(e),e.repairman.hiredForNextDay)return{ok:!1,reason:"Repairman already hired."};let t=Do(e);return e.cashPi(o)===t.key)||null}function gl(e){let t=null;for(let n of On(e)){let o=Dn(n);o<=.001||(!t||o>Dn(t))&&(t=n)}return t}function Ii(e,t){ye(e);let n=e.repairman;if(!n.active||e.phase!=="running")return;let o=Tl(e,n.target)||gl(e);if(!o){n.target=null;return}n.target={key:Pi(o),label:o.label};let r=$e.repairman.walkSpeed,s=o.center.x-n.x,l=o.center.y-n.y,d=Math.hypot(s,l);if(d>8){let F=Math.min(d,r*t);n.x+=s/d*F,n.y+=l/d*F;return}let k=t/($e.repairman.secondsPerOnePercent*100),M=sn(o),D=k*An(o);Ei(o,D);let L=Math.max(0,(M-sn(o))/An(o)*100);n.repairedToday=(n.repairedToday||0)+L,L>0&&Math.random()<.02&&N(e,n.x,n.y-28,"REPAIR",f.green),Dn(o)<=.001&&(n.target=null)}function El(e){let t=0,n="none";for(let o of On(e)){let r=Dn(o);r>t&&(t=r,n=o.label)}return{ratio:t,percent:Math.round(t*100),label:n}}function No(e){let t=El(e),n=$o(e);return{worst:t,avgBeltPerformance:n,repairman:e.repairman||null}}var Pl=Ee.commonWeight,Rl=Ee.rareWeight,Dl=Ee.ultraRareWeight||.45,Pt=Ee.baseDraftSize,Kt=ir;function _t(e,t){let n=Ie(e);return Math.max(0,Number(n[t])||0)}function Ie(e){e.cardEffects||(e.cardEffects={...to,loans:[]});for(let[t,n]of Object.entries(to))e.cardEffects[t]==null&&(e.cardEffects[t]=Array.isArray(n)?[]:n);return e.cardEffects.flattery!=null&&(e.cardEffects.fairiesFlatteryNext=Math.max(0,e.cardEffects.fairiesFlatteryNext||0)+Math.max(0,e.cardEffects.flattery||0),delete e.cardEffects.flattery),Array.isArray(e.cardEffects.loans)||(e.cardEffects.loans=[]),e.cardEffects.drawBonus!=null&&delete e.cardEffects.drawBonus,e.cardDraft||(e.cardDraft={pending:!1,choices:[],rerolls:0,picksRemaining:0}),e.cardDraft.picksRemaining==null&&(e.cardDraft.picksRemaining=e.cardDraft.pending?1:0),e.cardDraft.freeRerolls==null&&(e.cardDraft.freeRerolls=0),e.cardEffects}function Wi(e){let t=Math.max(.5,1-.05*Math.min(10,_t(e,"crowdedFarming"))),n=Math.pow(.96,_t(e,"hatchingFeed"));return t*n}function _i(e,t=null){return Math.min(3,Math.max(0,Number(t?.extraEggOutlet)||0))}function Ki(e){return Math.pow(.85,_t(e,"scannerQueueSpacing"))}function Gn(e,t=null){let n=Ie(e),o=mn*Math.pow(bn,Math.max(0,n.bearing||0)),r=t?Math.max(.1,Number(e?.conveyorMeta?.get?.(t)?.speedMultiplier)||1):1,s=t?1:$o(e);return Math.min(Lt,o*s)*r}function Qe(e,t=null){let n=Math.max(0,(e?.level||1)-1),o=Math.max(eo,hn*Math.pow(nr,n));return t?Math.max(eo,o*Bn(e)):o}function Fi(e){let t=e.cardDraft||{rerolls:0},n=Math.max(1,(t.rerolls||0)+1);return Math.ceil(Math.max(1,e.turn||1)/Ee.rerollCost.dayDivisor*n*Ee.rerollCost.multiplier)}function Uo(e){return Kt.find(t=>t.id===e)||null}function Wo(e,t){let n=typeof t=="string"?Uo(t):t;if(Ie(e),!n||n.type==="dud")return{ok:!1,reason:"Card not found."};if(n.id==="extraCards")return e.cardDraft=e.cardDraft||{pending:!1,choices:[],rerolls:0,picksRemaining:0},e.cardDraft.choices.push(...Nn(e,2)),{ok:!0,reason:`${n.title} added draft cards.`};if(n.type==="instant")return qi(e,n),{ok:!0,reason:`${n.title} granted.`};if(n.type==="equipmentUpgrade"){let o=Ue(e,n)[0];return o?(Hi(e,o),{ok:!0,reason:`${n.title} applied.`}):{ok:!1,reason:`No valid target for ${n.title}.`}}if(n.type==="cellAction"&&n.target==="blockedCell"){let o=Ue(e,n).slice(0,3);if(!o.length)return{ok:!1,reason:"No blocked cells to remove."};for(let r of o){e.blockedCells.delete(I(r.col,r.row));let s=$(r.col,r.row);st(e,s.x,s.y)}return be(e),{ok:!0,reason:`${n.title} removed ${o.length} blocked cells.`}}return{ok:!1,reason:`${n.title} cannot be debug-granted.`}}function Al(e,t){if(t.type==="blockedCell")return`Blocked cell ${t.col},${t.row}`;if(t.type==="eggFarm")return`EGG #${t.id} L${t.level} -> L${t.level+1}`;if(t.type==="eggOutlet"){let n=Math.max(0,Number(t.farm?.extraEggOutlet)||0);return`EGG #${t.id} OUTLET ${1+n} -> ${2+n}`}if(t.type==="scanner")return`AUTO #${t.id} L${t.level} -> L${t.level+1} | CD ${Qe(t,e).toFixed(1)}s -> ${Qe({...t,level:t.level+1},e).toFixed(1)}s`;if(t.type==="facility"&&(t.baseId||t.id)==="mixer"){let n=t.level,o=_e(e);t.level=n+1;let r=_e(e);return t.level=n,`MIXER L${t.level} -> L${t.level+1} | ${S(o)} -> ${S(r)}`}if(t.type==="facility"&&(t.baseId||t.id)==="truck"){let n=t.level,o=Le(e);t.level=n+1;let r=Le(e);return t.level=n,`TRUCK L${t.level} -> L${t.level+1} | ${S(o)} -> ${S(r)}`}if(t.type==="facility"&&t.id==="trash"){let n=Tt(e),o=Math.min(Gt(),n+1),r=(ot(n)*100).toFixed(2),s=(ot(o)*100).toFixed(2);return`SHREDDER L${t.level||1} -> L${(t.level||1)+1} | ${r}% -> ${s}% per item`}return`${t.name||t.id} L${t.level||1} -> L${(t.level||1)+1}`}function $l(e){return[...e.blockedCells||[]].map(t=>{let[n,o]=String(t).split(",").map(Number);return{type:"blockedCell",id:t,col:n,row:o}}).filter(t=>Number.isFinite(t.col)&&Number.isFinite(t.row))}function Ue(e,t){let n=typeof t=="string"?Uo(t):t;return Ie(e),n?n.target==="blockedCell"?$l(e):n.target==="eggFarm"?e.eggFarms.filter(o=>(o.level||1)<4):n.target==="eggOutlet"?e.eggFarms.filter(o=>Math.max(0,Number(o.extraEggOutlet)||0)<3).map(o=>({type:"eggOutlet",id:o.id,col:o.col,row:o.row,farm:o})):n.target==="autoScanner"?e.scanners.filter(o=>o.kind==="auto"):n.target==="mixer"?Object.values(e.facilities||{}).filter(o=>(o.baseId||o.id)==="mixer"):n.target==="truck"?Object.values(e.facilities||{}).filter(o=>(o.baseId||o.id)==="truck"):n.target==="trash"?Jr(e)(o.baseId||o.id)==="trash"):[]:[]:[]}function Il(e,t){let n=Ie(e);if(t.id==="crowdedFarming")return(n.crowdedFarming||0)>=10;if(t.id==="recyclingSubsidy")return(n.recyclingSubsidy||0)>=3;if(t.id==="dudFilter"){let o=Math.max(0,Math.min(1,Ee.dudChancePerCard||0)),r=Math.max(1e-4,Math.min(1,Ee.dudChanceReductionPerFilter||.05));return(n.dudFilter||0)>=Math.ceil(o/r)}return t.id==="laborExploitation"?!!n.laborExploitation:t.id==="usedMachine"?!!n.usedMachineActive:t.id==="newMachine"?!n.usedMachineActive:!1}function Fl(e){let t=e.repairman||{};return!!(t.active||t.hiredForNextDay||e.pendingRepairWorkerWages>0)}function Bl(e){return Kt.filter(t=>!(t.id==="laborExploitation"&&!Fl(e)||Il(e,t)||(t.type==="equipmentUpgrade"||t.type==="cellAction")&&Ue(e,t).length<=0))}function Bi(e,t){if(t.weightBase!=null){let n=_t(e,t.id);return Math.max(0,Number(t.weightBase)-Math.max(0,Number(t.weightLossPerCopy)||0)*n)}return t.rarity==="ultraRare"?Dl:t.rarity==="rare"?Rl:Pl}function Ll(e,t){let n=t.reduce((r,s)=>r+Bi(e,s),0);if(n<=0)return t[Math.floor(Math.random()*t.length)];let o=Math.random()*n;for(let r of t)if(o-=Bi(e,r),o<=0)return r;return t[t.length-1]}var Li=0;function Ol(){return Li+=1,{id:`dud:${Date.now()}:${Li}`,title:"Dud",rarity:"dud",type:"dud",description:"Click to flick this dud away. It does not consume a pick."}}function Nl(e){let t=Ie(e),n=Math.max(0,Math.min(1,Ee.dudChancePerCard||0)),o=Math.max(0,Math.min(1,Ee.dudChanceReductionPerFilter||0));return Math.max(0,n-o*Math.max(0,t.dudFilter||0))}function Gl(e,t){let n=[...t],o=0,r=Math.max(0,Ee.maxDudsPerDraft||0),s=Nl(e);for(let l=0;ld.id===s.id);l>=0&&r.splice(l,1)}return Gl(e,o)}function Wt(e){return e?e.type==="blockedCell"?`blockedCell:${e.id}`:e.type==="eggFarm"?`eggFarm:${e.id}`:e.type==="eggOutlet"?`eggOutlet:${e.id}`:e.type==="scanner"?`scanner:${e.id}`:e.type==="facility"?`facility:${e.id}`:`${e.type}:${e.id}`:""}function Oi(e){if(!e)return null;if(e.type==="blockedCell"){let t=$(e.col,e.row);return{x:t.x-y.cell*.48,y:t.y-y.cell*.48,w:y.cell*.96,h:y.cell*.96,cx:t.x,cy:t.y}}if(e.type==="eggFarm"||e.type==="eggOutlet"){let t=$(e.col,e.row);return{x:t.x-34,y:t.y-34,w:68,h:68,cx:t.x,cy:t.y}}if(e.type==="scanner"){let t=de(e);return{x:t.x-54,y:t.y-77,w:108,h:154,cx:t.x,cy:t.y}}return e.type==="facility"?{x:e.x,y:e.y,w:e.w,h:e.h,cx:e.x+e.w/2,cy:e.y+e.h/2}:null}function _o(e){if(!e.cardTargetPick?.pending)return[];if(e.cardTargetPick.mode==="autoScannerMenu"){let n=new Set(e.cardTargetPick.targetKeys||[]);return e.scanners.filter(o=>o.kind==="auto"&&n.has(Wt(o))).map(o=>({key:Wt(o),label:"AUTO ROUTE SETTINGS",target:o,bounds:Oi(o)})).filter(o=>o.bounds)}let t=new Set(e.cardTargetPick.targetKeys||[]);return Ue(e,e.cardTargetPick.cardId).filter(n=>t.has(Wt(n))).map(n=>({key:Wt(n),label:Al(e,n),target:n,bounds:Oi(n)})).filter(n=>n.bounds)}function Ul(e,t){let n=_o(e);for(let o of n){let r=o.bounds;if(t.x>=r.x&&t.x<=r.x+r.w&&t.y>=r.y&&t.y<=r.y+r.h)return o.target}return null}function Hi(e,t){if(t.type==="eggOutlet"){let n=t.farm||e.eggFarms.find(r=>r.id===t.id);if(!n)return;n.extraEggOutlet=Math.min(3,Math.max(0,Number(n.extraEggOutlet)||0)+1);let o=$(n.col,n.row);N(e,o.x,o.y-30,`OUTLET ${1+n.extraEggOutlet}`,f.green),be(e);return}if(t.level=(t.level||1)+1,t.type==="eggFarm"){t.nextSpawn=wt(t),t.lastInterval=t.nextSpawn;let n=$(t.col,t.row);N(e,n.x,n.y-30,`LV ${t.level}`,f.green);return}if(t.type==="scanner"){let n=de(t);N(e,n.x,n.y-34,`LV ${t.level}`,f.green);return}t.type==="facility"&&N(e,t.x+t.w/2,t.y+18,`LV ${t.level}`,f.green)}function qi(e,t){let n=Ie(e),o=r=>{n[r]=Math.max(0,n[r]||0)+1};if(t.id==="bearing"&&o("bearing"),t.id==="legalWork"&&o("legalWork"),t.id==="crowdedFarming"&&(n.crowdedFarming=Math.min(10,(n.crowdedFarming||0)+1)),t.id==="hatchingFeed"&&o("hatchingFeed"),t.id==="safetyCover"&&o("safetyCover"),t.id==="recyclingSubsidy"&&(n.recyclingSubsidy=Math.min(3,(n.recyclingSubsidy||0)+1)),t.id==="chemicalWeaponSubsidy"&&o("chemicalWeaponSubsidy"),t.id==="preventiveMaintenance"&&o("preventiveMaintenance"),t.id==="dudFilter"&&o("dudFilter"),t.id==="durabilityCoating"&&(o("durabilityCoating"),ye(e)),t.id==="sparePartsBin"){o("sparePartsBin");let r=Ri(e,.02);e.stats.sparePartsRepair=(e.stats.sparePartsRepair||0)+r,e.totals.sparePartsRepair=(e.totals.sparePartsRepair||0)+r,N(e,y.x+y.cols*y.cell/2,y.y-30,"REPAIR +2%",f.green)}if(t.id==="dudRefund"&&o("dudRefund"),t.id==="freeReroll"&&o("freeReroll"),t.id==="composter"&&o("composter"),t.id==="scannerQueueSpacing"&&o("scannerQueueSpacing"),t.id==="flattery"&&o("fairiesFlatteryNext"),t.id==="usedMachine"&&(n.usedMachineActive=!0),t.id==="newMachine"&&(n.usedMachineActive=!1),t.id==="laborExploitation"&&(n.laborExploitation=1),t.id==="rescueLoan"&&(o("rescueLoanCharges"),N(e,y.x+y.cols*y.cell/2,y.y-30,"RESCUE HELD",f.green)),t.id==="loan"){let r=Math.max(1,Math.floor(Number(e.turn)||1)),s=300*r;Ae(e,s),n.loans.push({daysRemaining:r,dailyPayment:400,borrowedOnTurn:e.turn||1}),N(e,y.x+y.cols*y.cell/2,y.y-30,`LOAN +${S(s)}`,f.green)}}function Ne(e){return`${Math.round(Number(e||0)*100)}%`}function Ni(e){let t=et[Math.max(0,Math.min(et.length-1,e-1))]||et[0]||[0,0];return`${t[0].toFixed(2)}-${t[1].toFixed(2)}s`}function Gi(e,t){return Math.ceil(e*Math.pow(Ce.incomeUpgradeRate,Math.max(0,t-1)))}function Ui(e,t,n){let r=Ue(e,t==="mixer"?"upgradeMixer":"upgradeTruck")[0];if(!r)return{before:Gi(n,1),after:Gi(n,2)};let s=t==="mixer"?_e(e):Le(e),l=r.level||1;r.level=l+1;let d=t==="mixer"?_e(e):Le(e);return r.level=l,{before:s,after:d}}function Wl(e,t){let n=Ie(e);if(t.id==="upgradeEgg"){let o=Ue(e,t),r=Math.min(3,Math.max(1,o[0]?.level||1));return`Choose one EGG. Level +1. Production interval ${Ni(r)} -> ${Ni(r+1)}.`}if(t.id==="upgradeAutoScanner"){let o=Ue(e,t)[0]||{level:1},r=Qe(o,e),s=Qe({...o,level:(o.level||1)+1},e);return`Choose one AUTO SCANNER. Level +1. Cooldown ${r.toFixed(2)}s -> ${s.toFixed(2)}s.`}if(t.id==="upgradeMixer"){let o=Ui(e,"mixer",Ce.income.mixer);return`Choose one MIXER. Earning +10%. Male-chick income ${S(o.before)} -> ${S(o.after)}.`}if(t.id==="upgradeTruck"){let o=Ui(e,"truck",Ce.income.truck);return`Choose one TRUCK. Earning +10%. Correct shipment income ${S(o.before)} -> ${S(o.after)}.`}if(t.id==="upgradeTrash"){let o=Tt(e),r=Math.min(Gt(),o+1);return`SHREDDER level +1. Bonus chance per item ${Ne(ot(o))} -> ${Ne(ot(r))}.`}if(t.id==="bearing"){let o=Math.min(Lt,mn*Math.pow(bn,Math.max(0,n.bearing||0))),r=Math.min(Lt,mn*Math.pow(bn,Math.max(0,(n.bearing||0)+1)));return`Conveyor speed +7.5%. After pick: ${o.toFixed(1)} -> ${r.toFixed(1)} px/s.`}if(t.id==="legalWork"){let o=Math.max(0,n.legalWork||0);return`ZUNDA TAX exemption +${S(250)}. After pick: exemption bonus ${S(250*(o+1))}.`}if(t.id==="crowdedFarming"){let o=Math.min(10,(n.crowdedFarming||0)+1);return`Held ${n.crowdedFarming||0}/10. After pick: EGG interval ${Ne(Math.max(.5,1-.05*o))}, deterioration ${Ne(Math.min(1.4,1+.04*o))}.`}if(t.id==="extraEggOutlet"){let o=Ue(e,t),r=Math.max(0,Number(o[0]?.farm?.extraEggOutlet)||0);return`Choose one EGG. Output ports ${1+r} -> ${2+r}. Max 4 ports per EGG.`}if(t.id==="hatchingFeed")return`Held ${n.hatchingFeed||0}. After pick: EGG interval ${Ne(Math.pow(.96,(n.hatchingFeed||0)+1))}, poop rate ${Ne(Math.pow(1.03,(n.hatchingFeed||0)+1))}.`;if(t.id==="safetyCover")return`Held ${n.safetyCover||0}. After pick: explosion damage ${Ne(Math.pow(.95,(n.safetyCover||0)+1))}.`;if(t.id==="recyclingSubsidy")return`Held ${n.recyclingSubsidy||0}/3. After pick: normal SELL refund ${Math.round(Math.min(.8,.5+.1*((n.recyclingSubsidy||0)+1))*100)}%.`;if(t.id==="chemicalWeaponSubsidy")return`Held ${n.chemicalWeaponSubsidy||0}. After pick: ${S(2e3*((n.chemicalWeaponSubsidy||0)+1))} per 100 truck-shipped poop each day.`;if(t.id==="preventiveMaintenance")return`Held ${n.preventiveMaintenance||0}. After pick: deterioration speed ${Ne(Math.pow(.95,(n.preventiveMaintenance||0)+1))}.`;if(t.id==="dudFilter"){let o=Math.max(0,Math.min(1,Ee.dudChancePerCard||0)),r=Math.max(0,Math.min(1,Ee.dudChanceReductionPerFilter||.05)),s=Math.max(0,n.dudFilter||0),l=Math.max(0,o-r*s),d=Math.max(0,o-r*(s+1));return`Held ${s}. DUD chance per card ${Ne(l)} -> ${Ne(d)}.`}if(t.id==="durabilityCoating")return`Held ${n.durabilityCoating||0}. After pick: maximum durability ${Ne(Math.pow(1.03,(n.durabilityCoating||0)+1))}.`;if(t.id==="sparePartsBin")return`Held ${n.sparePartsBin||0}. Immediately restores 2% durability to every maintained machine. Offer weight: ${Math.max(0,100-2*Math.max(0,n.sparePartsBin||0))}.`;if(t.id==="dudRefund")return`Held ${n.dudRefund||0}. After pick: DUD clicks award ${S(50*((n.dudRefund||0)+1))}.`;if(t.id==="freeReroll")return`Held ${n.freeReroll||0}. After pick: each card screen starts with ${(n.freeReroll||0)+1} free reroll${(n.freeReroll||0)+1===1?"":"s"}.`;if(t.id==="composter")return`Held ${n.composter||0}. After pick: SHREDDER poop grants ${S(3*((n.composter||0)+1))}.`;if(t.id==="scannerQueueSpacing")return`Held ${n.scannerQueueSpacing||0}. After pick: Manual/Auto Scanner queue spacing ${Ne(Math.pow(.85,(n.scannerQueueSpacing||0)+1))}.`;if(t.id==="flattery")return`Next Fairies tribute -50%. Held for next tribute: ${n.fairiesFlatteryNext||0}.`;if(t.id==="usedMachine")return"Enable Used Machines: future equipment costs 50%, has no SELL refund, and starts with 60% durability.";if(t.id==="newMachine")return"Cancel Used Machines. Future equipment returns to normal price, refund, and durability.";if(t.id==="laborExploitation")return"Repairman labor cost -30% permanently. One time only.";if(t.id==="rescueLoan")return`At day-end bankruptcy check, gain ${S(500)} if cash is below ${S(0)}. Held: ${n.rescueLoanCharges||0}.`;if(t.id==="loan"){let o=Math.max(1,Math.floor(Number(e.turn)||1));return`Gain ${S(300*o)} now. Starting tomorrow, pay ${S(400)} per day for ${o} days.`}return t.description}function Go(e,t){let n=e.cardDraft?.choices||[],o=n.findIndex(r=>r.id===t.id);o>=0&&n.splice(o,1)}function Yi({game:e,ui:t,onUpdatePanels:n}){function o(){n&&n()}function r(){Ie(e),e.cardTargetPick=null,e.cardDraft={pending:!0,choices:Nn(e,Pt),rerolls:0,freeRerolls:_t(e,"freeReroll"),picksRemaining:1}}function s(){Ie(e),e.cardDraft.pending=!1,e.cardDraft.choices=[],e.cardDraft.picksRemaining=0,e.cardTargetPick=null,t.modal.classList.remove("visible","equipment-popover"),o()}function l(g=Pt){Ie(e),e.cardDraft.choices=Nn(e,g)}function d(){Ie(e),!e.cardDraft.choices.length&&e.cardDraft.picksRemaining>0&&l(Pt)}function k(g){Go(e,g),e.cardDraft.picksRemaining=Math.max(0,(e.cardDraft.picksRemaining||1)-1),e.cardTargetPick=null,d(),e.cardDraft.picksRemaining<=0?s():j()}function M(g){Go(e,g),e.cardDraft.picksRemaining=Math.max(0,(e.cardDraft.picksRemaining||1)-1)+Ee.extraCardsAddedPicks,e.cardDraft.choices.push(...Nn(e,2)),j()}function D(g,_){let U=_t(e,"dudRefund")*50;if(U>0){let le=Ae(e,U);e.stats.dudRefundIncome=(e.stats.dudRefundIncome||0)+le,e.totals.dudRefundIncome=(e.totals.dudRefundIncome||0)+le,N(e,y.x+y.cols*y.cell/2,y.y-30,`DUD REFUND +${S(le)}`,f.green)}Et(e,34,.62),document.body?.animate&&document.body.animate([{transform:"translate(0, 0)"},{transform:"translate(-10px, 7px)"},{transform:"translate(12px, -8px)"},{transform:"translate(-8px, -5px)"},{transform:"translate(9px, 6px)"},{transform:"translate(0, 0)"}],{duration:260,easing:"steps(5, end)"}),_&&(_.style.setProperty("--fling-x",`${260+Math.random()*260}px`),_.style.setProperty("--fling-y",`${-260-Math.random()*170}px`),_.style.setProperty("--fling-r",`${(Math.random()<.5?-1:1)*(52+Math.random()*38)}deg`),_.classList.add("flung")),window.setTimeout(()=>{Go(e,g),d(),j()},340)}function L(g,_=null){if(g.type==="dud")return D(g,_);if(g.id==="extraCards")return M(g);if(g.type==="equipmentUpgrade"||g.type==="cellAction")return F(g);qi(e,g),k(g)}function F(g){let _=Ue(e,g);_.length&&(e.cardTargetPick={pending:!0,cardId:g.id,mode:g.target==="blockedCell"?"blockedCell":"equipment",targetKeys:_.map(Wt),remaining:g.id==="dynamite"?Math.min(3,_.length):1},t.modal.classList.remove("visible","equipment-popover"),o())}function z(g){if(!g||g.type!=="blockedCell")return!1;let _=I(g.col,g.row);if(!e.blockedCells?.has(_))return!1;e.blockedCells.delete(_);let U=$(g.col,g.row);return st(e,U.x,U.y),Xe(e,U.x,U.y,f.danger,62),it(e,U.x,U.y,18,f.warn),Rn(e,U.x,U.y,8),Et(e,16,.35),N(e,U.x,U.y-18,"BOOM",f.danger),be(e),e.cardTargetPick.remaining=Math.max(0,(e.cardTargetPick.remaining||1)-1),e.cardTargetPick.targetKeys=Ue(e,"dynamite").map(Wt),o(),!0}function oe(g){if(!e.cardTargetPick?.pending)return!1;let _=Uo(e.cardTargetPick.cardId),U=Ul(e,g);return!_||!U?(X(),!0):_.id==="dynamite"?(z(U)&&((e.cardTargetPick.remaining||0)<=0||!Ue(e,"dynamite").length)&&k(_),!0):(Hi(e,U),k(_),!0)}function X(){e.cardTargetPick?.pending&&(e.cardTargetPick=null,j())}function ae(){let g=Math.max(0,e.cardDraft?.freeRerolls||0);if(g>0){e.cardDraft.freeRerolls=g-1,e.cardDraft.rerolls+=1,l(Pt),j();return}let _=Fi(e);e.cash<_||(Ve(e,_),e.stats.cardRerollCost=(e.stats.cardRerollCost||0)+_,e.totals.cardRerollCost=(e.totals.cardRerollCost||0)+_,e.cardDraft.rerolls+=1,l(Pt),j())}function he(g,_){let U=document.createElement("button");U.type="button";let le=g.type==="dud"?"dud":g.rarity==="ultraRare"?"ultra-rare":g.rarity==="rare"?"rare":"common";U.className=`card-choice ${le}`;let me=g.type==="dud"?"MISS":g.rarity==="ultraRare"?"ULTRA RARE":g.rarity==="rare"?"RARE":"COMMON",fe=[me,...(g.tags||[]).filter(E=>E!==me)].slice(0,5);return U.innerHTML=`${g.title}
Choose ${le} card${le===1?"":"s"} before Build phase. Dud cards can be flicked away without consuming a pick. Equipment cards target machines; Dynamite targets blocked cells.
`;let me=t.modalBody.querySelector("#cardChoices");g.forEach((G,w)=>me.appendChild(he(G,w))),t.modalActions.innerHTML="";let fe=document.createElement("button");fe.type="button",fe.className="facility-action warn reroll-button",fe.textContent=U>0?`Reroll (FREE x${U})`:`Reroll ${S(_)}`,fe.disabled=U<=0&&e.cash<_,fe.title=U>0?`${U} free reroll${U===1?"":"s"} remaining.`:fe.disabled?"Not enough cash":"",fe.addEventListener("click",ae),t.modalActions.appendChild(fe);let E=document.createElement("button");E.type="button",E.className="facility-action",E.textContent="No Card",E.title="Skip this upgrade pick and enter Build phase.",E.addEventListener("click",s),t.modalActions.appendChild(E),t.modal.classList.remove("equipment-popover"),t.modal.classList.add("visible")}return{prepareDraft:r,showDraft:j,finishDraft:s,chooseTargetAtPoint:oe,cancelTargetPick:X}}var _l=!1,Kl={chickMale:"./assets/images/chick_male.png",chickFemale:"./assets/images/chick_female.png",poop:new URL("../../assets/images/poop.png",import.meta.url).href,conveyor:"./assets/images/conveyor.png",scannerManual:"./assets/images/scanner_manual.png",scannerAuto:"./assets/images/scanner_auto.png",eggFarm:"./assets/images/egg_farm.png",mixer:"./assets/images/mixer.png",shredder:"./assets/images/shredder.png",truck:"./assets/images/truck.png"},He={};for(let[e,t]of Object.entries(Kl)){let n=new Image;n.loaded=!1,n.onerror=()=>{n.loaded=!1},(_l||e==="poop")&&t&&(n.onload=()=>{n.loaded=!0},n.src=t),He[e]=n}function Xi(e,t,n,o){e.clearRect(0,0,t.width,t.height),Yl(e,t),e.save();let r=n.shake.time>0?W(-n.shake.strength,n.shake.strength):0,s=n.shake.time>0?W(-n.shake.strength,n.shake.strength):0,l=n.view?.scale||1;e.translate((n.view?.x||0)+r,(n.view?.y||0)+s),e.scale(l,l),Vl(e,n),Xl(e,n),Ql(e,n),sa(e,n),pa(e,n),la(e,n),ca(e,n),ql(e,n),ba(e,n,o.activeQueuedChick),ga(e,n),Ca(e,t,n),ka(e,n,o.selectedObject,o.selectedTitle),Sa(e,n),Ma(e,n),Ta(e,n),e.restore(),Ea(e,n,t)}function Hl(e){if(e.type==="eggFarm"){let n=$(e.ref.col,e.ref.row);return{x:n.x-34,y:n.y-34,w:68,h:68,cx:n.x,cy:n.y}}let t=e.ref;return{x:t.x,y:t.y,w:t.w,h:t.h,cx:t.x+t.w/2,cy:t.y+t.h/2}}function ql(e,t){if(t.phase!=="build")return;let n=gn(t);for(let o of n){let r=Hl(o);e.save(),e.fillStyle="rgba(196,36,36,.22)",e.strokeStyle=f.danger,e.lineWidth=5,e.setLineDash([10,6]),ee(e,r.x,r.y,r.w,r.h,!0,!0),e.setLineDash([]),e.fillStyle=f.danger,e.strokeStyle=f.white,e.lineWidth=4,e.font="900 16px ui-monospace, monospace",e.textAlign="center",e.strokeText("!",r.cx,r.y+24),e.fillText("!",r.cx,r.y+24),e.font="900 11px ui-monospace, monospace",e.strokeText("NO ROUTE",r.cx,r.y+r.h-8),e.fillText("NO ROUTE",r.cx,r.y+r.h-8),e.restore()}}function ee(e,t,n,o,r,s=!0,l=!0){e.beginPath(),e.rect(t,n,o,r),s&&e.fill(),l&&e.stroke()}function Ho(e,t,n,o,r=f.ink){e.save(),e.font="900 12px ui-monospace, monospace",e.textAlign="center",e.lineWidth=4,e.strokeStyle=f.white,e.fillStyle=r,e.strokeText(o,t,n),e.fillText(o,t,n),e.restore()}function Rt(e,t,n,o,r,s){return t?.loaded?(e.drawImage(t,n,o,r,s),!0):!1}function Yl(e,t){e.fillStyle=f.bg,e.fillRect(0,0,t.width,t.height),e.save(),e.strokeStyle="rgba(16, 32, 21, 0.035)",e.lineWidth=1;for(let n=0;n=n;for(let r of mt(t)){let s=bt(r);e.save(),e.fillStyle=o?"rgba(183,245,198,.34)":"rgba(255,255,255,.22)",e.strokeStyle=o?f.green:f.muted,e.lineWidth=5,e.setLineDash([16,10]),ee(e,s.x,s.y,s.w,s.h,!0,!0),e.setLineDash([]);let l=so(r),d=l.cx,k=l.cy;e.fillStyle="rgba(255,255,255,.94)",e.strokeStyle=f.ink,e.lineWidth=4,ee(e,l.x,l.y,l.w,l.h,!0,!0),e.fillStyle=o?f.green:f.danger,e.font="900 16px ui-monospace, monospace",e.textAlign="center",e.fillText(r.direction==="right"?"BUY RIGHT LOT":"BUY UPPER LOT",d,k-12),e.fillStyle=f.ink,e.font="900 16px ui-monospace, monospace",e.fillText(`${S(n)} / 10\xD710`,d,k+15),e.fillStyle=f.muted,e.font="900 11px ui-monospace, monospace",e.fillText("blocked tiles included",d,k+30),e.restore()}}function Je(e,t,n,o,r,s,l=0){let d=Ut(s);d<.5||(e.save(),e.globalAlpha=Math.min(.62,.12+d*.54),e.fillStyle="#6b4a23",l>0?(e.beginPath(),e.roundRect?.(t,n,o,r,l),e.roundRect?e.fill():ee(e,t,n,o,r,!0,!1)):ee(e,t,n,o,r,!0,!1),e.globalAlpha=Math.min(.9,.25+d*.6),e.strokeStyle="#3a2a16",e.lineWidth=Math.max(2,Math.floor(2+d*5)),e.setLineDash([5,6]),ee(e,t+3,n+3,o-6,r-6,!1,!0),e.restore())}function Ko(e,t){let n=e.componentLookup?.get(t);return(n?e.congestion.get(n):null)?.ratio||0}function Ql(e,t){let n=[],o=new Set;for(let s of t.conveyorTiles){let{col:l,row:d}=J(s);for(let k of pe){let M={col:l+k.dc,row:d+k.dr},D=I(M.col,M.row);if(!t.conveyorTiles.has(D))continue;let L=[s,D].sort().join("|");if(o.has(L))continue;o.add(L);let F=Math.max(Ko(t,s),Ko(t,D));n.push({a:$(l,d),b:$(M.col,M.row),ratio:F})}}e.save(),e.lineCap="round",e.lineJoin="round";for(let s of[{width:33,color:f.ink,alpha:1},{width:25,color:f.white,alpha:1},{width:17,color:f.greenSoft,alpha:1}]){e.globalAlpha=s.alpha,e.strokeStyle=s.color,e.lineWidth=s.width;for(let l of n)e.beginPath(),e.moveTo(l.a.x,l.a.y),e.lineTo(l.b.x,l.b.y),e.stroke()}for(let s of n){let l=Math.max(0,(s.ratio-.5)/.5);e.strokeStyle=ro(f.green,f.danger,l),e.globalAlpha=s.ratio>.5?.35+l*.55:.8,e.lineWidth=6,e.beginPath(),e.moveTo(s.a.x,s.a.y),e.lineTo(s.b.x,s.b.y),e.stroke()}let r=oa(t);for(let s of t.conveyorTiles){let l=$(...Object.values(J(s))),d=t.conveyorMeta.get(s)||{},k=Ko(t,s),M=d.kind==="boostConveyor"?"#fff2b8":f.white;e.fillStyle=k>.5?ro(M,"#ffd6d6",Math.max(0,(k-.5)/.5)):M,e.strokeStyle=f.ink,e.lineWidth=2,ee(e,l.x-8,l.y-8,16,16,!0,!0),d.kind==="boostConveyor"&&(e.save(),e.strokeStyle=f.warn,e.lineWidth=3,e.beginPath(),e.moveTo(l.x-15,l.y+13),e.lineTo(l.x-3,l.y-13),e.lineTo(l.x+2,l.y-2),e.lineTo(l.x+15,l.y-13),e.stroke(),e.restore()),Je(e,l.x-14,l.y-14,28,28,{meta:d}),We(e,t,"conveyor",s,l.x,l.y,38,38),ra(e,l,r.get(s)||[]),ta(e,l,d,branchSelectable(t,s,jl(t,s)),jl(t,s)),k>.5&&Ho(e,l.x,l.y-15,`${Math.floor(k*100)}%`,f.danger)}e.restore()}function Jl(e){return{random:"RND",pass:"PASS",up:"UP",right:"RT",down:"DN",left:"LF"}[e||"random"]||"RND"}function Zl(e,t,n){let o=J(t),r=pe.filter(d=>e.conveyorTiles.has(I(o.col+d.dc,o.row+d.dr))).map(d=>d.name),s=[...new Set([...Array.isArray(n.outDirs)?n.outDirs:[],n.dir].filter(Boolean))].filter(d=>r.includes(d)),l=s.length?s:r;if(r.length<3)return l;let k=new Set(r.filter(M=>{let D=pe.find(L=>L.name===M);if(!D)return!1;let L=e.conveyorMeta?.get?.(I(o.col+D.dc,o.row+D.dr));if(!L)return!1;let F=[...new Set([...Array.isArray(L.outDirs)?L.outDirs:[],L.dir].filter(Boolean))];return F.includes(D.opposite)}));if(n.branchMode&&n.branchMode!=="random"&&r.includes(n.branchMode)){let M=new Set(k);M.add(n.branchMode),r.filter(D=>!M.has(D)).length>=2&&k.add(n.branchMode)}let M=r.filter(D=>!k.has(D));if(M.length)return M;let D=l.filter(L=>!k.has(L));return D.length?D:l}function jl(e,t){let n=J(t);return pe.filter(o=>e.conveyorTiles.has(I(n.col+o.dc,n.row+o.dr))).map(o=>o.name)}function branchSelectable(e,t,n=jl(e,t)){if(n.length<3)return[];let o=J(t),r=new Set(n.filter(s=>{let l=pe.find(d=>d.name===s);if(!l)return!1;let d=e.conveyorMeta?.get?.(I(o.col+l.dc,o.row+l.dr));if(!d)return!1;let k=[...new Set([...Array.isArray(d.outDirs)?d.outDirs:[],d.dir].filter(Boolean))];return k.includes(l.opposite)}));return n.filter(s=>{let l=new Set(r);return l.add(s),n.filter(d=>!l.has(d)).length>=2})}function ea(e,t,n){let o=J(t),r=pe.filter(d=>e.conveyorTiles.has(I(o.col+d.dc,o.row+d.dr))).map(d=>d.name),s=[...new Set([...Array.isArray(n.outDirs)?n.outDirs:[],n.dir].filter(Boolean))].filter(d=>r.includes(d)),l=r;return s.length?s:l}function ta(e,t,n,o,r=o){if(r.length<3||o.length<2)return;e.save();let s=o.includes(n.branchMode)?n.branchMode:"random",l=s!=="random";e.lineJoin="round",e.lineCap="round",e.lineWidth=2,e.fillStyle="rgba(255,255,255,.9)",e.strokeStyle=l?f.warn:f.green,ee(e,t.x-17,t.y-17,34,34,!0,!0),e.strokeStyle=f.ink,e.lineWidth=2,e.fillStyle=f.ink,s!=="random"?(l=pe.find(d=>d.name===s),ia(e,t.x,t.y,l?.angle||0,9,6)):(e.beginPath(),e.moveTo(t.x-10,t.y),e.lineTo(t.x-2,t.y),e.lineTo(t.x+8,t.y-8),e.moveTo(t.x-2,t.y),e.lineTo(t.x+8,t.y+8),e.stroke(),ia(e,t.x+9,t.y-9,-Math.PI/4,4,3),ia(e,t.x+9,t.y+9,Math.PI/4,4,3)),e.restore()}function na(e,t,n){if(!n)return[];return Zl(e,t,n).map(o=>pe.find(r=>r.name===o)).filter(Boolean)}function oa(e){let t=new Map;for(let[n,o]of e.conveyorMeta||[]){let r=na(e,n,o);r.length&&t.set(n,r)}return t}function ra(e,t,n){let o=n.slice(0,4);o.length&&(e.save(),e.fillStyle=f.ink,e.globalAlpha=.86,o.forEach(r=>{ia(e,t.x+r.dc*12,t.y+r.dr*12,r.angle,6,5)}),e.restore())}function ia(e,t,n,o,r=11,s=8){e.save(),e.translate(t,n),e.rotate(o),e.beginPath(),e.moveTo(r,0),e.lineTo(-r*.72,-s),e.lineTo(-r*.72,s),e.closePath(),e.fill(),e.restore()}function sa(e,t){e.save(),e.lineWidth=2,e.font="900 12px ui-monospace, monospace",e.textAlign="center";for(let n of t.scanners){let o=ho(n),r=[{type:"inputA",p:Me(n,"inputA"),label:"IN",color:f.green},{type:"left",p:Me(n,"left"),label:bo(o.left),color:wo(o.left)},{type:"right",p:Me(n,"right"),label:bo(o.right),color:wo(o.right)}];for(let s of r){if(!s.p)continue;let l=$(s.p.col,s.p.row),d=Ir(t,n,s.type||(s.label==="IN"?"inputA":null))||t.conveyorTiles.has(I(s.p.col,s.p.row));e.fillStyle=d?s.color:"#f4c2c2",e.strokeStyle=f.ink,ee(e,l.x-18,l.y-12,36,24,!0,!0),e.fillStyle=d&&s.color===f.white?f.ink:f.white,e.fillText(s.label,l.x,l.y+4)}}e.restore()}function la(e,t){for(let n of t.eggFarms)aa(e,n,t)}function aa(e,t,n){let o=$(t.col,t.row);if(e.save(),Rt(e,He.eggFarm,o.x-29,o.y-29,58,58)){Je(e,o.x-29,o.y-29,58,58,t);let l=1+Math.max(0,Number(t.extraEggOutlet)||0);e.fillStyle="rgba(255,255,255,.92)",e.strokeStyle=f.ink,e.lineWidth=2,ee(e,o.x+9,o.y+12,30,18,!0,!0),e.fillStyle=f.ink,e.font="900 10px ui-monospace, monospace",e.textAlign="center",e.fillText(`O${l}`,o.x+24,o.y+24),We(e,n,"eggFarm",t.id,o.x,o.y,68,68),e.restore();return}e.fillStyle=f.white,e.strokeStyle=f.ink,e.lineWidth=4,ee(e,o.x-28,o.y-28,56,56,!0,!0),e.fillStyle=f.green,e.font="900 19px ui-monospace, monospace",e.textAlign="center",e.fillText("EGG",o.x,o.y-4);let r=1+Math.max(0,Number(t.extraEggOutlet)||0);e.font="900 11px ui-monospace, monospace",e.fillStyle=f.ink,e.fillText(`L${t.level} O${r}`,o.x,o.y+13),e.fillText(`${t.nextSpawn.toFixed(1)}s`,o.x,o.y+26);let s=Math.max(0,Math.min(1,t.shutterProgress||0));if(s>0){let l=56*s;e.fillStyle=f.ink,ee(e,o.x-28,o.y-28,56,l,!0,!1),e.strokeStyle=f.white,e.lineWidth=2;for(let d=o.y-24;d=1&&(e.fillStyle=f.white,e.font="900 12px ui-monospace, monospace",e.fillText("SHUT",o.x,o.y+4))}Je(e,o.x-28,o.y-28,56,56,t),We(e,n,"eggFarm",t.id,o.x,o.y,68,68),e.restore()}function ca(e,t){for(let n of t.scanners)ua(e,n,t)}function ua(e,t,n){let o=de(t);if(e.save(),t.kind==="manual"&&(n.manualCombo?.count||0)>=10){let k=n.manualCombo.count;e.save(),e.globalAlpha=Math.min(.55,.16+k/120),e.strokeStyle=k>=30?f.warn:f.green,e.lineWidth=Math.min(14,5+Math.floor(k/10)),e.shadowColor=e.strokeStyle,e.shadowBlur=Math.min(28,8+k),ee(e,o.x-54,o.y-76,108,152,!1,!0),e.restore()}let r=t.kind==="auto"?He.scannerAuto:He.scannerManual;if(Rt(e,r,o.x-50,o.y-73,100,146)){t.kind==="auto"?Je(e,o.x-50,o.y-73,100,146,t):zi(e,t,o),We(e,n,"scanner",t.id,o.x,o.y,108,154),e.restore();return}e.fillStyle=t.kind==="auto"?"#d8ffe2":f.white,e.strokeStyle=f.ink,e.lineWidth=4,ee(e,o.x-50,o.y-73,100,146,!0,!0),e.fillStyle=t.kind==="auto"?f.green:f.ink,e.font="900 19px ui-monospace, monospace",e.textAlign="center",e.fillText(`${t.kind==="auto"?"AUTO":`S${(t.slot??0)+1}`}`,o.x,o.y-48),e.font="900 11px ui-monospace, monospace";let s=t.keys?.left?.label||(t.slot===0?"A":"Left"),l=t.keys?.right?.label||(t.slot===0?"D":"Right");e.fillText(t.role===0?`${s}:M ${l}:NEXT`:`${s}:WASTE ${l}:TRUCK`,o.x,o.y-28);let d=t.queue.length;t.kind==="manual"?(zi(e,t,o),e.fillStyle=d>0?f.green:f.muted,e.font="900 10px ui-monospace, monospace",e.fillText(`Q:${d}`,o.x,o.y+54)):(e.fillStyle=d>0?f.green:f.muted,e.font="900 12px ui-monospace, monospace",e.fillText(`Q:${d} CD:${t.cooldown.toFixed(1)}`,o.x,o.y+54),Je(e,o.x-50,o.y-73,100,146,t)),We(e,n,"scanner",t.id,o.x,o.y,108,154),e.restore()}function zi(e,t,n){if(t.kind!=="manual")return;let r=(t.slot??0)===0?[{side:"left",text:"A"},{side:"right",text:"D"}]:[{side:"left",text:"\u2190"},{side:"right",text:"\u2192"}];r[0].text=t.keys?.left?.label||r[0].text,r[1].text=t.keys?.right?.label||r[1].text;let s=t.keyPressTime>0?t.keyPressSide:null,l=n.x-30,d=n.y+18;e.save(),e.lineWidth=3,e.fillStyle="#f7fff5",e.strokeStyle=f.ink,ee(e,l-4,d-4,68,25,!0,!0),e.font="900 19px ui-monospace, monospace",e.textAlign="center";for(let k=0;k.8,s=t.y+Math.sin(t.bob)*(r?5:1.5);if(e.save(),n&&(e.strokeStyle=f.green,e.lineWidth=5,e.beginPath(),e.arc(t.x,s,t.radius+8,0,Math.PI*2),e.stroke()),r&&(e.strokeStyle=f.danger,e.lineWidth=3,e.beginPath(),e.arc(t.x,s,t.radius+12+Math.sin(t.bob*2)*4,0,Math.PI*2),e.stroke()),t.sex==="poop")Vo(e,t.x,s,t.radius);else{let l=t.sex==="male"?He.chickMale:He.chickFemale;Rt(e,l,t.x-t.radius,s-t.radius,t.radius*2,t.radius*2)||(e.fillStyle=t.sex==="male"?f.male:f.female,e.strokeStyle=f.ink,e.lineWidth=5,e.beginPath(),e.arc(t.x,s,t.radius,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle=f.ink,e.beginPath(),e.arc(t.x-6,s-5,2.5,0,Math.PI*2),e.arc(t.x+6,s-5,2.5,0,Math.PI*2),e.fill(),e.fillStyle="#ffaa2e",e.beginPath(),e.moveTo(t.x,s+2),e.lineTo(t.x+9,s+6),e.lineTo(t.x,s+10),e.closePath(),e.fill())}e.restore()}function va(e,t){let n=null,o=1/0;for(let[r,s]of e.componentLookup.entries()){let l=J(r),d=$(l.col,l.row),k=Math.hypot(t.x-d.x,t.y-d.y);kVi(o.type,o.id)===Vi(t,n))}function We(e,t,n,o,r,s,l,d){xa(t,n,o)&&(e.save(),e.fillStyle="rgba(34,185,79,.18)",e.strokeStyle=f.green,e.lineWidth=(t.multiSelected||[]).length>1?6:4,e.setLineDash((t.multiSelected||[]).length>1?[]:[8,5]),ee(e,r-l/2,s-d/2,l,d,!0,!0),e.restore())}function ka(e,t,n,o){if(t.phase==="build"&&(t.multiSelected||[]).length>1){e.save(),e.fillStyle="rgba(255,255,255,.96)",e.strokeStyle=f.ink,e.lineWidth=3,ee(e,54-t.view.x,66-t.view.y,214,42,!0,!0),e.fillStyle=f.ink,e.font="900 11px ui-monospace, monospace",e.fillText(`${t.multiSelected.length} ITEMS SELECTED`,65-t.view.x,83-t.view.y),e.fillStyle=f.muted,e.font="900 11px ui-monospace, monospace",e.fillText("drag any selected item to move group",65-t.view.x,99-t.view.y),e.restore();return}}function Ca(e,t,n){if(!n.cardTargetPick?.pending)return;let o=_o(n);e.save(),e.fillStyle="rgba(0,0,0,.66)",e.beginPath();let r=n.view?.scale||1;e.rect(-(n.view?.x||0)/r,-(n.view?.y||0)/r,t.width/r,t.height/r);for(let k of o){let M=k.bounds,D=8;e.rect(M.x-D,M.y-D,M.w+D*2,M.h+D*2)}e.fill("evenodd");let s=n.cardTargetPick?.mode==="blockedCell";if(!o.length){e.fillStyle="rgba(255,255,255,.95)",e.strokeStyle=f.ink,e.lineWidth=3,ee(e,(260-(n.view?.x||0))/r,(96-(n.view?.y||0))/r,420/r,42/r,!0,!0),e.fillStyle=f.danger,e.font="900 12px ui-monospace, monospace",e.textAlign="center",e.fillText(s?"NO BLOCKED CELL. PRESS ESC.":"NO VALID UPGRADE TARGET. PRESS ESC.",(470-(n.view?.x||0))/r,(122-(n.view?.y||0))/r),e.restore();return}e.fillStyle="rgba(255,255,255,.95)",e.strokeStyle=f.ink,e.lineWidth=3;let l=Math.max(1,n.cardTargetPick?.remaining||1),d=n.cardTargetPick?.mode==="autoScannerMenu"?"AUTO SCANNER ROUTE SETTINGS. CLICK EMPTY AREA TO CLOSE.":s?`CLICK BLOCKED CELL: ${l} LEFT. PRESS ESC TO CANCEL.`:"CLICK AN UPGRADEABLE MACHINE. PRESS ESC TO CANCEL.";ee(e,(216-(n.view?.x||0))/r,(96-(n.view?.y||0))/r,560/r,42/r,!0,!0),e.fillStyle=f.ink,e.font="900 12px ui-monospace, monospace",e.textAlign="center",e.fillText(d,(496-(n.view?.x||0))/r,(122-(n.view?.y||0))/r),e.restore()}function Sa(e,t){if(t.phase!=="build"||!t.selectionBox)return;let n=t.selectionBox,o=Math.min(n.x1,n.x2),r=Math.min(n.y1,n.y2),s=Math.abs(n.x2-n.x1),l=Math.abs(n.y2-n.y1);e.save(),e.fillStyle="rgba(34,185,79,.12)",e.strokeStyle=f.green,e.lineWidth=2,e.setLineDash([7,4]),ee(e,o,r,s,l,!0,!0),e.restore()}function Ma(e,t){let n=[...t.effects].sort((o,r)=>(o.priority??Se.ambient)-(r.priority??Se.ambient));for(let o of n){let r=Math.max(0,o.life/o.maxLife);e.save(),e.globalAlpha=r,o.type==="meat"?(e.fillStyle=f.green,ee(e,o.x-o.size/2,o.y-o.size/2,o.size*1.5,o.size,!0,!1)):o.type==="sludge"?(e.fillStyle=f.poop,ee(e,o.x-o.size/2,o.y-o.size/2,o.size*1.4,o.size,!0,!1)):o.type==="spawn"?(e.strokeStyle=f.green,e.lineWidth=3,e.beginPath(),e.arc(o.x,o.y,o.size+(1-r)*20,0,Math.PI*2),e.stroke()):o.type==="spark"?(e.fillStyle=o.color||f.danger,ee(e,o.x-o.size/2,o.y-o.size/2,o.size,o.size,!0,!1)):o.type==="smoke"?(e.fillStyle="rgba(16,32,21,.24)",e.beginPath(),e.arc(o.x,o.y,o.size*(1.2-r*.2),0,Math.PI*2),e.fill()):o.type==="shockwave"?(e.strokeStyle=o.color||f.danger,e.lineWidth=4,e.beginPath(),e.arc(o.x,o.y,o.size+(1-r)*(o.maxSize||44),0,Math.PI*2),e.stroke()):o.type==="scannerPulse"?(e.strokeStyle=o.color||f.green,e.lineWidth=5,e.setLineDash([8,6]),e.beginPath(),e.arc(o.x,o.y,o.size+(1-r)*38,0,Math.PI*2),e.stroke()):o.type==="shred"?(e.fillStyle=o.color||f.ink,e.save(),e.translate(o.x,o.y),e.rotate(o.rot||0),ee(e,-o.w/2,-o.h/2,o.w,o.h,!0,!1),e.restore()):o.type==="load"?(e.strokeStyle=o.color||f.green,e.lineWidth=3,e.beginPath(),e.moveTo(o.x-14,o.y),e.lineTo(o.x+14,o.y),e.moveTo(o.x,o.y-14),e.lineTo(o.x,o.y+14),e.stroke()):o.type==="erase"?(e.strokeStyle=f.ink,e.lineWidth=3,e.setLineDash([4,4]),ee(e,o.x-o.size/2,o.y-o.size/2,o.size,o.size,!1,!0)):o.type==="rage"?(e.fillStyle=o.color||f.danger,e.font="900 16px ui-monospace, monospace",e.textAlign="center",e.fillText("!",o.x,o.y)):o.type==="flyingChick"&&(o.sex==="poop"?Vo(e,o.x,o.y,o.radius||11):Xo(e,o.x,o.y,o.sex,o.sex==="male")),e.restore()}}function Ta(e,t){e.save(),e.font="900 19px ui-monospace, monospace",e.textAlign="center";for(let n of t.floatingTexts){let o=Math.max(0,n.life/n.maxLife);e.globalAlpha=o,e.lineWidth=5,e.strokeStyle=f.white,e.fillStyle=n.color,e.strokeText(n.text,n.x,n.y),e.fillText(n.text,n.x,n.y)}e.restore()}function ga(e,t){let n=t.repairman;if(!(!!n?.active||t.phase==="build"&&!!n?.hiredForNextDay))return;e.save(),e.lineWidth=3,e.fillStyle="#fff0d1",e.strokeStyle=f.ink,e.beginPath(),e.arc(n.x,n.y,17,0,Math.PI*2),e.fill(),e.stroke(),e.fillStyle="#ffd6e7",e.beginPath(),e.arc(n.x-6,n.y-2,3.2,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(n.x+6,n.y-2,3.2,0,Math.PI*2),e.fill();let r=!!t.cardEffects?.laborExploitation;e.fillStyle=r?f.danger:f.ink,e.beginPath(),e.arc(n.x-5,n.y-5,r?2.8:2.2,0,Math.PI*2),e.fill(),e.beginPath(),e.arc(n.x+5,n.y-5,r?2.8:2.2,0,Math.PI*2),e.fill(),e.strokeStyle=f.ink,e.lineWidth=r?3:2,e.beginPath(),e.arc(n.x,n.y+(r?0:1),r?8:7,.1*Math.PI,.9*Math.PI),e.stroke(),e.fillStyle=f.green,ee(e,n.x-9,n.y+14,18,8,!0,!0),e.strokeStyle=f.ink,e.lineWidth=3,e.beginPath(),e.moveTo(n.x-11,n.y+18),e.lineTo(n.x-20,n.y+24),e.stroke(),e.beginPath(),e.moveTo(n.x+11,n.y+18),e.lineTo(n.x+20,n.y+24),e.stroke(),e.fillStyle=f.ink,e.font="900 11px ui-monospace, monospace",e.textAlign="center",e.fillText(n.active?"FIX":"HIRED",n.x,n.y+33),n.target?.label?Ho(e,n.x,n.y-24,n.target.label,f.green):!n.active&&n.hiredForNextDay&&Ho(e,n.x,n.y-24,"NEXT DAY",f.green),e.restore()}function Ea(e,t,n){e.save(),e.font="900 19px ui-monospace, monospace",e.textAlign="left",e.fillStyle=f.ink,e.fillStyle="rgba(255,255,255,.92)",e.strokeStyle=f.ink,e.lineWidth=3,ee(e,n.width-284,18,260,34,!0,!0),e.fillStyle=f.green,e.font="900 12px ui-monospace, monospace",e.fillText(yn,n.width-270,40),e.font="900 19px ui-monospace, monospace",e.fillStyle=f.ink;let o=[];t.phase==="running"&&o.push(t.timeLeft<=0?"TIME UP: FARMS SHUT. CLEAR LINE.":"A/D: S1 \u2190/\u2192: S2"),t.phase==="build"&&o.push(`BUILD: ${t.buildTool||"SELECT"} | connect 1 EGG route to any exit`);let r=76;for(let s of o)e.strokeStyle=f.white,e.lineWidth=4,e.strokeText(s,24,r),e.fillText(s,24,r),r+=20;e.restore()}var ji=[[{key:"a",code:"KeyA",label:"A"},{key:"d",code:"KeyD",label:"D"}],[{key:"arrowleft",code:"ArrowLeft",label:"Left"},{key:"arrowright",code:"ArrowRight",label:"Right"}],[{key:"j",code:"KeyJ",label:"J"},{key:"l",code:"KeyL",label:"L"}],[{key:"f",code:"KeyF",label:"F"},{key:"h",code:"KeyH",label:"H"}],[{key:"q",code:"KeyQ",label:"Q"},{key:"e",code:"KeyE",label:"E"}],[{key:"z",code:"KeyZ",label:"Z"},{key:"x",code:"KeyX",label:"X"}],[{key:"u",code:"KeyU",label:"U"},{key:"o",code:"KeyO",label:"O"}],[{key:"n",code:"KeyN",label:"N"},{key:"m",code:"KeyM",label:"M"}]];function Pa(e){let t=ji[e]||ji[0];return{left:{...t[0]},right:{...t[1]}}}function es(e,t,n){let o={type:"eggFarm",id:e.nextId++,col:t,row:n,level:1,nextSpawn:2,lastInterval:2,extraEggOutlet:0,price:pt.eggFarm,builtSession:e.buildSession};return o.nextSpawn=wt(o),o.lastInterval=o.nextSpawn,o}function ts(e,t,n,o){let r=o==="auto"?we.autoScanner.price:we.manualScanner.price,s=new Set(e.scanners.filter(d=>d.kind==="manual").map(d=>d.slot)),l=0;for(;s.has(l);)l+=1;return{type:"scanner",id:e.nextId++,kind:o,slot:o==="manual"?l:null,role:o==="manual"?l%2:0,col:t,row:n,level:1,queue:[],cooldown:0,price:r,builtSession:e.buildSession,autoMode:"standard",keys:o==="manual"?Pa(l):null}}function Un(e){let t=(e.x-y.x)/y.cell,n=(e.y-y.y)/y.cell,o=Math.max(0,Math.min(y.cols-1,Math.round(t-.5))),r=Math.max(0,Math.min(y.rows-1,Math.round(n-.5))),s=Math.abs(e.x-y.x),l=Math.abs(e.x-(y.x+y.cols*y.cell)),d=Math.abs(e.y-y.y),k=Math.abs(e.y-(y.y+y.rows*y.cell)),M=[["left",s],["right",l],["top",d],["bottom",k]].sort((D,L)=>D[1]-L[1])[0][0];return M==="left"?{side:M,entry:{col:0,row:r}}:M==="right"?{side:M,entry:{col:y.cols-1,row:r}}:M==="top"?{side:M,entry:{col:o,row:0}}:{side:M,entry:{col:o,row:y.rows-1}}}function Wn(e,t,n){let o={x:y.x+t.col*y.cell+y.cell/2,y:y.y+t.row*y.cell+y.cell/2},r={left:y.x,right:y.x+y.cols*y.cell,top:y.y,bottom:y.y+y.rows*y.cell};return e.entry={...t},e.side=n,n==="left"?(e.x=r.left-e.w-18,e.y=o.y-e.h/2):n==="right"?(e.x=r.right+18,e.y=o.y-e.h/2):n==="top"?(e.x=o.x-e.w/2,e.y=r.top-e.h-18):(e.x=o.x-e.w/2,e.y=r.bottom+18),e}function ns(e,t,n,o){let{entry:r,side:s}=Un(n),l=we[t],d=l?{name:l.name,w:l.body?.w||168,h:l.body?.h||110,price:l.price}:{name:t[0].toUpperCase()+t.slice(1),w:168,h:110,price:o},k={type:"facility",id:t,name:d.name,x:0,y:0,w:d.w,h:d.h,level:1,price:o||d.price,builtSession:e.buildSession};return Wn(k,r,s)}function Ra(e){return Math.random()({x:s.x,y:s.y})),r=o[0];return{id:e.nextId++,sex:n,x:r.x,y:r.y,route:o,targetIndex:o.length>1?1:o.length,stage:t.stage||"belt",scannerId:t.scannerId??null,nextScannerId:null,pendingScannerId:null,radius:n==="poop"?15:17,bob:Math.random()*Math.PI*2,queueIndex:-1,queueRoute:null}}function rs({game:e,canvasPoint:t,updatePanels:n,equipmentAtPoint:o,fail:r,pointInGrid:s,rectOfFacility:l,rectsOverlap:d}){function k(w){return w?w.type==="conveyor"?`conveyor:${w.id||w.oldKey}`:w.type==="facility"?`facility:${w.id||w.ref?.id}`:`${w.type}:${w.id||w.ref?.id}`:""}function M(w){return w?w.type==="conveyor"?{type:"conveyor",id:w.oldKey}:{type:w.type,id:w.ref.id}:null}function D(w){let C=k(M(w));return(e.multiSelected||[]).some(O=>k(O)===C)}function L(w){return w?w.type==="eggFarm"?e.eggFarms.find(C=>C.id===w.id)||null:w.type==="scanner"?e.scanners.find(C=>C.id===w.id)||null:w.type==="facility"?e.facilities[w.id]||null:w.type==="conveyor"&&e.conveyorTiles.has(w.id)?{type:"conveyor",id:w.id}:null:null}function F(){let w=[];for(let C of e.conveyorTiles){let O=J(C),Y=$(O.col,O.row);w.push({type:"conveyor",id:C,center:Y,cell:O})}for(let C of e.eggFarms)w.push({type:"eggFarm",id:C.id,ref:C,center:$(C.col,C.row),cell:{col:C.col,row:C.row}});for(let C of e.scanners)w.push({type:"scanner",id:C.id,ref:C,center:de(C),cell:{col:C.col,row:C.row}});for(let C of Object.values(e.facilities)){let O={x:C.x+C.w/2,y:C.y+C.h/2},Y=C.entry?$(C.entry.col,C.entry.row):O;w.push({type:"facility",id:C.id,ref:C,center:O,portCenter:Y})}return w}function z(w,C){let O=Math.min(C.x1,C.x2),Y=Math.max(C.x1,C.x2),te=Math.min(C.y1,C.y2),se=Math.max(C.y1,C.y2);return w.x>=O&&w.x<=Y&&w.y>=te&&w.y<=se}function oe(w){let C=[];for(let O of F())(z(O.center,w)||O.portCenter&&z(O.portCenter,w))&&C.push({type:O.type,id:O.id});return e.multiSelected=C,e.selected=C[0]||null,n(),C.length}function X(){e.multiSelected=[],e.selected=null,n()}function ae(w){let C=t(w);return e.selectionBox={x1:C.x,y1:C.y,x2:C.x,y2:C.y},e.multiSelected=[],e.selected=null,n(),!0}function he(w){if(!e.selectionBox)return;let C=t(w);e.selectionBox.x2=C.x,e.selectionBox.y2=C.y}function j(){if(!e.selectionBox)return 0;let w=e.selectionBox,C=Math.abs(w.x2-w.x1),O=Math.abs(w.y2-w.y1);return e.selectionBox=null,C<6&&O<6?(X(),0):oe(w)}function g(w){let C=M(w);return C?(e.multiSelected||[]).length&&D(w)?[...e.multiSelected]:[C]:[]}function _(w){let C=L(w);if(!C)return null;if(w.type==="conveyor"){let O=J(w.id);return{...w,obj:C,oldKey:w.id,currentKey:w.id,meta:e.conveyorMeta.get(w.id)||{price:Be("conveyor"),builtSession:null},col:O.col,row:O.row}}return w.type==="eggFarm"||w.type==="scanner"?{...w,obj:C,col:C.col,row:C.row}:w.type==="facility"?{...w,obj:C,x:C.x,y:C.y,w:C.w,h:C.h,entry:C.entry?{...C.entry}:null,side:C.side,center:{x:C.x+C.w/2,y:C.y+C.h/2}}:null}function U(w){let C=t(w),O=o(C);if(!O)return!1;let Y=g(O),te=Y.map(_).filter(Boolean);return te.length?(e.groupDrag={start:C,selections:Y,origins:te,historySnapshot:rn(e),committed:!1,lastDCol:0,lastDRow:0},e.multiSelected=Y,e.selected=Y[0]||null,n(),!0):!1}function le(){!e.groupDrag||e.groupDrag.committed||(e.undoStack.push(e.groupDrag.historySnapshot),e.redoStack=[],e.groupDrag.committed=!0)}function me(w,C,O){let Y=I(w,C),te=kt(e,w,C);if(te&&!O.has(`eggFarm:${te.id}`))return!0;let se=Ct(e,w,C);return!!(se&&!O.has(`scanner:${se.id}`)||e.conveyorTiles.has(Y)&&!O.has(`conveyor:${Y}`))}function fe(w,C,O){let Y=[];for(let te of e.groupDrag.origins){if(te.type!=="facility")continue;let se={x:te.center.x+w,y:te.center.y+C},{entry:ve,side:ce}=Un(se);if(!s(ve.col,ve.row)||e.blockedCells?.has?.(I(ve.col,ve.row)))return!0;let je={...te.obj,entry:{...ve},side:ce};Wn(je,ve,ce),Y.push({id:te.id,rect:l(je)})}for(let te of Y)for(let se of Object.values(e.facilities))if(!O.has(`facility:${se.id}`)&&d(te.rect,l(se),12))return!0;for(let te=0;teQ.type==="conveyor");for(let Q of je){let xe=Q.currentKey||Q.oldKey;e.conveyorTiles.delete(xe),e.conveyorMeta.delete(xe)}for(let Q of je){let xe=I(Q.col+te,Q.row+se);e.conveyorTiles.add(xe),e.conveyorMeta.set(xe,Q.meta||{price:Be("conveyor"),builtSession:null,uses:0}),Q.currentKey=xe}for(let Q of e.groupDrag.origins)if(Q.type==="eggFarm")Q.obj.col=Q.col+te,Q.obj.row=Q.row+se;else if(Q.type==="scanner")Q.obj.col=Q.col+te,Q.obj.row=Q.row+se;else if(Q.type==="facility"){let xe={x:Q.center.x+O,y:Q.center.y+Y},{entry:ut,side:qe}=Un(xe);Wn(Q.obj,ut,qe)}e.groupDrag.selections=e.groupDrag.origins.map(Q=>Q.type==="conveyor"?{type:"conveyor",id:Q.currentKey||Q.oldKey}:{type:Q.type,id:Q.id}),e.multiSelected=[...e.groupDrag.selections],e.selected=e.multiSelected[0]||null,be(e),n()}function G(){e.groupDrag&&(be(e),e.groupDrag=null,n())}return{selectionFromHit:M,startSelectionBox:ae,updateSelectionBox:he,finishSelectionBox:j,startGroupDrag:U,updateGroupDrag:E,finishGroupDrag:G}}function is({game:e,ui:t,canvas:n,canvasPoint:o,onUpdatePanels:r}){function s(){r&&r()}let l=null,d=!1,k=null,M=!1,D=["random","up","right","down","left"],L={random:"RND",up:"UP",right:"RT",down:"DN",left:"LF"},F={w:40,h:40,y:0};function z(){return xn(e)}function oe(){e.gridCols=y.cols,e.gridRows=y.rows,e.gridOwnedCells=vr(e)}function X(i){if(i){y.y-=i*y.cell,y.rows+=i,e.gridChunkOriginY=(e.gridChunkOriginY||0)-Math.floor(i/10),e.ownedCells=kn(e.ownedCells,i),e.blockedCells=kn(e.blockedCells,i),e.conveyorTiles=kn(e.conveyorTiles,i),e.conveyorMeta=Sr(e.conveyorMeta,i);for(let c of e.eggFarms||[])c.row+=i;for(let c of e.scanners||[])c.row+=i;for(let c of Object.values(e.facilities||{}))c.entry&&(c.entry.row+=i)}}function ae(i){e.ownedCells=e.ownedCells||new Set;for(let c of Cr(i))e.ownedCells.add(I(c.col,c.row))}function he(i){return e.phase!=="build"||e.cardDraft?.pending||e.cardTargetPick?.pending?null:mt(e).find(c=>c&&kr(c,i))||null}function j(i="right"){if(i&&typeof i=="object"&&Number.isFinite(i.chunkX)&&Number.isFinite(i.chunkY))return i;let c=["right","up"].includes(i)?i:"right";return xr(e,c)}function g(i="right"){let c=j(i);if(e.phase!=="build"||e.cardDraft?.pending||e.cardTargetPick?.pending)return{ok:!1,reason:"Cannot expand now."};if(!c)return{ok:!1,reason:"Invalid expansion lot."};let h=c.direction||"right",m=z();if(e.cashy.cols&&(y.cols=A.colStart+A.cols),A.rowStart+A.rows>y.rows&&(y.rows=A.rowStart+A.rows),ae(A),Mr(e,A.chunkX,A.chunkY),e.gridExpansionPurchases=(e.gridExpansionPurchases||0)+1,e.gridExpansionPurchasesByDirection[h]=(e.gridExpansionPurchasesByDirection[h]||0)+1,oe();let ne=yr({seed:`${e.runSeed}:grid-expansion:${A.chunkX},${A.chunkY}:${e.gridExpansionPurchases}`,colStart:A.colStart,colEnd:A.colStart+A.cols,rowStart:A.rowStart,rowEnd:A.rowStart+A.rows,targetRatio:q.map.blockedRatio});for(let Ft of ne)e.blockedCells.add(Ft);be(e);let ue=A.cols*A.rows,ke=bt(A);return N(e,ke.x+ke.w/2,ke.y+ke.h/2,`${h.toUpperCase()} +${ue} CELLS -${S(m)}`,f.green),s(),{ok:!0,direction:h,cost:m,addedCells:ue,blocked:ne.size,chunkX:A.chunkX,chunkY:A.chunkY}}function _(i,c){return i>=0&&i=0&&c!c.has(m.id)&&me(h,le(m),12))}function E(i,c,h=null){if(!_(i,c))return!1;if(U(i,c))return!0;let m=I(i,c),T=kt(e,i,c);if(T&&!(h?.type==="eggFarm"&&h.ref?.id===T.id))return!0;let A=Ct(e,i,c);return!!(A&&!(h?.type==="scanner"&&h.ref?.id===A.id)||e.conveyorTiles.has(m)&&!(h?.type==="conveyor"&&h.oldKey===m))}function G(i,c,h=null){let m={col:i,row:c};for(let T of xt(m)){if(!_(T.col,T.row)||U(T.col,T.row))return!0;let A=I(T.col,T.row);if(kt(e,T.col,T.row))return!0;let ue=Ct(e,T.col,T.row);if(ue&&!(h?.type==="scanner"&&h.ref?.id===ue.id)||e.conveyorTiles.has(A))return!0}return!1}function w(){return e.selected?e.selected.type==="eggFarm"?e.eggFarms.find(i=>i.id===e.selected.id)||null:e.selected.type==="scanner"?e.scanners.find(i=>i.id===e.selected.id)||null:e.selected.type==="conveyor"?e.conveyorTiles.has(e.selected.id)?{type:"conveyor",id:e.selected.id}:null:e.selected.type==="facility"&&e.facilities[e.selected.id]||null:null}function C(i){return i?i.type==="eggFarm"?`${ht("eggFarm")} #${i.id}`:i.type==="scanner"?`${i.kind==="auto"?ht("autoScanner"):ht("manualScanner")} #${i.id}`:i.type==="conveyor"?e.conveyorMeta.get(i.id)?.kind==="boostConveyor"?ht("boostConveyor"):ht("conveyor"):i.type==="facility"?i.name:"Equipment":"Equipment"}function O(i){return i?.type==="conveyor"?e.conveyorMeta?.get(i.oldKey||i.ref?.id)?.price||En(i):En(i)}function Y(){return!!e.cardEffects?.usedMachineActive}function te(){return Y()?{usedMachine:!0,noRefund:!0,durabilityBaseMultiplier:.6}:{usedMachine:!1,noRefund:!1,durabilityBaseMultiplier:1}}function se(i){let c=te();return Object.assign(i,c),i}function ve(i){let c=i?.ref||i||{};if(i?.type==="eggFarm"||c.type==="eggFarm")return e.eggFarms.length<=1?"Cannot sell the last EGG FARM.":"";if((i?.type==="facility"||c.type==="facility")&&["mixer","trash","truck"].includes(c.baseId||c.id)){let h=c.baseId||c.id;if(Object.values(e.facilities).filter(T=>(T.baseId||T.id)===h).length<=1)return`Cannot sell the last ${c.shortName||c.name||c.id}.`}return""}function ce(i){t.buildStatus.textContent=i,N(e,n.width/2-e.view.x,86-e.view.y,i.toUpperCase(),f.danger)}function je(i){if(!i)return null;let c=I(i.col,i.row);return e.conveyorMeta.get(c)||null}function Q(i){return i?(Array.isArray(i.outDirs)||(i.outDirs=[]),i.outDirs=[...new Set(i.outDirs.filter(c=>["right","left","down","up"].includes(c)))],D.includes(i.branchMode)||(i.branchMode="random"),i.kind||(i.kind="conveyor"),i.speedMultiplier||(i.speedMultiplier=i.kind==="boostConveyor"?2:1),i.outDirs):[]}function xe(i){return i?pe.filter(c=>e.conveyorTiles.has(I(i.col+c.dc,i.row+c.dr))).map(c=>c.name):[]}function ut(i,c){let h=pe.find(ue=>ue.name===c);if(!i||!h)return!1;let m=I(i.col+h.dc,i.row+h.dr),T=e.conveyorMeta.get(m);if(!T)return!1;let A=h.opposite;return[...new Set([...Array.isArray(T.outDirs)?T.outDirs:[],T.dir].filter(Boolean))].includes(A)}function qe(i){if(!e.conveyorTiles.has(i))return[];let c=J(i),h=e.conveyorMeta.get(i),m=Q(h),T=xe(c),A=[...new Set([...m,h?.dir].filter(Boolean))].filter(ke=>T.includes(ke)),ne=T,ue=A.length?A:ne;return h&&(h.outDirs=m.filter(ke=>T.includes(ke)),h.dir&&!T.includes(h.dir)&&(h.dir=h.outDirs[0]||null),h.branchMode!=="random"&&!T.includes(h.branchMode)&&(h.branchMode="random")),ue}function Fe(i,c){let h=yt(i,c);if(!h)return!1;let m=I(i.col,i.row),T=I(c.col,c.row),A=e.conveyorMeta.get(m),ne=e.conveyorMeta.get(T);if(!A||!ne)return!1;let ue=Q(A),ke=!ue.includes(h)||A.dir!==h||!ne.dir;return ue.includes(h)||ue.push(h),A.dir=h,ne.dir||(ne.dir=h),ke}function At(i){return i?pe.map(c=>({col:i.col+c.dc,row:i.row+c.dr})).filter(c=>e.conveyorTiles.has(I(c.col,c.row))):[]}function rn(i){return xe(i).length>=3}function sn(i){if(!i||!e.conveyorTiles.has(I(i.col,i.row))||rn(i))return[];let c=At(i);if(!c.length||c.length>2)return[];let h=m=>{let T=[],A=i,ne=m,ue=0,ke=new Set([I(i.col,i.row)]);for(;ne&&ue<200;){ue+=1;let Ft=I(ne.col,ne.row);if(ke.has(Ft))break;if(ke.add(Ft),T.push(ne),rn(ne))break;m=At(ne).filter(ae=>!(ae.col===A.col&&ae.row===A.row)),m.length===1?(A=ne,ne=m[0]):ne=null}return T};return[...(c[0]?h(c[0]).reverse():[]),i,...(c[1]?h(c[1]):[])]}function ln(i,c){return!!i&&[...new Set([...Array.isArray(i.outDirs)?i.outDirs:[],i.dir].filter(Boolean))].includes(c)}function hn(i){let c=0,h=0;for(let m=0;mh?[...i].reverse():i;for(let T=0;TA.name),A=m.dir&&T.includes(m.dir)?m.dir:null,ne=T[(Math.max(-1,T.indexOf(A))+1)%T.length];return Oe(e),m.dir=ne,m.outDirs=[ne],m.branchMode="random",be(e),s(),!0}return Oe(e),hn(c),be(e),s(),!0}function un(){return q.facilities[e.buildTool==="boostConveyor"?"boostConveyor":"conveyor"]}function dt(i,c=null){if(!i)return{ok:!1,reason:re.fail.outOfGrid};let{col:h,row:m}=i,T=I(h,m);if(e.conveyorTiles.has(T))return{ok:!1,exists:!0};if(U(h,m))return{ok:!1,reason:"Cannot build on blocked ground."};if(kt(e,h,m)||Ct(e,h,m))return{ok:!1,reason:re.fail.cellOccupied};let A=un(),ne=A.id||"conveyor",ue=Be(ne,e);if(e.cash=Math.abs(m)?{col:i.col+Math.sign(h),row:i.row}:{col:i.col,row:i.row+Math.sign(m)}}function zn(i){d=!1,k=i?{col:i.col,row:i.row}:null,M=!1,l=null,zt(i)}function $t(i){if(!i)return;if(!l)return zt(i);let c=l,h=0;for(;(c.col!==i.col||c.row!==i.row)&&h<64;){let m=Yn(c,i);if(zt(m),c=l||m,h+=1,!l)break}}function dn(){!M&&k&&e.conveyorTiles.has(I(k.col,k.row))&&cn(k),k=null,M=!1,l=null,d=!1}function Vt(i){if(!i)return ce(re.fail.outOfGrid);let{col:c,row:h}=i;if(e.buildTool==="conveyor"||e.buildTool==="boostConveyor"){let m=dt(i,null);if(!m.ok)return ce(m.reason||re.fail.cellOccupied);be(e);return}if(U(c,h))return ce("Cannot build on blocked ground.");if(e.buildTool==="manualScanner"||e.buildTool==="autoScanner"?G(c,h):E(c,h))return ce(re.fail.cellOccupied);e.buildTool==="eggFarm"?Vn(c,h):e.buildTool==="manualScanner"?It(c,h,"manual"):e.buildTool==="autoScanner"&&It(c,h,"auto")}function Xt(i){let c=Ge(i.x,i.y);if(["conveyor","boostConveyor","eggFarm","manualScanner","autoScanner"].includes(e.buildTool))return Vt(c);if(Zt.includes(e.buildTool))return Xn(i,e.buildTool)}function Vn(i,c){let h=Be("eggFarm",e);if(e.cashA.kind==="manual").length>=8)return ce("Manual Scanner limit reached (8 max).");let m=h==="auto"?Be("autoScanner",e):Be("manualScanner",e);if(e.cashT.id!==c.ref.id),st(e,m.x,m.y),be(e)}if(c.type==="scanner"){let m=de(c.ref);u(c,m.x,m.y),e.scanners=e.scanners.filter(T=>T.id!==c.ref.id),st(e,m.x,m.y),be(e)}if(c.type==="facility"){let m=c.ref;u(c,m.x+m.w/2,m.y+m.h/2),delete e.facilities[m.id],st(e,m.x+m.w/2,m.y+m.h/2),be(e)}e.selected=null,e.multiSelected=[],s()}function b(i){let c=Object.values(e.facilities).find(ne=>{if(i.x>=ne.x&&i.x<=ne.x+ne.w&&i.y>=ne.y&&i.y<=ne.y+ne.h)return!0;if(!ne.entry)return!1;let ke=$(ne.entry.col,ne.entry.row);return Math.abs(i.x-ke.x)<=y.cell*.46&&Math.abs(i.y-ke.y)<=y.cell*.46});if(c)return{type:"facility",ref:c};let h=Ge(i.x,i.y);if(!h)return null;let m=kt(e,h.col,h.row);if(m)return{type:"eggFarm",ref:m};let T=Ct(e,h.col,h.row);if(T)return{type:"scanner",ref:T};let A=I(h.col,h.row);return e.conveyorTiles.has(A)?{type:"conveyor",oldKey:A,ref:{type:"conveyor",id:A}}:null}let x=rs({game:e,canvasPoint:o,updatePanels:s,equipmentAtPoint:b,fail:ce,pointInGrid:_,rectOfFacility:le,rectsOverlap:me});function v(i){return null}function P(){let i=w();i&&(i.type==="conveyor"?p($(...Object.values(J(i.id)))):i.type==="eggFarm"?p($(i.col,i.row)):i.type==="scanner"?p(de(i)):i.type==="facility"&&p({x:i.x+i.w/2,y:i.y+i.h/2}))}function R(i,c,h="primary-button"){let m=document.createElement("button");return m.type="button",m.className=h,m.textContent=i,m.addEventListener("click",c),m}function V(){e.cardTargetPick?.mode==="autoScannerMenu"&&(e.cardTargetPick=null),t.modal.classList.remove("visible","equipment-popover"),t.modal.style.removeProperty("--popover-x"),t.modal.style.removeProperty("--popover-y")}function Z(i){t.modalTitle.textContent="Auto Scanner",e.cardTargetPick={pending:!0,mode:"autoScannerMenu",cardId:null,targetKeys:[`scanner:${i.id}`],remaining:1},t.modalBody.innerHTML=`
+
+
Left / right output routing for this AUTO scanner.
+
Current: ${i.role===0?"Male left / others right":"Poop left / others right"}
+
Cooldown: ${Qe(i).toFixed(1)}s.
+
`,t.modalActions.innerHTML="";let c=R("Male Left / Others Right",()=>{Oe(e),i.role=0,V(),s()},i.role===0?"facility-action warn":"facility-action"),h=R("Poop Left / Others Right",()=>{Oe(e),i.role=1,V(),s()},i.role===1?"facility-action warn":"facility-action");t.modalActions.append(c,h,R("Close",V,"facility-action")),Jn(i),t.modal.classList.add("visible","equipment-popover"),s()}function ge(i){return i?.label||i?.key||"?"}function fn(i){let c=i.key===" "?"Space":i.key.length===1?i.key.toUpperCase():i.key.replace(/^Arrow/,"");return{key:i.key.toLowerCase(),code:i.code,label:c}}function Qn(i,c,h){for(let m of e.scanners.filter(T=>T.kind==="manual"))for(let T of["left","right"]){if(m.id===i.id&&T===c)continue;let A=m.keys?.[T];if(A&&(A.code===h.code||A.key===h.key))return!0}return!1}function Qt(i,c=""){if(!i||i.kind!=="manual")return;t.modalTitle.textContent=`Manual Scanner #${i.id}`;let h=ge(i.keys?.left),m=ge(i.keys?.right),T=Ss(i);t.modalBody.innerHTML=`
+
+
Left route key: ${h}
+
Right route key: ${m}
+ ${c?`
${c}
`:""}
+ ${T?`
${T}
`:""}
+
`,t.modalActions.innerHTML="",t.modalActions.appendChild(R("Set Left Key",()=>Jo(i,"left"),"facility-action warn")),t.modalActions.appendChild(R("Set Right Key",()=>Jo(i,"right"),"facility-action warn")),t.modalActions.appendChild(R("Close",V,"facility-action")),Jn(i),t.modal.classList.add("visible","equipment-popover")}function Ss(i){let c=[{side:"left",binding:i.keys?.left},{side:"right",binding:i.keys?.right}];if(c[0].binding&&c[1].binding&&(c[0].binding.code===c[1].binding.code||c[0].binding.key===c[1].binding.key))return"Left and right keys conflict.";for(let h of c)if(h.binding)for(let m of e.scanners.filter(T=>T.kind==="manual"&&T.id!==i.id)){if(m.keys?.left&&(m.keys.left.code===h.binding.code||m.keys.left.key===h.binding.key))return`Key conflicts with Manual Scanner #${m.id} left.`;if(m.keys?.right&&(m.keys.right.code===h.binding.code||m.keys.right.key===h.binding.key))return`Key conflicts with Manual Scanner #${m.id} right.`}return""}function Jo(i,c){t.modalBody.innerHTML=`
Press a key for ${c.toUpperCase()} route.
Esc cancels.
`,t.modalActions.innerHTML="";let h=m=>{if(m.preventDefault(),m.stopPropagation(),window.removeEventListener("keydown",h,!0),m.key==="Escape")return Qt(i);let T=fn(m),A=Qn(i,c,T);Oe(e),i.keys=i.keys||{left:null,right:null},i.keys[c]=T,s(),Qt(i,A?`${T.label} assigned, but another scanner already uses it.`:`${c.toUpperCase()} set to ${T.label}.`)};window.addEventListener("keydown",h,!0)}function Ms(){let i=w();if(!(!i||i.type!=="scanner"))return i.kind==="auto"?Z(i):Qt(i)}function Ts(i){if(!i)return{x:80,y:80};if(i.type==="conveyor"){let c=J(i.id);return $(c.col,c.row)}return i.type==="eggFarm"?$(i.col,i.row):i.type==="scanner"?de(i):i.type==="facility"?{x:i.x+i.w/2,y:i.y+10}:{x:80,y:80}}function Jn(i){let c=n.getBoundingClientRect(),h=Ts(i),m=e.view?.scale||1,T=c.left+(h.x*m+(e.view?.x||0))/n.width*c.width+18,A=c.top+(h.y*m+(e.view?.y||0))/n.height*c.height-12,ne=Math.max(12,window.innerWidth-274),ue=Math.max(12,window.innerHeight-220);t.modal.style.setProperty("--popover-x",`${Math.max(12,Math.min(ne,T))}px`),t.modal.style.setProperty("--popover-y",`${Math.max(12,Math.min(ue,A))}px`)}function Zo(){let i=w();if(!i)return;let c=er(i);t.modalTitle.textContent=C(i),t.modalBody.innerHTML=`
+
${c.map(T=>`
${T}
`).join("")}
+ ${["mixer","truck"].includes(i.baseId||i.id)?'
Income/Fine = ceil(base x 1.10^upgrades)
':""}`,t.modalActions.innerHTML="",i.type==="scanner"&&i.kind==="auto"&&t.modalActions.appendChild(R("Auto Menu",()=>Z(i),"facility-action warn")),i.type==="scanner"&&i.kind==="manual"&&t.modalActions.appendChild(R("Set Keys",()=>Qt(i),"facility-action warn"));let h=i.type==="conveyor"?{type:"conveyor",oldKey:i.id,ref:i}:{type:i.type,ref:i},m=ve(h);if(m){let T=R(m,()=>{},"facility-action danger disabled");T.disabled=!0,t.modalActions.appendChild(T)}else{let T=gt(h,e),A=T.sameBuild?`Remove / Refund ${S(T.amount)}`:`Sell ${S(T.amount)}`;t.modalActions.appendChild(R(A,()=>{P(),V()},"facility-action danger"))}Jn(i),t.modal.classList.add("visible","equipment-popover")}function gs(i){e.phase==="build"&&(dn(),e.buildTool=e.buildTool===i?null:i,e.selected=null,e.multiSelected=[],e.selectionBox=null,s())}function Es(){let i=[];for(let[c,h]of Object.entries(e.facilities))if(i.push({id:`facility:${c}`,price:O({type:"facility",ref:h}),x:h.x,y:h.y,w:h.w,h:h.h}),h.entry){let m=$(h.entry.col,h.entry.row);i.push({id:`facilityPort:${c}`,price:O({type:"facility",ref:h}),x:m.x-18,y:m.y-18,w:36,h:36})}for(let c of e.eggFarms){let h=$(c.col,c.row);i.push({id:`eggFarm:${c.id}`,price:O({type:"eggFarm",ref:c}),x:h.x-24,y:h.y-24,w:48,h:48})}for(let c of e.scanners){let h=de(c);i.push({id:`scanner:${c.id}`,price:O({type:"scanner",ref:c}),x:h.x-50,y:h.y-73,w:100,h:146})}for(let c of e.conveyorTiles){let h=J(c),m=$(h.col,h.row),T=e.conveyorMeta.get(c)||{};i.push({id:`conveyor:${c}`,price:T.price||Be(T.kind==="boostConveyor"?"boostConveyor":"conveyor",e),x:m.x-22,y:m.y-22,w:44,h:44})}return i}function pn(i){return L[i]||L.random}function nc(i){return nr(i)}function nr(i){if(!e.conveyorTiles.has(i))return[];let c=J(i),h=xe(c);return rn(c)?h:h.length?h:qe(i)}function Zn(i){return e.conveyorTiles.has(i)?rn(J(i)):!1}function jo(i){if(e.phase!=="build"||e.cardDraft?.pending||e.cardTargetPick?.pending)return null;for(let c of e.conveyorTiles){if(!Zn(c))continue;let h=J(c),m=$(h.col,h.row),T=m.x-F.w/2,A=m.y+F.y-F.h/2;if(i.x>=T&&i.x<=T+F.w&&i.y>=A&&i.y<=A+F.h)return c}return null}function Ps(i){let c=jo(i);return c?(jn(c),!0):!1}function jn(i){let c=e.conveyorMeta.get(i);if(!c)return!1;let h=nr(i),m=J(i),T=new Set(h.filter(ne=>ut(m,ne))),A=h.filter(ne=>{let ue=new Set(T);return ue.add(ne),h.filter(ke=>!ue.has(ke)).length>=2});if(A.length<2)return!1;Oe(e);let ne=D.includes(c.branchMode)?c.branchMode:"random",ue=["random",...pe.map(ke=>ke.name).filter(ke=>A.includes(ke))];c.branchMode=ue[(Math.max(0,ue.indexOf(ne))+1)%ue.length],e.selected=null,e.multiSelected=[];return s(),!0}function er(i){ye(e);let c=[],h=i?.type==="facility"?i.baseId||i.id:"";if(i.type==="eggFarm"){let[m,T]=en(i);c.push(`Price: ${S(O(i))}`);{let A=ve({type:i.type,ref:i});c.push(A?`Sale: blocked (${A})`:`Sale value: ${S(gt({type:i.type,ref:i},e).amount)}`)}c.push(`Level: ${i.level}/4`),c.push(`Random interval: ${m.toFixed(2)}-${T.toFixed(2)}s`),c.push(`Durability: ${ln(i)}% | Spawn delay x${Ln(i).toFixed(2)}`)}else if(i.type==="scanner")c.push(`Price: ${S(O(i))}`),c.push(`Sale value: ${S(gt({type:i.type,ref:i},e).amount)}`),c.push(`Type: ${i.kind.toUpperCase()} / Standard`),i.kind==="auto"&&c.push(`Role: ${i.role===0?"Male left / Others right":"Poop left / Others right"}`),c.push(`Queue: ${i.queue.length}`),i.kind==="auto"&&c.push(`Cooldown: ${i.cooldown.toFixed(1)}s / ${Qe(i,e).toFixed(1)}s`),i.kind==="auto"&&c.push(`Durability: ${ln(i)}% | Delay x${Bn(i).toFixed(2)}`),i.kind==="manual"&&c.push("Durability: none | Always normal");else if(i.type==="conveyor"){let m=e.conveyorMeta.get(i.id),T=e.componentLookup?.get(i.id),A=T?e.congestion.get(T):null;c.push(`Price: ${S(O({type:"conveyor",oldKey:i.id,ref:i}))}`),c.push(`Cell: ${i.id}`),c.push(`Type: ${m?.kind==="boostConveyor"?"BOOST BELT":"Normal Belt"} | Speed x${Number(m?.speedMultiplier||1).toFixed(1)}`),c.push(`Congestion: ${A?Math.floor(A.ratio*100):0}%`),c.push(`Durability: ${ln({meta:m})}% | Speed x${Fn({meta:m}).toFixed(2)}`),Zn(i.id)?(c.push(`Branch mode: ${pn(m?.branchMode||"random")}`),c.push("Use the Branch button below or the on-belt branch badge.")):c.push("Branch mode: needs 3+ conveyor connections."),c.push(`Sale value: ${S(gt({type:"conveyor",oldKey:i.id,ref:i},e).amount)}`)}else if(i.type==="facility"){c.push(`Price: ${S(O(i))}`);{let m=ve({type:i.type,ref:i});c.push(m?`Sale: blocked (${m})`:`Sale value: ${S(gt({type:i.type,ref:i},e).amount)}`)}if(c.push(["mixer","truck","trash"].includes(i.id)?`Level: ${i.level} / no cap`:`Level: ${i.level}`),h==="truck"&&c.push("Durability: none | Always normal"),["mixer","trash"].includes(h)&&c.push(`Durability: ${ln(i)}% | Extra delay ${Bo(e,i).toFixed(2)}s`),h==="mixer"&&(c.push(`Income: ${S(_e(e))} per chick | upgrade x${nt(e,"mixer").toFixed(3)}`),c.push(`Poop fine: -${S(nn(e))}`)),h==="truck"&&(c.push(`Income: ${S(Le(e))} per target cargo | upgrade x${nt(e,"truck").toFixed(3)}`),c.push(`Poop shipment fine: -${S(on(e))}`)),h==="trash"){let m=Tt(e),T=ot(m);c.push(`Bonus cards: ${m}/${Gt()}`),c.push(`Bonus chance: ${(T*100).toFixed(2)}% for ${S(1)} per processed item.`),c.push(`Expected value: ${T.toFixed(3)} JPY per item.`)}i.entry&&c.push(`Receiver: edge cell ${i.entry.col},${i.entry.row} (${i.side})`)}return c}function Rs(i){if(!i||e.phase!=="build")return"";let c=gn(e).find(h=>h.type===i.type&&h.id===i.id);return c?c.message||"Not connected to conveyor route":""}function Ds(i){return i?i.type==="conveyor"&&e.conveyorMeta.get(i.id)?.kind==="boostConveyor"?"Moves chicks twice as fast. Wears down like a normal belt.":i.type==="conveyor"?"A stubborn belt tile. It only cares about the next cell.":i.type==="eggFarm"?"A tiny gatehouse producing questionable eggs on schedule.":i.type==="scanner"&&i.kind==="auto"?"Slower than hands without upgrades.":i.type==="scanner"?"A manual checkpoint. The operator is the algorithm.":i.type==="facility"&&(i.baseId||i.id)==="mixer"?"Male chicks become revenue here. Do not feed it poop.":i.type==="facility"&&(i.baseId||i.id)==="trash"?"Poop goes in. Sometimes coins come out, for reasons best left unaudited.":i.type==="facility"&&(i.baseId||i.id)==="truck"?"The shipping endpoint. Correct cargo pays; wrong cargo complains.":"Factory equipment.":""}return{buildAtCell:Vt,buildAtPoint:Xt,eraseAtPoint:p,equipmentAtPoint:b,startSelectionBox:x.startSelectionBox,updateSelectionBox:x.updateSelectionBox,finishSelectionBox:x.finishSelectionBox,startGroupDrag:x.startGroupDrag,updateGroupDrag:x.updateGroupDrag,finishGroupDrag:x.finishGroupDrag,selectedObject:w,selectedTitle:C,equipmentPrice:O,selectedUpgradeCost:v,selectedInfoLines:er,flavorText:Ds,disconnectedWarningFor:Rs,gridExpansionCost:z,buyGridExpansion:g,expansionOfferAtPoint:he,beginConveyorDrag:zn,continueConveyorDrag:$t,endConveyorDrag:dn,cycleSingleConveyorDirection:cn,branchSwitcherAtPoint:jo,cycleBranchModeAtPoint:Ps,cycleBranchModeForKey:jn,removeSelected:P,switchScannerRole:Ms,showManualScannerMenu:Qt,showAutoScannerMenu:Z,showSelectedMenu:Zo,setBuildTool:gs,fail:ce,isEquipmentCell:E,equipmentHitBoxes:Es,routeFromFarmToScanner:Mt}}function ss({game:e,ui:t,build:n,startGame:o,beginCardDraft:r,activeQueuedChick:s}){function l(E){return String(E).replace(/[&<>"']/g,G=>({"&":"&","<":"<",">":">",'"':""","'":"'"})[G])}function d(){return Math.round(Gn(e))}function k(){if(e.phase!=="build"||e.cardDraft?.pending||e.cardTargetPick?.pending)return!1;let E=!1;for(let G of no)if(E=!0,e.cash>=Be(G,e))return!1;return E}function M(){D(),L(),oe(),z(),F()}function D(){for(let[G,w]of Object.entries(t.buttons))w?.classList?.contains("tool-button")&&w.classList.toggle("active",e.buildTool===G);for(let G of no){let w=t.buttons[G];if(!w)continue;let C=Be(G,e),O=w.querySelector("span");O&&(O.textContent=G==="conveyor"||G==="boostConveyor"?`${S(C)} / tile`:S(C));let Y=G==="manualScanner"&&e.scanners.filter(se=>se.kind==="manual").length>=8,te=e.cashMt(e,ve)?.scannerId).length,G=tn(e),w=Math.max(0,Math.floor(e.lastResult?.profit??e.stats?.profit??0)),C=Pn(w,e),O=e.phase==="running"?Math.max(1,(e.totals.turnsCompleted||0)+1):Math.max(1,Number(e.turn)||1),Y=So(e,O),te=e.lastBuildFees?.turn===O?e.lastBuildFees.fairiesTribute||0:null,se=e.lastBuildFees?.turn===O&&e.lastBuildFees.reduction||0;t.turnSummary.innerHTML=[`Seed: ${l(e.runSeed||"none")} | Grid box: ${e.gridRows||10}x${e.gridCols||20} | Owned: ${e.gridOwnedCells||e.ownedCells?.size||(e.gridRows||10)*(e.gridCols||20)} cells | Blocked: ${e.blockedCells?.size||0} cells`,`Truck target: ${ze(e).toUpperCase()} | Male fine: -${S(Co(e))}`,`Poop fine: Mixer -${S(nn(e))} / Shipment -${S(on(e))}`,`ZUNDA TAX on Next Day: -${S(C.tax)} | basis net ${S(w)} | taxable ${S(C.taxable)} x${C.ratePercent}% | exemption ${S(C.exemption)} | 95% at ${S(C.maxRateCash)}`,te!=null?`Fairies tribute paid before Build: -${S(te)}${se?` | Flattery -${S(se)}`:""}`:`Fairies tribute before Build: -${S(Y.amount)}${Y.reduction?` | Flattery -${S(Y.reduction)}`:""}`,`Maintenance: worst ${No(e).worst.percent}% dirty (${No(e).worst.label}) | Repairman: ${e.repairman?.hiredForNextDay?"hired next day":e.repairman?.active?"working":"none"}`,`Manual combo: ${e.manualCombo?.count||0} | Card draft: ${e.cardDraft?.pending?Math.max(1,e.cardDraft.picksRemaining||1)+" pick(s) left":"ready after each day"} | Belt: ${d()}px/s | Farms with scanner route: ${E}/${e.eggFarms.length}`,e.cardEffects?.usedMachineActive?'Procurement: USED MACHINE MODE / no refunds / 60% durability':"",G.length?`Blocked: ${G[0]}`:`${re.status.allPortsConnected}`].join(" ")}function oe(){if(!t.contractPanel)return;let E=e.contractOffer;if(e.phase!=="build"){t.contractPanel.innerHTML=re.status.eventPanelRunning;return}if(!E){t.contractPanel.className="contract-card empty",e.turn+1Event lock active.No irregular events during Days 1-7. First possible forced event: Day ${ft}.`:t.contractPanel.innerHTML="No event.Random forced events can appear later.";return}t.contractPanel.className="contract-card accepted",t.contractPanel.innerHTML=`
+