{
  "filename": "debug-menu.js",
  "code": "(()=>{const K=\"__silentAimTest\";if(window[K]){const S=window[K];if(S.chamsCleanup)S.chamsCleanup();if(S.practiceCleanup)S.practiceCleanup();if(S.privateCleanup)S.privateCleanup();if(S.caseCleanup)S.caseCleanup();if(S.keybindCleanup)S.keybindCleanup();if(S.triggerCleanup)S.triggerCleanup();if(S.worldCleanup)S.worldCleanup();game.fireBullet=S.orig;game.tick=S.originalTick;game.player.accelerate=S.originalAccelerate;if(S.originalUpdate)game.player.update=S.originalUpdate;if(S.originalSpread)game.weapons.spread=S.originalSpread;if(S.originalFire)game.weapons.fire=S.originalFire;cancelAnimationFrame(S.espLoop);cancelAnimationFrame(S.ammoLoop);if(S.autoFireTimer)clearInterval(S.autoFireTimer);document.removeEventListener(\"mousedown\",S.mouseDownHandler);document.removeEventListener(\"mouseup\",S.mouseUpHandler);if(S.guiKeyHandler)document.removeEventListener(\"keydown\",S.guiKeyHandler);document.getElementById(\"__botESP\")?.remove();document.getElementById(\"__botFOV\")?.remove();document.getElementById(\"__testGUI\")?.remove();document.getElementById(\"__hotkeysHUD\")?.remove();delete window[K];return}\n\nconst cfg={\n  esp:true,\n  aim:true,\n  trigger:false,\n  triggerFov:1,\n  triggerDelay:120,\n  triggerTeamCheck:true,\n  triggerVisibleOnly:true,\n  triggerVisibilityTolerance:0,\n  triggerMaxDistance:0,\n  triggerRegion:\"either\",\n  triggerShowFov:false,\n  triggerFovColor:\"#ef9e55\",\n  aimTeamCheck:true,\n  aimVisibleOnly:false,\n  aimMaxDistance:0,\n  aimMinHealth:0,\n  showAimFov:true,\n  aimFovColor:\"#8055ed\",\n  aimFovOpacity:0.65,\n  wallHit:true,\n  ammo:true,\n  weaponMods:true,\n  autoFire:true,\n  fireRate:true,\n  speed:true,\n  airMult:3,\n  autoBhop:false,\n  flight:false,\n  flightSpeed:8,\n  noRecoil:false,\n  noSpread:false,\n  fov:10,\n  fireMult:3,\n  speedMult:2,\n  hitRegion:\"chest\"\n};\n\nconst espCfg={style:\"corners\",names:true,healthBar:true,healthText:true,distance:true,team:\"enemies\",enemyColor:\"#ff5555\",allyColor:\"#8ed04c\",textColor:\"#eeeeee\",healthColor:\"#8ed04c\",dynamicHealth:true,thickness:2,opacity:1,fontSize:11,maxDistance:0};\nconst espHealthCaps=new WeakMap();\n\nconst wallDamage={\n  glock:{chest:22.94,head:93.07},\n  awp:{chest:113.04,head:459.20},\n  sg553:{chest:29.05,head:114.55},\n  ssg08:{chest:84.92,head:340.87},\n  ak47:{chest:35.05,head:138.99},\n  g3sg1:{chest:77.74,head:316.48},\n  mp5sd:{chest:24.03,head:94.18},\n  p90:{chest:19.99,head:87.16},\n  mac10:{chest:23.09,head:101.65},\n  deagle:{chest:46.53,head:182.96},\n  tec9:{chest:27.52,head:110.63},\n  dualies:{chest:23.62,head:101.95},\n  p250:{chest:35.70,head:144.07},\n  scar20:{chest:77.50,head:308.98},\n  m4a1s:{chest:35.51,head:127.61},\n  aug:{chest:27.24,head:111.32},\n  mp9:{chest:23.91,head:78.55},\n  fiveseven:{chest:30.52},\n  usps:{chest:33.79,head:131.71}\n};\n\nconst orig=game.fireBullet,\noriginalTick=game.tick,\noriginalAccelerate=game.player.accelerate,\noriginalUpdate=game.player.update,\noriginalSpread=game.weapons.spread,\noriginalFire=game.weapons.fire;\n\nconst root=document.createElement(\"div\");\nroot.id=\"__botESP\";\nObject.assign(root.style,{\n  position:\"fixed\",\n  inset:\"0\",\n  pointerEvents:\"none\",\n  zIndex:\"2147483647\"\n});\ndocument.body.appendChild(root);\n\nconst fov=document.createElement(\"div\");\nfov.id=\"__botFOV\";\nObject.assign(fov.style,{\n  position:\"fixed\",\n  border:\"2px solid rgba(255,255,255,.65)\",\n  borderRadius:\"50%\",\n  pointerEvents:\"none\",\n  boxSizing:\"border-box\",\n  zIndex:\"2147483646\",\n  display:\"none\"\n});\ndocument.body.appendChild(fov);\n\nconst boxes=new Map,ammoCaps={};\nconst V=game.camera.position.constructor;\nconst canvas=document.querySelector(\"canvas:not(#radar)\");\n\nfor(const[k,s]of Object.entries(game.weapons.states||{}))\n  if(s&&typeof s.ammo===\"number\"&&typeof s.reserve===\"number\")\n    ammoCaps[k]={ammo:s.ammo,reserve:s.reserve};\n\nfunction project(x,y,z,view=game.camera){\n  if(!canvas)return null;\n  const r=canvas.getBoundingClientRect();\n  const v=new V(x,y,z).project(view);\n\n  if(v.z<0||v.z>1)return null;\n\n  return{\n    x:r.left+(v.x*.5+.5)*r.width,\n    y:r.top+(-v.y*.5+.5)*r.height,\n    z:v.z\n  };\n}\n\nfunction target(){\n  const me=game.player;\n  if(!me||!canvas)return null;\n\n  const r=canvas.getBoundingClientRect();\n  const cx=r.left+r.width/2;\n  const cy=r.top+r.height/2;\n  const maxR=Math.tan(cfg.fov*Math.PI/180)*r.height*.5;\n\n  let best=null,bd=Infinity;\n\n  for(const x of game.allEntities()){\n    if(\n      !x||\n      x===me||\n      !x.alive||\n      (cfg.aimTeamCheck&&x.team===me.team)||\n      x.isPlayer\n    )continue;\n\n    const distance=Math.hypot(x.x-me.x,x.y-me.y,x.z-me.z);\n    if(cfg.aimMaxDistance>0&&distance>cfg.aimMaxDistance)continue;\n    if(cfg.aimMinHealth>0&&(!Number.isFinite(x.health)||x.health<cfg.aimMinHealth))continue;\n    const y=x._visY==null?x.y:x._visY;\n    const h=x.height||1.8;\n    const aimY=cfg.hitRegion===\"head\"?y+h*.85:y+h*.55;\n    if(cfg.aimVisibleOnly){\n      const origin=game.camera.position;\n      const dx=x.x-origin.x,dy=aimY-origin.y,dz=x.z-origin.z,len=Math.hypot(dx,dy,dz);\n      if(!game.physics?.raycast||len<=0)continue;\n      const hit=game.physics.raycast(origin.x,origin.y,origin.z,dx/len,dy/len,dz/len,len,0x2);\n      if(hit&&hit.t<len-.05)continue;\n    }\n    const p=project(x.x,aimY,x.z);\n\n    if(!p)continue;\n\n    const d=Math.hypot(p.x-cx,p.y-cy);\n\n    if(d<bd&&d<=maxR){\n      bd=d;\n\n      best={\n        entity:x,\n        x:x.x,\n        y:aimY,\n        z:x.z\n      };\n    }\n  }\n\n  return best;\n}\n\nfunction makeEspBox(){\n  const b=document.createElement(\"div\");\n  Object.assign(b.style,{position:\"fixed\",pointerEvents:\"none\",boxSizing:\"border-box\"});\n  const frame=document.createElement(\"div\");Object.assign(frame.style,{position:\"absolute\",inset:\"0\",boxSizing:\"border-box\"});\n  const corners=[];\n  for(let i=0;i<4;i++){\n    const c=document.createElement(\"div\");\n    Object.assign(c.style,{position:\"absolute\",width:\"28%\",height:\"20%\",boxSizing:\"border-box\"});\n    c.style[i<2?\"top\":\"bottom\"]=\"0\";c.style[i%2?\"right\":\"left\"]=\"0\";\n    frame.appendChild(c);corners.push(c);\n  }\n  const bar=document.createElement(\"div\"),fill=document.createElement(\"div\");\n  Object.assign(bar.style,{position:\"absolute\",right:\"calc(100% + 5px)\",bottom:\"0\",width:\"4px\",height:\"100%\",background:\"#111c\",boxShadow:\"0 0 0 1px #000b\"});\n  Object.assign(fill.style,{position:\"absolute\",bottom:\"0\",left:\"0\",width:\"100%\"});bar.appendChild(fill);\n  function label(){const e=document.createElement(\"div\");Object.assign(e.style,{position:\"absolute\",whiteSpace:\"nowrap\",textShadow:\"0 1px 2px #000,1px 0 2px #000\",fontFamily:\"Arial,sans-serif\",fontWeight:\"600\"});return e}\n  const name=label(),health=label(),distance=label();\n  Object.assign(name.style,{bottom:\"calc(100% + 5px)\",left:\"50%\",transform:\"translateX(-50%)\"});\n  Object.assign(health.style,{right:\"calc(100% + 13px)\",top:\"50%\",transform:\"translateY(-50%)\"});\n  Object.assign(distance.style,{top:\"calc(100% + 5px)\",left:\"50%\",transform:\"translateX(-50%)\"});\n  for(const e of [frame,bar,name,health,distance])b.appendChild(e);\n  b._esp={frame,corners,bar,fill,name,health,distance};return b;\n}\nfunction paintEspBox(b,info){\n  const e=b._esp,color=info.ally?espCfg.allyColor:espCfg.enemyColor;\n  b.style.opacity=String(espCfg.opacity);\n  e.frame.style.border=espCfg.style===\"full\"?espCfg.thickness+\"px solid \"+color:\"none\";\n  e.frame.style.display=espCfg.style===\"none\"?\"none\":\"block\";\n  e.corners.forEach((c,i)=>{\n    c.style.display=espCfg.style===\"corners\"?\"block\":\"none\";\n    c.style.border=\"0 solid \"+color;\n    c.style[i<2?\"borderTopWidth\":\"borderBottomWidth\"]=espCfg.thickness+\"px\";\n    c.style[i%2?\"borderRightWidth\":\"borderLeftWidth\"]=espCfg.thickness+\"px\";\n  });\n  const ratio=Math.max(0,Math.min(1,info.health/info.maxHealth));\n  e.bar.style.display=espCfg.healthBar?\"block\":\"none\";\n  e.fill.style.height=(ratio*100)+\"%\";\n  e.fill.style.background=espCfg.dynamicHealth?(ratio>.6?\"#8ed04c\":ratio>.3?\"#ffd05a\":\"#ff5555\"):espCfg.healthColor;\n  for(const label of [e.name,e.health,e.distance]){label.style.color=espCfg.textColor;label.style.fontSize=espCfg.fontSize+\"px\"}\n  e.name.style.display=espCfg.names?\"block\":\"none\";e.name.textContent=info.name;\n  e.health.style.display=espCfg.healthText?\"block\":\"none\";e.health.textContent=Math.round(info.health).toLocaleString()+\" HP\";\n  e.distance.style.display=espCfg.distance?\"block\":\"none\";e.distance.textContent=info.distance.toFixed(1)+\" m\";\n}\nfunction update(){\n  const me=game.player;\n  for(const b of boxes.values())b.style.display=\"none\";\n  if(!me||!canvas){fov.style.display=\"none\";return}\n  const r=canvas.getBoundingClientRect(),cx=r.left+r.width/2,cy=r.top+r.height/2;\n  const d=Math.tan(cfg.fov*Math.PI/180)*r.height;\n  fov.style.display=cfg.aim&&cfg.showAimFov?\"block\":\"none\";\n  fov.style.borderColor=cfg.aimFovColor;fov.style.opacity=String(cfg.aimFovOpacity);\n  Object.assign(fov.style,{left:(cx-d/2)+\"px\",top:(cy-d/2)+\"px\",width:d+\"px\",height:d+\"px\"});\n  if(!cfg.esp)return;\n  const seen=new Set();\n  for(const x of game.allEntities()){\n    if(!x||x===me||!x.alive||x.isPlayer)continue;\n    const ally=x.team===me.team;\n    if(espCfg.team===\"enemies\"&&ally||espCfg.team===\"allies\"&&!ally)continue;\n    const distance=Math.hypot(x.x-me.x,x.y-me.y,x.z-me.z);\n    if(espCfg.maxDistance>0&&distance>espCfg.maxDistance)continue;\n    const y=x._visY??x.y,h=x.height||1.8,top=project(x.x,y+h,x.z,window[K]?.worldViewCamera||game.camera),bottom=project(x.x,y,x.z,window[K]?.worldViewCamera||game.camera);\n    if(!top||!bottom||bottom.y<=top.y)continue;\n    const bh=bottom.y-top.y,bw=bh*.55;\n    if(top.x+bw/2<r.left||top.x-bw/2>r.right||bottom.y<r.top||top.y>r.bottom)continue;\n    let b=boxes.get(x);if(!b){b=makeEspBox();root.appendChild(b);boxes.set(x,b)}\n    Object.assign(b.style,{display:\"block\",left:(top.x-bw/2)+\"px\",top:top.y+\"px\",width:bw+\"px\",height:bh+\"px\"});\n    const health=Number.isFinite(x.health)?Math.max(0,x.health):0;\n    const maxHealth=Math.max(100,espHealthCaps.get(x)||0,Number.isFinite(x.maxHealth)?x.maxHealth:0,health);\n    espHealthCaps.set(x,maxHealth);\n    paintEspBox(b,{ally,name:String(x.name||\"Bot\"),health,maxHealth,distance});seen.add(x);\n  }\n  for(const [x,b]of boxes)if(!seen.has(x)){b.remove();boxes.delete(x)}\n}\n\nfunction ammoLoop(){\n  if(cfg.weaponMods&&cfg.ammo){\n    for(const[k,s]of Object.entries(game.weapons.states||{})){\n      if(!s)continue;\n\n      if(\n        !ammoCaps[k]&&\n        typeof s.ammo===\"number\"&&\n        typeof s.reserve===\"number\"\n      ){\n        ammoCaps[k]={\n          ammo:s.ammo,\n          reserve:s.reserve\n        };\n      }\n\n      const o=ammoCaps[k];\n\n      if(o){\n        s.ammo=o.ammo;\n        s.reserve=o.reserve;\n      }\n    }\n  }\n\n  if(window[K])\n    window[K].ammoLoop=requestAnimationFrame(ammoLoop);\n}\n\nconst loop=()=>{\n  update();\n\n  if(window[K])\n    window[K].espLoop=requestAnimationFrame(loop);\n};\n\nlet mouseHeld=false;\n\nconst mouseDownHandler=e=>{\n  if(e.button===0&&!e.__debugTrigger)mouseHeld=true;\n};\n\nconst mouseUpHandler=e=>{\n  if(e.button===0&&!e.__debugTrigger)mouseHeld=false;\n};\n\ndocument.addEventListener(\"mousedown\",mouseDownHandler);\ndocument.addEventListener(\"mouseup\",mouseUpHandler);\n\nlet autoFireTimer=setInterval(()=>{\n  if(!cfg.weaponMods||!cfg.autoFire||!mouseHeld||!window[K])return;\n\n  const c=document.querySelector(\"canvas:not(#radar)\");\n\n  if(c)c.dispatchEvent(\n    new MouseEvent(\"mousedown\",{\n      bubbles:true,\n      cancelable:true,\n      button:0,\n      buttons:1,\n      clientX:innerWidth/2,\n      clientY:innerHeight/2\n    })\n  );\n},25);\n\nwindow[K]={\n  orig,\n  originalTick,\n  originalAccelerate,\n  originalUpdate,\n  originalSpread,\n  originalFire,\n  autoFireTimer,\n  mouseDownHandler,\n  mouseUpHandler,\n  ammoLoop:requestAnimationFrame(ammoLoop),\n  espLoop:requestAnimationFrame(loop)\n};\n\ngame.fireBullet=function(e,t,n,r,i,a,o,s){\n  if(!cfg.aim||e!==game.player)\n    return orig.call(this,e,t,n,r,i,a,o,s);\n\n  const best=target();\n\n  if(!best)\n    return orig.call(this,e,t,n,r,i,a,o,s);\n\n  let dx=best.x-t;\n  let dy=best.y-n;\n  let dz=best.z-r;\n\n  const len=Math.hypot(dx,dy,dz);\n\n  if(len<=0)\n    return orig.call(this,e,t,n,r,i,a,o,s);\n\n  i=dx/len;\n  a=dy/len;\n  o=dz/len;\n\n  /*\n   * Check whether map geometry exists between the\n   * muzzle and selected bot.\n   */\n  let obstruction=null;\n\n  if(cfg.wallHit){\n    obstruction=game.physics.raycast(\n      t,n,r,\n      i,a,o,\n      len,\n      0x2\n    );\n  }\n\n  const blocked=\n    cfg.wallHit&&\n    obstruction&&\n    obstruction.t<len-.05;\n\n  /*\n   * Always run the real bullet first.\n   */\n  const result=orig.call(\n    this,\n    e,t,n,r,\n    i,a,o,s\n  );\n\n  /*\n   * Simulated penetrated chest hit.\n   */\n  if(\n    blocked&&\n    best.entity&&\n    best.entity.alive\n  ){\n    const weaponId=s?.id||game.weapons.current;\n    const dmg=wallDamage[weaponId]?.[cfg.hitRegion];\n\n    if(dmg!=null){\n      const headshot=cfg.hitRegion===\"head\";\n\n      game.dealDamage(\n        best.entity,\n        dmg,\n        game.player,\n        headshot,\n        s,\n        cfg.hitRegion,\n        0,\n        true\n      );\n\n      console.log(\"[wall test]\",{\n        weapon:weaponId,\n        material:obstruction.mat,\n        damage:dmg,\n        health:best.entity.health,\n        alive:best.entity.alive\n      });\n    }\n  }\n\n  return result;\n};\n\ngame.tick=function(...args){\n  const before=game.weapons.nextFire;\n  const result=originalTick.apply(this,args);\n\n  if(\n    cfg.weaponMods&&cfg.fireRate&&\n    game.weapons.nextFire>before\n  ){\n    const delay=\n      game.weapons.nextFire-game.time;\n\n    if(delay>0)\n      game.weapons.nextFire=\n        game.time+delay/cfg.fireMult;\n  }\n\n  return result;\n};\n\ngame.player.accelerate=function(h,g,maxSpeed,accel,dt){\n  if(!cfg.speed)return originalAccelerate.call(this,h,g,maxSpeed,accel,dt);\n  const air=!this.onGround;\n  const mult=air?cfg.airMult:cfg.speedMult;\n  return originalAccelerate.call(this,h,g,maxSpeed*mult,accel*mult,dt);\n};\n\n// Reuse the game's native input API for held-space bunny hopping.\ngame.player.update=function(dt,input){\n  const player=this;\n  let wrapped=input;\n  if(cfg.autoBhop&&!cfg.flight&&input){\n    wrapped=Object.create(input);\n    wrapped.wasPressedA=function(action){\n      if(action===\"jump\"&&input.downA(\"jump\"))return true;\n      return input.wasPressedA(action);\n    };\n  }\n  const oldY=player.y;\n  const result=originalUpdate.call(player,dt,wrapped);\n  if(cfg.flight&&player.alive&&!game.frozen){\n    const forward=+(input.downA(\"forward\")) - +(input.downA(\"back\"));\n    const side=+(input.downA(\"right\")) - +(input.downA(\"left\"));\n    const yaw=player.yaw;\n    let dx=-Math.sin(yaw)*forward+Math.cos(yaw)*side;\n    let dz=-Math.cos(yaw)*forward-Math.sin(yaw)*side;\n    const mag=Math.hypot(dx,dz)||1;\n    const rise=+(input.downA(\"jump\")) - +(input.downA(\"crouch\"));\n    player.vx=dx/mag*cfg.flightSpeed;\n    player.vz=dz/mag*cfg.flightSpeed;\n    player.vy=rise*cfg.flightSpeed;\n    player.y=oldY+rise*cfg.flightSpeed*Math.max(0,Math.min(dt,.05));\n    player.onGround=false;\n  }\n  return result;\n};\n\ngame.weapons.spread=function(...args){\n  return cfg.weaponMods&&cfg.noSpread?0:originalSpread.apply(this,args);\n};\ngame.weapons.fire=function(...args){\n  const result=originalFire.apply(this,args);\n  if(cfg.weaponMods&&cfg.noRecoil){\n    if(this.punch&&typeof this.punch===\"object\"){\n      for(const key of Object.keys(this.punch)){\n        if(key!==\"index\"&&key!==\"lastShot\"&&typeof this.punch[key]===\"number\")this.punch[key]=0;\n      }\n    }\n    for(const key of [\"punchP\",\"punchY\",\"sprayP\",\"sprayY\",\"shkP\",\"shkY\",\"shkR\",\"shkPV\",\"shkRV\"]){\n      if(typeof this[key]===\"number\")this[key]=0;\n    }\n  }\n  return result;\n};\n\nlet skinCatalog=[];\nconst SKIN_CATALOG_URL=window.__clutcherAssetBase?new URL(\"skins.json\",window.__clutcherAssetBase).href:\"https://clutcher-debug.pages.dev/skins.json\";\nasync function loadSkinCatalog(){\n  const status=document.querySelector(\"#__testGUI #invStatus\");\n  try{\n    if(!/^https:\\/\\//.test(SKIN_CATALOG_URL))throw Error(\"Set the Gist raw URL in the bookmarklet first.\");\n    if(status)status.textContent=\"Loading skin catalogue...\";\n    const response=await fetch(SKIN_CATALOG_URL,{mode:\"cors\",cache:\"no-cache\"});\n    if(!response.ok)throw Error(\"HTTP \"+response.status);\n    const items=await response.json();\n    if(!Array.isArray(items)||!items.every(x=>x&&typeof x.id===\"string\"&&typeof x.name===\"string\"&&Number.isFinite(x.wmin)&&Number.isFinite(x.wmax)))throw Error(\"Invalid skin catalogue\");\n    skinCatalog=items;\n    renderSkins();\n  }catch(err){\n    if(status)status.textContent=\"Catalogue unavailable: \"+err.message;\n    console.error(\"[Debug menu] skin catalogue:\",err);\n  }\n}\n\nconst ui=document.createElement(\"div\");\nui.id=\"__testGUI\";\n\nObject.assign(ui.style,{\n  position:\"fixed\",\n  top:\"45px\",\n  left:\"80px\",\n  width:\"520px\",\n  padding:\"14px\",\n  background:\"rgba(15,15,18,.96)\",\n  color:\"#fff\",\n  font:\"13px Arial,sans-serif\",\n  border:\"1px solid #555\",\n  borderRadius:\"8px\",\n  zIndex:\"2147483647\",\n  boxShadow:\"0 5px 25px rgba(0,0,0,.45)\",\n  userSelect:\"none\"\n});\n\nui.innerHTML=`\n  <div id=\"guiHead\" style=\"cursor:move;font-size:15px;font-weight:bold;margin-bottom:10px\">\n    <span class=\"debugBrand\">GH</span>\n  </div>\n  <div id=\"guiTabs\" style=\"display:flex;gap:6px;margin-bottom:10px\"></div>\n  <div id=\"combatTab\" style=\"column-count:2;column-gap:18px\"></div>\n  <div id=\"inventoryTab\" style=\"display:none\"></div>\n  <div id=\"movementTab\" style=\"display:none\"></div>\n  <div id=\"visualsTab\" style=\"display:none\"></div>\n  <div id=\"worldTab\" style=\"display:none\"></div>\n  <div id=\"casesTab\" style=\"display:none\"></div>\n  <div id=\"privateTab\" style=\"display:none\"></div>\n  <div id=\"settingsTab\" style=\"display:none\"></div>\n`;\n\ndocument.body.appendChild(ui);\n\nconst tabs=ui.querySelector(\"#guiTabs\");\nconst combatBody=ui.querySelector(\"#combatTab\");\nconst inventoryBody=ui.querySelector(\"#inventoryTab\");\nconst movementBody=ui.querySelector(\"#movementTab\");\nconst visualsBody=ui.querySelector(\"#visualsTab\");\nconst worldBody=ui.querySelector(\"#worldTab\");\nconst casesBody=ui.querySelector(\"#casesTab\");\nconst privateBody=ui.querySelector(\"#privateTab\");\nconst settingsBody=ui.querySelector(\"#settingsTab\");\n\nfunction tabButton(name,target){\n  const b=document.createElement(\"button\");\n  b.textContent=name;\n  Object.assign(b.style,{\n    flex:\"1\",\n    padding:\"6px\",\n    cursor:\"pointer\",\n    background:\"#25252b\",\n    color:\"#fff\",\n    border:\"1px solid #555\",\n    borderRadius:\"4px\"\n  });\n  b.onclick=()=>{\n    combatBody.style.display=target===\"combat\"?\"block\":\"none\";\n    inventoryBody.style.display=target===\"inventory\"?\"block\":\"none\";\n    movementBody.style.display=target===\"movement\"?\"block\":\"none\";\n    visualsBody.style.display=target===\"visuals\"?\"block\":\"none\";\n    worldBody.style.display=target===\"world\"?\"block\":\"none\";\n    casesBody.style.display=target===\"cases\"?\"block\":\"none\";\n    privateBody.style.display=target===\"private\"?\"block\":\"none\";\n    settingsBody.style.display=target===\"settings\"?\"block\":\"none\";\n  };\n  tabs.appendChild(b);\n}\ntabButton(\"Combat\",\"combat\");\ntabButton(\"Movement\",\"movement\");\ntabButton(\"Visuals\",\"visuals\");\ntabButton(\"World\",\"world\");\ntabButton(\"Inventory\",\"inventory\");\n\ntabButton(\"Cases\",\"cases\");\n\ntabButton(\"Private\",\"private\");\ntabButton(\"Settings\",\"settings\");\n\n// Compact per-toggle keybinds and persistent interface preferences.\nconst BIND_STORE=\"clutcher_debug_bindings_v2\";\nconst PREF_STORE=\"clutcher_debug_appearance_v1\";\nfunction readStored(key){try{return JSON.parse(localStorage.getItem(key)||\"null\")||{}}catch{return {}}}\nconst savedBinds=readStored(BIND_STORE);\nconst preferences=Object.assign({accent:\"#8055ed\",theme:\"dark\",showHotkeys:false,menuKey:\"Insert\",menuMode:\"toggle\"},readStored(PREF_STORE));\nif(!/^#[0-9a-f]{6}$/i.test(preferences.accent))preferences.accent=\"#8ed04c\";\nif(![\"dark\",\"light\"].includes(preferences.theme))preferences.theme=\"dark\";\npreferences.menuMode=\"toggle\"; // Menu visibility always toggles; migrate older preferences.\nif(typeof preferences.menuKey!==\"string\")preferences.menuKey=\"Insert\";\nconst bindItems=new Map();\nconst groupSections=new Map();\nfunction refreshGroups(){for(const [key,section] of groupSections)section.hidden=!cfg[key];}\nlet bindingCapture=null,activeBindPop=null;\nconst hotkeysHud=document.createElement(\"div\");hotkeysHud.id=\"__hotkeysHUD\";document.body.appendChild(hotkeysHud);\nfunction savePrefs(){try{localStorage.setItem(PREF_STORE,JSON.stringify(preferences))}catch{}}\nfunction saveBinds(){\n const record={};for(const [id,item]of bindItems)record[id]={key:item.key,mode:item.mode};\n try{localStorage.setItem(BIND_STORE,JSON.stringify(record))}catch{}\n}\nfunction keyName(code){if(!code)return \"None\";return code.startsWith(\"Key\")?code.slice(3):code.startsWith(\"Digit\")?code.slice(5):code.replace(/^Mouse/,\"M\").replace(/^Arrow/,\"\");}\nfunction makeHotkeyEntry(item){const row=document.createElement(\"div\");row.className=\"hk-row\";const name=document.createElement(\"span\");name.textContent=item.label;const key=document.createElement(\"span\");key.className=\"hk-key\";key.textContent=item.mode===\"always\"?\"Always\":keyName(item.key);row.append(name,key);return row}\nfunction renderHotkeys(){\n refreshGroups();\n hotkeysHud.style.display=preferences.showHotkeys?\"block\":\"none\";\n hotkeysHud.replaceChildren();if(!preferences.showHotkeys)return;\n const heading=document.createElement(\"div\");heading.className=\"hk-title\";heading.textContent=\"HOTKEYS\";hotkeysHud.appendChild(heading);\n let count=0;\n for(const item of bindItems.values()){\n  if(![\"cfg:aim\",\"cfg:weaponMods\",\"cfg:speed\",\"cfg:flight\",\"cfg:esp\",\"cfg:trigger\",\"world:third\"].includes(item.id))continue;\n  if(!item.get()||item.mode===\"hold\"&&!item.held)continue;\n  if(count++>=14)break;\n  hotkeysHud.appendChild(makeHotkeyEntry(item));\n }\n if(!count){const empty=document.createElement(\"div\");empty.className=\"hk-empty\";empty.textContent=\"No active features\";hotkeysHud.appendChild(empty)}\n}\nfunction updateBind(item){\n item.button.textContent=keyName(item.key);\n item.button.title=item.label+\" · \"+({always:\"Always On\",hold:\"Hold\",toggle:\"Toggle\"}[item.mode])+\" · click to edit\";\n if(item.mode===\"always\")item.set(true);\n if(item.mode===\"hold\")item.set(false);\n item.sync();renderHotkeys();saveBinds();\n}\nfunction hideBindPopup(){if(activeBindPop){activeBindPop.remove();activeBindPop=null}bindingCapture=null}\nfunction editBind(item){\n hideBindPopup();\n const pop=document.createElement(\"div\");pop.className=\"bind-popup\";\n const title=document.createElement(\"div\");title.className=\"bind-popup-title\";title.textContent=item.label;\n const capture=document.createElement(\"button\");capture.type=\"button\";capture.textContent=\"Key: \"+keyName(item.key);\n capture.onclick=()=>{bindingCapture={item,capture};capture.textContent=\"Press any key…\"};\n const mode=document.createElement(\"select\");\n for(const [value,label]of [[\"always\",\"Always On\"],[\"hold\",\"Hold\"],[\"toggle\",\"Toggle\"]]){const option=document.createElement(\"option\");option.value=value;option.textContent=label;mode.appendChild(option)}\n mode.value=item.mode;mode.onchange=()=>{item.mode=mode.value;updateBind(item)};\n const clear=document.createElement(\"button\");clear.type=\"button\";clear.textContent=\"Clear\";clear.onclick=()=>{item.key=\"\";updateBind(item);capture.textContent=\"Key: None\"};\n const close=document.createElement(\"button\");close.type=\"button\";close.textContent=\"Done\";close.onclick=hideBindPopup;\n const actions=document.createElement(\"div\");actions.className=\"bind-popup-actions\";actions.append(clear,close);\n const hint=document.createElement(\"small\");hint.textContent=\"Esc cancels recording · Backspace clears\";\n pop.append(title,capture,mode,actions,hint);document.body.appendChild(pop);\n const r=item.button.getBoundingClientRect();pop.style.left=Math.min(window.innerWidth-210,Math.max(8,r.right-188))+\"px\";pop.style.top=Math.min(window.innerHeight-190,Math.max(8,r.bottom+5))+\"px\";\n activeBindPop=pop;\n}\nfunction attachBind(container,label,id,get,set,sync){\n const old=savedBinds[id]||{};\n const item={id,label,key:typeof old.key===\"string\"?old.key:\"\",mode:[\"always\",\"hold\",\"toggle\"].includes(old.mode)?old.mode:\"toggle\",get,set,sync:sync||(()=>{}),held:false};\n const button=document.createElement(\"button\");button.type=\"button\";button.className=\"mini-bind\";button.onclick=e=>{e.preventDefault();e.stopPropagation();editBind(item)};\n item.button=button;container.appendChild(button);bindItems.set(id,item);\n // Avoid forcing off old unbound toggles; Hold and Always apply only after explicit configuration.\n if(old.mode===\"hold\")item.set(false);\n if(old.mode===\"always\")item.set(true);\n item.sync();button.textContent=keyName(item.key);button.title=label+\" · edit hotkey\";\n renderHotkeys();return item;\n}\nfunction applyAppearance(){\n ui.style.setProperty(\"--green\",preferences.accent);\n ui.dataset.theme=preferences.theme;\n hotkeysHud.style.setProperty(\"--hk-accent\",preferences.accent);\n hotkeysHud.dataset.theme=preferences.theme;\n\n renderHotkeys();savePrefs();\n}\nlet menuRestorePointerLock=false;\nfunction unlockMenuPointer(){\n  if(ui.style.display===\"none\")return;\n  if(game.input?.locked||document.pointerLockElement){\n    if(game.input?.unlock)game.input.unlock();\n    else document.exitPointerLock?.();\n  }\n  mouseHeld=false;\n}\nfunction menuVisible(value){\n  const wasOpen=ui.style.display!==\"none\";\n  if(value){\n    if(!wasOpen)menuRestorePointerLock=!!(game.input?.locked||document.pointerLockElement===canvas&&canvas);\n    ui.style.display=\"flex\";fitMenuToViewport();unlockMenuPointer();\n  }else{\n    endMenuDrag();ui.style.display=\"none\";hideBindPopup();\n    const restore=menuRestorePointerLock;menuRestorePointerLock=false;\n    if(restore&&game.state===\"playing\"&&document.hasFocus()){\n      try{const pending=game.input?.lock?game.input.lock():canvas?.requestPointerLock?.();pending?.catch?.(()=>{})}catch{}\n    }\n  }\n}\nfunction onHotkeyDown(e){\n if(bindingCapture){\n  e.preventDefault();e.stopImmediatePropagation();\n  const {item,capture}=bindingCapture;\n  if(e.code===\"Escape\"){bindingCapture=null;capture.textContent=capture===menuKeyButton?keyName(item.key):\"Key: \"+keyName(item.key);return}\n  item.key=e.code===\"Backspace\"?\"\":e.code;\n  bindingCapture=null;\n  if(capture===menuKeyButton){preferences.menuKey=item.key;capture.textContent=keyName(item.key);applyAppearance()}\n  else{capture.textContent=\"Key: \"+keyName(item.key);updateBind(item)}\n  return;\n }\n if(e.repeat||e.isComposing||e.target?.closest?.(\"input,textarea,select,[contenteditable=true]\"))return;\n if(preferences.menuKey&&e.code===preferences.menuKey){\n  e.preventDefault();e.stopImmediatePropagation();\n  menuVisible(ui.style.display===\"none\");\n  return;\n }\n for(const item of bindItems.values()){\n  if(!item.key||item.key!==e.code||item.mode===\"always\")continue;\n  e.preventDefault();e.stopImmediatePropagation();\n  if(item.mode===\"toggle\")item.set(!item.get());\n  if(item.mode===\"hold\"){item.held=true;item.set(true)}\n  item.sync();renderHotkeys();break;\n }\n}\nfunction onHotkeyUp(e){\n for(const item of bindItems.values()){\n  if(item.mode===\"hold\"&&item.key===e.code&&item.held){item.held=false;item.set(false);item.sync();renderHotkeys()}\n }\n}\nfunction resetHeld(){for(const item of bindItems.values())if(item.held){item.held=false;item.set(false);item.sync()}renderHotkeys()}\nfunction ignoreOutsidePopup(e){if(activeBindPop&&!activeBindPop.contains(e.target)&&!e.target.closest?.(\".mini-bind\"))hideBindPopup()}\ndocument.addEventListener(\"keydown\",onHotkeyDown,true);\ndocument.addEventListener(\"keyup\",onHotkeyUp,true);\ndocument.addEventListener(\"pointerdown\",ignoreOutsidePopup,true);\nwindow.addEventListener(\"blur\",resetHeld);\nwindow[K].keybindCleanup=()=>{\n document.removeEventListener(\"keydown\",onHotkeyDown,true);document.removeEventListener(\"keyup\",onHotkeyUp,true);\n document.removeEventListener(\"pointerdown\",ignoreOutsidePopup,true);window.removeEventListener(\"blur\",resetHeld);\n hideBindPopup();hotkeysHud.remove();\n};\n\n// Settings tab: menu key, mode, theme, accent color and floating hotkey overlay.\nfunction settingsLine(label,control){const row=document.createElement(\"div\");row.className=\"setting-line\";const text=document.createElement(\"span\");text.textContent=label;row.append(text,control);settingsBody.appendChild(row);return row}\nconst menuKeyButton=document.createElement(\"button\");menuKeyButton.type=\"button\";menuKeyButton.className=\"settings-key\";menuKeyButton.textContent=keyName(preferences.menuKey);\nmenuKeyButton.onclick=()=>{bindingCapture={item:{key:preferences.menuKey},capture:menuKeyButton};menuKeyButton.textContent=\"Press a key…\"};\nsettingsLine(\"Menu key\",menuKeyButton);\nconst accentPicker=document.createElement(\"input\");accentPicker.type=\"color\";accentPicker.value=preferences.accent;accentPicker.oninput=()=>{preferences.accent=accentPicker.value;applyAppearance()};settingsLine(\"Accent color\",accentPicker);\nconst themeSelect=document.createElement(\"select\");for(const [v,name]of [[\"dark\",\"Dark\"],[\"light\",\"Light\"]]){const opt=document.createElement(\"option\");opt.value=v;opt.textContent=name;themeSelect.appendChild(opt)}themeSelect.value=preferences.theme;themeSelect.onchange=()=>{preferences.theme=themeSelect.value;applyAppearance()};settingsLine(\"Theme\",themeSelect);\nconst hudSwitch=document.createElement(\"input\");hudSwitch.type=\"checkbox\";hudSwitch.checked=!!preferences.showHotkeys;hudSwitch.onchange=()=>{preferences.showHotkeys=hudSwitch.checked;applyAppearance()};settingsLine(\"Show hotkeys overlay\",hudSwitch);\nconst settingsHelp=document.createElement(\"p\");settingsHelp.className=\"settings-help\";settingsHelp.textContent=\"Click the small key beside a toggle to assign a shortcut and select Always On, Hold, or Toggle. Settings are saved in this browser.\";settingsBody.appendChild(settingsHelp);\napplyAppearance();\n\nconst privateOptions={enabled:false,timer:true,cash:true};\nconst privatePatches=[];\nlet privateController=null;\nfunction privateActive(){return privateOptions.enabled&&game.mode===\"defusal\"&&game._pending?.botCount===0}\nfunction holdPrivateValue(object,key,enabled,value){\n  const descriptor=Object.getOwnPropertyDescriptor(object,key);\n  if(descriptor&&!descriptor.configurable)return;\n  let stored=object[key];\n  const get=()=>enabled()?value(stored):stored;\n  const set=v=>{if(!enabled())stored=v};\n  Object.defineProperty(object,key,{configurable:true,enumerable:descriptor?.enumerable??true,get,set});\n  privatePatches.push(()=>{\n    if(Object.getOwnPropertyDescriptor(object,key)?.get!==get)return;\n    if(descriptor){Object.defineProperty(object,key,{...descriptor,...('value' in descriptor?{value:stored}:{})})}\n    else{delete object[key];object[key]=stored}\n  });\n}\nlet privatePlayer=null;\nfunction updatePrivateHooks(){\n  if(!privateActive())return;\n  if(game.player&&privatePlayer!==game.player){\n    privatePlayer=game.player;\n    holdPrivateValue(privatePlayer,\"money\",()=>privateActive()&&privateOptions.cash,()=>16000);\n  }\n  const ctl=game.modeCtl;\n  if(!ctl||privateController===ctl)return;\n  privateController=ctl;\n  holdPrivateValue(ctl,\"roundClock\",()=>privateActive()&&privateOptions.timer&&ctl.state===\"live\",v=>Number.isFinite(v)&&v>0?v:135);\n  const onKill=ctl.onKill,roundEnd=ctl.roundEnd;\n  if(typeof onKill===\"function\"&&typeof roundEnd===\"function\"){\n    let killDepth=0;\n    const killHook=function(...args){killDepth++;try{return onKill.apply(this,args)}finally{killDepth--}};\n    const endHook=function(...args){if(privateActive()&&killDepth)return;return roundEnd.apply(this,args)};\n    const killOwn=Object.getOwnPropertyDescriptor(ctl,\"onKill\"),endOwn=Object.getOwnPropertyDescriptor(ctl,\"roundEnd\");\n    ctl.onKill=killHook;ctl.roundEnd=endHook;\n    privatePatches.push(()=>{\n      if(ctl.onKill===killHook){if(killOwn)Object.defineProperty(ctl,\"onKill\",killOwn);else delete ctl.onKill}\n      if(ctl.roundEnd===endHook){if(endOwn)Object.defineProperty(ctl,\"roundEnd\",endOwn);else delete ctl.roundEnd}\n    });\n  }\n}\nconst privateTick=game.tick;\nconst privateTickHook=function(...args){updatePrivateHooks();return privateTick.apply(this,args)};\ngame.tick=privateTickHook;\nwindow[K].privateCleanup=()=>{\n  privateOptions.enabled=false;\n  for(const undo of privatePatches.reverse())undo();\n  if(game.tick===privateTickHook)game.tick=privateTick;\n};\nconst privateStatus=document.createElement(\"div\");\nprivateStatus.setAttribute(\"role\",\"status\");\nObject.assign(privateStatus.style,{margin:\"10px 0\",color:\"#bbb\"});\nprivateStatus.textContent=\"Uses the loaded map. Select your team after starting.\";\nconst startPrivate=document.createElement(\"button\");\nstartPrivate.textContent=\"Start Private Game\";\nObject.assign(startPrivate.style,{padding:\"8px\",width:\"100%\",cursor:\"pointer\"});\nstartPrivate.onclick=async()=>{\n  if(game._starting||game._joining){privateStatus.textContent=\"Please wait for the current join to finish.\";return}\n  const map=game.map?.id;\n  if(!map){privateStatus.textContent=\"Load your preferred map once using Play, then try again.\";return}\n  const difficulty=Number.isFinite(game._pending?.difficulty)?game._pending.difficulty:6;\n  startPrivate.disabled=true;\n  privateOptions.enabled=true;\n  privateStatus.textContent=\"Loading \"+map+\" with zero bots...\";\n  try{\n    const ready=await game.startGame(map,0,difficulty,\"defusal\");\n    if(ready===false){privateOptions.enabled=false;privateStatus.textContent=\"Private game did not start. Try again.\";return}\n    updatePrivateHooks();\n    privateStatus.textContent=\"Private game ready — select your team. Map: \"+map;\n  }catch(err){privateOptions.enabled=false;privateStatus.textContent=\"Unable to start: \"+err.message}\n  finally{startPrivate.disabled=false}\n};\nprivateBody.appendChild(startPrivate);\nfor(const [key,label] of [[\"timer\",\"Infinite round timer\"],[\"cash\",\"Infinite cash ($16,000)\"]]){\n  const row=document.createElement(\"label\");\n  Object.assign(row.style,{display:\"block\",margin:\"10px 0\"});\n  const input=document.createElement(\"input\");input.type=\"checkbox\";input.checked=privateOptions[key];\n  input.onchange=()=>{privateOptions[key]=input.checked;updatePrivateHooks();if(key===\"cash\"&&game.state===\"playing\")game.hud.updateMoney?.();renderHotkeys()};\n  row.appendChild(input);row.appendChild(document.createTextNode(\" \"+label));\n  privateBody.appendChild(row);\n}\nprivateBody.appendChild(privateStatus);\n\nconst practiceOptions={ai:false,health:1000000};\nconst practiceTargets=new Map();\nlet practiceClass=window.__practiceBotClass||null;\nfunction capturePracticeClass(){\n  const sample=game.botMgr?.bots?.find(b=>typeof b.spawn===\"function\"&&typeof b._updateCS2Body===\"function\");\n  if(sample){practiceClass=sample.constructor;window.__practiceBotClass=practiceClass}\n}\ncapturePracticeClass();\nfunction configurePracticeBot(bot,record){\n  if(practiceOptions.ai){\n    if(record.originalOwn)Object.defineProperty(bot,\"update\",record.originalOwn);\n    else delete bot.update;\n  }else{\n    const position={x:bot.x,y:bot.y,z:bot.z};\n    bot.update=function(dt){\n      if(!this.alive)return;\n      Object.assign(this,position);this._visY=position.y;\n      this.vx=this.vy=this.vz=0;\n      this._updateCS2Body(dt,this.game);\n    };\n    record.hook=bot.update;\n    bot.update(1/60);\n  }\n}\nconst practicePanel=document.createElement(\"section\");\npracticePanel.style.cssText=\"margin-top:18px;padding-top:12px;border-top:1px solid #444\";\nconst practiceHeading=document.createElement(\"h3\");practiceHeading.textContent=\"Bot Spawner\";\npracticeHeading.style.cssText=\"color:#8ed04c;font-size:11px;text-transform:uppercase;letter-spacing:1px\";\npracticePanel.appendChild(practiceHeading);\nconst spawnPractice=document.createElement(\"button\");spawnPractice.textContent=\"Spawn Opposing Bot\";\npracticePanel.appendChild(spawnPractice);\nconst practiceAiRow=document.createElement(\"label\");practiceAiRow.style.display=\"block\";\nconst practiceAi=document.createElement(\"input\");practiceAi.type=\"checkbox\";practiceAi.checked=false;\npracticeAiRow.appendChild(practiceAi);practiceAiRow.appendChild(document.createTextNode(\" Enable bot AI\"));\npracticePanel.appendChild(practiceAiRow);\nconst practiceHealthRow=document.createElement(\"label\");practiceHealthRow.style.display=\"block\";practiceHealthRow.textContent=\"Bot health \";\nconst practiceHealth=document.createElement(\"input\");practiceHealth.type=\"number\";practiceHealth.min=\"1\";practiceHealth.max=\"1000000000\";practiceHealth.step=\"1\";practiceHealth.value=\"1000000\";practiceHealth.style.width=\"140px\";\npracticeHealthRow.appendChild(practiceHealth);practicePanel.appendChild(practiceHealthRow);\nconst practiceStatus=document.createElement(\"div\");practiceStatus.setAttribute(\"role\",\"status\");practiceStatus.style.cssText=\"margin-top:8px;color:#bbb;font-size:11px\";\npracticeStatus.textContent=\"Spawns 3 metres ahead. Face clear ground. AI and health apply to spawned targets.\";\npracticePanel.appendChild(practiceStatus);privateBody.appendChild(practicePanel);\nfunction currentPracticeTargets(){\n  for(const [bot]of practiceTargets)if(!game.botMgr?.bots?.includes(bot))practiceTargets.delete(bot);\n  return practiceTargets;\n}\npracticeAi.onchange=()=>{\n  practiceOptions.ai=practiceAi.checked;\n  for(const [bot,record]of currentPracticeTargets())configurePracticeBot(bot,record);\n  practiceStatus.textContent=\"Bot AI \"+(practiceOptions.ai?\"enabled\":\"disabled\")+\".\";renderHotkeys();\n};\nfunction readPracticeHealth(){\n  const value=Number(practiceHealth.value);\n  if(!Number.isFinite(value)||value<1||value>1000000000){practiceStatus.textContent=\"Enter health from 1 to 1,000,000,000.\";return false}\n  practiceOptions.health=Math.round(value);practiceHealth.value=String(practiceOptions.health);return true;\n}\npracticeHealth.onchange=()=>{\n  if(!readPracticeHealth())return;\n  for(const [bot]of currentPracticeTargets())if(bot.alive)bot.health=practiceOptions.health;\n  practiceStatus.textContent=\"Target health set to \"+practiceOptions.health.toLocaleString()+\".\";\n};\nspawnPractice.onclick=()=>{\n  capturePracticeClass();\n  const mgr=game.botMgr,player=game.player;\n  if(game.state!==\"playing\"||!player?.alive||!mgr){practiceStatus.textContent=\"Join a game and select your team first.\";return}\n  if(!practiceClass){practiceStatus.textContent=\"Load a bot-filled game once, then return to Private without refreshing the page.\";return}\n  if(!readPracticeHealth())return;\n  let bot=null;\n  try{\n    bot=new practiceClass(game,player.team===\"CT\"?\"T\":\"CT\",\"Practice Target\",game._pending?.difficulty??6);\n    if(typeof bot._updateCS2Body!==\"function\")throw Error(\"Bot visual updater unavailable\");\n    mgr.bots.push(bot);bot.spawn();\n    bot.x=player.x-Math.sin(player.yaw)*3;bot.y=player.y;bot.z=player.z-Math.cos(player.yaw)*3;bot._visY=bot.y;\n    bot.vx=bot.vy=bot.vz=0;bot.health=practiceOptions.health;\n    const record={originalOwn:Object.getOwnPropertyDescriptor(bot,\"update\")};\n    practiceTargets.set(bot,record);configurePracticeBot(bot,record);\n    if(practiceOptions.ai)bot._updateCS2Body(1/60,game);\n    practiceStatus.textContent=\"Spawned opposing target — \"+practiceOptions.health.toLocaleString()+\" HP, AI \"+(practiceOptions.ai?\"on\":\"off\")+\".\";\n  }catch(err){\n    if(bot){const index=mgr.bots.indexOf(bot);if(index>=0)mgr.bots.splice(index,1);practiceTargets.delete(bot);for(const model of [bot.mesh,bot.shadow,bot.cs2Agent?.root])if(model)game.scene.remove(model)}\n    practiceStatus.textContent=\"Unable to spawn target: \"+err.message;\n  }\n};\nconst practiceTick=game.tick;\nconst practiceTickHook=function(...args){capturePracticeClass();return practiceTick.apply(this,args)};\ngame.tick=practiceTickHook;\nwindow[K].practiceCleanup=()=>{\n  if(game.tick===practiceTickHook)game.tick=practiceTick;\n  for(const [bot,record]of practiceTargets){\n    if(bot.update===record.hook){if(record.originalOwn)Object.defineProperty(bot,\"update\",record.originalOwn);else delete bot.update}\n  }\n  practiceTargets.clear();\n};\n\n\n\nconst caseRolls={gold:.999,covert:.994,classified:.97,restricted:.85,milspec:.4};\nconst caseLabels={gold:\"Gold\",covert:\"Covert\",classified:\"Classified\",restricted:\"Restricted\",milspec:\"Mil-Spec\"};\nlet armedCase=null;\nconst caseHud=game.hud;\nconst originalOpenCaseFlow=caseHud?.openCaseFlow;\nconst caseStatus=document.createElement(\"div\");\ncaseStatus.setAttribute(\"role\",\"status\");\ncaseStatus.setAttribute(\"aria-live\",\"polite\");\nObject.assign(caseStatus.style,{margin:\"10px 0\",color:\"#bbb\"});\nfunction updateCaseStatus(){\n  caseStatus.textContent=armedCase?\"Armed: \"+caseLabels[armedCase]+\" — next case opening only.\":\"Armed: none\";\n}\nconst caseButtons=document.createElement(\"div\");\nObject.assign(caseButtons.style,{display:\"flex\",flexWrap:\"wrap\",gap:\"6px\"});\nfor(const key of Object.keys(caseRolls)){\n  const button=document.createElement(\"button\");\n  button.textContent=caseLabels[key];\n  Object.assign(button.style,{padding:\"8px\",cursor:\"pointer\"});\n  button.disabled=typeof originalOpenCaseFlow!==\"function\";\n  button.onclick=()=>{armedCase=key;updateCaseStatus()};\n  caseButtons.appendChild(button);\n}\ncasesBody.appendChild(caseButtons);\ncasesBody.appendChild(caseStatus);\nconst cancelGuarantee=document.createElement(\"button\");\ncancelGuarantee.textContent=\"Cancel Guarantee\";\nObject.assign(cancelGuarantee.style,{padding:\"8px\",cursor:\"pointer\"});\ncancelGuarantee.onclick=()=>{armedCase=null;updateCaseStatus()};\ncasesBody.appendChild(cancelGuarantee);\nupdateCaseStatus();\nlet activeCaseRandom=null;\nlet savedCaseRandom=null;\nfunction restoreCaseRandom(){\n  if(activeCaseRandom&&Math.random===activeCaseRandom)Math.random=savedCaseRandom;\n  activeCaseRandom=null;\n  savedCaseRandom=null;\n}\nfunction caseOpenHook(...args){\n  if(armedCase===null)return originalOpenCaseFlow.apply(this,args);\n  const roll=caseRolls[armedCase];\n  armedCase=null;\n  updateCaseStatus();\n  const previousRandom=Math.random;\n  let firstRoll=true;\n  savedCaseRandom=previousRandom;\n  activeCaseRandom=function(){\n    if(firstRoll){firstRoll=false;return roll}\n    return previousRandom();\n  };\n  Math.random=activeCaseRandom;\n  try{return originalOpenCaseFlow.apply(this,args)}\n  finally{restoreCaseRandom()}\n}\nif(typeof originalOpenCaseFlow===\"function\")caseHud.openCaseFlow=caseOpenHook;\nelse caseStatus.textContent=\"Armed: none — case opening hook unavailable.\";\nwindow[K].caseCleanup=()=>{\n  armedCase=null;\n  restoreCaseRandom();\n  if(caseHud?.openCaseFlow===caseOpenHook)caseHud.openCaseFlow=originalOpenCaseFlow;\n};\n\n\nfunction row(name,key,body=combatBody){\n  const d=document.createElement(\"label\");\n  d.style.display=\"block\";\n  d.style.margin=\"7px 0\";\n  d.innerHTML=`<input type=\"checkbox\" ${cfg[key]?\"checked\":\"\"}> ${name}`;\n  const checkbox=d.querySelector(\"input\");checkbox.onchange=e=>{cfg[key]=e.target.checked;renderHotkeys()};\n  if([\"aim\",\"weaponMods\",\"speed\",\"flight\",\"trigger\"].includes(key))attachBind(d,name,\"cfg:\"+key,()=>cfg[key],v=>{cfg[key]=v;refreshGroups()},()=>{checkbox.checked=cfg[key]});\n  body.appendChild(d);\n}\n\nfunction slider(name,key,min,max,step,body=combatBody){\n  const d=document.createElement(\"div\");\n  d.style.margin=\"10px 0\";\n  d.innerHTML=`<div>${name}: <span>${cfg[key]}</span></div><input type=\"range\" min=\"${min}\" max=\"${max}\" step=\"${step}\" value=\"${cfg[key]}\" style=\"width:100%\">`;\n  const s=d.querySelector(\"input\"),v=d.querySelector(\"span\");\n  s.oninput=()=>{cfg[key]=Number(s.value);v.textContent=cfg[key]};\n  body.appendChild(d);\n}\n\ncombatBody.innerHTML='<div class=\"combatSections\"><section id=\"aimSection\"><h3>Aim</h3></section><section id=\"weaponSection\"><h3>Weapon</h3></section></div>';\nconst aimBody=combatBody.querySelector(\"#aimSection\");\nconst weaponBody=combatBody.querySelector(\"#weaponSection\");\n\nvisualsBody.innerHTML='<div class=\"espSettings\"><section class=\"espControls\"><h3>ESP</h3></section><section class=\"espPreviewPanel\"><h3>Live Preview</h3><div class=\"espPreviewStage\"></div><div class=\"espPreviewCaption\">Enemy · 75 / 100 HP · 12 m</div></section></div>';\nconst espBody=visualsBody.querySelector(\".espControls\");\nconst previewStage=visualsBody.querySelector(\".espPreviewStage\");\nconst previewBox=makeEspBox();Object.assign(previewBox.style,{position:\"absolute\",left:\"50%\",top:\"51px\",width:\"74px\",height:\"146px\",transform:\"translateX(-50%)\"});\npreviewStage.appendChild(previewBox);\nconst previewCaption=visualsBody.querySelector(\".espPreviewCaption\");\nfunction paintEspPreview(){\n  const ally=espCfg.team===\"allies\";\n  previewBox.style.display=cfg.esp?\"block\":\"none\";\n  paintEspBox(previewBox,{ally,name:\"Practice Target\",health:75,maxHealth:100,distance:12});\n  previewCaption.textContent=cfg.esp?(ally?\"Ally\":\"Enemy\")+\" · 75 / 100 HP · 12 m\":\"ESP disabled\";\n}\nfunction espToggle(label,key,object=espCfg){\n  const row=document.createElement(\"label\"),input=document.createElement(\"input\");\n  input.type=\"checkbox\";input.checked=object[key];\n  input.onchange=()=>{object[key]=input.checked;paintEspPreview();renderHotkeys()};\n  row.appendChild(input);row.appendChild(document.createTextNode(\" \"+label));\n  if(object===cfg&&key===\"esp\")attachBind(row,label,\"cfg:esp\",()=>cfg.esp,v=>{cfg.esp=v;paintEspPreview();refreshGroups()},()=>{input.checked=cfg.esp});espBody.appendChild(row);\n}\nfunction espSelect(label,key,options){\n  const row=document.createElement(\"label\");row.textContent=label;\n  const select=document.createElement(\"select\");select.style.cssText=\"display:block;width:100%;margin:4px 0 8px\";\n  for(const [value,text]of options){const option=document.createElement(\"option\");option.value=value;option.textContent=text;select.appendChild(option)}\n  select.value=espCfg[key];select.onchange=()=>{espCfg[key]=select.value;paintEspPreview()};row.appendChild(select);espBody.appendChild(row);\n}\nfunction espSlider(label,key,min,max,step){\n  const row=document.createElement(\"div\"),heading=document.createElement(\"div\"),value=document.createElement(\"span\"),input=document.createElement(\"input\");\n  row.style.margin=\"9px 0\";value.style.float=\"right\";heading.textContent=label;heading.appendChild(value);\n  input.type=\"range\";input.min=min;input.max=max;input.step=step;input.value=espCfg[key];input.style.width=\"100%\";\n  const paint=()=>{value.textContent=key===\"maxDistance\"&&espCfg[key]===0?\"Unlimited\":String(espCfg[key]);input.style.setProperty(\"--fill\",((espCfg[key]-min)/(max-min)*100)+\"%\")};\n  input.oninput=()=>{espCfg[key]=Number(input.value);paint();paintEspPreview()};paint();row.appendChild(heading);row.appendChild(input);espBody.appendChild(row);\n}\nfunction espColor(label,key){\n  const row=document.createElement(\"label\"),input=document.createElement(\"input\");\n  row.style.cssText=\"display:flex;justify-content:space-between;align-items:center\";row.textContent=label;\n  input.type=\"color\";input.value=espCfg[key];input.setAttribute(\"aria-label\",label);input.style.cssText=\"width:32px;height:21px;padding:0;border:1px solid #444;background:#1b1b1b;cursor:pointer\";\n  input.oninput=()=>{espCfg[key]=input.value;paintEspPreview()};row.appendChild(input);espBody.appendChild(row);\n}\nespToggle(\"Enable ESP\",\"esp\",cfg);\nespSelect(\"Show\", \"team\",[[\"enemies\",\"Enemies\"],[\"allies\",\"Allies\"],[\"all\",\"Both teams\"]]);\nespSelect(\"Box style\",\"style\",[[\"corners\",\"Corners\"],[\"full\",\"Full box\"],[\"none\",\"No box\"]]);\nespToggle(\"Names\",\"names\");espToggle(\"Health bar\",\"healthBar\");espToggle(\"Health text\",\"healthText\");espToggle(\"Distance\",\"distance\");\nespToggle(\"Health-based bar colors\",\"dynamicHealth\");\nespSlider(\"Line thickness\",\"thickness\",1,4,1);espSlider(\"Opacity\",\"opacity\",.2,1,.05);espSlider(\"Text size\",\"fontSize\",9,16,1);espSlider(\"Maximum distance (m)\",\"maxDistance\",0,200,5);\nespColor(\"Enemy color\",\"enemyColor\");espColor(\"Ally color\",\"allyColor\");espColor(\"Text color\",\"textColor\");espColor(\"Fixed health-bar color\",\"healthColor\");\npaintEspPreview();\n// ESP appearance controls collapse independently of the chams settings.\nconst espMaster=espBody.querySelector(\"input[type=checkbox]\").parentElement;\nconst espDetails=document.createElement(\"div\");espDetails.className=\"debug-collapse\";\nwhile(espMaster?.nextSibling)espDetails.appendChild(espMaster.nextSibling);\nespBody.appendChild(espDetails);groupSections.set(\"esp\",espDetails);refreshGroups();\n\nconst chamsCfg={enabled:false,throughWalls:true,team:\"enemies\",visibleColor:\"#44ff66\",hiddenColor:\"#ff3344\",opacity:1};\nconst chamsRecords=new Map(),chamsRoots=new Map();\nlet chamsManager=null,chamsOriginalCull=null,chamsCullHook=null,chamsOwnCull=null;\nfunction chamsTint(source,color,depthTest){\n  const material=source.clone();\n  material.color?.set(color);material.emissive?.set(color);\n  if(\"emissiveIntensity\"in material)material.emissiveIntensity=1;\n  material.depthTest=depthTest;material.depthWrite=false;material.transparent=true;\n  material.opacity=chamsCfg.opacity;material.toneMapped=false;material.needsUpdate=true;\n  return material;\n}\nfunction chamsMaterials(value){return Array.isArray(value)?value:[value]}\nfunction chamsMap(value,color,depth){return Array.isArray(value)?value.map(m=>chamsTint(m,color,depth)):chamsTint(value,color,depth)}\nfunction restoreChamsRecord(mesh,record){\n  if(mesh.material===record.hidden||mesh.material===record.visible)mesh.material=record.original.material;\n  mesh.renderOrder=record.original.renderOrder;mesh.frustumCulled=record.original.frustumCulled;\n  record.overlay.removeFromParent();\n  for(const material of [...chamsMaterials(record.hidden),...chamsMaterials(record.visible)])material.dispose();\n  chamsRecords.delete(mesh);\n}\nfunction clearChams(){\n  for(const [mesh,record]of chamsRecords)restoreChamsRecord(mesh,record);\n  for(const [root,visible]of chamsRoots)root.visible=visible;\n  chamsRoots.clear();\n}\nfunction applyChams(){\n  if(!chamsCfg.enabled){if(chamsRecords.size)clearChams();return}\n  const seen=new Set(),activeRoots=new Set();\n  for(const bot of game.botMgr?.bots||[]){\n    const root=bot.cs2Agent?.root,model=bot.cs2Agent?.model;\n    if(!root||!model||!bot.alive||game._specHidden===bot)continue;\n    const ally=bot.team===game.player?.team;\n    if(chamsCfg.team===\"enemies\"&&ally||chamsCfg.team===\"allies\"&&!ally)continue;\n    activeRoots.add(root);\n    if(!chamsRoots.has(root))chamsRoots.set(root,root.visible);\n    root.visible=true;\n    const meshes=[];model.traverse(mesh=>{if(mesh.isMesh&&!mesh.__debugChamsOverlay&&!mesh.__dualChamsOverlay&&mesh.material)meshes.push(mesh)});\n    for(const mesh of meshes){\n      seen.add(mesh);let record=chamsRecords.get(mesh);\n      if(!record){\n        const original={material:mesh.material,renderOrder:mesh.renderOrder,frustumCulled:mesh.frustumCulled};\n        const hidden=chamsMap(mesh.material,chamsCfg.hiddenColor,false),visible=chamsMap(mesh.material,chamsCfg.visibleColor,true);\n        const overlay=mesh.clone(false);overlay.__debugChamsOverlay=true;\n        overlay.material=visible;overlay.renderOrder=10001;overlay.frustumCulled=false;overlay.matrixAutoUpdate=false;overlay.castShadow=false;overlay.receiveShadow=false;\n        if(mesh.isSkinnedMesh){overlay.skeleton=mesh.skeleton;overlay.bindMatrix.copy(mesh.bindMatrix);overlay.bindMatrixInverse.copy(mesh.bindMatrixInverse)}\n        mesh.parent.add(overlay);record={original,hidden,visible,overlay};chamsRecords.set(mesh,record);\n      }\n      for(const [materials,color]of [[record.hidden,chamsCfg.hiddenColor],[record.visible,chamsCfg.visibleColor]]){\n        for(const material of chamsMaterials(materials)){material.color?.set(color);material.emissive?.set(color);material.opacity=chamsCfg.opacity}\n      }\n      mesh.material=chamsCfg.throughWalls?record.hidden:record.visible;\n      mesh.renderOrder=10000;mesh.frustumCulled=false;\n      const overlay=record.overlay;overlay.visible=chamsCfg.throughWalls&&mesh.visible;\n      if(mesh.matrixAutoUpdate)mesh.updateMatrix();overlay.matrix.copy(mesh.matrix);overlay.matrixWorldNeedsUpdate=true;\n      if(mesh.morphTargetInfluences)overlay.morphTargetInfluences=mesh.morphTargetInfluences;\n    }\n  }\n  for(const [mesh,record]of chamsRecords)if(!seen.has(mesh))restoreChamsRecord(mesh,record);\n  for(const [root,visible]of chamsRoots)if(!activeRoots.has(root)){root.visible=visible;chamsRoots.delete(root)}\n}\nfunction detachChamsManager(){\n  if(chamsManager?.cullAgents===chamsCullHook){if(chamsOwnCull)Object.defineProperty(chamsManager,\"cullAgents\",chamsOwnCull);else delete chamsManager.cullAgents}\n  chamsManager=null;\n}\nfunction ensureChamsManager(){\n  if(chamsManager===game.botMgr)return;\n  clearChams();detachChamsManager();\n  const mgr=game.botMgr;if(typeof mgr?.cullAgents!==\"function\")return;\n  chamsManager=mgr;chamsOriginalCull=mgr.cullAgents;chamsOwnCull=Object.getOwnPropertyDescriptor(mgr,\"cullAgents\");\n  const native=chamsOriginalCull;\n  chamsCullHook=function(...args){const result=native.apply(this,args);applyChams();return result};mgr.cullAgents=chamsCullHook;\n}\nconst chamsTick=game.tick;\nconst chamsTickHook=function(...args){ensureChamsManager();return chamsTick.apply(this,args)};\ngame.tick=chamsTickHook;ensureChamsManager();\nwindow[K].chamsCleanup=()=>{\n  chamsCfg.enabled=false;clearChams();detachChamsManager();if(game.tick===chamsTickHook)game.tick=chamsTick;\n};\nfunction refreshChams(){\n  if(chamsCfg.enabled){window.__chamsGlowTest?.cleanup();window.__dualChamsTest?.cleanup();window.__chamsTest?.cleanup()}\n  ensureChamsManager();\n  // Console tests may have removed a wrapper that existed at installation.\n  if(chamsManager&&chamsManager.cullAgents!==chamsCullHook){detachChamsManager();ensureChamsManager()}\n  applyChams();\n}\nconst chamsPanel=document.createElement(\"section\");chamsPanel.style.cssText=\"margin-top:18px;border-top:1px solid #444;padding-top:12px\";\nconst chamsHeading=document.createElement(\"h3\");chamsHeading.textContent=\"Chams\";chamsPanel.appendChild(chamsHeading);espBody.appendChild(chamsPanel);\nfunction chamsToggle(label,key){\n  const row=document.createElement(\"label\"),input=document.createElement(\"input\");input.type=\"checkbox\";input.checked=chamsCfg[key];\n  input.onchange=()=>{chamsCfg[key]=input.checked;refreshChams();renderHotkeys()};row.appendChild(input);row.appendChild(document.createTextNode(\" \"+label));\n  chamsPanel.appendChild(row);\n}\nchamsToggle(\"Enable chams\",\"enabled\");chamsToggle(\"Show behind walls\",\"throughWalls\");\nconst chamsTeamLabel=document.createElement(\"label\");chamsTeamLabel.textContent=\"Show\";\nconst chamsTeam=document.createElement(\"select\");chamsTeam.style.cssText=\"display:block;width:100%;margin:4px 0 8px\";\nfor(const [value,label]of [[\"enemies\",\"Enemies\"],[\"allies\",\"Allies\"],[\"all\",\"Both teams\"]]){const option=document.createElement(\"option\");option.value=value;option.textContent=label;chamsTeam.appendChild(option)}\nchamsTeam.value=chamsCfg.team;chamsTeam.onchange=()=>{chamsCfg.team=chamsTeam.value;refreshChams()};chamsTeamLabel.appendChild(chamsTeam);chamsPanel.appendChild(chamsTeamLabel);\nfor(const [key,label]of [[\"visibleColor\",\"Visible color\"],[\"hiddenColor\",\"Behind-wall color\"]]){\n  const row=document.createElement(\"label\"),input=document.createElement(\"input\");row.textContent=label;row.style.cssText=\"display:flex;align-items:center;justify-content:space-between\";\n  input.type=\"color\";input.value=chamsCfg[key];input.setAttribute(\"aria-label\",label);input.style.cssText=\"width:32px;height:21px;padding:0;border:1px solid #444;background:#1b1b1b\";\n  input.oninput=()=>{chamsCfg[key]=input.value;refreshChams()};row.appendChild(input);chamsPanel.appendChild(row);\n}\nconst chamsOpacityLabel=document.createElement(\"label\"),chamsOpacity=document.createElement(\"input\");\nchamsOpacityLabel.textContent=\"Opacity\";chamsOpacity.type=\"range\";chamsOpacity.min=\"0.1\";chamsOpacity.max=\"1\";chamsOpacity.step=\"0.05\";chamsOpacity.value=\"1\";chamsOpacity.style.width=\"100%\";\nchamsOpacity.oninput=()=>{chamsCfg.opacity=Number(chamsOpacity.value);chamsOpacity.style.setProperty(\"--fill\",((chamsCfg.opacity-.1)/.9*100)+\"%\");refreshChams()};chamsOpacity.style.setProperty(\"--fill\",\"100%\");chamsOpacityLabel.appendChild(chamsOpacity);chamsPanel.appendChild(chamsOpacityLabel);\nconst chamsNote=document.createElement(\"div\");chamsNote.textContent=\"Green: exposed · Red: behind cover. Chams work independently of ESP.\";chamsNote.style.cssText=\"color:#999;font-size:10px;line-height:1.5;margin-top:8px\";chamsPanel.appendChild(chamsNote);\n\nrow(\"Silent Aim\",\"aim\",aimBody);\nslider(\"FOV (degrees)\",\"fov\",1,45,1,aimBody);\nrow(\"Team Check\",\"aimTeamCheck\",aimBody);\nrow(\"Visible Targets Only\",\"aimVisibleOnly\",aimBody);\nslider(\"Maximum Distance (0 = unlimited)\",\"aimMaxDistance\",0,500,5,aimBody);\nslider(\"Minimum Target Health\",\"aimMinHealth\",0,100,1,aimBody);\nrow(\"Show FOV Circle\",\"showAimFov\",aimBody);\nslider(\"FOV Circle Opacity\",\"aimFovOpacity\",0.1,1,0.05,aimBody);\nconst aimColorRow=document.createElement(\"label\");aimColorRow.className=\"setting-line\";\naimColorRow.textContent=\"FOV Circle Color\";\nconst aimColor=document.createElement(\"input\");aimColor.type=\"color\";aimColor.value=cfg.aimFovColor;\naimColor.oninput=()=>{cfg.aimFovColor=aimColor.value};aimColorRow.appendChild(aimColor);aimBody.appendChild(aimColorRow);\n\n\nconst regionRow=document.createElement(\"div\");\nregionRow.style.margin=\"10px 0\";\nregionRow.innerHTML=`<div style=\"margin-bottom:4px\">Aim Region</div><select style=\"width:100%;padding:5px;background:#222;color:#fff;border:1px solid #555;border-radius:4px\"><option value=\"chest\">Chest</option><option value=\"head\">Head</option></select>`;\nconst regionSelect=regionRow.querySelector(\"select\");\nregionSelect.value=cfg.hitRegion;\nregionSelect.onchange=()=>{cfg.hitRegion=regionSelect.value};\naimBody.appendChild(regionRow);\nrow(\"Wallbang\",\"wallHit\",aimBody);\nrow(\"Weapon Modifiers\",\"weaponMods\",weaponBody);\nrow(\"Infinite Ammo\",\"ammo\",weaponBody);\nrow(\"Force Auto\",\"autoFire\",weaponBody);\nrow(\"Fire Rate\",\"fireRate\",weaponBody);\n\nslider(\"Fire Rate\",\"fireMult\",1,10,.5,weaponBody);\nrow(\"No Recoil\",\"noRecoil\",weaponBody);\nrow(\"No Spread\",\"noSpread\",weaponBody);\nrow(\"Enable Speed Modifier\",\"speed\",movementBody);\nslider(\"Ground Speed Multiplier\",\"speedMult\",1,8,.5,movementBody);\nslider(\"Air Momentum Multiplier\",\"airMult\",1,12,.5,movementBody);\nrow(\"Auto Bhop (hold Space)\",\"autoBhop\",movementBody);\nrow(\"Flight (WASD / Space / Ctrl)\",\"flight\",movementBody);\nslider(\"Flight Speed\",\"flightSpeed\",1,25,1,movementBody);\n\n// Master toggles collapse their child settings without deleting their values.\nfunction collapseAfter(parent,from,key,until=null){\n  const panel=document.createElement(\"div\");panel.className=\"debug-collapse\";\n  let node=from.nextSibling;\n  while(node&&node!==until){const next=node.nextSibling;panel.appendChild(node);node=next}\n  parent.insertBefore(panel,until);groupSections.set(key,panel);\n}\ncollapseAfter(aimBody,aimBody.querySelector(\"input[type=checkbox]\").parentElement,\"aim\");\ncollapseAfter(weaponBody,weaponBody.querySelector(\"input[type=checkbox]\").parentElement,\"weaponMods\");\nconst speedRow=[...movementBody.children].find(n=>n.textContent.includes(\"Enable Speed Modifier\"));\nconst bhopRow=[...movementBody.children].find(n=>n.textContent.includes(\"Auto Bhop\"));\nconst flightRow=[...movementBody.children].find(n=>n.textContent.includes(\"Flight (\"));\nif(speedRow&&bhopRow)collapseAfter(movementBody,speedRow,\"speed\",bhopRow);\nif(flightRow)collapseAfter(movementBody,flightRow,\"flight\");\nrefreshGroups();\n\n\nconst invKey=\"clutcher_inv_v1\";\nfunction loadInv(){\n  let d;\n  try{d=JSON.parse(localStorage.getItem(invKey)||\"null\")}catch{}\n  if(!d)d={coins:600,items:[],equipped:{},stats:{games:0,kills:0,wins:0}};\n  if(!Array.isArray(d.items))d.items=[];\n  if(!d.equipped||typeof d.equipped!==\"object\")d.equipped={};\n  if(!d.stats||typeof d.stats!==\"object\")d.stats={games:0,kills:0,wins:0};\n  return d;\n}\nfunction saveInv(d){localStorage.setItem(invKey,JSON.stringify(d))}\n\nconst inv=loadInv();\ninventoryBody.innerHTML=`<div style=\"display:grid;grid-template-columns:180px 1fr;gap:16px;align-items:start\"><div>\n  <div style=\"margin-bottom:8px\">\n    <div style=\"margin-bottom:4px\">Money</div>\n    <input id=\"invCoins\" type=\"number\" style=\"width:100%;box-sizing:border-box;padding:6px;background:#222;color:#fff;border:1px solid #555;border-radius:4px\">\n  </div>\n  <div style=\"margin-bottom:10px\">\n    <div style=\"margin-bottom:4px\">Rank / Rating</div>\n    <input id=\"invRating\" type=\"number\" style=\"width:100%;box-sizing:border-box;padding:6px;background:#222;color:#fff;border:1px solid #555;border-radius:4px\">\n  </div>\n  <button id=\"saveStats\" style=\"width:100%;padding:6px;cursor:pointer;margin-bottom:12px\">Save Money & Rating</button>\n  <button id=\"reloadInv\" style=\"width:100%;padding:6px;cursor:pointer;margin-top:4px\">Save & Reload</button>\n  </div><div style=\"border-left:1px solid #444;padding-left:16px\">\n    <div style=\"margin-bottom:4px\">Skin Search</div>\n    <input id=\"skinSearch\" placeholder=\"e.g. Dragon Lore, Fade...\" style=\"width:100%;box-sizing:border-box;padding:6px;background:#222;color:#fff;border:1px solid #555;border-radius:4px\">\n    <select id=\"skinResults\" size=\"5\" style=\"width:100%;margin-top:6px;background:#222;color:#fff;border:1px solid #555\"></select>\n    <div style=\"display:flex;gap:10px;margin-top:8px\">\n      <div style=\"flex:1\">\n        <div style=\"margin-bottom:4px\">Wear <span id=\"wearRange\" style=\"color:#aaa;font-size:10px\"></span></div>\n        <input id=\"skinWear\" type=\"number\" min=\"0\" max=\"1\" step=\"0.000001\" value=\"0.000001\" style=\"width:100%;box-sizing:border-box;padding:6px;background:#222;color:#fff;border:1px solid #555;border-radius:4px\">\n      </div>\n      <div style=\"flex:1\">\n        <div style=\"margin-bottom:4px\">Pattern / Seed</div>\n        <input id=\"skinSeed\" type=\"number\" min=\"0\" max=\"999\" step=\"1\" value=\"0\" style=\"width:100%;box-sizing:border-box;padding:6px;background:#222;color:#fff;border:1px solid #555;border-radius:4px\">\n      </div>\n    </div>\n    <button id=\"giveSkin\" style=\"width:100%;padding:6px;cursor:pointer;margin-top:8px\">Give Selected Skin</button>\n    <div id=\"invStatus\" style=\"min-height:16px;margin-top:7px;color:#bbb;font-size:11px\"></div>\n  </div></div></div>\n`;\n\nconst coinsInput=inventoryBody.querySelector(\"#invCoins\");\nconst ratingInput=inventoryBody.querySelector(\"#invRating\");\nconst searchInput=inventoryBody.querySelector(\"#skinSearch\");\nconst results=inventoryBody.querySelector(\"#skinResults\");\nconst wearInput=inventoryBody.querySelector(\"#skinWear\");\nconst seedInput=inventoryBody.querySelector(\"#skinSeed\");\nconst wearRange=inventoryBody.querySelector(\"#wearRange\");\nconst status=inventoryBody.querySelector(\"#invStatus\");\n\ncoinsInput.value=Number.isFinite(Number(inv.coins))?inv.coins:0;\nratingInput.value=Number.isFinite(Number(inv.stats.rating))?inv.stats.rating:0;\n\ninventoryBody.querySelector(\"#saveStats\").onclick=()=>{\n  const d=loadInv();\n  const coins=Number(coinsInput.value);\n  const rating=Number(ratingInput.value);\n  if(Number.isFinite(coins))d.coins=coins;\n  if(Number.isFinite(rating))d.stats.rating=rating;\n  saveInv(d);\n  status.textContent=\"Money and rating saved.\";\n};\n\nfunction renderSkins(){\n  const q=searchInput.value.trim().toLowerCase();\n  const matches=skinCatalog.filter(s=>!q||s.name.toLowerCase().includes(q)||s.id.toLowerCase().includes(q)).slice(0,150);\n  results.innerHTML=\"\";\n  for(const s of matches){\n    const o=document.createElement(\"option\");\n    o.value=s.id;\n    o.textContent=s.name;\n    results.appendChild(o);\n  }\n  status.textContent=matches.length+(matches.length===150?\" shown\":\" result\"+(matches.length===1?\"\":\"s\"));\n  updateSkinControls();\n}\nfunction updateSkinControls(){\n  const skin=skinCatalog.find(s=>s.id===results.value);\n  if(!skin){\n    wearRange.textContent=\"\";\n    return;\n  }\n  wearInput.min=skin.wmin;\n  wearInput.max=skin.wmax;\n  wearInput.value=((skin.wmin+skin.wmax)/2).toFixed(6);\n  wearRange.textContent=`(${skin.wmin}–${skin.wmax})`;\n}\nsearchInput.oninput=renderSkins;\nresults.onchange=updateSkinControls;\nloadSkinCatalog();\n\ninventoryBody.querySelector(\"#giveSkin\").onclick=()=>{\n  const id=results.value;\n  if(!id){status.textContent=\"Select a skin first.\";return}\n  const skin=skinCatalog.find(s=>s.id===id);\n  if(!skin){status.textContent=\"Skin not found.\";return}\n  const d=loadInv();\n  \n  let wear=Number(wearInput.value);\n  let seed=Math.round(Number(seedInput.value));\n  if(!Number.isFinite(wear))wear=(skin.wmin+skin.wmax)/2;\n  if(!Number.isFinite(seed))seed=0;\n  wear=Math.max(skin.wmin,Math.min(skin.wmax,wear));\n  seed=Math.max(0,Math.min(999,seed));\n  wearInput.value=wear.toFixed(6);\n  seedInput.value=seed;\n  const now=Date.now();\n  d.items.push({\n    uid:\"i\"+now.toString(36)+d.items.length.toString(36),\n    skin:id,\n    wear:+wear.toFixed(6),\n    seed:seed,\n    st:false,\n    kills:0,\n    t:now\n  });\n  saveInv(d);\n  status.textContent=\"Added \"+skin.name+\".\";\n};\n\ninventoryBody.querySelector(\"#reloadInv\").onclick=()=>{\n  inventoryBody.querySelector(\"#saveStats\").click();\n  location.reload();\n};\n\n\n\n\nconst theme=document.createElement(\"style\");\ntheme.textContent=`\n#__testGUI{--green:#8ed04c;--panel:#262626;position:fixed!important;width:600px!important;max-width:calc(100vw - 24px);box-sizing:border-box;padding:0!important;background:#202020!important;color:#e7e7e7!important;font:600 12px Arial,sans-serif!important;letter-spacing:.25px;border:1px solid #686868!important;border-radius:0!important;box-shadow:0 4px 20px #0008!important}\n#__testGUI *{box-sizing:border-box}\n#__testGUI #guiHead{height:31px;display:flex;align-items:center;justify-content:space-between;margin:0!important;padding:0 9px!important;border-bottom:2px solid #678b3c;background:#1d1d1d;font-size:14px!important}\n#__testGUI .debugBrand{font:bold 19px Arial,sans-serif;letter-spacing:-1px;color:white}\n#__testGUI .debugHint{color:#999;font-size:9px;letter-spacing:1px}\n#__testGUI #guiTabs{margin:0!important;padding:6px 7px!important;gap:4px!important;background:#202020;border-bottom:1px solid #343434;flex-wrap:wrap}\n#__testGUI button{border:1px solid #383838!important;border-radius:0!important;background:#1b1b1b!important;color:#ddd!important;font:600 11px Arial,sans-serif!important;letter-spacing:.3px;padding:6px 8px!important;cursor:pointer}\n#__testGUI button:hover{background:#303929!important;border-color:#678b3c!important;color:white!important}\n#__testGUI button:active{background:#40552d!important}\n#__testGUI button:disabled{opacity:.45;cursor:wait}\n#__testGUI #guiTabs button{flex:1!important;padding:5px 7px!important;border:0!important;border-top:2px solid transparent!important;background:#282828!important}\n#__testGUI #guiTabs button[aria-selected=\"true\"]{color:var(--green)!important;background:#30352a!important;border-top-color:var(--green)!important}\n#__testGUI :is(#combatTab,#movementTab,#visualsTab,#worldTab,#inventoryTab,#casesTab,#privateTab){background:var(--panel);margin:7px;min-height:260px;max-height:calc(100vh - 190px);overflow:auto;padding:10px!important;scrollbar-color:#678b3c #202020;scrollbar-width:thin}\n#__testGUI #combatTab{column-count:1!important;column-rule:none!important}\n\n#__testGUI .espSettings{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:20px}\n#__testGUI .espSettings h3{font:700 11px Arial,sans-serif;text-transform:uppercase;letter-spacing:1px;color:var(--green);margin:0 0 12px;padding-bottom:7px;border-bottom:1px solid #3a3a3a}\n#__testGUI .espControls label{display:block}\n#__testGUI .espPreviewPanel{position:sticky;top:0;align-self:start;min-width:0}\n#__testGUI .espPreviewStage{height:245px;position:relative;overflow:hidden;border:1px solid #383838;background:radial-gradient(ellipse at 50% 85%,#35402e55,transparent 60%),repeating-linear-gradient(0deg,transparent,transparent 23px,#ffffff04 24px),#1d1f1c}\n#__testGUI .espPreviewStage::before{content:\"\";position:absolute;left:50%;top:72px;transform:translateX(-50%);width:45px;height:113px;border-radius:35% 35% 15% 15%;background:#ffffff08}\n#__testGUI .espPreviewCaption{margin-top:9px;color:#999;font-size:10px;text-align:center;line-height:1.5}\n\n#__testGUI .combatSections{display:grid;grid-template-columns:1fr 1fr;gap:22px}\n#__testGUI .combatSections section{min-width:0}\n#__testGUI .combatSections section+section{border-left:5px solid #202020;padding-left:12px}\n#__testGUI .combatSections h3{font:700 11px Arial,sans-serif;color:var(--green);text-transform:uppercase;letter-spacing:1px;margin:0 0 10px;padding-bottom:6px;border-bottom:1px solid #3a3a3a}\n#__testGUI #combatTab>*,#__testGUI #movementTab>*,#__testGUI #visualsTab>*{break-inside:avoid}\n#__testGUI label{font-size:12px;line-height:18px;margin:4px 0!important}\n#__testGUI input[type=\"checkbox\"]{appearance:none;-webkit-appearance:none;vertical-align:-1px;width:11px;height:11px;margin:0 5px 0 0;border:1px solid #646464;border-radius:2px;background:#191919;cursor:pointer}\n#__testGUI input[type=\"checkbox\"]:checked{background:var(--green);border-color:#7caf45;box-shadow:0 0 2px #8ed04c55}\n#__testGUI input[type=\"range\"]{appearance:none;-webkit-appearance:none;display:block;height:6px;margin:7px 0 9px;background:linear-gradient(to right,var(--green) 0%,var(--green) var(--fill,0%),#191919 var(--fill,0%),#191919 100%);border:0;border-radius:2px;cursor:pointer}\n#__testGUI input[type=\"range\"]::-webkit-slider-thumb{appearance:none;width:8px;height:9px;border:0;border-radius:1px;background:var(--green)}\n#__testGUI input[type=\"range\"]::-moz-range-thumb{width:8px;height:9px;border:0;border-radius:1px;background:var(--green)}\n#__testGUI :is(input[type=\"number\"],input:not([type]),select){border:1px solid #303030!important;border-radius:0!important;background:#1b1b1b!important;color:#ddd!important;padding:5px!important;font:600 11px Arial,sans-serif!important}\n#__testGUI option:checked{background:#40552d;color:white}\n#__testGUI :is(input,select,button):focus-visible{outline:1px solid var(--green);outline-offset:2px}\n#__testGUI #invStatus{color:#a8bd91!important}\n#__testGUI>button:last-child{display:block;margin:0!important;width:100%!important;border:0!important;border-top:1px solid #383838!important;color:#999!important;font-size:10px!important}\n\n#__testGUI :is(#combatTab,#movementTab,#visualsTab,#worldTab,#inventoryTab,#casesTab,#privateTab,#settingsTab){min-height:200px}\n#__testGUI .debug-collapse[hidden]{display:none!important}\n#__testGUI .mini-bind{float:right!important;min-width:33px!important;max-width:64px!important;padding:2px 5px!important;line-height:15px!important;margin-left:6px!important;border-radius:6px!important;font-size:10px!important;color:var(--fg-muted,#999)!important;background:var(--bind-bg,#191919)!important;border:1px solid var(--border-subtle,#444)!important;text-transform:none!important}\n#__testGUI .mini-bind:hover{color:var(--green)!important;border-color:var(--green)!important}\n#__testGUI label:has(.mini-bind){display:block!important;min-height:22px;clear:both}\n#__testGUI .setting-line{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:10px 2px;border-bottom:1px solid var(--border-subtle,#444)}\n#__testGUI .setting-line>span{font-weight:600}\n#__testGUI .setting-line input[type=color]{width:32px;height:25px;padding:1px;background:transparent;border:0;cursor:pointer}\n#__testGUI .setting-line select{width:135px}\n#__testGUI .settings-key{min-width:58px;border-radius:6px!important}\n#__testGUI .settings-help{font-size:11px;line-height:1.6;color:var(--fg-muted,#999);margin:15px 2px}\n#__testGUI #guiHead{border-bottom-color:var(--green)!important}\n#__testGUI[data-theme=light]{--panel:#f2f2f3;--fg-muted:#686870;--bind-bg:#e4e4e7;--border-subtle:#bcbcc3;background:#f7f7f8!important;color:#202025!important;border-color:#aaa!important}\n#__testGUI[data-theme=light] #guiHead{background:#ebebed!important;color:#202025!important}\n#__testGUI[data-theme=light] .debugBrand{color:#202025!important}\n#__testGUI[data-theme=light] #guiTabs{background:#f5f5f6!important;border-bottom-color:#ccc}\n#__testGUI[data-theme=light] #guiTabs button{background:#e9e9eb!important;color:#333!important}\n#__testGUI[data-theme=light] #guiTabs button[aria-selected=true]{background:#dedee1!important;color:#202025!important}\n#__testGUI[data-theme=light] :is(#combatTab,#movementTab,#visualsTab,#worldTab,#inventoryTab,#casesTab,#privateTab,#settingsTab){background:#f0f0f2!important}\n#__testGUI[data-theme=light] button{background:#e5e5e9!important;color:#333!important;border-color:#bbb!important}\n#__testGUI[data-theme=light] input[type=checkbox]{background:#fafafa;border-color:#999}\n#__testGUI[data-theme=light] input[type=checkbox]:checked{background:var(--green)}\n#__testGUI[data-theme=light] :is(input[type=number],input:not([type]),select){background:#fff!important;color:#202025!important;border-color:#c6c6cc!important}\n#__testGUI[data-theme=light] :is(.combatSections h3,.espSettings h3){border-bottom-color:#ccc}\n#__testGUI[data-theme=light] .combatSections section+section{border-left-color:#ddd}\n#__testGUI[data-theme=light] .espPreviewStage{background:#e5e7e5!important}\n#__testGUI[data-theme=light] .setting-line{border-bottom-color:#d1d1d5}\n#__hotkeysHUD{--hk-accent:#8ed04c;position:fixed;top:14px;right:14px;min-width:142px;max-width:195px;padding:8px 10px;background:#111b;backdrop-filter:blur(8px);border:1px solid #ffffff24;border-top:2px solid var(--hk-accent);border-radius:7px;color:#eee;font:500 11px Arial,sans-serif;z-index:2147483645;pointer-events:none;box-shadow:0 5px 16px #0005}\n#__hotkeysHUD[data-theme=light]{background:#f4f4f4e8;color:#222;border-color:#2224;border-top-color:var(--hk-accent)}\n#__hotkeysHUD .hk-title{font-weight:700;color:var(--hk-accent);font-size:10px;letter-spacing:1px;margin-bottom:6px}\n#__hotkeysHUD .hk-row{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:2px 0}\n#__hotkeysHUD .hk-key{color:var(--hk-accent);font-size:10px;white-space:nowrap}\n#__hotkeysHUD .hk-empty{opacity:.6;font-size:10px}\n.bind-popup{position:fixed;z-index:2147483647;width:196px;padding:10px;background:#1a1a1f;border:1px solid #666;border-top:2px solid #8ed04c;color:white;box-shadow:0 7px 22px #0009;font:12px Arial,sans-serif;border-radius:6px}\n.bind-popup>*{display:block;width:100%;margin:0 0 7px}\n.bind-popup .bind-popup-title{font-weight:bold;font-size:12px}\n.bind-popup select,.bind-popup button{padding:5px;background:#292930;color:white;border:1px solid #555;border-radius:4px;cursor:pointer}\n.bind-popup .bind-popup-actions{display:flex;gap:5px}\n.bind-popup small{color:#aaa;font-size:10px;line-height:1.5}\n\n@media(max-width:540px){#__testGUI{left:12px!important}#__testGUI #inventoryTab>div{grid-template-columns:1fr!important}#__testGUI #inventoryTab>div>div{border:0!important;padding:0!important}}\n`;\ntheme.textContent+=\"\\n/* Reference-inspired compact cards. */\\n#__testGUI{width:min(660px,calc(100vw - 24px))!important;max-height:calc(100vh - 24px);overflow:auto;background:#0c0c10!important;border:1px solid #26232f!important;border-radius:10px!important;box-shadow:0 20px 65px #0009!important}\\n#__testGUI #guiHead{background:#0d0d12!important;padding:15px 17px!important;border-bottom:1px solid #24212e!important}\\n#__testGUI .debugBrand{font-size:13px;letter-spacing:1px;color:var(--green)!important}\\n#__testGUI #guiTabs{background:#101015!important;padding:8px!important;gap:3px!important}\\n#__testGUI #guiTabs button{background:transparent!important;border-radius:5px!important;border-top:0!important;padding:9px 7px!important;color:#aaa6b5!important;font-size:10px!important}\\n#__testGUI #guiTabs button[aria-selected=true]{background:color-mix(in srgb,var(--green) 15%,transparent)!important;color:var(--green)!important}\\n#__testGUI :is(#combatTab,#movementTab,#visualsTab,#worldTab,#inventoryTab,#casesTab,#privateTab,#settingsTab){background:#0c0c10;max-height:calc(100vh - 155px);scrollbar-color:#3e3557 #101015}\\n#__testGUI .combatSections{gap:12px}\\n#__testGUI .combatSections section,#__testGUI .espControls,#__testGUI .espPreviewPanel{background:#111116;border:1px solid #1c1b24;border-radius:8px;padding:14px;min-width:0}\\n#__testGUI .combatSections section+section{border-left:1px solid #1c1b24;padding-left:14px}\\n#__testGUI :is(.combatSections h3,.espSettings h3){font-size:11px;text-transform:none;letter-spacing:0;border-bottom:1px solid #25212f;padding-bottom:12px;margin-bottom:12px}\\n#__testGUI label{font-size:11px;line-height:23px;color:#c4c1cc}\\n#__testGUI input[type=checkbox]{width:14px;height:14px;border-radius:4px;border-color:#3b354b;vertical-align:-3px;margin-right:7px}\\n#__testGUI input[type=checkbox]:checked{border-color:var(--green);box-shadow:0 0 8px color-mix(in srgb,var(--green) 25%,transparent)}\\n#__testGUI input[type=range]{height:5px;margin-top:9px;margin-bottom:15px}\\n#__testGUI input[type=range]::-webkit-slider-thumb{width:9px;height:9px;border-radius:50%}\\n#__testGUI select{min-height:30px;border-radius:5px!important;background:#17161d!important;border-color:#272430!important}\\n#__testGUI .mini-bind{border:0!important;background:#19171f!important;border-radius:4px!important}\\n#__testGUI[data-theme=light] :is(.combatSections section,.espControls,.espPreviewPanel){background:#faf9fc;border-color:#d9d5e2}\\n#__testGUI[data-theme=light] label{color:#393541}\\n@media(max-width:560px){#__testGUI .combatSections,#__testGUI .espSettings{grid-template-columns:1fr}#__testGUI{left:12px!important;top:12px!important}}\\n\";\n\nfunction polishRemainingTabs(){\n  function card(title,nodes){\n    const section=document.createElement(\"section\");section.className=\"debug-card\";\n    const heading=document.createElement(\"h3\");heading.textContent=title;section.appendChild(heading);\n    for(const node of nodes)if(node)section.appendChild(node);\n    return section;\n  }\n  function grid(parent){const grid=document.createElement(\"div\");grid.className=\"debug-card-grid\";parent.appendChild(grid);return grid}\n  const movementNodes=[...movementBody.children];\n  const flightIndex=movementNodes.findIndex(n=>n.tagName===\"LABEL\"&&n.textContent.includes(\"Flight (\"));\n  const movementGrid=grid(movementBody);\n  movementGrid.appendChild(card(\"Speed & Movement\",movementNodes.slice(0,flightIndex<0?movementNodes.length:flightIndex)));\n  if(flightIndex>=0)movementGrid.appendChild(card(\"Flight\",movementNodes.slice(flightIndex)));\n  const inventoryGrid=inventoryBody.firstElementChild;\n  if(inventoryGrid){\n    inventoryGrid.classList.add(\"debug-card-grid\",\"debug-inventory-grid\");\n    for(const [index,column]of [...inventoryGrid.children].entries()){\n      const panel=card(index===0?\"Player Stats\":\"Skin Library\",[...column.childNodes]);\n      column.replaceWith(panel);\n    }\n  }\n  const privateNodes=[...privateBody.children].filter(n=>n!==practicePanel);\n  const privateGrid=grid(privateBody);\n  privateGrid.appendChild(card(\"Private Session\",privateNodes));\n  practicePanel.classList.add(\"debug-card\");\n  const practiceHeading=document.createElement(\"h3\");practiceHeading.textContent=\"Practice Targets\";\n  practicePanel.prepend(practiceHeading);privateGrid.appendChild(practicePanel);\n  const caseNodes=[...casesBody.children];\n  casesBody.appendChild(card(\"Case Selection\",caseNodes));\n  caseButtons.classList.add(\"debug-case-buttons\");\n  const settingRows=[...settingsBody.children].filter(n=>n.classList.contains(\"setting-line\"));\n  const appearance=[],shortcuts=[];\n  for(const row of settingRows)(row.querySelector('input[type=\"color\"],select')?appearance:shortcuts).push(row);\n  const settingsGrid=grid(settingsBody);\n  settingsGrid.appendChild(card(\"Appearance\",appearance));\n  settingsGrid.appendChild(card(\"Shortcuts & Display\",shortcuts));\n  if(settingsHelp)settingsBody.appendChild(settingsHelp);\n}\npolishRemainingTabs();\n\ntheme.textContent+=\"\\n/* Shared cards and controls across every tab. */\\n#__testGUI{--card-bg:#111116;--card-border:#1c1b24;--control-bg:#17161d;--control-border:#302b3b;--text-main:#c4c1cc;--text-muted:#96909f}\\n#__testGUI[data-theme=light]{--card-bg:#faf9fc;--card-border:#d9d5e2;--control-bg:#fff;--control-border:#ccc6d6;--text-main:#393541;--text-muted:#716a7e}\\n#__testGUI .debug-card-grid{display:grid!important;grid-template-columns:minmax(0,1fr) minmax(0,1fr)!important;gap:12px!important;align-items:start}\\n#__testGUI .debug-card{box-sizing:border-box;min-width:0;background:var(--card-bg)!important;border:1px solid var(--card-border)!important;border-radius:8px;padding:14px!important;margin:0!important;color:var(--text-main);font-size:11px;line-height:1.6}\\n#__testGUI .debug-card h3{font:700 11px Arial,sans-serif;color:var(--green);letter-spacing:0;text-transform:none;margin:0 0 12px;padding:0 0 12px;border-bottom:1px solid var(--card-border)}\\n#__testGUI .debug-card input:not([type=checkbox]):not([type=range]):not([type=color]),#__testGUI .debug-card select{box-sizing:border-box;max-width:100%;min-height:30px;background:var(--control-bg)!important;border:1px solid var(--control-border)!important;border-radius:5px!important;color:var(--text-main)!important;padding:6px 8px!important;font:500 11px Arial,sans-serif!important}\\n#__testGUI .debug-card input::placeholder{color:var(--text-muted)}\\n#__testGUI .debug-card button{background:var(--control-bg)!important;border:1px solid var(--control-border)!important;border-radius:5px!important;color:var(--text-main)!important;padding:8px 10px!important;line-height:1.3!important;font:600 11px Arial,sans-serif!important;letter-spacing:0}\\n#__testGUI .debug-card button:hover{background:color-mix(in srgb,var(--green) 14%,var(--control-bg))!important;border-color:var(--green)!important;color:var(--green)!important}\\n#__testGUI .debug-card button:disabled{opacity:.45}\\n#__testGUI .debug-card button.mini-bind{padding:2px 5px!important;font-size:10px!important}\\n#__testGUI .debug-card .setting-line{padding:10px 0;gap:10px;border-color:var(--card-border);font-size:11px;flex-wrap:wrap}\\n#__testGUI .debug-card .setting-line:first-of-type{padding-top:0}\\n#__testGUI .debug-card .setting-line:last-child{border-bottom:0}\\n#__testGUI .debug-card .setting-line select{width:120px}\\n#__testGUI .debug-case-buttons{display:grid!important;grid-template-columns:repeat(auto-fit,minmax(90px,1fr));gap:8px!important}\\n#__testGUI .debug-card [role=status],#__testGUI #invStatus{font-size:10px!important;line-height:1.6;color:var(--text-muted)!important}\\n#__testGUI .settings-help{color:var(--text-muted);font-size:10px;line-height:1.6;margin:12px 2px}\\n#__testGUI .debug-card #skinResults{height:145px;padding:4px!important}\\n#__testGUI .debug-card #skinResults option{padding:6px;border-radius:3px}\\n#__testGUI .debug-card #skinResults option:checked{background:color-mix(in srgb,var(--green) 22%,var(--control-bg));color:var(--text-main)}\\n@media(max-width:560px){#__testGUI .debug-card-grid{grid-template-columns:minmax(0,1fr)!important}#__testGUI .debug-card{padding:12px!important}}\\n\";\n\nconst triggerBody=document.createElement(\"section\");triggerBody.id=\"triggerSection\";\nconst triggerHeading=document.createElement(\"h3\");triggerHeading.textContent=\"Trigger Bot\";triggerBody.appendChild(triggerHeading);\ncombatBody.querySelector(\".combatSections\").appendChild(triggerBody);\nrow(\"Trigger Bot\",\"trigger\",triggerBody);\nslider(\"Trigger FOV (degrees)\",\"triggerFov\",0.1,15,0.1,triggerBody);\nslider(\"Reaction Delay (ms)\",\"triggerDelay\",0,1000,10,triggerBody);\nrow(\"Team Check\",\"triggerTeamCheck\",triggerBody);\nrow(\"Visible Targets Only\",\"triggerVisibleOnly\",triggerBody);\nslider(\"Visibility Tolerance\",\"triggerVisibilityTolerance\",0,100,1,triggerBody);\nslider(\"Maximum Distance (0 = unlimited)\",\"triggerMaxDistance\",0,500,5,triggerBody);\nconst triggerRegionRow=document.createElement(\"label\");triggerRegionRow.textContent=\"Hit Region\";\nconst triggerRegionSelect=document.createElement(\"select\");triggerRegionSelect.style.cssText=\"display:block;width:100%;margin:5px 0 10px\";\nfor(const [value,label]of [[\"either\",\"Head or Chest\"],[\"head\",\"Head\"],[\"chest\",\"Chest\"]]){const option=document.createElement(\"option\");option.value=value;option.textContent=label;triggerRegionSelect.appendChild(option)}\ntriggerRegionSelect.value=cfg.triggerRegion;triggerRegionSelect.onchange=()=>{cfg.triggerRegion=triggerRegionSelect.value};triggerRegionRow.appendChild(triggerRegionSelect);triggerBody.appendChild(triggerRegionRow);\nrow(\"Show Trigger FOV\",\"triggerShowFov\",triggerBody);\nconst triggerColorRow=document.createElement(\"label\");triggerColorRow.className=\"setting-line\";triggerColorRow.textContent=\"Trigger FOV Color\";\nconst triggerColor=document.createElement(\"input\");triggerColor.type=\"color\";triggerColor.value=cfg.triggerFovColor;triggerColor.oninput=()=>{cfg.triggerFovColor=triggerColor.value};triggerColorRow.appendChild(triggerColor);triggerBody.appendChild(triggerColorRow);\nconst triggerNote=document.createElement(\"div\");triggerNote.className=\"settings-help\";triggerNote.textContent=\"FOV detects target points near the crosshair. Visibility Tolerance: 0 requires all 9 body samples clear; 99 accepts one clear sample; 100 also permits a hidden target within 0.75 game units behind the first obstruction. Applies only with Visible Targets Only on. Shots still follow the crosshair.\";triggerBody.appendChild(triggerNote);\ncollapseAfter(triggerBody,triggerBody.querySelector(\"input[type=checkbox]\").parentElement,\"trigger\");refreshGroups();\n\n\n// Trigger FOV tests projected target points; it never redirects shots.\nconst triggerCircle=document.createElement(\"div\");triggerCircle.id=\"__triggerFOV\";\nObject.assign(triggerCircle.style,{position:\"fixed\",pointerEvents:\"none\",boxSizing:\"border-box\",border:\"1px dashed\",borderRadius:\"50%\",zIndex:\"2147483646\",display:\"none\"});\ndocument.body.appendChild(triggerCircle);\nlet triggerCandidate=null,triggerSince=0,triggerPressed=false;\nfunction triggerVisibilityPass(entity){\n  if(!game.physics?.raycast)return false;\n  const origin=game.camera.position,base=entity._visY??entity.y,height=entity.height||1.8;\n  // Nine body samples approximate exposure without changing the real hitbox.\n  const dx=entity.x-origin.x,dz=entity.z-origin.z,horizontal=Math.hypot(dx,dz);\n  const sideX=horizontal>0?dz/horizontal:1,sideZ=horizontal>0?-dx/horizontal:0;\n  const samples=[[0,.92],[0,.7],[0,.5],[0,.3],[0,.1],[-.18,.72],[.18,.72],[-.13,.35],[.13,.35]];\n  const tolerance=Math.max(0,Math.min(100,Number(cfg.triggerVisibilityTolerance)||0));\n  const required=tolerance===100?1:Math.max(1,Math.ceil(samples.length*(1-tolerance/100)));\n  let visible=0,nearWall=false;\n  for(const [offset,fraction]of samples){\n    const x=entity.x+sideX*height*offset,y=base+height*fraction,z=entity.z+sideZ*height*offset;\n    const vx=x-origin.x,vy=y-origin.y,vz=z-origin.z,len=Math.hypot(vx,vy,vz);\n    if(!Number.isFinite(len)||len<=0)continue;\n    const hit=game.physics.raycast(origin.x,origin.y,origin.z,vx/len,vy/len,vz/len,len,0x2);\n    if(!hit||(Number.isFinite(hit.t)&&hit.t>=len-.05))visible++;\n    else if(Number.isFinite(hit.t)&&hit.t>=0&&len-hit.t<=.75)nearWall=true;\n    if(visible>=required)return true;\n  }\n  // At maximum only, permit targets up to 0.75 game units beyond the first obstruction.\n  return tolerance===100&&nearWall;\n}\nfunction findTriggerTarget(){\n  const me=game.player;\n  if(!me||!canvas)return null;\n  const r=canvas.getBoundingClientRect(),cx=r.left+r.width/2,cy=r.top+r.height/2;\n  const radius=Math.tan(cfg.triggerFov*Math.PI/180)*r.height*.5;\n  let best=null,bestScore=Infinity;\n  for(const entity of game.allEntities()){\n    if(!entity||entity===me||!entity.alive||entity.isPlayer||cfg.triggerTeamCheck&&entity.team===me.team)continue;\n    const distance=Math.hypot(entity.x-me.x,entity.y-me.y,entity.z-me.z);\n    if(cfg.triggerMaxDistance>0&&distance>cfg.triggerMaxDistance)continue;\n    const base=entity._visY??entity.y,height=entity.height||1.8;\n    const points=cfg.triggerRegion===\"head\"?[.85]:cfg.triggerRegion===\"chest\"?[.55]:[.85,.55];\n    let visibility=null;\n    for(const fraction of points){\n      const y=base+height*fraction,p=project(entity.x,y,entity.z);\n      if(!p)continue;\n      const score=Math.hypot(p.x-cx,p.y-cy);\n      if(score>radius||score>=bestScore)continue;\n      if(cfg.triggerVisibleOnly){\n        if(visibility===null)visibility=triggerVisibilityPass(entity);\n        if(!visibility)continue;\n      }\n      best=entity;bestScore=score;\n    }\n  }\n  return best;\n}\nfunction triggerMouse(type){\n  if(!canvas)return;\n  const r=canvas.getBoundingClientRect();\n  const event=new MouseEvent(type,{bubbles:true,cancelable:true,button:0,buttons:type===\"mousedown\"?1:0,clientX:r.left+r.width/2,clientY:r.top+r.height/2});\n  Object.defineProperty(event,\"__debugTrigger\",{value:true});canvas.dispatchEvent(event);\n}\nfunction releaseTrigger(){\n  if(triggerPressed){triggerPressed=false;if(!mouseHeld)triggerMouse(\"mouseup\")}\n}\nfunction triggerTick(){\n  releaseTrigger();\n  const active=cfg.trigger&&window[K]&&game.state===\"playing\"&&game.player?.alive&&!game.frozen&&document.hasFocus()&&document.pointerLockElement===canvas&&!bindingCapture&&!activeBindPop;\n  triggerCircle.style.display=active&&cfg.triggerShowFov?\"block\":\"none\";\n  if(active&&cfg.triggerShowFov){\n    const r=canvas.getBoundingClientRect(),d=Math.tan(cfg.triggerFov*Math.PI/180)*r.height;\n    Object.assign(triggerCircle.style,{left:(r.left+(r.width-d)/2)+\"px\",top:(r.top+(r.height-d)/2)+\"px\",width:d+\"px\",height:d+\"px\",borderColor:cfg.triggerFovColor});\n  }\n  if(!active||mouseHeld){triggerCandidate=null;triggerSince=0;return}\n  const candidate=findTriggerTarget(),now=performance.now();\n  if(!candidate){triggerCandidate=null;triggerSince=0;return}\n  if(candidate!==triggerCandidate){triggerCandidate=candidate;triggerSince=now}\n  if(now-triggerSince<cfg.triggerDelay)return;\n  triggerPressed=true;triggerMouse(\"mousedown\");\n}\nconst triggerTimer=setInterval(triggerTick,25);\nwindow[K].triggerCleanup=()=>{clearInterval(triggerTimer);releaseTrigger();triggerCircle.remove()};\n\ntheme.textContent+=\"\\n/* Keep navigation and footer visible; scroll only the active tab. */\\n#__testGUI{display:flex;flex-direction:column;box-sizing:border-box!important;width:min(660px,calc(100vw - 24px))!important;height:min(780px,calc(100dvh - 24px))!important;max-height:calc(100dvh - 24px)!important;min-height:0!important;overflow:hidden!important}\\n#__testGUI #guiHead,#__testGUI #guiTabs,#__testGUI>button:last-child{flex:0 0 auto}\\n#__testGUI #guiTabs{min-width:0;flex-wrap:wrap}\\n#__testGUI :is(#combatTab,#movementTab,#visualsTab,#worldTab,#inventoryTab,#casesTab,#privateTab,#settingsTab){flex:1 1 0%;min-height:0!important;max-height:none!important;min-width:0;overflow-y:auto!important;overflow-x:hidden!important;overscroll-behavior:contain;box-sizing:border-box;scrollbar-gutter:stable;column-count:1!important}\\n#__testGUI .combatSections{display:grid;grid-template-columns:minmax(0,1fr) minmax(0,1fr);gap:12px;align-items:start;grid-template-rows:auto auto}\\n#__testGUI #aimSection{grid-column:1;grid-row:1 / span 2}\\n#__testGUI #weaponSection{grid-column:2;grid-row:1}\\n#__testGUI #triggerSection{grid-column:2;grid-row:2}\\n#__testGUI .combatSections section{box-sizing:border-box;overflow-wrap:anywhere}\\n#__testGUI input[type=range]{box-sizing:border-box;max-width:100%}\\n@media(max-width:560px){#__testGUI .combatSections{grid-template-columns:minmax(0,1fr)}#__testGUI :is(#aimSection,#weaponSection,#triggerSection){grid-column:auto;grid-row:auto}}\\n\";\ntheme.textContent+=\"\\n/* A single scroll container per tab; avoid multicolumn fragmentation. */\\n#__testGUI{height:min(780px,calc(100dvh - 24px))!important;overflow:hidden!important}\\n#__testGUI #guiHead,#__testGUI #guiTabs{flex-shrink:0!important}\\n#__testGUI :is(#combatTab,#movementTab,#visualsTab,#worldTab,#inventoryTab,#casesTab,#privateTab,#settingsTab){height:0!important;flex:1 1 auto!important;min-height:0!important;max-height:none!important;overflow-y:scroll!important;overflow-x:hidden!important;column-count:auto!important;column-width:auto!important;columns:auto!important;touch-action:pan-y;scrollbar-width:thin;scrollbar-color:var(--green) #19171f}\\n#__testGUI :is(#combatTab,#movementTab,#visualsTab)>*{break-inside:auto!important}\\n#__testGUI .combatSections{height:auto!important;min-height:0!important;overflow:visible!important}\\n\";\n\nconst worldCfg={brightness:false,brightnessMult:1,ambient:false,ambientColor:\"#ffffff\",background:false,backgroundColor:\"#8299b5\",fog:false,fogMode:\"remove\",fogColor:\"#9caabd\",fogNear:5,fogFar:100,fogDensity:.015};\nlet worldScene=null,worldBackground=null,worldFog=null;\nconst worldLightLevels=new Map(),worldLightColors=new Map();\nfunction worldLights(scene){const result=[];scene?.traverse?.(object=>{if(object.isLight)result.push(object)});return result}\nfunction restoreWorld(){\n  if(worldBackground&&worldScene)worldScene.background=worldBackground.original;\n  if(worldFog&&worldScene)worldScene.fog=worldFog.original;\n  for(const [light,value]of worldLightLevels)light.intensity=value;\n  for(const [light,value]of worldLightColors)light.color.copy(value);\n  worldLightLevels.clear();worldLightColors.clear();worldBackground=null;worldFog=null;\n}\nfunction syncWorld(){\n  const scene=game.scene;\n  if(scene!==worldScene){restoreWorld();worldScene=scene}\n  if(!scene)return;\n  const lights=worldLights(scene);\n  if(worldCfg.brightness){\n    const active=new Set(lights);\n    for(const [light,value]of worldLightLevels)if(!active.has(light)){light.intensity=value;worldLightLevels.delete(light)}\n    for(const light of lights){\n      if(!Number.isFinite(light.intensity))continue;\n      if(!worldLightLevels.has(light))worldLightLevels.set(light,light.intensity);\n      light.intensity=worldLightLevels.get(light)*worldCfg.brightnessMult;\n    }\n  }else{for(const [light,value]of worldLightLevels)light.intensity=value;worldLightLevels.clear()}\n  if(worldCfg.ambient){\n    const active=new Set(lights.filter(light=>light.isAmbientLight||light.isHemisphereLight));\n    for(const [light,value]of worldLightColors)if(!active.has(light)){light.color.copy(value);worldLightColors.delete(light)}\n    for(const light of active)if(light.color?.clone&&light.color?.set){\n      if(!worldLightColors.has(light))worldLightColors.set(light,light.color.clone());\n      light.color.set(worldCfg.ambientColor);\n    }\n  }else{for(const [light,value]of worldLightColors)light.color.copy(value);worldLightColors.clear()}\n  if(worldCfg.background){\n    if(worldBackground&&scene.background!==worldBackground.applied)worldBackground=null;\n    if(!worldBackground){\n      const color=[scene.background,scene.fog?.color,...lights.map(light=>light.color)].find(color=>color?.isColor&&color.clone&&color.set);\n      if(color)worldBackground={original:scene.background,applied:color.clone()};\n    }\n    if(worldBackground){worldBackground.applied.set(worldCfg.backgroundColor);scene.background=worldBackground.applied}\n  }else if(worldBackground){scene.background=worldBackground.original;worldBackground=null}\n  if(worldCfg.fog){\n    if(worldFog&&scene.fog!==worldFog.applied)worldFog=null;\n    if(!worldFog)worldFog={original:scene.fog,applied:scene.fog,custom:null};\n    if(worldCfg.fogMode===\"remove\"){scene.fog=null;worldFog.applied=null}\n    else{\n      const source=worldFog.original;\n      if(source?.clone){\n        if(!worldFog.custom)worldFog.custom=source.clone();\n        const custom=worldFog.custom;custom.color?.set(worldCfg.fogColor);\n        if(custom.isFog){custom.near=worldCfg.fogNear;custom.far=Math.max(worldCfg.fogNear+.1,worldCfg.fogFar)}\n        if(custom.isFogExp2)custom.density=worldCfg.fogDensity;\n        scene.fog=custom;worldFog.applied=custom;\n      }else{scene.fog=source;worldFog.applied=source}\n    }\n  }else if(worldFog){scene.fog=worldFog.original;worldFog=null}\n}\n\n\n\nconst worldCameraCfg={fov:false,fovAmount:74,third:false,distance:3,height:.3,shoulder:.35,collision:true,exposure:false,exposureAmount:1.12};\nlet worldFovOriginal=null,worldExposureOriginal=null,worldViewDepth=0,worldAgent=null,worldAgentPending=false,worldAgentGeneration=0,worldAgentTeam=null,worldAgentWeapon=null,worldAgentError=\"\",worldCameraDisposed=false;\nconst worldRenderRecords=[];\nconst originalWorldSetFov=game.setFov;\nfunction worldSetFov(amount,scoped){return originalWorldSetFov.call(this,worldCameraCfg.fov&&!scoped?worldCameraCfg.fovAmount:amount,scoped)}\nif(typeof originalWorldSetFov===\"function\")game.setFov=worldSetFov;\nfunction syncCameraSettings(){\n  const camera=game.camera;\n  if(worldCameraCfg.fov&&camera?.updateProjectionMatrix){\n    if(!worldFovOriginal)worldFovOriginal={base:game.baseFov,fov:camera.fov};\n    game.baseFov=worldCameraCfg.fovAmount;\n    if(!game.scoped&&camera.fov!==worldCameraCfg.fovAmount){camera.fov=worldCameraCfg.fovAmount;camera.updateProjectionMatrix()}\n  }else if(worldFovOriginal){\n    game.baseFov=worldFovOriginal.base;\n    if(!game.scoped&&camera?.updateProjectionMatrix){camera.fov=worldFovOriginal.fov;camera.updateProjectionMatrix()}\n    worldFovOriginal=null;\n  }\n  const renderer=game.renderer;\n  if(worldCameraCfg.exposure&&Number.isFinite(renderer?.toneMappingExposure)){\n    if(worldExposureOriginal&&worldExposureOriginal.renderer!==renderer){worldExposureOriginal.renderer.toneMappingExposure=worldExposureOriginal.value;worldExposureOriginal=null}\n    if(!worldExposureOriginal)worldExposureOriginal={renderer,value:renderer.toneMappingExposure};\n    renderer.toneMappingExposure=worldCameraCfg.exposureAmount;\n  }else if(worldExposureOriginal){worldExposureOriginal.renderer.toneMappingExposure=worldExposureOriginal.value;worldExposureOriginal=null}\n  if(!worldCameraCfg.third){worldAgentError=\"\";if(worldAgent)worldAgent.root.visible=false;if(window[K])window[K].worldViewCamera=null}\n  installWorldRenderHooks();\n}\nfunction thirdPersonActive(){return worldCameraCfg.third&&game.state===\"playing\"&&game.player?.alive&&!game._topCam}\nfunction clearWorldAgent(){\n  worldAgentGeneration++;worldAgentPending=false;\n  if(worldAgent){worldAgent.root.removeFromParent();worldAgent.dispose?.();worldAgent=null}\n  worldAgentTeam=null;worldAgentWeapon=null;\n}\nfunction ensureWorldAgent(){\n  if(!thirdPersonActive())return;\n  const team=game.player.team;if(![\"CT\",\"T\"].includes(team))return;\n  if(worldAgent&&worldAgentTeam!==team)clearWorldAgent();\n  if(worldAgent||worldAgentPending||worldAgentError)return;\n  const template=game.previewAgent||(game.botMgr?.bots||[]).map(bot=>bot.cs2Agent).find(agent=>agent?.load&&agent?.setTransform);\n  if(!template?.constructor||!template.load)return;\n  const generation=++worldAgentGeneration;worldAgentPending=true;\n  let agent;\n  try{agent=new template.constructor(game.renderer)}catch(error){worldAgentPending=false;worldAgentError=\"Player body could not be created.\";return}\n  Promise.resolve(agent.load(team)).then(loaded=>{\n    if(generation!==worldAgentGeneration||worldCameraDisposed){(loaded||agent).dispose?.();return}\n    worldAgent=loaded||agent;worldAgentTeam=team;worldAgentPending=false;worldAgentError=\"\";worldAgent.root.visible=false;\n  }).catch(()=>{agent.dispose?.();if(generation===worldAgentGeneration){worldAgentPending=false;worldAgentError=\"Player body could not be loaded.\"}});\n}\nfunction thirdPersonPosition(camera){\n  const forward=camera.position.clone();camera.getWorldDirection(forward);\n  const right=camera.position.clone().set(Math.cos(game.player.yaw),0,-Math.sin(game.player.yaw));\n  const origin=camera.position.clone(),desired=origin.clone().addScaledVector(forward,-worldCameraCfg.distance).addScaledVector(right,worldCameraCfg.shoulder);\n  desired.y+=worldCameraCfg.height;\n  if(worldCameraCfg.collision){\n    const travel=desired.clone().sub(origin),length=travel.length();\n    if(length>0&&game.physics?.raycast){\n      travel.multiplyScalar(1/length);\n      // A small fan of parallel casts leaves room for the camera's near plane.\n      let allowed=length;\n      for(const [side,up]of [[0,0],[.12,0],[-.12,0],[0,.12],[0,-.12]]){\n        const hit=game.physics.raycast(origin.x+right.x*side,origin.y+up,origin.z+right.z*side,travel.x,travel.y,travel.z,length,0x2);\n        if(hit&&Number.isFinite(hit.t))allowed=Math.min(allowed,Math.max(0,hit.t-.18));\n      }\n      desired.copy(origin).addScaledVector(travel,allowed);\n    }\n  }\n  return desired;\n}\nfunction withWorldView(render){\n  if(worldViewDepth)return render();\n  syncCameraSettings();\n  if(!thirdPersonActive()){if(window[K])window[K].worldViewCamera=null;return render()}\n  const camera=game.camera;if(!camera?.getWorldDirection)return render();\n  const position=camera.position.clone(),quaternion=camera.quaternion.clone();\n  const viewmodelScene=game.viewmodel?.scene,viewmodelVisible=viewmodelScene?.visible;\n  worldViewDepth++;\n  try{\n    camera.position.copy(thirdPersonPosition(camera));camera.updateMatrixWorld(true);\n    if(window[K]){const copy=window[K].worldViewCamera||camera.clone();copy.copy(camera);copy.updateMatrixWorld(true);window[K].worldViewCamera=copy}\n    if(viewmodelScene)viewmodelScene.visible=false;\n    ensureWorldAgent();\n    if(worldAgent){\n      if(worldAgent.root.parent!==game.scene)game.scene.add(worldAgent.root);\n      const p=game.player;worldAgent.setTransform(p.x,p.y,p.z,p.yaw);worldAgent.root.visible=true;\n      worldAgent.update?.(Math.min(.05,1/(game.fpsCap||60)),{vx:p.vx||0,vz:p.vz||0,crouch:p.crouching?1:0,airborne:!p.onGround});\n      const weapon=game.weapons?.current;\n      if(weapon&&worldAgentWeapon!==weapon&&worldAgent.setWeapon){worldAgentWeapon=weapon;try{Promise.resolve(worldAgent.setWeapon(weapon,game.weapons.def?.()?.class)).catch(()=>{})}catch{}}\n    }\n    return render();\n  }finally{\n    camera.position.copy(position);camera.quaternion.copy(quaternion);camera.updateMatrixWorld(true);\n    if(viewmodelScene)viewmodelScene.visible=viewmodelVisible;\n    if(worldAgent)worldAgent.root.visible=false;\n    worldViewDepth--;\n  }\n}\nfunction installWorldRenderHooks(){\n  for(const [object,type]of [[game.renderer,\"renderer\"],[game.postfx,\"postfx\"]]){\n    if(!object||typeof object.render!==\"function\"||worldRenderRecords.some(record=>record.object===object))continue;\n    const original=object.render;\n    const hook=function(...args){\n      if(type===\"renderer\"&&thirdPersonActive()&&args[0]===game.viewmodel?.scene)return;\n      if(type===\"postfx\"&&game.state===\"playing\"||type===\"renderer\"&&args[0]===game.scene&&args[1]===game.camera)return withWorldView(()=>original.apply(this,args));\n      return original.apply(this,args);\n    };\n    object.render=hook;worldRenderRecords.push({object,original,hook});\n  }\n}\nfunction cleanupWorldCamera(){\n  worldCameraDisposed=true;worldCameraCfg.fov=false;worldCameraCfg.exposure=false;worldCameraCfg.third=false;syncCameraSettings();\n  for(const {object,original,hook}of worldRenderRecords)if(object.render===hook)object.render=original;\n  if(game.setFov===worldSetFov)game.setFov=originalWorldSetFov;\n  clearWorldAgent();if(window[K])delete window[K].worldViewCamera;\n}\nconst originalEnvironmentSync=syncWorld;\nsyncWorld=function(){originalEnvironmentSync();syncCameraSettings()};\n\n\nconst worldMapMaterials=new Map();let worldSkyVisibility=null;\nfunction restoreMapColors(){\n  for(const [material,original]of worldMapMaterials)material.color.copy(original);\n  worldMapMaterials.clear();\n  if(worldSkyVisibility){worldSkyVisibility.sky.visible=worldSkyVisibility.visible;worldSkyVisibility=null}\n}\nfunction syncMapColors(){\n  const seen=new Set();\n  if(worldCfg.ambient)game._mapRoot?.traverse?.(mesh=>{\n    if(!mesh.isMesh||!mesh.material||mesh.isSkinnedMesh)return;\n    for(const material of Array.isArray(mesh.material)?mesh.material:[mesh.material]){\n      if(!material?.color?.clone||!material.color.copy||!material.color.multiply||seen.has(material))continue;\n      seen.add(material);\n      if(!worldMapMaterials.has(material))worldMapMaterials.set(material,material.color.clone());\n      const original=worldMapMaterials.get(material),tint=original.clone().set(worldCfg.ambientColor);\n      // Preserve material identity, shader callbacks, texture arrays, and alpha/depth settings.\n      material.color.copy(original).multiply(tint);\n    }\n  });\n  for(const [material,original]of worldMapMaterials)if(!seen.has(material)){\n    material.color.copy(original);worldMapMaterials.delete(material);\n  }\n  if(worldSkyVisibility&&(!worldCfg.background||worldSkyVisibility.sky!==game._sky)){\n    worldSkyVisibility.sky.visible=worldSkyVisibility.visible;worldSkyVisibility=null;\n  }\n  if(worldCfg.background&&game._sky){\n    if(!worldSkyVisibility)worldSkyVisibility={sky:game._sky,visible:game._sky.visible};\n    game._sky.visible=false;\n  }\n}\nconst previousMapWorldSync=syncWorld;\nsyncWorld=function(){previousMapWorldSync();syncMapColors()};\nconst previousMapWorldRestore=restoreWorld;\nrestoreWorld=function(){restoreMapColors();previousMapWorldRestore()};\n\nconst worldGrid=document.createElement(\"div\");worldGrid.className=\"debug-card-grid\";worldBody.appendChild(worldGrid);\nconst worldCards=[];\nfunction worldCard(title,key){\n  const card=document.createElement(\"section\");card.className=\"debug-card\";\n  const heading=document.createElement(\"h3\");heading.textContent=title;card.appendChild(heading);\n  const label=document.createElement(\"label\"),toggle=document.createElement(\"input\");toggle.type=\"checkbox\";\n  label.append(toggle,document.createTextNode(\" Enable \"+title));card.appendChild(label);\n  const details=document.createElement(\"div\");details.className=\"debug-collapse\";details.hidden=true;card.appendChild(details);\n  toggle.onchange=()=>{worldCfg[key]=toggle.checked;details.hidden=!toggle.checked;syncWorld();refreshWorldAvailability()};\n  const status=document.createElement(\"div\");status.setAttribute(\"role\",\"status\");status.style.marginTop=\"8px\";card.appendChild(status);\n  const record={card,key,toggle,details,status};worldCards.push(record);worldGrid.appendChild(card);return record;\n}\nfunction worldRange(record,label,key,min,max,step){\n  const row=document.createElement(\"label\"),value=document.createElement(\"span\"),range=document.createElement(\"input\");\n  row.appendChild(document.createTextNode(label+\": \"));row.appendChild(value);value.textContent=worldCfg[key];\n  range.type=\"range\";range.min=min;range.max=max;range.step=step;range.value=worldCfg[key];range.style.width=\"100%\";\n  range.oninput=()=>{worldCfg[key]=Number(range.value);value.textContent=range.value;syncWorld()};\n  row.appendChild(range);record.details.appendChild(row);return row;\n}\nfunction worldColor(record,label,key){\n  const row=document.createElement(\"label\");row.className=\"setting-line\";row.textContent=label;\n  const input=document.createElement(\"input\");input.type=\"color\";input.value=worldCfg[key];input.setAttribute(\"aria-label\",label);\n  input.oninput=()=>{worldCfg[key]=input.value;syncWorld()};row.appendChild(input);record.details.appendChild(row);\n}\nconst worldBrightnessCard=worldCard(\"Lighting Brightness\",\"brightness\");worldRange(worldBrightnessCard,\"Light Multiplier\",\"brightnessMult\",0,3,.05);\nconst worldAmbientCard=worldCard(\"World / Ambient Tint\",\"ambient\");worldColor(worldAmbientCard,\"Map & Ambient Color\",\"ambientColor\");\nconst worldBackgroundCard=worldCard(\"Sky / Background\",\"background\");worldColor(worldBackgroundCard,\"Background Color\",\"backgroundColor\");\nconst backgroundNote=document.createElement(\"p\");backgroundNote.className=\"settings-help\";backgroundNote.textContent=\"Replaces the original sky with a solid background color. Switching this off restores the original sky.\";worldBackgroundCard.details.appendChild(backgroundNote);\nconst worldFogCard=worldCard(\"Fog\",\"fog\");\nconst fogModeRow=document.createElement(\"label\");fogModeRow.textContent=\"Fog Mode\";\nconst fogModeSelect=document.createElement(\"select\");fogModeSelect.style.cssText=\"display:block;width:100%;margin:5px 0 12px\";\nfor(const [value,label]of [[\"remove\",\"Remove Fog\"],[\"custom\",\"Custom Fog\"]]){const option=document.createElement(\"option\");option.value=value;option.textContent=label;fogModeSelect.appendChild(option)}\nfogModeSelect.value=worldCfg.fogMode;fogModeSelect.onchange=()=>{worldCfg.fogMode=fogModeSelect.value;syncWorld();refreshWorldAvailability()};fogModeRow.appendChild(fogModeSelect);worldFogCard.details.appendChild(fogModeRow);\nconst fogCustom=document.createElement(\"div\");worldFogCard.details.appendChild(fogCustom);\nworldColor({details:fogCustom},\"Fog Color\",\"fogColor\");\nconst worldFogNearRow=worldRange({details:fogCustom},\"Fog Start\",\"fogNear\",0,100,1);\nconst worldFogFarRow=worldRange({details:fogCustom},\"Fog End\",\"fogFar\",1,500,1);\nconst worldFogDensityRow=worldRange({details:fogCustom},\"Fog Density\",\"fogDensity\",0,.1,.001);\nfunction refreshWorldAvailability(){\n  const scene=game.scene,lights=worldLights(scene),originalFog=worldFog?.original??scene?.fog;\n  const hasColor=[scene?.background,originalFog?.color,...lights.map(light=>light.color)].some(color=>color?.isColor&&color.clone&&color.set);\n  for(const record of worldCards){\n    const supported=record.key===\"brightness\"?lights.some(light=>Number.isFinite(light.intensity)):record.key===\"ambient\"?(!!game._mapRoot?.traverse||lights.some(light=>(light.isAmbientLight||light.isHemisphereLight)&&light.color?.clone)):record.key===\"background\"?hasColor:!!originalFog;\n    record.toggle.disabled=!supported&&!record.toggle.checked;\n    record.status.textContent=!scene?\"Load a map to use this control.\":!supported?(record.key===\"fog\"?\"This map has no scene fog to customize.\":record.key===\"ambient\"?\"No supported map materials or ambient lights found.\":record.key===\"brightness\"?\"No supported scene lights found.\":\"No supported scene color found.\"):record.key===\"fog\"&&worldCfg.fog&&worldCfg.fogMode===\"custom\"&&!originalFog?.clone?\"Custom fog is unavailable for this map.\":\"\";\n  }\n  const canCustomize=!!originalFog?.clone;\n  fogModeSelect.options[1].disabled=!canCustomize;\n  fogCustom.hidden=worldCfg.fogMode!==\"custom\"||!canCustomize;\n  worldFogNearRow.hidden=!originalFog?.isFog;worldFogFarRow.hidden=!originalFog?.isFog;worldFogDensityRow.hidden=!originalFog?.isFogExp2;\n}\n\nfunction worldCameraCard(title,key){\n  const card=document.createElement(\"section\");card.className=\"debug-card\";\n  const heading=document.createElement(\"h3\");heading.textContent=title;card.appendChild(heading);\n  const label=document.createElement(\"label\"),toggle=document.createElement(\"input\");toggle.type=\"checkbox\";label.append(toggle,document.createTextNode(\" Enable \"+title));card.appendChild(label);\n  const details=document.createElement(\"div\");details.className=\"debug-collapse\";details.hidden=true;card.appendChild(details);\n  const status=document.createElement(\"div\");status.setAttribute(\"role\",\"status\");card.appendChild(status);\n  toggle.onchange=()=>{worldCameraCfg[key]=toggle.checked;details.hidden=!toggle.checked;syncCameraSettings()};\n  if(key===\"third\")attachBind(label,\"Third Person\",\"world:third\",()=>worldCameraCfg.third,value=>{worldCameraCfg.third=value;details.hidden=!value;syncCameraSettings()},()=>{toggle.checked=worldCameraCfg.third});\n  worldGrid.prepend(card);return{card,details,status,toggle,key};\n}\nfunction cameraRange(record,label,key,min,max,step){\n  const row=document.createElement(\"label\"),value=document.createElement(\"span\"),range=document.createElement(\"input\");\n  row.appendChild(document.createTextNode(label+\": \"));value.textContent=worldCameraCfg[key];row.appendChild(value);\n  range.type=\"range\";range.min=min;range.max=max;range.step=step;range.value=worldCameraCfg[key];range.style.width=\"100%\";\n  range.oninput=()=>{worldCameraCfg[key]=Number(range.value);value.textContent=range.value;syncCameraSettings()};row.appendChild(range);record.details.appendChild(row);\n}\nconst exposureCard=worldCameraCard(\"Exposure\",\"exposure\");cameraRange(exposureCard,\"Exposure\",\"exposureAmount\",.1,3,.05);\nconst thirdCard=worldCameraCard(\"Third Person\",\"third\");cameraRange(thirdCard,\"Distance\",\"distance\",.5,8,.1);cameraRange(thirdCard,\"Height Offset\",\"height\",-.5,2,.05);cameraRange(thirdCard,\"Shoulder Offset\",\"shoulder\",-1.5,1.5,.05);\nconst collisionLabel=document.createElement(\"label\"),collisionToggle=document.createElement(\"input\");collisionToggle.type=\"checkbox\";collisionToggle.checked=true;collisionLabel.append(collisionToggle,document.createTextNode(\" Avoid Camera Clipping\"));collisionToggle.onchange=()=>{worldCameraCfg.collision=collisionToggle.checked};thirdCard.details.appendChild(collisionLabel);\nconst cameraFovCard=worldCameraCard(\"Camera Field of View\",\"fov\");cameraRange(cameraFovCard,\"FOV (degrees)\",\"fovAmount\",50,120,1);\nconst cameraNote=document.createElement(\"p\");cameraNote.className=\"settings-help\";cameraNote.textContent=\"Camera FOV preserves scope zoom. Third person moves the view; shots keep the game's first-person direction.\";cameraFovCard.details.appendChild(cameraNote);\nconst originalWorldAvailability=refreshWorldAvailability;\nrefreshWorldAvailability=function(){\n  originalWorldAvailability();\n  const camera=game.camera,exposureAvailable=Number.isFinite(game.renderer?.toneMappingExposure);\n  cameraFovCard.toggle.disabled=!camera?.updateProjectionMatrix;exposureCard.toggle.disabled=!exposureAvailable;\n  thirdCard.toggle.disabled=!camera?.getWorldDirection||!game.renderer?.render;\n  thirdCard.status.textContent=!worldCameraCfg.third?\"\":worldAgentError||(!game.player?.alive?\"Active while your character is alive.\":worldAgentPending?\"Loading player body…\":!worldAgent?\"Camera ready. Player body loads when an agent model is available.\":\"\");\n  exposureCard.status.textContent=exposureAvailable?\"\":\"Exposure is unavailable on this renderer.\";\n};\n\nsyncWorld();refreshWorldAvailability();\nconst worldTimer=setInterval(()=>{syncWorld();refreshWorldAvailability()},250);\nwindow[K].worldCleanup=()=>{clearInterval(worldTimer);cleanupWorldCamera();restoreWorld()};\n\nui.appendChild(theme);\n\n// Scroll manually so the game's wheel cancellation cannot disable menu scrolling.\nfunction scrollMenuWheel(event){\n  if(ui.style.display===\"none\"||!ui.contains(event.target))return;\n  const tab=event.target.closest?.(\"#combatTab,#movementTab,#visualsTab,#worldTab,#inventoryTab,#casesTab,#privateTab,#settingsTab\");\n  if(!tab||event.ctrlKey)return;\n  let scrollTarget=event.target instanceof Element?event.target:tab;\n  while(scrollTarget!==tab){\n    const overflow=getComputedStyle(scrollTarget).overflowY;\n    if((overflow===\"auto\"||overflow===\"scroll\")&&scrollTarget.scrollHeight>scrollTarget.clientHeight)break;\n    scrollTarget=scrollTarget.parentElement||tab;\n  }\n  const unit=event.deltaMode===1?20:event.deltaMode===2?scrollTarget.clientHeight:1;\n  scrollTarget.scrollTop+=event.deltaY*unit;\n  event.preventDefault();event.stopImmediatePropagation();\n}\nwindow.addEventListener(\"wheel\",scrollMenuWheel,{capture:true,passive:false});\nconst previousScrollCleanup=window[K].keybindCleanup;\nwindow[K].keybindCleanup=()=>{window.removeEventListener(\"wheel\",scrollMenuWheel,true);previousScrollCleanup?.()};\n\n\nfunction fitMenuToViewport(){\n  if(ui.style.display===\"none\")return;\n  const r=ui.getBoundingClientRect(),margin=12;\n  const maxLeft=Math.max(margin,window.innerWidth-r.width-margin);\n  const maxTop=Math.max(margin,window.innerHeight-r.height-margin);\n  ui.style.left=Math.min(maxLeft,Math.max(margin,r.left))+\"px\";\n  ui.style.top=Math.min(maxTop,Math.max(margin,r.top))+\"px\";\n}\nui.style.display=\"flex\";\nfitMenuToViewport();\nwindow.addEventListener(\"resize\",fitMenuToViewport);\nconst previousViewportCleanup=window[K].keybindCleanup;\nwindow[K].keybindCleanup=()=>{window.removeEventListener(\"resize\",fitMenuToViewport);previousViewportCleanup?.()};\n\nconst themeTabs=[...tabs.querySelectorAll(\"button\")];\ntabs.setAttribute(\"role\",\"tablist\");\nfor(const [index,button] of themeTabs.entries()){\n  button.setAttribute(\"role\",\"tab\");\n  button.setAttribute(\"aria-selected\",String(index===0));\n  button.addEventListener(\"click\",()=>{for(const other of themeTabs)other.setAttribute(\"aria-selected\",String(other===button))});\n}\nfor(const input of ui.querySelectorAll('input[type=\"range\"]')){\n  const paint=()=>{const min=Number(input.min),max=Number(input.max);input.style.setProperty(\"--fill\",((Number(input.value)-min)/(max-min)*100)+\"%\")};\n  input.addEventListener(\"input\",paint);paint();\n}\n\nlet dragPointer=null,dragOffsetX=0,dragOffsetY=0;\nconst head=ui.querySelector(\"#guiHead\");head.style.touchAction=\"none\";\nfunction endMenuDrag(){\n  const pointer=dragPointer;dragPointer=null;\n  if(pointer!==null&&head.hasPointerCapture?.(pointer))head.releasePointerCapture(pointer);\n}\nfunction beginMenuDrag(event){\n  if(event.button!==0||event.isPrimary===false||event.target.closest?.(\"button,input,select,a\"))return;\n  const bounds=ui.getBoundingClientRect();\n  dragOffsetX=event.clientX-bounds.left;dragOffsetY=event.clientY-bounds.top;dragPointer=event.pointerId;\n  try{head.setPointerCapture(event.pointerId)}catch{}\n  event.preventDefault();\n}\nfunction moveMenuDrag(event){\n  if(dragPointer===null||event.pointerId!==dragPointer)return;\n  if(!(event.buttons&1)){endMenuDrag();return}\n  ui.style.left=event.clientX-dragOffsetX+\"px\";ui.style.top=event.clientY-dragOffsetY+\"px\";\n  fitMenuToViewport();\n}\nfunction releaseMenuDrag(event){if(event.pointerId===dragPointer)endMenuDrag()}\nhead.addEventListener(\"pointerdown\",beginMenuDrag);\nhead.addEventListener(\"lostpointercapture\",releaseMenuDrag);\nwindow.addEventListener(\"pointermove\",moveMenuDrag,true);\nwindow.addEventListener(\"pointerup\",releaseMenuDrag,true);\nwindow.addEventListener(\"pointercancel\",releaseMenuDrag,true);\nwindow.addEventListener(\"blur\",endMenuDrag);\nconst previousDragCleanup=window[K].keybindCleanup;\nwindow[K].keybindCleanup=()=>{\n  endMenuDrag();head.removeEventListener(\"pointerdown\",beginMenuDrag);head.removeEventListener(\"lostpointercapture\",releaseMenuDrag);\n  window.removeEventListener(\"pointermove\",moveMenuDrag,true);window.removeEventListener(\"pointerup\",releaseMenuDrag,true);window.removeEventListener(\"pointercancel\",releaseMenuDrag,true);window.removeEventListener(\"blur\",endMenuDrag);\n  previousDragCleanup?.();\n};\n\nfunction stopMenuMouse(event){event.stopPropagation()}\nfor(const type of [\"mousedown\",\"mouseup\",\"click\"])ui.addEventListener(type,stopMenuMouse);\ndocument.addEventListener(\"pointerlockchange\",unlockMenuPointer);\n// The menu starts open; remember the original lock before releasing it.\nmenuRestorePointerLock=!!(game.input?.locked||document.pointerLockElement===canvas&&canvas);\nunlockMenuPointer();\nconst previousMenuPointerCleanup=window[K].keybindCleanup;\nwindow[K].keybindCleanup=()=>{\n  document.removeEventListener(\"pointerlockchange\",unlockMenuPointer);\n  for(const type of [\"mousedown\",\"mouseup\",\"click\"])ui.removeEventListener(type,stopMenuMouse);\n  previousMenuPointerCleanup?.();\n};\n\n\n})()"
}
