1(function(){"use strict";var ORDER=["up","right","down","left"],VEC={up:[0,-1],right:[1,0],down:[0,1],left:[-1,0]},OPP={up:"down",down:"up",left:"right",right:"left"},CELL=4,CROSS=[[0,0],[-1,0],[1,0],[0,-1],[0,1]],STORE_KEY="lvh-grid-best";function leftOf(d){return ORDER[(ORDER.indexOf(d)+3)%4]}function rightOf(d){return ORDER[(ORDER.indexOf(d)+1)%4]}function attr(el,name,fallback){var v=el.getAttribute("data-"+name);return v===null||v===""?fallback:v}function numAttr(el,name,fallback){var n=parseFloat(attr(el,name,""));return isNaN(n)?fallback:n}function boolAttr(el,name,fallback){var v=attr(el,name,null);return v===null?fallback:v==="true"||v==="1"}function hexToRgb(hex){hex=String(hex||"").replace("#","").trim(),hex.length===3&&(hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2]);var n=parseInt(hex,16);return isNaN(n)?[255,255,255]:[n>>16&255,n>>8&255,n&255]}function mix(hex,target,amount){var a=hexToRgb(hex),b=hexToRgb(target);return"rgb("+Math.round(a[0]+(b[0]-a[0])*amount)+","+Math.round(a[1]+(b[1]-a[1])*amount)+","+Math.round(a[2]+(b[2]-a[2])*amount)+")"}function mulberry32(a){return function(){a|=0,a=a+1831565813|0;var t=Math.imul(a^a>>>15,1|a);return t=t+Math.imul(t^t>>>7,61|t)^t,((t^t>>>14)>>>0)/4294967296}}var reduceMotion=typeof window!="undefined"&&window.matchMedia&&window.matchMedia("(prefers-reduced-motion: reduce)").matches;function Rider(color,isHuman,mistake,sight){this.color=color,this.light=mix(color,"#ffffff",.45),this.isHuman=!!isHuman,this.mistake=mistake,this.sight=sight||400,this.trail=[],this.dir="right",this.queued=null,this.x=0,this.y=0}function BullittGrid(root){this.root=root,this.cfg={playerColor:attr(root,"player-color","#ff2e88"),aiColor:attr(root,"ai-color","#25e5ff"),bgColor:attr(root,"bg-color","#07070d"),gridColor:attr(root,"grid-color","#171727"),trailDim:numAttr(root,"trail-dim",0),stepMs:numAttr(root,"step-ms",72),aiMistake:numAttr(root,"ai-mistake",.1),colsDesktop:numAttr(root,"cols-desktop",136),colsMobile:numAttr(root,"cols-mobile",70),maxSeconds:numAttr(root,"max-seconds",40),glow:boolAttr(root,"glow",!0)&&!reduceMotion,attract:boolAttr(root,"attract",!0)&&!reduceMotion,gridEvery:numAttr(root,"grid-every",2),rampSpeed:numAttr(root,"ramp-speed",1.2),rampCurve:numAttr(root,"ramp-curve",1.5),rampFloor:numAttr(root,"ramp-floor",38),rampSharp:numAttr(root,"ramp-sharp",.86),logoStepMs:numAttr(root,"logo-step-ms",34),logoHoldMs:numAttr(root,"logo-hold-ms",2200),logoSpawnMs:numAttr(root,"logo-spawn-ms",420),logoParts:numAttr(root,"logo-particles",5),logoScatter:numAttr(root,"logo-scatter",7),logoOutMs:numAttr(root,"logo-out-ms",850),logoOutScatter:numAttr(root,"logo-out-scatter",26),idleReturnMs:numAttr(root,"idle-return-ms",3e4),logoLine:attr(root,"logo-line-color","#eed9ea"),logoAccent:attr(root,"logo-accent-color","#613393"),logoAccentOn:boolAttr(root,"logo-accent",!0),logoRidden:attr(root,"logo-ridden-color",""),phaseOn:boolAttr(root,"phase-enabled",!0),phaseEvery:numAttr(root,"phase-every-steps",48),phaseSteps:numAttr(root,"phase-steps",26),phaseColor:attr(root,"phase-color","#ffe45e"),boostColor:attr(root,"boost-color","#5effc4"),boostSteps:numAttr(root,"boost-steps",34),boostScale:numAttr(root,"boost-scale",.62),phaseMax:numAttr(root,"phase-max-onboard",2),tutorialOn:boolAttr(root,"tutorial",!0),mobilePlay:boolAttr(root,"mobile-play",!1),mobileMax:numAttr(root,"mobile-breakpoint",749),tutorialMs:numAttr(root,"tutorial-ms",4200),aiMinSpace:numAttr(root,"ai-min-space",14),aiSight:numAttr(root,"ai-sight",150),aiSightRamp:numAttr(root,"ai-sight-ramp",1.35),aiPlan:numAttr(root,"ai-plan",.45),aiPlanRamp:numAttr(root,"ai-plan-ramp",.1),aiSafeFloor:numAttr(root,"ai-safe-floor",26),aiSeek:numAttr(root,"ai-seek",1),aiBlock:numAttr(root,"ai-block",.8),aiBlockRamp:numAttr(root,"ai-block-ramp",.12),aiHuntGain:numAttr(root,"ai-hunt-gain",2.5),aiSafeFrac:numAttr(root,"ai-safe-frac",.6),aiUsesPowerups:boolAttr(root,"ai-powerups",!0),critOn:boolAttr(root,"crit-enabled",!0),critSweepMs:numAttr(root,"crit-sweep-ms",1100),critZone:numAttr(root,"crit-zone",.26),critShrink:numAttr(root,"crit-shrink",.62),critMaxTries:numAttr(root,"crit-max-tries",10),critZoneFinal:numAttr(root,"crit-zone-final",1e-6),critRewind:numAttr(root,"crit-rewind-steps",12),critPasses:numAttr(root,"crit-passes",3),critPrompt:attr(root,"crit-prompt","CRIT SAVE \u2014 HIT SPACE"),critPromptTouch:attr(root,"crit-prompt-touch","CRIT SAVE \u2014 TAP NOW"),critRewindMs:numAttr(root,"crit-rewind-ms",700),rewindLagMs:numAttr(root,"rewind-lag-ms",130),rewindFxMs:numAttr(root,"rewind-fx-ms",420),rewindScatter:numAttr(root,"rewind-scatter",9),shareTitle:attr(root,"share-title","MISS BULLITT"),shareTag:attr(root,"share-tag","#missbullitthighscore"),shareSite:attr(root,"share-site","larryvsharry.com"),shareText:attr(root,"share-text","wins in a row on the Bullitt Grid.")},this.canvas=root.querySelector("[data-lvh-canvas]"),this.glowCanvas=root.querySelector("[data-lvh-glow]"),this.gridCanvas=root.querySelector("[data-lvh-gridlayer]"),this.fxCanvas=root.querySelector("[data-lvh-fx]"),this.poster=root.querySelector("[data-lvh-poster]"),this.startBtn=root.querySelector("[data-lvh-start]"),this.overCard=root.querySelector("[data-lvh-over]"),this.overTitle=root.querySelector("[data-lvh-over-title]"),this.overBody=root.querySelector("[data-lvh-over-body]"),this.retryBtn=root.querySelector("[data-lvh-retry]"),this.countEl=root.querySelector("[data-lvh-count]"),this.streakEl=root.querySelector("[data-lvh-streak]"),this.levelEl=root.querySelector("[data-lvh-level]"),this.bestEl=root.querySelector("[data-lvh-best]"),this.newBestEl=root.querySelector("[data-lvh-newbest]"),this.reward=root.querySelector("[data-lvh-reward]"),this.dp
1ad=root.querySelector("[data-lvh-dpad]"),this.shareBtn=root.querySelector("[data-lvh-share]"),this.saveBtn=root.querySelector("[data-lvh-save]"),this.statusEl=root.querySelector("[data-lvh-status]"),this.heldEl=root.querySelector("[data-lvh-held]"),this.tutorialEl=root.querySelector("[data-lvh-tutorial]"),this.tutReadyBtn=root.querySelector("[data-lvh-tut-ready]"),this.tutCloseBtn=root.querySelector("[data-lvh-tut-close]"),this.canvas&&(this.ctx=this.canvas.getContext("2d"),this.gctx=this.glowCanvas?this.glowCanvas.getContext("2d"):null,this.fx=this.fxCanvas?this.fxCanvas.getContext("2d"):null,this.pickups=[],this.phaseLeft=0,this.boostLeft=0,this.held=null,this.critZone=this.cfg.critZone,this.critTries=0,this.critHits=0,this.critPerfect=0,this._chain=2166138321,this._shadowStreak=0,this._shadowLevel=0,this.mode="idle",this.streak=0,this.level=0,this.best=this.readBest(),this.acc=0,this.last=0,this.raf=null,this.countdown=0,this.idleOnly=!this.cfg.mobilePlay&&window.innerWidth<=this.cfg.mobileMax,this.idleOnly&&this.root.classList.add("is-idleonly"),this.bindUI(),this.paintBest(),this.observe())}BullittGrid.prototype.bindUI=function(){var self=this;this.startBtn&&this.startBtn.addEventListener("click",function(){self.newRun(!0)}),this.retryBtn&&this.retryBtn.addEventListener("click",function(){self.newRun()}),this.tutReadyBtn&&this.tutReadyBtn.addEventListener("click",function(e){e.stopPropagation(),self.endTutorial()}),this.tutCloseBtn&&this.tutCloseBtn.addEventListener("click",function(e){e.stopPropagation(),self.endTutorial()}),this.tutorialEl&&this.tutorialEl.addEventListener("click",function(e){var chip=e.target.closest("[data-lvh-dots] i");if(chip)for(var dots=self.tutorialEl.querySelectorAll("[data-lvh-dots] i"),i=0;i<dots.length;i++)dots[i]===chip&&self.goTutorial(i)}),this.shareBtn&&this.shareBtn.addEventListener("click",function(){self.shareCard()}),this.saveBtn&&this.saveBtn.addEventListener("click",function(){self.saveCard()}),this._onKey=function(e){if(!self.idleOnly){if(e.key==="t"||e.key==="T"){e.preventDefault(),self.toggleTutorial();return}var isSpace=e.key===" "||e.key==="Spacebar"||e.key==="Enter";if(self.mode==="crit"){isSpace&&(e.preventDefault(),self.critAttempt());return}if(self.mode==="tutorial"){e.preventDefault(),e.key==="ArrowRight"||e.key==="ArrowDown"?self.goTutorial(self.tutPage+1):(e.key==="ArrowLeft"||e.key==="ArrowUp")&&self.goTutorial(self.tutPage-1);return}if(self.mode==="playing"){if(isSpace){e.preventDefault(),self.usePowerUp();return}var map={ArrowUp:"up",ArrowDown:"down",ArrowLeft:"left",ArrowRight:"right",w:"up",s:"down",a:"left",d:"right",W:"up",S:"down",A:"left",D:"right"};if(e.key==="Escape"){self.abandonRun();return}var dir=map[e.key];dir&&(e.preventDefault(),self.queueTurn(self.p1,dir))}}},window.addEventListener("keydown",this._onKey,{passive:!1}),window.addEventListener("blur",function(){self.mode==="playing"&&self.abandonRun()});var sx=0,sy=0,tracking=!1;this.root.addEventListener("pointerdown",function(){self.idleOnly||(self.mode==="crit"?self.critAttempt():self.mode==="playing"&&self.held&&self.usePowerUp())}),this.canvas.addEventListener("touchstart",function(e){self.mode==="playing"&&(tracking=!0,sx=e.touches[0].clientX,sy=e.touches[0].clientY)},{passive:!0}),this.canvas.addEventListener("touchmove",function(e){if(!(!tracking||self.mode!=="playing")){var dx=e.touches[0].clientX-sx,dy=e.touches[0].clientY-sy;Math.abs(dx)<24&&Math.abs(dy)<24||(e.preventDefault(),self.queueTurn(self.p1,Math.abs(dx)>Math.abs(dy)?dx>0?"right":"left":dy>0?"down":"up"),tracking=!1)}},{passive:!1}),this.dpad&&this.dpad.addEventListener("click",function(e){var btn=e.target.closest("[data-dir]");if(btn){if(self.mode!=="playing"){self.newRun();return}self.queueTurn(self.p1,btn.getAttribute("data-dir"))}});var t;window.addEventListener("resize",function(){clearTimeout(t),t=setTimeout(function(){self.maybeResize()},200)})},BullittGrid.prototype.observe=function(){var self=this,boot=function(){self.booted||(self.booted=!0,self.buildField(),self.cfg.attract&&window.LVH_LOGO?self.startLogo():self.cfg.attract?self.startRound(!1):self.root.classList.add("is-ready"))};if(!("IntersectionObserver"in window)){boot();return}var io=new IntersectionObserver(function(entries){entries[0].isIntersecting&&(io.disconnect(),"requestIdleCallback"in window?requestIdleCallback(boot,{timeout:1200}):setTimeout(boot,200))},{rootMargin:"200px"});io.observe(this.root)},BullittGrid.prototype.buildField=function(){var stripe=this.root.querySelector(".lvhg__stats"),inset=stripe?Math.ceil(stripe.getBoundingClientRect().height):0;this.root.style.setProperty("--lvh-top",inset+"px");var rect=(this.canvas||this.root).getBoundingClientRect(),w=Math.max(rect.width,320),h=Math.max(rect.height,240),wide=window.innerWidth>=750;this.cols=wide?this.cfg.colsDesktop:this.cfg.colsMobile,window.LVH_LOGO&&(this.cols=Math.max(this.cols,window.LVH_LOGO.cols+4)),this.rows=Math.max(24,Math.round(this.cols*(h/w))),this.canvas.width=this.cols*CELL,this.canvas.height=this.rows*CELL,this.glowCanvas&&(this.glowCanvas.width=this.canvas.width,this.glowCanvas.height=this.canvas.height),this.fxCanvas&&(this.fxCanvas.width=this.canvas.width,this.fxCanvas.height=this.canvas.height,this.fx.imageSmoothingEnabled=!1),this.grid=new Uint8Array(this.cols*this.rows),this._stamp=new Uint16Array(this.cols*this.rows),this._gen=0,this.ctx.imageSmoothingEnabled=!1,this.gctx&&(this.gctx.imageSmoothingEnabled=!1),this._fieldW=w,this._fieldH=h,this.paintGridLayer(w,h)},BullittGrid.prototype.paintGridLayer=function(w,h){if(this.gridCanvas){var dpr=Math.min(window.devicePixelRatio||1,2),g=this.gridCanvas.getContext("2d");this.gridCanvas.width=Math.round(w*dpr),this.gridCanvas.height=Math.round(h*dpr),g.setTransform(dpr,0,0,dpr,0,0),g.clearRect(0,0,w,h);
1var cellW=w/this.cols,cellH=h/this.rows,every=Math.max(1,this.cfg.gridEvery);g.fillStyle=this.cfg.gridColor;var i;for(i=0;i<=this.cols;i+=every)g.fillRect(Math.round(i*cellW),0,1,h);for(i=0;i<=this.rows;i+=every)g.fillRect(0,Math.round(i*cellH),w,1)}},BullittGrid.prototype.maybeResize=function(){if(this.booted){var idle=!this.cfg.mobilePlay&&window.innerWidth<=this.cfg.mobileMax;idle!==this.idleOnly&&(this.idleOnly=idle,this.root.classList.toggle("is-idleonly",idle),idle&&this.mode!=="logo"&&this.startLogo());var rect=(this.canvas||this.root).getBoundingClientRect();if(!(Math.abs(rect.width-this._fieldW)/this._fieldW<.05&&Math.abs(rect.height-this._fieldH)/this._fieldH<.05)){var wasPlaying=this.mode==="playing",wasLogo=this.mode==="logo";this.buildField(),wasLogo||this.idleOnly?this.startLogo():this.startRound(wasPlaying)}}},BullittGrid.prototype.spawnPickup=function(){if(this.cfg.phaseOn&&!(this.pickups.length>=this.cfg.phaseMax))for(var tries=0;tries<40;tries++){for(var x=3+Math.floor(this.rnd()*(this.cols-6)),y=3+Math.floor(this.rnd()*(this.rows-6)),clear=!0,c,k=0;k<CROSS.length;k++)if(c=CROSS[k],this.grid[this.idx(x+c[0],y+c[1])]!==0){clear=!1;break}if(clear&&!(Math.abs(x-this.p1.x)+Math.abs(y-this.p1.y)<6)&&!(Math.abs(x-this.p2.x)+Math.abs(y-this.p2.y)<6)){var kind=this.rnd()<.5?"phase":"boost";this.pickups.push({x:x,y:y,kind:kind,born:performance.now()});return}}},BullittGrid.prototype.takePickup=function(x,y){for(var i=0;i<this.pickups.length;i++){for(var p=this.pickups[i],hit=!1,k=0;k<CROSS.length;k++)if(p.x+CROSS[k][0]===x&&p.y+CROSS[k][1]===y){hit=!0;break}if(hit)return this.held=this.pickups[i].kind,this.pickups.splice(i,1),this.paintHeld(),!0}return!1},BullittGrid.prototype.usePowerUp=function(){this.mode!=="playing"||!this.held||(this.held==="phase"?this.phaseLeft=this.cfg.phaseSteps:this.held==="boost"&&(this.boostLeft=this.cfg.boostSteps),this.held=null,this.paintHeld())},BullittGrid.prototype.paintHeld=function(){this.heldEl&&(this.heldEl.textContent=this.held?this.held==="phase"?"PHASE":"BOOST":"\u2014",this.heldEl.style.color=this.held?this.held==="phase"?this.cfg.phaseColor:this.cfg.boostColor:"")},BullittGrid.prototype.critZoneFor=function(attempt){var max=Math.max(2,this.cfg.critMaxTries);if(attempt>=max)return 0;var a=this.cfg.critZone,b=this.cfg.critZoneFinal,n=max-1;return n<2?a:a*Math.pow(Math.pow(b/a,1/(n-1)),attempt-1)},BullittGrid.prototype.critExhausted=function(){return this.critTries>=this.cfg.critMaxTries},BullittGrid.prototype.startCritSave=function(pendingResult){this.mode="crit",this.critResult=pendingResult,this.critT0=performance.now(),this.critLocked=null,this.critTries++,this.critZone=this.critZoneFor(this.critTries),this.critCentre=.25+this.rnd()*.5,this.root.classList.add("is-crit");var touch=window.matchMedia&&window.matchMedia("(pointer: coarse)").matches;this.showCount(touch?this.cfg.critPromptTouch:this.cfg.critPrompt),this.last=0,this.run()},BullittGrid.prototype.critExpired=function(now){return this.critLocked===null&&now-this.critT0>this.cfg.critSweepMs*2*this.cfg.critPasses},BullittGrid.prototype.critResolve=function(hit){var self=this;this.showCount(hit?"SAVED":""),setTimeout(function(){self.root.classList.remove("is-crit"),self.showCount(""),hit?self.startRewind():(self.mode="over",self.root.classList.remove("is-playing"),self.root.classList.add("is-over"),self.endRun(self.critResult))},420)},BullittGrid.prototype.critMarker=function(now){var t=(now-this.critT0)%(this.cfg.critSweepMs*2)/this.cfg.critSweepMs;return t<=1?t:2-t},BullittGrid.prototype.critAttempt=function(forcedPos){if(!(this.mode!=="crit"||this.critLocked!==null)){var pos=typeof forcedPos=="number"?forcedPos:this.critMarker(performance.now());pos=Math.max(0,Math.min(1,pos)),this.critLocked=pos,this.inputLog&&this.inputLog.push([this.steps,"crit",pos]);var half=this.critZone/2,hit=!this.critExhausted()&&half>0&&Math.abs(pos-this.critCentre)<=half;if(hit){var acc=1-Math.min(1,Math.abs(pos-this.critCentre)/half);this.critSeconds=1+2*acc,this.critAccuracy=acc,this.critHits=(this.critHits||0)+1,acc>.999&&(this.critPerfect=(this.critPerfect||0)+1),this._fold(99^Math.round(pos*1e6))}this.critResolve(hit)}},BullittGrid.prototype.startRewind=function(){this.mode="rewind",this.last=0,this.run(),this.rewindT0=performance.now();var secs=this.critSeconds||1,want=Math.round(secs*1e3/this.stepMs);this.rewindMs=Math.max(420,Math.min(1100,300+secs*260)),this.rewindFrom=M
1ath.min(want,this.p1.trail.length-2,this.p2.trail.length-2),this.rewindFrom<1&&(this.rewindFrom=1),this.rewindDone=0,this.rewindFx=[]},BullittGrid.prototype.stepRewind=function(){var r,c,now=typeof performance!="undefined"?performance.now():Date.now();this.rewindFx||(this.rewindFx=[]);for(var k=0;k<2;k++)if(r=k?this.p2:this.p1,!(r.trail.length<2)){c=r.trail.pop(),this.grid[this.idx(c[0],c[1])]=0,this.ctx.clearRect(c[0]*CELL,c[1]*CELL,CELL,CELL);var ang=Math.random()*Math.PI*2;this.rewindFx.push({x:c[0],y:c[1],col:r.color,vx:Math.cos(ang)*(.6+Math.random()*.9),vy:Math.sin(ang)*(.6+Math.random()*.9),born:now+this.cfg.rewindLagMs});var head=r.trail[r.trail.length-1];r.x=head[0],r.y=head[1]}for(k=0;k<2;k++){r=k?this.p2:this.p1;var n=r.trail.length;if(n>=2){var a=r.trail[n-2],b=r.trail[n-1],dx=b[0]-a[0],dy=b[1]-a[1];r.dir=dx>0?"right":dx<0?"left":dy>0?"down":"up"}r.queued=null}this.rewindDone++},BullittGrid.prototype.finishRewind=function(){this.gctx&&(this.gctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.gctx.drawImage(this.canvas,0,0)),this.mode="countdown",this.countdown=3,this.showCount("3"),this.acc=0,this.last=0,this.phaseLeft=0,this.run()},BullittGrid.prototype.startLogo=function(){var D=window.LVH_LOGO;!D||!this.booted||(this.mode="logo",this.stop(),this.clearIdleTimer(),this.logoStep=0,this.logoAcc=0,this.logoDone=!1,this.logoPhase="in",this.dissolve=null,this.spawns=[],this.solid=[],this.decoAt=0,this.camY=Math.round((this.rows-D.rows)/2),this.camX=this.cols>=D.cols+4?Math.round((this.cols-D.cols)/2):0,this.logoFits=this.cols>=D.cols+4,this.pickups=[],this.phaseLeft=0,this.boostLeft=0,this.held=null,this.fx&&this.fx.clearRect(0,0,this.fxCanvas.width,this.fxCanvas.height),this.root.classList.add("is-ready","is-running","is-logo"),this.root.classList.remove("is-playing","is-attract","is-over"),this.overCard&&(this.overCard.hidden=!0),this.poster&&this.poster.classList.add("is-hidden"),this.showCount(""),this.last=0,this.run())},BullittGrid.prototype.beginDissolve=function(now){var D=window.LVH_LOGO;this.dissolve=[];var cx=D.cols/2,cy=D.rows/2,self=this;function add(c,kind){var dx=(c[0]-cx)/Math.max(1,cx),dy=(c[1]-cy)/Math.max(1,cy),ang=Math.random()*Math.PI*2;self.dissolve.push({x:c[0],y:c[1],k:kind,vx:dx*1.7+Math.cos(ang)*.9,vy:dy*1.3+Math.sin(ang)*.9,d:Math.random()*.22})}var i;for(i=0;i<=this.logoStep&&i<D.path.length;i++)add(D.path[i],D.pathKind[i]);if(D.fill){var fshown=D.fillCount[Math.min(this.logoStep,D.path.length)];for(i=0;i<fshown;i++)add(D.fill[i],D.fillKind[i])}for(i=0;i<this.solid.length;i++)add(this.solid[i],this.solid[i][2]);this.dissolveT0=now,this.logoPhase="out"},BullittGrid.prototype.paintDissolve=function(now){var ctx=this.ctx,S=CELL,t=(now-this.dissolveT0)/this.cfg.logoOutMs;ctx.clearRect(0,0,this.canvas.width,this.canvas.height);for(var LINE=this.cfg.logoLine,ACCENT=this.cfg.logoAccent,spread=this.cfg.logoOutScatter,i=0;i<this.dissolve.length;i++){var f=this.dissolve[i],ft=(t-f.d)/(1-f.d);if(ft<=0&&(ft=0),!(ft>=1)){var e=ft*ft;ctx.globalAlpha=1-ft,ctx.fillStyle=f.k===1?ACCENT:LINE,ctx.fillRect(Math.round((f.x+this.camX)*S+f.vx*spread*S*e),Math.round((f.y+this.camY)*S+f.vy*spread*S*e),S,S)}}return ctx.globalAlpha=1,this.gctx&&(this.gctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.gctx.drawImage(this.canvas,0,0)),t>=1},BullittGrid.prototype.logoCam=function(){var D=window.LVH_LOGO;if(!this.logoFits){var want=Math.round(this.cols*.35)-this.logoX();this.camX=Math.max(Math.min(want,0),this.cols-D.cols)}},BullittGrid.prototype.logoX=function(){var D=window.LVH_LOGO;return D.path[Math.min(this.logoStep,D.path.length-1)][0]},BullittGrid.prototype.stepLogo=function(now){var D=window.LVH_LOGO;if(this.logoStep++,this.logoStep>=D.path.length){this.logoStep=D.path.length-1,this.logoDone=!0,this.logoDoneAt=now;return}for(var target=D.revealCount[this.logoStep];this.decoAt<target;){var cell=D.deco[this.decoAt++];if(!(cell[2]===1&&!this.cfg.logoAccentOn)){for(var parts=[],i=0;i<this.cfg.logoParts;i++){var ang=Math.random()*Math.PI*2,dist=(.4+Math.random()*.6)*this.cfg.logoScatter;parts.push({ox:Math.cos(ang)*dist,oy:Math.sin(ang)*dist*.6,d:Math.random()*.35})}this.spawns.push({x:cell[0],y:cell[1],k:cell[2]||0,t0:now,parts:parts})}}},BullittGrid.prototype.paintLogo=function(now){var D=window.LVH_LOGO,ctx=this.ctx,S=CELL;this.logoCam(),ctx.clearRect(0,0,this.canvas.width,this.canvas.height);var LINE=this.cfg.logoLine,ACCENT=this.cfg.logoAccent,RIDDEN=this.cfg.logoRidden||LINE,i,c;for(i=0;i<=this.logoStep;i++){c=D.path[i];var pk=D.pathKind?D.pathKind[i]:0;ctx.fillStyle=pk===1?ACCENT:RIDDEN,ctx.fillRect((c[0]+this.camX)*S,(c[1]+this.camY)*S,S,S)}if(D.fill){var fshown=D.fillCount[Math.min(this.logoStep,D.path.length)];for(i=0;i<fshown;i++)c=D.fill[i],ctx.fillStyle=D.fillKind[i]===1?ACCENT:LINE,ctx.fillRect((c[0]+this.camX)*S,(c[1]+this.camY)*S,S,S)}for(i=0;i<this.solid.length;i++)c=this.solid[i],ctx.fillStyle=c[2]===1?ACCENT:LINE,ctx.fillRect((c[0]+this.camX)*S,(c[1]+this.camY)*S,S,S);var dur=this.cfg.logoSpawnMs,frag=Math.max(1,Math.round(S/2));for(i=this.spawns.length-1;i>=0;i--){var sp=this.spawns[i],age=(now-sp.t0)/dur;if(age>=1){this.solid.push([sp.x,sp.y,sp.k]),this.spawns.splice(i,1);continue}for(var bx=(sp.x+this.camX)*S,by=(sp.y+this.camY)*S,fragCol=sp.k===1?ACCENT:LINE,p=0;p<sp.parts.length;p++){var q=sp.parts[p],t=(age-q.d)/(1-q.d);if(!(t<=0)){t=t>1?1:t;var e=1-Math.pow(1-t,3);ctx.globalAlpha=.35+.65*e,ctx.fillStyle=fragCol,ctx.fillRect(Math.round(bx+q.ox*S*(1-e)),Math.round(by+q.oy*S*(1-e)),frag,frag)}}ctx.globalAlpha=1}c=D.path[this.logoStep],ctx.fillStyle=this.cfg.playerColor,ctx.fillRect((c[0]+this.camX)*S,(c[1]+this.camY)*S,S,S),this.gctx&&(this.gctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.gctx.drawImage(this.canvas,0,0))},BullittGrid.prototype.clearIdleTimer=function(){this._idle&&(clearTimeout(this._idle),this._idle=null)},BullittGrid.prototype.armIdleTimer=function(){var self=this;this.clearIdleTimer(),!(!this.cfg.attract||!window.LVH_LOGO||!this.cfg.idleReturnMs)&&(this._idle=setTimeout(function(){self.mode==="playing"||self.mode==="countdown"||self.startLogo()},this.cfg.idleReturnMs))},BullittGrid.prototype.startTutorial=function(page,returnTo){this.tutReturn=returnTo||null,this.mode="tutorial",this.tutPage=page||0,this.root.classList.add("is-tutorial"),this.tutorialEl&&(this.tutorialEl.hidden=!1),this.paintTutorial(),this.stop()},BullittGrid.prototype.paintTutorial=function(){if(this.tutorialEl){var pages=this.tutorialEl.querySelectorAll("[data-lvh-page]"),dots=this.tutorialEl.querySelectorAll("[data-lvh-dots] i"),i;for(i=0;i<pages.length;i++)pages[i].hidden=i!==this.tutPage;for(i=0;i<dots.length;i++)dots[i].className=i===this.tutPage?"on":"";this.tutPages=pages.length}},BullittGrid.prototype.goTutorial=function(page){if(this.mode==="tutorial"){var last=(this.tutPages||2)-1;this.tutPage=Math.max(0,Math.min(last,page)),this.paintTutorial()}},BullittGrid.prototype.endTutorial=function(){if(this.mode==="tutorial"){if(this.root.classList.remove("is-tutorial"),this.tutorialEl&&(this.tutorialEl.hidden=!0),this.tutorialSeen=!0,this.tutReturn==="playing"){this.tutReturn=null,this.mode="countdown",this.countdown=3,this.showCount("3"),this.acc=0,this.last=0,this.run();return}if(this.tutReturn==="logo"){this.tutReturn=null,this.startLogo();return}this.tutReturn=null,this.startRound(!0)}},BullittGrid.prototype.toggleTutorial=function(){if(this.mode==="tutorial"){this.endTutorial();return}if(!(this.mode==="crit"||this.mode==="rewind")){var back=this.mode==="playing"||this.mode==="countdown"?"playing":this.mode==="logo"||this.mode==="attract"?"logo":null;this.startTutorial(0,back)}},BullittGrid.prototype.newRun=function(fromStart){if(!this.idleOnly){if(this.clearIdleTimer(),this.pickups=[],this.phaseLeft=0,this.boostLeft=0,this.aiPhaseLeft=0,this.aiBo
1ostLeft=0,this.held=null,this.paintHeld(),this.critZone=this.cfg.critZone,this.critTries=0,this.root.classList.remove("is-logo","is-over"),this.streak=0,this.level=0,this.setStatus(""),this.newBestEl&&(this.newBestEl.hidden=!0),this.overCard&&(this.overCard.hidden=!0),fromStart&&this.cfg.tutorialOn){this.startTutorial(0);return}this.startRound(!0)}},BullittGrid.prototype.abandonRun=function(){this.showCount(""),this.streak=0,this.level=0,this.cfg.attract&&window.LVH_LOGO?this.startLogo():this.cfg.attract?this.startRound(!1):(this.mode="idle",this.stop(),this.root.classList.remove("is-playing","is-running","is-over")),this.paintHud()},BullittGrid.prototype.tuneLevel=function(){var lvl=this.level;this.stepMs=Math.max(this.cfg.rampFloor,Math.round(this.cfg.stepMs-this.cfg.rampSpeed*Math.pow(lvl,this.cfg.rampCurve))),this.oppMistake=Math.max(.03,this.cfg.aiMistake*Math.pow(this.cfg.rampSharp,lvl)),this.oppSight=Math.min(400,Math.round(this.cfg.aiSight*Math.pow(this.cfg.aiSightRamp,lvl)))},BullittGrid.prototype.startRound=function(human){this.booted||(this.buildField(),this.booted=!0),this.tuneLevel(),this.grid.fill(0),this.ctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.gctx&&this.gctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.p1=new Rider(this.cfg.playerColor,human,this.cfg.aiMistake,400),this.p2=new Rider(this.cfg.aiColor,!1,human?this.oppMistake:this.cfg.aiMistake,human?this.oppSight:400),this.p1.x=Math.round(this.cols*.22),this.p1.y=Math.round(this.rows*.35),this.p1.dir="right",this.p2.x=Math.round(this.cols*.78),this.p2.y=Math.round(this.rows*.65),this.p2.dir="left",this.occupy(this.p1,1),this.occupy(this.p2,2),this.seed=this.pendingSeed!=null?this.pendingSeed:Math.random()*2147483647|0,this.pendingSeed=null,this.rng=mulberry32(this.seed),this.inputLog=[],this._chain===void 0&&(this._chain=2166138321,this._shadowStreak=0,this._shadowLevel=0),this._fold(this.seed),this.steps=0,this.maxSteps=Math.round(this.cfg.maxSeconds*1e3/this.stepMs),this.pickups=[],this.phaseLeft=0,this.boostLeft=0,this.aiPhaseLeft=0,this.aiBoostLeft=0,this.aiAcc=0,this.curInterval=this.stepMs,this.fx&&this.fx.clearRect(0,0,this.fxCanvas.width,this.fxCanvas.height),this.root.classList.add("is-ready","is-running"),this.root.classList.remove("is-over"),this.root.classList.toggle("is-playing",!!human),this.root.classList.toggle("is-attract",!human),this.overCard&&(this.overCard.hidden=!0),this.poster&&this.poster.classList.add("is-hidden"),human?(this.mode="countdown",this.countdown=this.streak===0?3:1,this.showCount(String(this.countdown))):(this.mode="attract",this.showCount("")),this.acc=0,this.last=0,this.paintHud(),this.paint(),this.run()},BullittGrid.prototype.endRound=function(result){this.lastOutcome=result;var self=this;if(this.stop(),!this.p1.isHuman){this.mode="over",setTimeout(function(){self.mode==="over"&&self.startRound(!1)},1400);return}if(result==="draw"){this.mode="over",this.showCount("REMATCH"),setTimeout(function(){self.mode==="over"&&(self.showCount(""),self.startRound(!0))},900);return}if(result==="win"){this.streak++,this.level++,this._shadowStreak++,this._shadowLevel++,this._fold(5709472^this.steps),this.mode="over",this.paintHud(),this.showCount(this.streak+" IN A ROW"),setTimeout(function(){self.mode==="over"&&(self.showCount(""),self.startRound(!0))},1100);return}if(result==="lose"&&this.cfg.critOn&&this.p1.trail.length>4&&!this.critExhausted()){this.startCritSave(result);return}this.mode="over",this.root.classList.remove("is-playing"),this.root.classList.add("is-over"),this.endRun(result)},BullittGrid.prototype.endRun=function(result){var isBest=this.streak>this.best&&this.streak>0;isBest&&(this.best=this.streak,this.writeBest(this.best)),this.paintBest(),this.setStatus(""),this.overCard&&(this.overTitle.textContent=isBest?"NEW PERSONAL BEST":this.streak>0?"STREAK OVER":"WIPEOUT",this.overBody.textContent=this.streak===0?"The grid got you on round one.":this.streak+(this.streak===1?" win":" wins")+" in a row.",this.reward&&(this.reward.hidden=!(this.streak>0)),this.newBestEl&&(this.newBestEl.hidden=!isBest),this.shareBtn&&(this.shareBtn.hidden=this.streak<1),this.saveBtn&&(this.saveBtn.hidden=this.streak<1),this.overCard.hidden=!1,this.retryBtn&&this.retryBtn.focus()),this.armIdleTimer()},BullittGrid.prototype.paintBest=function(){this.bestEl&&(this.bestEl.textContent=this.best)};function bestDigest(v){for(var h=2166138321,str="lvh:"+v+":bullitt",i=0;i<str.length;i++)h^=str.charCodeAt(i),h=Math.imul(h,16777619)>>>0;return h.toString(36)}BullittGrid.prototype.readBest=function(){try{var raw=window.localStorage.getItem(STORE_KEY);if(!raw)return 0;var parts=String(raw).split("."),v=parseInt(parts[0],10)||0;return parts.length!==2||parts[1]!==bestDigest(v)?0:v}catch(e){return 0}},BullittGrid.prototype.writeBest=function(v){try{window.localStorage.setItem(STORE_KEY,v+"."+bestDigest(v))}catch(e){}},BullittGrid.prototype.setStatus=function(msg){this.statusEl&&(this.statusEl.textContent=msg)},BullittGrid.prototype.buildShareCanvas=function(){var S=1080,c=document.createElement("canvas");c.width=S,c.height=S;var x=c.getContext("2d");x.fillStyle=this.cfg.bgColor,x.fillRect(0,0,S,S),x.strokeStyle=this.cfg.gridColor,x.lineWidth=2;for(var i=0;i<=S;i+=60)x.beginPath(),x.moveTo(i+.5,0),x.lineTo(i+.5,S),x.stroke(),x.beginPath(),x.moveTo(0,i+.5),x.lineTo(S,i+.5),x.stroke();x.imageSmoothingEnabled=!1;var gw=this.canvas.width,gh=this.canvas.height,scale=Math.max(1,Math.floor(Math.min((S-120)/gw,S*.34/gh))),dw=gw*scale,dh=gh*scale,dx=Math.round((S-dw)/2),dy=Math.round(S*.52);x.globalAlpha=.9,x.drawImage(this.canvas,dx,dy,dw,dh),x.globalAlpha=1,x.textAlign="center";var sans='ui-sans-serif, system-ui, -apple-system, "Helvetica Neue", Arial, sans-serif';return x.fillStyle=this.cfg.playerColor,x.font="600 30px "+sans,x.fillText(this.cfg.shareTitle.toUpperCase(),S/2,120),x.fillStyle="#ffffff",x.font="800 260px "+sans,x.fillText(String(this.streak),S/2,380),x.font="700 38px "+sans,x.fillText(this.cfg.shareText.toUpperCase(),S/2,445),x.fillStyle=this.cfg.playerColor,x.font="700 34px "+sans,x.fillText(this.cfg.shareTag,S/2,S-92),x.fillStyle="rgba(255,255,255,.55)",x.font="500 26px "+sans,x.fillText(this.cfg.shareSite,S/2,S-48),c},BullittGrid.prototype.cardBlob=function(){var c=this.buildShareCanvas();return new Promise(function(resolve,reject){if(!c.toBlob){reject(new Error("unsupported"));return}c.toBlob(function(b){b?resolve(b):reject(new Error("empty"))},"image/jpeg",.92)})},BullittGrid.prototype.fileName=function(){return"miss-bullitt-"+this.streak+"-in-a-row.jpg"},BullittGrid.prototype.canDownload=function(){if(!("download"in document.createElement("a")))return!1;try{if(window.self!==window.top)return!1}catch(e){return!1}return!0},BullittGrid.prototype.coarse=function(){return!!(window.matchMedia&&window.matchMedia("(pointer: coarse)").matches)},BullittGrid.prototype.showCardInline=function(dataUrl){var panel=this.overCard&&this.overCard.querySelector(".lvhg-panel");
1if(!panel||!dataUrl)return!1;var old=panel.querySelector("[data-lvh-cardimg]");old&&old.parentNode&&old.parentNode.removeChild(old);var img=document.createElement("img");return img.setAttribute("data-lvh-cardimg",""),img.src=dataUrl,img.alt="Your score card",img.style.cssText="display:block;width:100%;max-width:300px;margin:14px auto 0;image-rendering:pixelated;border:0;",panel.appendChild(img),this.setStatus(this.coarse()?"Long-press the card to save it, then tag us.":"Right-click the card to save it, then tag us."),!0},BullittGrid.prototype.saveCard=function(){var self=this;this.setStatus("Building your card\u2026");var canvas,shown=!1;try{canvas=this.buildShareCanvas(),shown=this.showCardInline(canvas.toDataURL("image/jpeg",.92))}catch(e){}if(!this.canDownload()){shown||this.setStatus("Could not build the image on this browser.");return}if(!canvas||!canvas.toBlob){shown||this.setStatus("Could not build the image on this browser.");return}canvas.toBlob(function(blob){if(!blob){shown||self.setStatus("Could not build the image.");return}try{var url=URL.createObjectURL(blob),el=document.createElement("a");el.href=url,el.download=self.fileName(),el.rel="noopener",document.body.appendChild(el),el.click(),document.body.removeChild(el),setTimeout(function(){URL.revokeObjectURL(url)},4e3),self.setStatus("Saved. Tag us when you post it.")}catch(e){shown||self.setStatus("Could not save on this browser.")}},"image/jpeg",.92)},BullittGrid.prototype.shareCard=function(){var self=this;this.setStatus("Building your card\u2026"),this.cardBlob().then(function(blob){var file=null;try{file=new File([blob],self.fileName(),{type:"image/jpeg"})}catch(e){}var payload={title:self.cfg.shareTitle,text:self.streak+" "+self.cfg.shareText+" "+self.cfg.shareTag};if(file&&(payload.files=[file]),navigator.share&&(!file||!navigator.canShare||navigator.canShare({files:[file]})))return navigator.share(payload).then(function(){self.setStatus("Shared. Thanks for tagging us.")}).catch(function(err){!err||err.name!=="AbortError"?self.saveCard():self.setStatus("")});self.saveCard()}).catch(function(){self.setStatus("Could not build the image on this browser.")})},BullittGrid.prototype.run=function(){var self=this;if(!this.raf){var tick=function(ts){if(self.raf=requestAnimationFrame(tick),self.mode==="logo"){if(!self.last){self.last=ts;return}var ld=ts-self.last;if(self.last=ts,ld>400)return;if(self.logoPhase==="out"){self.paintDissolve(ts)&&self.startLogo();return}if(self.logoDone){ts-self.logoDoneAt>=self.cfg.logoHoldMs?self.beginDissolve(ts):self.paintLogo(ts);return}for(self.logoAcc+=ld;self.logoAcc>=self.cfg.logoStepMs&&!self.logoDone;)self.logoAcc-=self.cfg.logoStepMs,self.stepLogo(ts);self.paintLogo(ts);return}if(self.mode==="crit"){self.critExpired(ts)&&(self.critLocked=-1,self.critResolve(!1)),self.paintFx(ts);return}if(self.mode==="rewind"){for(var prog=(ts-self.rewindT0)/(self.rewindMs||self.cfg.critRewindMs),want=Math.min(self.rewindFrom,Math.floor(prog*self.rewindFrom));self.rewindDone<want;)self.stepRewind();self.gctx&&(self.gctx.clearRect(0,0,self.canvas.width,self.canvas.height),self.gctx.drawImage(self.canvas,0,0)),self.paintFx(ts),prog>=1&&!(self.rewindFx&&self.rewindFx.length)&&self.finishRewind();return}if(!(self.mode!=="attract"&&self.mode!=="playing"&&self.mode!=="countdown")){if(!self.last){self.last=ts;return}var dt=ts-self.last;if(self.last=ts,dt>400){self.acc=0;return}self.acc+=dt;var interval=self.mode==="countdown"?700:self.boostLeft>0?self.stepMs*self.cfg.boostScale:self.stepMs;for(self.curInterval=interval;self.acc>=interval;)if(self.acc-=interval,self.mode==="countdown"?self.tickCountdown():self.step(),self.mode==="over"){self.acc=0;break}}};this.raf=requestAnimationFrame(tick)}},BullittGrid.prototype.stop=function(){this.raf&&cancelAnimationFrame(this.raf),this.raf=null,this.last=0},BullittGrid.prototype.tickCountdown=function(){if(this.countdown--,this.countdown>0){this.showCount(String(this.countdown));return}this.showCount("RIDE");var self=this;this.mode="playing",setTimeout(function(){self.mode==="playing"&&self.showCount("")},400)},BullittGrid.prototype.showCount=function(txt){this.countEl&&(this.countEl.textContent=txt,this.countEl.hidden=!txt)},BullittGrid.prototype.paintHud=function(){this.streakEl&&(this.streakEl.textContent=this.streak),this.levelEl&&(this.levelEl.textContent=this.level+1)},BullittGrid.prototype.idx=function(x,y){return y*this.cols+x},BullittGrid.prototype.blocked=function(x,y){return x<0||y<0||x>=this.cols||y>=this.rows||this.grid[this.idx(x,y)]!==0},BullittGrid.prototype.occupy=function(r,mark){this.grid[this.idx(r.x,r.y)]=mark,r.trail.push([r.x,r.y])},BullittGrid.prototype._fold=function(v){var h=this._chain>>>0;h^=v>>>0,h=Math.imul(h,16777619)>>>0,this._chain=h},BullittGrid.prototype.verifyIntegrity=function(){return this.streak===this._shadowStreak&&this.level===this._shadowLevel},BullittGrid.prototype.rnd=function(){return this.rng?this.rng():Math.random()},BullittGrid.prototype.queueTurn=function(r,dir){!r||dir===OPP[r.dir]||dir===r.dir||(r.queued=dir,r.isHuman&&this.inputLog&&(this.inputLog.push([this.steps,dir]),this._fold(this.steps<<3^ORDER.indexOf(dir))))},BullittGrid.prototype.getReplay=function(){return{seed:this.seed,inputs:(this.inputLog||[]).slice(),steps:this.steps,streak:this.streak,level:this.level,chain:this._chain>>>0,critTries:this.critTries||0,critHits:this.critHits||0,critPerfect:this.critPerfect||0,tampered:!this.verifyIntegrity()}},BullittGrid.prototype.step=function(){var p1=this.p1,p2=this.p2;if(this.steps++,this.steps>this.maxSteps){this.endRound("draw");return}
1var aiInterval=this.aiBoostLeft>0?this.stepMs*this.cfg.boostScale:this.stepMs;this.aiAcc=(this.aiAcc||0)+(this.curInterval||this.stepMs);var p2moves=this.aiAcc>=aiInterval-.001;p2moves&&(this.aiAcc-=aiInterval),p1.isHuman?p1.queued&&(p1.dir=p1.queued,p1.queued=null):p1.dir=this.chooseAi(p1),p2moves&&(p2.dir=this.chooseAi(p2));var a=VEC[p1.dir],b=VEC[p2.dir],nax=p1.x+a[0],nay=p1.y+a[1],nbx=p2moves?p2.x+b[0]:p2.x,nby=p2moves?p2.y+b[1]:p2.y,phasing=p1.isHuman&&this.phaseLeft>0,aDead=phasing?nax<0||nay<0||nax>=this.cols||nay>=this.rows:this.blocked(nax,nay),aiPhasing=this.aiPhaseLeft>0,bDead=p2moves?aiPhasing?nbx<0||nby<0||nbx>=this.cols||nby>=this.rows:this.blocked(nbx,nby):!1,headOn=p2moves&&nax===nbx&&nay===nby;if(headOn||aDead&&bDead){this.endRound("draw");return}if(aDead){this.endRound("lose");return}if(bDead){this.endRound("win");return}p1.x=nax,p1.y=nay,this.occupy(p1,1),p2moves&&(p2.x=nbx,p2.y=nby,this.occupy(p2,2)),p1.isHuman&&(this.phaseLeft>0&&this.phaseLeft--,this.boostLeft>0&&this.boostLeft--,this.takePickup(nax,nay),this.cfg.phaseOn&&this.steps%this.cfg.phaseEvery===0&&this.spawnPickup()),p2moves&&(this.aiPhaseLeft>0&&this.aiPhaseLeft--,this.aiBoostLeft>0&&this.aiBoostLeft--,p1.isHuman&&this.cfg.aiUsesPowerups&&this.aiTakePickup(nbx,nby)),this.paint()},BullittGrid.prototype.aiTakePickup=function(x,y){for(var i=0;i<this.pickups.length;i++)for(var p=this.pickups[i],k=0;k<CROSS.length;k++)if(p.x+CROSS[k][0]===x&&p.y+CROSS[k][1]===y)return p.kind==="phase"?this.aiPhaseLeft=this.cfg.phaseSteps:this.aiBoostLeft=this.cfg.boostSteps,this.pickups.splice(i,1),!0;return!1},BullittGrid.prototype.chooseAi=function(r){for(var options=[r.dir,leftOf(r.dir),rightOf(r.dir)],cap=Math.min(r.sight||400,this.cols*this.rows),viable=[],best=null,bestScore=-1,bestSpace=0,hunting=r===this.p2&&this.p1&&this.p1.isHuman,goal=hunting?this.nearestPickup(r):null,cut=hunting?this.interceptPoint():null,blockW=hunting?this.cfg.aiBlock+this.cfg.aiBlockRamp*this.level:0,planW=hunting?Math.min(1,this.cfg.aiPlan+this.cfg.aiPlanRamp*this.level):1,i=0;i<options.length;i++){var d=options[i],v=VEC[d],nx=r.x+v[0],ny=r.y+v[1];if(!this.blocked(nx,ny)){var sp=this.openSpace(nx,ny,cap);viable.push({dir:d,space:sp,exits:this.exitsFrom(nx,ny),x:nx,y:ny}),sp>bestSpace&&(bestSpace=sp)}}if(!viable.length)return r.dir;var floor=Math.max(this.cfg.aiMinSpace,bestSpace*this.cfg.aiSafeFrac),safe=[];for(i=0;i<viable.length;i++)viable[i].exits>0&&viable[i].space>=floor&&safe.push(viable[i]);if(!safe.length){var room=viable[0];for(i=1;i<viable.length;i++)viable[i].space>room.space&&(room=viable[i]);return room.dir}for(bestScore=-1/0,i=0;i<safe.length;i++){var c=safe[i],sc=c.space/Math.max(1,cap)*20*planW+(c.dir===r.dir?6:0)+this.rnd()*4;goal&&(sc+=Math.max(0,22-(Math.abs(c.x-goal.x)+Math.abs(c.y-goal.y)))*this.cfg.aiSeek),cut&&blockW>0&&(sc-=(Math.abs(c.x-cut.x)+Math.abs(c.y-cut.y))*blockW*this.cfg.aiHuntGain),sc>bestScore&&(bestScore=sc,best=c.dir)}if(best||(best=safe[0].dir),safe.length>1&&this.rnd()<r.mistake){var alt=[];for(i=0;i<safe.length;i++)safe[i].dir!==best&&alt.push(safe[i].dir);alt.length&&(best=alt[Math.floor(this.rnd()*alt.length)])}return best},BullittGrid.prototype.exitsFrom=function(x,y){for(var n=0,k=0;k<4;k++){var v=VEC[ORDER[k]];this.blocked(x+v[0],y+v[1])||n++}return n},BullittGrid.prototype.nearestPickup=function(r){if(!this.pickups||!this.pickups.length)return null;for(var best=null,bd=1e9,i=0;i<this.pickups.length;i++){var p=this.pickups[i],d=Math.abs(p.x-r.x)+Math.abs(p.y-r.y);d<bd&&(bd=d,best=p)}return bd<=26?best:null},BullittGrid.prototype.interceptPoint=function(){var p=this.p1;if(!p)return null;var v=VEC[p.dir],lead=6;return{x:Math.max(0,Math.min(this.cols-1,p.x+v[0]*lead)),y:Math.max(0,Math.min(this.rows-1,p.y+v[1]*lead))}},BullittGrid.prototype.openSpace=function(x,y,cap){this._gen++,this._gen>65e3&&(this._stamp.fill(0),this._gen=1);var gen=this._gen,stack=[this.idx(x,y)];this._stamp[stack[0]]=gen;for(var n=0;stack.length&&n<cap;){var i=stack.pop();n++;for(var cx=i%this.cols,cy=(i-cx)/this.cols,k=0;k<4;k++){var v=VEC[ORDER[k]],ax=cx+v[0],ay=cy+v[1];if(!(ax<0||ay<0||ax>=this.cols||ay>=this.rows)){var ai=ay*this.cols+ax;this._stamp[ai]===gen||this.grid[ai]!==0||(this._stamp[ai]=gen,stack.push(ai))}}}return n},BullittGrid.prototype.paintFx=function(now){if(this.fx){var W=this.fxCanvas.width,H=this.fxCanvas.height,S=CELL;if(this.fx.clearRect(0,0,W,H),this.rewindFx&&this.rewindFx.length){for(var life=this.cfg.rewindFxMs,sp=this.cfg.rewindScatter,ri=this.rewindFx.length-1;ri>=0;ri--){var f=this.rewindFx[ri],ft=(now-f.born)/life;if(this.fx.fillStyle=f.col,ft<=0){this.fx.globalAlpha=1,this.fx.fillRect(f.x*S,f.y*S,S,S);continue}if(ft>=1){this.rewindFx.splice(ri,1);continue}var fe=ft*ft;this.fx.globalAlpha=1-ft,this.fx.fillRect(Math.round(f.x*S+f.vx*sp*S*fe),Math.round(f.y*S+f.vy*sp*S*fe),S,S)}this.fx.globalAlpha=1}var i,p;for(i=0;i<this.pickups.length;i++)p=this.pickups[i],this.fx.globalAlpha=.78+.22*Math.sin((now-p.born)/320),this.paintRing(p,S,now),this.fx.globalAlpha=1;if(this.phaseLeft>0&&this.p1){this.fx.fillStyle=this.cfg.phaseColor,this.fx.globalAlpha=.35+.4*Math.sin(now/90);var t=this.p1.trail,n=t.length;for(i=1;i<10&&n-i*2>=0;i++){var c=t[n-i*2];c&&this.fx.fillRect(c[0]*S+1,c[1]*S+1,S-2,S-2)}this.fx.globalAlpha=1}if(this.boostLeft>0&&this.p1){this.fx.fillStyle=this.cfg.boostColor;var bt=this.p1.trail,bn=bt.length;for(i=1;i<7&&bn-i>=0;i++){var bc=bt[bn-i];bc&&(this.fx.globalAlpha=.5*(1-i/7),this.fx.fillRect(bc[0]*S,bc[1]
1*S,S,S))}this.fx.globalAlpha=1}if(this.aiBoostLeft>0&&this.p2){this.fx.fillStyle=this.cfg.boostColor;var at=this.p2.trail,an=at.length;for(i=1;i<7&&an-i>=0;i++){var ac=at[an-i];ac&&(this.fx.globalAlpha=.4*(1-i/7),this.fx.fillRect(ac[0]*S,ac[1]*S,S,S))}this.fx.globalAlpha=1}if(this.aiPhaseLeft>0&&this.p2){this.fx.fillStyle=this.cfg.phaseColor,this.fx.globalAlpha=.3+.3*Math.sin(now/90);var pt=this.p2.trail,pn=pt.length;for(i=1;i<8&&pn-i*2>=0;i++){var pc=pt[pn-i*2];pc&&this.fx.fillRect(pc[0]*S+1,pc[1]*S+1,S-2,S-2)}this.fx.globalAlpha=1}this.mode==="crit"&&this.paintCritBar(now,W,H)}},BullittGrid.prototype.paintRing=function(p,S,now){var f=this.fx;f.fillStyle=p.kind==="boost"?this.cfg.boostColor:this.cfg.phaseColor;for(var k=0;k<CROSS.length;k++){var c=CROSS[k];f.fillRect((p.x+c[0])*S,(p.y+c[1])*S,S,S)}},BullittGrid.prototype.paintCritBar=function(now,W,H){var f=this.fx,bw=Math.round(W*.5),bh=Math.max(6,Math.round(H*.035)),bx=Math.round((W-bw)/2),by=Math.round(H*.58),pad=Math.max(8,Math.round(bh*.9)),e=Math.max(2,Math.round(bh*.22)),px=bx-pad,py=by-pad,pw=bw+pad*2,ph=bh+pad*2;f.fillStyle=this.cfg.playerColor,f.fillRect(px-e,py-e,pw+e*2,ph+e*2),f.fillStyle="#0b0b14",f.fillRect(px,py,pw,ph);var half=this.critZone/2,zx=Math.round(bx+(this.critCentre-half)*bw),zw=Math.max(2,Math.round(this.critZone*bw));f.fillStyle=this.cfg.playerColor,f.globalAlpha=.85,f.fillRect(zx,by,zw,bh),f.globalAlpha=1,f.fillStyle="rgba(255,255,255,.35)",f.fillRect(bx,by+Math.floor(bh/2)-1,bw,2);var pos=this.critLocked!==null?this.critLocked:this.critMarker(now),mx=Math.round(bx+pos*bw),hit=Math.abs(pos-this.critCentre)<=half;f.fillStyle=this.critLocked===null?"#ffffff":hit?this.cfg.phaseColor:"#ff4444",f.fillRect(mx-1,by-5,3,bh+10)},BullittGrid.prototype.paint=function(){this.paintRider(this.p1),this.paintRider(this.p2),this.fx&&this.paintFx(typeof performance!="undefined"?performance.now():Date.now()),this.gctx&&(this.gctx.clearRect(0,0,this.canvas.width,this.canvas.height),this.gctx.drawImage(this.canvas,0,0))},BullittGrid.prototype.paintRider=function(r){for(var ctx=this.ctx,t=r.trail,n=t.length,dim=mix(r.color,"#000000",this.cfg.trailDim),k=1;k<=3;k++){var c=t[n-1-k];c&&(ctx.fillStyle=dim,ctx.fillRect(c[0]*CELL,c[1]*CELL,CELL,CELL))}var body=t[n-2];body&&(ctx.fillStyle=r.color,ctx.fillRect(body[0]*CELL,body[1]*CELL,CELL,CELL));var head=t[n-1];head&&(ctx.fillStyle=r.light,ctx.fillRect(head[0]*CELL,head[1]*CELL,CELL,CELL))};function initAll(scope){(scope||document).querySelectorAll("[data-lvh-game]").forEach(function(el){el.__lvhGame||(el.__lvhGame=new BullittGrid(el))})}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",function(){initAll()}):initAll(),document.addEventListener("shopify:section:load",function(e){initAll(e.target)}),window.LvhPixelGame={init:initAll}})(); 2//# sourceMappingURL=/cdn/shop/t/52/assets/lvh-pixel-game.js.map?v=36932288549512991081786976417
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.