SOURCE / PINNED RELEASE
Made of little things.
Black Site
- Release
- 666bc7c74ebd…
- Author-recorded commit
- 05e95af79676…
- License
- Check the original source
- Author’s source reference
- nostr://npub12lm3rxsva8kfempyjkxupt09e02n3fezurkyadyqfejdc5e0r2kscqty6r/wss%3A%2F%2Fgit.napplet.soy%2F/n-d2225ddc391
The hash-verified playable HTML, which may contain bundled or minified code. This view does not execute it.
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" /><title>Black Site</title><meta name="description" content="Top-down tactical extraction shooter. See only what is in your field of view, loot supply caches, fight through five maps, call in the helicopter and survive until it lands. Includes a campaign, four characters, an armory and three difficulties."><meta name="napplet-id" content="black-site">
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<script type="module" crossorigin>function e(){let e=window;if(!e.napplet)throw Error(`window.napplet is unavailable -- runtime did not inject the napplet namespace`);return e.napplet}function t(t){let n=e()[t];if(!n)throw Error(`window.napplet.${String(t)} is unavailable -- runtime did not inject this domain`);return n}var n={getItem(e){return t(`storage`).getItem(e)},setItem(e,n){return t(`storage`).setItem(e,n)},removeItem(e){return t(`storage`).removeItem(e)},keys(){return t(`storage`).keys()},instance:{getItem(e){return t(`storage`).instance.getItem(e)},setItem(e,n){return t(`storage`).instance.setItem(e,n)},removeItem(e){return t(`storage`).instance.removeItem(e)},keys(){return t(`storage`).instance.keys()}}},r={registerAction(e){return t(`keys`).registerAction(e)},unregisterAction(e){t(`keys`).unregisterAction(e)},onAction(e,n){return t(`keys`).onAction(e,n)},async register(e,n){let r=t(`keys`),i=await r.registerAction(e),a=r.onAction(e.id,n);return{...i,close(){a.close(),r.unregisterAction(e.id)}}}},i={getPublicKey(){return t(`identity`).getPublicKey()},onChanged(e){return t(`identity`).onChanged(e)},getRelays(){return t(`identity`).getRelays()},getProfile(){return t(`identity`).getProfile()},getFollows(){return t(`identity`).getFollows()},getList(e){return t(`identity`).getList(e)},getZaps(){return t(`identity`).getZaps()},getMutes(){return t(`identity`).getMutes()},getBlocked(){return t(`identity`).getBlocked()},getBadges(){return t(`identity`).getBadges()}},a={info(){return t(`resource`).info()},bytes(e,n){return t(`resource`).bytes(e,n)},bytesMany(e,n){return t(`resource`).bytesMany(e,n)},bytesAsObjectURL(e){return t(`resource`).bytesAsObjectURL(e)}},o={getEvent(e,n){return t(`outbox`).getEvent(e,n)},query(e,n){return t(`outbox`).query(e,n)},subscribe(e,n){return t(`outbox`).subscribe(e,n)},publish(e,n){return t(`outbox`).publish(e,n)},resolveRelays(e){return t(`outbox`).resolveRelays(e)}},s={encodeNip19(e){return t(`common`).encodeNip19(e)},decodeNip19(e){return t(`common`).decodeNip19(e)},getProfile(e){return t(`common`).getProfile(e)},follows(){return t(`common`).follows()},follow(...e){return t(`common`).follow(...e)},unfollow(...e){return t(`common`).unfollow(...e)},react(e,n,r){return t(`common`).react(e,n,r)},report(e,n,r){return t(`common`).report(e,n,r)}};function c(e,t){return!!e?.[t]}function l(e){return c(window.napplet,e)}var u=[{id:`blacksite.primary`,label:`Equip primary weapon`,defaultKey:`1`,code:`Digit1`},{id:`blacksite.secondary`,label:`Equip secondary weapon`,defaultKey:`2`,code:`Digit2`},{id:`blacksite.throwable`,label:`Equip throwable`,defaultKey:`3`,code:`Digit3`},{id:`blacksite.medical`,label:`Equip medical item`,defaultKey:`4`,code:`Digit4`},{id:`blacksite.reload`,label:`Reload`,defaultKey:`r`,code:`KeyR`},{id:`blacksite.knife`,label:`Knife attack`,defaultKey:`q`,code:`KeyQ`},{id:`blacksite.interact`,label:`Interact`,defaultKey:`f`,code:`KeyF`},{id:`blacksite.inventory`,label:`Toggle inventory`,defaultKey:`i`,code:`KeyI`},{id:`blacksite.pause`,label:`Pause or resume`,defaultKey:`p`,code:`KeyP`}];function d(e){return e.isComposing||e.target instanceof Element&&!!e.target.closest(`input, textarea, select, [contenteditable]:not([contenteditable="false"])`)}function f(e,t,n){let i=new Set,a=new Map,o=new Set,s=!1,c,f=e=>{c=e,window.setTimeout(()=>{c===e&&(c=void 0)},0)},p=n=>{n.defaultPrevented||d(n)||n.ctrlKey||n.altKey||n.metaKey||(e(n.code,!0),!n.repeat&&(n.code===`Escape`||u.some(e=>e.code===n.code&&!i.has(e.id)))&&t(n.code))},m=t=>e(t.code,!1),h=()=>{document.hidden&&n()};window.addEventListener(`keydown`,f,!0),window.addEventListener(`keydown`,p),window.addEventListener(`keyup`,m),window.addEventListener(`blur`,n),document.addEventListener(`visibilitychange`,h);let g=e=>{a.get(e)?.close(),a.delete(e),i.delete(e);try{r.unregisterAction(e)}catch{}};if(l(`keys`))for(let{code:n,...l}of u)(async()=>{try{a.set(l.id,r.onAction(l.id,()=>queueMicrotask(()=>{s||c&&(c.repeat||d(c))||(c&&e(c.code,!1),t(n))}))),o.add(l.id),await r.registerAction(l),s?g(l.id):i.add(l.id)}catch(e){g(l.id),console.warn(`Keyboard action ${l.id} unavailable; using local shortcut.`,e)}})();let _=()=>{if(!s){s=!0,window.removeEventListener(`keydown`,f,!0),window.removeEventListener(`keydown`,p),window.removeEventListener(`keyup`,m),window.removeEventListener(`blur`,n),document.removeEventListener(`visibilitychange`,h),window.removeEventListener(`pagehide`,_);for(let e of o)g(e);n()}};return window.addEventListener(`pagehide`,_),_}function p(){let e=[{$schema:`../../../spec/schemas/black-site-map.schema.json`,format:`black-site-map`,version:1,id:`town`,name:`TOWN`,desc:`Streets and houses. Fight through the town to the helipad.`,size:[64,44],theme:{ground:[78,73,60],road:[44,45,47],style:`grass`,clutter:[`T`,`T`,`b`,`c`]},generate:{expand:!0,buildings:16,cover:80},spawns:{extraEnemies:.2,extraCaches:3},start:[3,41],exfil:[57,5],roads:[[1,27,62,28],[36,1,37,42]],buildings:[{r:[10,30,19,37],doors:[[14,30],[15,30],[19,33],[19,34]],walls:[[16,31,16,33]]},{r:[24,33,35,41],doors:[[24,36],[24,37],[28,33],[29,33],[35,38],[35,39]],walls:[[30,34,30,35],[30,38,30,40]]},{r:[8,14,17,23],doors:[[12,23],[13,23],[17,17],[17,18]],walls:[[9,19,12,19]]},{r:[22,16,33,26],doors:[[22,20],[22,21],[29,16],[30,16],[25,26],[26,26],[33,22],[33,23]],walls:[[27,17,27,19],[27,22,27,25]]},{r:[40,30,50,37],doors:[[40,33],[40,34],[45,30],[46,30],[50,32],[50,33]],walls:[[41,35,44,35],[47,35,49,35]]},{r:[38,8,47,17],doors:[[38,11],[38,12],[44,17],[45,17],[47,9],[47,10]],walls:[[42,9,42,11],[42,14,42,16]]},{r:[4,3,13,9],doors:[[8,9],[9,9],[13,5],[13,6]],walls:[]},{r:[52,18,60,25],doors:[[52,21],[52,22],[56,18],[57,18]],walls:[[53,23,55,23]]}],crates:[[6,35],[7,35],[15,26],[19,13],[20,13],[27,30],[28,30],[33,8],[34,8],[44,22],[45,22],[46,22],[55,13],[56,13],[30,12],[12,12],[3,20],[4,20],[60,30],[61,30],[57,38],[48,40],[49,40],[23,8],[16,3],[29,3],[24,23],[31,19],[26,40],[32,35],[43,32],[11,6]],wrecks:[[8,27,9,27],[20,28,21,28],[36,10,36,11],[37,35,37,36],[50,27,51,27],[14,40,15,40]],sandbags:[[6,39,6,41],[29,9,31,9],[47,24,48,24],[20,36,20,37],[58,34,59,34],[51,2,51,4],[51,7,51,10],[52,10,54,10],[58,10,62,10]],enemies:[[9,25,`p`],[21,30,`p`],[31,30,`p`],[38,39,`p`],[45,40,`p`],[20,11,`p`],[34,13,`p`],[49,22,`p`],[57,31,`p`],[60,14,`p`],[15,34],[27,39],[33,35],[11,17],[24,19],[31,24],[43,33],[48,32],[40,14],[45,11],[10,5],[57,21],[54,5],[59,8],[56,3]],caches:[[5,39,`start`],[12,36],[26,34],[34,40,`weapons`],[9,22],[23,25],[32,17],[49,36],[46,16,`weapons`],[5,4],[59,24,`weapons`],[3,21],[61,31],[28,31],[44,34]]},{$schema:`../../../spec/schemas/black-site-map.schema.json`,format:`black-site-map`,version:1,id:`docks`,name:`DOCKYARD`,desc:`Container stacks and warehouses on the waterfront. Extract from the north pier.`,size:[64,44],theme:{ground:[88,88,86],road:[52,53,55],style:`concrete`,clutter:[`b`,`b`,`c`]},generate:{expand:!0,buildings:16,cover:80},spawns:{extraEnemies:.2,extraCaches:3},start:[2,41],exfil:[57,5],water:[[52,1,62,42]],paved:[[52,3,61,7],[52,19,58,22],[52,35,59,38]],roads:[[1,12,50,13],[24,1,25,42]],buildings:[{r:[3,2,20,10],doors:[[10,10],[11,10],[20,5],[20,6]],walls:[[12,3,12,5]]},{r:[28,2,46,9],doors:[[28,5],[28,6],[36,9],[37,9],[46,4],[46,5]],walls:[[37,3,37,4]]},{r:[4,30,18,40],doors:[[10,30],[11,30],[18,35],[18,36]],walls:[[11,31,11,33]]},{r:[36,33,47,41],doors:[[40,33],[41,33],[36,37],[36,38],[47,36],[47,37]],walls:[[41,34,41,35]]}],containers:[[4,15,8,16,`#8a3b2a`],[4,18,8,19,`#2f5a7a`],[12,15,16,16,`#6a7a3a`],[12,19,16,20,`#a87a2a`],[28,15,29,19,`#2f5a7a`],[32,15,33,19,`#8a3b2a`],[36,16,40,17,`#5a5a5a`],[36,20,40,21,`#2f6a5a`],[44,15,45,19,`#a87a2a`],[44,22,48,23,`#8a3b2a`],[28,24,32,25,`#6a7a3a`],[4,24,8,25,`#a87a2a`],[12,25,13,28,`#2f5a7a`],[20,30,21,34,`#8a3b2a`],[28,30,32,31,`#2f5a7a`],[40,26,44,27,`#6a7a3a`]],crates:[[6,22],[7,22],[18,17],[18,18],[22,27],[34,27],[35,27],[47,12],[49,30],[49,31],[30,36],[31,36],[16,8],[40,5],[8,37],[44,39]],wrecks:[[25,20,25,21],[5,13,6,13],[40,12,41,12]],sandbags:[[50,2,50,3],[50,7,50,8],[20,22,21,22],[44,30,45,30],[55,21,56,21]],enemies:[[10,14,`p`],[22,18,`p`],[30,13,`p`],[42,13,`p`],[48,28,`p`],[26,35,`p`],[34,22,`p`],[14,23,`p`],[50,17,`p`],[55,20,`p`],[8,5],[16,7],[33,5],[42,7],[14,33],[15,38],[40,38],[45,35],[38,18],[30,22],[17,27],[54,4],[59,6],[50,10]],caches:[[3,40,`start`],[6,4],[18,4,`weapons`],[30,4],[44,7,`weapons`],[6,38],[16,32],[38,40],[46,34,`weapons`],[10,21],[34,28],[50,36],[57,20],[22,40]]},{$schema:`../../../spec/schemas/black-site-map.schema.json`,format:`black-site-map`,version:1,id:`desert`,name:`DESERT OUTPOST`,desc:`A walled compound in the sand. Breach the gates or go around.`,size:[64,44],theme:{ground:[146,122,84],road:[112,95,68],style:`sand`,markings:!1,clutter:[`b`,`c`,`h`]},generate:{expand:!0,buildings:16,cover:80},spawns:{extraEnemies:.2,extraCaches:3},start:[2,41],exfil:[58,5],roads:[[1,34,62,35],[47,1,48,42]],walls:[[18,12,29,12],[33,12,45,12],[18,32,23,32],[27,32,37,32],[41,32,45,32],[18,13,18,19],[18,23,18,31],[45,13,45,23],[45,27,45,31]],buildings:[{r:[21,15,28,20],doors:[[24,20],[25,20],[28,17],[28,18]],walls:[]},{r:[34,15,42,21],doors:[[34,18],[34,19],[38,21],[39,21]],walls:[]},{r:[22,25,30,30],doors:[[26,25],[27,25],[30,27],[30,28]],walls:[]},{r:[35,25,42,30],doors:[[35,27],[35,28],[38,25],[39,25]],walls:[]},{r:[3,3,9,8],doors:[[6,8],[9,5]],walls:[]},{r:[52,37,58,41],doors:[[52,39],[55,37]],walls:[]},{r:[4,22,10,28],doors:[[10,25],[7,22]],walls:[]},{r:[50,14,57,20],doors:[[50,17],[53,20]],walls:[]},{r:[26,37,33,41],doors:[[29,37],[30,37]],walls:[]}],crates:[[23,22],[24,22],[32,22],[33,23],[40,23],[41,23],[20,14],[14,10],[15,10],[58,22],[2,15],[3,15],[38,38],[39,38],[16,40],[44,5],[45,5],[40,17],[5,4]],wrecks:[[10,34,11,34],[48,8,48,9],[60,34,61,34],[36,6,37,6]],sandbags:[[29,10,30,10],[33,10,34,10],[12,16,13,16],[56,25,56,26],[8,32,9,32],[52,9,55,9],[59,9,62,9],[52,2,52,4],[52,7,52,8]],enemies:[[24,17],[38,17],[26,28],[39,28],[31,14],[31,23],[20,26],[43,15],[43,29],[31,10,`p`],[25,34,`p`],[39,34,`p`],[16,21,`p`],[12,13,`p`],[47,28,`p`],[60,20,`p`],[6,5],[7,25],[53,17],[55,39],[29,39],[56,4],[60,7],[54,7]],caches:[[3,40,`start`],[22,16],[41,20,`weapons`],[23,29],[41,29,`weapons`],[32,27],[5,7],[8,27],[56,15],[57,40,`weapons`],[32,40],[2,2],[60,28]]},{$schema:`../../../spec/schemas/black-site-map.schema.json`,format:`black-site-map`,version:1,id:`snow`,name:`FROZEN BASE`,desc:`A fenced military base in the snow. Cross it to the southeast pad.`,size:[64,44],theme:{ground:[186,192,198],road:[78,80,84],style:`snow`,clutter:[`T`,`T`,`c`,`b`]},generate:{expand:!0,buildings:16,cover:80},spawns:{extraEnemies:.2,extraCaches:3},start:[2,2],exfil:[58,40],roads:[[1,6,54,7],[30,1,31,42],[1,24,62,25]],walls:[[8,10,14,10],[17,10,29,10],[32,10,54,10],[8,38,29,38],[32,38,44,38],[47,38,54,38],[8,11,8,15],[8,18,8,23],[8,26,8,37],[54,11,54,23],[54,26,54,32],[54,35,54,37]],buildings:[{r:[11,12,27,16],doors:[[19,16],[20,16],[11,14]],walls:[]},{r:[34,12,51,16],doors:[[42,16],[43,16],[51,14]],walls:[]},{r:[11,18,27,22],doors:[[19,18],[20,18],[27,20]],walls:[]},{r:[34,18,51,22],doors:[[42,18],[43,18],[34,20]],walls:[]},{r:[11,28,27,35],doors:[[19,28],[20,28],[27,31],[27,32]],walls:[[20,30,20,34]]},{r:[34,28,51,35],doors:[[42,28],[43,28],[34,31],[34,32],[51,30]],walls:[[40,29,40,31]]},{r:[56,2,62,9],doors:[[56,6],[56,7],[59,9]],walls:[]},{r:[1,30,6,36],doors:[[6,32],[6,33],[3,30]],walls:[]},{r:[57,14,62,21],doors:[[57,17],[57,18]],walls:[]}],crates:[[14,8],[15,8],[40,4],[41,4],[24,2],[3,15],[4,15],[12,26],[13,26],[24,26],[36,26],[37,26],[48,26],[49,26],[20,36],[21,36],[40,36],[41,36],[58,28],[59,28],[3,40],[4,40],[14,14],[46,14],[14,20],[46,20],[16,33],[46,33]],wrecks:[[22,6,23,6],[30,30,30,31],[45,24,46,24],[60,24,61,24]],sandbags:[[28,9,29,9],[32,9,33,9],[7,23,7,23],[7,26,7,26],[55,23,55,23],[55,26,55,26],[55,36,57,36],[60,36,62,36]],enemies:[[30,9,`p`],[9,24,`p`],[53,24,`p`],[31,39,`p`],[15,14],[24,14],[38,14],[48,14],[15,20],[24,20],[38,20],[48,20],[15,31],[24,33],[38,31],[48,33],[20,26,`p`],[42,26,`p`],[30,17,`p`],[45,37,`p`],[45,4,`p`],[15,4,`p`],[58,6],[60,18],[3,33],[56,38],[61,39],[58,42]],caches:[[4,2,`start`],[25,13],[36,13,`weapons`],[13,21],[50,21],[13,34,`weapons`],[26,30],[49,34,`weapons`],[2,35],[61,16],[60,4],[20,3],[44,26],[9,40]]},{$schema:`../../../spec/schemas/black-site-map.schema.json`,format:`black-site-map`,version:1,id:`refinery`,name:`REFINERY`,desc:`Fuel tanks, pipelines and plant buildings. Exfil from the northwest pad.`,size:[64,44],theme:{ground:[70,67,60],road:[46,46,48],style:`concrete`,clutter:[`b`,`b`,`b`,`c`]},generate:{expand:!0,buildings:16,cover:80},spawns:{extraEnemies:.2,extraCaches:3},start:[61,41],exfil:[5,5],roads:[[1,20,62,21],[20,1,21,42],[44,1,45,42]],buildings:[{r:[6,33,16,40],doors:[[11,33],[12,33],[16,36],[16,37]],walls:[]},{r:[34,10,41,17],doors:[[34,13],[34,14],[38,17],[39,17]],walls:[]},{r:[49,32,59,39],doors:[[49,35],[49,36],[54,32],[55,32]],walls:[[52,36,52,38]]},{r:[24,12,31,17],doors:[[27,17],[28,17],[24,14]],walls:[]}],tanks:[[4,12],[8,12],[4,25],[8,25],[26,4],[30,4],[34,4],[26,26],[30,26],[48,5],[52,5],[56,5],[50,26],[54,26],[26,34],[30,34]],pipes:[[2,17,8,17],[11,17,17,17],[23,23,23,26],[23,28,23,31],[36,24,42,24],[47,14,47,18],[47,23,47,30],[56,12,61,12],[56,16,61,16],[33,39,42,39],[10,23,17,23]],crates:[[14,3],[15,3],[38,3],[39,3],[13,28],[14,28],[37,28],[38,28],[58,22],[59,22],[3,22],[40,41],[41,41],[60,30],[61,30],[25,40],[26,40],[8,38],[40,12],[57,37]],wrecks:[[22,10,22,11],[44,30,44,31],[5,20,6,20],[55,20,56,20]],sandbags:[[2,9,4,9],[7,9,9,9],[10,2,10,4],[10,7,10,8],[17,40,17,41]],enemies:[[8,7],[3,8],[8,3],[7,16,`p`],[7,29,`p`],[15,25],[29,9,`p`],[33,8],[28,30,`p`],[33,30],[24,38],[52,9,`p`],[57,9],[52,30,`p`],[57,24],[40,21,`p`],[11,37],[14,35],[37,13],[40,15],[26,14],[29,15],[51,34],[50,37],[44,10,`p`],[33,40,`p`]],caches:[[59,41,`start`],[12,36],[39,16,`weapons`],[27,13],[57,38,`weapons`],[2,2],[15,10],[32,9],[45,25],[3,30],[36,32],[60,14],[18,27],[24,2]]}],t=96,n=66,r={m4a1:{name:`M4A1`,slot:`primary`,cls:`Assault Rifle`,dmg:24,rpm:780,auto:!0,mag:30,reserve:120,reload:2.1,speed:2e3,range:1200,mobility:.93,kick:2,snd:`rifle`},ak47:{name:`AK-47`,slot:`primary`,cls:`Assault Rifle`,dmg:30,rpm:600,auto:!0,mag:30,reserve:120,reload:2.4,speed:2e3,range:1200,mobility:.9,kick:3,snd:`rifle2`},mp5:{name:`MP5`,slot:`primary`,cls:`Submachine Gun`,dmg:18,rpm:860,auto:!0,mag:30,reserve:150,reload:1.8,speed:1700,range:750,mobility:1,kick:1.5,snd:`smg`},spas12:{name:`SPAS-12`,slot:`primary`,cls:`Shotgun`,dmg:14,rpm:75,auto:!1,mag:8,reserve:32,reload:2.8,speed:1500,range:480,mobility:.95,kick:6,snd:`shotgun`,pellets:8,spread:.12},barrett:{name:`Barrett .50 Cal`,slot:`primary`,cls:`Sniper Rifle`,dmg:160,rpm:50,auto:!1,mag:5,reserve:20,reload:3.3,speed:3400,range:2400,mobility:.82,kick:9,snd:`sniper`,pierce:!0},m249:{name:`M249 SAW`,slot:`primary`,cls:`Light Machine Gun`,dmg:22,rpm:820,auto:!0,mag:100,reserve:200,reload:4.6,speed:2e3,range:1300,mobility:.8,kick:2,snd:`rifle`},m1911:{name:`M1911`,slot:`secondary`,cls:`Pistol`,dmg:26,rpm:420,auto:!1,mag:8,reserve:48,reload:1.4,speed:1600,range:750,mobility:1.06,kick:2,snd:`pistol`},glock18:{name:`Glock 18`,slot:`secondary`,cls:`Machine Pistol`,dmg:14,rpm:1100,auto:!0,mag:20,reserve:100,reload:1.5,speed:1600,range:600,mobility:1.06,kick:1,snd:`smg`},deagle:{name:`Desert Eagle`,slot:`secondary`,cls:`Hand Cannon`,dmg:48,rpm:220,auto:!1,mag:7,reserve:35,reload:1.9,speed:1900,range:900,mobility:1.02,kick:5,snd:`magnum`},magnum:{name:`.357 Magnum`,slot:`secondary`,cls:`Revolver`,dmg:55,rpm:160,auto:!1,mag:6,reserve:36,reload:2.6,speed:1900,range:950,mobility:1.02,kick:5,snd:`magnum`}};for(let e in r){let t=r[e];t.id=e,t.pellets=t.pellets||1,t.spread=t.spread||0}let i=Object.keys(r).filter(e=>r[e].slot===`primary`),a=Object.keys(r).filter(e=>r[e].slot===`secondary`),o={frag:{name:`Frag Grenade`,kind:`throwable`,cls:`Lethal`,unlock:2e3,desc:`Bounces off walls and detonates after 1.9s. Lethal close to the blast.`},molotov:{name:`Molotov Cocktail`,kind:`throwable`,cls:`Lethal`,unlock:2500,desc:`Shatters on impact. The fire burns for 5s and deals 15 damage per second to anyone standing in it. Anyone it catches keeps burning for 3s afterwards (10 damage per second).`},smoke:{name:`Smoke Grenade`,kind:`throwable`,cls:`Tactical`,unlock:1500,desc:`Pops a thick smoke cloud after 1.6s. Nobody - you or the enemy - can see through it.`},flash:{name:`Flashbang`,kind:`throwable`,cls:`Tactical`,unlock:1500,desc:`Blinds and stuns every enemy with a line of sight to the blast. Don't look at it.`},medkit:{name:`Medkit`,kind:`medical`,heal:100,use:2.6,desc:`Restores full health. Takes 2.6s to apply.`},bandage:{name:`Bandage`,kind:`medical`,heal:35,use:1.2,desc:`Restores 35 health. Takes 1.2s to apply.`},ammo:{name:`Ammo Box`,kind:`ammo`,desc:`Opened automatically when you reload with no reserve ammo left. +3 magazines.`},intel:{name:`Intel Files`,kind:`valuable`,value:250,desc:`Classified documents. Worth $250 if you extract with them.`},drive:{name:`Encrypted Drive`,kind:`valuable`,value:750,desc:`Black site server data. Worth $750 if you extract with it.`}},s=[`frag`,`molotov`,`flash`,`smoke`],c={soft:{name:`Soft Armour`,tier:`SOFT`,reduce:5,hp:50,price:1e3,col:`#6b6a55`},l1:{name:`Level I Armour`,tier:`I`,reduce:7,hp:75,price:2500,col:`#5a6444`},l2:{name:`Level II Armour`,tier:`II`,reduce:9,hp:125,price:4e3,col:`#46553a`},l3:{name:`Level III Armour`,tier:`III`,reduce:11,hp:175,price:6e3,col:`#3a4148`},l4:{name:`Level IV Armour`,tier:`IV`,reduce:13,hp:225,price:8500,col:`#25292e`}},l=Object.keys(c),u={hard:{name:`HARD`,extractTime:60,enemyDmg:1,extraDmg:8,fireDelay:1,money:3,desc:`Enemy bullets do +8 damage. All money rewards x3.`},normal:{name:`NORMAL`,extractTime:60,enemyDmg:1,extraDmg:0,fireDelay:1,money:1,desc:`The standard experience.`},easy:{name:`EASY`,extractTime:60,enemyDmg:.5,extraDmg:0,fireDelay:1.6,money:1/3,desc:`Enemies do half damage and shoot slower. All money rewards are 1/3 of normal.`}},d=[`hard`,`normal`,`easy`],p={assaulter:{name:`ASSAULTER`,role:`Infiltration`,perks:[`Footsteps are much quieter - enemies hear you far less`,`Extra grenade slot: a grenade in it can be thrown 3 times`],pal:{body:`#3a3d40`,vest:`#1c1e20`,helmet:`#2a2c2f`,sleeve:`#33363a`,skin:`#c79b74`,boot:`#151617`,gun:`#141516`,accent:`#a5d63f`,pack:`#26282a`,camo:`#202224`}},gunner:{name:`MACHINE GUNNER`,role:`Suppression`,perks:[`M249: +50 rounds in every belt`,`M249: reloads 40% faster`],pal:{body:`#56603e`,vest:`#3a4128`,helmet:`#4d5636`,sleeve:`#4f5838`,skin:`#b88a64`,boot:`#1f211c`,gun:`#18191b`,accent:`#e8c547`,pack:`#454d30`,camo:`#3a4229`}},sniper:{name:`SNIPER`,role:`Marksman`,perks:[`Barrett: +35% rate of fire`,`Barrett: 8-round magazine and 40 reserve rounds`],pal:{body:`#4a5a34`,vest:`#3a4a28`,helmet:`#56683a`,sleeve:`#506038`,skin:`#c79b74`,boot:`#1f211c`,gun:`#18191b`,accent:`#7fe36a`,pack:`#3e4c2c`,camo:`#6b7a44`}},cutthroat:{name:`CUT THROAT`,role:`Close quarters`,perks:[`[Q] throw a knife - kills in one hit`,`[Q] up close: knife slash - kills in one hit`,`Knife kills are silent, and the victim is left crawling`],pal:{body:`#2e2a2a`,vest:`#1a1717`,helmet:`#262222`,sleeve:`#2a2626`,skin:`#c79b74`,boot:`#121010`,gun:`#121314`,accent:`#c3352a`,pack:`#1e1b1b`,camo:`#3a1e1c`}},hauler:{name:`HAULER`,role:`Logistics`,perks:[`6 item slots instead of 4`,`Heavy pack: moves at 25% speed`],pal:{body:`#5e4a33`,vest:`#3f3122`,helmet:`#4f3f2b`,sleeve:`#574530`,skin:`#b88a64`,boot:`#1f1a14`,gun:`#18191b`,accent:`#e0913a`,pack:`#6b5434`,camo:`#46372a`}}},m=Object.keys(p),h=.03,g={barrett:.02};function _(e){return e===0?1500:2e3}let v=[[`bandage`,24],[`medkit`,9],[`frag`,12],[`molotov`,8],[`flash`,8],[`smoke`,8],[`ammo`,20],[`intel`,12],[`drive`,5]];function y(e){return e[Math.random()*e.length|0]}function b(e){return{type:`item`,id:e}}function x(e,t){let n=r[e];return t?{type:`weapon`,id:e,mag:Math.ceil(n.mag*(.3+Math.random()*.7)),reserve:n.mag*(1+(Math.random()*2|0))}:{type:`weapon`,id:e,mag:n.mag,reserve:n.reserve}}function S(){let e=0;for(let[,t]of v)e+=t;let t=Math.random()*e;for(let[e,n]of v)if((t-=n)<0)return b(e);return b(`bandage`)}function C(){return x(y(Object.keys(r)),!0)}function w(e){return e.type===`weapon`?r[e.id]:o[e.id]}let T=[64,44];function E(e){let t=e>>>0;return()=>{t=t+1831565813>>>0;let e=t;return e=Math.imul(e^e>>>15,e|1),e^=e+Math.imul(e^e>>>7,e|61),((e^e>>>14)>>>0)/4294967296}}function ee(e){let t=2166136261;for(let n of e)t^=n.charCodeAt(0),t=Math.imul(t,16777619);return t>>>0}function D(e,t,n){let r=t===0?0:1,i=[...(e.buildings||[]).map(e=>e.r),...e.containers||[],...(e.tanks||[]).map(([e,t])=>[e,t,e+2,t+2]),...(e.wrecks||[]).map(e=>e.length>=4?e:[e[0],e[1],e[0],e[1]])],a=e=>i.every(t=>!(t[r]<e&&e<=t[r+2]));for(let e=0;e<n/2;e++)for(let t of[Math.round(n/2)+e,Math.round(n/2)-e])if(a(t))return t;return Math.round(n/2)}function O(t){let n=typeof t==`string`?e.find(e=>e.id===t)||e[0]:t,[r,i]=n.size||T,a=n.generate||{},o=a.expand?Math.round(r*1.5):r,s=a.expand?Math.round(i*1.5):i,c=o-r,l=s-i,u=a.expand?D(n,0,r):1/0,d=a.expand?D(n,1,i):1/0,f=e=>e>=u?e+c:e,p=e=>e>=d?e+l:e,m=e=>[f(e[0]),p(e[1]),f(e.length>=4?e[2]:e[0]),p(e.length>=4?e[3]:e[1])],h=([e,t,...n])=>[f(e),p(t),...n],g=e=>{let[t,n]=h(e);return e.length>=4?[t,n,t+e[2]-e[0],n+e[3]-e[1]]:[t,n,t,n]},_=e=>{let t=m(e);return t[2]>=o-2-1&&(e.length>=4?e[2]:e[0])>=r-2&&(t[2]=o-2),t[3]>=s-2-1&&(e.length>=4?e[3]:e[1])>=i-2&&(t[3]=s-2),t},v=Array.from({length:s},()=>Array(o).fill(`.`)),y=(e,t)=>e>=0&&t>=0&&e<o&&t<s,b=(e,t,n)=>{y(e,t)&&(v[t][e]=n)},x=(e,t,n,r,i)=>{for(let a=t;a<=r;a++)for(let t=e;t<=n;t++)b(t,a,i)},S=(e,t,n=m)=>{let r=[];for(let i of e||[]){let e=n(i);x(e[0],e[1],e[2],e[3],t),r.push(e)}return r};S(n.water,`w`,_);let C=S(n.paved,`=`,g),w=S(n.roads,`=`,_),O=[],k=(e,t,n)=>{x(e[0],e[1],e[2],e[3],`#`),x(e[0]+1,e[1]+1,e[2]-1,e[3]-1,`,`);for(let e of t)x(e[0],e[1],e[2],e[3],`#`);for(let[e,t]of n)b(e,t,`,`);O.push({r:e})};for(let e of n.buildings||[])k(m(e.r),(e.walls||[]).map(m),(e.doors||[]).map(h));S(n.walls,`#`),x(0,0,o-1,0,`#`),x(0,s-1,o-1,s-1,`#`),x(0,0,0,s-1,`#`),x(o-1,0,o-1,s-1,`#`);let re=h(n.start),ie=h(n.exfil),ae=(n.enemies||[]).map(h),A=(n.caches||[]).map(h),j=E((a.seed===void 0?ee(n.id):a.seed)^1374496523),M=v.map(e=>e.slice());for(let[e,t]of[[n.crates,g],[n.wrecks,g],[n.sandbags,g],[n.pipes,m],[n.containers,m]])for(let n of e||[]){let e=t(n);for(let t=e[1];t<=e[3];t++)for(let n=e[0];n<=e[2];n++)y(n,t)&&(M[t][n]=`c`)}for(let e of n.tanks||[]){let[t,n]=h(e);for(let e=n;e<=n+2;e++)for(let n=t;n<=t+2;n++)M[e][n]=`o`}te(v,M,j,[re,ie],k,ae,A,a.buildings||0);let N=v.map(e=>e.slice()),oe=(n.containers||[]).map(e=>{let t=m(e);return x(t[0],t[1],t[2],t[3],`K`),[...t,e[4]]}),se=(n.tanks||[]).map(e=>{let[t,n]=h(e);return x(t,n,t+2,n+2,`o`),[t,n,3]});S(n.pipes,`p`),S(n.crates,`c`,g),S(n.wrecks,`v`,g),S(n.sandbags,`h`,g),ne(v,j,n,[re,ie],a.cover||0);let ce=(e,t)=>y(e,t)&&!`#chvpKowbT`.includes(v[t][e]),le=([e,t,...n])=>{if(ce(e,t))return[e,t,...n];for(let r=1;r<6;r++)for(let i=-r;i<=r;i++)for(let a=-r;a<=r;a++)if(ce(e+a,t+i))return[e+a,t+i,...n];return[e,t,...n]};return{id:n.id,name:n.name,theme:n.theme,w:o,h:s,grid:v,floor:N,spawns:n.spawns||{},buildings:O,roads:w,paved:C,containers:oe,tanks:se,start:le(re),exfil:le(ie),enemies:ae.map(le),caches:A.map(le)}}function te(e,t,n,r,i,a,o,s){let c=e.length,l=e[0].length,u=(n,r,i,a)=>{if(n<2||r<2||i>l-3||a>c-3)return!1;for(let o=r;o<=a;o++)for(let r=n;r<=i;r++)if(e[o][r]!==`.`||t[o][r]!==`.`)return!1;return!0},d=0;for(let t=0;t<4e3&&d<s;t++){let t=n()<.3,s=t?5+Math.floor(n()*3):9+Math.floor(n()*7),f=t?5+Math.floor(n()*2):7+Math.floor(n()*5),p=2+Math.floor(n()*(l-s-4)),m=2+Math.floor(n()*(c-f-4)),h=p+s-1,g=m+f-1;if(!u(p-2,m-2,h+2,g+2)||r.some(([e,t])=>e>=p-6&&e<=h+6&&t>=m-6&&t<=g+6))continue;let _=[],v=[],y=null;if(!t&&s>=11&&n()<.7){y=p+Math.floor(s/2);let e=m+2+Math.floor(n()*(f-5));e-1>=m+1&&_.push([y,m+1,y,e-1]),e+2<=g-1&&_.push([y,e+2,y,g-1])}let b=[`top`,`bottom`,`left`,`right`].sort(()=>n()-.5).slice(0,t?1:2+Math.floor(n()*2));y!==null&&!b.includes(`left`)&&!b.includes(`right`)&&b.push(n()<.5?`left`:`right`);for(let e of b)if(e===`top`||e===`bottom`){let t;for(let e=0;e<10&&(t=p+2+Math.floor(n()*(s-5)),!(y===null||t+1<y-0&&t+1!==y||t>y));e++);y!==null&&(t===y||t+1===y)&&(t=y+1<=h-2?y+1:y-2);let r=e===`top`?m:g;v.push([t,r],[t+1,r])}else{let t=m+2+Math.floor(n()*(f-5)),r=e===`left`?p:h;v.push([r,t],[r,t+1])}i([p,m,h,g],_,v);let x=()=>[p+1+Math.floor(n()*(s-2)),m+1+Math.floor(n()*(f-2))],S=t?+(n()<.5):1+Math.floor(n()*2);for(let t=0;t<S;t++){let t=x();e[t[1]][t[0]]===`,`&&a.push(t)}if(n()<(t?.6:.8)){let t=x();e[t[1]][t[0]]===`,`&&o.push(n()<.25?[...t,`weapons`]:t)}!t&&n()<.6&&a.push([p+Math.floor(s/2),g+2,`p`]),d++}}function ne(e,t,n,r,i){let a=e.length,o=e[0].length,s=n.theme.clutter||[`b`,`c`],c=(t,n,r)=>{for(let i=-r;i<=r;i++)for(let s=-r;s<=r;s++){let r=n+i,c=t+s;if(r<1||c<1||r>=a-1||c>=o-1||e[r][c]!==`.`)return!1}return!0},l=0;for(let n=0;n<3e3&&l<i;n++){let n=2+Math.floor(t()*(o-4)),i=2+Math.floor(t()*(a-4));if(!c(n,i,2)||r.some(([e,t])=>Math.hypot(e-n,t-i)<6))continue;let u=s[Math.floor(t()*s.length)];if(e[i][n]=u,u!==`T`&&t()<.55){let[r,a]=t()<.5?[1,0]:[0,1];e[i+a][n+r]=u,u===`h`&&t()<.5&&(e[i+a*2][n+r*2]=u)}l++}}function k(e,t){let n=document.createElement(`canvas`);return n.width=e,n.height=t,n}function re(e){let t=e>>>0||1;return()=>(t^=t<<13,t>>>=0,t^=t>>>17,t^=t<<5,t>>>=0,t/4294967296)}function ie(e){let t=parseInt(e.slice(1),16);return[t>>16&255,t>>8&255,t&255]}function ae(e){let[t,n,r]=ie(e),i=Math.round((t*.3+n*.59+r*.11)*.5+6);return`rgb(${i},${i},${Math.min(255,Math.round(i*1.07))})`}function A(e,t,n){return`rgb(${e|0},${t|0},${n|0})`}function j(e,t,n,r,i,a){e.fillStyle=a,e.beginPath(),e.ellipse(t,n,r,i,0,0,Math.PI*2),e.fill()}function M(e,t,n,r,i){e.beginPath(),e.moveTo(t,n),e.lineTo(r,i),e.stroke()}function N(e,t,n,r,i,a){e.beginPath(),e.moveTo(t+a,n),e.arcTo(t+r,n,t+r,n+i,a),e.arcTo(t+r,n+i,t,n+i,a),e.arcTo(t,n+i,t,n,a),e.arcTo(t,n,t+r,n,a),e.closePath()}let oe={body:`#6b5c45`,vest:`#2a2420`,helmet:`#2f2b27`,sleeve:`#5f523d`,skin:`#b48660`,boot:`#1d1a17`,gun:`#151516`,accent:`#c3352a`,pack:`#4a3f30`,camo:`#584a36`};function se(e){let t={};for(let n in e)t[n]=ae(e[n]);return t}let ce={m4a1:30,ak47:32,mp5:23,spas12:30,barrett:42,m249:34,m1911:11,glock18:11,deagle:13,magnum:13};function le(e){let t=ce[e]||28;return r[e].slot===`secondary`?[12+t,0]:[4+t,2.75]}function ue(e,t){let n=t.pal;e.save(),e.translate(t.x,t.y),j(e,4,5,17,14,`rgba(0,0,0,0.3)`),e.rotate(t.a);let i=Math.sin(t.walk||0)*5;for(let[t,r]of[[i,-6],[-i,6]])j(e,t,r,6.5,4.2,n.boot),j(e,t+2,r-1,2.5,1.5,`rgba(255,255,255,0.08)`);e.fillStyle=n.pack,N(e,-14,-8,9,16,3),e.fill(),e.fillStyle=`rgba(0,0,0,0.25)`,e.fillRect(-13,-1,7,2),e.fillStyle=`rgba(255,255,255,0.08)`,e.fillRect(-13,-7,2,14);let a=t.weapon?r[t.weapon]:null,o=a&&a.slot===`secondary`,s=-(t.recoil||0)*3,c=t.weapon?ce[t.weapon]:0;t.hold===`gun`&&a&&(e.fillStyle=n.gun,o?(e.fillRect(12+s,-2.5,c,5),e.fillStyle=`rgba(255,255,255,0.15)`,e.fillRect(12+s,-2.5,c,1.2)):(e.fillRect(4+s,0,c,5.5),e.fillRect(13+s,5,5,5),e.fillStyle=`#2a2c2f`,e.fillRect(4+s+c-3,1,4,3.5),e.fillStyle=`rgba(255,255,255,0.14)`,e.fillRect(4+s,.5,c*.6,1.5),e.fillStyle=`#0d0e0f`,e.fillRect(9+s,-1.5,6,2),t.weapon===`barrett`&&(e.fillStyle=`#0d0e0f`,e.fillRect(8+s,-2.5,14,3)))),e.strokeStyle=n.sleeve,e.lineWidth=5.5,e.lineCap=`round`;let l;t.hold===`gun`&&a?(l=o?[[13+s,-1],[13+s,1.5]]:[[9+s,4],[21+s,3]],M(e,0,10,l[0][0],l[0][1]),M(e,0,-10,l[1][0],l[1][1])):t.hold===`grenade`||t.hold===`med`?(l=[[14,7],[8,-8]],M(e,0,10,14,7),M(e,0,-10,8,-8),t.hold===`grenade`?(j(e,17,7,4,4,`#3f4a2e`),j(e,16,6,1.5,1.5,`rgba(255,255,255,0.2)`)):(e.fillStyle=`#e8e4da`,e.fillRect(13,3,9,8),e.fillStyle=`#c3352a`,e.fillRect(16.5,4,2,6),e.fillRect(14.5,6,6,2))):(l=[[4,13],[4,-13]],M(e,0,10,4,13),M(e,0,-10,4,-13));for(let[t,r]of l)j(e,t,r,3,3,`#24261f`),j(e,t+.6,r-.4,1.4,1.4,n.skin);j(e,0,0,9.5,14.5,n.body),j(e,1,-11,4.5,3.5,n.sleeve),j(e,1,11,4.5,3.5,n.sleeve),e.fillStyle=n.vest,N(e,-6,-10,13,20,3),e.fill(),e.fillStyle=`rgba(0,0,0,0.25)`;for(let t of[-8,-3,2])e.fillRect(3,t,4,4);e.fillStyle=`rgba(255,255,255,0.07)`,e.fillRect(-5,-9,2,18),e.strokeStyle=`rgba(0,0,0,0.35)`,e.lineWidth=1,e.strokeRect(-5.5,-9.5,12,19),e.fillStyle=n.accent,e.fillRect(-3,-14.5,5,3),j(e,1,0,8,8,n.helmet),e.fillStyle=n.camo;for(let[t,n,r]of[[-2,-3,2.2],[3,3,2],[4,-4,1.6],[-3,3,1.5]])e.beginPath(),e.arc(t,n,r,0,Math.PI*2),e.fill();e.strokeStyle=`rgba(0,0,0,0.35)`,e.lineWidth=1,e.beginPath(),e.arc(1,0,7.6,0,Math.PI*2),e.stroke(),j(e,2.5,-2,3,3.5,`rgba(255,255,255,0.12)`),t.player&&(e.fillStyle=`#1a1c1a`,e.fillRect(6,-2,3.5,4),e.fillStyle=`#a5d63f`,e.fillRect(8.5,-1,1,2)),t.hurt>0&&j(e,0,0,11,15,`rgba(255,70,60,${Math.min(.6,t.hurt*4)})`),e.restore()}function de(e,t){let n=t.pal,r=t.k==null?1:t.k,i=re(t.seed||1),a=t.crawl,o=[.12+i()*.45,.12+i()*.45],s=[.5+i()*1.3,.5+i()*1.4],c=(i()-.5)*6,l=i()<.5?1:-1,u=i()*6.3,d=18+i()*14;e.save(),e.translate(t.x,t.y),e.rotate(t.a),j(e,0,3,18+12*r,13,`rgba(0,0,0,0.25)`),e.lineCap=`round`,e.lineJoin=`round`;let f=(t,n,r)=>{e.strokeStyle=r,e.lineWidth=n,e.beginPath(),e.moveTo(t[0][0],t[0][1]);for(let n=1;n<t.length;n++)e.lineTo(t[n][0],t[n][1]);e.stroke()},p=(e,t,n)=>[e[0]+Math.cos(t)*n,e[1]+Math.sin(t)*n];for(let[t,i]of[[0,1],[1,-1]])if(a!=null){let t=.5+.5*Math.sin(a+(i>0?Math.PI/2:-Math.PI/2)),r=[-6,i*4],o=p(r,Math.PI-i*(.35+.75*t),11),s=p(o,Math.PI+i*(.1+.5*t),11);f([r,o,s],7,n.body),j(e,s[0]-2,s[1],4.5,3.2,n.boot)}else{let a=Math.PI-i*o[t]*r,s=[-6*r-2,i*4],c=p(s,a,10+16*r);f([s,c],7,n.body),j(e,c[0]+Math.cos(a)*3,c[1]+Math.sin(a)*3,4.5,3.5,n.boot)}for(let[t,i]of[[0,1],[1,-1]]){let o=[8,i*9],c;if(a!=null){let e=.5+.5*Math.sin(a+(i>0?0:Math.PI)),t=p(o,i*(1.25-.75*e),10);c=p(t,i*(-.15+.55*(1-e)),11+3*e),f([o,t,c],5.5,n.sleeve)}else c=p(o,i*s[t]*r,16),f([o,c],5.5,n.sleeve);j(e,c[0],c[1],3,3,`#24261f`),j(e,c[0]+.5,c[1],1.5,1.5,n.skin)}e.fillStyle=n.body,N(e,-10,-10,23,20,7),e.fill(),e.fillStyle=n.vest,N(e,-5,-8,15,16,3),e.fill(),e.fillStyle=`rgba(0,0,0,0.25)`;for(let t of[-2,3])e.fillRect(t,-6,4,4);e.fillStyle=n.pack,N(e,-9,-6,6,12,2),e.fill(),e.fillStyle=`rgba(110,10,8,0.6)`;for(let t=0;t<3;t++)e.beginPath(),e.arc(-4+i()*14,(i()-.5)*14,1.5+i()*2.5,0,Math.PI*2),e.fill();j(e,18,c,7.5,7.5,n.helmet),e.fillStyle=n.camo,e.beginPath(),e.arc(16,c-2,2,0,Math.PI*2),e.fill(),j(e,19.5,c-2,2.5,3,`rgba(255,255,255,0.1)`),t.weapon&&a==null&&r>.6&&(e.save(),e.translate(Math.cos(u)*d*.5+4,l*d),e.rotate(u),e.fillStyle=n.gun,e.fillRect(-13,-2.5,26,5),e.fillRect(-3,2,4,4),e.restore()),e.restore()}let fe=(()=>{try{return`filter`in k(1,1).getContext(`2d`)}catch{return!1}})();function pe(e,r,i,a,o){let s=k(t*r,n*r);o(s.getContext(`2d`),r);let c=s;if(fe){let e=k(s.width,s.height),t=e.getContext(`2d`);t.filter=`blur(${i}px)`,t.drawImage(s,0,0),c=e}e.save(),e.globalAlpha=a,e.imageSmoothingEnabled=!0,e.drawImage(c,0,0,t*40,n*40),e.restore()}function me(e,r,i,a,o,s){let c=k(t*i,n*i),l=c.getContext(`2d`),u=l.createImageData(c.width,c.height),d=u.data;for(let e=0;e<d.length;e+=4){let t=(r()-.5)*a;d[e]=s[0]+t,d[e+1]=s[1]+t,d[e+2]=s[2]+t*.85,d[e+3]=255}l.putImageData(u,0,0),e.save(),e.globalAlpha=o,e.imageSmoothingEnabled=!0,e.drawImage(c,0,0,t*40,n*40),e.restore()}let he=[`#5a3c2c`,`#4a2e28`,`#3a4450`,`#6a5a3a`,`#4c4c4a`],ge=[[`#7a2f24`,`#a4442f`],[`#2f4f6e`,`#3f6a90`],[`#4c5a36`,`#647648`],[`#a8862a`,`#d0a83a`]];function _e(e){let r=t*40,i=n*40,a=k(r,i),o=a.getContext(`2d`),s=re(ee(e.id)||1),c=e.theme,l=c.ground,u=c.road,d=c.style,f=(r,i)=>r<0||i<0||r>=t||i>=n?`#`:e.grid[i][r],p=(r,i)=>r<0||i<0||r>=t||i>=n?`#`:e.floor[i][r],m=(e,t)=>f(e,t)===`#`,h=e=>e===`#`||e===`K`||e===`o`,g=e=>{let r=[];for(let i=0;i<n;i++)for(let n=0;n<t;n++)e(n,i)&&r.push([n,i]);return r},_=e=>e[Math.floor(s()*e.length)],v=g((e,t)=>p(e,t)===`.`),y=g((e,t)=>p(e,t)===`=`);o.fillStyle=A(...l),o.fillRect(0,0,r,i),me(o,s,1,26,1,l),me(o,s,5,12,.55,l);for(let e=0;e<1400;e++){let e=s()*r,t=s()*i,n=25+s()*120,a=s()<.6?`20,18,12`:`255,250,230`,c=s()<.6?.05+s()*.09:.03+s()*.05,l=o.createRadialGradient(e,t,0,e,t,n);l.addColorStop(0,`rgba(${a},${c})`),l.addColorStop(1,`rgba(${a},0)`),o.fillStyle=l,o.fillRect(e-n,t-n,n*2,n*2)}for(let e=0;e<16e4;e++){let e=.5+s()*1;o.fillStyle=`rgba(${l[0]*e|0},${l[1]*e|0},${l[2]*e|0},${.18+s()*.3})`,o.fillRect(s()*r,s()*i,1+s()*1.6,1+s()*1.6)}for(let e=0;e<(d===`snow`?600:3500);e++){let[e,t]=_(v),n=(e+s())*40,r=(t+s())*40,i=1+s()*2.4,a=.6+s()*.6;j(o,n+.8,r+.8,i,i*.8,`rgba(0,0,0,0.25)`),j(o,n,r,i,i*.8,A(l[0]*a,l[1]*a,l[2]*a)),j(o,n-i*.3,r-i*.3,i*.4,i*.3,`rgba(255,255,255,0.18)`)}if(d===`grass`){for(let e=0;e<260;e++){let[e,t]=_(v);o.fillStyle=`rgba(70,92,42,${.08+s()*.12})`,o.beginPath(),o.ellipse((e+s())*40,(t+s())*40,25+s()*60,18+s()*40,s()*3,0,Math.PI*2),o.fill()}o.lineWidth=1.4;for(let e=0;e<4500;e++){let[e,t]=_(v),n=(e+s())*40,r=(t+s())*40;o.strokeStyle=`rgba(${60+s()*40},${85+s()*45},${35+s()*20},0.7)`;for(let e=0;e<5;e++)M(o,n+e*2-4,r,n+e*2-4+(s()-.5)*7,r-4-s()*7)}for(let e=0;e<70;e++){let[e,t]=_(v),n=(e+.5)*40,r=(t+.5)*40;j(o,n+4,r+5,15,11,`rgba(0,0,0,0.25)`);for(let e=0;e<6;e++)j(o,n+(s()-.5)*16,r+(s()-.5)*12,6+s()*6,5+s()*5,A(48+s()*20,70+s()*25,32+s()*12));for(let e=0;e<5;e++)j(o,n+(s()-.5)*14-2,r+(s()-.5)*10-2,2+s()*2,2,`rgba(160,190,110,0.35)`)}for(let e=0;e<25;e++){let[e,t]=_(v),n=(e+.5)*40,r=(t+.5)*40;j(o,n,r,20+s()*20,9+s()*8,`rgba(40,52,58,0.55)`),j(o,n-5,r-3,8,3,`rgba(180,200,210,0.18)`)}}else if(d===`sand`){o.lineWidth=1.5;for(let e=0;e<6e3;e++){let[e,t]=_(v),n=(e+s())*40,r=(t+s())*40,i=10+s()*18;o.strokeStyle=s()<.5?`rgba(255,240,205,0.16)`:`rgba(90,66,36,0.14)`,o.beginPath(),o.moveTo(n,r),o.quadraticCurveTo(n+i/2,r-3,n+i,r),o.stroke()}for(let e=0;e<260;e++){let[e,t]=_(v),n=(e+s())*40,r=(t+s())*40,i=3+s()*6;j(o,n+2,r+2,i,i*.7,`rgba(60,40,20,0.3)`),j(o,n,r,i,i*.7,A(120+s()*30,104+s()*25,80+s()*20)),j(o,n-i*.3,r-i*.3,i*.4,i*.25,`rgba(255,255,255,0.2)`)}for(let e=0;e<60;e++){let[e,t]=_(v),n=(e+.5)*40,r=(t+.5)*40;o.strokeStyle=`rgba(95,80,45,0.8)`,o.lineWidth=1.2;for(let e=0;e<9;e++){let e=s()*6.3,t=6+s()*9;M(o,n,r,n+Math.cos(e)*t,r+Math.sin(e)*t)}}}else if(d===`snow`){for(let e=0;e<420;e++){let[e,t]=_(v),n=(e+s())*40,r=(t+s())*40,i=25+s()*60,a=o.createRadialGradient(n,r,0,n,r,i),c=s()<.6?`255,255,255`:`130,150,185`;a.addColorStop(0,`rgba(${c},${.12+s()*.12})`),a.addColorStop(1,`rgba(${c},0)`),o.fillStyle=a,o.fillRect(n-i,r-i,i*2,i*2)}for(let e=0;e<5e3;e++)o.fillStyle=`rgba(255,255,255,${.4+s()*.6})`,o.fillRect(s()*r,s()*i,1,1);for(let e=0;e<18;e++){let[e,t]=_(v),n=e*40,r=t*40,i=s()*6.3;for(let e=0;e<40;e++){i+=(s()-.5)*.3,n+=Math.cos(i)*14,r+=Math.sin(i)*14;let t=e%2?1:-1;j(o,n-Math.sin(i)*5*t,r+Math.cos(i)*5*t,3.5,2.2,`rgba(120,135,160,0.35)`)}}}else if(d===`concrete`){o.fillStyle=`rgba(0,0,0,0.13)`;for(let[e,t]of v)e%3==0&&o.fillRect(e*40,t*40,1.5,40),t%3==0&&o.fillRect(e*40,t*40,40,1.5);for(let e=0;e<220;e++){let[e,t]=_(v),n=(e+s())*40,r=(t+s())*40;o.fillStyle=s()<.6?`rgba(15,12,10,${.15+s()*.2})`:`rgba(110,60,30,${.12+s()*.15})`;for(let e=0;e<4;e++)o.beginPath(),o.ellipse(n+(s()-.5)*20,r+(s()-.5)*20,5+s()*18,4+s()*12,s()*3,0,Math.PI*2),o.fill()}}o.strokeStyle=d===`snow`?`rgba(100,115,140,0.3)`:`rgba(12,10,8,0.45)`,o.lineWidth=1;for(let e=0;e<380;e++){let e=s()*r,t=s()*i;o.beginPath(),o.moveTo(e,t);for(let n=0;n<6;n++)e+=(s()-.5)*34,t+=(s()-.5)*34,o.lineTo(e,t),s()<.3&&(o.moveTo(e,t),o.lineTo(e+(s()-.5)*20,t+(s()-.5)*20),o.moveTo(e,t));o.stroke()}let b=c.markings===!1;for(let[e,t]of y){let n=(s()-.5)*6;o.fillStyle=A(u[0]+n,u[1]+n,u[2]+n),o.fillRect(e*40,t*40,40,40);for(let n=0;n<40;n++)o.fillStyle=s()<.5?`rgba(0,0,0,0.25)`:`rgba(255,255,255,0.08)`,o.fillRect(e*40+s()*40,t*40+s()*40,1.3,1.3)}if(!b){for(let e=0;e<90;e++){let[e,t]=_(y),n=20+s()*50,r=14+s()*30,i=(e+s())*40-n/2,a=(t+s())*40-r/2;o.fillStyle=`rgba(15,15,17,0.18)`,o.fillRect(i,a,n,r),o.strokeStyle=`rgba(0,0,0,0.25)`,o.lineWidth=1,o.strokeRect(i,a,n,r)}for(let e=0;e<26;e++){let[e,t]=_(y),n=(e+.5)*40,r=(t+.5)*40;j(o,n,r,12,12,`#2a2b2d`),o.strokeStyle=`#4a4b4e`,o.lineWidth=2,o.beginPath(),o.arc(n,r,11,0,Math.PI*2),o.stroke(),o.strokeStyle=`rgba(255,255,255,0.12)`,o.lineWidth=1;for(let e=-8;e<=8;e+=4)M(o,n-8,r+e,n+8,r+e)}for(let[e,t]of y){let n=e*40,r=t*40;for(let[i,a]of[[0,-1],[0,1],[-1,0],[1,0]]){let s=p(e+i,t+a);s!==`=`&&s!==`w`&&s!==`#`&&(o.fillStyle=`#8e8b82`,a===-1&&o.fillRect(n,r,40,5),a===1&&o.fillRect(n,r+40-5,40,5),i===-1&&o.fillRect(n,r,5,40),i===1&&o.fillRect(n+40-5,r,5,40),o.fillStyle=`rgba(0,0,0,0.35)`,a===-1&&o.fillRect(n,r+5,40,1.5),a===1&&o.fillRect(n,r+40-6.5,40,1.5),i===-1&&o.fillRect(n+5,r,1.5,40),i===1&&o.fillRect(n+40-6.5,r,1.5,40))}}}for(let[t,n,r,i]of e.roads){let e=r-t>i-n;if(b){o.strokeStyle=`rgba(70,52,30,0.35)`,o.lineWidth=6;for(let a of[-12,12]){if(o.beginPath(),e){let e=(n+i+1)/2*40+a;o.moveTo(t*40,e);for(let n=t*40;n<(r+1)*40;n+=60)o.lineTo(n,e+(s()-.5)*6)}else{let e=(t+r+1)/2*40+a;o.moveTo(e,n*40);for(let t=n*40;t<(i+1)*40;t+=60)o.lineTo(e+(s()-.5)*6,t)}o.stroke()}}else if(o.fillStyle=`rgba(225,215,190,0.55)`,e){o.fillRect(t*40,n*40+9,(r-t+1)*40,2),o.fillRect(t*40,(i+1)*40-11,(r-t+1)*40,2),o.fillStyle=`rgba(222,184,60,0.8)`;let e=(n+i+1)/2*40-1.5;for(let n=t*40+10;n<(r+1)*40-20;n+=56)o.fillRect(n,e,28,3)}else{o.fillRect(t*40+9,n*40,2,(i-n+1)*40),o.fillRect((r+1)*40-11,n*40,2,(i-n+1)*40),o.fillStyle=`rgba(222,184,60,0.8)`;let e=(t+r+1)/2*40-1.5;for(let t=n*40+10;t<(i+1)*40-20;t+=56)o.fillRect(e,t,3,28)}}for(let t=0;t<e.roads.length;t++)for(let n=t+1;n<e.roads.length;n++){let r=e.roads[t],i=e.roads[n],a=Math.max(r[0],i[0]),s=Math.max(r[1],i[1]),c=Math.min(r[2],i[2]),l=Math.min(r[3],i[3]);if(!(a>c||s>l)&&(o.fillStyle=A(u[0]+1,u[1]+1,u[2]+1),o.fillRect(a*40,s*40,(c-a+1)*40,(l-s+1)*40),!b)){o.fillStyle=`rgba(230,225,210,0.5)`;for(let e=0;e<(c-a+1)*40;e+=12)o.fillRect(a*40+e+2,s*40-26,7,20),o.fillRect(a*40+e+2,(l+1)*40+6,7,20);for(let e=0;e<(l-s+1)*40;e+=12)o.fillRect(a*40-26,s*40+e+2,20,7),o.fillRect((c+1)*40+6,s*40+e+2,20,7)}}for(let[t,n,r,i]of e.paved||[]){let e=t*40,a=n*40,c=(r-t+1)*40,l=(i-n+1)*40;for(let t=a;t<a+l;t+=12){let n=(s()-.5)*16;o.fillStyle=A(104+n,82+n,58+n),o.fillRect(e,t,c,12),o.fillStyle=`rgba(0,0,0,0.35)`,o.fillRect(e,t+11,c,1);for(let n=e+s()*90;n<e+c;n+=70+s()*70)o.fillRect(n,t,1,12),o.fillStyle=`rgba(30,25,20,0.6)`,o.fillRect(n-3,t+3,1.5,1.5),o.fillRect(n+3,t+7,1.5,1.5),o.fillStyle=`rgba(0,0,0,0.35)`;o.fillStyle=`rgba(255,240,210,0.06)`,o.fillRect(e,t+1,c,2)}}let x=(e,t)=>{for(let n=1;n<=4;n++)for(let r=-n;r<=n;r++)for(let i=-n;i<=n;i++){if(Math.max(Math.abs(i),Math.abs(r))!==n)continue;let a=p(e+i,t+r);if(a!==`w`&&a!==`#`)return n}return 5};for(let[e,t]of g((e,t)=>p(e,t)===`w`)){let n=e*40,r=t*40,i=(x(e,t)-1)/4;o.fillStyle=A(46-i*26+(s()-.5)*4,88-i*44,98-i*38),o.fillRect(n,r,40,40),o.strokeStyle=`rgba(170,210,225,0.13)`,o.lineWidth=1.4;for(let e=0;e<3;e++){let e=r+6+s()*28,t=n+s()*16;o.beginPath(),o.moveTo(t,e),o.quadraticCurveTo(t+6,e-3,t+12,e),o.quadraticCurveTo(t+18,e+3,t+24,e),o.stroke()}for(let[i,a]of[[0,-1],[0,1],[-1,0],[1,0]]){let c=p(e+i,t+a);if(c!==`w`&&c!==`#`){for(let e=0;e<8;e++)j(o,i?i<0?n+s()*6:n+40-s()*6:n+s()*40,a?a<0?r+s()*6:r+40-s()*6:r+s()*40,2+s()*3,1.5+s()*2,`rgba(225,240,245,${.25+s()*.35})`);if(c===`=`){let e=n+20+i*-12,t=r+20+a*-12;j(o,e+2,t+2,6,6,`rgba(0,0,0,0.35)`),j(o,e,t,6,6,`#4a3626`),j(o,e-1.5,t-1.5,2.5,2.5,`#6a5038`)}}}}e.buildings.forEach((e,t)=>{let[n,r,i,a]=e.r,c=n*40,l=r*40,u=(i-n+1)*40,d=(a-r+1)*40,f=t%4;if(o.save(),o.beginPath(),o.rect(c,l,u,d),o.clip(),f===0)for(let e=l;e<l+d;e+=10){let t=(s()-.5)*16;o.fillStyle=A(96+t,72+t,48+t),o.fillRect(c,e,u,10),o.strokeStyle=`rgba(40,25,10,0.18)`,o.lineWidth=1;for(let t=0;t<u/30;t++){let t=c+s()*u;M(o,t,e+2+s()*6,t+10+s()*20,e+2+s()*6)}o.fillStyle=`rgba(0,0,0,0.32)`,o.fillRect(c,e+9,u,1);for(let t=c+s()*80;t<c+u;t+=60+s()*70)o.fillRect(t,e,1,10)}else if(f===1)for(let e=l;e<l+d;e+=20)for(let t=c;t<c+u;t+=20){let n=(s()-.5)*10,r=((t-c)/20+(e-l)/20)%2?6:0;o.fillStyle=A(88+n+r,92+n+r,94+n+r),o.fillRect(t,e,20,20),o.fillStyle=`rgba(255,255,255,0.05)`,o.fillRect(t+1,e+1,18,2),o.fillStyle=`rgba(0,0,0,0.35)`,o.fillRect(t,e,20,1),o.fillRect(t,e,1,20)}else if(f===2){o.fillStyle=A(74,76,75),o.fillRect(c,l,u,d);for(let e=0;e<70;e++)o.fillStyle=`rgba(${s()<.5?`20,20,20`:`150,150,145`},${.04+s()*.07})`,o.beginPath(),o.arc(c+s()*u,l+s()*d,8+s()*40,0,Math.PI*2),o.fill();o.fillStyle=`rgba(0,0,0,0.28)`;for(let e=c;e<c+u;e+=80)o.fillRect(e,l,1,d);for(let e=l;e<l+d;e+=80)o.fillRect(c,e,u,1)}else{let e=[[92,40,38],[46,58,74],[70,60,44]][Math.floor(s()*3)];o.fillStyle=A(...e),o.fillRect(c,l,u,d);for(let e=0;e<u*d/60;e++)o.fillStyle=`rgba(${s()<.5?`0,0,0`:`255,255,255`},0.06)`,o.fillRect(c+s()*u,l+s()*d,2,2);for(let e=0;e<12;e++)o.fillStyle=`rgba(0,0,0,0.12)`,o.beginPath(),o.arc(c+s()*u,l+s()*d,10+s()*30,0,Math.PI*2),o.fill()}for(let e=0;e<(u*d>6e4?2:1);e++){let e=70+s()*70,t=50+s()*50,n=c+40+s()*Math.max(1,u-80-e),r=l+40+s()*Math.max(1,d-80-t),i=[[120,40,34],[40,60,90],[110,90,50]][Math.floor(s()*3)];o.fillStyle=A(...i),o.fillRect(n,r,e,t),o.strokeStyle=`rgba(230,210,170,0.45)`,o.lineWidth=2,o.strokeRect(n+5,r+5,e-10,t-10),o.strokeStyle=`rgba(0,0,0,0.3)`,o.lineWidth=1,o.strokeRect(n+10,r+10,e-20,t-20),o.fillStyle=`rgba(230,210,170,0.5)`;for(let i=n;i<n+e;i+=4)o.fillRect(i,r-3,1.5,3),o.fillRect(i,r+t,1.5,3)}for(let e=0;e<Math.max(8,u*d/9e3);e++){o.save(),o.translate(c+30+s()*(u-60),l+30+s()*(d-60)),o.rotate(s()*6.3);let e=s();if(e<.5){o.fillStyle=`rgba(225,220,205,0.75)`,o.fillRect(-4,-5,8+s()*4,10),o.fillStyle=`rgba(40,40,40,0.4)`;for(let e=-3;e<4;e+=2)o.fillRect(-3,e,7,.8)}else e<.8?(o.fillStyle=`rgba(40,36,30,0.65)`,o.beginPath(),o.moveTo(-5,-3),o.lineTo(4,-5),o.lineTo(6,3),o.lineTo(-3,5),o.closePath(),o.fill()):(o.fillStyle=`rgba(190,215,225,0.5)`,o.beginPath(),o.moveTo(0,-4),o.lineTo(3,2),o.lineTo(-2,3),o.closePath(),o.fill());o.restore()}o.restore()});for(let[e,t]of g((e,t)=>p(e,t)===`,`&&f(e,t)===`,`)){if(s()>.13)continue;let n=[[0,-1],[0,1],[-1,0],[1,0]].filter(([n,r])=>m(e+n,t+r));if(!n.length)continue;let[r,i]=n[Math.floor(s()*n.length)],a=e*40,c=t*40,l=r===1?a+40-11:a,u=i===1?c+40-11:c,d=r?11:40,f=i?11:40,p=s();if(o.fillStyle=`rgba(0,0,0,0.3)`,o.fillRect(l+2,u+2,d,f),o.fillStyle=p<.4?`#5a4632`:p<.7?`#565c62`:`#6b6a60`,o.fillRect(l,u,d,f),o.fillStyle=`rgba(255,255,255,0.1)`,o.fillRect(l,u,d,1.5),o.fillRect(l,u,1.5,f),p<.4)for(let e=2;e<(r?f:d)-3;e+=4)o.fillStyle=A(80+s()*120,40+s()*80,30+s()*60),r?o.fillRect(l+2,u+e,d-4,3):o.fillRect(l+e,u+2,3,f-4);else if(p<.7){o.fillStyle=`rgba(0,0,0,0.35)`;for(let e=8;e<(r?f:d);e+=10)r?o.fillRect(l,u+e,d,1):o.fillRect(l+e,u,1,f)}else for(let e=0;e<3;e++)o.fillStyle=A(120+s()*100,120+s()*100,110+s()*90),o.fillRect(l+2+s()*(d-7),u+2+s()*(f-7),4,4)}for(let e=0;e<160;e++){let[e,t]=_(v),n=(e+s())*40,r=(t+s())*40,i=s();if(i<.3)j(o,n+2,r+2,6,5,`rgba(0,0,0,0.3)`),j(o,n,r,6,5,`#1e1f1d`),j(o,n-2,r-2,2,1.5,`rgba(255,255,255,0.15)`);else if(i<.6)o.save(),o.translate(n,r),o.rotate(s()*6.3),o.fillStyle=A(120+s()*100,100+s()*80,80+s()*60),o.fillRect(-4,-3,8,6),o.restore();else{o.fillStyle=`rgba(80,78,72,0.8)`;for(let e=0;e<6;e++)o.fillRect(n+(s()-.5)*18,r+(s()-.5)*18,2+s()*4,2+s()*3)}}pe(o,4,3,.55,(e,r)=>{e.fillStyle=`#000`;for(let i=0;i<n;i++)for(let n=0;n<t;n++)h(f(n,i))&&e.fillRect(n*r,i*r,r,r)}),pe(o,5,1.2,.42,(r,i)=>{r.fillStyle=`#000`;for(let e=0;e<n;e++)for(let n=0;n<t;n++){let t=f(n,e);t===`#`||t===`K`?r.fillRect(n*i+1,e*i+1,i,i):`cvhpb`.includes(t)&&r.fillRect(n*i+1,e*i+1,i-1,i-1)}for(let[t,n,a]of e.tanks)r.beginPath(),r.arc((t+a/2)*i+1.2,(n+a/2)*i+1.2,a/2*i,0,Math.PI*2),r.fill()});let S=e.buildings.map(e=>e.r),C=(e,t)=>S.some(([n,r,i,a])=>(e===n||e===i||t===r||t===a)&&e>=n&&e<=i&&t>=r&&t<=a);for(let[e,r]of g(m)){let i=e*40,a=r*40,c=(s()-.5)*10,l=e===0||r===0||e===t-1||r===n-1?[70,68,64]:d===`sand`?[150,128,96]:d===`snow`?[116,120,126]:[100,96,88];o.fillStyle=A(l[0]+c,l[1]+c,l[2]+c),o.fillRect(i,a,40,40),o.fillStyle=`rgba(0,0,0,0.13)`;for(let e=0;e<4;e++){o.fillRect(i,a+e*10,40,1);let t=e%2?10:0;for(let n=t;n<40;n+=20)o.fillRect(i+n,a+e*10,1,10)}for(let e=0;e<6;e++)o.fillStyle=`rgba(0,0,0,${.05+s()*.08})`,o.fillRect(i+s()*34,a+s()*34,2+s()*6,2+s()*6);if(m(e,r-1)||(o.fillStyle=`rgba(255,250,235,0.45)`,o.fillRect(i,a,40,3)),m(e-1,r)||(o.fillStyle=`rgba(255,250,235,0.32)`,o.fillRect(i,a,3,40)),m(e,r+1)||(o.fillStyle=`rgba(0,0,0,0.5)`,o.fillRect(i,a+40-4,40,4)),m(e+1,r)||(o.fillStyle=`rgba(0,0,0,0.4)`,o.fillRect(i+40-4,a,4,40)),C(e,r)&&s()<.35){let t=m(e-1,r)&&m(e+1,r);if(t!==(m(e,r-1)&&m(e,r+1))){let[e,n,r,s]=t?[i+5,a+15,30,10]:[i+15,a+5,10,30];o.fillStyle=`#2b2f32`,o.fillRect(e-1,n-1,r+2,s+2);let c=o.createLinearGradient(e,n,e+r,n+s);c.addColorStop(0,`#6f8ea0`),c.addColorStop(1,`#3d5564`),o.fillStyle=c,o.fillRect(e,n,r,s),o.fillStyle=`rgba(255,255,255,0.35)`,t?o.fillRect(e+2,n+2,r*.4,1.5):o.fillRect(e+2,n+2,1.5,s*.4),o.fillStyle=`#2b2f32`,t?o.fillRect(e+r/2,n,1.5,s):o.fillRect(e,n+s/2,r,1.5)}}if(d===`snow`&&!m(e,r-1)){o.fillStyle=`rgba(240,245,250,0.85)`,o.fillRect(i,a,40,6);for(let e=0;e<4;e++)j(o,i+s()*40,a+6,4+s()*4,2+s()*2,`rgba(240,245,250,0.85)`)}d===`grass`&&s()<.12&&(o.fillStyle=`rgba(70,95,45,0.35)`,j(o,i+s()*40,a+40-4,6+s()*6,3,`rgba(70,95,45,0.4)`))}for(let[t,n,r,i,a]of e.containers){let e=t*40,c=n*40,l=(r-t+1)*40,u=(i-n+1)*40,d=l>=u;o.fillStyle=a,o.fillRect(e+2,c+2,l-4,u-4);let f=d?o.createLinearGradient(e,c,e,c+u):o.createLinearGradient(e,c,e+l,c);f.addColorStop(0,`rgba(255,255,255,0.16)`),f.addColorStop(.5,`rgba(255,255,255,0)`),f.addColorStop(1,`rgba(0,0,0,0.25)`),o.fillStyle=f,o.fillRect(e+2,c+2,l-4,u-4);for(let t=7;t<(d?l:u)-6;t+=7)o.fillStyle=`rgba(0,0,0,0.22)`,d?o.fillRect(e+t,c+5,2.5,u-10):o.fillRect(e+5,c+t,l-10,2.5),o.fillStyle=`rgba(255,255,255,0.08)`,d?o.fillRect(e+t+2.5,c+5,1.5,u-10):o.fillRect(e+5,c+t+2.5,l-10,1.5);if(o.fillStyle=`rgba(0,0,0,0.3)`,d){o.fillRect(e+l-14,c+3,11,u-6),o.fillStyle=`#8a8d90`;for(let t of[.3,.7])o.fillRect(e+l-12,c+u*t-1,8,2)}else{o.fillRect(e+3,c+u-14,l-6,11),o.fillStyle=`#8a8d90`;for(let t of[.3,.7])o.fillRect(e+l*t-1,c+u-12,2,8)}o.fillStyle=`#26282a`;for(let[t,n]of[[e+2,c+2],[e+l-8,c+2],[e+2,c+u-8],[e+l-8,c+u-8]])o.fillRect(t,n,6,6);for(let t=0;t<10;t++){o.fillStyle=`rgba(110,55,25,0.35)`;let t=e+6+s()*(l-12),n=c+6+s()*(u-12);o.fillRect(t,n,2+s()*3,4+s()*12)}o.save(),o.translate(e+l/2,c+u/2),d||o.rotate(Math.PI/2),o.fillStyle=`rgba(240,240,235,0.55)`,o.font=`bold 13px Arial`,o.textAlign=`center`,o.textBaseline=`middle`,o.fillText(`BSCU ${1e3+Math.floor(s()*9e3)}`,0,0),o.restore(),o.strokeStyle=`rgba(0,0,0,0.6)`,o.lineWidth=2,o.strokeRect(e+3,c+3,l-6,u-6)}for(let[t,n,r]of e.tanks){let e=(t+r/2)*40,i=(n+r/2)*40,a=r/2*40-2,s=o.createRadialGradient(e-a*.35,i-a*.35,a*.1,e,i,a);s.addColorStop(0,`#e0e2de`),s.addColorStop(.7,`#a6a9a4`),s.addColorStop(1,`#7c7f7a`),o.fillStyle=s,o.beginPath(),o.arc(e,i,a,0,Math.PI*2),o.fill(),o.strokeStyle=`rgba(0,0,0,0.16)`,o.lineWidth=2;for(let t of[.82,.6,.36])o.beginPath(),o.arc(e,i,a*t,0,Math.PI*2),o.stroke();o.fillStyle=`rgba(40,40,40,0.5)`;for(let t=0;t<Math.PI*2;t+=Math.PI/18)o.fillRect(e+Math.cos(t)*(a-4)-1,i+Math.sin(t)*(a-4)-1,2,2);o.strokeStyle=`#55585a`,o.lineWidth=1.5,o.beginPath(),o.arc(e,i,a+3,-.6,.6),o.stroke(),o.strokeStyle=`rgba(0,0,0,0.5)`,o.lineWidth=2,o.beginPath(),o.arc(e,i,a-1,0,Math.PI*2),o.stroke(),o.fillStyle=`#4a4d48`,o.fillRect(e+a*.2,i-3,a*.78,6),o.fillStyle=`#6a6d68`;for(let t=e+a*.25;t<e+a*.95;t+=6)o.fillRect(t,i-3,1.5,6);j(o,e,i,9,9,`#5d605b`),j(o,e,i,5,5,`#3e413c`),j(o,e-a*.45,i+a*.3,7,7,`#6d706b`),o.fillStyle=`#b8402e`,o.font=`bold 15px Arial`,o.textAlign=`center`,o.textBaseline=`middle`,o.fillText(`FUEL`,e,i+a*.62),o.save(),o.translate(e-a*.55,i-a*.45),o.rotate(Math.PI/4),o.fillStyle=`#c9402e`,o.fillRect(-6,-6,12,12),o.restore()}let w=new Set;for(let e=0;e<n;e++)for(let n=0;n<t;n++){let t=f(n,e),r=n*40,i=e*40;if(t===`c`){let e=s()<.35,t=o.createLinearGradient(r,i,r+40,i+40);if(t.addColorStop(0,e?`#5c6b48`:`#8a6a44`),t.addColorStop(1,e?`#3e4a30`:`#634a2e`),o.fillStyle=t,o.fillRect(r+3,i+3,34,34),o.strokeStyle=e?`#26301c`:`#3a2a18`,o.lineWidth=2,o.strokeRect(r+4,i+4,32,32),e){for(let e=0;e<5;e++)o.fillStyle=`rgba(0,0,0,0.2)`,o.fillRect(r+7+e*6,i+5,2,30),o.fillStyle=`rgba(255,255,255,0.08)`,o.fillRect(r+9+e*6,i+5,1,30);o.fillStyle=`#c9b23c`,o.fillRect(r+10,i+16,20,7),o.fillStyle=`#1b1c1e`;for(let e=0;e<4;e++)o.fillRect(r+12+e*5,i+16,2,7);o.fillStyle=`#2a2c2e`,o.fillRect(r+5,i+18,3,5),o.fillRect(r+40-8,i+18,3,5)}else{o.strokeStyle=`rgba(50,32,15,0.28)`,o.lineWidth=1;for(let e=1;e<4;e++){o.fillStyle=`rgba(0,0,0,0.25)`,o.fillRect(r+4,i+4+e*8,32,1);for(let t=0;t<2;t++){let t=r+6+s()*20;M(o,t,i+e*8,t+8,i+e*8+1)}}o.strokeStyle=`#5a4128`,o.lineWidth=3.5,M(o,r+6,i+6,r+40-6,i+40-6),o.fillStyle=`#2c2218`;for(let[e,t]of[[7,7],[31,7],[7,31],[31,31]])o.fillRect(r+e,i+t,2,2);o.fillStyle=`rgba(255,240,200,0.14)`,o.fillRect(r+4,i+4,32,2),s()<.3&&(o.fillStyle=`rgba(20,20,20,0.45)`,o.font=`bold 8px Arial`,o.textAlign=`center`,o.textBaseline=`middle`,o.fillText(`FRAGILE`,r+20,i+20+6))}}else if(t===`h`){o.save(),o.beginPath(),o.rect(r-2,i-2,44,44),o.clip();for(let[e,t]of[[11,12],[29,12],[20,28],[4,28],[36,28]]){let n=o.createRadialGradient(r+e-3,i+t-3,1,r+e,i+t,11);n.addColorStop(0,`#a8987a`),n.addColorStop(1,`#6e6248`),o.fillStyle=n,o.beginPath(),o.ellipse(r+e,i+t,10.5,7.5,0,0,Math.PI*2),o.fill(),o.strokeStyle=`#4a4130`,o.lineWidth=1.5,o.stroke(),o.strokeStyle=`rgba(60,50,35,0.6)`,o.lineWidth=1,o.setLineDash([2,2]),o.beginPath(),o.moveTo(r+e-7,i+t),o.lineTo(r+e+7,i+t),o.stroke(),o.setLineDash([]),o.fillStyle=`rgba(40,32,20,0.5)`,o.fillRect(r+e-10,i+t-1.5,3,3)}if(d===`snow`)for(let e=0;e<3;e++)j(o,r+s()*40,i+6+s()*20,5,2.5,`rgba(240,245,250,0.8)`);o.restore()}else if(t===`b`){let[e,t]=ge[Math.floor(s()*ge.length)],n=r+20,a=i+20,c=o.createRadialGradient(n-5,a-5,2,n,a,16);c.addColorStop(0,t),c.addColorStop(1,e),o.fillStyle=c,o.beginPath(),o.arc(n,a,15,0,Math.PI*2),o.fill(),o.strokeStyle=`rgba(0,0,0,0.5)`,o.lineWidth=2,o.stroke(),o.strokeStyle=`rgba(0,0,0,0.3)`,o.lineWidth=1.5,o.beginPath(),o.arc(n,a,11,0,Math.PI*2),o.stroke(),j(o,n+5,a-4,2.5,2.5,`#2a2a2a`),j(o,n-6,a+5,1.6,1.6,`#2a2a2a`),j(o,n-5,a-6,4,2.5,`rgba(255,255,255,0.2)`);for(let e=0;e<3;e++)o.fillStyle=`rgba(110,55,25,0.4)`,o.fillRect(n+(s()-.5)*20,a+(s()-.5)*20,3,3);e===`#a8862a`&&(o.fillStyle=`#1b1c1e`,o.font=`bold 10px Arial`,o.textAlign=`center`,o.textBaseline=`middle`,o.fillText(`!`,n,a+1))}else if(t===`p`){let t=f(n-1,e)===`p`||f(n+1,e)===`p`;o.fillStyle=`#34373a`,t?o.fillRect(r+16,i+6,8,28):o.fillRect(r+6,i+16,28,8);let a=t?o.createLinearGradient(r,i+11,r,i+29):o.createLinearGradient(r+11,i,r+29,i);a.addColorStop(0,`#565b60`),a.addColorStop(.35,`#c0c5ca`),a.addColorStop(1,`#5b6065`),o.fillStyle=a,t?o.fillRect(r,i+11,40,18):o.fillRect(r+11,i,18,40),o.fillStyle=`#464b50`,t?o.fillRect(r,i+9,5,22):o.fillRect(r+9,i,22,5),o.fillStyle=`#2a2d30`;for(let e=0;e<3;e++)t?o.fillRect(r+1.5,i+11+e*7,2,2):o.fillRect(r+11+e*7,i+1.5,2,2);for(let e=0;e<3;e++)o.fillStyle=`rgba(120,60,25,0.35)`,t?o.fillRect(r+s()*40,i+13+s()*12,3+s()*5,2):o.fillRect(r+13+s()*12,i+s()*40,2,3+s()*5);if(s()<.12){let e=r+20,t=i+20;o.strokeStyle=`#b8402e`,o.lineWidth=2.5,o.beginPath(),o.arc(e,t,7,0,Math.PI*2),o.stroke(),M(o,e-7,t,e+7,t),M(o,e,t-7,e,t+7)}}else if(t===`T`){let e=r+20,t=i+20;if(j(o,e+9,t+10,26,22,`rgba(0,0,0,0.3)`),d===`snow`){for(let n=0;n<3;n++){let r=26-n*7;o.fillStyle=A(30+n*8,58+n*10,44+n*6),o.beginPath();for(let i=0;i<16;i++){let a=i%2?r*.65:r,s=i/16*Math.PI*2+n*.2;o.lineTo(e+Math.cos(s)*a,t+Math.sin(s)*a)}o.closePath(),o.fill()}for(let n=0;n<8;n++)j(o,e+(s()-.5)*34,t+(s()-.5)*34,3+s()*3,2,`rgba(240,245,250,0.85)`)}else{for(let n=0;n<9;n++)j(o,e+(s()-.5)*26,t+(s()-.5)*26,11+s()*7,10+s()*6,A(42+s()*18,66+s()*22,30+s()*12));for(let n=0;n<12;n++)j(o,e+(s()-.5)*30-3,t+(s()-.5)*30-3,3+s()*3,2.5,`rgba(150,185,95,0.3)`);j(o,e,t,3,3,`#3a2a1c`)}}else if(t===`v`&&!w.has(n+`,`+e)){let t=1,a=1;for(;f(n+t,e)===`v`;)t++;for(;f(n,e+a)===`v`;)a++;for(let r=0;r<a;r++)for(let i=0;i<t;i++)w.add(n+i+`,`+(e+r));let c=t*40,l=a*40,u=c>=l,d=he[Math.floor(s()*he.length)];o.save(),o.translate(r+c/2,i+l/2),u||o.rotate(Math.PI/2);let p=Math.max(c,l)-6,m=Math.min(c,l)-10;o.fillStyle=`#121212`;for(let[e,t]of[[-p*.32,-m/2-2],[p*.32,-m/2-2],[-p*.32,m/2-3],[p*.32,m/2-3]])o.fillRect(e-6,t,12,5);o.fillStyle=d,N(o,-p/2,-m/2,p,m,9),o.fill(),o.fillStyle=`rgba(255,255,255,0.1)`,N(o,-p/2+3,-m/2+3,p-6,m/3,6),o.fill(),o.fillStyle=`rgba(0,0,0,0.25)`,o.fillRect(-p/2+6,-1,p*.25,2),o.fillStyle=`#2a3540`,N(o,-p*.12,-m/2+4,p*.1,m-8,3),o.fill(),o.fillStyle=`rgba(0,0,0,0.3)`,N(o,-p*.02,-m/2+5,p*.3,m-10,4),o.fill(),o.fillStyle=`#2a3540`,N(o,p*.29,-m/2+5,p*.07,m-10,3),o.fill(),o.fillStyle=`rgba(200,220,230,0.4)`,o.beginPath(),o.moveTo(-p*.1,-m/2+6),o.lineTo(-p*.05,-m/2+12),o.lineTo(-p*.08,-m/2+14),o.closePath(),o.fill(),o.fillStyle=`#1a1a1a`,o.fillRect(-p*.1,-m/2-3,4,3),o.fillRect(-p*.1,m/2,4,3);for(let e=0;e<14;e++)o.fillStyle=s()<.5?`rgba(10,8,6,0.5)`:`rgba(150,80,40,0.35)`,o.beginPath(),o.arc((s()-.5)*p,(s()-.5)*m,2+s()*7,0,Math.PI*2),o.fill();o.strokeStyle=`rgba(0,0,0,0.6)`,o.lineWidth=1.5,N(o,-p/2,-m/2,p,m,9),o.stroke(),o.restore();for(let e=0;e<20;e++)j(o,r+c/2+(s()-.5)*(c+30),i+l/2+(s()-.5)*(l+30),1+s(),1,`rgba(190,215,225,0.45)`)}}let T=(e.exfil[0]+.5)*40,E=(e.exfil[1]+.5)*40;j(o,T+4,E+4,92,92,`rgba(0,0,0,0.3)`);let D=o.createRadialGradient(T-30,E-30,10,T,E,92);D.addColorStop(0,`#4a4f4a`),D.addColorStop(1,`#343834`),o.fillStyle=D,o.beginPath(),o.arc(T,E,90,0,Math.PI*2),o.fill(),o.strokeStyle=`rgba(0,0,0,0.35)`,o.lineWidth=1;for(let e=-80;e<=80;e+=40)M(o,T+e,E-88,T+e,E+88),M(o,T-88,E+e,T+88,E+e);o.strokeStyle=`#d6b23a`,o.lineWidth=6,o.beginPath(),o.arc(T,E,78,0,Math.PI*2),o.stroke(),o.strokeStyle=`rgba(255,255,255,0.7)`,o.lineWidth=2,o.beginPath(),o.arc(T,E,70,0,Math.PI*2),o.stroke();for(let e=0;e<Math.PI*2;e+=Math.PI/8){let t=T+Math.cos(e)*86,n=E+Math.sin(e)*86;j(o,t,n,3.5,3.5,`#1a1a1a`),j(o,t,n,2,2,`#9be86a`)}o.fillStyle=`#e8e6df`,o.font=`bold 70px Arial, sans-serif`,o.textAlign=`center`,o.textBaseline=`middle`,o.fillText(`H`,T,E+3),o.fillStyle=`rgba(232,230,223,0.7)`,o.font=`bold 12px Arial`,o.fillText(`EXFIL`,T,E+52),o.strokeStyle=`rgba(15,15,15,0.4)`,o.lineWidth=7,o.beginPath(),o.arc(T-10,E+10,60,2.6,3.4),o.stroke();let O=k(r,i),te=O.getContext(`2d`);te.drawImage(a,0,0);let ne=te.getImageData(0,0,r,i),ie=ne.data;for(let e=0;e<ie.length;e+=4){let t=(ie[e]*.3+ie[e+1]*.59+ie[e+2]*.11)*.5+6;ie[e]=t,ie[e+1]=t,ie[e+2]=Math.min(255,t*1.07)}return te.putImageData(ne,0,0),{color:a,gray:O,cx:o,gx:te}}let ve={m4a1:{kind:`rifle`,recv:46,hand:34,barrel:22,stock:`tube`,mag:`straight`,optic:`red`,col:`#3a3d40`,furn:`#3a3d40`},ak47:{kind:`rifle`,recv:48,hand:30,barrel:26,stock:`solid`,mag:`curve`,optic:`none`,col:`#2b2b2b`,furn:`#6b4226`},mp5:{kind:`rifle`,recv:40,hand:22,barrel:10,stock:`tube`,mag:`curve`,optic:`none`,col:`#33363a`,furn:`#33363a`,short:!0},spas12:{kind:`rifle`,recv:44,hand:30,barrel:30,stock:`skeleton`,mag:`tube`,optic:`none`,col:`#36383b`,furn:`#36383b`},barrett:{kind:`rifle`,recv:54,hand:30,barrel:40,stock:`solid`,mag:`box`,optic:`scope`,col:`#3a3b36`,furn:`#3a3b36`,bipod:!0,brake:!0},m249:{kind:`rifle`,recv:52,hand:30,barrel:26,stock:`solid`,mag:`drum`,optic:`carry`,col:`#2a2b2a`,furn:`#3b4130`,bipod:!0},m1911:{kind:`pistol`,slide:54,col:`#55585c`,grip:`#5a3a22`},glock18:{kind:`pistol`,slide:50,col:`#3a3c40`,grip:`#3a3c40`,ext:!0},deagle:{kind:`pistol`,slide:64,col:`#9a9c9e`,grip:`#222`,heavy:!0},magnum:{kind:`revolver`,slide:60,col:`#6f7276`,grip:`#6b4226`}};function ye(e){let t=ve[e],n=k(160,64),r=n.getContext(`2d`);if(r.lineJoin=`round`,t.kind===`rifle`){let e=t.stock===`none`?20:t.short?22:12,n=e+26;r.fillStyle=t.furn,t.stock===`solid`?(r.beginPath(),r.moveTo(n,26),r.lineTo(e,28),r.lineTo(e,42),r.lineTo(n,37),r.closePath(),r.fill()):t.stock===`tube`?(r.fillRect(e+8,27,n-e-8,4),r.fillRect(e,24,9,16)):t.stock===`skeleton`&&(r.strokeStyle=t.furn,r.lineWidth=3,r.beginPath(),r.moveTo(n,27),r.lineTo(e,28),r.lineTo(e,41),r.lineTo(n,34),r.stroke()),r.fillStyle=t.col,r.fillRect(n,24,t.recv,13);let i=n+t.recv;r.fillStyle=t.furn,r.fillRect(i,25,t.hand,10),r.fillStyle=t.col,r.fillRect(i+t.hand,28,t.barrel,4),t.brake&&r.fillRect(i+t.hand+t.barrel-6,25,8,10),r.fillStyle=t.col,r.beginPath(),r.moveTo(n+8,37),r.lineTo(n+17,37),r.lineTo(n+13,52),r.lineTo(n+5,51),r.closePath(),r.fill();let a=n+t.recv-20;r.fillStyle=t.mag===`drum`?`#4a5136`:t.col,t.mag===`straight`?r.fillRect(a,37,9,17):t.mag===`curve`?(r.beginPath(),r.moveTo(a,37),r.lineTo(a+9,37),r.quadraticCurveTo(a+14,49,a+20,55),r.lineTo(a+11,58),r.quadraticCurveTo(a+4,49,a,37),r.fill()):t.mag===`box`?r.fillRect(a-2,37,13,12):t.mag===`drum`?r.fillRect(a-6,37,20,16):t.mag===`tube`&&(r.fillRect(i-6,36,t.hand+18,5),r.fillStyle=`#3a3b3d`,r.fillRect(i+4,35,18,8)),r.fillStyle=`#151617`,t.optic===`red`?(r.fillRect(n+12,15,16,9),r.fillStyle=`#c3352a`,r.fillRect(n+25,17,2,4)):t.optic===`scope`?(r.fillRect(n+6,13,40,8),r.fillRect(n+2,11,8,12),r.fillRect(n+42,11,8,12),r.fillRect(n+22,20,6,4)):t.optic===`carry`?(r.fillRect(n+10,17,30,4),r.fillRect(n+12,20,4,4),r.fillRect(n+34,20,4,4)):(r.fillRect(i+t.hand-4,20,3,4),r.fillRect(n+4,21,6,3)),t.bipod&&(r.strokeStyle=`#1a1a1a`,r.lineWidth=2.5,M(r,i+t.hand-4,35,i+t.hand+8,53),M(r,i+t.hand-4,35,i+t.hand-12,53)),r.fillStyle=`rgba(255,255,255,0.12)`,r.fillRect(n,25,t.recv+t.hand,2)}else{if(t.kind===`revolver`)r.fillStyle=t.col,r.fillRect(66,23,t.slide-18,8),r.fillRect(44,20,26,15),r.fillStyle=`#4c4f53`,N(r,48,21,18,13,4),r.fill(),r.fillStyle=t.col,r.fillRect(38,17,6,6);else{r.fillStyle=t.col,r.fillRect(40,20,t.slide,t.heavy?14:11),r.fillStyle=`rgba(0,0,0,0.3)`;for(let e=0;e<4;e++)r.fillRect(44+e*3,22,1.5,7);r.fillStyle=t.col,r.fillRect(46,30,26,6)}r.fillStyle=t.grip,r.beginPath(),r.moveTo(44,32),r.lineTo(60,32),r.lineTo(54,58),r.lineTo(38,56),r.closePath(),r.fill(),t.ext&&(r.fillStyle=`#18191a`,r.fillRect(39,54,14,12)),r.strokeStyle=t.col,r.lineWidth=2,r.beginPath(),r.arc(64,36,6,0,Math.PI),r.stroke(),r.fillStyle=`rgba(255,255,255,0.18)`,r.fillRect(40,20,t.slide,2)}return n}function be(e){let t=k(64,64),n=t.getContext(`2d`);if(n.lineJoin=`round`,e===`frag`){j(n,32,36,15,17,`#3f4a2e`),n.strokeStyle=`rgba(0,0,0,0.35)`,n.lineWidth=1.5;for(let e=-2;e<=2;e++)M(n,18,36+e*6,46,36+e*6);M(n,32,20,32,52),n.fillStyle=`#7d7f7a`,n.fillRect(26,14,12,7),n.fillStyle=`#9a9c95`,n.fillRect(36,15,12,4),n.strokeStyle=`#c9b23c`,n.lineWidth=2,n.beginPath(),n.arc(24,15,5,0,Math.PI*2),n.stroke(),j(n,27,30,4,6,`rgba(255,255,255,0.12)`)}else if(e===`flash`){n.fillStyle=`#5b6066`,N(n,20,18,24,38,4),n.fill(),n.fillStyle=`#2b5c8a`,n.fillRect(20,26,24,5),n.fillStyle=`#1b1c1e`;for(let e=0;e<3;e++)for(let t=0;t<3;t++)n.fillRect(24+t*7,35+e*6,3,3);n.fillStyle=`#8b8f94`,n.fillRect(26,11,12,8),n.strokeStyle=`#c9b23c`,n.lineWidth=2,n.beginPath(),n.arc(22,12,5,0,Math.PI*2),n.stroke()}else if(e===`medkit`)n.fillStyle=`#d8d4c8`,N(n,10,18,44,34,5),n.fill(),n.fillStyle=`#8f8b80`,n.fillRect(24,12,16,7),n.fillStyle=`#c3352a`,n.fillRect(28,24,8,22),n.fillRect(21,31,22,8);else if(e===`bandage`){j(n,32,34,18,18,`#e2dac6`),n.strokeStyle=`#b3a98f`,n.lineWidth=2;for(let e=4;e<=14;e+=5)n.beginPath(),n.arc(32,34,e,0,Math.PI*2),n.stroke();n.fillStyle=`#e2dac6`,n.fillRect(44,40,14,10)}else if(e===`ammo`){n.fillStyle=`#4c5a3b`,n.fillRect(8,26,48,28),n.fillStyle=`#3a4530`,n.fillRect(8,22,48,6),n.fillStyle=`#c9b23c`,n.font=`bold 11px Arial`,n.textAlign=`center`,n.fillText(`7.62`,32,44);for(let e=0;e<5;e++)n.fillStyle=`#c9a03c`,n.fillRect(14+e*8,8,5,14),n.fillStyle=`#8d5a2b`,n.fillRect(14+e*8,6,5,5)}else e===`intel`?(n.fillStyle=`#b89a5c`,n.fillRect(8,16,48,38),n.fillStyle=`#c9ad6e`,n.fillRect(8,12,20,6),n.fillStyle=`#eee8d8`,n.fillRect(12,18,40,4),n.save(),n.translate(32,38),n.rotate(-.25),n.strokeStyle=`#c3352a`,n.lineWidth=2,n.strokeRect(-20,-8,40,15),n.fillStyle=`#c3352a`,n.font=`bold 9px Arial`,n.textAlign=`center`,n.fillText(`TOP SECRET`,0,3),n.restore()):e===`drive`?(n.fillStyle=`#26282b`,N(n,12,10,40,46,4),n.fill(),n.fillStyle=`#3d4044`,n.fillRect(16,14,32,22),n.fillStyle=`#a5d63f`,n.fillRect(42,46,5,4),n.fillStyle=`#c9b23c`,n.fillRect(16,40,18,10),n.fillStyle=`#26282b`,n.font=`bold 7px Arial`,n.fillText(`ENC`,18,48)):e===`molotov`?(n.fillStyle=`rgba(120,150,90,0.85)`,N(n,20,26,24,32,6),n.fill(),n.fillStyle=`rgba(214,150,40,0.85)`,n.fillRect(21,40,22,17),n.fillStyle=`rgba(120,150,90,0.9)`,n.fillRect(27,12,10,16),n.fillStyle=`#d8cfb8`,n.beginPath(),n.moveTo(27,13),n.lineTo(24,4),n.lineTo(33,8),n.lineTo(37,2),n.lineTo(37,13),n.closePath(),n.fill(),n.fillStyle=`#ff9a2a`,n.beginPath(),n.moveTo(26,6),n.quadraticCurveTo(30,-4,36,4),n.quadraticCurveTo(32,2,30,8),n.closePath(),n.fill(),n.fillStyle=`rgba(255,255,255,0.25)`,n.fillRect(23,30,3,20)):e===`smoke`&&(n.fillStyle=`#5c6660`,N(n,20,16,24,40,4),n.fill(),n.fillStyle=`#a5d63f`,n.fillRect(20,24,24,4),n.fillStyle=`#1b1c1e`,n.font=`bold 8px Arial`,n.textAlign=`center`,n.fillText(`SMOKE`,32,44),n.fillStyle=`#8b8f94`,n.fillRect(26,9,12,8),n.strokeStyle=`#c9b23c`,n.lineWidth=2,n.beginPath(),n.arc(22,10,5,0,Math.PI*2),n.stroke());return t}function xe(e){let t=c[e],n=k(64,64),r=n.getContext(`2d`);r.fillStyle=t.col,r.beginPath(),r.moveTo(14,8),r.lineTo(24,8),r.quadraticCurveTo(32,18,40,8),r.lineTo(50,8),r.lineTo(54,22),r.lineTo(54,56),r.lineTo(10,56),r.lineTo(10,22),r.closePath(),r.fill(),r.fillStyle=`rgba(0,0,0,0.25)`,e!==`soft`&&(N(r,17,22,30,24,3),r.fill()),r.fillRect(10,48,44,3),r.fillStyle=`rgba(255,255,255,0.1)`;for(let e=0;e<3;e++)r.fillRect(14+e*13,49,9,7);return r.fillStyle=`#e6eadf`,r.font=`bold 12px Arial`,r.textAlign=`center`,r.textBaseline=`middle`,r.fillText(t.tier,32,35),n}function Se(e){let r=k(t*3,n*3),i=r.getContext(`2d`),a={"#":`#a49e92`,",":`#5c5044`,w:`#24485a`,c:`#8a6a40`,h:`#8a7c58`,v:`#5a3c2c`,p:`#9aa0a6`,K:`#a0503a`,o:`#c4c6c2`,b:`#7a3a2a`,T:`#3c5a2c`};for(let r=0;r<n;r++)for(let n=0;n<t;n++){let t=e.grid[r][n];i.fillStyle=a[t]||A(...t===`=`?e.theme.road:e.theme.ground),i.fillRect(n*3,r*3,3,3)}return i.fillStyle=`#7fe36a`,i.beginPath(),i.arc((e.start[0]+.5)*3,(e.start[1]+.5)*3,5,0,Math.PI*2),i.fill(),i.strokeStyle=`#e8c547`,i.lineWidth=2,i.beginPath(),i.arc((e.exfil[0]+.5)*3,(e.exfil[1]+.5)*3,9,0,Math.PI*2),i.stroke(),i.fillStyle=`#e8c547`,i.font=`bold 11px Arial`,i.textAlign=`center`,i.textBaseline=`middle`,i.fillText(`H`,(e.exfil[0]+.5)*3,(e.exfil[1]+.5)*3+1),r}let Ce={},we={};function Te(e){return e.type[0]+`:`+e.id}function Ee(e){let t=Te(e);return Ce[t]||(Ce[t]=(e.type===`weapon`?ye(e.id):e.type===`armour`?xe(e.id):be(e.id)).toDataURL()),Ce[t]}function De(e){let t=Te(e);if(!we[t]){let n=new Image;n.src=Ee(e),we[t]=n}return we[t]}let P=(()=>{let e=null,t=null,n=null,r=null,i=null,a=null,o=[];function s(){if(e)e.state===`suspended`&&e.resume();else try{e=new(window.AudioContext||window.webkitAudioContext),t=e.createGain(),t.gain.value=.45,r=e.createBiquadFilter(),r.type=`lowpass`,r.frequency.value=22e3,r.Q.value=.4,i=e.createGain(),i.gain.value=1;let o=e.createDynamicsCompressor();t.connect(r),r.connect(i),i.connect(o),o.connect(e.destination),a=e.createGain(),a.gain.value=1,a.connect(e.destination),n=e.createBuffer(1,e.sampleRate*2,e.sampleRate);let s=n.getChannelData(0);for(let e=0;e<s.length;e++)s[e]=Math.random()*2-1;let c=[`scream`,`groan`,`scream`,`groan`,`scream`,`scream`,`groan`,`scream`,`groan`,`scream`],l=()=>{let e=c.shift();e&&(_[e].length<6&&_[e].push(y(e)),setTimeout(l,60))};setTimeout(l,500)}catch{e=null}}function c(r,i,a,o={}){if(!e||a<.005)return;let s=e.currentTime+(o.delay||0),c=e.createBufferSource();c.buffer=n;let l=e.createBiquadFilter();l.type=o.type||`lowpass`,l.Q.value=o.q||.7,l.frequency.setValueAtTime(i,s),o.sweep&&l.frequency.exponentialRampToValueAtTime(o.sweep,s+r);let u=e.createGain();o.attack?(u.gain.setValueAtTime(1e-4,s),u.gain.exponentialRampToValueAtTime(a,s+o.attack)):u.gain.setValueAtTime(a,s),u.gain.exponentialRampToValueAtTime(8e-4,s+r),c.connect(l),l.connect(u),u.connect(t),c.start(s,Math.random()*1.5),c.stop(s+r+.02)}function l(n,r,i,a=`sine`,o=null,s=0){if(!e||i<.005)return;let c=e.currentTime+s,l=e.createOscillator();l.type=a,l.frequency.setValueAtTime(n,c),o&&l.frequency.exponentialRampToValueAtTime(o,c+r);let u=e.createGain();u.gain.setValueAtTime(1e-4,c),u.gain.exponentialRampToValueAtTime(i,c+.005),u.gain.exponentialRampToValueAtTime(8e-4,c+r),l.connect(u),u.connect(t),l.start(c),l.stop(c+r+.02)}let u={m4a1:{crack:[6200,.03,.5],body:[2500,.13,.6,520],thump:[140,.11,.42],tail:[950,.5,.17]},ak47:{crack:[4300,.035,.45],body:[1500,.2,.72,280],thump:[92,.17,.62],tail:[650,.75,.23]},mp5:{crack:[4800,.02,.22],body:[1900,.08,.42,650],thump:[175,.07,.28],tail:[1300,.22,.07]},spas12:{crack:[2600,.045,.5],body:[1100,.36,.95,140],thump:[66,.32,.85],tail:[450,1.1,.3],after:`pump`},barrett:{crack:[5200,.05,.75],body:[900,.55,1,110],thump:[46,.55,.95],tail:[380,1.9,.36],echo:.38,after:`bolt`},m249:{crack:[5600,.03,.45],body:[2100,.15,.64,420],thump:[118,.13,.52],tail:[800,.55,.19]},m1911:{crack:[3300,.025,.38],body:[1400,.13,.56,380],thump:[105,.12,.52],tail:[850,.35,.1]},glock18:{crack:[6800,.018,.33],body:[2900,.065,.4,950],thump:[185,.06,.24],tail:[1500,.18,.06]},deagle:{crack:[4600,.04,.62],body:[1250,.3,.88,190],thump:[72,.27,.78],tail:[580,.95,.26],echo:.22},magnum:{crack:[5600,.04,.6],body:[1800,.26,.82,300],thump:[84,.22,.66],tail:[820,.85,.22],ring:2300}},d={m4a1:[`rifle`,1],ak47:[`rifle`,.78],mp5:[`rifle`,1.18],m249:[`lmg`,.85],spas12:[`shotgun`,.95],barrett:[`bolt`,.7],m1911:[`pistol`,1],glock18:[`pistol`,1.22],deagle:[`pistol`,.82],magnum:[`revolver`,1]};function f(e,t,n,r=1){switch(e){case`click`:c(.025,3600*r,.5*n,{type:`bandpass`,q:4,delay:t}),l(2100*r,.02,.12*n,`square`,null,t);break;case`clack`:c(.05,1700*r,.6*n,{type:`bandpass`,q:2,delay:t}),l(620*r,.05,.22*n,`triangle`,300*r,t);break;case`slide`:c(.13,2600*r,.35*n,{type:`bandpass`,q:3,sweep:900*r,delay:t});break;case`magout`:c(.09,2200*r,.35*n,{type:`bandpass`,q:2.5,sweep:1200*r,delay:t}),f(`click`,t+.02,n*.7,r);break;case`magin`:f(`slide`,t,n*.6,r),f(`clack`,t+.1,n,r);break;case`rack`:f(`slide`,t,n,r),f(`clack`,t+.14,n*1.1,r);break;case`snap`:c(.04,2400*r,.7*n,{type:`bandpass`,q:2.5,delay:t}),l(900*r,.04,.2*n,`square`,500*r,t);break;case`shell`:l(1900*r,.04,.14*n,`triangle`,1300*r,t),c(.035,3800*r,.35*n,{type:`bandpass`,q:3,delay:t+.01});break;case`jingle`:for(let e=0;e<6;e++)l(3200+Math.random()*2400,.06,.05*n,`sine`,null,t+e*.035+Math.random()*.02);break;case`cover`:c(.08,900*r,.7*n,{type:`bandpass`,q:1.5,delay:t}),l(220*r,.08,.3*n,`triangle`,140*r,t);break;case`belt`:for(let e=0;e<8;e++)c(.02,3e3+Math.random()*1500,.18*n,{type:`bandpass`,q:4,delay:t+e*.03});break;case`pump`:c(.1,1500*r,.5*n,{type:`bandpass`,q:2,sweep:700*r,delay:t}),f(`clack`,t+.12,n*1.2,r*.9);break;case`bolt`:f(`clack`,t,n*.8,r*.8),f(`slide`,t+.08,n*.8,r*.8),f(`slide`,t+.25,n*.8,r*.9),f(`clack`,t+.38,n,r*.8)}}function p(e,t=1){let n=u[e]||u.m4a1;c(n.crack[1],n.crack[0],n.crack[2]*t,{type:`highpass`}),c(n.body[1],n.body[0],n.body[2]*t,{sweep:n.body[3]}),l(n.thump[0],n.thump[1],n.thump[2]*t,`sine`,n.thump[0]*.35),c(n.tail[1],n.tail[0],n.tail[2]*t,{sweep:n.tail[0]*.4,delay:.02}),n.echo&&c(n.tail[1]*.8,n.tail[0]*.8,n.tail[2]*.45*t,{sweep:n.tail[0]*.3,delay:n.echo}),n.ring&&l(n.ring,.3,.035*t,`sine`,null,.01),n.after&&f(n.after,n.after===`pump`?.38:.55,.6*t,n.after===`pump`?.95:.7)}function m(e,t,n=1){let[r,i]=d[e]||d.m4a1;switch(r){case`rifle`:f(`magout`,t*.12,n,i),f(`magin`,t*.55,n,i),f(`rack`,t*.8,n,i);break;case`lmg`:f(`cover`,t*.08,n,i),f(`belt`,t*.3,n,i),f(`magout`,t*.42,n,i),f(`belt`,t*.55,n,i),f(`cover`,t*.72,n*1.2,i),f(`rack`,t*.86,n,i);break;case`shotgun`:for(let e=0;e<5;e++)f(`shell`,t*(.08+e*.15),n,i);f(`pump`,t*.86,n,i);break;case`bolt`:f(`bolt`,t*.06,n,i),f(`magout`,t*.32,n,i),f(`magin`,t*.6,n,i),f(`bolt`,t*.8,n,i);break;case`pistol`:f(`magout`,t*.12,n,i),f(`magin`,t*.5,n,i),f(`snap`,t*.82,n,i);break;case`revolver`:f(`click`,t*.06,n,.8),f(`jingle`,t*.2,n,i);for(let e=0;e<3;e++)f(`shell`,t*(.42+e*.1),n,i);f(`snap`,t*.86,n,.7)}}function h(e,t=1){let n=.9+Math.random()*.2;switch(e){case`wood`:c(.06,850*n,.55*t,{type:`bandpass`,q:1.6}),l(150*n,.09,.3*t,`triangle`,105);break;case`grass`:c(.1,1300*n,.33*t,{type:`bandpass`,q:.8,attack:.015}),c(.07,3600,.1*t,{type:`highpass`,delay:.02});break;case`sand`:c(.12,2700*n,.3*t,{type:`bandpass`,q:1,attack:.02}),c(.08,5200,.12*t,{type:`highpass`,delay:.035});break;case`snow`:c(.07,1100*n,.42*t,{type:`bandpass`,q:2.2}),c(.09,2100*n,.32*t,{type:`bandpass`,q:3,delay:.05});break;case`carpet`:c(.06,480*n,.3*t,{attack:.01});break;default:c(.035,2300*n,.45*t,{type:`bandpass`,q:1.2}),l(115*n,.05,.22*t,`sine`,70)}}let g=0,_={scream:[],groan:[]};function v(){return(Math.random()+Math.random()+Math.random()-1.5)*1.15}function y(t){let n=e.sampleRate,r=t===`scream`,i=r?.85+Math.random()*.6:1.1+Math.random()*.6,a=Math.floor((i+0+.1)*n),o=new Float32Array(a),s=r?300+Math.random()*90:115+Math.random()*30,c=r?1.25+Math.random()*.2:1.1,l=r?.45+Math.random()*.3:-1,u=[0,1,2].map(()=>[.6+Math.random()*2.2,Math.random()*6.3,.02+Math.random()*.03]),d=4.5+Math.random()*2.5,f=e=>{let t;t=e<.12?.62+(c-.62)*Math.sin(e/.12*Math.PI/2):e<.75?c-(e-.12)*.25:c-.16-(e-.75)/.25*(r?.45:.25),l>0&&e>l&&e<l+.06&&(t*=1.35);let n=0;for(let[t,r,a]of u)n+=Math.sin(e*i*t*6.283+r)*a;return s*t*(1+n+Math.sin(e*i*d*6.283)*.018)},p=.92+Math.random()*.16,m=r?[[700,880,620,110],[1180,1420,1080,130],[2500,2650,2400,190],[3450,3550,3350,260],[4300,4400,4200,320]]:[[480,560,430,90],[900,980,820,110],[2400,2450,2350,170],[3300,3350,3250,250],[4200,4200,4200,300]],h=m.map(()=>[0,0]),g=0,_=1/f(0),y=1,b=0,x=0,S=r?.5:.62,C=r?.18+Math.random()*.22:.12,w=Math.floor(i*n);for(let e=0;e<w;e++){let t=e/w;g+=1/(_*n),g>=1&&(--g,b++,_=1/f(t)*(1+v()*(r?.025:.018)),y=(1+v()*(r?.12:.08))*(b%2?1-C:1));let i,a=S*.62;i=g<a?.5*(1-Math.cos(Math.PI*g/a)):g<S?Math.cos(Math.PI/2*(g-a)/(S-a)):0,i*=y;let s=(i-x)*18;x=i;let c;c=t<.04?t/.04:t<.6?1-(t-.04)*.35:t<.7?.8+(t-.6)*1.5:.95*(1-(t-.7)/.3)**1.6,s*=c;for(let e=0;e<m.length;e++){let[r,i,a,o]=m[e],c=(t<.3?r+(i-r)*(t/.3):i+(a-i)*((t-.3)/.7))*p,l=-Math.exp(-2*Math.PI*o/n),u=2*Math.exp(-Math.PI*o/n)*Math.cos(2*Math.PI*c/n),d=(1-u-l)*s+u*h[e][0]+l*h[e][1];h[e][1]=h[e][0],h[e][0]=d,s=d}o[e]=s}let T=0;for(let e=0;e<a;e++)T=Math.max(T,Math.abs(o[e]));let E=r?2.2:1.4,ee=0;for(let e=0;e<a;e++)o[e]=Math.tanh(o[e]/(T||1)*E),ee=Math.max(ee,Math.abs(o[e]));let D=e.createBuffer(1,a,n),O=D.getChannelData(0);for(let e=0;e<a;e++)O[e]=o[e]/(ee||1)*.9;return D}function b(n,r,i){if(!e||r<.01)return;let a=_[n];a.length||a.push(y(n));let o=e.createBufferSource();o.buffer=a[Math.floor(Math.random()*a.length)],o.playbackRate.value=Math.min(1.15,Math.max(.85,i))*(.96+Math.random()*.08);let s=e.createGain();s.gain.value=(n===`scream`?.14:.22)*r,o.connect(s),s.connect(t),o.start()}function x(e=1,t=1){b(`scream`,e,t)}function S(e){return y(e)}function C(t=5,n=2,s=.12,c=.03){if(!e)return;let l=e.currentTime;for(let e of o)try{e.stop(l+.05)}catch{}o=[];for(let[e,a,o]of[[r.frequency,320,22e3],[i.gain,.28,1]])e.cancelScheduledValues(l),e.setValueAtTime(e.value,l),e.exponentialRampToValueAtTime(a,l+.06),e.setValueAtTime(a,l+t),e.exponentialRampToValueAtTime(o,l+t+n);for(let[r,i]of[[3520,1],[3534,.55],[7040,.1]]){let u=e.createOscillator();u.type=`sine`,u.frequency.value=r*(.98+Math.random()*.04);let d=e.createGain();d.gain.setValueAtTime(1e-4,l),d.gain.exponentialRampToValueAtTime(s*i,l+c),d.gain.setValueAtTime(s*i,l+t),d.gain.exponentialRampToValueAtTime(1e-4,l+t+n),u.connect(d),d.connect(a),u.start(l),u.stop(l+t+n+.05),o.push(u)}let u=++g;setTimeout(()=>{if(u!==g||!e)return;let t=e.currentTime;for(let[e,n]of[[r.frequency,22e3],[i.gain,1]])e.cancelScheduledValues(t),e.setTargetAtTime(n,t,.08)},(t+n)*1e3+150)}function w(){return r?r.frequency.value:22e3}function T(){return e?e.currentTime:0}function E(e=1,t=1){b(`groan`,e,t)}function ee(e){if(e===`bandage`){c(.18,1800,.35,{type:`bandpass`,q:3,sweep:4200}),c(.12,2600,.3,{type:`bandpass`,q:4,sweep:5200,delay:.22});for(let e=0;e<4;e++)c(.16,1500+e*200,.12,{type:`bandpass`,q:1.2,attack:.04,delay:.45+e*.17})}else{for(let e=0;e<16;e++)c(.015,4200,.18,{type:`bandpass`,q:5,delay:e*.025});c(.2,1800,.3,{type:`bandpass`,q:3,sweep:4200,delay:.55});for(let e=0;e<6;e++)c(.18,1400+e*150,.12,{type:`bandpass`,q:1.2,attack:.04,delay:.85+e*.25})}}return{init:s,shot:p,reload:m,step:h,scream:x,groan:E,useMed:ee,ring:C,muffleHz:w,audioTime:T,renderVoiceForTest:S,explosion(e=1){c(1.3,900,e,{sweep:50}),l(70,.9,.6*e,`sine`,25)},flashbang(e=1){c(.5,3500,.8*e,{type:`highpass`})},hit(){l(1900,.05,.16,`square`)},kill(){l(1400,.08,.18,`square`),l(900,.12,.18,`square`,null,.05)},hurt(){c(.15,600,.4),l(160,.15,.22,`sawtooth`,80)},armourHit(){c(.05,3800,.3,{type:`bandpass`,q:2}),l(700,.06,.1,`square`,400)},click(){l(1200,.03,.12,`square`)},pickup(){l(660,.06,.13,`triangle`),l(990,.08,.13,`triangle`,null,.05)},deny(){l(180,.12,.18,`square`)},throwIt(){c(.15,1200,.25,{type:`bandpass`})},bounce(){l(900,.04,.08,`triangle`,500)},heal(){l(520,.12,.12,`sine`,780),l(780,.15,.1,`sine`,1040,.1)},beep(){l(880,.07,.1,`sine`)},extract(){l(440,.2,.18,`triangle`),l(660,.2,.18,`triangle`,null,.15),l(880,.45,.18,`triangle`,null,.3)},ignite(e=1){c(.12,2500,.5*e,{type:`highpass`}),c(1.2,700,.6*e,{sweep:200,delay:.05})},smoke(e=1){c(1.8,5e3,.35*e,{type:`highpass`,sweep:1500})},armourBreak(){c(.25,3e3,.45,{type:`bandpass`,q:1.5}),l(300,.25,.15,`square`,120)},rotor(e=1){c(.09,180,.5*e,{sweep:60})},radio(){l(1200,.05,.08,`square`),l(900,.05,.08,`square`,null,.07),c(.25,2500,.08,{type:`bandpass`,q:1,delay:.14})},death(){C(6,3,.08,1)},knifeThrow(){c(.16,2600,.3,{type:`bandpass`,q:1.5,sweep:900})},slash(){c(.14,3200,.35,{type:`bandpass`,q:1.2,sweep:1200}),c(.12,700,.45,{delay:.08}),l(140,.12,.2,`sine`,80,.08)},knifeClink(){l(2600,.08,.1,`triangle`,1800),c(.04,4200,.2,{type:`bandpass`,q:3})}}})(),Oe=document.getElementById(`game`),F=Oe.getContext(`2d`),I=0,L=0,ke=1,Ae=1,je=(e,t,n)=>e<t?t:e>n?n:e,R=(e,t)=>e+Math.random()*(t-e),Me=(e,t)=>{let n=e-t;for(;n>Math.PI;)n-=Math.PI*2;for(;n<-Math.PI;)n+=Math.PI*2;return n},Ne=(e,t,n)=>{let r=Me(t,e);return Math.abs(r)<=n?t:e+Math.sign(r)*n},Pe=100*Math.PI/180,Fe=1150,Ie=15*Math.PI/180,Le=50*Math.PI/180,Re=2.5,ze=new Set([`#`,`c`,`h`,`v`,`p`,`K`,`o`,`w`,`b`,`T`]),Be=new Set([`#`,`K`,`o`]),Ve=new Set([`#`,`c`,`h`,`v`,`p`,`K`,`o`,`b`,`T`]),He=`Bahnschrift, 'Arial Narrow', 'Segoe UI', sans-serif`,Ue=[`ak47`,`ak47`,`ak47`,`m4a1`,`m4a1`,`mp5`,`mp5`,`m249`,`m1911`,`m1911`,`glock18`,`magnum`],We=[[1,0],[-1,0],[0,1],[0,-1],[1,1],[1,-1],[-1,1],[-1,-1]],z={keys:Object.create(null),mx:0,my:0,mdown:!1,clicked:!1},Ge=e=>!!z.keys[e],B=null,Ke=null,V=null;function qe(){ke=Math.min(window.devicePixelRatio||1,2),I=window.innerWidth,L=window.innerHeight,Oe.width=Math.round(I*ke),Oe.height=Math.round(L*ke),Ae=je(Math.min(I/1280,L/820),.55,1.4),lr=null,fr=null}function Je(e,r){return e<0||r<0||e>=t||r>=n?`#`:B.grid[r][e]}function Ye(e,t){return ze.has(Je(e,t))}function Xe(e,t,n,r,i,a){let o=Math.floor(e/40),s=Math.floor(t/40);if(a.has(Je(o,s)))return 0;let c=n>0?1:-1,l=r>0?1:-1,u=n===0?1/0:Math.abs(40/n),d=r===0?1/0:Math.abs(40/r),f=n>0?((o+1)*40-e)/n:n<0?(o*40-e)/n:1/0,p=r>0?((s+1)*40-t)/r:r<0?(s*40-t)/r:1/0;for(;;){let e;if(f<p?(o+=c,e=f,f+=u):(s+=l,e=p,p+=d),e>=i)return i;if(a.has(Je(o,s)))return e}}function Ze(e,t,n,r,i){let a=Math.hypot(n-e,r-t);return a<1||Xe(e,t,(n-e)/a,(r-t)/a,a,i)>=a-1}function Qe(e,t,n,r,i,a,o,s){let c=a-e,l=o-t,u=c*n+l*r,d=c-n*u,f=l-r*u,p=d*d+f*f;if(p>s*s)return-1;let m=Math.sqrt(s*s-p),h=u-m;if(h<0){if(u+m<0)return-1;h=0}return h<=i?h:-1}function $e(e,t){let n=Math.floor((e.x-t)/40),r=Math.floor((e.x+t)/40),i=Math.floor((e.y-t)/40),a=Math.floor((e.y+t)/40);for(let o=i;o<=a;o++)for(let i=n;i<=r;i++){if(!Ye(i,o))continue;let n=i*40,r=o*40,a=je(e.x,n,n+40),s=je(e.y,r,r+40),c=e.x-a,l=e.y-s,u=c*c+l*l;if(!(u>=t*t)){if(u>1e-6){let n=Math.sqrt(u);e.x+=c/n*(t-n),e.y+=l/n*(t-n)}else{let i=e.x-n,a=n+40-e.x,o=e.y-r,s=r+40-e.y,c=Math.min(i,a,o,s);c===i?e.x=n-t:c===a?e.x=n+40+t:e.y=c===o?r-t:r+40+t}}}}function et(e,t,n,r){e.x+=t,$e(e,r),e.y+=n,$e(e,r)}let tt=.9;function nt(e,t){return Math.abs(e-V.cam.x)<I/2/Ae&&Math.abs(t-V.cam.y)<L/2/Ae}function rt(e){return 150*Math.min(1,(12-e.t)/.8)*Math.min(1,e.t/1.5)}function it(e,t,n,r,i){let a=i;for(let i of V.smokes){let o=rt(i);if(o<8)continue;let s=i.x-e,c=i.y-t;if(s*s+c*c<o*o)return Math.min(a,28);let l=Qe(e,t,n,r,a,i.x,i.y,o);l>=0&&(a=l)}return a}function at(e,t,n,r,i){return it(e,t,n,r,Xe(e,t,n,r,i,Be))}function ot(e,t){let n=V.player;if(n.dead)return!1;let r=Math.hypot(e-n.x,t-n.y);return r>Fe||r>88&&Math.abs(Me(Math.atan2(t-n.y,e-n.x),n.angle))>Pe/2+Math.atan2(13,r)?!1:r<1||at(n.x,n.y,(e-n.x)/r,(t-n.y)/r,r)>=r-1}function st(e,t,n,r){let i=Math.hypot(n-e,r-t)||1,a=-(r-t)/i*16,o=(n-e)/i*16;return!Ze(e,t,n,r,Ve)&&!Ze(e,t,n+a,r+o,Ve)&&!Ze(e,t,n-a,r-o,Ve)}function ct(e,t){for(let n of V.enemies)if(n!==t&&!n.dead&&n.suppressT>0&&n.coverTile===e)return!0;return!1}function lt(e,r,i){let a=t*n,o=new Int32Array(a).fill(-1),s=new Uint8Array(a),c=new Int32Array(a),l=Math.floor(e.y/40)*t+Math.floor(e.x/40),u=0,d=0;for(o[l]=l,c[d++]=l;u<d;){let n=c[u++],a=n%t,f=n/t|0,p=(a+.5)*40,m=(f+.5)*40;if(Math.hypot(p-r,m-i)>150&&!ct(n,e)&&st(r,i,p,m)){e.coverTile=n;let r=[];for(let e=n;e!==l;e=o[e])r.push({x:(e%t+.5)*40,y:((e/t|0)+.5)*40});return r.reverse(),r.length||r.push({x:p,y:m}),r}if(!(s[n]>=8))for(let[e,r]of We){let i=a+e,l=f+r;if(Ye(i,l)||e&&r&&(Ye(a+e,f)||Ye(a,f+r)))continue;let u=l*t+i;o[u]===-1&&(o[u]=n,s[u]=s[n]+1,c[d++]=u)}}return null}function ut(e,t,n){e.pending||={},e.pending[t]||(e.pending[t]={t:.5,fn:n})}function dt(e,t,n,r){let i=Math.cos(n),a=Math.sin(n);for(let n of V.enemies){if(n.dead)continue;let o=n.x-e,s=n.y-t,c=o*i+s*a;c<0||c>r||Math.abs(o*a-s*i)>90+c*.12||(n.suppressT>0?n.suppressT=Re:ut(n,`suppress`,()=>{n.coverT=0,n.suppressT=Re,n.lastSeen={x:e,y:t},n.state!==`alert`&&(n.state=`alert`,n.reactT=Math.max(n.reactT,.4))}))}}function ft(e,r,i,a){let o=Math.floor(e/40),s=Math.floor(r/40),c=Math.floor(i/40),l=Math.floor(a/40);if(Ye(c,l))return null;let u=new Int32Array(t*n).fill(-1),d=new Int32Array(t*n),f=s*t+o,p=l*t+c,m=0,h=0;for(u[f]=f,d[h++]=f;m<h;){let e=d[m++];if(e===p)break;let n=e%t,r=e/t|0;for(let[i,a]of We){let o=n+i,s=r+a;if(Ye(o,s)||i&&a&&(Ye(n+i,r)||Ye(n,r+a)))continue;let c=s*t+o;u[c]===-1&&(u[c]=e,d[h++]=c)}}if(u[p]===-1)return null;let g=[];for(let e=p;e!==f;e=u[e])g.push({x:(e%t+.5)*40,y:((e/t|0)+.5)*40});return g.reverse(),g.length&&(g[g.length-1]={x:i,y:a}),g}function pt(e,t,n){let r=Math.floor(e/40),i=Math.floor(t/40);for(let e=0;e<15;e++){let e=r+Math.round(R(-n,n)),t=i+Math.round(R(-n,n));if(!Ye(e,t))return{x:(e+.5)*40,y:(t+.5)*40}}return null}function mt(e,t){let n=e.throwable&&J.unlocked.includes(e.throwable)?b(e.throwable):null;if(t===`assaulter`)return n&&(n.uses=Vt),{weapons:[x(e.primary),x(e.secondary)],items:[b(`bandage`),null,null,null,n]};let r=[n,b(`bandage`)];for(;r.length<ht(t);)r.push(null);return{weapons:[x(e.primary),x(e.secondary)],items:r}}function ht(e){return e===`hauler`?6:4}function gt(e,t){return e=_t(e,t),t===`assaulter`&&Ut(e),e}function _t(e,t){let n=e.length===5?e[4]:null,r=e.length===5?e.slice(0,4):e.slice(),i=ht(t),a=r.slice(0,i);for(;a.length<i;)a.push(null);let s=r.slice(i).filter(Boolean);t===`assaulter`&&a.push(null),n&&(t===`assaulter`&&o[n.id].kind===`throwable`?a[Bt]=n:s.unshift(n));for(let e of s){let t=a.findIndex((e,t)=>!e&&t<i);if(t<0)break;a[t]=e}return a}function vt(e,r,i,a){let o=p[Z]?Z:`assaulter`,s=i?JSON.parse(JSON.stringify({weapons:i.weapons,items:i.items})):mt(e,o);s.items=gt(s.items,o),B=O(r),t=B.w,n=B.h,B.surface=bn(B),Ke=_e(B);let c={x:(B.start[0]+.5)*40,y:(B.start[1]+.5)*40,angle:-Math.PI/4,hp:100,dead:!1,armour:J.armour,armourHp:J.armour?Wt(J.armour):0,weapons:s.weapons,items:s.items,equip:s.weapons[0]?`primary`:s.weapons[1]?`secondary`:`none`,lastGun:`primary`,itemSlot:-1,fireCd:0,reloadT:0,reloadMax:1,swapT:0,throwCd:0,useT:0,useMax:1,useSlot:-1,sprinting:!1,sprintOut:0,walk:0,recoil:0,flashT:0,autoReload:!1,stepT:0};if(V={charId:o,charPal:p[o].pal,knives:[],slashT:0,campaign:!!i,campaignStage:i?i.stage:0,diff:u[a]||u.normal,player:c,enemies:[],ripples:[],bullets:[],grenades:[],fires:[],smokes:[],particles:[],lights:[],piles:[],toasts:[],floaters:[],dmgInd:[],time:0,kills:0,shots:0,hits:0,lastHitShot:0,nextShot:1,dmgTaken:0,shake:0,hitT:0,hitKill:!1,hurtFlash:0,crossBloom:0,corpses:[],crawlers:[],extractCalled:!1,exfilState:`idle`,exfilT:0,spawnT:0,rotorT:0,reinforcements:0,smokeT:0,minutesCharged:0,penalty:0,cam:{x:c.x,y:c.y},invOpen:!1,invPile:null,over:!1,won:!1,overT:0,endShown:!1,payout:0},!i)for(let e of c.weapons)e&&(e.mag=Lt(e.id),e.reserve=zt(e.id));for(let[e,t,n]of B.enemies)V.enemies.push(bt(e,t,n===`p`));for(let e of B.caches)V.piles.push(xt(e));yt(),Ct(`REACH THE EXTRACTION POINT`,4)}function yt(){let[e,r]=B.start,i=new Uint8Array(t*n),a=[r*t+e],o=[];for(i[a[0]]=1;a.length;){let e=a.pop(),n=e%t,r=e/t|0;o.push([n,r]);for(let[e,o]of We.slice(0,4)){let s=n+e,c=r+o,l=c*t+s;!i[l]&&!Ye(s,c)&&(i[l]=1,a.push(l))}}let s=new Set([...V.enemies.map(e=>Math.floor(e.x/40)+`,`+Math.floor(e.y/40)),...V.piles.map(e=>Math.floor(e.x/40)+`,`+Math.floor(e.y/40))]),c=e=>{for(let t=0;t<300;t++){let[t,n]=o[Math.random()*o.length|0];if(!s.has(t+`,`+n)&&e(t,n))return s.add(t+`,`+n),[t,n]}return null},l=Math.round(B.enemies.length*(B.spawns.extraEnemies||0));for(let t=0;t<l;t++){let t=c((t,n)=>Math.hypot(t-e,n-r)>18);t&&V.enemies.push(bt(t[0],t[1],Math.random()<.6))}for(let t=0;t<(B.spawns.extraCaches||0);t++){let t=c((t,n)=>B.floor[n][t]===`,`&&Math.hypot(t-e,n-r)>8);t&&V.piles.push(xt(t))}}function bt(e,t,n){let i=(e+.5)*40,a=(t+.5)*40,o=y(Ue),s=Math.random()*Math.PI*2;return{x:i,y:a,hx:i,hy:a,angle:s,look:s,lookT:R(1,3),moveAng:s,hp:50,dead:!1,weapon:o,mag:r[o].mag,reloadT:0,fireCd:0,burst:0,state:n?`patrol`:`idle`,patrol:n,path:null,pathT:0,waitT:R(0,3),reactT:0,lastSeen:null,lostT:0,searchPt:null,searchT:0,strafe:0,strafeT:0,stunT:0,hurtT:0,walk:0,recoil:0,sees:!1,suppressT:0,coverT:0,coverTile:-1,rippleT:R(0,2)}}function xt([e,t,n]){let r=[];if(n===`start`)r.push(b(`ammo`),b(`bandage`));else{n===`weapons`&&r.push(C());let e=2+(Math.random()*2|0);for(let t=0;t<e;t++)r.push(Math.random()<.12?C():S())}for(;r.length<6;)r.push(null);return{x:(e+.5)*40,y:(t+.5)*40,kind:`cache`,items:r}}function St(e,t){let n=0;for(let r of e)t(r)&&(e[n++]=r);e.length=n}function Ct(e,t=2.2){V.toasts.push({text:e,t,max:t}),V.toasts.length>4&&V.toasts.shift()}function H(e,t,n,r){for(let i=0;i<n;i++){let n=r.dir===void 0?Math.random()*Math.PI*2:r.dir+R(-r.cone,r.cone),i=R(r.speed[0],r.speed[1]),a=R(r.life[0],r.life[1]);V.particles.push({x:e,y:t,vx:Math.cos(n)*i,vy:Math.sin(n)*i,life:a,max:a,size:R(r.size[0],r.size[1]),grow:r.grow||0,color:r.color,rgb:`rgb(${r.color})`,drag:r.drag||4,clip:!!r.clip,glow:!!r.glow,rise:r.rise||0})}}function wt(e,t,n,r,i,a){V.lights.push({x:e,y:t,r:n,t:r,max:r,color:i,clip:a})}function Tt(e){e(Ke.cx,!1),e(Ke.gx,!0)}let Et=(e,t)=>t?ae(e):e;function Dt(e,t,n){let r=[];for(let i=0;i<9;i++)r.push([e+R(-n,n),t+R(-n,n),R(n*.25,n*.6)]);Tt((e,t)=>{e.globalAlpha=.8,e.fillStyle=Et(`#4f0d0a`,t);for(let[t,n,i]of r)e.beginPath(),e.arc(t,n,i,0,Math.PI*2),e.fill();e.globalAlpha=1})}function Ot(e,t){Tt((n,r)=>{let i=n.createRadialGradient(e,t,5,e,t,75);i.addColorStop(0,r?`rgba(5,5,6,0.85)`:`rgba(10,8,6,0.85)`),i.addColorStop(1,`rgba(0,0,0,0)`),n.fillStyle=i,n.beginPath(),n.arc(e,t,75,0,Math.PI*2),n.fill()})}function kt(e,t){let n=Math.random()*3;Tt((r,i)=>{r.save(),r.translate(e,t),r.rotate(n),r.fillStyle=Et(`#b8923a`,i),r.fillRect(-2.5,-1,5,2),r.restore()})}function At(e,t){Tt(n=>{n.fillStyle=`rgba(15,14,12,0.75)`,n.beginPath(),n.arc(e,t,1.8,0,Math.PI*2),n.fill()})}function jt(e,t,n,r,i,a){a||=Math.random()*1e9|0,Dt(e+Math.cos(n)*4,t+Math.sin(n)*4,20),Tt((o,s)=>de(o,{x:e,y:t,a:n,pal:s?se(r):r,seed:a,k:1,weapon:i}))}function Mt(e,t,n){let r=[];for(let i=0;i<7;i++){let i=3+Math.random()*30,a=n+(Math.random()-.5)*.7;r.push([e+Math.cos(a)*i,t+Math.sin(a)*i,Math.max(.8,3.2-i*.08)*(.6+Math.random()*.6),a])}Tt((e,t)=>{e.fillStyle=Et(`#6a0f0b`,t),e.globalAlpha=.8;for(let[t,n,i,a]of r)e.beginPath(),e.ellipse(t,n,i*1.8,i,a,0,Math.PI*2),e.fill();e.globalAlpha=1})}function Nt(e,t,n){let r=3+Math.random()*3,i=7+Math.random()*5,a=(Math.random()-.5)*6;Tt((o,s)=>{o.fillStyle=Et(`#5a0c09`,s),o.globalAlpha=.5,o.beginPath(),o.ellipse(e-Math.sin(n)*a,t+Math.cos(n)*a,i,r,n,0,Math.PI*2),o.fill(),o.globalAlpha=1})}function Pt(e){return J.levels[e]||0}function Ft(e){return g[e]?1:1+h*Pt(e)}function It(e){return(1+(g[e]||0)*Pt(e))*(V.charId===`sniper`&&e===`barrett`?1.35:1)}function Lt(e){return V.charId===`gunner`&&e===`m249`?r[e].mag+50:V.charId===`sniper`&&e===`barrett`?8:r[e].mag}function Rt(e){return r[e].reload*(V.charId===`gunner`&&e===`m249`?.6:1)}function zt(e){return V.charId===`sniper`&&e===`barrett`?40:r[e].reserve}let Bt=4,Vt=3;function Ht(){return V.charId===`assaulter`}function Ut(e){let t=e[4];t&&o[t.id].kind===`throwable`&&t.uses===void 0&&(t.uses=3)}function Wt(e){return c[e].hp+((J.armourLevels||{})[e]||0)*5}function Gt(e){let t=V.player,n=t.armour&&c[t.armour];if(!n||t.armourHp<=0)return e;let r=Math.min(n.reduce,Math.max(0,e-1),t.armourHp);return t.armourHp-=r,V.armourHitT=.25,t.armourHp<=0&&(t.armourHp=0,Ct(`ARMOUR BROKEN`),P.armourBreak()),e-r}function Kt(){let e=V.player;return e.equip===`primary`?e.weapons[0]:e.equip===`secondary`?e.weapons[1]:null}function qt(){V.player.useT=0}function Jt(e){let t=V.player;if(t.dead)return;if(e===`primary`||e===`secondary`){let n=e===`primary`?0:1;if(!t.weapons[n]){Ct(`NO ${e.toUpperCase()} WEAPON`),P.deny();return}if(t.equip===e)return;qt(),t.reloadT=0,t.autoReload=!1,t.equip=e,t.lastGun=e,t.swapT=.35,P.click();return}let n=[];if(t.items.forEach((t,r)=>{t&&o[t.id].kind===e&&n.push(r)}),!n.length){Ct(e===`throwable`?`NO THROWABLES`:`NO MEDICAL ITEMS`),P.deny();return}let r=n[0];t.equip===e&&(r=n[(n.indexOf(t.itemSlot)+1)%n.length]),qt(),t.reloadT=0,t.autoReload=!1,t.equip=e,t.itemSlot=r,t.swapT=.25,P.click()}function Yt(){let e=V.player;e.equip=e.lastGun===`primary`&&e.weapons[0]?`primary`:e.lastGun===`secondary`&&e.weapons[1]?`secondary`:e.weapons[0]?`primary`:e.weapons[1]?`secondary`:`none`,e.swapT=.3}function Xt(){let e=V.player;if((e.equip===`none`||e.equip===`primary`&&!e.weapons[0]||e.equip===`secondary`&&!e.weapons[1])&&(e.reloadT=0,Yt()),e.equip===`throwable`||e.equip===`medical`){let t=e.items[e.itemSlot];if(!t||o[t.id].kind!==e.equip){let t=e.items.findIndex(t=>t&&o[t.id].kind===e.equip);t>=0?e.itemSlot=t:Yt()}}}function Zt(){let e=V.player,t=Kt();if(!t||e.reloadT>0||e.dead)return;r[t.id];let n=Lt(t.id);if(!(t.mag>=n)){if(t.reserve<=0){let r=e.items.findIndex(e=>e&&e.id===`ammo`);if(r<0){Ct(`NO AMMO - FIND AN AMMO BOX`),P.deny();return}e.items[r]=null,t.reserve+=n*3,Ct(`AMMO BOX OPENED +${n*3}`)}qt(),e.reloadT=e.reloadMax=Rt(t.id),P.reload(t.id,e.reloadT)}}function Qt(){let e=Kt();if(!e)return;r[e.id];let t=Math.min(Lt(e.id)-e.mag,e.reserve);e.mag+=t,e.reserve-=t}function $t(){return{x:(z.mx-I/2)/Ae+V.cam.x,y:(z.my-L/2)/Ae+V.cam.y}}function en(e,t,n,r){let[i,a]=le(r);return{x:e+Math.cos(n)*i-Math.sin(n)*a,y:t+Math.sin(n)*i+Math.cos(n)*a}}function tn(){let e=V.player,t=Kt();if(!t||e.reloadT>0||e.swapT>0||e.fireCd>0||e.sprintOut>0)return;let n=r[t.id];if(!n.auto&&!z.clicked)return;if(t.mag<=0){z.clicked&&(P.click(),Zt());return}t.mag--,e.fireCd=60/(n.rpm*It(t.id));let i=$t(),a=Math.atan2(i.y-e.y,i.x-e.x);e.angle=a;let o=V.nextShot++;for(let r=0;r<n.pellets;r++){let i=n.pellets>1?a+(r/(n.pellets-1)-.5)*2*n.spread:a;sn(e.x,e.y,i,n,`player`,o,n.dmg*Ft(t.id))}V.shots++;let s=en(e.x,e.y,a,t.id);wt(s.x,s.y,170,.06,`255,190,90`,!1),H(s.x,s.y,4,{dir:a,cone:.35,speed:[80,260],life:[.04,.09],size:[2,4],color:`255,210,120`,glow:!0}),H(s.x,s.y,2,{dir:a,cone:.5,speed:[20,60],life:[.3,.6],size:[3,5],grow:14,color:`150,150,150`,drag:3}),kt(e.x+Math.cos(a+1.6)*R(18,32),e.y+Math.sin(a+1.6)*R(18,32)),V.shake=Math.min(14,V.shake+n.kick),V.crossBloom=Math.min(1,V.crossBloom+.35),e.recoil=1,P.shot(t.id,1),En(e.x,e.y,n.snd===`sniper`||n.snd===`shotgun`?1150:850),dt(e.x,e.y,a,n.range),t.mag===0&&(e.autoReload=!0)}function nn(){let e=V.player;if(!z.clicked||e.throwCd>0||e.swapT>0)return;let t=e.items[e.itemSlot];if(!t)return;let n=$t(),r=n.x-e.x,i=n.y-e.y,a=Math.min(Math.hypot(r,i),480),o=Math.atan2(i,r),s=.75;V.grenades.push({x:e.x+Math.cos(o)*14,y:e.y+Math.sin(o)*14,vx:Math.cos(o)*a/s,vy:Math.sin(o)*a/s,z:14,vz:(900*s*s/2-14)/s,grav:900,kind:t.id,fuse:{frag:1.9,flash:1.4,smoke:1.6,molotov:99}[t.id],spin:0}),Ht()&&Ut(e.items),t.uses>1?t.uses--:e.items[e.itemSlot]=null,e.throwCd=.6,P.throwIt(),Xt()}function rn(){let e=V.player;if(!z.clicked||e.useT>0||e.swapT>0)return;let t=e.items[e.itemSlot];t&&(e.hp>=100?(Ct(`HEALTH IS FULL`),P.deny()):(e.useSlot=e.itemSlot,e.useT=e.useMax=o[t.id].use,P.useMed(t.id)))}function an(e,t,n,r){let i=V.player;i.dead||V.over||(i.hp-=e,V.dmgTaken+=e,V.hurtFlash=Math.min(.5,V.hurtFlash+(r?.08:.25)),r||(V.dmgInd.push({a:Math.atan2(n-i.y,t-i.x),t:1.3}),V.shake=Math.min(14,V.shake+3),P.hurt()),i.hp<=0&&(i.hp=0,i.dead=!0,jt(i.x,i.y,i.angle+Math.PI,V.charPal,null),P.death(),on(!1)))}function on(e){if(!V.over&&(V.over=!0,V.won=e,V.overT=e?1.2:2,V.invOpen&&Fr.close(),e)){let e=0;for(let t of V.player.items)t&&o[t.id].kind===`valuable`&&(e+=o[t.id].value);V.valuables=Math.round(e*V.diff.money),V.payout=Math.max(0,V.valuables+Math.round(V.kills*10*V.diff.money)-V.penalty)}}function sn(e,t,n,r,i,a,o){V.bullets.push({x:e,y:t,px:e,py:t,sx:e,sy:t,dx:Math.cos(n),dy:Math.sin(n),speed:r.speed,travel:0,max:r.range,dmg:o,owner:i,shot:a,pierce:!!r.pierce,hitSet:null,dead:!1})}function cn(e){St(V.bullets,e=>!e.dead);for(let t of V.bullets){let n=Math.min(t.speed*e,t.max-t.travel),r=Xe(t.x,t.y,t.dx,t.dy,n,Ve),i=r;if(t.owner===`player`){let e=[];for(let n of V.enemies){if(n.dead||t.hitSet&&t.hitSet.has(n))continue;let r=Qe(t.x,t.y,t.dx,t.dy,i,n.x,n.y,14);r>=0&&e.push([r,n])}for(let n of V.crawlers){if(n.done||t.hitSet&&t.hitSet.has(n))continue;let r=Qe(t.x,t.y,t.dx,t.dy,i,n.x,n.y,13);r>=0&&e.push([r,n])}e.sort((e,t)=>e[0]-t[0]);for(let[n,r]of e){if(r.crawler?gn(t,r,n):ln(t,r,n),!t.pierce){t.dead=!0,i=n;break}(t.hitSet||=new Set).add(r),t.dmg*=.7}}else{let e=V.player;if(!e.dead){let n=Qe(t.x,t.y,t.dx,t.dy,i,e.x,e.y,13);if(n>=0){i=n,t.dead=!0;let r=t.x+t.dx*n,a=t.y+t.dy*n,o=Math.atan2(t.dy,t.dx);e.armour&&e.armourHp>0?(H(r,a,6,{dir:o+Math.PI,cone:1,speed:[60,200],life:[.08,.2],size:[1,2],color:`255,220,150`,glow:!0}),P.armourHit()):(H(r,a,8,{dir:o,cone:.6,speed:[40,180],life:[.2,.45],size:[1.5,3],color:`140,15,12`}),Mt(r,a,o)),an(Gt(t.dmg*V.diff.enemyDmg+V.diff.extraDmg),t.sx,t.sy)}}}if(t.px=t.x,t.py=t.y,t.x+=t.dx*i,t.y+=t.dy*i,t.travel+=i,!t.dead&&r<n){t.dead=!0;let e=Math.atan2(-t.dy,-t.dx);H(t.x,t.y,5,{dir:e,cone:1.1,speed:[60,240],life:[.08,.2],size:[1,2.2],color:`255,200,120`,glow:!0,clip:t.owner!==`player`}),H(t.x,t.y,2,{dir:e,cone:.8,speed:[10,50],life:[.3,.7],size:[2,4],grow:10,color:`120,115,105`,clip:t.owner!==`player`}),At(t.x-t.dx*1.5,t.y-t.dy*1.5)}t.travel>=t.max&&(t.dead=!0)}}function ln(e,t,n){let r=e.x+e.dx*n,i=e.y+e.dy*n;H(r,i,8,{dir:Math.atan2(e.dy,e.dx),cone:.5,speed:[60,220],life:[.2,.5],size:[1.5,3.2],color:`150,16,12`}),Mt(r,i,Math.atan2(e.dy,e.dx)),e.shot!==V.lastHitShot&&(V.hits++,V.lastHitShot=e.shot),un(t,e.dmg)}function un(e,t,n){if(e.dead)return;if(e.hp-=t,e.hurtT=.15,e.hp<=0){dn(e);return}n||(V.hitT=.2,V.hitKill=!1,P.hit());let r=V.player,i={x:r.x,y:r.y};e.state===`alert`?e.lastSeen=i:ut(e,`hit`,()=>{e.lastSeen=i,e.state!==`alert`&&(e.state=`alert`,e.reactT=.3,e.path=null,e.pathT=0),e.look=Math.atan2(i.y-e.y,i.x-e.x)})}function dn(e,t){e.dead=!0,V.kills++,V.hitKill=!0,V.hitT=.3,P.kill(),V.floaters.push({text:`+$${+(10*V.diff.money).toFixed(2)}`,t:1});let n=[x(e.weapon,!0)];for(Math.random()<.6&&n.push(S());n.length<6;)n.push(null);let r=V.player,i={x:e.x,y:e.y,seed:Math.random()*1e9|0,weapon:e.weapon,pal:oe,items:n};t||Math.random()<.25?V.crawlers.push({...i,crawler:!0,a:Math.atan2(e.y-r.y,e.x-r.x),t:30,phase:0,voiceT:.2,trailT:0,voice:R(.85,1.2)}):(V.corpses.push({...i,a:Math.atan2(e.y-r.y,e.x-r.x)+R(-.7,.7),k:0}),V.piles.push({x:e.x,y:e.y,kind:`body`,items:n}))}function fn(){let e=V.player;if(V.charId!==`cutthroat`||e.dead||V.over||V.invOpen||(e.knifeCd||0)>0)return;let t=t=>{let n=Math.hypot(t.x-e.x,t.y-e.y);return n<58&&(n<30||Math.abs(Me(Math.atan2(t.y-e.y,t.x-e.x),e.angle))<1.1)&&Ze(e.x,e.y,t.x,t.y,Ve)},n=V.enemies.find(e=>!e.dead&&t(e))||V.crawlers.find(e=>!e.done&&t(e));if(n){e.knifeCd=.45,V.slashT=.18,P.slash();let t=Math.atan2(n.y-e.y,n.x-e.x);H(n.x,n.y,14,{dir:t,cone:.7,speed:[60,240],life:[.2,.5],size:[1.5,3.4],color:`150,16,12`}),Mt(n.x,n.y,t),pn(n);return}e.knifeCd=.8;let r=$t(),i=Math.atan2(r.y-e.y,r.x-e.x);V.knives.push({x:e.x,y:e.y,dx:Math.cos(i),dy:Math.sin(i),travel:0,spin:0}),P.knifeThrow()}function pn(e){if(V.hitT=.3,V.hitKill=!0,e.crawler)_n(e);else{if(V.player.x!==void 0){let t=V.player;e.lastSeen={x:t.x,y:t.y}}dn(e,!0)}}function mn(e){for(let t of V.knives){let n=Math.min(1100*e,650-t.travel),r=Xe(t.x,t.y,t.dx,t.dy,n,Ve),i=r<n,a=null;for(let e of[V.enemies,V.crawlers])for(let n of e){if(n.dead||n.done)continue;let e=Qe(t.x,t.y,t.dx,t.dy,r,n.x,n.y,15);e>=0&&e<=r&&(r=e,a=n)}if(t.x+=t.dx*r,t.y+=t.dy*r,t.travel+=r,t.spin+=e*30,a)t.dead=!0,H(t.x,t.y,10,{dir:Math.atan2(t.dy,t.dx),cone:.6,speed:[60,200],life:[.2,.5],size:[1.5,3],color:`150,16,12`}),Mt(t.x,t.y,Math.atan2(t.dy,t.dx)),P.hit(),pn(a);else if(i||t.travel>=650){t.dead=!0,i&&P.knifeClink();let e=Math.atan2(t.dy,t.dx)+(i?Math.PI+R(-.5,.5):R(-.4,.4)),n=t.x-t.dx*6,r=t.y-t.dy*6;Tt((t,i)=>{t.save(),t.translate(n,r),t.rotate(e),t.fillStyle=Et(`#2a2018`,i),t.fillRect(-7,-1.5,6,3),t.fillStyle=Et(`#b8bcc0`,i),t.fillRect(-1,-1.2,10,2.4),t.restore()})}}St(V.knives,e=>!e.dead);let t=V.player;t.knifeCd>0&&(t.knifeCd-=e),V.slashT>0&&(V.slashT-=e)}function hn(){for(let e of V.knives)F.save(),F.translate(e.x,e.y),F.rotate(e.spin),F.fillStyle=`#2a2018`,F.fillRect(-7,-1.5,6,3),F.fillStyle=`#d0d4d8`,F.fillRect(-1,-1.3,11,2.6),F.restore();let e=V.player;V.slashT>0&&!e.dead&&(F.strokeStyle=`rgba(235,240,245,${V.slashT/.18*.8})`,F.lineWidth=3,F.lineCap=`round`,F.beginPath(),F.arc(e.x,e.y,40,e.angle-1,e.angle+1),F.stroke())}function gn(e,t,n){let r=e.x+e.dx*n,i=e.y+e.dy*n;H(r,i,8,{dir:Math.atan2(e.dy,e.dx),cone:.5,speed:[60,220],life:[.2,.5],size:[1.5,3.2],color:`150,16,12`}),Mt(r,i,Math.atan2(e.dy,e.dx)),V.hitT=.2,V.hitKill=!1,P.hit(),_n(t)}function _n(e){e.done||(e.done=!0,jt(e.x,e.y,e.a,e.pal,null,e.seed),V.piles.push({x:e.x,y:e.y,kind:`body`,items:e.items}))}function vn(e){let t=V.player;for(let t of V.corpses)t.k=Math.min(1,t.k+e/.4),t.k>=1&&(t.settled=!0,jt(t.x,t.y,t.a,t.pal,t.weapon,t.seed));St(V.corpses,e=>!e.settled);for(let n of V.crawlers){if(n.done)continue;n.t-=e,n.phase+=e*5,n.a=Ne(n.a,Math.atan2(n.y-t.y,n.x-t.x),1.2*e);let r=22*(.25+.75*Math.max(0,Math.sin(n.phase)))*Math.min(1,.35+n.t/15);if(et(n,Math.cos(n.a)*r*e,Math.sin(n.a)*r*e,11),n.trailT-=e,n.trailT<=0&&(n.trailT=.16,Nt(n.x-Math.cos(n.a)*12,n.y-Math.sin(n.a)*12,n.a)),n.voiceT-=e,n.voiceT<=0){n.voiceT=R(1.3,2.6);let e=wn(n.x,n.y);Math.random()<.55?P.groan(e,n.voice):P.scream(e*.8,n.voice*.95,.6)}n.t<=0&&_n(n)}St(V.crawlers,e=>!e.done)}function yn(){for(let e of V.corpses)de(F,{x:e.x,y:e.y,a:e.a,pal:e.pal,seed:e.seed,k:e.k,weapon:e.weapon});for(let e of V.crawlers)de(F,{x:e.x,y:e.y,a:e.a,pal:e.pal,seed:e.seed,crawl:e.phase})}function bn(e){let t=e.theme.style,n=t===`grass`?`grass`:t===`sand`?`sand`:t===`snow`?`snow`:`hard`,r=e.theme.markings===!1?`sand`:`hard`,i=e.floor.map(e=>e.map(e=>e===`=`?r:e===`.`?n:`hard`)),a=([e,t,n,r],a)=>{for(let o=t;o<=r;o++)for(let t=e;t<=n;t++)i[o]&&i[o][t]!==void 0&&(i[o][t]=a)};e.buildings.forEach((e,t)=>a(e.r,[`wood`,`hard`,`hard`,`carpet`][t%4]));for(let t of e.paved||[])a(t,`wood`);return i}function xn(e,t){let n=B.surface[Math.floor(t/40)];return n&&n[Math.floor(e/40)]||`hard`}function Sn(e){let t=e.lx===void 0?0:Math.hypot(e.x-e.lx,e.y-e.ly);return e.lx=e.x,e.ly=e.y,t>40||(e.stepDist=(e.stepDist||0)+t,e.stepDist<(e.sprinting?56:42))?!1:(e.stepDist=0,!0)}function Cn(){let e=V.player;!e.dead&&Sn(e)&&P.step(xn(e.x,e.y),(e.sprinting?.5:.3)*(V.charId===`assaulter`?.3:1));let t=3;for(let e of V.enemies){if(e.dead||!Sn(e)||t<=0)continue;let n=Tn(e.x,e.y,750,.45);n>.02&&(P.step(xn(e.x,e.y),n),t--)}}function wn(e,t){let n=V.player,r=je(1-Math.hypot(n.x-e,n.y-t)/1100,0,1);return r*r}function Tn(e,t,n,r,i=0){let a=V.player;return je((1-Math.hypot(a.x-e,a.y-t)/n)*r,i,r)}function En(e,t,n){n*=.6;let r=V.player;for(let i of V.enemies){if(i.dead||i.state===`alert`||Math.hypot(i.x-e,i.y-t)>n)continue;let a={x:r.x+R(-80,80),y:r.y+R(-80,80)};ut(i,`noise`,()=>{i.state!==`alert`&&(i.state=`search`,i.searchPt=a,i.searchT=8,i.path=null,i.look=Math.atan2(t-i.y,e-i.x))})}}function Dn(e,t,n,r){if(!e.path||!e.path.length)return!1;let i=e.path[0],a=i.x-e.x,o=i.y-e.y,s=Math.hypot(a,o);if(s<(r&&e.path.length===1?1.5:8))return e.path.shift(),e.path.length>0;let c=Math.min(s,t*n);return et(e,a/s*c,o/s*c,13),e.moveAng=Math.atan2(o,a),e.walk+=c*.08,!0}function On(e){if(e.fireCd>0||e.reloadT>0)return;let t=r[e.weapon];if(e.mag<=0){e.reloadT=2.4,P.reload(e.weapon,2.4,Tn(e.x,e.y,900,.6));return}e.burst<=0&&(e.burst=t.auto?2+(Math.random()*3|0):1),e.mag--,e.burst--;for(let n=0;n<t.pellets;n++){let n=e.angle+(Math.random()-.5)*(e.suppressT>0?Le:Ie);sn(e.x,e.y,n,t,`enemy`,0,t.dmg*.42)}e.fireCd=(e.burst>0?60/t.rpm*3:R(1.5,2.6)+ +!t.auto)*V.diff.fireDelay,e.recoil=1;let n=en(e.x,e.y,e.angle,e.weapon);wt(n.x,n.y,150,.06,`255,190,90`,!0),H(n.x,n.y,3,{dir:e.angle,cone:.35,speed:[80,240],life:[.04,.08],size:[2,4],color:`255,210,120`,glow:!0,clip:!0}),V.player,P.shot(e.weapon,Tn(e.x,e.y,1700,.8,.08))}function kn(e){let t=V.player;for(let n of V.enemies)n===e||n.dead||n.state===`alert`||Math.hypot(n.x-e.x,n.y-e.y)>300||(n.state=`search`,n.searchPt={x:t.x,y:t.y},n.searchT=8,n.path=null)}function An(e,t){if(e.pending)for(let n in e.pending){let r=e.pending[n];r.t-=t,r.t<=0&&(delete e.pending[n],r.fn())}let n=V.player;e.fireCd-=t,e.stunT-=t,e.hurtT-=t,e.recoil=Math.max(0,e.recoil-t*6),e.reloadT>0&&(e.reloadT-=t,e.reloadT<=0&&(e.mag=r[e.weapon].mag));let i=n.x-e.x,a=n.y-e.y,o=Math.hypot(i,a)||1,s=Math.atan2(a,i),c=!1;if(!n.dead&&e.stunT<=0&&nt(e.x,e.y)&&o<(e.state===`alert`?1e3:e.state===`search`?800:650)){let t=e.state===`alert`?1.5:e.state===`search`?1.1:.9,r=o<(n.sprinting&&V.charId!==`assaulter`?160:90);(Math.abs(Me(s,e.angle))<t||r)&&at(e.x,e.y,i/o,a/o,o)>=o-2&&(c=!0)}e.sees=c,c&&(e.state!==`alert`&&(e.state=`alert`,e.reactT=R(.35,.7),e.path=null,kn(e)),e.lastSeen={x:n.x,y:n.y},e.lostT=0);let l=e.stunT>0?35:120;if(e.suppressT>0&&(e.suppressT-=t,e.stunT<=0)){e.coverT-=t,e.coverT<=0&&(e.coverTile=-1,e.path=lt(e,n.x,n.y),e.coverT=.8);let r=Dn(e,150,t,!0);c?e.angle=Ne(e.angle,s,4.5*t):r&&(e.angle=Ne(e.angle,e.moveAng,5*t)),e.reactT>0?e.reactT-=t:c&&Math.abs(Me(s,e.angle))<.3&&Xe(e.x,e.y,i/o,a/o,o,Ve)>=o-2&&On(e),e.suppressT<=0&&(e.path=null,e.pathT=0,e.coverTile=-1)}else switch(e.state){case`idle`:e.lookT-=t,e.lookT<=0&&(e.look=e.angle+R(-1.6,1.6),e.lookT=R(1.5,4)),e.angle=Ne(e.angle,e.look,1.4*t);break;case`patrol`:if(e.path&&e.path.length)Dn(e,70,t),e.angle=Ne(e.angle,e.moveAng,3*t);else if(e.waitT-=t,e.lookT-=t,e.lookT<=0&&(e.look=e.angle+R(-1.4,1.4),e.lookT=R(1,2.5)),e.angle=Ne(e.angle,e.look,1.4*t),e.waitT<=0){let t=pt(e.hx,e.hy,7);t&&(e.path=ft(e.x,e.y,t.x,t.y)),e.waitT=R(2,5)}break;case`search`:e.searchT-=t,!e.path&&e.searchPt&&(e.path=ft(e.x,e.y,e.searchPt.x,e.searchPt.y)||[],e.searchPt=null),e.path&&e.path.length?(Dn(e,105,t),e.angle=Ne(e.angle,e.moveAng,3.5*t)):(e.lookT-=t,e.lookT<=0&&(e.look=e.angle+R(-2,2),e.lookT=R(.8,1.6)),e.angle=Ne(e.angle,e.look,2.5*t)),e.searchT<=0&&(e.state=e.patrol?`patrol`:`idle`,e.hx=e.x,e.hy=e.y,e.path=null);break;case`alert`:if(e.stunT>0){e.angle+=t*2.5*Math.sin(V.time*4+e.x);break}if(e.pathT-=t,c){e.angle=Ne(e.angle,s,4.5*t);let c=r[e.weapon],u=Xe(e.x,e.y,i/o,a/o,o,Ve)>=o-2,d=Math.min(c.range*.7,420);if(!u||o>d)(e.pathT<=0||!e.path)&&(e.path=ft(e.x,e.y,n.x,n.y),e.pathT=.6),e.path&&Dn(e,l*.9,t);else if(e.path=null,e.strafeT-=t,e.strafeT<=0&&(e.strafe=Math.random()<.3?0:Math.random()<.5?-1:1,e.strafeT=R(.6,1.6)),e.strafe){let n=s+Math.PI/2*e.strafe;et(e,Math.cos(n)*55*t,Math.sin(n)*55*t,13),e.walk+=55*t*.08}e.reactT>0?e.reactT-=t:u&&Math.abs(Me(s,e.angle))<.18&&o<c.range*.95&&On(e)}else e.lostT+=t,(!e.path||e.pathT<=0)&&(e.path=e.lastSeen?ft(e.x,e.y,e.lastSeen.x,e.lastSeen.y):null,e.pathT=1),e.path&&e.path.length?(Dn(e,l,t),e.angle=Ne(e.angle,e.moveAng,4*t)):e.angle=Ne(e.angle,e.look,3*t),(e.lostT>5||(!e.path||!e.path.length)&&e.lostT>1.5)&&(e.state=`search`,e.searchT=7,e.path=[])}}function jn(){let e=V.enemies,t=V.player;for(let n=0;n<e.length;n++){let r=e[n];if(!r.dead){for(let t=n+1;t<e.length;t++){let n=e[t];if(n.dead)continue;let i=n.x-r.x,a=n.y-r.y,o=Math.hypot(i,a);if(o>.01&&o<26){let e=(26-o)/2;et(r,-i/o*e,-a/o*e,13),et(n,i/o*e,a/o*e,13)}}if(!t.dead){let e=r.x-t.x,n=r.y-t.y,i=Math.hypot(e,n);i>.01&&i<26&&et(r,e/i*(26-i),n/i*(26-i),13)}}}}function Mn(e){for(let t of V.grenades){if(t.fuse-=e,t.spin+=Math.hypot(t.vx,t.vy)*e*.05,t.z>0||t.vz>0)t.vz-=t.grav*e,t.z+=t.vz*e,t.z<=0&&(t.z=0,t.hit=!0,Math.abs(t.vz)>120?(t.vz=-t.vz*.3,P.bounce()):t.vz=0,t.vx*=.6,t.vy*=.6);else{let n=.04**e;t.vx*=n,t.vy*=n}let n=t.z>16?Be:Ve,r=t.x+t.vx*e;n.has(Je(Math.floor((r+Math.sign(t.vx)*4)/40),Math.floor(t.y/40)))?(t.vx*=-.45,t.hit=!0,P.bounce()):t.x=r;let i=t.y+t.vy*e;n.has(Je(Math.floor(t.x/40),Math.floor((i+Math.sign(t.vy)*4)/40)))?(t.vy*=-.45,t.hit=!0,P.bounce()):t.y=i,(t.fuse<=0||t.kind===`molotov`&&t.hit)&&(t.dead=!0,Bn(t))}St(V.grenades,e=>!e.dead)}function Nn(e,t){V.fires.push({x:e,y:t,t:5,tick:0}),Ot(e,t),H(e,t,18,{speed:[60,260],life:[.2,.5],size:[3,7],color:`255,150,40`,glow:!0,drag:5}),wt(e,t,320,.3,`255,140,40`,!1);let n=V.player;P.ignite(je(1.2-Math.hypot(n.x-e,n.y-t)/1500,.15,1)),En(e,t,500)}let Pn=new Map;function Fn(e,t,n){let r=Pn.get(e);if(!r){r=k(t,t);let i=r.getContext(`2d`),a=t/2,o=i.createRadialGradient(a,a,a*n[0],a,a,a);for(let e=1;e<n.length;e+=2)o.addColorStop(n[e],n[e+1]);i.fillStyle=o,i.fillRect(0,0,t,t),Pn.set(e,r)}return r}function In(e){return Fn(e,96,[.2,0,`rgba(${e},${e+2},${e-4},0.9)`,1,`rgba(${e},${e+2},${e-4},0)`])}let Ln=()=>Fn(`core`,256,[0,0,`rgba(165,167,162,0.95)`,.8,`rgba(165,167,162,0.85)`,1,`rgba(165,167,162,0)`]);function Rn(e,t){let n=[];for(let e=0;e<16;e++){let e=Math.random()*Math.PI*2,t=Math.sqrt(Math.random())*.75;n.push({ox:Math.cos(e)*t,oy:Math.sin(e)*t,s:R(.35,.6),spin:R(-.3,.3),shade:R(150,190)|0})}V.smokes.push({x:e,y:t,t:12,puffs:n});let r=V.player;P.smoke(je(1.2-Math.hypot(r.x-e,r.y-t)/1500,.15,1))}function zn(e){let t=V.player;for(let n of V.fires){if(n.t-=e,n.tick-=e,n.tick<=0){n.tick+=.25;let e=3.75;for(let t of V.enemies)!t.dead&&Math.hypot(t.x-n.x,t.y-n.y)<91.5&&un(t,e,!0);!t.dead&&Math.hypot(t.x-n.x,t.y-n.y)<91.5&&an(e,n.x,n.y,!0)}if(Math.random()<e*40){let e=Math.random()*Math.PI*2,t=Math.sqrt(Math.random())*85;H(n.x+Math.cos(e)*t,n.y+Math.sin(e)*t,1,{speed:[5,30],life:[.3,.7],size:[3,7],grow:-4,color:Math.random()<.5?`255,140,30`:`255,200,70`,glow:!0,drag:2,rise:30})}Math.random()<e*6&&H(n.x+R(-85,85)*.6,n.y+R(-85,85)*.6,1,{speed:[5,20],life:[1.2,2],size:[6,10],grow:14,color:`40,36,32`,drag:1,rise:25})}St(V.fires,e=>e.t>0);let n=(e,t)=>V.fires.some(n=>Math.hypot(e.x-n.x,e.y-n.y)<85+t*.5),r=(t,r,i,a)=>{if(n(t,r))t.burnT=3,t.burnTick=.25,t.burnAcc=0;else if(t.burnT>0){let n=Math.min(e,t.burnT);t.burnT-=n,t.burnAcc+=n,t.burnTick-=e,(t.burnTick<=0||t.burnT<=0)&&(i(10*t.burnAcc),t.burnAcc=0,t.burnTick+=.25)}t.burnT>0&&Math.random()<e*30&&H(t.x+R(-8,8),t.y+R(-8,8),1,{speed:[5,25],life:[.25,.5],size:[3,6],grow:-5,color:Math.random()<.5?`255,140,30`:`255,200,70`,glow:!0,drag:2,rise:35,clip:a})};for(let t of V.enemies)t.dead||(r(t,13,e=>un(t,e,!0),!0),t.burnT>0&&!t.dead?(t.screamT=(t.screamT||0)-e,t.screamT<=0&&(t.screamT=R(.8,1.2),P.scream(wn(t.x,t.y),t.voice||=R(.85,1.2)))):t.screamT=0);t.dead||r(t,13,e=>an(e,t.x,t.y,!0),!1);for(let t of V.enemies)if(!t.dead)for(let n of V.fires){let r=t.x-n.x,i=t.y-n.y,a=Math.hypot(r,i)||1;a<98&&et(t,r/a*110*e,i/a*110*e,13)}for(let t of V.smokes)t.t-=e;St(V.smokes,e=>e.t>0)}function Bn(e){if(e.kind===`molotov`){Nn(e.x,e.y);return}if(e.kind===`smoke`){Rn(e.x,e.y);return}let t=V.player,n=Math.hypot(t.x-e.x,t.y-e.y);if(e.kind===`frag`){for(let t of V.enemies){if(t.dead)continue;let n=Math.hypot(t.x-e.x,t.y-e.y);n<210&&Ze(e.x,e.y,t.x,t.y,Be)&&un(t,170*(1-n/210)+10)}for(let t of V.crawlers)!t.done&&Math.hypot(t.x-e.x,t.y-e.y)<210&&_n(t);n<210&&Ze(e.x,e.y,t.x,t.y,Be)&&an(150*(1-n/210),e.x,e.y),n<210&&!t.dead&&P.ring(5,2),H(e.x,e.y,30,{speed:[100,520],life:[.15,.45],size:[2,5],color:`255,170,60`,glow:!0,drag:5}),H(e.x,e.y,22,{speed:[20,160],life:[.8,1.8],size:[8,16],grow:30,color:`70,66,60`,drag:2.5,rise:10}),H(e.x,e.y,16,{speed:[80,300],life:[.4,.9],size:[1.5,3],color:`40,36,30`,drag:3}),wt(e.x,e.y,420,.3,`255,160,60`,!1),Ot(e.x,e.y),V.shake=Math.min(22,V.shake+je(18-n/60,3,18)),P.explosion(je(1.2-n/1500,.15,1)),En(e.x,e.y,1300)}else{for(let n of V.enemies){if(n.dead)continue;let r=Math.hypot(n.x-e.x,n.y-e.y);r<420&&Ze(e.x,e.y,n.x,n.y,Be)&&(n.stunT=4.2*(1-r/420*.5),n.state=`alert`,n.lastSeen={x:t.x,y:t.y},n.reactT=.6,n.path=null)}if(n<420&&Ze(e.x,e.y,t.x,t.y,Be)){let r=Math.abs(Me(Math.atan2(e.y-t.y,e.x-t.x),t.angle))<1.3;t.flashT=Math.max(t.flashT,(r?3.2:1)*(1-n/420*.6))}H(e.x,e.y,24,{speed:[100,420],life:[.1,.3],size:[2,4],color:`255,255,240`,glow:!0,drag:6}),H(e.x,e.y,10,{speed:[20,90],life:[.8,1.6],size:[6,10],grow:22,color:`200,200,200`,drag:2.5}),wt(e.x,e.y,600,.35,`255,255,255`,!1),P.flashbang(je(1.2-n/1500,.15,1)),n<420&&!t.dead&&P.ring(5,2),En(e.x,e.y,900)}}function Vn(e){let t=V.player,n=null,r=e;for(let e of V.piles){if(!e.items.some(Boolean)&&e.kind!==`cache`)continue;let i=Math.hypot(e.x-t.x,e.y-t.y);i<r&&(r=i,n=e)}return n}function Hn(){V.over||V.player.dead||(V.exfilState===`idle`&&Kn()?qn():V.exfilState===`landed`&&Kn(40)?(P.extract(),on(!0)):Un())}function Un(){if(V.over||V.player.dead)return;let e=Vn(70);Fr.open(e||{x:V.player.x,y:V.player.y,kind:`ground`,items:[,,,,,,].fill(null),virtual:!0})}function Wn(e){let t=V.player;if(t.fireCd-=e,t.swapT-=e,t.throwCd-=e,t.sprintOut-=e,t.flashT=Math.max(0,t.flashT-e),t.recoil=Math.max(0,t.recoil-e*8),t.dead||V.over)return;if(!V.invOpen){let e=$t();t.angle=Math.atan2(e.y-t.y,e.x-t.x)}let n=0,i=0;Ge(`KeyW`)&&--i,Ge(`KeyS`)&&(i+=1),Ge(`KeyA`)&&--n,Ge(`KeyD`)&&(n+=1);let a=n!==0||i!==0;t.sprinting=a&&(Ge(`ShiftLeft`)||Ge(`ShiftRight`))&&t.useT<=0,t.sprinting&&(t.sprintOut=.15);let s=Kt(),c=205*(s?r[s.id].mobility:1.05)*(t.sprinting?1.6:1)*(t.useT>0?.55:1)*(V.charId===`hauler`?.25:1);if(a){let r=Math.hypot(n,i);et(t,n/r*c*e,i/r*c*e,13),t.walk+=c*e*.06,t.sprinting&&(t.stepT-=e,t.stepT<=0&&(t.stepT=.4,En(t.x,t.y,V.charId===`assaulter`?80:230)))}if(t.reloadT>0&&(t.reloadT-=e,t.reloadT<=0&&(t.reloadT=0,Qt())),t.autoReload&&t.fireCd<=0&&t.reloadT<=0){t.autoReload=!1;let e=Kt();e&&e.mag===0&&(e.reserve>0||t.items.some(e=>e&&e.id===`ammo`))&&Zt()}if(t.useT>0&&(t.useT-=e,t.useT<=0)){t.useT=0;let e=t.items[t.useSlot];if(e&&o[e.id].kind===`medical`){let n=o[e.id].heal;t.hp=Math.min(100,t.hp+n),t.items[t.useSlot]=null,P.heal(),Ct(`+${n} HEALTH`),Xt()}}!V.invOpen&&(z.mdown||z.clicked)&&(t.equip===`primary`||t.equip===`secondary`?tn():t.equip===`throwable`?nn():t.equip===`medical`&&rn())}function Gn(){return{x:(B.exfil[0]+.5)*40,y:(B.exfil[1]+.5)*40}}function Kn(e=0){let t=Gn(),n=V.player;return Math.hypot(n.x-t.x,n.y-t.y)<110+e}function qn(){V.exfilState=`calling`,V.extractCalled=!0,V.exfilT=V.diff.extractTime,V.spawnT=3,P.radio(),Ct(`EXTRACTION CALLED - HELICOPTER INBOUND IN ${Jn(V.exfilT)}`,4),Ct(`ENEMY REINFORCEMENTS INCOMING`,4)}function Jn(e){return e=Math.max(0,Math.ceil(e)),`${Math.floor(e/60)}:${String(e%60).padStart(2,`0`)}`}function Yn(){let e=V.player;if(V.enemies.filter(e=>!e.dead&&e.reinforcement).length>=25)return!1;for(let t=0;t<60;t++){let t=Math.random()*Math.PI*2,n=R(14,26)*40,r=Math.floor((e.x+Math.cos(t)*n)/40),i=Math.floor((e.y+Math.sin(t)*n)/40);if(Ye(r,i))continue;let a=(r+.5)*40,o=(i+.5)*40;if(ot(a,o)||!ft(a,o,e.x,e.y))continue;let s=bt(r,i,!1);return s.reinforcement=!0,s.state=`search`,s.searchPt={x:e.x+R(-60,60),y:e.y+R(-60,60)},s.searchT=40,s.path=null,V.enemies.push(s),V.reinforcements++,!0}return!1}function Xn(e){if(V.over||V.exfilState===`idle`)return;let t=V.player,n=Gn();if(V.spawnT-=e,V.spawnT<=0){V.spawnT+=3,Yn();for(let e of V.enemies)e.reinforcement&&!e.dead&&e.state!==`alert`&&!e.path&&(e.state=`search`,e.searchPt={x:t.x,y:t.y},e.searchT=40)}V.exfilT-=e,V.exfilState===`calling`&&V.exfilT<=0?(V.exfilState=`landed`,V.exfilT=60,P.radio()):V.exfilState===`landed`&&V.exfilT<=0?(V.exfilState=`leaving`,V.exfilT=6,Ct(`YOU MISSED THE HELICOPTER - CALL IT AGAIN AT THE PAD`,5)):V.exfilState===`leaving`&&V.exfilT<=0&&(V.exfilState=`idle`);let r=Zn();r&&(V.rotorT-=e,V.rotorT<=0&&(V.rotorT=.11,P.rotor(je(1.1-Math.hypot(t.x-r.x,t.y-r.y)/1600,0,.8)*(r.alt>1.3?.6:1))),r.alt<1.25&&Math.random()<e*25&&H(n.x+R(-120,120),n.y+R(-120,120),1,{dir:Math.random()*6.3,cone:0,speed:[60,160],life:[.4,.9],size:[4,9],grow:16,color:`150,140,120`,drag:2}))}function Zn(){let e=Gn(),t={x:e.x-1500,y:e.y+900};if(V.exfilState===`calling`&&V.exfilT<=6){let n=1-V.exfilT/6,r=1-(1-n)*(1-n);return{x:t.x+(e.x-t.x)*r,y:t.y+(e.y-t.y)*r,alt:1+(1-r)*.9}}if(V.exfilState===`landed`)return{x:e.x,y:e.y,alt:1};if(V.exfilState===`leaving`){let t=1-V.exfilT/6,n=t*t;return{x:e.x+(e.x+1500-e.x)*n,y:e.y-900*n,alt:1+n*.9}}return null}function Qn(e){let t=V.time*28,n=-.55,r=(e.alt-1)*160;F.save(),F.translate(e.x+10+r,e.y+14+r*.6),F.rotate(n),F.fillStyle=`rgba(0,0,0,0.3)`,N(F,-52,-18,84,36,16),F.fill(),F.fillRect(-115,-5,64,10),F.restore(),F.save(),F.translate(e.x,e.y),F.scale(e.alt,e.alt),F.rotate(n),F.strokeStyle=`#1c1d1a`,F.lineWidth=3,F.lineCap=`round`,M(F,-40,-22,28,-22),M(F,-40,22,28,22),F.fillStyle=`#343c2c`,F.fillRect(-118,-4,70,8),F.fillStyle=`#2c3326`,F.fillRect(-122,-14,10,28),F.save(),F.translate(-117,15),F.rotate(t*1.6),F.fillStyle=`rgba(20,20,20,0.8)`,F.fillRect(-12,-1.5,24,3),F.restore();let i=F.createLinearGradient(0,-18,0,18);i.addColorStop(0,`#56614a`),i.addColorStop(1,`#2f3628`),F.fillStyle=i,N(F,-54,-18,86,36,17),F.fill(),F.strokeStyle=`rgba(0,0,0,0.5)`,F.lineWidth=1.5,N(F,-54,-18,86,36,17),F.stroke(),F.fillStyle=`rgba(0,0,0,0.25)`,F.fillRect(-30,-17,2,34),F.fillRect(-6,-17,2,34),F.fillStyle=`#20251c`,F.fillRect(-28,-16,20,3),F.fillRect(-28,13,20,3);let a=F.createLinearGradient(14,-14,34,14);a.addColorStop(0,`#8fb0c4`),a.addColorStop(1,`#34505f`),F.fillStyle=a,F.beginPath(),F.ellipse(20,0,13,13,0,-Math.PI/2,Math.PI/2),F.lineTo(14,13),F.lineTo(14,-13),F.closePath(),F.fill(),F.fillStyle=`rgba(255,255,255,0.35)`,F.fillRect(20,-9,6,2),F.fillStyle=`#e8e6df`,F.font=`bold 9px Arial`,F.textAlign=`center`,F.textBaseline=`middle`,F.fillText(`B-07`,-42,0),F.fillStyle=`rgba(20,20,20,0.12)`,F.beginPath(),F.arc(-10,0,108,0,Math.PI*2),F.fill(),F.save(),F.translate(-10,0),F.rotate(t),F.fillStyle=`rgba(18,18,18,0.85)`;for(let e=0;e<4;e++)F.rotate(Math.PI/2),F.fillRect(4,-3.5,104,7);F.restore(),j(F,-10,0,7,7,`#2a2d26`),j(F,-11,-1,3,3,`#5a5f52`),Math.sin(V.time*6)>0&&(j(F,-120,0,3,3,`#ff4030`),j(F,30,-16,2.5,2.5,`#5aff6a`)),F.restore()}function $n(e){for(let t of V.particles){t.life-=e;let n=Math.exp(-t.drag*e);t.vx*=n,t.vy*=n,t.x+=t.vx*e,t.y+=t.vy*e-t.rise*e,t.size+=t.grow*e}St(V.particles,e=>e.life>0);for(let t of V.lights)t.t-=e;St(V.lights,e=>e.t>0)}function er(e){V.time+=V.over?0:e,!V.over&&!V.campaign&&!V.extractCalled&&Math.floor(V.time/60)>V.minutesCharged&&(V.minutesCharged++,V.penalty+=50,Ct(`${V.minutesCharged} MIN WITHOUT EXTRACTING -$50`,3),P.deny()),Wn(e);for(let t of V.enemies)t.dead||An(t,e);vn(e),Cn(),jn();for(let t of V.enemies)t.dead||(t.rippleT-=e,t.rippleT<=0&&(t.rippleT=R(1.3,2.1),ot(t.x,t.y)||V.ripples.push({x:t.x,y:t.y,t:0})));for(let t of V.ripples)t.t+=e;St(V.ripples,e=>e.t<tt),cn(e),Mn(e),mn(e),zn(e),Xn(e),$n(e),V.smokeT-=e,Zn()&&(V.smokeT=1),V.smokeT<=0&&(V.smokeT=.08,H((B.exfil[0]+.5)*40+40,(B.exfil[1]+.5)*40+40,1,{dir:-1.9,cone:.5,speed:[10,40],life:[2.5,4],size:[8,12],grow:18,color:`90,200,90`,drag:.6,rise:18}));for(let t of V.toasts)t.t-=e;St(V.toasts,e=>e.t>0);for(let t of V.floaters)t.t-=e;St(V.floaters,e=>e.t>0);for(let t of V.dmgInd)t.t-=e;if(St(V.dmgInd,e=>e.t>0),V.hitT-=e,V.armourHitT=Math.max(0,(V.armourHitT||0)-e),V.hurtFlash=Math.max(0,V.hurtFlash-e),V.crossBloom=Math.max(0,V.crossBloom-e*3),V.shake*=Math.exp(-10*e),V.invOpen&&V.invPile&&!V.invPile.virtual){let e=V.player;Math.hypot(V.invPile.x-e.x,V.invPile.y-e.y)>100&&Fr.close()}let t=V.player,n=V.invOpen||t.dead?{x:0,y:0}:{x:(z.mx-I/2)/Ae*.3,y:(z.my-L/2)/Ae*.3},r=1-Math.exp(-7*e);V.cam.x+=(t.x+n.x-V.cam.x)*r,V.cam.y+=(t.y+n.y-V.cam.y)*r,V.over&&!V.endShown&&(V.overT-=e,V.overT<=0&&(V.endShown=!0,$.showEnd()))}function tr(e,t,n){let r=[],i=(n,i)=>{let a=Math.cos(n),o=Math.sin(n),s=Xe(e,t,a,o,i,Be);s<i&&(s+=10),s=it(e,t,a,o,s),r.push([e+a*s,t+o*s])};for(let e=0;e<=150;e++)i(n-Pe/2+Pe*e/150,Fe);let a=Math.PI*2-Pe;for(let e=1;e<60;e++)i(n+Pe/2+a*e/60,75);return r.cone=150,r}function nr(e){for(let t of V.piles){let n=t.items.some(Boolean);if(t.kind===`cache`){F.save(),F.translate(t.x,t.y);let r=(t,n)=>e?n:t;F.fillStyle=`rgba(0,0,0,0.35)`,F.fillRect(-14,-8,34,22),F.fillStyle=r(`#4a5a35`,`#3b3d3a`),F.fillRect(-17,-11,34,22),F.fillStyle=r(`#5a6b42`,`#474946`),F.fillRect(-17,-11,34,3),F.fillStyle=`rgba(0,0,0,0.3)`,F.fillRect(-17,9,34,2),F.fillStyle=r(`#2a3220`,`#2a2c2a`),F.fillRect(-20,-4,3,8),F.fillRect(17,-4,3,8),n?(F.fillStyle=r(`#38452a`,`#2c2e2c`),F.fillRect(-17,-11,34,7),F.fillStyle=r(`#8a8d84`,`#5e5f5c`),F.fillRect(-12,-5,4,3),F.fillRect(8,-5,4,3),F.fillStyle=r(`#d6b23a`,`#6b6b66`),F.font=`bold 7px Arial`,F.textAlign=`center`,F.textBaseline=`middle`,F.fillText(`SUPPLY`,0,4)):(F.fillStyle=`#141612`,F.fillRect(-14,-8,28,16),F.fillStyle=r(`#38452a`,`#2c2e2c`),F.save(),F.translate(-17,-11),F.rotate(-.35),F.fillRect(0,-7,34,6),F.restore()),F.restore()}else n&&t.kind!==`body`&&(j(F,t.x+2,t.y+3,12,9,`rgba(0,0,0,0.3)`),j(F,t.x,t.y,12,9,e?`#3f403d`:`#4b4a3a`),F.fillStyle=e?`#2f302d`:`#35342a`,F.fillRect(t.x-2,t.y-9,4,18),j(F,t.x-4,t.y-3,4,3,e?`#55554f`:`#6d6a50`));if(!e&&n){let e=.35+Math.sin(V.time*4)*.2;F.strokeStyle=`rgba(232,197,71,${e})`,F.lineWidth=1.5,F.beginPath(),F.arc(t.x,t.y,20,0,Math.PI*2),F.stroke()}}}function rr(e){F.globalCompositeOperation=`lighter`;for(let t of V.lights){if(t.clip!==e)continue;let n=je(t.t/t.max,0,1)*.55,r=F.createRadialGradient(t.x,t.y,0,t.x,t.y,t.r);r.addColorStop(0,`rgba(${t.color},${n})`),r.addColorStop(1,`rgba(${t.color},0)`),F.fillStyle=r,F.fillRect(t.x-t.r,t.y-t.r,t.r*2,t.r*2)}F.globalCompositeOperation=`source-over`}function ir(e){for(let t of V.particles){if(t.clip!==e)continue;let n=je(t.life/t.max,0,1);F.fillStyle=t.rgb,F.globalAlpha=t.glow?n:n*.7,F.beginPath(),F.arc(t.x,t.y,t.size,0,Math.PI*2),F.fill()}F.globalAlpha=1}let ar={player:[`rgba(255,230,150,0)`,`rgba(255,230,150,0.95)`],enemy:[`rgba(255,140,90,0)`,`rgba(255,140,90,0.95)`]};function or(e){let[t,n]=e===`player`?ar.player:ar.enemy;F.lineCap=`round`;for(let r of V.bullets){if(r.owner!==e)continue;let i=Math.min(r.travel,70),a=r.x-r.dx*i,o=r.y-r.dy*i,s=F.createLinearGradient(a,o,r.x,r.y);s.addColorStop(0,t),s.addColorStop(1,n),F.strokeStyle=s,F.lineWidth=2,F.beginPath(),F.moveTo(a,o),F.lineTo(r.x,r.y),F.stroke()}}function sr(){if(F.setTransform(1,0,0,1,0,0),F.fillStyle=`#0b0c0d`,F.fillRect(0,0,Oe.width,Oe.height),!V)return;let e=V.player,t=Ae,n=(Math.random()-.5)*V.shake,r=(Math.random()-.5)*V.shake,i=I/2-V.cam.x*t+n,a=L/2-V.cam.y*t+r;F.setTransform(ke*t,0,0,ke*t,ke*i,ke*a),F.drawImage(Ke.gray,0,0),nr(!0);let o=tr(e.x,e.y,e.angle);F.save(),F.beginPath(),F.moveTo(o[0][0],o[0][1]);for(let e=1;e<o.length;e++)F.lineTo(o[e][0],o[e][1]);F.closePath(),F.clip(),F.drawImage(Ke.color,0,0),nr(!1);let s=F.createRadialGradient(e.x,e.y,80,e.x,e.y,Fe);s.addColorStop(0,`rgba(0,0,0,0)`),s.addColorStop(1,`rgba(0,0,0,0.5)`),F.fillStyle=s,F.fillRect(e.x-Fe,e.y-Fe,Fe*2,Fe*2);let c=I/2/t+60,l=L/2/t+60;F.font=`bold 16px ${He}`,F.textAlign=`center`;for(let e of V.enemies)e.dead||Math.abs(e.x-V.cam.x)>c||Math.abs(e.y-V.cam.y)>l||(ue(F,{x:e.x,y:e.y,a:e.angle,pal:oe,weapon:e.weapon,hold:`gun`,walk:e.walk,recoil:e.recoil,hurt:e.hurtT}),(e.stunT>0||e.state===`alert`||e.state===`search`)&&(F.fillStyle=e.stunT>0?`#e8e6df`:e.state===`alert`?`#e0402f`:`#e8c547`,F.fillText(e.stunT>0?`~`:e.state===`alert`?`!`:`?`,e.x,e.y-22)));yn(),or(`enemy`),ir(!0),rr(!0),F.restore();for(let e of V.fires){let t=Math.min(1,e.t/.6,(5-e.t)/.2);F.globalCompositeOperation=`lighter`;let n=.85+Math.random()*.15,r=F.createRadialGradient(e.x,e.y,4,e.x,e.y,106.25);r.addColorStop(0,`rgba(255,170,60,${.55*t*n})`),r.addColorStop(.65,`rgba(230,80,20,${.35*t*n})`),r.addColorStop(1,`rgba(200,40,10,0)`),F.fillStyle=r,F.beginPath(),F.arc(e.x,e.y,106.25,0,Math.PI*2),F.fill(),F.globalCompositeOperation=`source-over`}for(let e of V.ripples){let t=e.t/tt;F.strokeStyle=`rgba(255,255,255,${(1-t)*.75})`,F.lineWidth=2,F.beginPath(),F.arc(e.x,e.y,5+t*28,0,Math.PI*2),F.stroke(),t>.25&&(F.strokeStyle=`rgba(255,255,255,${(1-t)*.4})`,F.beginPath(),F.arc(e.x,e.y,5+(t-.25)*28,0,Math.PI*2),F.stroke())}F.strokeStyle=`rgba(230,240,210,0.14)`,F.lineWidth=1.5/t,F.beginPath(),F.moveTo(o[0][0],o[0][1]),F.lineTo(e.x,e.y),F.lineTo(o[o.cone][0],o[o.cone][1]),F.stroke();let u=(B.exfil[0]+.5)*40,d=(B.exfil[1]+.5)*40;F.strokeStyle=`rgba(120,230,110,${.45+Math.sin(V.time*3)*.2})`,F.lineWidth=3,F.setLineDash([14,10]),F.beginPath(),F.arc(u,d,110,V.time*.3,V.time*.3+Math.PI*2),F.stroke(),F.setLineDash([]),hn();for(let e of V.grenades){j(F,e.x+3,e.y+3,5,4,`rgba(0,0,0,0.35)`);let t=5+e.z*.05;F.save(),F.translate(e.x,e.y-e.z*.35),F.rotate(e.spin),j(F,0,0,t,t*.85,{frag:`#3f4a2e`,flash:`#5b6066`,smoke:`#5c6660`,molotov:`#7a9a5a`}[e.kind]),F.fillStyle=`#9a9c95`,F.fillRect(-1.5,-t-2,3,3),F.restore(),e.kind===`frag`&&e.fuse<1.2&&Math.sin(e.fuse*30)>0&&j(F,e.x,e.y-e.z*.35,2,2,`#ff4030`)}if(or(`player`),!e.dead){let t=e.equip===`primary`||e.equip===`secondary`?`gun`:e.equip===`throwable`?`grenade`:e.equip===`medical`?`med`:null,n=Kt();ue(F,{x:e.x,y:e.y,a:e.angle,pal:V.charPal,weapon:n?n.id:null,hold:t,walk:e.walk,recoil:e.recoil,hurt:V.hurtFlash>.3?.05:0,player:!0})}for(let e of V.smokes){let t=rt(e),n=Math.min(1,e.t/1.5);if(!(t<2)){for(let r of e.puffs){let i=(12-e.t)*r.spin,a=e.x+(r.ox*Math.cos(i)-r.oy*Math.sin(i))*t,o=e.y+(r.ox*Math.sin(i)+r.oy*Math.cos(i))*t,s=r.s*t*1.25;F.globalAlpha=n,F.drawImage(In(r.shade),a-s,o-s,s*2,s*2)}F.globalAlpha=n,F.drawImage(Ln(),e.x-t,e.y-t,t*2,t*2)}}F.globalAlpha=1;let f=Kt();if(f&&!e.dead&&!V.over&&Pt(f.id)>=20){let t=en(e.x,e.y,e.angle,f.id),n=$t(),r=Math.atan2(n.y-t.y,n.x-t.x),i=Math.cos(r),a=Math.sin(r),o=Xe(t.x,t.y,i,a,Fe,Ve);for(let e of V.enemies){if(e.dead)continue;let n=Qe(t.x,t.y,i,a,o,e.x,e.y,13);n>=0&&(o=n)}let s=t.x+i*o,c=t.y+a*o;F.lineCap=`round`,F.strokeStyle=`rgba(255,40,30,0.18)`,F.lineWidth=4,F.beginPath(),F.moveTo(t.x,t.y),F.lineTo(s,c),F.stroke(),F.strokeStyle=`rgba(255,70,50,0.85)`,F.lineWidth=1.2,F.beginPath(),F.moveTo(t.x,t.y),F.lineTo(s,c),F.stroke(),j(F,s,c,5,5,`rgba(255,60,40,0.3)`),j(F,s,c,2.2,2.2,`#ff5a40`)}ir(!1),rr(!1);let p=Zn();p&&Qn(p),F.setTransform(ke,0,0,ke,0,0),ur(i,a)}let cr=``;function U(e,t,n,r,i,a=`left`,o=600){let s=`${o} ${r}px ${He}`;s!==cr&&(F.font=s,cr=s),F.textAlign=a,F.textBaseline=`alphabetic`,F.fillStyle=`rgba(0,0,0,0.6)`,F.fillText(e,t+1,n+1),F.fillStyle=i,F.fillText(e,t,n)}let lr=null;function ur(t,n){let i=V.player,a=Ae;cr=``;let s=(1-i.hp/100)*.55+V.hurtFlash;s>.02&&(lr||(lr=F.createRadialGradient(I/2,L/2,Math.min(I,L)*.3,I/2,L/2,Math.max(I,L)*.75),lr.addColorStop(0,`rgba(150,0,0,0)`),lr.addColorStop(1,`rgb(150,0,0)`)),F.fillStyle=lr,F.globalAlpha=Math.min(.85,s),F.fillRect(0,0,I,L),F.globalAlpha=1);for(let e of V.dmgInd){let t=e.a;F.strokeStyle=`rgba(230,40,30,${Math.min(1,e.t)*.85})`,F.lineWidth=8,F.beginPath(),F.arc(I/2,L/2,120,t-.28,t+.28),F.stroke()}let l=(B.exfil[0]+.5)*40,u=(B.exfil[1]+.5)*40,d=t+l*a,f=n+u*a,p=Math.round(Math.hypot(l-i.x,u-i.y)/32),m=I-40,h=L-180,g=d<40||f<120||d>m||f>h;if(g){let e=Math.atan2(f-L/2,d-I/2),t=Math.cos(e),n=Math.sin(e),r=1/0;t>0&&(r=Math.min(r,(m-I/2)/t)),t<0&&(r=Math.min(r,(40-I/2)/t)),n>0&&(r=Math.min(r,(h-L/2)/n)),n<0&&(r=Math.min(r,(120-L/2)/n)),d=I/2+t*r,f=L/2+n*r,F.save(),F.translate(d,f),F.rotate(e),F.fillStyle=`#7fe36a`,F.beginPath(),F.moveTo(16,0),F.lineTo(4,-8),F.lineTo(4,8),F.closePath(),F.fill(),F.restore()}F.save(),F.translate(d,f-(g?0:30)),F.rotate(Math.PI/4),F.strokeStyle=`#7fe36a`,F.lineWidth=2,F.strokeRect(-7,-7,14,14),F.restore(),U(`EXTRACT`,d,f-(g?16:46),12,`#7fe36a`,`center`),U(`${p}m`,d,f+(g?24:-8),12,`#cfe9c7`,`center`),F.fillStyle=`rgba(10,12,10,0.55)`,F.fillRect(18,18,300,96),F.fillStyle=`#a5d63f`,F.fillRect(18,18,3,96),U(`${V.campaign?`CAMPAIGN ${V.campaignStage+1} / ${e.length} - ${B.name}`:`OBJECTIVE`} - ${V.diff.name}`,32,38,12,`#a5d63f`),U(V.exfilState===`calling`?`Survive until the helicopter arrives`:V.exfilState===`landed`?`Board the helicopter`:`Call extraction at the helipad`,32,58,16,`#e6eadf`);let _=Math.floor(V.time/60),v=Math.floor(V.time%60),y=0;for(let e of i.items)e&&o[e.id].kind===`valuable`&&(y+=o[e.id].value);U(`${_}:${String(v).padStart(2,`0`)} KILLS ${V.kills} INTEL $${Math.round(y*V.diff.money)}`,32,80,13,`#8c978a`);let b=Math.ceil(60-V.time%60),x=Math.max(0,Math.round((y+V.kills*10)*V.diff.money)-V.penalty);V.campaign?U(`TO FUNDS HOLD $${x.toLocaleString()}`,32,102,13,`#e8c547`):V.extractCalled?U(`PAYOUT $${x.toLocaleString()} TIME PENALTY STOPPED`,32,102,13,`#7fe36a`):U(`PAYOUT $${x.toLocaleString()} -$50 IN ${b}s`,32,102,13,b<=10?`#e0402f`:`#e8c547`);let S=L-46;U(`HEALTH`,24,S-10,12,`#8c978a`),F.fillStyle=`rgba(0,0,0,0.55)`,F.fillRect(24,S,260,16),F.fillStyle=i.hp>50?`#e6eadf`:i.hp>25?`#e8c547`:`#e0402f`,F.fillRect(26,S+2,256*(i.hp/100),12),F.fillStyle=`rgba(0,0,0,0.5)`;for(let e=1;e<10;e++)F.fillRect(26+e*25.6,S+2,1,12);if(U(String(Math.ceil(i.hp)),296,S+14,22,`#e6eadf`),i.burnT>0&&U(`BURNING ${i.burnT.toFixed(1)}s`,344,S+14,15,Math.sin(V.time*12)>0?`#ff8a30`:`#ffc060`,`left`,700),i.armour){let e=c[i.armour],t=Wt(i.armour),n=S-44,r=i.armourHp<=0;U(r?`${e.name.toUpperCase()} - BROKEN`:`${e.name.toUpperCase()} -${e.reduce} DMG PER HIT`,24,n-6,12,r?`#e0402f`:`#8fb8d8`),F.fillStyle=`rgba(0,0,0,0.55)`,F.fillRect(24,n,260,10),F.fillStyle=V.armourHitT>0?`#e6f2ff`:`#5f9fd6`,F.fillRect(26,n+2,256*(i.armourHp/t),6),U(`${Math.ceil(i.armourHp)}/${t}`,296,n+10,13,r?`#e0402f`:`#8fb8d8`)}let C=Kt(),w=I-24;if(C){let e=r[C.id],t=Pt(C.id);U(e.name.toUpperCase()+(t?` LV ${t}`:``),w,L-92,16,t>=20?`#e8c547`:`#e6eadf`,`right`);let n=` / ${C.reserve}`;F.font=cr=`600 18px ${He}`;let a=F.measureText(n).width;U(n,w,L-50,18,`#8c978a`,`right`),U(String(C.mag),w-a,L-50,40,C.mag===0?`#e0402f`:C.mag<=Lt(C.id)*.25?`#e8c547`:`#e6eadf`,`right`,700),C.mag===0&&i.reloadT<=0&&U(C.reserve>0||i.items.some(e=>e&&e.id===`ammo`)?`RELOAD [R]`:`NO AMMO`,I/2,L/2+60,15,`#e0402f`,`center`)}else if(i.equip===`throwable`||i.equip===`medical`){let e=i.items[i.itemSlot];e&&(U(o[e.id].name.toUpperCase(),w,L-92,16,`#e6eadf`,`right`),U(i.equip===`throwable`?`CLICK TO THROW`:`CLICK TO USE`,w,L-54,18,`#a5d63f`,`right`,700))}else U(`UNARMED`,w,L-54,18,`#8c978a`,`right`);let T=i.items.reduce((e,t)=>e+(t&&o[t.id].kind===`throwable`?t.uses||1:0),0),E=i.items.filter(e=>e&&o[e.id].kind===`medical`).length,ee=[[`1`,i.weapons[0]?r[i.weapons[0].id].name:`-`,i.equip===`primary`,i.weapons[0]],[`2`,i.weapons[1]?r[i.weapons[1].id].name:`-`,i.equip===`secondary`,i.weapons[1]],[`3`,`THROW x${T}`,i.equip===`throwable`,T?i.items[i.equip===`throwable`?i.itemSlot:i.items.findIndex(e=>e&&o[e.id].kind===`throwable`)]:null],[`4`,`MED x${E}`,i.equip===`medical`,E?i.items[i.equip===`medical`?i.itemSlot:i.items.findIndex(e=>e&&o[e.id].kind===`medical`)]:null]],D=I-24-ee.length*108+8;for(let[e,t,n,r]of ee){let i=L-150;if(F.fillStyle=n?`rgba(165,214,63,0.22)`:`rgba(10,12,10,0.5)`,F.fillRect(D,i,100,40),F.strokeStyle=n?`#a5d63f`:`rgba(255,255,255,0.12)`,F.lineWidth=1,F.strokeRect(D+.5,i+.5,99,39),r){let e=De(r);e.complete&&(r.type===`weapon`?F.drawImage(e,D+18,i+2,80,32):F.drawImage(e,D+62,i+3,34,34))}U(e,D+5,i+14,12,n?`#a5d63f`:`#8c978a`,`left`,700),U(t.length>13?t.slice(0,12)+`.`:t,D+5,i+35,11,`#e6eadf`),D+=108}let O=i.reloadT>0?[1-i.reloadT/i.reloadMax,`RELOADING`]:i.useT>0?[1-i.useT/i.useMax,`APPLYING`]:null;if(O&&(F.fillStyle=`rgba(0,0,0,0.6)`,F.fillRect(I/2-70,L/2+46,140,6),F.fillStyle=`#e6eadf`,F.fillRect(I/2-70,L/2+46,140*O[0],6),U(O[1],I/2,L/2+40,12,`#e6eadf`,`center`)),!V.invOpen&&!i.dead&&!V.over){let e=Vn(70),t=V.exfilState===`idle`&&Kn()?`CALL EXTRACTION`:V.exfilState===`landed`&&Kn(40)?`BOARD HELICOPTER`:null;if(t||e){let n=t||(e.kind===`cache`?`SEARCH SUPPLY CACHE`:e.kind===`body`?`SEARCH BODY`:`PICK UP ITEMS`);F.fillStyle=`rgba(10,12,10,0.65)`,F.fillRect(I/2-120,L-120,240,30),U(`[F] ${n}`,I/2,L-100,15,`#e8c547`,`center`)}}if((V.exfilState===`calling`||V.exfilState===`landed`)&&!V.over){let e=V.exfilState===`landed`,t=e?60:V.diff.extractTime,n=1-V.exfilT/t,r=e?V.exfilT<15&&Math.sin(V.time*8)>0?`#e0402f`:`#7fe36a`:`#e8c547`;U(e?`HELICOPTER ON THE PAD - BOARD [F] ${Jn(V.exfilT)}`:`HELICOPTER INBOUND ${Jn(V.exfilT)}`,I/2,140,24,r,`center`,700),F.fillStyle=`rgba(0,0,0,0.6)`,F.fillRect(I/2-180,152,360,8),F.fillStyle=r,F.fillRect(I/2-180,152,360*(e?1-n:n),8),e||U(`HOLD OUT - REINFORCEMENTS EVERY 3s (${V.reinforcements} SO FAR)`,I/2,178,13,`#c9a0a0`,`center`)}let te=190;for(let e of V.toasts){let t=Math.min(1,e.t*2,(e.max-e.t)*6+.2);F.globalAlpha=t,U(e.text,I/2,te,17,`#e6eadf`,`center`,700),F.globalAlpha=1,te+=26}if(!V.invOpen&&!i.dead&&!V.over){let e=z.mx,t=z.my,n=6+V.crossBloom*8+(i.sprinting?8:0);F.strokeStyle=`rgba(0,0,0,0.6)`,F.lineWidth=4;let r=[[1,0],[-1,0],[0,1],[0,-1]];for(let[i,a]of r)F.beginPath(),F.moveTo(e+i*n,t+a*n),F.lineTo(e+i*(n+9),t+a*(n+9)),F.stroke();F.strokeStyle=i.sprinting?`rgba(230,234,223,0.4)`:`#e6eadf`,F.lineWidth=2;for(let[i,a]of r)F.beginPath(),F.moveTo(e+i*n,t+a*n),F.lineTo(e+i*(n+9),t+a*(n+9)),F.stroke();if(j(F,e,t,1.5,1.5,`#e6eadf`),V.hitT>0){F.strokeStyle=V.hitKill?`rgba(230,50,40,${Math.min(1,V.hitT*5)})`:`rgba(255,255,255,${Math.min(1,V.hitT*6)})`,F.lineWidth=2.5;for(let[n,r]of[[1,1],[1,-1],[-1,1],[-1,-1]])F.beginPath(),F.moveTo(e+n*7,t+r*7),F.lineTo(e+n*15,t+r*15),F.stroke()}for(let n of V.floaters)U(n.text,e+24,t-20-(1-n.t)*30,16,`rgba(232,197,71,${n.t})`,`left`,700)}i.flashT>0&&(F.fillStyle=`rgba(255,255,250,${Math.min(1,i.flashT/1.4)})`,F.fillRect(0,0,I,L))}let dr=performance.now(),fr=null;function pr(e){let t=Math.min(.05,(e-dr)/1e3);dr=e,W===`play`&&V&&er(t),W!==`play`&&fr&&fr.mode===W&&fr.g===V||(sr(),fr=W===`play`?null:{mode:W,g:V}),z.clicked=!1,requestAnimationFrame(pr)}let W=`menu`,G=e=>document.getElementById(e),K=globalThis.BLACKSITE_STORE,q=K.get(`blacksite.loadout`,null)||{primary:`m4a1`,secondary:`m1911`,throwable:`frag`};i.includes(q.primary)||(q.primary=`m4a1`),a.includes(q.secondary)||(q.secondary=`m1911`),s.includes(q.throwable)||(q.throwable=null);let J=Object.assign({bank:0,levels:{},armours:[],armour:null,unlocked:[],armourLevels:{},armourBonus:{}},K.get(`blacksite.profile`,{})),mr=K.get(`blacksite.map`,`town`);e.some(e=>e.id===mr)||(mr=`town`);let hr=t=>(e.find(e=>e.id===t)||e[0]).name,gr=()=>!!q.throwable&&J.unlocked.includes(q.throwable);function _r(){K.set(`blacksite.profile`,J)}let Y=e=>`$`+e.toLocaleString(),X=K.get(`blacksite.campaign`,null);function vr(){K.set(`blacksite.campaign`,X)}function yr(){if(!X||!X.inMap)return 0;let e=Math.min(400,X.hold);return X.hold-=e,X.inMap=!1,X.lastQuit=e,vr(),e}yr();let br=e=>JSON.parse(JSON.stringify(e)),Z=K.get(`blacksite.character`,`assaulter`);p[Z]||(Z=`assaulter`);let xr=K.get(`blacksite.difficulty`,`normal`);u[xr]||(xr=`normal`);function Sr(){let e=u[xr];G(`diffSlider`).value=d.indexOf(xr),G(`diffName`).textContent=e.name,G(`diffName`).className=`d-`+xr,G(`diffDesc`).textContent=e.desc+(X?` (Your saved campaign keeps the difficulty it was started on.)`:``)}G(`diffSlider`).addEventListener(`input`,e=>{xr=d[+e.target.value]||`normal`,K.set(`blacksite.difficulty`,xr),Sr()});function Q(e){return String(e).replace(/[&<>"]/g,e=>({"&":`&`,"<":`<`,">":`>`,'"':`"`})[e])}let $={show(e){for(let t of document.querySelectorAll(`.screen`))t.classList.toggle(`on`,t.id===e)},menu(){W=`menu`,V=null;let t=K.get(`blacksite.best`,null);G(`best`).textContent=t?`BEST PAYOUT $${t.payout.toLocaleString()} - ${t.time}`:``,G(`bank`).textContent=`FUNDS ${Y(J.bank)}`,Sr(),G(`menuMap`).textContent=`MAP: ${hr(mr)}`,G(`menuCampaign`).textContent=X?`CAMPAIGN IN PROGRESS: MAP ${X.stage+1} / ${e.length} - HOLD ${Y(X.hold)}${X.lastQuit?` (-${Y(X.lastQuit)} FOR QUITTING)`:``}`:``,G(`menuChar`).textContent=`CHARACTER: ${p[Z].name}`,G(`menuLoadout`).textContent=`${r[q.primary].name} / ${r[q.secondary].name} / ${gr()?o[q.throwable].name:`No throwable`}`,$.show(`menu`)},deploy(){P.init(),vt(q,mr,null,xr),W=`play`,$.show(null)},deployCampaign(){X?(P.init(),vt(q,e[X.stage].id,X,X.difficulty),X.inMap=!0,X.lastQuit=0,vr(),W=`play`,$.show(null)):$.campaign()},newCampaign(){let e=mt(q,Z);X={stage:0,hold:0,kills:0,time:0,weapons:e.weapons,items:e.items,difficulty:xr},vr(),$.deployCampaign()},campaign(){W=`campaign`,V=null,Er(),$.show(`campaign`)},pause(){W===`play`&&V&&!V.over&&(W=`paused`,z.mdown=!1,G(`pauseQuit`).textContent=V.campaign?`QUIT TO MENU (-${Y(400)} FUNDS HOLD)`:`QUIT TO MENU`,G(`pauseRestart`).textContent=V.campaign?`RESTART MAP (-${Y(400)} FUNDS HOLD)`:`RESTART MISSION`,$.show(`pause`))},resume(){W=`play`,$.show(null)},showEnd(){if(W=`end`,V.campaign){wr();return}for(let e of document.querySelectorAll(`#end .quick`))e.style.display=``;for(let e of document.querySelectorAll(`#end .camp`))e.style.display=`none`;let e=V.won,t=`${Math.floor(V.time/60)}:${String(Math.floor(V.time%60)).padStart(2,`0`)}`;G(`endTitle`).textContent=e?`EXTRACTED`:`K.I.A.`,G(`endTitle`).className=e?`win`:`lose`,G(`endSub`).textContent=e?`Mission complete. Exfil successful.`:`You were killed in action.`;let n=V.shots?Math.round(V.hits/V.shots*100):0,r=[[`MAP`,B.name],[`DIFFICULTY`,V.diff.name],[`TIME`,t],[`KILLS`,V.kills],[`ACCURACY`,`${n}%`],[`DAMAGE TAKEN`,Math.round(V.dmgTaken)]];if(V.penalty&&r.push([`TIME PENALTY`,`-`+Y(V.penalty)]),e){J.bank+=V.payout,_r(),r.push([`INTEL SECURED`,Y(V.valuables)],[`PAYOUT`,Y(V.payout)]);let e=K.get(`blacksite.best`,null);(!e||V.payout>e.payout)&&(K.set(`blacksite.best`,{payout:V.payout,time:t}),r.push([``,`NEW BEST`]))}r.push([`FUNDS`,Y(J.bank)]),G(`endStats`).innerHTML=r.map(([e,t])=>`<div>${Q(e)}</div><div>${Q(t)}</div>`).join(``),$.show(`end`)}};function Cr(e){return`${Math.floor(e/60)}:${String(Math.floor(e%60)).padStart(2,`0`)}`}function wr(){let t=V.won;for(let e of document.querySelectorAll(`#end .quick`))e.style.display=`none`;let n=[[`MAP`,`${B.name} (${V.campaignStage+1}/${e.length})`],[`DIFFICULTY`,V.diff.name],[`TIME`,Cr(V.time)],[`KILLS`,V.kills]],r=!1;if(t&&X){if(X.hold+=V.payout,X.kills+=V.kills,X.time+=V.time,X.stage++,X.inMap=!1,X.weapons=br(V.player.weapons),X.items=br(V.player.items.map(e=>e&&o[e.id].kind===`valuable`?null:e)),V.penalty&&n.push([`TIME PENALTY`,`-`+Y(V.penalty)]),n.push([`INTEL SECURED`,Y(V.valuables)],[`ADDED TO HOLD`,Y(V.payout)],[`FUNDS HOLD`,Y(X.hold)]),X.stage>=e.length){let e=Math.round(3e3*V.diff.money),t=X.hold+e;J.bank+=t,_r(),n.push([`COMPLETION BONUS`,Y(e)],[`TOTAL PAID`,Y(t)],[`TOTAL KILLS`,X.kills],[`TOTAL TIME`,Cr(X.time)],[`FUNDS`,Y(J.bank)]),G(`endTitle`).textContent=`CAMPAIGN COMPLETE`,G(`endSub`).textContent=`All five maps cleared. The funds hold has been paid out.`,X=null}else G(`endTitle`).textContent=`MAP CLEARED`,G(`endSub`).textContent=`Next: ${e[X.stage].name} (${X.stage+1}/${e.length}). Health and armour will be restored. Progress saved.`,r=!0;G(`endTitle`).className=`win`}else n.push([`FUNDS HOLD LOST`,Y(X?X.hold:0)]),G(`endTitle`).textContent=`K.I.A.`,G(`endTitle`).className=`lose`,G(`endSub`).textContent=`You were killed in action. The campaign is over and cannot be continued.`,X=null;vr(),G(`endContinue`).style.display=r?``:`none`,G(`endStats`).innerHTML=n.map(([e,t])=>`<div>${Q(e)}</div><div>${Q(t)}</div>`).join(``),$.show(`end`)}let Tr=!1;function Er(){Tr=!1;let t=X;if(G(`campHold`).textContent=Y(t?t.hold:0),G(`campMaps`).innerHTML=e.map((e,n)=>{Mr[e.id]||(Mr[e.id]=Se(O(e.id)).toDataURL());let r=t?n<t.stage?`CLEARED`:n===t.stage?`NEXT`:`LOCKED`:``;return`<div class="mcard${r===`NEXT`?` sel`:``}${r===`CLEARED`?` done`:``}">
<img src="${Mr[e.id]}" alt="">
<div class="lname">${n+1}. ${Q(e.name)}</div>
<div class="lmeta">${r||`HOSTILE POSITIONS UNKNOWN`}</div>
</div>`}).join(``),t){let n=[...t.weapons,...t.items].filter(Boolean).map(e=>w(e).name);G(`campStatus`).textContent=`${(u[t.difficulty]||u.normal).name} - MAP ${t.stage+1} / ${e.length} - ${t.kills} KILLS SO FAR - CARRYING: ${n.join(`, `)||`nothing`}`}else G(`campStatus`).textContent=`No campaign in progress. A new campaign starts with your current loadout.`;G(`campContinue`).style.display=t?``:`none`,G(`campNew`).textContent=`NEW CAMPAIGN`}G(`campContinue`).addEventListener(`click`,()=>{P.init(),P.click(),$.deployCampaign()}),G(`campNew`).addEventListener(`click`,()=>{P.init(),P.click(),X&&!Tr?(Tr=!0,G(`campNew`).textContent=`CLICK AGAIN - THIS DELETES YOUR SAVED CAMPAIGN`):$.newCampaign()});function Dr(e){return[[`DAMAGE`,e.dmg*e.pellets/120],[`FIRE RATE`,e.rpm/1100],[`RANGE`,e.range/2400],[`MOBILITY`,(e.mobility-.75)/.33],[`CAPACITY`,e.mag/60]].map(([e,t])=>`<div class="stat"><span>${e}</span><i><b style="width:${Math.round(je(t,.05,1)*100)}%"></b></i></div>`).join(``)}function Or(){let e=(e,t,n)=>{let i=r[t];return`<div class="lcard${n?` sel`:``}" data-kind="${e}" data-id="${t}">
<div class="lhead"><div><div class="lname">${Q(i.name)}</div><div class="lcls">${Q(i.cls)}${Pt(t)?` - LV ${Pt(t)}`:``}</div></div>
<img src="${Ee({type:`weapon`,id:t})}" alt=""></div>
${Dr(i)}
<div class="lmeta">${i.mag} RDS / ${i.auto?`AUTO`:`SEMI`} / ${i.dmg}${i.pellets>1?`x`+i.pellets:``} DMG</div>
</div>`};G(`lPrimary`).innerHTML=i.map(t=>e(`primary`,t,q.primary===t)).join(``),G(`lSecondary`).innerHTML=a.map(t=>e(`secondary`,t,q.secondary===t)).join(``),G(`lThrow`).innerHTML=s.map(e=>`<div class="lcard small${gr()&&q.throwable===e?` sel`:``}${J.unlocked.includes(e)?``:` locked`}" data-kind="throwable" data-id="${e}">
<div class="lhead"><div><div class="lname">${Q(o[e].name)}</div><div class="lcls">${J.unlocked.includes(e)?o[e].cls:`LOCKED - UNLOCK IN THE ARMORY`}</div></div>
<img class="sq" src="${Ee({type:`item`,id:e})}" alt=""></div>
<div class="ldesc">${Q(o[e].desc)}</div></div>`).join(``)}G(`loadout`).addEventListener(`click`,e=>{let t=e.target.closest(`.lcard`);t&&(P.init(),t.classList.contains(`locked`)?P.deny():(q[t.dataset.kind]=t.dataset.kind===`throwable`&&q.throwable===t.dataset.id?null:t.dataset.id,K.set(`blacksite.loadout`,q),P.init(),P.click(),Or()))});let kr={};function Ar(e){if(!kr[e]){let t=k(160,120),n=t.getContext(`2d`);n.scale(2.6,2.6);let r={assaulter:`m4a1`,gunner:`m249`,sniper:`barrett`,cutthroat:`mp5`,hauler:`ak47`}[e];ue(n,{x:26,y:23,a:0,pal:p[e].pal,weapon:r,hold:`gun`,walk:.6,player:!0}),kr[e]=t.toDataURL()}return kr[e]}function jr(){G(`charGrid`).innerHTML=m.map(e=>{let t=p[e];return`<div class="mcard${e===Z?` sel`:``}" data-char="${e}">
<img class="charimg" src="${Ar(e)}" alt="">
<div class="lname">${Q(t.name)}</div>
<div class="lcls">${Q(t.role)}</div>
<ul class="perks">${t.perks.map(e=>`<li>${Q(e)}</li>`).join(``)}</ul>
</div>`}).join(``)}G(`character`).addEventListener(`click`,e=>{let t=e.target.closest(`[data-char]`);t&&(Z=t.dataset.char,K.set(`blacksite.character`,Z),P.init(),P.click(),jr())});let Mr={};function Nr(){G(`mapGrid`).innerHTML=e.map(e=>(Mr[e.id]||(Mr[e.id]=Se(O(e.id)).toDataURL()),`<div class="mcard${e.id===mr?` sel`:``}" data-map="${e.id}">
<img src="${Mr[e.id]}" alt="">
<div class="lname">${Q(e.name)}</div>
<div class="ldesc">${Q(e.desc)}</div>
<div class="lmeta">HOSTILE POSITIONS UNKNOWN</div>
</div>`)).join(``)}G(`maps`).addEventListener(`click`,e=>{let t=e.target.closest(`.mcard`);t&&(mr=t.dataset.map,K.set(`blacksite.map`,mr),P.init(),P.click(),Nr())});function Pr(){G(`shopFunds`).textContent=Y(J.bank),G(`sWeapons`).innerHTML=[...i,...a].map(e=>{let t=r[e],n=Pt(e),i=n>=20,a=i?0:_(n),o=g[e]||h,s=g[e]?`FIRE RATE`:`DAMAGE`,c=e=>Math.round(e*o*100),l=i?` - LASER SIGHT`:` -> +${c(n+1)}%${n+1===20?` + LASER SIGHT`:``}`;return`<div class="lcard${i?` sel`:``}">
<div class="lhead"><div><div class="lname">${Q(t.name)}</div><div class="lcls">${Q(t.cls)}</div></div>
<img src="${Ee({type:`weapon`,id:e})}" alt=""></div>
<div class="lvlrow"><span>LV ${n} / 20</span><i><b style="width:${n/20*100}%"></b></i></div>
<div class="lmeta">${s} +${c(n)}%${l}</div>
<button class="buy" data-up="${e}" ${i||J.bank<a?`disabled`:``}>${i?`MAX LEVEL`:`UPGRADE `+Y(a)}</button>
</div>`}).join(``),G(`sThrow`).innerHTML=s.map(e=>{let t=o[e],n=J.unlocked.includes(e);return`<div class="lcard${n?` sel`:``}">
<div class="lhead"><div><div class="lname">${Q(t.name)}</div><div class="lcls">${t.cls}</div></div>
<img class="sq" src="${Ee({type:`item`,id:e})}" alt=""></div>
<div class="ldesc">${Q(t.desc)}</div>
<button class="buy" data-unlock="${e}" ${n||J.bank<t.unlock?`disabled`:``}>${n?`UNLOCKED - PICK IT IN LOADOUT`:`UNLOCK `+Y(t.unlock)}</button>
</div>`}).join(``),G(`sArmour`).innerHTML=l.map(e=>{let t=c[e],n=J.armours.includes(e),r=J.armour===e,i=r?`EQUIPPED - CLICK TO REMOVE`:n?`EQUIP`:`BUY `+Y(t.price),a=J.armourLevels[e]||0,o=a>=10,s=n?`<button class="buy" data-armour-up="${e}" ${o||J.bank<500?`disabled`:``}>${o?`FULLY UPGRADED`:`UPGRADE +5 HP ${Y(500)}`}</button>`:``;return`<div class="lcard${r?` sel`:``}">
<div class="lhead"><div><div class="lname">${Q(t.name)}</div><div class="lcls">BODY ARMOUR</div></div>
<img class="sq" src="${Ee({type:`armour`,id:e})}" alt=""></div>
<div class="ldesc">Takes ${t.reduce} damage off every enemy bullet that hits you, until its health runs out.</div>
<div class="lvlrow"><span>${Wt(e)} HP</span><i><b class="ahp" style="width:${a/10*100}%"></b></i></div>
<div class="lmeta">UPGRADES ${a} / 10${a?` (+${a*5} HP)`:``}</div>
<button class="buy" data-armour="${e}" ${!n&&J.bank<t.price?`disabled`:``}>${i}</button>
${s}
</div>`}).join(``)}G(`shop`).addEventListener(`click`,e=>{let t=e.target.closest(`button.buy`);if(t&&!t.disabled){if(P.init(),t.dataset.unlock){let e=t.dataset.unlock,n=o[e].unlock;if(J.unlocked.includes(e)||J.bank<n){P.deny();return}J.bank-=n,J.unlocked.push(e),gr()||(q.throwable=e,K.set(`blacksite.loadout`,q))}else if(t.dataset.up){let e=t.dataset.up,n=Pt(e),r=_(n);if(n>=20||J.bank<r){P.deny();return}J.bank-=r,J.levels[e]=n+1}else if(t.dataset.armourUp){let e=t.dataset.armourUp,n=J.armourLevels[e]||0;if(!J.armours.includes(e)||n>=10||J.bank<500){P.deny();return}J.bank-=500,J.armourLevels[e]=n+1}else{let e=t.dataset.armour,n=c[e];if(J.armour===e)J.armour=null;else if(J.armours.includes(e))J.armour=e;else{if(J.bank<n.price){P.deny();return}J.bank-=n.price,J.armours.push(e),J.armour=e}}_r(),P.pickup(),Pr()}});let Fr=(()=>{let e=null,t=G(`ghost`),n=e=>{let[t,n]=e.split(`:`);return t===`loot`?V.invPile.items[+n]:t===`w`?V.player.weapons[+n]:V.player.items[+n]},i=(e,t)=>{let[n,r]=e.split(`:`);n===`loot`?V.invPile.items[+r]=t:n===`w`?V.player.weapons[+r]=t:V.player.items[+r]=t},a=(e,t)=>{if(!t)return!0;let[n,i]=e.split(`:`);return n===`loot`?!0:n===`w`?t.type===`weapon`&&r[t.id].slot===(i===`0`?`primary`:`secondary`):n===`i`&&+i==4&&Ht()?t.type===`item`&&o[t.id].kind===`throwable`:t.type===`item`},s=(e,t)=>{let[n,r]=e.split(`:`);return n===`w`&&t.type!==`weapon`?`Only weapons go in weapon slots`:n===`i`&&+r==4&&Ht()?`The grenade slot only takes throwables`:n===`w`?r===`0`?`Pistols go in the secondary slot`:`Rifles go in the primary slot`:n===`i`&&t.type===`weapon`?`Weapons go in the weapon slots`:`Can't place that there`};function l(e,t){if(e===t)return!1;let r=n(e),o=n(t);if(!a(t,r))return _(s(t,r),!0),P.deny(),!1;if(o&&!a(e,o))return _(s(e,o),!0),P.deny(),!1;i(t,r),i(e,o),Ht()&&Ut(V.player.items);let c=V.player;return(e[0]===`w`||t[0]===`w`)&&(c.reloadT=0,c.autoReload=!1),qt(),c.equip===`none`&&(c.weapons[0]||c.weapons[1])&&(c.equip=c.weapons[0]?`primary`:`secondary`),Xt(),P.pickup(),!0}function u(e){let t=V.invPile,n=t.items.indexOf(null);return n<0&&(t.items.push(null),n=t.items.length-1),l(e,`loot:`+n)}function d(e){let t=n(e);if(t){if(e.startsWith(`loot`)){let i;if(t.type===`weapon`){if(i=r[t.id].slot===`primary`?`w:0`:`w:1`,n(i)){_(`No room - your ${i===`w:0`?`primary`:`secondary`} slot is full. Drag onto it to swap.`,!0),P.deny();return}}else{let e=p(t);if(e<0){_(`No room - your item slots are full. Drag onto an item to swap.`,!0),P.deny();return}i=`i:`+e}l(e,i)}else u(e);h()}}let f={ref:null,t:0};function p(e){let t=V.player.items;if(Ht()&&!t[4]&&a(`i:4`,e))return 4;for(let n=0;n<t.length;n++)if(!t[n]&&a(`i:`+n,e))return n;return-1}function m(e,t,n){if(!t)return`<div class="cell empty" data-ref="${e}"><span class="ph">${n}</span></div>`;let r=w(t),i=``;return i=t.type===`weapon`?`${t.mag} | ${t.reserve}`:r.kind===`valuable`?`$${Math.round(r.value*V.diff.money).toLocaleString()}`:r.kind===`medical`?`+${r.heal} HP`:t.uses>1?`${t.uses} THROWS LEFT`:r.kind.toUpperCase(),`<div class="cell${t.type===`weapon`?` wpn`:``}" data-ref="${e}">
<img src="${Ee(t)}" alt="" draggable="false"><div class="nm">${Q(r.name)}</div><div class="sb">${Q(i)}</div></div>`}function h(){if(!V||!V.invOpen)return;let e=V.invPile,t=V.player;G(`lootTitle`).textContent=e.kind===`cache`?`SUPPLY CACHE`:e.kind===`body`?`ENEMY BODY`:e.kind===`drop`?`DROPPED ITEMS`:`GROUND`,G(`lootGrid`).innerHTML=e.items.map((e,t)=>m(`loot:`+t,e,``)).join(``),G(`lootEmpty`).style.display=e.items.some(Boolean)?`none`:`block`,G(`wSlots`).innerHTML=`<div class="slotlbl">1 PRIMARY</div>${m(`w:0`,t.weapons[0],`RIFLE`)}<div class="slotlbl">2 SECONDARY</div>${m(`w:1`,t.weapons[1],`PISTOL`)}`,G(`iSlots`).innerHTML=t.items.map((e,t)=>m(`i:`+t,e,t===4&&Ht()?`GRENADE SLOT (3 THROWS)`:`EMPTY`)).join(``);let n=t.armour&&c[t.armour];G(`aSlot`).innerHTML=n?`<div class="cell locked"><img src="${Ee({type:`armour`,id:t.armour})}" alt="" draggable="false"><div class="nm">${Q(n.name)}</div><div class="sb">${t.armourHp>0?`-${n.reduce} DMG / ${Math.ceil(t.armourHp)} / ${Wt(t.armour)} HP`:`BROKEN`}</div></div>`:`<div class="cell empty locked"><span class="ph">BUY ARMOUR IN THE ARMORY</span></div>`,G(`invHp`).style.width=`${t.hp}%`,G(`invHpTxt`).textContent=Math.ceil(t.hp)}let g=0;function _(e,t){let n=G(`invTip`);n.textContent=e,n.classList.toggle(`bad`,!!t),clearTimeout(g),t&&(g=setTimeout(()=>{n.textContent=``,n.classList.remove(`bad`)},1800))}function v(e){let t=w(e);return e.type===`weapon`?`${t.name} - ${t.cls}. ${t.dmg}${t.pellets>1?`x`+t.pellets:``} damage, ${t.rpm} RPM, ${t.mag} round magazine. ${t.slot===`primary`?`Primary`:`Secondary`} slot.`:`${t.name} - ${t.desc}`}function y(e){V&&!V.over&&(V.invOpen=!0,V.invPile=e,z.mdown=!1,e.kind===`cache`&&e.items.some(Boolean)&&P.pickup(),_(`Drag items between the panels. Double-click to quick-move. Right-click a medical item to use it.`),G(`inv`).classList.add(`on`),h())}function b(){if(!V||!V.invOpen)return;let e=V.invPile;e.virtual&&e.items.some(Boolean)&&(e.virtual=!1,e.kind=`drop`,V.piles.push(e)),V.piles=V.piles.filter(e=>e.kind===`cache`||e.items.some(Boolean)),V.invOpen=!1,V.invPile=null,x(),G(`inv`).classList.remove(`on`),Xt()}function x(){e&&e.cell.classList.remove(`src`),e=null,t.style.display=`none`;for(let e of document.querySelectorAll(`.cell.ok, .cell.no`))e.classList.remove(`ok`,`no`)}let S=G(`inv`);return S.addEventListener(`pointerdown`,t=>{if(t.button!==0)return;let r=t.target.closest(`.cell`);r&&r.dataset.ref&&n(r.dataset.ref)&&(e={ref:r.dataset.ref,cell:r,x0:t.clientX,y0:t.clientY,moved:!1},t.preventDefault())}),window.addEventListener(`pointermove`,r=>{if(!V||!V.invOpen)return;if(!e){let e=r.target.closest&&r.target.closest(`.cell`),t=e&&e.dataset.ref&&n(e.dataset.ref);t&&!G(`invTip`).classList.contains(`bad`)&&_(v(t));return}if(!e.moved&&Math.hypot(r.clientX-e.x0,r.clientY-e.y0)<4)return;e.moved||(e.moved=!0,e.cell.classList.add(`src`),t.innerHTML=e.cell.innerHTML,t.className=`cell ghost`+(e.cell.classList.contains(`wpn`)?` wpn`:``),t.style.display=`flex`),t.style.left=`${r.clientX-t.offsetWidth/2}px`,t.style.top=`${r.clientY-t.offsetHeight/2}px`;for(let e of document.querySelectorAll(`.cell.ok, .cell.no`))e.classList.remove(`ok`,`no`);let i=document.elementFromPoint(r.clientX,r.clientY),o=i&&i.closest(`#inv .cell[data-ref]`);if(o&&o!==e.cell){let t=n(e.ref),r=n(o.dataset.ref);o.classList.add(a(o.dataset.ref,t)&&(!r||a(e.ref,r))?`ok`:`no`)}}),window.addEventListener(`pointerup`,t=>{if(!e)return;if(e.moved){let i=document.elementFromPoint(t.clientX,t.clientY),a=i&&i.closest(`#inv .cell[data-ref]`);if(a)l(e.ref,a.dataset.ref);else if(i&&i.closest(`#invRight`)){let t=n(e.ref);if(e.ref.startsWith(`loot`)){if(t.type===`weapon`)l(e.ref,r[t.id].slot===`primary`?`w:0`:`w:1`);else{let n=p(t);n>=0?l(e.ref,`i:`+n):(_(`Inventory full`,!0),P.deny())}}}else e.ref.startsWith(`loot`)||u(e.ref);f={ref:null,t:0},x(),h();return}let i=e.ref,a=performance.now();x(),f.ref===i&&a-f.t<400?(f={ref:null,t:0},d(i)):f={ref:i,t:a}}),S.addEventListener(`contextmenu`,e=>{e.preventDefault();let t=e.target.closest(`.cell`);if(!t||!t.dataset.ref||!t.dataset.ref.startsWith(`i:`))return;let n=V.player,r=+t.dataset.ref.slice(2),i=n.items[r];i&&o[i.id].kind===`medical`&&(n.hp>=100?(_(`Health is already full`,!0),P.deny()):(n.reloadT=0,n.equip=`medical`,n.itemSlot=r,n.useSlot=r,n.useT=n.useMax=o[i.id].use,P.useMed(i.id),b()))}),G(`invClose`).addEventListener(`click`,()=>b()),{open:y,close:b,render:h}})();f((e,t)=>{z.keys[e]=t},e=>{if(W===`play`&&V&&!V.over){if(V.invOpen){(e===`KeyF`||e===`Escape`||e===`KeyI`)&&Fr.close();return}switch(e){case`Digit1`:Jt(`primary`);break;case`Digit2`:Jt(`secondary`);break;case`Digit3`:Jt(`throwable`);break;case`Digit4`:Jt(`medical`);break;case`KeyR`:Zt();break;case`KeyQ`:fn();break;case`KeyF`:Hn();break;case`KeyI`:Un();break;case`KeyP`:case`Escape`:$.pause()}}else W===`paused`&&(e===`Escape`||e===`KeyP`)&&$.resume()},()=>{z.keys=Object.create(null),z.mdown=!1}),window.addEventListener(`mousemove`,e=>{z.mx=e.clientX,z.my=e.clientY}),Oe.addEventListener(`mousedown`,e=>{e.button===0&&(P.init(),z.mdown=!0,z.clicked=!0)}),window.addEventListener(`mouseup`,e=>{e.button===0&&(z.mdown=!1)}),Oe.addEventListener(`contextmenu`,e=>e.preventDefault()),window.addEventListener(`resize`,qe);for(let e of document.querySelectorAll(`[data-go]`))e.addEventListener(`click`,()=>{P.init(),P.click();let t=e.dataset.go;t===`deploy`?$.deploy():t===`restart`?V&&V.campaign?(yr(),$.deployCampaign()):$.deploy():t===`quit`?(V&&V.campaign&&yr(),$.menu()):t===`campaign`?$.campaign():t===`campaign-next`?$.deployCampaign():t===`character`?(W=`character`,V=null,jr(),$.show(`character`)):t===`maps`?(W=`maps`,V=null,Nr(),$.show(`maps`)):t===`shop`?(W=`shop`,V=null,Pr(),$.show(`shop`)):t===`loadout`?(W=`loadout`,V=null,Or(),$.show(`loadout`)):t===`menu`?$.menu():t===`resume`&&$.resume()});qe(),$.menu(),requestAnimationFrame(pr);let Ir=()=>JSON.stringify([J.unlocked,J.armours,J.levels,J.armourLevels]),Lr=Ir();G(`shop`).addEventListener(`click`,()=>{let e=Ir();e!==Lr&&(Lr=e,window.dispatchEvent(new Event(`blacksite:armory`)))});let Rr=null,zr=()=>({character:Z,loadout:{...q},equippedArmor:Rr||J.armour||null,difficulty:xr,map:mr}),Br=JSON.stringify(zr()),Vr=e=>{e.target.closest&&e.target.closest(`[data-armour]`)&&(Rr=null);let t=JSON.stringify(zr());t!==Br&&(Br=t,window.dispatchEvent(new Event(`blacksite:customization`)))};for(let e of[`character`,`loadout`,`maps`,`shop`])G(e).addEventListener(`click`,Vr);G(`diffSlider`).addEventListener(`input`,Vr);let Hr=$.show;$.show=function(e){Hr.call($,e),window.dispatchEvent(new CustomEvent(`blacksite:screen`,{detail:e}))};let Ur=()=>{let e=document.querySelector(`.screen.on`)?.id;$.menu(),e&&e!==`menu`&&Hr.call($,e)};return{isSafe:()=>V===null,profile:()=>br(J),customization:()=>br(zr()),applyCustomization(e){if(V!==null)throw Error(`game-busy`);Z=e.character,q={...e.loadout},xr=e.difficulty,mr=e.map,Rr=e.equippedArmor&&!J.armours.includes(e.equippedArmor)?e.equippedArmor:null,J.armour=Rr?null:e.equippedArmor,K.set(`blacksite.character`,Z),K.set(`blacksite.loadout`,q),K.set(`blacksite.difficulty`,xr),K.set(`blacksite.map`,mr),_r(),Br=JSON.stringify(zr()),W===`menu`?Ur():W===`character`?jr():W===`loadout`?Or():W===`maps`?Nr():W===`shop`&&Pr()},applyArmory(e){if(V!==null)throw Error(`game-busy`);J.unlocked=[...e.unlockedThrowables],J.armours=[...e.ownedArmors],J.levels={...e.weaponLevels},J.armourLevels={...e.armorLevels},Rr&&J.armours.includes(Rr)&&(J.armour=Rr,Rr=null),Lr=Ir(),Br=JSON.stringify(zr()),_r(),W===`shop`?Pr():W===`loadout`?Or():W===`menu`&&Ur()},reloadSaves(){if(V!==null)throw Error(`game-busy`);for(let e of Object.keys(J))delete J[e];Object.assign(J,{bank:0,levels:{},armours:[],armour:null,unlocked:[],armourLevels:{},armourBonus:{}},K.get(`blacksite.profile`,{})),q=K.get(`blacksite.loadout`,null)||{primary:`m4a1`,secondary:`m1911`,throwable:`frag`},i.includes(q.primary)||(q.primary=`m4a1`),a.includes(q.secondary)||(q.secondary=`m1911`),s.includes(q.throwable)||(q.throwable=null),mr=K.get(`blacksite.map`,`town`),e.some(e=>e.id===mr)||(mr=`town`),X=K.get(`blacksite.campaign`,null),Z=K.get(`blacksite.character`,`assaulter`),p[Z]||(Z=`assaulter`),xr=K.get(`blacksite.difficulty`,`normal`),u[xr]||(xr=`normal`),yr(),Rr=null,Br=JSON.stringify(zr()),Lr=Ir(),$.menu()}}}async function m(e){let t;try{return await Promise.race([e(),new Promise((e,n)=>{t=setTimeout(()=>n(Error(`timeout`)),5e3)})])}finally{clearTimeout(t)}}function h(e){let t=0,n=!1,r,a=(t,r,i,a=``)=>{n||e({pubkey:t,name:r,picture:a,status:i})};async function o(e,r){try{let o=await m(async()=>{if(l(`common`)){let t=await s.getProfile(e);if(!t.ok||t.pubkey!==e)throw Error(`profile unavailable`);return t.profile}return await i.getProfile()});if(r!==t||n)return;let c=o,u=[c?.display_name,c?.displayName,c?.name].find(e=>typeof e==`string`&&e.trim());a(e,typeof u==`string`?u.trim().slice(0,120):``,o?`Signed in`:`Signed in · Player profile not set`,typeof c?.picture==`string`?c.picture:``)}catch{r===t&&a(e,``,`Signed in · Player profile unavailable`)}}function c(e){let r=++t;n||(e?/^[a-f0-9]{64}$/i.test(e)?(a(e,``,`Signed in · Loading player profile…`),o(e,r)):a(``,``,`Player account unavailable`):a(``,``,`Playing as guest`))}async function u(){let e=++t;if(!n){if(!l(`identity`))a(``,``,`Player account unavailable`);else{a(``,``,`Checking player account…`);try{let r=await m(()=>i.getPublicKey());e===t&&!n&&c(r)}catch{e===t&&a(``,``,`Could not load player account`)}}}}if(l(`identity`))try{r=i.onChanged(c)}catch{}return u(),{refresh:u,close(){n=!0,++t;try{r?.close()}catch{}}}}function g(){let e=document.createElement(`section`);e.className=`help-sync`,e.setAttribute(`aria-labelledby`,`helpSyncHeading`);let t=(t,n)=>{let r=document.createElement(t);return r.textContent=n,e.append(r),r},n=t=>{let n=document.createElement(`ul`);for(let e of t){let t=document.createElement(`li`);t.textContent=e,n.append(t)}e.append(n)};return t(`h3`,`ACCOUNT SYNC`).id=`helpSyncHeading`,t(`p`,`Your progress always saves on this device first. Sync is optional: it copies your progress to your player account so you can continue on another device.`),n([`Armory sync saves your permanent unlocks and upgrades.`,`Player choice sync saves your character, loadout, equipped armor, difficulty and map.`,`Turn sync on from PLAYER ACCOUNT or ARMORY while signed in. Each save asks for your approval, and saved account data is public.`,`Loading your account armory combines it with this device, so unlocks are never lost. If another device saved in the meantime, save again.`]),t(`h4`,`WHY SYNC MAY BE UNAVAILABLE`),t(`p`,`Black Site runs inside a host app (the runtime). Sync only works when that host provides everything it needs. Otherwise the game shows "This runtime does not support the features needed for sync." and keeps playing with device saves only.`),n([`A signed-in player account (identity).`,`Reading and publishing your account events (outbox).`,`App data storage (soy.app-data/1) with a storage relay chosen in the host’s Network settings.`]),t(`p`,`To use sync, open Black Site in a host that supports these features, sign in, and make sure a storage relay is set. Nothing on this device is removed while sync is unavailable.`),e}function _(e=()=>{}){let t=document.querySelector(`#menu .col`);if(!t)return;let n=(e,t)=>{let n=document.createElement(`section`);n.id=e,n.className=`screen account-screen`;let r=document.createElement(`div`);r.className=`lbar`;let i=document.createElement(`h2`);i.textContent=t;let a=document.createElement(`button`);return a.type=`button`,a.dataset.go=`menu`,a.textContent=`BACK`,r.append(i,a),n.append(r),document.body.append(n),{screen:n,back:a}},r=(e,t)=>{for(let t of document.querySelectorAll(`.screen`))t.classList.toggle(`on`,t===e);t.focus()},i=n(`howToPlay`,`HELP & HOW TO PLAY`),o=t.querySelector(`.hint`);o&&i.screen.append(o),i.screen.append(g());let s=document.createElement(`button`);s.type=`button`,s.id=`helpButton`,s.textContent=`HELP & HOW TO PLAY`,s.addEventListener(`click`,()=>r(i.screen,i.back)),t.append(s);let c=n(`playerAccount`,`PLAYER ACCOUNT`),u=document.createElement(`div`);u.className=`player-details`,u.setAttribute(`role`,`status`);let d=document.createElement(`div`);d.className=`user-name`;let f=document.createElement(`div`);f.className=`user-status`;let p=document.createElement(`span`);p.className=`player-avatar`,u.append(p,d,f),c.screen.append(u);let _=document.createElement(`button`);_.type=`button`,_.id=`currentUser`,_.setAttribute(`aria-controls`,`playerAccount`),_.addEventListener(`click`,()=>r(c.screen,c.back));let v=document.createElement(`span`);v.className=`player-avatar`;let y=document.createElement(`span`);y.className=`player-label`,_.append(v,y),t.append(_);let b=0,x,S,C=()=>{++b,S?.abort(),S=void 0,x&&URL.revokeObjectURL(x),x=void 0},w=async(e,t)=>{let n=new AbortController;S=n;try{let r=await m(()=>a.bytes(e,{signal:n.signal}));if(t!==b||!/^image\/(png|jpeg|webp|gif)$/.test(r.type))return;x=URL.createObjectURL(r);for(let e of[v,p]){let n=document.createElement(`img`);n.alt=``,n.src=x,n.addEventListener(`load`,()=>{t===b&&e.replaceChildren(n)},{once:!0})}}catch{}finally{n.abort(),S===n&&(S=void 0)}},T=()=>h(t=>{t.status!==`Checking player account…`&&e(t.pubkey);let n=t.name||(t.pubkey?`Player`:`Guest player`);y.textContent=n,C();let r=t.name?t.name.split(/\s+/).slice(0,2).map(e=>e[0]).join(``).toUpperCase():`P`;for(let e of[v,p])e.textContent=r;t.picture&&l(`resource`)&&w(t.picture,b),_.setAttribute(`aria-label`,`Player account: ${n}`),d.textContent=n,f.textContent=t.status}),E=T();window.addEventListener(`pagehide`,()=>{E.close(),C()}),window.addEventListener(`pageshow`,e=>{e.persisted&&(E=T())});for(let[e,t]of[[i,s],[c,_]])e.back.addEventListener(`click`,()=>t.focus()),e.screen.addEventListener(`keydown`,t=>{t.key===`Escape`&&(t.preventDefault(),e.back.click())})}async function v(e,t=8e3){let n;try{return await Promise.race([e(),new Promise((e,r)=>{n=setTimeout(()=>r(Error(`operation-timeout`)),t)})])}finally{clearTimeout(n)}}var y=[`profile`,`loadout`,`map`,`best`,`campaign`,`difficulty`,`character`,`armorySync`,`customizationSync`];function b(e=()=>{}){let t=new Map,r=new Map,i=l(`storage`),a={owner:``,values:new Map,unreadable:new Set,saveFailed:!1},o=(e,t)=>e?`blacksite.account.${e}.${t}`:`blacksite.${t}`;function s(t,a,s){if(!i||t.unreadable.has(a)){t.saveFailed=!0,e();return}let c=o(t.owner,a),l=(r.get(c)??Promise.resolve()).then(async()=>{let r=Promise.resolve().then(()=>n.setItem(c,s));try{await v(()=>r,3e3)}catch{t.saveFailed=!0,e()}await r.catch(()=>void 0)});r.set(c,l),l.finally(()=>{r.get(c)===l&&r.delete(c)})}async function c(e){if(e&&!/^[a-f0-9]{64}$/.test(e))throw Error(`invalid-account`);let r=t.get(e);if(r)return r;let a=(async()=>{let t={owner:e,values:new Map,unreadable:new Set,saveFailed:!i};return i&&await Promise.all(y.map(async r=>{try{let i=await v(()=>n.getItem(o(e,r)),3e3);if(i!==null&&typeof i!=`string`)throw Error(`invalid-save`);typeof i==`string`&&(JSON.parse(i),t.values.set(r,i))}catch{t.unreadable.add(r),t.saveFailed=!0}})),t})();return t.set(e,a),a}let u=e=>e.replace(/^blacksite\./,``),d=(e,t,n=a)=>{try{return JSON.parse(n.values.get(u(e))??`null`)??t}catch{return t}};return{load:c,activate(e){a=e},owner:()=>a.owner,bucket:()=>a,get:d,set:(e,t,n=a)=>{let r=u(e),i=JSON.stringify(t);n.values.set(r,i),s(n,r,i)},preferences:()=>{let e=d(`blacksite.armorySync`,{});return{enabled:e?.enabled===!0,imported:e?.imported===!0}},async guestChoices(){let e=await c(``);return{character:d(`blacksite.character`,`assaulter`,e),loadout:d(`blacksite.loadout`,{primary:`m4a1`,secondary:`m1911`,throwable:`frag`},e),equippedArmor:d(`blacksite.profile`,{},e).armour??null,difficulty:d(`blacksite.difficulty`,`normal`,e),map:d(`blacksite.map`,`town`,e)}},async guestProfile(){return d(`blacksite.profile`,{},await c(``))},flush:()=>Promise.all([...r.values()])}}var x={weapons:[`m4a1`,`ak47`,`mp5`,`spas12`,`barrett`,`m249`,`m1911`,`glock18`,`deagle`,`magnum`],throwables:[`frag`,`molotov`,`flash`,`smoke`],armors:[`soft`,`l1`,`l2`,`l3`,`l4`],maxWeaponLevel:20,maxArmorLevel:10,primary:[`m4a1`,`ak47`,`mp5`,`spas12`,`barrett`,`m249`],secondary:[`m1911`,`glock18`,`deagle`,`magnum`],characters:[`assaulter`,`gunner`,`sniper`,`cutthroat`,`hauler`],difficulties:[`hard`,`normal`,`easy`],maps:[`town`,`docks`,`desert`,`snow`,`refinery`]},S=()=>({unlockedThrowables:[],ownedArmors:[],weaponLevels:{},armorLevels:{}});function C(e){if(!e||typeof e!=`object`||Array.isArray(e)||![Object.prototype,null].includes(Object.getPrototypeOf(e)))throw Error(`armory-invalid`);return e}function w(e,t){if(!Array.isArray(e)||e.length>t.length||e.some(e=>typeof e!=`string`||!t.includes(e))||new Set(e).size!==e.length)throw Error(`armory-invalid`);return[...e].sort()}function T(e,t,n){let r={};for(let[i,a]of Object.entries(C(e)).sort(([e],[t])=>e.localeCompare(t))){if(!t.includes(i)||typeof a!=`number`||!Number.isSafeInteger(a)||a<0||a>n)throw Error(`armory-invalid`);a&&(r[i]=a)}return r}function E(e){let t=C(e);if(Object.keys(t).sort().join(`,`)!==`armorLevels,ownedArmors,unlockedThrowables,weaponLevels`)throw Error(`armory-invalid`);let n={unlockedThrowables:w(t.unlockedThrowables,x.throwables),ownedArmors:w(t.ownedArmors,x.armors),weaponLevels:T(t.weaponLevels,x.weapons,x.maxWeaponLevel),armorLevels:T(t.armorLevels,x.armors,x.maxArmorLevel)};if(Object.keys(n.armorLevels).some(e=>!n.ownedArmors.includes(e)))throw Error(`armory-invalid`);return n}function ee(e){let t=C(e);return E({unlockedThrowables:t.unlocked??[],ownedArmors:t.armours??[],weaponLevels:t.levels??{},armorLevels:t.armourLevels??{}})}function D(e,t){let n=(e,t)=>Object.fromEntries([...new Set([...Object.keys(e),...Object.keys(t)])].sort().map(n=>[n,Math.max(e[n]??0,t[n]??0)]));return E({unlockedThrowables:[...new Set([...e.unlockedThrowables,...t.unlockedThrowables])],ownedArmors:[...new Set([...e.ownedArmors,...t.ownedArmors])],weaponLevels:n(e.weaponLevels,t.weaponLevels),armorLevels:n(e.armorLevels,t.armorLevels)})}var O=e=>JSON.stringify(E(e)),te=`soy.app-data/1`,ne=30078,k=/^[a-f0-9]{64}$/;function re(e,t,n){if(typeof e!=`string`||typeof t!=`string`||typeof n!=`string`||!k.test(e)||!/^[a-z][a-z0-9_-]{0,47}$/.test(t)||!/^[a-zA-Z0-9_-]{1,64}$/.test(n))throw Error(`app-data-invalid-id: use a collection name and a stable record ID.`);return`${te}:${e}:${t}:${n}`}function ie(e){let t=0,n=new Set,r=(e,i)=>{if(++t>4096||i>12)throw Error(`app-data-too-complex: simplify the data or use Blossom.`);if(e!==null&&typeof e!=`boolean`&&!(typeof e==`number`&&Number.isFinite(e))&&!(typeof e==`string`&&e.length<=16384)){if(typeof e!=`object`||!e||n.has(e))throw Error(`app-data-invalid-json: data must contain only finite JSON values.`);if(n.add(e),Array.isArray(e)){if(e.length>1024)throw Error(`app-data-too-complex: arrays are limited to 1024 items.`);for(let t of e)r(t,i+1)}else{if(Object.getPrototypeOf(e)!==Object.prototype&&Object.getPrototypeOf(e)!==null)throw Error(`app-data-invalid-json: use plain JSON objects.`);let t=Object.keys(e);if(t.length>128||t.some(e=>e.length>128||[`__proto__`,`constructor`,`prototype`].includes(e)))throw Error(`app-data-invalid-json: invalid object keys or too many fields.`);for(let n of t)r(e[n],i+1)}n.delete(e)}};r(e,0)}function ae(e,t,n,r,i){return[[`d`,re(e,t,n)],[`s`,e],[`c`,t],[`L`,te],[`l`,r,te],[`v`,String(i)]]}function A(e){if(e.kind!==30078||typeof e.content!=`string`||new TextEncoder().encode(e.content).length>16384)throw Error(`app-data-invalid-record: expected a kind-30078 record of at most 16 KiB.`);let t;try{t=JSON.parse(e.content)}catch{throw Error(`app-data-invalid-json: record content must be JSON.`)}if(ie(t),!t||Array.isArray(t)||typeof t!=`object`||Object.keys(t).sort().join(`,`)!==`data,deleted,previous,schema,title,version`||typeof t.schema!=`string`||!/^[a-zA-Z0-9][a-zA-Z0-9._/-]{0,95}$/.test(t.schema)||!Number.isSafeInteger(t.version)||t.version<1||t.version>1e6||typeof t.title!=`string`||!t.title.trim()||t.title.length>160||/[\u0000-\u001f\u007f\u202a-\u202e\u2066-\u2069]/.test(t.title)||t.previous!==null&&(typeof t.previous!=`string`||!k.test(t.previous))||typeof t.deleted!=`boolean`||t.deleted&&(t.data!==null||t.previous===null))throw Error(`app-data-invalid-record: check schema, version, title, previous revision and deletion fields.`);if(!Array.isArray(e.tags)||e.tags.length!==6)throw Error(`app-data-invalid-tags: use the documented application-data tags.`);let n=e.tags.find(e=>e[0]===`d`)?.[1]??``,r=n.split(`:`),[i,a,o,s]=r;if(r.length!==4||i!==`soy.app-data/1`)throw Error(`app-data-invalid-id: unsupported record identifier.`);if(!ae(a,o,s,t.schema,t.version).every(t=>e.tags.filter(e=>JSON.stringify(e)===JSON.stringify(t)).length===1))throw Error(`app-data-invalid-tags: record tags must match its schema and namespace.`);return{scope:a,collection:o,id:s,identifier:n,body:t}}async function j(e){let t=e.host??globalThis.napplet;if(!t?.shell?.onReady||!t.outbox||!t.identity)throw Error(`app-data-unavailable: this host needs shell, outbox and identity support.`);let n=await new Promise((e,n)=>{let r,i=!1,a=setTimeout(()=>{r?.close(),n(Error(`app-data-unavailable: host initialization did not finish. Keep drafts locally and retry.`))},5e3);r=t.shell.onReady(t=>{i=!0,clearTimeout(a),r?.close(),e(t.capabilities?.appData)}),i&&r.close()});if(n?.profile!==`soy.app-data/1`)throw Error(`app-data-unavailable: update soyLI or use a host supporting soy.app-data/1. Keep drafts locally.`);let r=e.relays??n.defaultRelays;if(!Array.isArray(r)||!r.length||r.length>8)throw Error(`app-data-no-relays: choose a storage relay in host Network settings.`);re(n.scope,e.collection,`check`),A({kind:ne,tags:ae(n.scope,e.collection,`check`,e.schema,e.version),content:JSON.stringify({schema:e.schema,version:e.version,title:`Check`,previous:null,deleted:!1,data:null})});let i=t=>{let{scope:n,collection:r,id:i,body:a}=A(t);if(a.schema!==e.schema||a.version!==e.version||r!==e.collection)throw Error(`app-data-incompatible: this record uses another collection or schema version.`);return{id:i,author:t.pubkey,scope:n,collection:r,title:a.title,revision:t.id,createdAt:t.created_at,deleted:a.deleted,data:a.deleted?null:e.validate(a.data),event:t}},a=async e=>{let n=await t.outbox.query(e,{relays:r,timeoutMs:8e3});if(n.error)throw Error(n.error);return n},o=e=>e.sort((e,t)=>t.created_at-e.created_at||e.id.localeCompare(t.id));return{policy:n,relays:r,async list(t={}){let r=t.scope??n.scope;re(r,e.collection,`check`);let s=t.limit??40;if(!Number.isSafeInteger(s)||s<1||s>100||t.until!==void 0&&(!Number.isSafeInteger(t.until)||t.until<0))throw Error(`app-data-invalid-query: limit must be 1–100 and until a Unix timestamp.`);let c=await a([{kinds:[ne],"#s":[r],"#c":[e.collection],"#L":[te],limit:s,...t.until===void 0?{}:{until:t.until}}]),l=new Map;for(let{event:t}of c.events){let n=t.tags.find(e=>e[0]===`d`)?.[1];if(t.kind!==30078||!n?.startsWith(`soy.app-data/1:${r}:${e.collection}:`))continue;let i=`${t.pubkey}:${n}`,a=l.get(i);a&&o([a,t])[0]!==t||l.set(i,t)}let u=o([...l.values()]).slice(0,s),d=[],f=0;for(let e of u)try{let t=i(e);t.deleted||d.push(t)}catch{f++}return{records:d,incomplete:!!c.incomplete,invalid:f,nextUntil:u.length>=s?u.at(-1).created_at:null}},async get(t,r,s=n.scope){if(!/^[a-f0-9]{64}$/.test(t))throw Error(`app-data-invalid-author: expected a public key.`);let c=re(s,e.collection,r),l=await a([{kinds:[ne],authors:[t],"#d":[c],limit:1}]),u=o(l.events.map(e=>e.event).filter(e=>e.kind===30078&&e.pubkey===t&&e.tags.some(e=>e[0]===`d`&&e[1]===c)))[0];return{record:u?i(u):null,incomplete:!!l.incomplete}},async prepare(a){let o=await t.identity.getPublicKey();if(!/^[a-f0-9]{64}$/.test(o))throw Error(`not-signed-in: connect a viewer identity to publish.`);let{base:s}=a;if(s&&(s.author!==o||s.scope!==n.scope||s.collection!==e.collection||s.id!==a.id))throw Error(`app-data-owner-mismatch: copy this creation to a new ID to make it your own.`);let c={schema:e.schema,version:e.version,title:a.title,previous:s?.revision??null,deleted:a.deleted??!1,data:null};if(!c.deleted){let t=e.validate(a.data);ie(t),c.data=t}let l={kind:ne,created_at:Math.max(Math.floor(Date.now()/1e3),(s?.createdAt??0)+1),tags:ae(n.scope,e.collection,a.id,e.schema,e.version),content:JSON.stringify(c)};if(A(l),new TextEncoder().encode(l.content).length>Math.min(n.maxContentBytes,16384))throw Error(`app-data-too-large: store the large payload on Blossom and publish its URL/hash.`);return{template:structuredClone(l),async publish(){if(await t.identity.getPublicKey()!==o)throw Error(`app-data-identity-changed: prepare the change again with the selected identity.`);let e=await t.outbox.publish(structuredClone(l),{relays:r,toOutbox:!1});if(!e.ok||!e.event)throw Error(e.error??`app-data-publish-failed: no signed record returned.`);if(e.event.pubkey!==o||e.event.kind!==l.kind||e.event.created_at!==l.created_at||e.event.content!==l.content||JSON.stringify(e.event.tags)!==JSON.stringify(l.tags))throw Error(`app-data-invalid-result: host returned a different record.`);return i(e.event)}}}}}function M(e,t){if(!e||typeof e!=`object`||Array.isArray(e)||Object.keys(e).sort().join(`,`)!==t)throw Error(`customization-invalid`);return e}function N(e,t){if(typeof e!=`string`||!t.includes(e))throw Error(`customization-invalid`);return e}function oe(e){let t=M(e,`character,difficulty,equippedArmor,loadout,map`),n=M(t.loadout,`primary,secondary,throwable`);return{character:N(t.character,x.characters),loadout:{primary:N(n.primary,x.primary),secondary:N(n.secondary,x.secondary),throwable:n.throwable===null?null:N(n.throwable,x.throwables)},equippedArmor:t.equippedArmor===null?null:N(t.equippedArmor,x.armors),difficulty:N(t.difficulty,x.difficulties),map:N(t.map,x.maps)}}var se=e=>JSON.stringify(oe(e));async function ce(e,t,n){if(!l(`identity`)||!l(`outbox`))throw Error(`app-data-unavailable`);let r=globalThis.napplet;if(!r?.shell?.onReady)throw Error(`app-data-unavailable`);return j({collection:e,schema:t,version:1,validate:n,host:{shell:r.shell,identity:{getPublicKey:()=>i.getPublicKey()},outbox:{query:(e,t)=>o.query(e,t),publish:(e,t)=>o.publish(e,t)}}})}var le=()=>ce(`player-armory`,`blacksite.armory`,E),ue=()=>ce(`player-customization`,`blacksite.customization`,oe);function de(e,t,n,r=le){let i=``,a=0,o,s=!1,c=!1,l=!1,u,d,f=!1,p=`Sign in to sync your armory`,m,h=()=>ee(t()?.profile()??e.get(`blacksite.profile`,{})),g=()=>e.preferences(),_=t=>t===a&&i!==``&&e.owner()===i,y=()=>{let r=i!==``&&e.owner()===i&&!!t()?.isSafe(),a=!1;try{a=O(h())!==d}catch{}n({supported:s,unsupported:c,message:p+(e.bucket().saveFailed?` · Device save unavailable`:``),busy:l,enabled:g().enabled,canEnable:r&&!!o&&!l&&!g().enabled,canSave:r&&!!o&&!l&&g().enabled&&(a||!!m),canImport:r&&s&&f&&!g().imported&&!l,canLoad:r&&s&&!l})};function b(){if(i!==e.owner()||!t()?.isSafe()||!u)return;let n=D(h(),u);u=void 0,O(n)!==O(h())&&t().applyArmory(n)}let x=e=>{let t=e instanceof Error?e.message:``;return/app-data-(unavailable|no-relays)/.test(t)?`This runtime does not support the features needed for sync.`:/incompatible|invalid|deleted/.test(t)?`Account armory cannot be loaded · Device progress kept`:/denied|reject|consent|permission/i.test(t)?`Account save not approved · Device progress kept`:/stale|conflict/i.test(t)?`Account changed on another device · Try saving again`:`Armory sync failed · Device progress kept. Try again`};async function C(e){if(!o){let t=await v(()=>r());if(!_(e))return;o=t,s=!0,c=!1}if(!_(e))return;let t=await v(()=>o.get(i,`progress`));if(_(e)){if(t.incomplete)throw Error(`armory-incomplete`);if(t.record?.deleted)throw Error(`armory-deleted`);return s=!0,c=!1,u=t.record?.data??S(),d=O(u),b(),t.record}}async function w(){if(l||!i||e.owner()!==i)return;let n=a;l=!0,p=`Loading account armory…`,y();try{await C(n),_(n)&&(p=t()?.isSafe()?O(h())===d?`Armory is up to date`:`Changes saved on this device · Ready to save to account`:`Account armory ready · Applies when you return to the menu`)}catch(e){_(n)&&(c=/app-data-(unavailable|no-relays)/.test(e instanceof Error?e.message:``),p=x(e))}finally{n===a&&(l=!1,y())}}return{async select(t){i=t;let n=++a;if(o=void 0,s=!1,c=!1,u=void 0,d=void 0,m=void 0,l=!1,f=!1,p=t?`Loading account armory…`:`Sign in to sync your armory`,y(),!t){l=!0,p=`Checking sync support…`,y();try{let e=await v(r);if(n!==a)return;o=e,s=!0,p=`Sign in to sync your armory`}catch{n===a&&(c=!0,p=`This runtime does not support the features needed for sync.`)}finally{n===a&&(l=!1,y())}return}if(e.owner()!==t)return;let h=!1;try{h=O(ee(await e.guestProfile()))!==O(S())}catch{}_(n)&&(f=h,await w())},suspend(){++a,i=``,s=!1,c=!1,u=void 0,m=void 0,o=void 0,l=!1,p=`Account changed · Player save switches after this mission`,y()},changed(){i&&i===e.owner()&&(p=`Changes saved on this device · Ready to save to account`),y()},menu(){b(),y()},restore:w,enable(){i&&e.owner()===i&&t()?.isSafe()&&o&&!l&&(e.set(`blacksite.armorySync`,{...g(),enabled:!0}),p=`Armory sync enabled · Ready to save to account`,y())},async importGuest(){if(!i||l||!t()?.isSafe()||g().imported)return;let n=a,r=ee(await e.guestProfile());_(n)&&t()?.isSafe()&&(t().applyArmory(D(h(),r)),e.set(`blacksite.armorySync`,{...g(),imported:!0}),p=`Device armory imported · Ready to save to account`,y())},async save(){if(l||!i||e.owner()!==i||!t()?.isSafe()||!g().enabled)return;let n=a,r=i;l=!0,p=`Saving armory to account…`,y();try{let e=await C(n);if(!_(n)||!t()?.isSafe())return;let i=h(),a=O(i);if(a===d){m=void 0,p=`Armory is up to date`;return}let s;if(s=m&&m.digest===a&&m.change.template.content&&JSON.parse(m.change.template.content).previous===(e?.revision??null)?m.change:await v(()=>o.prepare({id:`progress`,title:`Black Site armory`,data:i,base:e??null})),!_(n)||!t()?.isSafe())return;m={change:s,digest:a};let c=await v(()=>s.publish(),6e4);if(!_(n)||c.author!==r)return;d=a,m=void 0,p=O(h())===a?`Saved to account`:`Saved to account · Newer changes still on this device`}catch(e){_(n)&&(/stale|conflict|denied|consent|permission/i.test(e instanceof Error?e.message:``)&&(m=void 0),p=x(e))}finally{n===a&&(l=!1,y())}},close(){++a,i=``,o=void 0,u=void 0,m=void 0}}}function fe(e,t,n,r=ue){let i=``,a=0,o=!1,s,c=!1,l=!1,u,d,f,p=`Sign in to sync your player choices`,m=()=>{let t=e.get(`blacksite.customizationSync`,{});return{enabled:t?.enabled===!0,imported:t?.imported===!0,dirty:t?.dirty===!0}},h=t=>e.set(`blacksite.customizationSync`,{...m(),...t}),g=t=>t===a&&!!i&&i===e.owner(),_=()=>oe(t().customization()),y=()=>{let r=!!i&&i===e.owner()&&!!t()?.isSafe();n({supported:c,unsupported:l,message:p+(e.bucket().saveFailed?` · Device save unavailable`:``),busy:o,enabled:m().enabled,canEnable:r&&!!s&&!o&&!m().enabled,canSave:r&&!!s&&!o&&m().enabled&&(d!==se(_())||!!f),canLoad:r&&c&&!o,canImport:r&&c&&!m().imported&&!o})};function b(){if(!u||!t()?.isSafe()||i!==e.owner())return;let n=u;u=void 0,!m().dirty&&se(_())!==se(n)&&t().applyCustomization(n)}async function x(e){if(!s){let t=await v(r);if(!g(e))return;s=t,c=!0,l=!1}let t=await v(()=>s.get(i,`choices`));if(g(e)){if(t.incomplete)throw Error(`customization-incomplete`);if(t.record?.deleted)throw Error(`customization-deleted`);return c=!0,l=!1,d=t.record?.data?se(t.record.data):void 0,u=t.record?.data??void 0,b(),t.record}}let S=e=>{let t=e instanceof Error?e.message:``;return/unavailable|no-relays/.test(t)?`This runtime does not support the features needed for sync.`:/invalid|incompatible|deleted/.test(t)?`Account choices cannot be loaded · Device choices kept`:/stale|conflict/.test(t)?`Choices changed on another device · Try saving again`:/denied|consent|permission|reject/i.test(t)?`Account save not approved · Device choices kept`:`Player choice sync failed · Device choices kept. Try again`};async function C(){if(o||!i||i!==e.owner())return;o=!0;let t=a;p=`Loading player choices…`,y();try{await x(t),g(t)&&(p=m().dirty?`Device choices ready to save to account`:u?`Account choices ready · Applies when you return to the menu`:`Player choices are up to date`)}catch(e){g(t)&&(l=/app-data-(unavailable|no-relays)/.test(e instanceof Error?e.message:``),p=S(e))}finally{t===a&&(o=!1,y())}}return{async select(e){i=e;let t=++a;if(c=!1,l=!1,s=void 0,u=void 0,d=void 0,f=void 0,o=!1,p=e?`Loading player choices…`:`Sign in to sync your player choices`,y(),e)await C();else{o=!0,p=`Checking sync support…`,y();try{let e=await v(r);if(t!==a)return;s=e,c=!0,p=`Sign in to sync your player choices`}catch{t===a&&(l=!0,p=`This runtime does not support the features needed for sync.`)}finally{t===a&&(o=!1,y())}}},suspend(){++a,i=``,c=!1,l=!1,s=void 0,f=void 0,u=void 0,o=!1,p=`Account changed · Player save switches after this mission`,y()},changed(){i&&i===e.owner()&&(h({dirty:!0}),p=`Choices saved on this device · Ready to save to account`),y()},menu(){b(),y()},restore:C,enable(){i&&i===e.owner()&&t()?.isSafe()&&s&&!o&&(h({enabled:!0}),p=`Player choice sync enabled · Ready to save to account`,y())},async importGuest(){if(!i||o||!t()?.isSafe()||m().imported)return;let n=a,r=oe(await e.guestChoices());g(n)&&t()?.isSafe()&&(t().applyCustomization(r),h({imported:!0,dirty:!0}),p=`Device choices imported · Ready to save to account`,y())},async save(){if(o||!i||i!==e.owner()||!t()?.isSafe()||!m().enabled)return;let n=a;o=!0,p=`Saving player choices…`,y();try{let e=await x(n);if(!g(n)||!t()?.isSafe())return;let r=_(),i=se(r);if(i===d){f=void 0,h({dirty:!1}),p=`Player choices are up to date`;return}let a=f&&f.digest===i&&JSON.parse(f.change.template.content).previous===(e?.revision??null)?f.change:await v(()=>s.prepare({id:`choices`,title:`Black Site player choices`,data:r,base:e??null}));if(!g(n)||!t()?.isSafe()||(f={change:a,digest:i},await v(()=>a.publish(),6e4),!g(n)))return;d=i,f=void 0;let o=se(_())!==i;h({dirty:o}),p=o?`Saved to account · Newer choices still on this device`:`Choices saved to account`}catch(e){g(n)&&(/stale|conflict|denied|consent|permission/i.test(e instanceof Error?e.message:``)&&(f=void 0),p=S(e))}finally{n===a&&(o=!1,y())}},close(){++a,i=``,s=void 0,u=void 0,f=void 0}}}function pe(e,t=!1){let n=[];for(let r of t?[`playerAccount`]:[`playerAccount`,`shop`]){let i=document.getElementById(r);if(!i)continue;let a=document.createElement(`section`);a.className=`armory-sync`,a.dataset.syncGroup=t?`customization`:`armory`,a.setAttribute(`aria-label`,t?`Player choice sync`:`Armory sync`);let o=document.createElement(`h3`);o.textContent=t?`PLAYER CHOICE SYNC`:`ARMORY SYNC`;let s=document.createElement(`p`);s.setAttribute(`role`,`status`);let c=document.createElement(`p`);c.className=`sync-disclosure`,c.textContent=t?`Save your character, loadout, equipped armor, difficulty and map to your account. Account choices are public. Each save asks for your approval.`:`Save permanent unlocks and upgrades to your account for use on another device. Account progress is public. Each save asks for your approval.`;let l=document.createElement(`div`);l.className=`sync-actions`;let u=(e,t)=>{let n=document.createElement(`button`);return n.type=`button`,n.textContent=e,n.addEventListener(`click`,()=>{Promise.resolve().then(t).catch(()=>{s.textContent=`Armory sync failed · Device progress kept`})}),l.append(n),n},d=u(t?`ENABLE PLAYER CHOICE SYNC`:`ENABLE ARMORY SYNC`,()=>e().enable());d.dataset.sync=`enable`;let f=u(t?`SAVE PLAYER CHOICES`:`SAVE ARMORY TO ACCOUNT`,()=>e().save());f.dataset.sync=`save`;let p=u(t?`LOAD ACCOUNT CHOICES`:`LOAD ACCOUNT ARMORY`,()=>e().restore());p.dataset.sync=`load`;let m=u(t?`USE THIS DEVICE'S CHOICES`:`USE THIS DEVICE'S ARMORY`,()=>e().importGuest());m.dataset.sync=`import`,a.append(o,s,c,l),r===`shop`?i.querySelector(`.lbar`)?.after(a):i.append(a),n.push({panel:a,heading:o,buttons:l,status:s,disclosure:c,enable:d,save:f,load:p,importGuest:m})}return e=>{for(let r of n){r.panel.hidden=t&&e.unsupported,r.panel.classList.toggle(`sync-warning`,e.unsupported),r.heading.hidden=e.unsupported||!e.supported,r.buttons.hidden=e.unsupported||!e.supported||!e.busy&&!e.canEnable&&!e.canSave&&!e.canImport&&!e.canLoad,r.status.textContent=e.message,r.disclosure.hidden=e.unsupported||!e.supported||e.enabled,r.enable.hidden=!e.canEnable,r.save.hidden=!e.enabled,r.save.disabled=!e.canSave,r.load.disabled=!e.canLoad,r.importGuest.hidden=!e.canImport;for(let t of[r.enable,r.importGuest])t.disabled=e.busy}}}var me=b(()=>Ce.forEach(e=>e.menu()));globalThis.BLACKSITE_STORE={get:me.get,set:me.set};var he,ge=``,_e=!1,ve=!1,ye=!1,be=document.createElement(`div`);be.id=`accountLoading`,be.setAttribute(`role`,`status`),be.hidden=!0,be.textContent=`Loading player save…`,document.body.append(be),_(e=>{let t=/^[a-f0-9]{64}$/i.test(e)?e.toLowerCase():``;t!==ge&&(ge=t,we())});var xe=de(me,()=>he,pe(()=>xe)),Se=fe(me,()=>he,pe(()=>Se,!0)),Ce=[xe,Se];async function we(){if(he&&!_e){if(!he.isSafe())ye=!0,ge!==me.owner()&&!ve&&(ve=!0,Ce.forEach(e=>e.suspend()));else if(ge===me.owner()&&!ve)Ce.forEach(e=>e.menu()),ye&&(ye=!1,Ce.forEach(e=>{e.restore()}));else{_e=!0,be.hidden=!1,Ce.forEach(e=>e.suspend());try{let e=ge,t=await me.load(e);for(;e!==ge;)e=ge,t=await me.load(e);me.activate(t),he.reloadSaves(),ve=!1,ye=!1,Ce.forEach(t=>{t.select(e)})}finally{_e=!1,be.hidden=!0}ge!==me.owner()&&we()}}}window.addEventListener(`blacksite:screen`,()=>{we()}),window.addEventListener(`blacksite:armory`,()=>xe.changed()),window.addEventListener(`blacksite:customization`,()=>Se.changed()),window.addEventListener(`pagehide`,()=>Ce.forEach(e=>e.close())),window.addEventListener(`pageshow`,e=>{e.persisted&&Ce.forEach(e=>{e.select(me.owner()===ge?ge:``)})}),(async()=>{me.activate(await me.load(``)),he=p(),l(`identity`)&&ge?await we():Ce.forEach(e=>{e.select(``)})})();</script>
<style>:root{--acc:#a5d63f;--gold:#e8c547;--red:#e0402f;--txt:#e6eadf;--dim:#8c978a;--line:#ffffff1f;--panel:#0c0f0ced}*{box-sizing:border-box}html,body{height:100%;color:var(--txt);-webkit-user-select:none;user-select:none;background:#0b0c0d;margin:0;font-family:Bahnschrift,Arial Narrow,Segoe UI,sans-serif;overflow:hidden}#game{cursor:none;width:100%;height:100%;display:block;position:fixed;inset:0}.screen{z-index:5;display:none;position:fixed;inset:0}.screen.on{display:flex}button{font:inherit;cursor:pointer;color:var(--txt);border:1px solid var(--line);letter-spacing:4px;text-align:left;background:#141814d9;padding:14px 22px;transition:background .12s,border-color .12s,transform .12s,color .12s}button:hover{background:var(--acc);color:#10140c;border-color:var(--acc);transform:translate(4px)}button.big{padding:18px 26px;font-size:22px;font-weight:700}kbd{color:var(--txt);background:#00000059;border:1px solid #556052;border-radius:3px;padding:1px 7px;font-family:inherit}#menu{background:radial-gradient(at 75% 35%,#1f2c1b 0%,#0b0d0b 60%);align-items:safe center;padding:3vh 8vw;overflow-y:auto}#menu button{padding:11px 22px}#menu button.big{padding:14px 26px}#campaign{background:radial-gradient(at 40% 20%,#1f2a1b 0%,#0b0d0b 65%);flex-direction:column;padding:3vh 4vw;overflow-y:auto}#campaign .mcard{cursor:default}.mcard.done{opacity:.6}.mcard.done .lmeta{color:#7fe36a}.mcard.sel .lmeta{color:var(--acc)}.campbtns{gap:12px;margin-top:18px;display:flex;position:relative}.diff{max-width:420px;margin:4px 0 8px}.difflbl{letter-spacing:3px;color:var(--dim);margin-bottom:4px;font-size:13px}.difflbl b{letter-spacing:3px;margin-left:8px}.difflbl b.d-hard{color:var(--red)}.difflbl b.d-normal{color:var(--txt)}.difflbl b.d-easy{color:#7fe36a}#diffSlider{width:100%;accent-color:var(--acc);cursor:pointer;margin:0}.diffends{letter-spacing:2px;color:var(--dim);justify-content:space-between;font-size:11px;display:flex}#diffDesc{color:#a3ad9f;letter-spacing:.5px;margin-top:4px;font-size:12px}#character{background:radial-gradient(at 50% 20%,#1f2a1b 0%,#0b0d0b 65%);flex-direction:column;padding:3vh 4vw;overflow-y:auto}.charimg{background:radial-gradient(circle,#a5d63f1a,#0000 70%);height:120px;margin:0 auto 6px;image-rendering:auto!important;border:none!important;width:160px!important}.perks{color:#b7c0b3;margin:8px 0 0;padding-left:18px;font-size:13px;line-height:1.6}#maps{background:radial-gradient(at 50% 20%,#1c2219 0%,#0b0d0b 65%);flex-direction:column;padding:3vh 4vw;overflow-y:auto}.mgrid{grid-template-columns:repeat(auto-fill,minmax(290px,1fr));gap:12px;margin-top:14px;display:grid;position:relative}.mcard{border:1px solid var(--line);cursor:pointer;background:#101410e6;padding:12px;transition:border-color .12s,background .12s}.mcard:hover{border-color:#6d7a63}.mcard.sel{border-color:var(--acc);box-shadow:inset 3px 0 0 var(--acc);background:#28341ae6}.mcard img{width:100%;image-rendering:pixelated;border:1px solid #0009;margin-bottom:10px;display:block}#shop{background:radial-gradient(at 70% 20%,#1c2219 0%,#0b0d0b 65%);flex-direction:column;padding:3vh 4vw;overflow-y:auto}.funds{letter-spacing:3px;color:var(--dim);align-self:center;margin-right:12px}.funds b{color:#7fe36a;letter-spacing:1px;font-size:22px}.lcard button.buy{text-align:center;letter-spacing:2px;width:100%;margin-top:10px;padding:9px;font-size:13px}.lcard button.buy:hover{transform:none}.lcard button.buy:disabled{opacity:.35;cursor:not-allowed;color:var(--txt);border-color:var(--line);background:#141814d9}.lvlrow{letter-spacing:1px;grid-template-columns:90px 1fr;align-items:center;gap:8px;margin-top:8px;font-size:12px;display:grid}.lvlrow i{background:#ffffff14;height:6px;display:block}.lvlrow b{background:var(--gold);height:100%;display:block}.lvlrow b.ahp{background:#5f9fd6}#shop .lcard,.cell.locked{cursor:default}.lcard.locked{opacity:.45;cursor:not-allowed}.lcard.locked .lcls{color:var(--gold)}#aSlot .cell{height:84px}#aSlot .cell img{width:44px;height:44px}#menu:before,#loadout:before,#shop:before,#maps:before,#campaign:before,#character:before{content:"";pointer-events:none;background-image:linear-gradient(#a5d63f09 1px,#0000 1px),linear-gradient(90deg,#a5d63f09 1px,#0000 1px);background-size:40px 40px;position:absolute;inset:0}.col{flex-direction:column;gap:8px;max-width:560px;display:flex;position:relative}h1{letter-spacing:10px;margin:0;font-size:80px;font-weight:800;line-height:.9}h1 span{color:var(--acc)}.sub{letter-spacing:7px;color:var(--dim);margin:4px 0 12px;font-size:14px}.info{color:var(--dim);letter-spacing:2px;font-size:13px}.hint{color:#a3ad9f;letter-spacing:.5px;margin-top:10px;font-size:13px;line-height:1.85}#loadout{background:radial-gradient(at 30% 20%,#1a2418 0%,#0b0d0b 65%);flex-direction:column;padding:3vh 4vw;overflow-y:auto}.lbar{justify-content:space-between;align-items:baseline;margin-bottom:10px;display:flex;position:relative}.lbar h2{letter-spacing:8px;margin:0;font-size:40px}.lbar .btns{gap:10px;display:flex}.lbar button{padding:10px 18px}h3{letter-spacing:5px;color:var(--acc);margin:16px 0 8px;font-size:14px;font-weight:600;position:relative}.lgrid{grid-template-columns:repeat(auto-fill,minmax(250px,1fr));gap:10px;display:grid;position:relative}.lcard{border:1px solid var(--line);cursor:pointer;background:#101410e6;padding:12px 14px;transition:border-color .12s,background .12s}.lcard:hover{border-color:#6d7a63}.lcard.sel{border-color:var(--acc);box-shadow:inset 3px 0 0 var(--acc);background:#28341ae6}.lhead{justify-content:space-between;align-items:center;gap:8px;display:flex}.lhead img{width:120px;height:48px}.lhead img.sq{width:48px;height:48px}.lname{letter-spacing:1px;font-size:18px;font-weight:700}.lcls{color:var(--dim);letter-spacing:2px;text-transform:uppercase;font-size:12px}.stat{color:var(--dim);letter-spacing:1px;grid-template-columns:84px 1fr;align-items:center;gap:8px;margin-top:4px;font-size:11px;display:grid}.stat i{background:#ffffff14;height:5px;display:block}.stat b{background:var(--txt);height:100%;display:block}.lcard.sel .stat b{background:var(--acc)}.lmeta{color:var(--dim);letter-spacing:1px;margin-top:8px;font-size:11px}.ldesc{color:#b7c0b3;margin-top:8px;font-size:13px;line-height:1.4}.overlay{background:#060806b8;justify-content:center;align-items:center}.box{flex-direction:column;gap:10px;min-width:340px;display:flex}.box h2{letter-spacing:10px;margin:0 0 10px;font-size:48px}#endTitle.win{color:#7fe36a}#endTitle.lose{color:var(--red)}#endSub{color:var(--dim);letter-spacing:2px;margin:-6px 0 10px}#endStats{grid-template-columns:auto auto;gap:8px 50px;margin-bottom:20px;font-size:18px;display:grid}#endStats div:nth-child(odd){color:var(--dim);letter-spacing:3px;align-self:center;font-size:14px}#endStats div:nth-child(2n){text-align:right;font-weight:700}#inv{z-index:4;cursor:default;background:linear-gradient(90deg,#0507058c,#0507051a 35% 65%,#0507058c);display:none;position:fixed;inset:0}#inv.on{display:block}.ipanel{background:var(--panel);border:1px solid var(--line);width:360px;max-height:92vh;padding:16px;position:absolute;top:50%;overflow-y:auto;transform:translateY(-50%)}#invLeft{left:2.5vw}#invRight{right:2.5vw}.ititle{letter-spacing:5px;margin-bottom:4px;font-size:20px;font-weight:700}.isub{letter-spacing:2px;color:var(--dim);margin-bottom:12px;font-size:12px}#lootGrid{grid-template-columns:1fr 1fr;gap:8px;display:grid}#lootEmpty{color:var(--dim);letter-spacing:1px;margin-top:10px;font-size:13px}#iSlots{grid-template-columns:1fr 1fr;gap:8px;display:grid}.slotlbl{letter-spacing:3px;color:var(--acc);margin:8px 0 4px;font-size:11px}.cell{border:1px solid var(--line);cursor:grab;background:#ffffff09;flex-direction:column;justify-content:center;align-items:center;height:96px;padding:4px;display:flex;position:relative}.cell.wpn{height:104px}.cell img{pointer-events:none;width:56px;height:56px}.cell.wpn img{width:125px;height:50px}.cell .nm{letter-spacing:.5px;white-space:nowrap;text-overflow:ellipsis;max-width:100%;font-size:13px;font-weight:600;overflow:hidden}.cell .sb{color:var(--dim);letter-spacing:1px;font-size:11px}.cell.empty{cursor:default;background:repeating-linear-gradient(45deg,#ffffff05 0 6px,#0000 6px 12px)}.cell .ph{letter-spacing:3px;color:#4f584c;font-size:11px}.cell:not(.empty):hover{background:#ffffff0f;border-color:#6d7a63}.cell.src{opacity:.3}.cell.ok{border-color:var(--acc);background:#a5d63f24}.cell.no{border-color:var(--red);background:#e0402f24}.cell.ghost{z-index:20;pointer-events:none;border-color:var(--acc);cursor:grabbing;background:#1e241cf2;width:160px;display:none;position:fixed}#wSlots .cell{width:100%}.ihp{letter-spacing:2px;color:var(--dim);align-items:center;gap:10px;margin-top:14px;font-size:12px;display:flex}.ihp i{background:#00000080;flex:1;height:8px;display:block}.ihp b{background:var(--txt);height:100%;display:block}#invTip{text-align:center;color:#c8d0c4;background:#080a08cc;max-width:560px;min-height:18px;padding:8px 14px;font-size:14px;position:absolute;bottom:4vh;left:50%;transform:translate(-50%)}#invTip:empty{display:none}#invTip.bad{color:#ffb0a6;border:1px solid var(--red)}#invClose{padding:8px 18px;font-size:13px;position:absolute;top:3vh;left:50%;transform:translate(-50%)}#invClose:hover{transform:translate(-50%)}html,body,#app{height:100%}#tooSmall{z-index:50;text-align:center;color:#e6eadf;letter-spacing:2px;background:#0b0c0d;justify-content:center;align-items:center;padding:16px;font:600 14px/1.5 Bahnschrift,Arial Narrow,Segoe UI,sans-serif;display:none;position:fixed;inset:0}@media (width<=559px),(height<=379px){#tooSmall{display:flex}}#menu #currentUser{border-left:3px solid var(--acc);color:var(--acc);letter-spacing:1px;overflow-wrap:anywhere;align-items:center;gap:12px;min-height:44px;margin-top:12px;display:flex}#currentUser:after{content:"›";margin-left:auto}.player-label{overflow-wrap:anywhere;min-width:0}.player-avatar{width:40px;height:40px;color:var(--acc);border:1px solid var(--line);background:#26301e;flex:0 0 40px;justify-content:center;align-items:center;font-size:15px;display:inline-flex;overflow:hidden}.player-avatar img{object-fit:cover;width:100%;height:100%}.player-details .player-avatar{width:64px;height:64px;margin-bottom:12px}.account-screen{background:radial-gradient(at 75% 35%,#1f2c1b 0%,#0b0d0b 60%);flex-direction:column;padding:3vh 8vw;overflow-y:auto}.account-screen .lbar{flex-wrap:wrap;gap:16px}.account-screen .lbar h2{font-size:clamp(22px,4vw,36px)}#menu .hint{display:none}.account-screen .hint{max-width:760px;margin:0}.help-panel,.help-sync{border:1px solid var(--line);background:var(--panel);max-width:760px;margin:16px 0;padding:16px}.help-panel h3,.help-sync h3{margin-top:0}.help-panel h4,.help-sync h4{color:var(--gold);letter-spacing:2px;margin:20px 0 8px;font-size:13px}.help-panel p,.help-sync p,.help-sync li{letter-spacing:.5px;overflow-wrap:anywhere;margin:0 0 8px;font-size:14px;line-height:1.7}.help-sync ul{margin:8px 0;padding-left:20px}.help-sync li{margin-bottom:4px}.hint+.help-sync{margin-top:0}.control-groups{grid-template-columns:repeat(auto-fit,minmax(240px,1fr));gap:8px 24px;display:grid}.control-group h4{margin-top:8px}.control-group dl{margin:0}.control-group dl>div{border-top:1px solid #ffffff0f;align-items:baseline;gap:12px;padding:6px 0;display:flex}.control-group dt{white-space:nowrap;flex:none;width:124px}.control-group dd{color:var(--txt);margin:0;font-size:14px;line-height:1.5}.player-details{border-left:3px solid var(--acc);background:var(--panel);max-width:560px;padding:16px}.user-name{overflow-wrap:anywhere;color:var(--acc);font-size:22px}.user-status{color:var(--dim);margin-top:8px;font-size:14px;line-height:1.5}#currentUser:focus-visible,#helpButton:focus-visible,.account-screen button:focus-visible{outline:2px solid var(--acc);outline-offset:3px}#menu .col{flex-shrink:0;width:560px;min-width:min(420px,100%);max-width:100%}.armory-sync{border:1px solid var(--line);background:var(--panel);max-width:760px;margin:16px 0;padding:16px;position:relative}.armory-sync h3{margin-top:0}.armory-sync p{letter-spacing:.5px;font-size:14px;line-height:1.6}.sync-disclosure{color:var(--dim)}.sync-actions{flex-wrap:wrap;gap:10px;display:flex}.sync-actions button{letter-spacing:1px;min-height:44px;font-size:12px}.sync-actions button:focus-visible{outline:2px solid var(--acc);outline-offset:3px}.sync-actions button:disabled{opacity:.5;cursor:default;transform:none}.sync-actions button[hidden]{display:none}#accountLoading{z-index:30;background:var(--panel);justify-content:center;align-items:center;font-size:18px;display:flex;position:fixed;inset:0}#accountLoading[hidden],.armory-sync[hidden],.sync-actions[hidden]{display:none}.armory-sync.sync-warning{border-color:#e8c54759;padding:8px 12px}.sync-warning p{color:var(--gold);margin:0;font-size:12px}
/*$vite$:1*/</style>
</head>
<body>
<canvas id="game"></canvas>
<div id="menu" class="screen">
<div class="col">
<h1>BLACK<br><span>SITE</span></h1>
<div class="sub">TACTICAL EXTRACTION</div>
<div class="info" id="bank" style="color:#7fe36a;font-size:16px"></div>
<div class="info" id="menuChar"></div>
<div class="info" id="menuMap"></div>
<div class="info" id="menuLoadout"></div>
<div class="info" id="menuCampaign" style="color:var(--acc)"></div>
<div class="diff">
<div class="difflbl">DIFFICULTY <b id="diffName"></b></div>
<input type="range" id="diffSlider" min="0" max="2" step="1">
<div class="diffends"><span>HARD</span><span>NORMAL</span><span>EASY</span></div>
<div id="diffDesc"></div>
</div>
<div class="info" id="best" style="color:var(--gold)"></div>
<button class="big" data-go="deploy">DEPLOY</button>
<button class="big" data-go="campaign">CAMPAIGN</button>
<button data-go="maps">SELECT MAP</button>
<button data-go="character">CHARACTER</button>
<button data-go="loadout">LOADOUT</button>
<button data-go="shop">ARMORY</button>
<div class="hint">
<section class="help-panel" aria-labelledby="helpObjectiveHeading">
<h3 id="helpObjectiveHeading">OBJECTIVE</h3>
<p>You only see what's in your 100° field of view. Reach the helipad, press <kbd>F</kbd> to call the helicopter, survive until it lands, then board it with <kbd>F</kbd>.</p>
</section>
<section class="help-panel" aria-labelledby="helpControlsHeading">
<h3 id="helpControlsHeading">KEYBOARD & MOUSE CONTROLS</h3>
<div class="control-groups">
<section class="control-group">
<h4>MOVEMENT</h4>
<dl>
<div><dt><kbd>W</kbd> <kbd>A</kbd> <kbd>S</kbd> <kbd>D</kbd></dt><dd>Move</dd></div>
<div><dt><kbd>SHIFT</kbd></dt><dd>Sprint</dd></div>
<div><dt><kbd>MOUSE</kbd></dt><dd>Aim</dd></div>
</dl>
</section>
<section class="control-group">
<h4>COMBAT</h4>
<dl>
<div><dt><kbd>LEFT CLICK</kbd></dt><dd>Fire, throw or use the equipped item</dd></div>
<div><dt><kbd>R</kbd></dt><dd>Reload</dd></div>
<div><dt><kbd>Q</kbd></dt><dd>Knife (Cut Throat)</dd></div>
</dl>
</section>
<section class="control-group">
<h4>EQUIPMENT</h4>
<dl>
<div><dt><kbd>1</kbd></dt><dd>Primary weapon</dd></div>
<div><dt><kbd>2</kbd></dt><dd>Secondary weapon</dd></div>
<div><dt><kbd>3</kbd></dt><dd>Throwable</dd></div>
<div><dt><kbd>4</kbd></dt><dd>Medical</dd></div>
</dl>
</section>
<section class="control-group">
<h4>ACTIONS & MENUS</h4>
<dl>
<div><dt><kbd>F</kbd></dt><dd>Loot, call or board the helicopter</dd></div>
<div><dt><kbd>I</kbd></dt><dd>Inventory</dd></div>
<div><dt><kbd>P</kbd> / <kbd>ESC</kbd></dt><dd>Pause</dd></div>
</dl>
</section>
</div>
</section>
</div>
</div>
</div>
<div id="loadout" class="screen">
<div class="lbar">
<h2>LOADOUT</h2>
<div class="btns"><button data-go="menu">BACK</button><button data-go="deploy" style="border-color:var(--acc)">DEPLOY</button></div>
</div>
<h3>PRIMARY</h3>
<div class="lgrid" id="lPrimary"></div>
<h3>SECONDARY</h3>
<div class="lgrid" id="lSecondary"></div>
<h3>THROWABLE</h3>
<div class="lgrid" id="lThrow"></div>
</div>
<div id="campaign" class="screen">
<div class="lbar">
<h2>CAMPAIGN</h2>
<div class="btns"><div class="funds">FUNDS HOLD <b id="campHold"></b></div><button data-go="menu">BACK</button></div>
</div>
<div class="info" style="position:relative;line-height:1.7">Fight through all five maps in order. Your weapons and items carry over from map to map, and health and armour are restored after each one.
Kills and intel go into the funds hold (no time penalty in the campaign). Quitting or restarting a map partway through costs the hold $400. Clear all five to collect the hold plus a $3,000 bonus (scaled by difficulty). If you die, the campaign and its hold are lost.</div>
<div class="info" id="campStatus" style="position:relative;color:var(--gold);margin-top:10px"></div>
<div class="mgrid" id="campMaps"></div>
<div class="campbtns"><button class="big" id="campContinue">CONTINUE CAMPAIGN</button><button id="campNew">NEW CAMPAIGN</button></div>
</div>
<div id="character" class="screen">
<div class="lbar">
<h2>CHARACTER</h2>
<div class="btns"><button data-go="menu">BACK</button><button data-go="deploy" style="border-color:var(--acc)">DEPLOY</button></div>
</div>
<div class="info" style="position:relative">Pick who you deploy as. Each character has their own perks.</div>
<div class="mgrid" id="charGrid"></div>
</div>
<div id="maps" class="screen">
<div class="lbar">
<h2>SELECT MAP</h2>
<div class="btns"><button data-go="menu">BACK</button><button data-go="deploy" style="border-color:var(--acc)">DEPLOY</button></div>
</div>
<div class="info" style="position:relative">Green dot: insertion. H: extraction. Enemy positions are unknown until you deploy.</div>
<div class="mgrid" id="mapGrid"></div>
</div>
<div id="shop" class="screen">
<div class="lbar">
<h2>ARMORY</h2>
<div class="btns"><div class="funds">FUNDS <b id="shopFunds"></b></div><button data-go="menu">BACK</button><button data-go="loadout">LOADOUT</button><button data-go="deploy" style="border-color:var(--acc)">DEPLOY</button></div>
</div>
<div class="info" style="position:relative">Extract with intel to earn funds ($10 per kill). Every minute before you call extraction takes $50 off that mission's payout. Each weapon level adds +3% damage (the Barrett gets +2% fire rate instead). Level 20 weapons get a laser sight.</div>
<h3>WEAPON UPGRADES</h3>
<div class="lgrid" id="sWeapons"></div>
<h3>THROWABLES</h3>
<div class="lgrid" id="sThrow"></div>
<h3>BODY ARMOUR</h3>
<div class="lgrid" id="sArmour"></div>
</div>
<div id="pause" class="screen overlay">
<div class="box">
<h2>PAUSED</h2>
<button class="big" data-go="resume">RESUME</button>
<button id="pauseRestart" data-go="restart">RESTART MISSION</button>
<button id="pauseQuit" data-go="quit">QUIT TO MENU</button>
</div>
</div>
<div id="end" class="screen overlay">
<div class="box">
<h2 id="endTitle"></h2>
<div id="endSub"></div>
<div id="endStats"></div>
<button class="big camp" id="endContinue" data-go="campaign-next">CONTINUE CAMPAIGN</button>
<button class="big quick" data-go="deploy">REDEPLOY</button>
<button data-go="shop">ARMORY</button>
<button class="quick" data-go="loadout">LOADOUT</button>
<button data-go="menu">MAIN MENU</button>
</div>
</div>
<div id="inv">
<div class="ipanel" id="invLeft">
<div class="ititle" id="lootTitle">SUPPLY CACHE</div>
<div class="isub">DRAG ITEMS TO YOUR INVENTORY</div>
<div id="lootGrid"></div>
<div id="lootEmpty">Nothing here. Drag items here to drop them.</div>
</div>
<div class="ipanel" id="invRight">
<div class="ititle">INVENTORY</div>
<div class="isub">2 WEAPON SLOTS / 4 ITEM SLOTS</div>
<div id="wSlots"></div>
<div class="slotlbl">BODY ARMOUR</div>
<div id="aSlot"></div>
<div class="slotlbl">ITEMS</div>
<div id="iSlots"></div>
<div class="ihp">HEALTH <i><b id="invHp"></b></i> <span id="invHpTxt"></span></div>
</div>
<button id="invClose">CLOSE [F]</button>
<div id="invTip"></div>
</div>
<div id="ghost" class="cell ghost"></div>
<div id="tooSmall" role="status">Make the window bigger to play Black Site.</div>
</body>
</html>
