fiverunner 1.4.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -41,7 +41,7 @@ npx fiverunner test
|
|
|
41
41
|
|
|
42
42
|
## Resources of GitHub, in your browser
|
|
43
43
|
|
|
44
|
-
The playground runs the resources and servers of GitHub too, which `?gh=` and the name of a repository after its address name, such as [overextended/ox_target](https://dariushq.github.io/fiverunner/?gh=overextended/ox_target), [qbcore-fivem/qb-core](https://dariushq.github.io/fiverunner/?gh=qbcore-fivem/qb-core) or [Qbox-project/qbx_core](https://dariushq.github.io/fiverunner/?gh=Qbox-project/qbx_core), with `@` and a branch or a tag after the name, and the directory of a resource after a slash. It reads them from GitHub with the resources that they need, as far as it knows where those are: ox_lib, ox_target and ox_inventory, qb-core, qb-target, qb-weapons, qb-menu and qb-input, qbx_core and qbx_vehicles, es_extended and the tables of ESX, and PolyZone. Scripts that use the exports of a framework or of a target, without their manifests naming it, get it too, and ox_inventory gets Qbox when nothing brings a framework. A link brings others with `&with=owner/repo
|
|
44
|
+
The playground runs the resources and servers of GitHub too, which `?gh=` and the name of a repository after its address name, such as [overextended/ox_target](https://dariushq.github.io/fiverunner/?gh=overextended/ox_target), [qbcore-fivem/qb-core](https://dariushq.github.io/fiverunner/?gh=qbcore-fivem/qb-core) or [Qbox-project/qbx_core](https://dariushq.github.io/fiverunner/?gh=Qbox-project/qbx_core), with `@` and a branch or a tag after the name, and the directory of a resource after a slash. It reads them from GitHub with the resources that they need, as far as it knows where those are: ox_lib, ox_target and ox_inventory, qb-core, qb-target, qb-weapons, qb-menu and qb-input, qbx_core and qbx_vehicles, es_extended, skinchanger and the tables of ESX, and PolyZone. Scripts that use the exports of a framework or of a target, without their manifests naming it, get it too, and ox_inventory gets Qbox when nothing brings a framework. A link brings others with `&with=owner/repo`, once for each, or with commas between them.
|
|
45
45
|
|
|
46
46
|
Put its button in the README of your resource, and people run it with a click:
|
|
47
47
|
|
|
@@ -55,7 +55,7 @@ The playground gives the Markdown of the button of each repository that it runs.
|
|
|
55
55
|
|
|
56
56
|
## Testing resources
|
|
57
57
|
|
|
58
|
-
Start with a test that your resource or server starts without script errors, and a GitHub workflow that runs it on each push:
|
|
58
|
+
Start with a test that your resource or server starts without script errors, and that a player logs in with a character on servers of Qbox, QBCore and ESX, and a GitHub workflow that runs it on each push:
|
|
59
59
|
|
|
60
60
|
```bash
|
|
61
61
|
npx fiverunner init
|
|
@@ -151,7 +151,7 @@ Servers also get FiveM's own `io` and `os` libraries, its VFS and file permissio
|
|
|
151
151
|
|
|
152
152
|
## Differences from FiveM
|
|
153
153
|
|
|
154
|
-
FiveRunner follows FiveM's Windows server and its clients down to their error messages and their quirks. Where it differs, on purpose or for now, [docs/differences.md](docs/differences.md) says so.
|
|
154
|
+
FiveRunner follows FiveM's Windows server and its clients down to their error messages and their quirks. Where it differs, on purpose or for now, [docs/differences.md](docs/differences.md) says so. [docs/faq.md](docs/faq.md) answers what people ask first, such as whether it is a way to play without GTA V, which it is not.
|
|
155
155
|
|
|
156
156
|
## Clean room
|
|
157
157
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{t as e}from"./routes-DFIWFSAi.js";var t=`/__fiverunner/api/`;new TextDecoder;function n(e,t){let n=document.createElement(`label`);return n.append(t,e),n}function r(e,t){switch(e.type){case`TextBlock`:{let t=document.createElement(`p`);return t.textContent=e.text??``,t.classList.toggle(`large`,/large/i.test(e.size??``)),t.classList.toggle(`bold`,e.weight===`Bolder`),[t]}case`Input.Text`:case`Input.Number`:{let n=document.createElement(e.isMultiline?`textarea`:`input`);return n.placeholder=e.placeholder??``,n.value=e.value??``,n.ariaLabel=e.placeholder??e.id??``,t.set(e.id??``,()=>n.value),[n]}case`Input.Toggle`:{let r=document.createElement(`input`);r.type=`checkbox`;let i=e.valueOn??`true`;return r.checked=e.value===i,t.set(e.id??``,()=>r.checked?i:e.valueOff??`false`),[n(e.title??``,r)]}case`Input.ChoiceSet`:{let n=document.createElement(`select`);n.ariaLabel=e.id??``;for(let{title:t,value:r}of e.choices??[])n.add(new Option(t,r));return n.value=e.value??n.value,t.set(e.id??``,()=>n.value),[n]}case`Container`:case`Column`:return i(e.items??[],t);case`ColumnSet`:return i(e.columns??[],t);default:return}}function i(e,t){let n=e.map(e=>r(e,t));return n.every(e=>e!==void 0)?n.flat():void 0}function a(e,t){let n;try{n=JSON.parse(e)}catch{return}let r=new Map,a=i(n.body??[],r);if(a===void 0)return;let o=document.createElement(`form`);o.className=`adaptive`,o.addEventListener(`submit`,e=>e.preventDefault()),o.append(...a);for(let e of n.actions??[]){if(e.type!==`Action.Submit`)return;let n=document.createElement(`button`);n.textContent=e.title??`Submit`,n.addEventListener(`click`,()=>{let n=Object.fromEntries([...r].map(([e,t])=>[e,t()])),i=e.id===void 0?{}:{submitId:e.id};t(JSON.stringify({...n,...e.data,...i}))}),o.append(n)}return o}var o=[``,`red`,`green`,`yellow`,`blue`,`cyan`,`magenta`,``,`orange`,`gray`],s=2e3,c=class{element;constructor(e){this.element=e}add(e){this.entry(e.channel,e.text,`kind-${e.kind}`)}entry(e,t,n){let r=document.createElement(`div`);r.className=`line ${n}`;let i=document.createElement(`span`);i.className=`channel`,i.textContent=`[${e}] `,r.append(i,...u(t)),this.#e(r)}note(e){let t=document.createElement(`div`);t.className=`line note`,t.textContent=e,this.#e(t)}#e(e){let{element:t}=this,n=t.scrollHeight-t.scrollTop-t.clientHeight<4;for(t.append(e);t.childElementCount>s;)t.firstElementChild.remove();n&&(t.scrollTop=t.scrollHeight)}};function l(e){let t=[],n=0;return e.addEventListener(`keydown`,r=>{(r.key===`ArrowUp`||r.key===`ArrowDown`)&&(r.preventDefault(),n=Math.max(0,Math.min(t.length,n+(r.key===`ArrowUp`?-1:1))),e.value=t[n]??``)}),e=>{t.push(e),n=t.length}}function u(e){let t=[],n=``;for(let[r,i]of e.split(/\^(\d)/).entries())if(r%2==1)n=o[Number(i)]??``;else if(i!==``){let e=document.createElement(`span`);n!==``&&(e.className=`color-${n}`),e.textContent=i,t.push(e)}return t}var d=class{#e;#t;#n=new Map;constructor(e,t,n){this.#e=new c(e),this.#t=t.elements.namedItem(`target`);let r=t.elements.namedItem(`name`),i=t.elements.namedItem(`args`);t.addEventListener(`submit`,e=>{e.preventDefault();let t=f(this.#t.value);if(t===void 0||r.value.trim()===``)return;let a;try{a=JSON.parse(i.value.trim()===``?`[]`:i.value)}catch(e){this.#e.note(`The arguments are no JSON: ${String(e)}`);return}Array.isArray(a)?n.emit(r.value.trim(),a,t):this.#e.note(`The arguments are a JSON array, such as [100, "cash"]`)}),this.players([])}add({from:e,to:t,name:n,args:r}){this.#e.entry(`${this.#r(e)} -> ${this.#r(t)}`,`${n}(${r})`,`kind-event`)}note(e){this.#e.note(e)}players(e){this.#n.clear();for(let{client:t,name:n}of e)this.#n.set(t,n);let t=e.filter(({state:e})=>e===`joined`),n=[...t.map(({client:e,name:t})=>[`from:${e}`,`To the server, from ${t}`]),...t.map(({client:e,name:t})=>[`to:${e}`,`To ${t}, from the server`]),[`to:everyone`,`To every player, from the server`]],r=this.#t.value;this.#t.replaceChildren(...n.map(([e,t])=>{let n=document.createElement(`option`);return n.value=e,n.textContent=t,n})),n.some(([e])=>e===r)&&(this.#t.value=r)}#r(e){return e===`server`?`server`:this.#n.get(e)??`client ${e}`}};function f(e){let[t,n]=e.split(`:`);if(t===`to`&&n===`everyone`)return{to:`everyone`};let r=Number(n);if(!(!Number.isInteger(r)||r<1))return t===`from`?{from:r}:{to:r}}function p(e,t){if(t.length===0){let t=document.createElement(`p`);t.className=`empty`,t.textContent=`No state bag has keys.`,e.replaceChildren(t)}else e.replaceChildren(...t.map(({name:e,keys:t})=>{let n=document.createElement(`section`),r=document.createElement(`h3`);r.textContent=e;let i=document.createElement(`dl`);for(let{key:e,value:n}of t){let t=document.createElement(`dt`);t.textContent=e;let r=document.createElement(`dd`);r.textContent=n,i.append(t,r)}return n.append(r,i),n}))}var m=1e3,h=[[`Exports`,({exports:e})=>e],[`Events`,({events:e})=>e],[`NUI callbacks`,({nuiCallbacks:e})=>e],[`Commands`,({commands:e})=>e],[`Key mappings`,({keyMappings:e})=>e],[`KVP`,({kvp:e})=>e.map(({key:e,value:t})=>`${e} = ${t}`)]],g=e=>String(e),_=class{#e;#t;#n=new Map;#r;#i;#a=``;#o=``;constructor(e,t){this.#t=e,this.#e=t;let{process:n,form:r,code:i,filter:a}=e;this.players([]),n.addEventListener(`change`,()=>{this.#r=void 0,this.#c()});let o=l(i);r.addEventListener(`submit`,e=>{e.preventDefault(),i.value.trim()!==``&&this.#i!==void 0&&(t.evaluate(this.#s,this.#i,i.value),o(i.value),i.value=``)}),a.addEventListener(`input`,()=>this.#f()),setInterval(()=>this.#c(),m)}players(e){let{process:t}=this.#t,n=t.value,r=[[`server`,`Server`],...e.filter(({state:e})=>e===`joined`).map(({client:e,name:t})=>[g(e),t])];t.replaceChildren(...r.map(([e,t])=>{let n=document.createElement(`option`);return n.value=e,n.textContent=t,n})),t.value=r.some(([e])=>e===n)?n:`server`}show(e){if(e.process!==this.#s)return;this.#l(e),this.#r=e,this.#d();let t=JSON.stringify(e.convars);t!==this.#o&&(this.#o=t,this.#t.convars.replaceChildren(...e.convars.flatMap(({name:e,value:t})=>{let n=document.createElement(`dt`);n.textContent=e;let r=document.createElement(`dd`);return r.textContent=t,[n,r]})),this.#f())}get#s(){let{value:e}=this.#t.process;return e===`server`?e:Number(e)}#c(){document.hidden||this.#e.inspect(this.#s)}#l({resources:e,ticks:t}){let n=this.#t.resources,r=e.map(({name:e})=>e);r.join()!==[...this.#n.keys()].join()&&(this.#n.clear(),n.replaceChildren(...r.map(e=>this.#u(e))));let i=this.#r;for(let n of e){let e=this.#n.get(n.name);e.classList.toggle(`stopped`,n.state!==`started`),e.classList.toggle(`chosen`,n.name===this.#i);let r=i?.resources.find(({name:e})=>e===n.name),a=t-(i?.ticks??0);r!==void 0&&a>0&&(e.lastElementChild.textContent=`${((n.cpu-r.cpu)/a).toFixed(2)} ms`)}}#u(e){let t=document.createElement(`button`);t.type=`button`;let n=document.createElement(`span`);return n.textContent=e,t.append(n,document.createElement(`span`)),t.addEventListener(`click`,()=>{this.#i=e;for(let[t,n]of this.#n)n.classList.toggle(`chosen`,t===e);this.#d()}),this.#n.set(e,t),t}#d(){let e=this.#r?.resources.find(({name:e})=>e===this.#i),{details:t,code:n}=this.#t;n.disabled=e===void 0,n.placeholder=e===void 0?`Pick a resource to run code in it`:`Code to run in ${e.name}, such as GetNumResources()`;let r=JSON.stringify(e&&{...e,cpu:0});r!==this.#a&&(this.#a=r??``,e===void 0?t.textContent=`Pick a resource`:t.replaceChildren(...h.flatMap(([t,n])=>{let r=n(e);if(r.length===0)return[];let i=document.createElement(`h3`);i.textContent=`${t} (${r.length})`;let a=document.createElement(`ul`);return a.replaceChildren(...r.map(e=>{let t=document.createElement(`li`);return t.textContent=e,t})),[i,a]})))}#f(){let{convars:e,filter:t}=this.#t,n=t.value.trim().toLowerCase();for(let t of e.querySelectorAll(`dt`)){let e=!t.textContent.toLowerCase().includes(n);t.hidden=e,t.nextElementSibling.hidden=e}}},v=[657415,1708816,2497301,3351579,4140064,4994598,5914672,6834999,7755326,8675910,9662543,10649435,11570534,12360562,13085055,13743756,14336923,14864298,15326139,15721932,16051933,4004370,5382682,7023388,8729630,10370848,12078372,13393708,14251837,14914910,3874639,5580911,7485856,9523911,11894496,7149638,10231646,13184891,14899868,15765437,1780843,2311326,3106761,5215203,8830448,1003351,1407616,2073507,1923628,2787900,5749063,10802750,15255082,15769892,15232287,13185054,2829101,4474183,6250595,8158592,10263968,12369343,14343132,15987697],y=new Map([[8,`flag`],[40,`house`],[50,`car`],[52,`basket`],[56,`badge`],[59,`basket`],[60,`badge`],[61,`cross`],[67,`car`],[68,`lock`],[71,`scissors`],[72,`spray`],[73,`shirt`],[75,`heart`],[93,`bottle`],[102,`syringe`],[108,`dollar`],[110,`gun`],[198,`car`],[225,`car`],[273,`cutlery`],[326,`car`],[356,`boat`],[357,`parking`],[359,`plane`],[360,`plane`],[361,`fuel`],[366,`shirt`],[402,`wrench`],[403,`pill`],[423,`plane`],[424,`plane`],[427,`boat`],[477,`car`],[566,`anvil`],[729,`anchor`]]);function b(e){return y.get(e)}function x(e,t,n=!1){let r=0;for(let e=0;e<t.length;e+=2){let n=(e+2)%t.length;r+=t[e]*t[n+1]-t[n]*t[e+1]}let i=[...Array(t.length/2).keys()];r>0===n&&i.reverse(),i.forEach((n,r)=>{r===0?e.moveTo(t[2*n],t[2*n+1]):e.lineTo(t[2*n],t[2*n+1])}),e.closePath()}function S(e,t,n,r,i=!1){e.moveTo(t+r,n),e.arc(t,n,r,0,Math.PI*2,i),e.closePath()}function C(e,t){let n=new Path2D;return n.addPath(e,new DOMMatrix().rotate(t)),n}function w(e,t,n=0){let r=new Path2D;e(r);let i=n===0?r:C(r,n);return t===void 0?{path:i}:{path:i,width:t}}var T;function ee(){return{anchor:[w(e=>{S(e,0,-5.4,2.1),S(e,0,-5.4,1,!0),e.roundRect(-.95,-3.6,1.9,10.4,.6),e.roundRect(-3.8,-2.6,7.6,1.7,.85),x(e,[-7.4,1.2,-4.2,1.2,-5.8,3.6]),x(e,[7.4,1.2,4.2,1.2,5.8,3.6])}),w(e=>{e.moveTo(-5.8,2.4),e.quadraticCurveTo(-5,6.6,0,6.7),e.quadraticCurveTo(5,6.6,5.8,2.4)},1.7)],anvil:[w(e=>x(e,[-6.4,-4.4,4.2,-4.4,7.8,-3.4,4.6,-1.4,2.6,-1.4,2.6,1.6,4.8,4.4,4.8,6.2,-4.8,6.2,-4.8,4.4,-2.6,1.6,-2.6,-1.4,-6.4,-1.4]))],badge:[w(e=>{let t=[];for(let e=0;e<10;e++){let n=e*Math.PI/5-Math.PI/2,r=e%2==0?7.8:3.4;t.push(Math.cos(n)*r,Math.sin(n)*r+.6)}x(e,t)})],basket:[w(e=>{e.roundRect(-7.8,-2.4,15.6,2.4,1),x(e,[-6.8,-.4,6.8,-.4,5.2,6.6,-5.2,6.6]);for(let t of[-3.7,-.75,2.2])x(e,[t,1.2,t+1.5,1.2,t+1.5,5,t,5],!0)}),w(e=>{e.moveTo(-4.6,-2.4),e.arc(0,-2.4,4.6,Math.PI,Math.PI*2)},1.6)],boat:[w(e=>{x(e,[-7.6,2,7.6,2,5,6.6,-5,6.6]),x(e,[.6,-7.6,6,.8,.6,.8]),x(e,[-.6,-5.6,-.6,.8,-5,.8])})],bottle:[w(e=>{e.roundRect(-1.9,-7.8,3.8,1.6,.6),e.roundRect(-1.35,-6.6,2.7,3,.4),x(e,[-1.35,-4,1.35,-4,3.7,-1.4,-3.7,-1.4]),e.roundRect(-3.7,-2.4,7.4,10.2,1.8),x(e,[-2.3,.6,2.3,.6,2.3,4.2,-2.3,4.2],!0)})],car:[w(e=>{e.roundRect(-7.6,-1.6,15.2,5,1.8),x(e,[-4.8,-1.6,-2.9,-5.8,3.1,-5.8,5.2,-1.6]),x(e,[-2.9,-2.4,-.4,-2.4,-.4,-4.8,-2.1,-4.8],!0),x(e,[.5,-2.4,3.6,-2.4,2.6,-4.8,.5,-4.8],!0),S(e,-4.2,3.6,2.2),S(e,4.2,3.6,2.2)})],cross:[w(e=>{e.roundRect(-2.7,-7.4,5.4,14.8,1),e.roundRect(-7.4,-2.7,14.8,5.4,1)})],cutlery:[w(e=>{e.roundRect(-5.6,-3.4,5,2.6,1.3),x(e,[2,-7.6,4.9,-4.8,4.9,.6,2,.6])}),w(e=>{e.moveTo(-3.1,-1.4),e.lineTo(-3.1,7),e.moveTo(3.4,.6),e.lineTo(3.4,7)},1.9),w(e=>{for(let t of[-5,-3.1,-1.2])e.moveTo(t,-7.4),e.lineTo(t,-2.6)},1.1)],dollar:[w(e=>{e.moveTo(0,-7.6),e.lineTo(0,7.6)},1.6),w(e=>{e.moveTo(4.3,-3.9),e.bezierCurveTo(3.3,-6.3,-4.6,-6.3,-4.4,-2.6),e.bezierCurveTo(-4.2,.2,4.4,-.4,4.4,2.8),e.bezierCurveTo(4.4,6.5,-3.6,6.5,-4.6,3.8)},2.3)],flag:[w(e=>{e.roundRect(-5.4,-7.8,1.9,15.6,.9),e.moveTo(-3.8,-7.4),e.quadraticCurveTo(.8,-9.4,6.8,-6),e.quadraticCurveTo(.8,-2.4,-3.8,-1.2),e.closePath()})],fuel:[w(e=>{e.roundRect(-6.6,-7,8.6,14.4,1.6),x(e,[-5,-5.4,.4,-5.4,.4,-1.6,-5,-1.6],!0),e.roundRect(-7.6,5.6,10.6,1.8,.6)}),w(e=>{e.moveTo(2,-3.4),e.lineTo(4.6,-3.4),e.lineTo(5.8,-1.8),e.lineTo(5.8,4.2),e.quadraticCurveTo(5.8,5.4,4.6,5.2)},1.5)],gun:[w(e=>x(e,[-7.4,-4.6,7,-4.6,7,-1.4,-.4,-1.4,-1.1,1.8,-2.7,1.8,-3.6,6.6,-7.2,6.6,-5.7,-1.4,-7.4,-1.4])),w(e=>{e.moveTo(-.4,-1.4),e.quadraticCurveTo(.6,2.4,-2.4,2)},1.1)],heart:[w(e=>{S(e,-3.2,-2.4,3.8),S(e,3.2,-2.4,3.8),x(e,[-6.8,-1,6.8,-1,0,7])})],house:[w(e=>x(e,[0,-7.8,7.8,-.4,5.2,-.4,5.2,7.2,1.6,7.2,1.6,2.6,-1.6,2.6,-1.6,7.2,-5.2,7.2,-5.2,-.4,-7.8,-.4]))],lock:[w(e=>{e.moveTo(-3.7,-.6),e.lineTo(-3.7,-3.6),e.arc(0,-3.6,3.7,Math.PI,Math.PI*2),e.lineTo(3.7,-.6)},2),w(e=>{e.roundRect(-6.2,-1.8,12.4,9.4,1.8);let t=Math.sqrt(1.5**2-.6**2);e.moveTo(.6,1.8+t),e.arc(0,1.8,1.5,Math.atan2(t,.6),Math.atan2(t,-.6),!0),e.lineTo(-1,5.2),e.lineTo(1,5.2),e.closePath()})],parking:[w(e=>{e.roundRect(-7.2,-7.2,14.4,14.4,3),e.moveTo(-2.9,4.9),e.lineTo(-.8,4.9),e.lineTo(-.8,1.1),e.lineTo(.8,1.1),e.arc(.8,-1.9,3,Math.PI/2,-Math.PI/2,!0),e.lineTo(-2.9,-4.9),e.closePath(),e.moveTo(-.8,-3),e.lineTo(.7,-3),e.arc(.7,-1.9,1.1,-Math.PI/2,Math.PI/2),e.lineTo(-.8,-.8),e.closePath()})],pill:[w(e=>{e.roundRect(-3.1,-7.6,6.2,15.2,3.1),x(e,[-3.1,-.45,3.1,-.45,3.1,.45,-3.1,.45],!0)},void 0,45)],plane:[w(e=>{e.moveTo(0,-8),e.quadraticCurveTo(1.6,-7,1.6,-3),e.lineTo(8,1),e.lineTo(8,2.6),e.lineTo(1.6,.6),e.lineTo(1.1,5),e.lineTo(3.6,7),e.lineTo(3.6,8),e.lineTo(0,7),e.lineTo(-3.6,8),e.lineTo(-3.6,7),e.lineTo(-1.1,5),e.lineTo(-1.6,.6),e.lineTo(-8,2.6),e.lineTo(-8,1),e.lineTo(-1.6,-3),e.quadraticCurveTo(-1.6,-7,0,-8),e.closePath()})],scissors:[w(e=>{for(let t of[-3.5,3.5])S(e,t,4.3,2.8),S(e,t,4.3,1.35,!0);x(e,[-2.9,2,-1.3,2.5,3.9,-7.4,2.5,-7.8]),x(e,[2.9,2,1.3,2.5,-3.9,-7.4,-2.5,-7.8])})],shirt:[w(e=>{e.moveTo(-3,-7.2),e.lineTo(-7.8,-4.6),e.lineTo(-5.8,-.4),e.lineTo(-4.2,-1.4),e.lineTo(-4.2,7.2),e.lineTo(4.2,7.2),e.lineTo(4.2,-1.4),e.lineTo(5.8,-.4),e.lineTo(7.8,-4.6),e.lineTo(3,-7.2),e.quadraticCurveTo(0,-4.2,-3,-7.2),e.closePath()})],spray:[w(e=>{e.roundRect(-4.6,-3.2,7.2,11,1.6),x(e,[-3.4,0,1.4,0,1.4,3.4,-3.4,3.4],!0),e.roundRect(-3.2,-5.8,4.4,2.8,.8),e.roundRect(-1.8,-7.4,1.6,1.8,.4),S(e,2.6,-6.6,.9),S(e,4.6,-7.4,.8),S(e,4.8,-5.2,.9),S(e,6.8,-6.2,.8)})],syringe:[w(e=>{e.roundRect(-2.7,-4.2,5.4,8.2,.9),x(e,[-1.2,-2.8,1.2,-2.8,1.2,2.6,-1.2,2.6],!0),e.roundRect(-3.4,3.4,6.8,1.3,.5),e.roundRect(-.7,4.6,1.4,2.2,.3),e.roundRect(-2.6,6.6,5.2,1.3,.5),e.roundRect(-1,-5.4,2,1.4,.4),x(e,[-.55,-5.2,.55,-5.2,0,-8.4])},void 0,45)],wrench:[w(e=>{e.roundRect(-1.4,-1.4,2.8,9.4,1.4);let t=Math.sqrt(3.7**2-1.25**2);e.moveTo(1.25,-4.2-t),e.arc(0,-4.2,3.7,Math.atan2(-t,1.25),Math.atan2(-t,-1.25)+Math.PI*2),e.lineTo(-1.25,-3.5),e.lineTo(1.25,-3.5),e.closePath()},void 0,45)]}}function E(e,t,n,r=0){T??=ee();let i=T[t],a=n/16,o=e.fillStyle;if(e.save(),e.scale(a,a),e.lineJoin=`round`,e.lineCap=`round`,r>0)for(let{path:t,width:n}of i)e.lineWidth=(n??0)+r*2/a,e.stroke(t);e.strokeStyle=o;for(let{path:t,width:n}of i)n===void 0?e.fill(t):(e.lineWidth=n,e.stroke(t));e.restore()}var te=`#f0f0f0.#e04646.#6fcf6f.#5a9ef0.#f0f0f0.#f0d24a.#e57373.#b07ee0.#f080c0.#f0b070.#c8a070.#90e090.#80c8f0.#c8a0f0.#7050b0.#50d0d0.#f0e090.#f09030.#6aa8f0.#c05090.#c0a030.#d07020.#b0b0b0.#f0b0d0.#c0e050.#3a8a3a.#4060f0.#a040f0.#806050.#304090.#208080.#b09070.#90c0f0.#f0e8a0.#f0a8c0.#f08080.#e0d0a0.#f4f4f4.#3c78e0.#c0c0c0.#606060.#f06080.#4c8ce0.#a0e0a0.#f0c080.#f8f8f8.#e0b030.#f08c28.#f050a0.#d83c3c.#9070d0.#f09080.#2c7a3c.#a0d8f0.#3c6e7a.#c0c8d0.#8a5a30.#4a80e0.#4a5a8a.#e04848.#f0b040.#c04890.#d0d0d0.#3a7aa0.#c86020.#8a7a9a.#f0b440.#4a88e8.#5090e8.#58c058.#f0b848.#f0bc4c.#202020.#f0b040.#4888e0.#e04040.#a02828.#4888e8.#5090f0.#284080.#505050.#f0d840.#a0e040.#9050c0.#4878d8.#484848`.split(`.`),D=[`#f0a030`,`#4fd6e0`,`#d070f0`,`#5fd068`,`#ff5c5c`,`#5c8dff`],O=[10,25,50,100,250,500,1e3,2e3],ne=`Bahnschrift, 'Arial Narrow', 'Roboto Condensed', 'Helvetica Neue', Arial, sans-serif`,k=`'Nunito', 'Varela Round', 'Segoe UI', system-ui, sans-serif`;function re(e,t,n){let r=t*Math.min(n,1-n),i=t=>{let i=(t+e/30)%12,a=n-r*Math.max(-1,Math.min(i-3,9-i,1));return Math.round(a*255).toString(16).padStart(2,`0`)};return`#${i(0)}${i(8)}${i(4)}`}function A(e){return te[e]??re(e*137.5%360,.7,.62)}function j(e){return D[(e-1)%D.length]}function M(e){let t=Number.parseInt(e.slice(1,7),16);return[t>>16&255,t>>8&255,t&255]}function N(e,t){let[n,r,i]=M(e).map(e=>Math.round(t<0?e*(1+t):e+(255-e)*t));return`rgb(${n} ${r} ${i})`}function P(e){let[t,n,r]=M(e).map(e=>(e/255)**2.2);return .2126*t+.7152*n+.0722*r}function F(e,t,n,r=[],i=0){let{context:a,width:o,height:s}=e,c=O.find(t=>t*e.scale>=70)??O.at(-1),[l,u]=e.toWorld(0,0),[d,f]=e.toWorld(o,s);a.lineWidth=1,a.font=n,a.fillStyle=t.text,a.setLineDash(r);for(let n=Math.ceil(l/c)*c;n<=d;n+=c){let[r]=e.toScreen(n,0);a.strokeStyle=n===0?t.axis:t.line,a.beginPath(),a.moveTo(Math.round(r)+.5,0),a.lineTo(Math.round(r)+.5,s),a.stroke(),e.bare!==!0&&a.fillText(String(n),r+3,i+12)}for(let n=Math.ceil(f/c)*c;n<=u;n+=c){let[,r]=e.toScreen(0,n);a.strokeStyle=n===0?t.axis:t.line,a.beginPath(),a.moveTo(0,Math.round(r)+.5),a.lineTo(o,Math.round(r)+.5),a.stroke(),r>i+20&&e.bare!==!0&&a.fillText(String(n),3,r-3)}a.setLineDash([])}function I(e,t,n,r,i){let a=r.findIndex(([r,i])=>e.claim(r,i,t,n));if(a>=0)return a;if(!i)return;let o=r.map(([r,i])=>e.crowding(r,i,t,n)),s=o.indexOf(Math.min(...o));return e.claim(...r[s],t,n,!0),s}function L(e,t,n,r,i,a,o=!1){let{context:s}=e;s.font=a;let c=s.measureText(t).width,l=([e,,t])=>t===`center`?e-c/2:t===`right`?e-c:e,u=I(e,c+4,16,n.map(e=>[l(e)-2,e[1]-12]),o);if(u===void 0)return;let d=l(n[u]),f=n[u][1];s.lineJoin=`round`,s.lineWidth=3,s.strokeStyle=i,s.strokeText(t,d,f),s.fillStyle=r,s.fillText(t,d,f),s.lineWidth=1}var R=e=>-e.heading*Math.PI/180;function z(e,t){let n=Math.sin(e*127.1+t*311.7)*43758.5453;return n-Math.floor(n)}var ie=Float64Array.from({length:512},(e,t)=>{let n=Math.floor(t/2)/256*Math.PI*2;return t%2==0?Math.cos(n):Math.sin(n)});function ae(e,t){let n=Math.imul(e|0,668265261)^Math.imul(t|0,374761393);return n=Math.imul(n^n>>>15,2246822507),((n^n>>>13)&255)*2}function oe(e,t){let n=Math.floor(e),r=Math.floor(t),i=e=>e*e*e*(e*(e*6-15)+10),a=(n,r)=>{let i=ae(n,r);return ie[i]*(e-n)+ie[i+1]*(t-r)},o=i(e-n),s=i(t-r),c=a(n,r)+(a(n+1,r)-a(n,r))*o;return .5+(c+(a(n,r+1)+(a(n+1,r+1)-a(n,r+1))*o-c)*s)*.75}function se(e,t){return oe(e,t)*.68+oe((e*.8-t*.6)*2.1+31,(e*.6+t*.8)*2.1-7)*.32}function B(e,t){return 2**Math.round(Math.log2(t/e.scale))}function ce(e=1/0){let t,n=``;return(r,i,a=``)=>{let[o,s]=r.toWorld(0,0),c=`${r.width} ${r.height} ${r.ratio} ${o} ${s} ${r.scale} ${a}`;if(t??=document.createElement(`canvas`),c!==n){let a=Math.min(r.ratio,e),o=Math.round(r.width*a),s=Math.round(r.height*a);(t.width!==o||t.height!==s)&&(t.width=o,t.height=s);let l=t.getContext(`2d`);l.setTransform(1,0,0,1,0,0),l.clearRect(0,0,o,s),l.setTransform(a,0,0,a,0,0),i({...r,context:l,ratio:a}),n=c}r.context.drawImage(t,0,0,r.width,r.height)}}function le(e){let t=e.length;for(let{x:n,y:r}of e)t=(t*31+Math.round(n)*7+Math.round(r))%1e9;return String(t)}var V={name:`Classic`,animated:!1,background(e){e.context.clearRect(0,0,e.width,e.height),F(e,{line:`#1f232b`,axis:`#3a404c`,text:`#5a606c`},`11px ui-monospace, Consolas, monospace`)},area(e,t,n,r){let{context:i}=e;if(i.globalAlpha=t.alpha/255*.35,i.fillStyle=A(t.colour),i.beginPath(),t.shape===`radius`)i.arc(n,r,(t.radius??0)*e.scale,0,Math.PI*2);else{let a=(t.width??0)*e.scale,o=(t.height??0)*e.scale;i.rect(n-a/2,r-o/2,a,o)}i.fill(),i.globalAlpha=1},route(e,t,n,r){let{context:i}=e;i.strokeStyle=r,i.lineWidth=2,i.setLineDash([6,5]),i.beginPath(),i.moveTo(...t),i.lineTo(...n),i.stroke(),i.setLineDash([]),i.lineWidth=1},blip(e,t,n,r){let{context:i}=e;e.claim(n-6,r-6,12,12,!0),i.globalAlpha=Math.max(t.alpha/255,.25),t.sprite===8?(i.fillStyle=`#d070f0`,i.beginPath(),i.moveTo(n,r-9),i.lineTo(n+7,r),i.lineTo(n,r+9),i.lineTo(n-7,r),i.closePath(),i.fill()):t.shape!==`radius`&&t.shape!==`area`&&(i.fillStyle=A(t.colour),i.strokeStyle=`#0b0c10`,i.beginPath(),i.arc(n,r,5,0,Math.PI*2),i.fill(),i.stroke()),i.globalAlpha=1},label(e,t,n,r,i){L(e,t,[[n+8,r+4,`left`],[n-8,r+4,`right`]],`#c8ccd4`,`#0b0c10`,`12px system-ui, sans-serif`,i)},tag(e,t,n,r,i){L(e,t,[[r,i+22,`center`],[r,i-14,`center`]],n,`#0b0c10`,`12px system-ui, sans-serif`,!0)},entity(e,t,n,r,i,a){let{context:o}=e;if(t.kind===`player`){let i=a?.colour??`#d7dae0`;e.claim(n-8,r-10,16,18,!0),o.save(),o.translate(n,r),o.rotate(R(t)),o.fillStyle=i,o.strokeStyle=`#0b0c10`,o.beginPath(),o.moveTo(0,-10),o.lineTo(7,7),o.lineTo(0,3),o.lineTo(-7,7),o.closePath(),o.fill(),o.stroke(),o.restore()}else t.kind===`vehicle`?(o.save(),o.translate(n,r),o.rotate(R(t)),o.fillStyle=`#8a909c`,o.fillRect(-4,-7,8,14),o.restore()):(o.fillStyle=t.kind===`ped`?`#a8adb8`:`#5a606c`,o.beginPath(),o.arc(n,r,t.kind===`ped`?3.5:2.5,0,Math.PI*2),o.fill());return[n,r]}},H={grass:`#8fcf68`,light:[166,220,127],dark:[124,192,88],tuft:`#6eb24c`,ink:`#2b2d3a`,text:`#2d3142`},ue=[`#ef5b5b`,`#3f8efc`,`#ffc145`,`#34c38f`,`#a66cff`,`#ff8a3d`,`#f2f4f8`],U=[`#8d99ae`,`#e9c46a`,`#2a9d8f`,`#e76f51`,`#9b5de5`,`#577590`],W=[`#f8d5b5`,`#eab78e`,`#c98d62`,`#9c6644`,`#6f4630`],G=[`#3b2a20`,`#6b4423`,`#d8a93f`,`#a0522d`,`#23232b`,`#c8553d`],K=[`#3d4a6b`,`#e9c46a`,`#2a9d8f`,`#e76f51`,`#9b5de5`,`#577590`,`#f4f1de`,`#ef476f`,`#118ab2`,`#06d6a0`,`#ffd166`,`#264653`,`#8d99ae`,`#f78c6b`,`#2b2d42`,`#b5838d`],de=[`#f8d5b5`,`#f1c6a0`,`#eab78e`,`#d9a077`,`#c98d62`,`#b07650`,`#9c6644`,`#845437`,`#6f4630`];function fe(e){if(e===void 0)return;let t=([e,t],n)=>K[Math.abs(e*5+t*3+n)%K.length],n=e=>M(de[Math.abs(e)%de.length]),[r,i,a]=e.skin,[o,s]=[n(r),n(i)],c=o.map((e,t)=>Math.round(e+(s[t]-e)*a)),l=v[e.hair]??v[0];return{skin:`rgb(${c.join(` `)})`,hair:`#${l.toString(16).padStart(6,`0`)}`,top:t(e.top,1),legs:t(e.legs,0),shoes:t(e.shoes,14),long:e.hairStyle%2==1}}function q(e,t,n,r=1.6){e.lineWidth=r*2,e.strokeStyle=H.ink,e.stroke(t),e.fillStyle=n,e.fill(t)}function J(e,t,n,r,i,a=.22){e.fillStyle=`rgba(32, 70, 26, ${a})`,e.beginPath(),e.ellipse(t,n,r,i,0,0,Math.PI*2),e.fill()}function pe(e,t,n,r,i){J(e,t+4*i,n+1,12*i,4.5*i);let a=new Path2D;a.roundRect(t-2.2*i,n-9*i,4.4*i,10*i,1.6*i),q(e,a,`#9a6a45`,1.1);let o=new Path2D;if(r){for(let[e,r,a]of[[-30,7,-18],[-24,9.5,-12],[-18,11.5,-6]])o.moveTo(t,n+e*i),o.lineTo(t+r*i,n+a*i),o.lineTo(t-r*i,n+a*i),o.closePath();q(e,o,`#3f9a54`,1.1),e.fillStyle=`rgba(255, 255, 255, 0.18)`,e.beginPath(),e.moveTo(t,n-29*i),e.lineTo(t-5*i,n-20*i),e.lineTo(t-1*i,n-20*i),e.closePath(),e.fill()}else{for(let[e,r,a]of[[-6,-14,7],[6,-14,7],[0,-20,8.5]])o.moveTo(t+(e+a)*i,n+r*i),o.arc(t+e*i,n+r*i,a*i,0,Math.PI*2);q(e,o,`#4caf50`,1.1),e.fillStyle=`#7bd06b`,e.beginPath(),e.arc(t-3*i,n-22*i,3.6*i,0,Math.PI*2),e.arc(t-7.5*i,n-15.5*i,2.4*i,0,Math.PI*2),e.fill()}}function me(e,t,n,r){if(r<.12){J(e,t+2,n+1,9,3);let r=new Path2D;for(let[e,i,a]of[[-5,-4,4.6],[4.5,-4,4.6],[0,-7,5.4]])r.moveTo(t+e+a,n+i),r.arc(t+e,n+i,a,0,Math.PI*2);q(e,r,`#5cb85c`,1),e.fillStyle=`#86d176`,e.beginPath(),e.arc(t-1.5,n-8.5,2,0,Math.PI*2),e.fill()}else if(r<.19){let[i,a]=[[`#ffffff`,`#ffd23f`],[`#ff8fb1`,`#fff3b0`],[`#ffd23f`,`#f08a3c`]][Math.floor(r*1e3)%3];for(let[r,o]of[[0,0],[6,3],[-5,4]]){e.fillStyle=i,e.beginPath();for(let i=0;i<5;i++){let a=i*Math.PI*2/5;e.moveTo(t+r+Math.cos(a)*1.8+1.5,n+o+Math.sin(a)*1.8),e.arc(t+r+Math.cos(a)*1.8,n+o+Math.sin(a)*1.8,1.5,0,Math.PI*2)}e.fill(),e.fillStyle=a,e.beginPath(),e.arc(t+r,n+o,1.2,0,Math.PI*2),e.fill()}}else if(r<.215){J(e,t+2,n+1.5,7,2.5);let r=new Path2D;r.ellipse(t,n-2,6,4,0,0,Math.PI*2),q(e,r,`#c3ccd6`,1),e.fillStyle=`#e6ebf0`,e.beginPath(),e.ellipse(t-2,n-3.6,2.4,1.3,-.3,0,Math.PI*2),e.fill()}else{e.strokeStyle=H.tuft,e.lineWidth=1.8,e.lineCap=`round`,e.beginPath();for(let r of[-3,0,3])e.moveTo(t+r,n),e.quadraticCurveTo(t+r*1.1,n-3,t+r*1.7,n-6+Math.abs(r)*.4);e.stroke(),e.lineCap=`butt`}}function he(e,t){let{context:n,width:r,height:i}=e;n.fillStyle=H.grass,n.fillRect(0,0,r,i);let a=B(e,380),o=Math.ceil(r/16)+1,s=Math.ceil(i/16)+1,c=document.createElement(`canvas`);c.width=o,c.height=s;let l=c.getContext(`2d`),u=l.createImageData(o,s),[d,f]=e.toWorld(0,0);for(let t=0;t<s;t++)for(let n=0;n<o;n++){let r=se((d+n*16/e.scale)/a,(f-t*16/e.scale)/a),i=Math.min(Math.max((r-.55)/.09,0),1),s=Math.min(Math.max((.45-r)/.09,0),1),[c,l,p]=i>0?H.light:H.dark,m=i>0?i:s,h=(t*o+n)*4;u.data[h]=c,u.data[h+1]=l,u.data[h+2]=p,u.data[h+3]=Math.round(m*255)}l.putImageData(u,0,0),n.imageSmoothingQuality=`high`,n.drawImage(c,-8,-8,o*16,s*16);let p=new Set;for(let a of t){if(a.shape===`radius`||a.shape===`area`)continue;let[t,o]=e.toScreen(a.x,a.y);if(!(t<-30||o<-30||t>r+30||o>i+30)){for(let e=-1;e<=1;e++)for(let n=-1;n<=1;n++)p.add(`${Math.floor(t/30)+e} ${Math.floor(o/30)+n}`);e.scale>=.1&&a.sprite!==8&&(n.fillStyle=`rgba(244, 228, 178, 0.85)`,n.beginPath(),n.ellipse(t,o+6,19,8.5,0,0,Math.PI*2),n.fill(),n.fillStyle=`rgba(255, 246, 214, 0.7)`,n.beginPath(),n.ellipse(t,o+5,12,5,0,0,Math.PI*2),n.fill())}}let m=B(e,58),h=Math.log2(m),[g,_]=e.toWorld(-40,-40),[v,y]=e.toWorld(r+40,i+60),b=[];for(let t=Math.floor(g/m);t<=v/m;t++)for(let n=Math.floor(y/m);n<=_/m;n++){let r=z(t+h*7.3,n-h*3.1);if(r>.55)continue;let[i,a]=e.toScreen((t+.15+z(n,t+h)*.7)*m,(n+.15+z(t+3.7,n-h)*.7)*m);r<.215&&p.has(`${Math.floor(i/30)} ${Math.floor(a/30)}`)||b.push([i,a,r])}b.sort((e,t)=>e[1]-t[1]);for(let[e,t,r]of b)r<.07?pe(n,e,t,r<.025,.85+r*97%1*.35):me(n,e,t,r);F(e,{line:`rgba(255, 255, 255, 0.22)`,axis:`rgba(255, 255, 255, 0.6)`,text:`#3f6e2c`},`800 10px ${k}`,[2,6])}function ge(e){let{context:t,width:n,height:r,time:i}=e;t.fillStyle=`rgba(28, 60, 36, 0.05)`;for(let e=0;e<4;e++){let a=n+600,o=(e*.31*a+i*.012)%a-300,s=(e*.37+.12)%1*r+Math.sin(i/9e3+e)*24;t.beginPath();for(let[e,n,r,i]of[[0,0,120,52],[90,-20,90,44],[-80,14,80,38]])t.moveTo(o+e+r,s+n),t.ellipse(o+e,s+n,r,i,0,0,Math.PI*2);t.fill()}}function _e(e){return e.scale>=.1?12.5:e.scale>=.04?10.5:8.5}function ve(e){let t=P(e);return t>.8?`#5f6b7d`:t>.42?N(e,-.32):e}function ye(e,t,n,r,i,a){let{context:o}=e;o.font=`800 12px ${k}`;let s=Math.ceil(o.measureText(t).width)+16,c=r.map(([e,t])=>t?e:e-20),l=I(e,s,26,r.map(([,,e=0],t)=>[n+e-s/2,c[t]-3]),a);if(l===void 0)return;let u=c[l],[,d,f=0]=r[l],p=n+f,m=new Path2D;m.roundRect(p-s/2,u,s,20,10);let h=d?u:u+20;m.moveTo(p-5,h),m.lineTo(p,h+(d?-5:5)),m.lineTo(p+5,h),o.fillStyle=`rgba(30, 50, 30, 0.18)`,o.save(),o.translate(0,2.5),o.fill(m),o.restore(),o.fillStyle=i,o.fill(m),o.fillStyle=H.text,o.textAlign=`center`,o.fillText(t,p,u+14.5),o.textAlign=`left`}function be(e){return[`back`,`right`,`front`,`left`][Math.round((e%(Math.PI*2)+Math.PI*2)/(Math.PI/2))%4]}function xe(e,t,n,r,i,a,o=!1,s){let c=be(r),l=s?.skin??W[a%W.length],u=s?.hair??G[Math.floor(a/5)%G.length],d=s?.long??Math.floor(a/3)%2==0,f=t/105+a,p=n?Math.sin(f):0,m=n?-Math.abs(Math.sin(f))*2:Math.sin(t/420+a)*.5;o||J(e,0,.5,10-(n?Math.abs(p):0),3.6,.26),e.save(),e.translate(0,m);let h=c===`left`||c===`right`,g=c===`left`?-1:1,_=new Path2D,v=new Path2D;for(let[e,t]of[[-3,Math.max(0,p)],[3,Math.max(0,-p)]]){let n=h?p*(e<0?3:-3)*g:0,r=o?1.5:-t*2.6;_.roundRect((h?e*.35:e)-2.1+n,-8.5+r,4.2,8.5,2),v.roundRect((h?e*.35+g:e)-2.6+n,-2.8+r,5.2,3.2,1.5)}q(e,_,s?.legs??`#3d4a6b`,1.4),q(e,v,s?.shoes??`#2b2d42`,1.2);let y=new Path2D;for(let[e,t]of[[-8.2,-p],[8.2,p]]){if(h&&e*g<0)continue;let n=h?t*2.2*g:0;y.roundRect((h?1.5*g:e)-2+n,-18-(o?3:0)+t*1.2,4,8.5,2)}let b=new Path2D;if(b.roundRect(-7,-20,14,12.5,5),q(e,b,i,1.4),e.save(),e.clip(b),e.fillStyle=`rgba(0, 0, 0, 0.13)`,e.fillRect(h?-7*g:2,-20,h?6*g:5,13),e.restore(),d&&c!==`back`){let t=new Path2D;h?t.roundRect(g>0?-10.6:.6,-31,10,14,4):(t.roundRect(-10.6,-31,6.6,13.5,3.3),t.roundRect(4,-31,6.6,13.5,3.3)),q(e,t,u,1.4)}q(e,y,N(i,-.08),1.4);let x=new Path2D;x.arc(0,-27.5,9,0,Math.PI*2),q(e,x,l,1.4);let S=c===`back`?[[0,-31.5,11.5,9.5]]:h?[[-2.5*g,-34.2,10,6.5],[-5.5*g,-29.5,5.5,8.5]]:[[0,-35.6,11,6.6]];e.save(),e.clip(x),e.strokeStyle=N(u,-.35),e.lineWidth=2,e.fillStyle=u;for(let t of[`stroke`,`fill`])for(let[n,r,i,a]of S)e.beginPath(),e.ellipse(n,r,i,a,0,0,Math.PI*2),e[t]();if(e.restore(),d&&c===`back`){let t=new Path2D;t.arc(0,-27.5,9,0,Math.PI*2),t.roundRect(-7.6,-27.5,15.2,11,4.5),q(e,t,u,1.4)}if(c!==`back`){let n=(t+a*977)%3800<130,r=h?[3.6*g]:[-3.2,3.2];e.fillStyle=H.ink,e.strokeStyle=H.ink,e.lineWidth=1.3;for(let t of r)e.beginPath(),n?(e.moveTo(t-1.4,-26.5),e.lineTo(t+1.4,-26.5),e.stroke()):(e.ellipse(t,-26.6,1.25,1.6,0,0,Math.PI*2),e.fill());e.fillStyle=`rgba(255, 120, 120, 0.35)`;for(let t of h?[2*g]:[-5.2,5.2])e.beginPath(),e.ellipse(t,-23.4,1.9,1.2,0,0,Math.PI*2),e.fill();h||(e.beginPath(),e.arc(0,-24,1.8,.15*Math.PI,.85*Math.PI),e.stroke())}e.restore()}function Se(e,t,n,r){let i=new Path2D;for(let[e,t]of[[-9,-11],[5.4,-11],[-9,5.5],[5.4,5.5]])i.roundRect(e,t,3.6,6.5,1.6);e.fillStyle=`#23232b`,e.fill(i);let a=new Path2D;a.roundRect(-8,-15.5,16,31,6.5),q(e,a,t,1.3),e.save(),e.clip(a),e.fillStyle=`rgba(255, 255, 255, 0.22)`,e.fillRect(-8,-15.5,4,31),e.fillStyle=`rgba(0, 0, 0, 0.12)`,e.fillRect(4.5,-15.5,4,31),e.restore();let o=e.createLinearGradient(0,-9,0,-3);o.addColorStop(0,`#d9f4ff`),o.addColorStop(1,`#7cc6ee`),e.fillStyle=o,e.strokeStyle=H.ink,e.lineWidth=1,e.beginPath(),e.roundRect(-6,-9.5,12,6,2),e.fill(),e.stroke(),e.fillStyle=N(t,.18),e.beginPath(),e.roundRect(-6,-2.5,12,9,2.5),e.fill(),e.stroke(),e.fillStyle=`#7cc6ee`,e.beginPath(),e.roundRect(-5.5,7.5,11,4,1.5),e.fill(),e.stroke(),e.strokeStyle=`rgba(255, 255, 255, 0.85)`,e.lineWidth=1.2,e.beginPath(),e.moveTo(-3.5,-8.5),e.lineTo(-1,-4.5),e.stroke();for(let[t,n,r]of[[-6,-15.4,`#ffe066`],[3.6,-15.4,`#ffe066`],[-6,13.6,`#ff6b6b`],[3.6,13.6,`#ff6b6b`]])e.fillStyle=r,e.beginPath(),e.roundRect(t,n,2.4,1.8,.8),e.fill();if(n)for(let t=0;t<3;t++){let n=(r/420+t/3)%1;e.fillStyle=`rgba(255, 255, 255, ${.55*(1-n)})`,e.beginPath(),e.arc(-3+Math.sin(t*2.1)*2,18+n*12,2+n*3,0,Math.PI*2),e.fill()}}function Ce(){let e=ce();return{name:`Cartoon`,animated:!0,background(t,n){e(t,e=>he(e,n),le(n)),ge(t)},area(e,t,n,r){let{context:i}=e,a=A(t.colour),o=new Path2D;if(t.shape===`radius`)o.arc(n,r,(t.radius??0)*e.scale,0,Math.PI*2);else{let i=(t.width??0)*e.scale,a=(t.height??0)*e.scale;o.roundRect(n-i/2,r-a/2,i,a,Math.min(16,i/4,a/4))}i.globalAlpha=t.alpha/255*.22,i.fillStyle=a,i.fill(o),i.globalAlpha=Math.max(t.alpha/255,.4),i.strokeStyle=N(a,-.15),i.lineWidth=2.5,i.setLineDash([8,6]),i.lineDashOffset=-e.time/45,i.stroke(o),i.setLineDash([]),i.lineDashOffset=0,i.globalAlpha=1,i.lineWidth=1},route(e,t,n,r){let{context:i,time:a}=e;i.strokeStyle=r,i.globalAlpha=.18,i.lineWidth=9,i.lineCap=`round`,i.beginPath(),i.moveTo(...t),i.lineTo(...n),i.stroke(),i.globalAlpha=1,i.lineCap=`butt`;let o=Math.hypot(n[0]-t[0],n[1]-t[1]),s=a/36%14;i.lineWidth=1.6,i.strokeStyle=N(r,-.25),i.fillStyle=`#ffffff`;for(let e=s;e<o-6;e+=14){let r=e/o;i.beginPath(),i.arc(t[0]+(n[0]-t[0])*r,t[1]+(n[1]-t[1])*r,3,0,Math.PI*2),i.fill(),i.stroke()}i.lineWidth=1},blip(e,t,n,r,i){let{context:a,time:o}=e,s=A(t.colour);if(a.globalAlpha=Math.max(t.alpha/255,.35),t.sprite===8){e.claim(n-3,r-30,22,32,!0);let t=o/1600%1;a.strokeStyle=`rgba(239, 71, 111, ${.7*(1-t)})`,a.lineWidth=2,a.beginPath(),a.ellipse(n,r,6+t*14,(6+t*14)*.4,0,0,Math.PI*2),a.stroke(),J(a,n+2,r,6,2.4);let i=new Path2D;i.roundRect(n-1.3,r-28,2.6,28,1.3),q(a,i,`#e8e2d4`,1);let s=new Path2D,c=e=>Math.sin(o/160-e/4)*1.6*(e/16);s.moveTo(n+1,r-27);for(let e=0;e<=16;e+=2)s.lineTo(n+1+e,r-27+c(e)+e*.06);for(let e=16;e>=0;e-=2)s.lineTo(n+1+e,r-17+c(e)-e*.06);s.closePath(),q(a,s,`#ef476f`,1)}else if(t.shape!==`radius`&&t.shape!==`area`){let c=_e(e);e.claim(n-c,r-c*1.35-1,c*2,c*2.1+2,!0);let l=i?5:0,u=Math.sin(o/700+t.handle*1.7)*1.1-l;J(a,n,r+c*.75,c*.85-l*.3,c*.32),a.save(),a.translate(n,r+u-c*.35),i&&a.scale(1.12,1.12),a.fillStyle=N(P(s)>.8?`#9aa5b4`:s,-.35),a.beginPath(),a.arc(0,2.6,c,0,Math.PI*2),a.fill(),a.fillStyle=`#ffffff`,a.beginPath(),a.arc(0,0,c,0,Math.PI*2),a.fill(),a.strokeStyle=P(s)>.8?`#9aa5b4`:s,a.lineWidth=c>10?3:2.4,a.beginPath(),a.arc(0,0,c-1.5,0,Math.PI*2),a.stroke();let d=b(t.sprite);a.fillStyle=ve(s),d===void 0?(a.font=`900 ${Math.round(c)}px ${k}`,a.textAlign=`center`,a.fillText((t.name??`•`).slice(0,1).toUpperCase(),0,c*.36),a.textAlign=`left`):E(a,d,c*1.18),a.restore()}a.globalAlpha=1,a.lineWidth=1},label(e,t,n,r,i){let a=_e(e);ye(e,t,n,[[r+a*.75+9,!0],[r-a*1.45-7,!1]],`#ffffff`,i)},tag(e,t,n,r,i){ye(e,t,r,[[i-47,!1],[i+10,!0],[i-47,!1,48],[i-47,!1,-48]],n,!0)},entity(e,t,n,r,i,a){let{context:o,time:s}=e;if(t.kind===`player`||t.kind===`ped`){let c=a?.colour??U[t.id%U.length],l=t.kind===`ped`?.86:1.08;if(e.claim(n-10*l,r-37*l,20*l,38*l,!0),a!==void 0){let e=s/2200%1;o.strokeStyle=c,o.lineWidth=2.5,o.beginPath(),o.ellipse(n,r,14,5.5,0,0,Math.PI*2),o.stroke(),o.globalAlpha=1-e,o.lineWidth=1.5,o.beginPath(),o.ellipse(n,r,14+e*12,5.5+e*4.5,0,0,Math.PI*2),o.stroke(),o.globalAlpha=1}o.save(),o.translate(n,r),o.scale(l,l);let u=fe(t.look);return xe(o,s,i,R(t),u?.top??c,(a?.client??t.id)*7,!1,u),o.restore(),[n,r-14*l]}if(t.kind===`vehicle`){let a=Math.min(Math.max(e.scale/6,.8),1.4),c=R(t),l=i?Math.sin(s/55)*.5:0;return o.save(),o.translate(n+3*a,r+4*a),o.rotate(c),o.scale(a,a),o.fillStyle=`rgba(32, 70, 26, 0.24)`,o.beginPath(),o.roundRect(-9,-15,18,31,7),o.fill(),o.restore(),o.save(),o.translate(n,r+l),o.rotate(c),o.scale(a,a),Se(o,ue[t.id%ue.length],i,s),o.restore(),o.lineWidth=1,[n,r]}J(o,n+2,r+5,8,3);let c=new Path2D;return c.roundRect(n-6,r-6,12,12,2),q(o,c,`#c8915a`,1.2),o.strokeStyle=`#8a5a30`,o.lineWidth=1.2,o.beginPath(),o.moveTo(n-4.5,r-4.5),o.lineTo(n+4.5,r+4.5),o.moveTo(n+4.5,r-4.5),o.lineTo(n-4.5,r+4.5),o.stroke(),o.lineWidth=1,[n,r]},dragging(e,t,n,r){let{context:i,time:a}=e;i.fillStyle=`#ffffff`;let o=Math.hypot(n[0]-t[0],n[1]-t[1]);for(let e=8;e<o-24;e+=12){let r=e/o;i.beginPath(),i.arc(t[0]+(n[0]-t[0])*r,t[1]+(n[1]-t[1])*r,2.2,0,Math.PI*2),i.fill()}J(i,n[0],n[1]+26,9,3.2,.3),i.save(),i.translate(n[0],n[1]+16+Math.sin(a/160)*1.5),i.rotate(Math.sin(a/240)*.08);let s=fe(r.look);xe(i,a,!1,Math.PI,s?.top??r.colour,r.client*7,!0,s),i.restore()},overlay(e){let{context:t,height:n,time:r}=e,i=n-34;t.fillStyle=`rgba(30, 50, 30, 0.2)`,t.beginPath(),t.arc(34,i+3,21,0,Math.PI*2),t.fill();let a=new Path2D;a.arc(34,i,21,0,Math.PI*2),q(t,a,`#ffffff`,1.2),t.save(),t.translate(34,i),t.rotate(Math.sin(r/900)*.07),t.fillStyle=`#ef476f`,t.beginPath(),t.moveTo(0,-15),t.lineTo(4.5,0),t.lineTo(-4.5,0),t.closePath(),t.fill(),t.fillStyle=`#b8c2cf`,t.beginPath(),t.moveTo(0,15),t.lineTo(4.5,0),t.lineTo(-4.5,0),t.closePath(),t.fill(),t.restore(),t.fillStyle=H.ink,t.beginPath(),t.arc(34,i,2,0,Math.PI*2),t.fill(),t.font=`900 9px ${k}`,t.textAlign=`center`,t.fillText(`N`,34,i-23-3);let o=[5,10,25,50,100,250,500,1e3,2500,5e3].find(t=>t*e.scale>=56)??5e3,s=o*e.scale,c=o>=1e3?`${o/1e3} km`:`${o} m`;t.font=`800 11px ${k}`;let l=Math.max(s,t.measureText(c).width)+20;t.fillStyle=`rgba(30, 50, 30, 0.2)`,t.beginPath(),t.roundRect(66,i-12+2.5,l,26,13),t.fill(),t.fillStyle=`#ffffff`,t.beginPath(),t.roundRect(66,i-12,l,26,13),t.fill(),t.fillStyle=H.text,t.fillText(c,66+l/2,i+1),t.fillStyle=H.ink,t.fillRect(66+(l-s)/2,i+6,s/2,3),t.fillStyle=`#b8c2cf`,t.fillRect(66+l/2,i+6,s/2,3),t.textAlign=`left`}}}var we=[[],[[3,2]],[[2,1]],[[3,1]],[[0,1]],[[0,3],[1,2]],[[0,2]],[[0,3]],[[0,3]],[[0,2]],[[0,1],[3,2]],[[0,1]],[[3,1]],[[1,2]],[[3,2]],[]];function Te(e){let{context:t,width:n,height:r}=e,i=B(e,520),a=Math.ceil(n/9)+1,o=Math.ceil(r/9)+1,[s,c]=e.toWorld(0,0),l=9/e.scale,u=new Float32Array(a*o);for(let e=0;e<o;e++)for(let t=0;t<a;t++)u[e*a+t]=se((s+t*l)/i,(c-e*l)/i);let d=.3,f=.04,p=Array.from({length:12},()=>new Path2D);for(let e=0;e<o-1;e++)for(let t=0;t<a-1;t++){let n=u[e*a+t],r=u[e*a+t+1],i=u[(e+1)*a+t+1],o=u[(e+1)*a+t],s=Math.max(n,r,i,o);for(let a=Math.max(Math.ceil((Math.min(n,r,i,o)-d)/f),0);a<p.length&&d+a*f<=s;a++){let s=d+a*f,c=a=>a===0?[(t+(s-n)/(r-n))*9,e*9]:a===1?[(t+1)*9,(e+(s-r)/(i-r))*9]:a===2?[(t+(s-o)/(i-o))*9,(e+1)*9]:[t*9,(e+(s-n)/(o-n))*9],l=(n>s?8:0)|(r>s?4:0)|(i>s?2:0)|o>s;for(let[e,t]of we[l])p[a].moveTo(...c(e)),p[a].lineTo(...c(t))}}t.lineWidth=1,p.forEach((e,n)=>{t.strokeStyle=n%4==3?`rgba(150, 200, 235, 0.13)`:`rgba(150, 200, 235, 0.055)`,t.stroke(e)})}function Ee(e){let t=`#c65ad8`,n=`#05080b`,r=(e,t=600)=>`semi-condensed ${t} ${e}px ${ne}`,i=e=>e>=760,a=ce(1),o=e=>{e.fillStyle=`rgba(0, 0, 0, 0.4)`,e.beginPath(),e.ellipse(0,0,4.5,1.8,0,0,Math.PI*2),e.fill();let r=new Path2D;r.moveTo(0,0),r.bezierCurveTo(-1.8,-5,-7,-8,-7,-13.5),r.arc(0,-13.5,7,Math.PI,0),r.bezierCurveTo(7,-8,1.8,-5,0,0),r.closePath(),e.lineWidth=3,e.lineJoin=`round`,e.strokeStyle=n,e.stroke(r),e.fillStyle=t,e.fill(r),e.fillStyle=`#ffffff`,e.beginPath(),e.arc(0,-13.5,2.6,0,Math.PI*2),e.fill()},s=(e,t)=>{let r=new Path2D;r.moveTo(0,-12),r.lineTo(8.5,9),r.lineTo(0,4.5),r.lineTo(-8.5,9),r.closePath(),e.lineJoin=`round`,e.lineWidth=3.5,e.strokeStyle=n,e.stroke(r),e.fillStyle=t,e.fill(r),e.fillStyle=`rgba(255, 255, 255, 0.35)`,e.beginPath(),e.moveTo(0,-12),e.lineTo(0,4.5),e.lineTo(-8.5,9),e.closePath(),e.fill()},c=(e,t,n,i)=>{e.strokeStyle=`#ffffff`,e.fillStyle=`#ffffff`,e.lineWidth=1.4,e.beginPath(),e.roundRect(t,n,11,16,5.5),e.stroke(),e.beginPath(),e.moveTo(t,n+6.5),e.lineTo(t+11,n+6.5),e.moveTo(t+5.5,n),e.lineTo(t+5.5,n+6.5),e.stroke(),e.beginPath(),i===`wheel`?e.roundRect(t+4.2,n+1.8,2.6,4,1.3):(e.moveTo(t+5.5,n+.7),e.lineTo(t+5.5,n+6.5),e.lineTo(t+.7,n+6.5),e.arc(t+5.5,n+5.5,4.8,Math.PI,Math.PI*1.5)),e.fill(),i===`twice`&&(e.font=r(9,700),e.fillText(`2`,t+13,n+6))};return{name:`GTA`,animated:!0,instructions:!0,insets:e=>({top:48,right:i(e)?260:0,bottom:42,left:0}),background(t){let{context:n,width:i,height:o}=t,s=n.createRadialGradient(i*.45,o*.55,0,i*.45,o*.55,Math.hypot(i,o)*.62);s.addColorStop(0,`#1d3448`),s.addColorStop(1,`#0c1824`),n.fillStyle=s,n.fillRect(0,0,i,o);let c=e();if(c!==void 0){let[e,r]=t.toScreen(c.left,c.top),[i,a]=t.toScreen(c.right,c.bottom);n.drawImage(c.image,e,r,i-e,a-r)}else a(t,Te);F(t,{line:`rgba(140, 180, 215, 0.09)`,axis:`rgba(140, 180, 215, 0.26)`,text:`rgba(180, 205, 228, 0.5)`},r(10),[],48);let l=n.createRadialGradient(i/2,o/2,Math.min(i,o)*.4,i/2,o/2,Math.hypot(i,o)*.6);l.addColorStop(0,`rgba(0, 0, 0, 0)`),l.addColorStop(1,`rgba(0, 0, 0, 0.45)`),n.fillStyle=l,n.fillRect(0,0,i,o)},area(e,t,n,r){let{context:i}=e,a=A(t.colour),o=new Path2D;if(t.shape===`radius`)o.arc(n,r,(t.radius??0)*e.scale,0,Math.PI*2);else{let i=(t.width??0)*e.scale,a=(t.height??0)*e.scale;o.rect(n-i/2,r-a/2,i,a)}i.globalAlpha=t.alpha/255*.3,i.fillStyle=a,i.fill(o),i.globalAlpha=Math.max(t.alpha/255,.3)*.7,i.strokeStyle=a,i.lineWidth=1.5,i.stroke(o),i.globalAlpha=1,i.lineWidth=1},route(e,n,r){let{context:i,time:a}=e;i.lineCap=`round`;for(let[e,a]of[[`#16081c`,8],[t,4.5]])i.strokeStyle=e,i.lineWidth=a,i.beginPath(),i.moveTo(...n),i.lineTo(...r),i.stroke();let o=Math.hypot(r[0]-n[0],r[1]-n[1]),s=Math.atan2(r[1]-n[1],r[0]-n[0]);i.strokeStyle=`rgba(255, 255, 255, 0.8)`,i.lineWidth=1.6;for(let e=a/24%26;e<o-14;e+=26){let t=e/o;i.save(),i.translate(n[0]+(r[0]-n[0])*t,n[1]+(r[1]-n[1])*t),i.rotate(s),i.beginPath(),i.moveTo(-1.8,-2.6),i.lineTo(1.4,0),i.lineTo(-1.8,2.6),i.stroke(),i.restore()}i.lineCap=`butt`,i.lineWidth=1},blip(e,t,r,i,a){let{context:s,time:c}=e;if(t.sprite===8?e.claim(r-8,i-22,16,24,!0):t.shape!==`radius`&&t.shape!==`area`&&e.claim(r-9,i-9,18,18,!0),s.globalAlpha=Math.max(t.alpha/255,.3),s.strokeStyle=n,s.save(),s.translate(r,i),t.sprite===8)o(s);else if(t.shape!==`radius`&&t.shape!==`area`){let e=b(t.sprite);s.fillStyle=A(t.colour),e===void 0?(s.lineWidth=3,s.beginPath(),s.arc(0,0,5.5,0,Math.PI*2),s.stroke(),s.fill()):E(s,e,17,1.6)}if(s.restore(),s.globalAlpha=1,a){let e=15+Math.sin(c/160);s.strokeStyle=`#ffffff`,s.lineWidth=2;for(let t=0;t<4;t++){let n=t*Math.PI/2+Math.PI/4;s.beginPath(),s.arc(r,i,e,n-.42,n+.42),s.stroke()}s.lineWidth=1}},label(e,t,i,a,o){L(e,t.toUpperCase(),[[i+12,a+4,`left`],[i-12,a+4,`right`],[i,a+22,`center`],[i,a-14,`center`]],`#ffffff`,n,r(11,700),o)},tag(e,t,n,i,a){let{context:o}=e;o.font=r(11,700);let s=t.toUpperCase(),c=Math.ceil(o.measureText(s).width)+15,l=[[i-c/2,a+16],[i-c/2,a-33],[i+15,a-8.5],[i-15-c,a-8.5]],u=l[I(e,c,17,l,!0)];o.fillStyle=`rgba(0, 0, 0, 0.8)`,o.fillRect(u[0],u[1],c,17),o.fillStyle=n,o.fillRect(u[0],u[1],3,17),o.fillStyle=`#ffffff`,o.fillText(s,u[0]+9,u[1]+12.5)},entity(e,t,r,i,a,o){let{context:c,time:l}=e;if(t.kind===`player`){let n=o?.colour??`#ffffff`;e.claim(r-10,i-12,20,22,!0),c.save(),c.translate(r,i),c.rotate(R(t));let a=c.createRadialGradient(0,0,0,0,0,44);a.addColorStop(0,`rgba(255, 255, 255, 0.32)`),a.addColorStop(1,`rgba(255, 255, 255, 0)`),c.fillStyle=a,c.globalAlpha=.8+Math.sin(l/500)*.2,c.beginPath(),c.moveTo(0,0),c.arc(0,0,44,-Math.PI/2-.55,-Math.PI/2+.55),c.closePath(),c.fill(),c.globalAlpha=1,s(c,n),c.restore(),c.lineWidth=1}else if(t.kind===`vehicle`){c.save(),c.translate(r,i),c.rotate(R(t));let e=new Path2D;e.roundRect(-5,-9,10,18,3),c.lineWidth=3,c.strokeStyle=n,c.stroke(e),c.fillStyle=`#dbe3ea`,c.fill(e),c.fillStyle=`#2b3743`,c.beginPath(),c.roundRect(-3.6,-5,7.2,3.4,1),c.roundRect(-3.6,3.6,7.2,2.4,1),c.fill(),c.restore(),c.lineWidth=1}else c.lineWidth=2.5,c.strokeStyle=n,c.fillStyle=t.kind===`ped`?`#c9d1d9`:`#8b98a5`,c.beginPath(),t.kind===`ped`?c.arc(r,i,3.8,0,Math.PI*2):c.rect(r-3.5,i-3.5,7,7),c.stroke(),c.fill(),c.lineWidth=1;return[r,i]},dragging(e,t,n,r){let{context:i}=e;i.strokeStyle=`rgba(255, 255, 255, 0.7)`,i.lineWidth=1.5,i.setLineDash([5,5]),i.beginPath(),i.moveTo(...t),i.lineTo(...n),i.stroke(),i.setLineDash([]),i.save(),i.translate(...n),i.globalAlpha=.7,s(i,r.colour),i.restore(),i.globalAlpha=1,i.lineWidth=1},overlay(e,t,a,o){let{context:s,width:l,height:u}=e,d=s.createLinearGradient(0,0,0,48);d.addColorStop(0,`rgba(3, 6, 9, 0.94)`),d.addColorStop(1,`rgba(3, 6, 9, 0.78)`),s.fillStyle=d,s.fillRect(0,0,l,48),s.fillStyle=`rgba(255, 255, 255, 0.12)`,s.fillRect(0,47,l,1),s.fillStyle=`#ffffff`,s.font=`italic ${r(25,700)}`,s.fillText(`FIVERUNNER`,18,33);let f=s.measureText(`FIVERUNNER`).width,p=a.find(({client:e})=>e===o)?.colour??`#f0a030`;s.font=r(13,700);let m=s.measureText(`MAP`).width+28,h=18+f+18;s.fillStyle=`#ffffff`,s.fillRect(h,12,m,26),s.fillStyle=p,s.fillRect(h,12,m,3),s.fillStyle=`#05080b`,s.fillText(`MAP`,h+14,30.5),s.textAlign=`right`;let g=l-18;s.fillStyle=`rgba(220, 230, 240, 0.7)`,s.font=r(12,600);let _=`${t.length} ${t.length===1?`BLIP`:`BLIPS`}`;s.fillText(_,g,29),g-=s.measureText(_).width+22;for(let e of[...a].reverse()){if(e.name===void 0)continue;let t=e.name.toUpperCase();s.font=r(13,700),s.fillStyle=o===void 0||o===e.client?`#ffffff`:`rgba(255, 255, 255, 0.45)`,s.fillText(t,g,29);let n=s.measureText(t).width;if(s.fillStyle=e.colour,s.beginPath(),s.arc(g-n-9,25,4,0,Math.PI*2),s.fill(),g-=n+30,g<h+m+40)break}if(s.textAlign=`left`,i(l)){let e=new Map;for(let n of t){if(n.name===void 0)continue;let t=e.get(n.name);t===void 0?e.set(n.name,{blip:n,count:1}):t.count++}if(e.size>0){let t=[...e.entries()].sort(([e],[t])=>e.localeCompare(t)),i=l-236-14,a=Math.max(Math.floor((u-62-28-30-36)/22),1),o=t.length>a?t.slice(0,a-1):t,c=t.length-o.length,d=36+(o.length+ +(c>0))*22+6;s.fillStyle=`rgba(3, 6, 9, 0.78)`,s.fillRect(i,62,236,d),s.fillStyle=p,s.fillRect(i,62,236,2),s.fillStyle=`#ffffff`,s.font=r(14,700),s.fillText(`LEGEND`,i+12,86),s.textAlign=`right`,s.fillStyle=`rgba(220, 230, 240, 0.6)`,s.font=r(12,600),s.fillText(String(e.size),i+236-12,86),s.textAlign=`left`,o.forEach(([e,{blip:t,count:a}],o)=>{let c=98+o*22;o%2==0&&(s.fillStyle=`rgba(255, 255, 255, 0.035)`,s.fillRect(i,c,236,22)),s.save(),s.translate(i+22,c+11),s.fillStyle=A(t.colour),s.strokeStyle=n;let l=b(t.sprite);l===void 0?(s.lineWidth=2.4,s.beginPath(),s.arc(0,0,4.5,0,Math.PI*2),s.stroke(),s.fill()):E(s,l,14,1.2),s.restore(),s.font=r(12,600);let u=e.toUpperCase();for(;u.length>1&&s.measureText(u).width>146;)u=u.slice(0,-1);u!==e.toUpperCase()&&(u=`${u.trimEnd()}…`),s.fillStyle=`#eef3f8`,s.fillText(u,i+40,c+15.5),s.textAlign=`right`,s.fillStyle=`rgba(200, 215, 230, 0.55)`,s.font=r(11,600),s.fillText(`×${a}`,i+236-12,c+15.5),s.textAlign=`left`}),c>0&&(s.fillStyle=`rgba(200, 215, 230, 0.6)`,s.font=r(11,700),s.fillText(`+ ${c} MORE`,i+40,98+o.length*22+15.5))}}let v=[[`left`,`MOVE PLAYER`],[`twice`,`WAYPOINT`],[`wheel`,`ZOOM`]];s.font=r(11,700);let y=v.map(([,e])=>s.measureText(e).width+36),x=l-14-y.reduce((e,t)=>e+t,0)-8,S=u-14-28;s.fillStyle=`rgba(3, 6, 9, 0.78)`,s.fillRect(x,S,l-14-x,28),x+=12,v.forEach(([e,t],n)=>{c(s,x,S+6,e),s.fillStyle=`#ffffff`,s.font=r(11,700),s.fillText(t,x+22,S+18.5),x+=y[n]}),s.lineWidth=1}}}var De=7,Y={left:-4e3,right:4500,bottom:-4e3,top:8e3},X={top:0,right:0,bottom:0,left:0},Oe=450,ke=`fiverunner:map-style`,Ae=`fiverunner:map-image`;function je(e){try{return localStorage.getItem(e)}catch{return null}}function Z(e,t){try{localStorage.setItem(e,t)}catch{}}var Me=class{element;#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f={entities:[],blips:[]};#p=[];#m=(Y.left+Y.right)/2;#h=(Y.bottom+Y.top)/2;#g=.05;#_=!1;#v=[];#y=new Map;#b=new Map;#x=!1;#S=!0;#C;#w;constructor(e,t,n){this.element=e,this.#s=t,this.#l=n,this.#c=[V,Ce(),Ee(()=>this.#d)],this.#u=this.#c.find(({name:e})=>e===je(ke))??V;let r=document.createElement(`div`);r.className=`toolbar`;let i=document.createElement(`h2`);i.textContent=`Map`,this.#a=document.createElement(`select`),this.#a.setAttribute(`aria-label`,`Whose blips the map shows`),this.#a.addEventListener(`change`,()=>this.#R());let a=document.createElement(`select`);a.setAttribute(`aria-label`,`How the map looks`),a.append(...this.#c.map(({name:e})=>new Option(e,e))),a.value=this.#u.name,a.addEventListener(`change`,()=>{this.use(a.value),this.#s.styled?.(a.value)});let o=document.createElement(`button`);o.type=`button`,o.textContent=`Fit`,o.addEventListener(`click`,()=>{this.#_=!1,this.#M()}),this.#o=this.#E(),this.#i=document.createElement(`span`),this.#i.className=`hint`,this.#i.textContent=`Drag a player to move them, double-click to set their waypoint`,r.append(i,this.#a,a,o,this.#o,this.#i);let s=document.createElement(`div`);s.className=`view`,this.#n=s,this.#e=document.createElement(`canvas`),this.#t=this.#e.getContext(`2d`),this.#r=document.createElement(`div`),this.#r.className=`tooltip`,this.#r.hidden=!0,s.append(this.#e,this.#r),e.append(...n===void 0?[r,s]:[s]),new ResizeObserver(()=>this.#R()).observe(s),new IntersectionObserver(([e])=>{this.#S=e?.isIntersecting??!0,this.#T()}).observe(s),n===void 0&&this.#I(),this.use(this.#u.name)}show(e,t){let n=performance.now();for(let t of e.entities){let e=this.#b.get(t.id);if(this.#u.animated&&e!==void 0&&(e[0]!==t.x||e[1]!==t.y)){let[r,i]=this.#j(t.id,e,n);this.#y.set(t.id,{fromX:r,fromY:i,toX:t.x,toY:t.y,start:n})}this.#b.set(t.id,[t.x,t.y])}if(this.#f=e,t.map(({client:e,name:t})=>`${e} ${t}`).join()!==this.#p.map(({client:e,name:t})=>`${e} ${t}`).join()){let e=this.#a.value;this.#a.replaceChildren(new Option(`Blips of every player`,``),...t.map(({client:e,name:t})=>new Option(`Blips of ${t} (${e})`,String(e)))),this.#a.value=t.some(({client:t})=>String(t)===e)?e:``}this.#p=t,this.#_?this.#R():this.#M()}use(e){this.#u=this.#c.find(t=>t.name===e)??V,this.#l===void 0&&Z(ke,this.#u.name),this.#y.clear(),this.#o.hidden=this.#u.name!==`GTA`,this.#i.hidden=this.#u.instructions===!0,this.#n.dataset.style=this.#u.name,this.#_?this.#R():this.#M(),this.#T()}#T(){if(this.#x||!this.#u.animated||!this.#S)return;this.#x=!0;let e=()=>{!this.#u.animated||!this.#S?this.#x=!1:(this.#R(),requestAnimationFrame(e))};requestAnimationFrame(e)}#E(){let e=document.createElement(`details`);e.className=`map-image`;let t=document.createElement(`summary`);t.textContent=`Map image`;let n=document.createElement(`input`);n.type=`file`,n.accept=`image/*`,n.setAttribute(`aria-label`,`An image of the world to show under the map`);let r=JSON.parse(je(Ae)??`null`)??[Y.left,Y.top,Y.right,Y.bottom],i=[`Left`,`Top`,`Right`,`Bottom`].map((e,t)=>{let n=document.createElement(`input`);return n.type=`number`,n.value=String(r[t]),n.setAttribute(`aria-label`,`The ${e.toLowerCase()} edge of the image, in metres of the world`),n.title=`${e} edge, in metres`,n}),a,o=()=>{let[e,t,n,r]=i.map(e=>Number(e.value));Z(Ae,JSON.stringify([e,t,n,r])),this.#d=a===void 0?void 0:{image:a,left:e,top:t,right:n,bottom:r},this.#R()};n.addEventListener(`change`,()=>{let e=n.files?.[0];if(e===void 0)return;let t=new Image;t.addEventListener(`load`,()=>{a=t,o()}),t.src=URL.createObjectURL(e)});for(let e of i)e.addEventListener(`change`,o);return e.append(t,n,...i),e}get#D(){let e=this.#a.value;return e===``?this.#f.blips:this.#f.blips.filter(({client:t})=>String(t)===e)}get#O(){let e=this.#a.value;return e===``?void 0:Number(e)}get#k(){return this.#p.map(({client:e,name:t})=>{let n=this.#f.entities.find(({kind:t,owner:n})=>t===`player`&&n===e)?.look;return{client:e,name:t,colour:j(e),...n===void 0?{}:{look:n}}})}get#A(){let e=this.#a.value;return e===``?this.#p.find(({state:e})=>e===`joined`)?.client:Number(e)}#j(e,t,n){let r=this.#y.get(e);if(r===void 0)return[t[0],t[1]];let i=Math.min((n-r.start)/Oe,1);i===1&&this.#y.delete(e);let a=1-(1-i)**3;return[r.fromX+(r.toX-r.fromX)*a,r.fromY+(r.toY-r.fromY)*a]}#M(){if(this.#l!==void 0)return this.#R();let e=[...this.#D,...this.#f.entities],t=this.#e.getBoundingClientRect();if(t.width===0||t.height===0)return;let n=this.#u.insets?.(t.width,t.height)??X,r=Math.max(t.width-n.left-n.right,80),i=Math.max(t.height-n.top-n.bottom,80),a=Y.left,o=Y.right,s=Y.bottom,c=Y.top;e.length>0&&(a=Math.min(...e.map(({x:e})=>e)),o=Math.max(...e.map(({x:e})=>e)),s=Math.min(...e.map(({y:e})=>e)),c=Math.max(...e.map(({y:e})=>e)));let l=Math.max(o-a,c-s,200)*.15;this.#g=Math.min(r/(o-a+2*l),i/(c-s+2*l)),this.#m=(a+o)/2-(n.left-n.right)/2/this.#g,this.#h=(s+c)/2+(n.top-n.bottom)/2/this.#g,this.#R()}#N(){return this.#l??this.#e.getBoundingClientRect()}#P(e,t){let{width:n,height:r}=this.#N();return[(e-this.#m)*this.#g+n/2,(this.#h-t)*this.#g+r/2]}#F(e,t){let{width:n,height:r}=this.#N();return[(e-n/2)/this.#g+this.#m,this.#h-(t-r/2)/this.#g]}#I(){let e=this.#e,t=t=>{let n=e.getBoundingClientRect();return[t.clientX-n.left,t.clientY-n.top]};e.addEventListener(`wheel`,e=>{e.preventDefault(),this.#_=!0;let[n,r]=t(e),[i,a]=this.#F(n,r);this.#g=Math.min(Math.max(this.#g*(e.deltaY<0?1.25:.8),.005),40);let[o,s]=this.#F(n,r);this.#m+=i-o,this.#h+=a-s,this.#R()}),e.addEventListener(`mousedown`,e=>{let[n,r]=t(e),i=this.#L(n,r);i?.kind===`entity`&&i.entity.kind===`player`&&i.entity.owner!==void 0?(this.#_=!0,this.#w={kind:`player`,client:i.entity.owner,x:n,y:r}):this.#w={kind:`pan`,x:n,y:r,cx:this.#m,cy:this.#h}}),e.addEventListener(`mousemove`,e=>{let[n,r]=t(e),i=this.#w;i?.kind===`pan`?(this.#_=!0,this.#m=i.cx-(n-i.x)/this.#g,this.#h=i.cy+(r-i.y)/this.#g):i?.kind===`player`?(i.x=n,i.y=r):this.#C=this.#L(n,r)?.key,this.#R()}),e.addEventListener(`mouseup`,e=>{let n=this.#w;if(this.#w=void 0,n?.kind===`player`){let r=this.#L(...t(e),`blip`);r?.kind===`blip`?this.#s.teleport(n.client,r.blip.x,r.blip.y,r.blip.z):this.#s.teleport(n.client,...this.#F(...t(e)))}this.#R()}),e.addEventListener(`mouseleave`,()=>{this.#w=void 0,this.#C=void 0,this.#R()}),e.addEventListener(`dblclick`,e=>{let n=this.#A;if(n===void 0)return;let[r,i]=this.#F(...t(e));this.#s.waypoint(n,r,i)})}#L(e,t,n){let r,i=12;for(let a of this.#v){if(n!==void 0&&a.kind!==n)continue;let o=Math.hypot(a.sx-e,a.sy-t);o<=i&&(i=o,r=a)}return r}#R(){let e=this.#e,t=e.getBoundingClientRect();if(t.width===0||t.height===0)return;let{width:n,height:r}=this.#N(),i=devicePixelRatio*(t.width/n);(e.width!==Math.round(t.width*devicePixelRatio)||e.height!==Math.round(t.height*devicePixelRatio))&&(e.width=Math.round(t.width*devicePixelRatio),e.height=Math.round(t.height*devicePixelRatio));let a=performance.now(),o=this.#l;if(o!==void 0){let e=this.#f.entities.find(({kind:e,owner:t})=>e===`player`&&t===o.client);e!==void 0&&([this.#m,this.#h]=this.#j(e.id,[e.x,e.y],a)),this.#g=De}e.dataset.view=`${this.#m} ${this.#h} ${this.#g}`,e.dataset.players=JSON.stringify(this.#f.entities.flatMap(({kind:e,owner:t,x:n,y:r})=>e===`player`&&t!==void 0?[[t,n,r]]:[]));let s=this.#t;s.setTransform(i,0,0,i,0,0);let c=[],l={context:s,width:n,height:r,ratio:i,bare:o!==void 0,scale:this.#g,time:a,toScreen:(e,t)=>this.#P(e,t),toWorld:(e,t)=>this.#F(e,t),claim:(e,t,n,r,i=!1)=>{let a=!c.some(([i,a,o,s])=>e<i+o&&i<e+n&&t<a+s&&a<t+r);return(a||i)&&c.push([e,t,n,r]),a||i},crowding:(e,t,n,r)=>c.reduce((i,[a,o,s,c])=>i+Math.max(0,Math.min(e+n,a+s)-Math.max(e,a))*Math.max(0,Math.min(t+r,o+c)-Math.max(t,o)),0)},u=this.#u,d=this.#D,f=o===void 0?u.insets?.(n,r)??X:X;l.claim(0,0,n,f.top,!0),l.claim(n-f.right,0,f.right,r,!0),l.claim(0,r-f.bottom,n,f.bottom,!0),l.claim(0,0,f.left,r,!0),u.background(l,d),this.#v=[];let p=this.#f.entities.map(e=>{let t=this.#y.has(e.id),[n,r]=this.#j(e.id,[e.x,e.y],a);return{entity:e,moving:t,at:this.#P(n,r)}});for(let e of d)(e.shape===`radius`||e.shape===`area`)&&u.area(l,e,...this.#P(e.x,e.y));for(let e of d){if(!e.route)continue;let t=p.find(({entity:t})=>t.kind===`player`&&t.owner===e.client);t!==void 0&&u.route(l,t.at,this.#P(e.x,e.y),A(e.colour))}for(let e of d){let[t,n]=this.#P(e.x,e.y),r=`blip ${e.client} ${e.handle}`;this.#v.push({key:r,kind:`blip`,blip:e,sx:t,sy:n}),u.blip(l,e,t,n,this.#C===r)}let m=this.#k,h=[];for(let{entity:e,moving:t,at:n}of[...p].sort((e,t)=>e.at[1]-t.at[1])){let r=e.kind===`player`&&e.owner!==void 0?m.find(({client:t})=>t===e.owner)??{client:e.owner,name:void 0,colour:j(e.owner)}:void 0,[i,a]=u.entity(l,e,...n,t,r);this.#v.push({key:`entity ${e.id}`,kind:`entity`,entity:e,sx:i,sy:a}),r?.name!==void 0&&h.push([r.name,r.colour,...n])}for(let e of h)u.tag(l,...e);let g=this.#C,_=this.#v.filter(e=>e.kind===`blip`&&(e.key===g||this.#g>=.12));_.sort((e,t)=>Number(t.key===g)-Number(e.key===g));for(let e of _)e.kind===`blip`&&e.blip.name!==void 0&&u.label(l,e.blip.name,e.sx,e.sy,e.key===g);let v=this.#w;if(v?.kind===`player`){let e=p.find(({entity:e})=>e.kind===`player`&&e.owner===v.client)?.at,t=m.find(({client:e})=>e===v.client);u.dragging!==void 0&&e!==void 0&&t!==void 0?u.dragging(l,e,[v.x,v.y],t):(s.strokeStyle=j(v.client),s.setLineDash([4,4]),s.beginPath(),s.arc(v.x,v.y,9,0,Math.PI*2),s.stroke(),s.setLineDash([]))}o===void 0&&u.overlay?.(l,d,m,this.#O),this.#z()}#z(){let e=this.#w===void 0?this.#C:void 0,t=this.#v.find(({key:t})=>t===e);if(this.#r.hidden=t===void 0,t===void 0)return;let n=e=>this.#p.find(t=>t.client===e)?.name??`nobody`,r=(e,t)=>`${e.toFixed(1)}, ${t.toFixed(1)}`;this.#r.textContent=t.kind===`blip`?`${t.blip.name??(t.blip.sprite===8?`Waypoint`:`Blip`)}\n${r(t.blip.x,t.blip.y)}\nsprite ${t.blip.sprite}, colour ${t.blip.colour}\n${t.blip.script??`the player`}, on the map of ${n(t.blip.client)}`:`${t.entity.kind} ${t.entity.id}, model 0x${(t.entity.model>>>0).toString(16)}\n${r(t.entity.x,t.entity.y)}, z ${t.entity.z.toFixed(1)}, heading ${t.entity.heading.toFixed(0)}\nowned by ${n(t.entity.owner)}`,this.#r.style.left=`${t.sx+14}px`,this.#r.style.top=`${t.sy+14}px`}},Q=1920,Ne=1080,Pe=250,Fe={Escape:`ESCAPE`,Enter:`RETURN`,Backspace:`BACK`,Tab:`TAB`,Space:`SPACE`,CapsLock:`CAPITAL`,ShiftLeft:`LSHIFT`,ShiftRight:`RSHIFT`,ControlLeft:`LCONTROL`,ControlRight:`RCONTROL`,AltLeft:`LMENU`,AltRight:`RMENU`,ArrowUp:`UP`,ArrowDown:`DOWN`,ArrowLeft:`LEFT`,ArrowRight:`RIGHT`,PageUp:`PAGEUP`,PageDown:`PAGEDOWN`,Home:`HOME`,End:`END`,Insert:`INSERT`,Delete:`DELETE`,NumpadMultiply:`MULTIPLY`,NumpadAdd:`ADD`,NumpadSubtract:`SUBTRACT`,NumpadDecimal:`DECIMAL`,NumpadDivide:`DIVIDE`};function Ie(e){return/^Key[A-Z]$/.test(e)?e.slice(3):/^Digit\d$/.test(e)?e.slice(5):/^F\d{1,2}$/.test(e)?e:/^Numpad\d$/.test(e)?`NUMPAD${e.slice(6)}`:Fe[e]}var Le=class{element;world;#e;#t;#n;#r=new Map;#i=new Map;#a=new Map;#o=0;#s=[];#c=[];#l=1;#u=new Set;constructor(e,t){this.#n=t,this.element=document.createElement(`div`),this.element.className=`screen`,this.element.tabIndex=0;let n=document.createElement(`div`);n.className=`world`,this.world=new Me(n,{teleport:()=>{},waypoint:()=>{}},{client:e,width:Q/2,height:Ne/2}),this.#e=document.createElement(`div`),this.#e.className=`fade`,this.element.append(n,this.#e),this.#t=document.createElement(`div`),this.#t.className=`viewport`,this.#t.style.width=`${Q}px`,this.#t.style.height=`${Ne}px`,this.element.append(this.#t),new ResizeObserver(()=>{this.#l=this.element.clientWidth/Q,this.#t.style.transform=`scale(${this.#l})`}).observe(this.element),this.element.addEventListener(`keydown`,e=>this.#m(e,!0)),this.element.addEventListener(`keyup`,e=>this.#m(e,!1)),this.element.addEventListener(`blur`,()=>{for(let e of this.#u)this.#n.key(e,!1);this.#u.clear()}),this.element.addEventListener(`mousedown`,()=>this.element.focus()),this.element.addEventListener(`mousemove`,e=>{let t=this.#t.getBoundingClientRect();this.#h((e.clientX-t.left)/this.#l,(e.clientY-t.top)/this.#l)})}frameOf(e){for(let[t,n]of this.#r)if(n.contentWindow===e)return t}fade(e){this.#e.style.opacity=String(e)}blur(e){this.element.classList.toggle(`blurred`,e)}cursorOver(e,t){this.#h(e,t)}async create({resource:e,url:t}){let n=++this.#o;this.#a.set(e,n),this.#i.set(e,[]);let r=this.#n.frame(t);if(await this.#n.ready(r),this.#a.get(e)!==n)return;this.#a.delete(e);let i=document.createElement(`iframe`);i.name=e,i.style.visibility=`hidden`,i.allow=`microphone *; camera *; autoplay; payment 'none'; geolocation 'none';`,i.sandbox.value=`allow-forms allow-scripts allow-same-origin`,i.src=r,i.tabIndex=-1,i.addEventListener(`load`,()=>{i.style.visibility=`visible`,setTimeout(()=>{for(let t of this.#i.get(e)??[])this.#d(i,t);this.#i.delete(e)},Pe)}),this.#r.set(e,i),this.#s.push(e);let a=document.activeElement;this.#t.append(i),a instanceof HTMLIFrameElement&&a!==i&&a.focus()}destroy(e){this.#a.delete(e),this.#i.delete(e);let t=this.#r.get(e);t!==void 0&&(this.#s=this.#s.filter(t=>t!==e),t.remove(),this.#r.delete(e))}message(e,t){let n=this.#i.get(e),r=this.#r.get(e);n===void 0?r!==void 0&&this.#d(r,t):n.push(t)}#d(e,t){e.contentWindow?.postMessage(JSON.parse(t),`*`)}frameFocus(e,t){t?this.#f(e):this.#p(e)}zIndex(e,t){let n=this.#r.get(e);n!==void 0&&(n.style.zIndex=String(t))}focus(e,t){this.element.classList.toggle(`nui-cursor`,t),this.element.classList.toggle(`nui-focus`,e);let n=document.activeElement;!e&&n instanceof HTMLIFrameElement&&this.frameOf(n.contentWindow)&&this.element.focus()}#f(e){this.#s=[...this.#s.filter(t=>t!==e),e],this.#c=[e,...this.#c.filter(t=>t!==e)],this.#s.forEach((e,t)=>{let n=this.#r.get(e);n!==void 0&&(n.style.zIndex=String(t))});let t=this.#r.get(e);t!==void 0&&(t.style.zIndex=`99999`,t.contentWindow?.focus())}#p(e){this.#c=this.#c.filter(t=>t!==e),this.#r.get(e)?.contentWindow?.blur();let[t]=this.#c;t!==void 0&&this.#f(t)}#m(e,t){let n=Ie(e.code);if(n!==void 0&&e.target===this.element&&(e.preventDefault(),!(t&&e.repeat))){if(t)this.#u.add(n);else if(!this.#u.delete(n))return;this.#n.key(n,t)}}#h(e,t){this.#n.cursor(Math.round(e),Math.round(t))}};function $(e){return document.getElementById(e)}function Re({worker:e,frames:t,project:n,watch:r}){let i=t=>e.postMessage(t),o=$(`status`),s=$(`project`),u=new c($(`console`)),f=$(`resources-list`),m=$(`player-list`),h=new d($(`events`),$(`emit`),{emit:(e,t,n)=>i({type:`emit`,name:e,args:t,target:n})}),g=$(`bags`),v=new Me($(`map`),{teleport:(e,t,n,r)=>i({type:`teleport`,client:e,x:t,y:n,...r===void 0?{}:{z:r}}),waypoint:(e,t,n)=>i({type:`waypoint`,client:e,x:t,y:n}),styled:e=>{for(let t of b.values())t.screen.world.use(e)}}),y=new _({process:$(`inspected`),resources:$(`inspected-resources`),details:$(`inspected-details`),filter:$(`convar-filter`),convars:$(`convars`),form:$(`evaluate`),code:$(`code`)},{inspect:e=>i({type:`inspect`,process:e}),evaluate:(e,t,n)=>{(e===`server`?u:w(e).console).note(`${t}> ${n}`),i({type:`evaluate`,process:e,resource:t,code:n})}}),b=new Map,x=new Map,S=0;t.listen((e,t,n,r)=>{let a=S++;x.set(a,r),i({type:`ask`,id:a,client:e,host:t,ask:n})});function C(e,t){o.textContent=e,o.className=t}function w(e){let n=b.get(e);if(n!==void 0)return n;let r=document.createElement(`article`);r.className=`player`;let a=document.createElement(`header`),o=document.createElement(`span`);o.className=`info`;let s=document.createElement(`button`);s.textContent=`Enlarge`,s.addEventListener(`click`,()=>{let e=r.classList.toggle(`large`);s.textContent=e?`Shrink`:`Enlarge`});let l=document.createElement(`button`);l.textContent=`Disconnect`,l.addEventListener(`click`,()=>i({type:`disconnect`,client:e})),a.append(o,s,l);let u=document.createElement(`div`);u.className=`card`,u.hidden=!0;let d=new Le(e,{frame:n=>t.url(n,e),ready:e=>t.ready(e),cursor:(t,n)=>i({type:`cursor`,client:e,x:t,y:n}),key:(t,n)=>i({type:`key`,client:e,key:t,down:n})}),f=document.createElement(`div`);return f.className=`console small`,r.append(a,d.element,u,f),m.append(r),n={element:r,info:o,card:u,screen:d,console:new c(f),cardJson:void 0},b.set(e,n),n}function T(e,t,n){let r=n.state===`connecting`?n.card:void 0;if(t.cardJson===r||(t.cardJson=r,t.card.replaceChildren(),t.card.hidden=r===void 0,r===void 0))return;let o=a(r,t=>i({type:`submitCard`,client:e,json:t}));if(o!==void 0){t.card.append(o);return}let s=document.createElement(`pre`);s.textContent=r;let c=document.createElement(`form`),l=document.createElement(`textarea`);l.value=`{}`,l.setAttribute(`aria-label`,`What the card submits, as JSON`);let u=document.createElement(`button`);u.textContent=`Submit card`,c.append(l,u),c.addEventListener(`submit`,t=>{t.preventDefault(),i({type:`submitCard`,client:e,json:l.value})}),t.card.append(s,c)}function ee(e){f.replaceChildren(...e.resources.map(({name:e,state:t})=>{let n=document.createElement(`li`),r=document.createElement(`span`);r.textContent=e;let a=document.createElement(`span`);a.className=`state ${t}`,a.textContent=t,n.append(r,a);for(let r of t===`started`?[`restart`,`stop`]:[`start`]){let t=document.createElement(`button`);t.textContent=r,t.addEventListener(`click`,()=>i({type:`command`,line:`${r} "${e}"`})),n.append(t)}return n})),h.players(e.players),y.players(e.players),p(g,e.bags),v.show(e.map,e.players);for(let t of e.players){let n=w(t.client),r=t.state===`dropped`||t.state===`rejected`,i=t.state===`connecting`?t.message?.trim():void 0,a=t.rejection??i;n.info.textContent=`${t.name} (id ${t.id}) ${t.state}${a?`: ${a}`:``}`,n.element.classList.toggle(`gone`,r),n.screen.world.show(e.map,e.players),n.screen.fade(t.fade??0),n.screen.blur(t.blurred===!0),T(t.client,n,t)}}function E(e,t){let{screen:n}=w(e);switch(t.type){case`create`:n.create(t.frame);break;case`destroy`:n.destroy(t.resource);break;case`message`:n.message(t.resource,t.json);break;case`frameFocus`:n.frameFocus(t.resource,t.focused);break;case`focus`:n.focus(t.focus,t.cursor);break;case`zIndex`:n.zIndex(t.resource,t.zIndex)}}function te(e){let t=/^client (\d+)$/.exec(e.process)?.[1];t===void 0?u.add(e):w(Number(t)).console.add(e)}function D(e){C(`Starting`,`starting`),u.note(e),h.note(e);for(let e of b.values())e.element.remove();b.clear();let t=n();i({type:`start`,...t===void 0?{}:{project:t}})}e.addEventListener(`message`,e=>{let t=e.data;switch(t.type){case`started`:s.textContent=t.project.name,document.title=`${t.project.name} - FiveRunner`,C(`Running`,`running`);break;case`failed`:C(`Failed: ${t.message}`,`failed`),u.note(t.message);break;case`changed`:t.restarted===null?D(`Files changed`):t.restarted.length>0&&u.note(`Files changed: restarted ${t.restarted.join(`, `)}`);break;case`event`:{let{event:e}=t;e.type===`output`?te(e.line):e.type===`state`?ee(e.state):e.type===`nui`?E(e.client,e.event):e.type===`net`?h.add(e.event):(C(`Crashed`,`failed`),u.note(e.message));break}case`inspection`:y.show(t.inspection);break;case`answer`:x.get(t.id)?.(t.answer),x.delete(t.id)}}),addEventListener(`message`,e=>{for(let t of b.values()){let n=t.screen.frameOf(e.source);if(n===void 0)continue;let r=e.data;r.type===`fiverunner:cursor`&&typeof r.x==`number`&&typeof r.y==`number`?t.screen.cursorOver(r.x,r.y):r.type===`fiverunner:invokeNative`&&t.console.note(`${n} called invokeNative('${String(r.native)}', '${String(r.arg)}')`);return}}),$(`command`).addEventListener(`submit`,e=>{e.preventDefault();let t=$(`command-line`),n=t.value;n.trim()!==``&&(O(n),u.note(`> ${n}`),i({type:`command`,line:n}),t.value=``)});let O=l($(`command-line`));$(`connect`).addEventListener(`submit`,e=>{e.preventDefault();let t=$(`player-name`).value.trim();i({type:`connect`,name:t===``?`Player`:t})}),$(`restart`).addEventListener(`click`,()=>D(`Restarted`)),r(e=>i({type:`change`,paths:e})),D(`Started`)}var ze=`fiverunner.localhost`,Be=new TextEncoder,Ve=new TextDecoder;function He({host:e,client:t,tab:n}){let r=e.replace(/[A-Z]/g,e=>e.toLowerCase());return`${/^[a-z0-9_-]+$/.test(r)?r:`${Array.from(Be.encode(r),e=>e.toString(16).padStart(2,`0`)).join(``)}.x`}.c${t}.${n}.${ze}`}function Ue(e){let t=/^(.+)\.c([1-9][0-9]*)\.([a-z0-9]+)\.fiverunner\.localhost$/.exec(e);if(t===null)return;let[,n=``,r=``,i=``]=t,a=Number(r);if(/^[a-z0-9_-]+$/.test(n))return{host:n,client:a,tab:i};let o=/^((?:[0-9a-f]{2})+)\.x$/.exec(n)?.[1];if(o===void 0)return;let s=Uint8Array.from(o.match(/../g),e=>parseInt(e,16));return{host:Ve.decode(s),client:a,tab:i}}function We(e,t,n,r){let i=/^(?:nui:\/\/|https:\/\/(?=cfx-nui-))([^/?#]*)(.*)$/i.exec(e);if(i===null)return e;let[,a=``,o=``]=i,s=o.startsWith(`/`)?o:`/${o}`;return`http://${He({host:a,client:t,tab:n})}${r===``?``:`:${r}`}${s}`}function Ge(){let e=`fiverunner:tab`;try{let t=sessionStorage.getItem(e);if(t!==null&&/^[a-z0-9]{1,16}$/.test(t))return t;let n=Math.random().toString(36).slice(2,10);return sessionStorage.setItem(e,n),n}catch{return Math.random().toString(36).slice(2,10)}}var Ke=class{#e=Ge();#t;#n=new Map;#r=new Map;#i=()=>{};constructor(e){this.#t=e,addEventListener(`message`,e=>{let t=this.#n.get(e.origin);if(t===void 0||e.source!==t.frame.contentWindow)return;let n=e.data;n.type===`fiverunner:bridge`?this.#r.get(e.origin)?.():n.type===`fiverunner:ask`&&this.#a(e.origin,t.frame,n.id,n.ask)})}url(e,t){return We(e,t,this.#e,location.port)}ready(t){let n=new URL(t);if(Ue(n.hostname)===void 0)return Promise.resolve();let{origin:r}=n,i=this.#n.get(r);if(i===void 0){let t=document.createElement(`iframe`);t.src=`${r}${e}bridge.html`,t.title=`FiveRunner NUI bridge`,i={frame:t,ready:new Promise(e=>this.#r.set(r,e))},this.#n.set(r,i),this.#t.append(t)}return i.ready}listen(e){this.#i=e}#a(e,t,n,r){let i=Ue(new URL(e).hostname);i!==void 0&&i.tab===this.#e&&this.#i(i.client,i.host,r,r=>{let i={type:`fiverunner:answer`,id:n,answer:r};t.contentWindow?.postMessage(i,e)})}};Re({worker:new Worker(new URL(`/__fiverunner/assets/worker-BnznZQ2X.js`,``+import.meta.url),{type:`module`}),frames:new Ke(document.getElementById(`bridges`)),project:()=>void 0,watch(e){new EventSource(`${t}events`).addEventListener(`change`,t=>e(JSON.parse(t.data)))}});
|
package/dist/dev/index.html
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
6
6
|
<title>FiveRunner</title>
|
|
7
7
|
<link rel="icon" type="image/svg+xml" href="/__fiverunner/logo.svg" />
|
|
8
|
-
<script type="module" crossorigin src="/__fiverunner/assets/index-
|
|
8
|
+
<script type="module" crossorigin src="/__fiverunner/assets/index-BEO79shi.js"></script>
|
|
9
9
|
<link rel="modulepreload" crossorigin href="/__fiverunner/assets/routes-DFIWFSAi.js">
|
|
10
10
|
<link rel="stylesheet" crossorigin href="/__fiverunner/assets/index-BrojKg9W.css">
|
|
11
11
|
</head>
|
package/dist/fiverunner.js
CHANGED
|
@@ -6,20 +6,27 @@ import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "nod
|
|
|
6
6
|
import { createServer } from "node:http";
|
|
7
7
|
var package_default = {
|
|
8
8
|
name: "fiverunner",
|
|
9
|
-
version: "1.
|
|
9
|
+
version: "1.5.0",
|
|
10
10
|
description: "Run FiveM resources (Lua, JavaScript and NUI) in your browser and in CI. No GTA V, no server, no restarts.",
|
|
11
11
|
keywords: [
|
|
12
12
|
"fivem",
|
|
13
13
|
"cfx",
|
|
14
|
+
"fxserver",
|
|
15
|
+
"txadmin",
|
|
14
16
|
"gta5",
|
|
15
17
|
"qbcore",
|
|
16
18
|
"qbox",
|
|
17
19
|
"esx",
|
|
20
|
+
"ox_lib",
|
|
21
|
+
"oxmysql",
|
|
18
22
|
"lua",
|
|
19
23
|
"nui",
|
|
20
24
|
"emulator",
|
|
21
25
|
"testing",
|
|
22
|
-
"ci"
|
|
26
|
+
"ci",
|
|
27
|
+
"audit",
|
|
28
|
+
"security",
|
|
29
|
+
"mcp"
|
|
23
30
|
],
|
|
24
31
|
homepage: "https://github.com/DariusHQ/fiverunner#readme",
|
|
25
32
|
bugs: "https://github.com/DariusHQ/fiverunner/issues",
|
|
@@ -102754,7 +102761,7 @@ function text$1(value) {
|
|
|
102754
102761
|
}
|
|
102755
102762
|
//#endregion
|
|
102756
102763
|
//#region src/cli/audit.lua?raw
|
|
102757
|
-
var audit_default = "-- FiveRunner's audit, which `fiverunner audit` runs as a test of the project:\n-- it triggers each event of the server that clients may trigger, from a\n-- player, with the arguments that cheaters give, and tells what each changed\n-- of what the player has, of the database and of the world, as lines of JSON.\n\nlocal MARK = 'fiverunner:audit '\n\n--- Tells `fiverunner audit` of something, as a line of JSON.\nlocal function tell(record)\n print(MARK .. json.encode(record))\nend\n\nlocal function started(name)\n return GetResourceState(name) == 'started'\nend\n\n-- The framework that logs players in, and the inventory that holds their items.\nlocal framework = started('qbx_core') and 'qbx' or started('qb-core') and 'qb' or started('es_extended') and 'esx' or nil\nlocal oxInventory = started('ox_inventory')\n\nlocal CHARINFO = { firstname = 'Audit', lastname = 'Player', birthdate = '1990-01-01', gender = 0, nationality = 'Romania' }\n\nlocal core\n\n--- The shared object of QBCore or ESX, which exports copy whole, so once.\nlocal function coreOf()\n if core == nil then\n if framework == 'qb' then core = exports['qb-core']:GetCoreObject() end\n if framework == 'esx' then core = exports.es_extended:getSharedObject() end\n end\n return core\nend\n\n--- The object of the framework for a player, once it logged in.\nlocal function frameworkPlayer(id)\n local ok, found = pcall(function()\n if framework == 'qbx' then return exports.qbx_core:GetPlayer(id) end\n if framework == 'qb' then return coreOf().Functions.GetPlayer(id) end\n if framework == 'esx' then return coreOf().GetPlayerFromId(id) end\n end)\n return ok and found or nil\nend\n\n--- Whether the client of `player` sent the page of `resource` a message of `action`.\nlocal function sent(player, resource, action)\n for _, message in ipairs(player:nuiMessages(resource)) do\n if message.action == action then return true end\n end\n return false\nend\n\nlocal joined = 0\n\n--- Connects a player and logs it in with a new character, as the framework of the server has players do.\nlocal function join()\n joined = joined + 1\n local player, why = fiverunner.connect({ name = 'audit' .. joined })\n if not player then return nil, why end\n pcall(function()\n if framework == 'qbx' then\n exports.qbx_core:Login(player.id, nil, { charinfo = CHARINFO })\n elseif framework == 'qb' and started('qb-multicharacter') then\n fiverunner.waitFor(function() return sent(player, 'qb-multicharacter', 'ui') end, 10000)\n player:nuiCallback('qb-multicharacter', 'createNewCharacter', {\n firstname = 'Audit', lastname = 'Player', nationality = 'Romania', birthdate = '1990-01-01', gender = 'Male', cid = 1,\n })\n elseif framework == 'qb' then\n coreOf().Player.Login(player.id, false, { charinfo = CHARINFO })\n end\n end)\n if framework then\n pcall(fiverunner.waitFor, function() return frameworkPlayer(player.id) end, 10000)\n end\n return player\nend\n\n--- Whether `player` is still on the server, and still logged in to its framework.\nlocal function present(player)\n if GetPlayerName(player.id) == nil then return false end\n return framework == nil or frameworkPlayer(player.id) ~= nil\nend\n\n--- What `player` has: money by account, items by name, job, gang, group, and whether it may run every command.\nlocal function holdings(player)\n local held = { money = {}, items = {}, admin = IsPlayerAceAllowed(player.id, 'command') }\n local found = frameworkPlayer(player.id)\n pcall(function()\n if found and framework == 'esx' then\n for account, money in pairs(found.getAccounts(true)) do held.money[account] = money end\n if not oxInventory then\n for name, count in pairs(found.getInventory(true)) do held.items[name] = count end\n end\n local job = found.getJob()\n held.job = ('%s %s'):format(job.name, job.grade)\n held.group = found.getGroup()\n elseif found then\n local data = found.PlayerData\n for account, money in pairs(data.money or {}) do held.money[account] = money end\n if not oxInventory then\n for _, item in pairs(data.items or {}) do\n held.items[item.name] = (held.items[item.name] or 0) + (item.amount or item.count or 0)\n end\n end\n if data.job then held.job = ('%s %s'):format(data.job.name, data.job.grade and data.job.grade.level) end\n if data.gang then held.gang = ('%s %s'):format(data.gang.name, data.gang.grade and data.gang.grade.level) end\n end\n end)\n if oxInventory then\n pcall(function()\n for _, item in pairs(exports.ox_inventory:GetInventoryItems(player.id) or {}) do\n held.items[item.name] = (held.items[item.name] or 0) + item.count\n end\n end)\n end\n return held\nend\n\nlocal function byText(a, b)\n return a.text < b.text\nend\n\n--- What `player` gained from `before` to `after`, as { kind, text }, with\n--- kind money, item or field, and the money that it lost, as words.\nlocal function diff(before, after)\n local gained, lost = {}, {}\n for account, money in pairs(after.money) do\n local was = before.money[account] or 0\n if type(money) == 'number' and type(was) == 'number' then\n if money > was then\n gained[#gained + 1] = { kind = 'money', text = ('%s +%s'):format(account, money - was) }\n elseif money < was then\n lost[#lost + 1] = ('%s -%s'):format(account, was - money)\n end\n end\n end\n for name, count in pairs(after.items) do\n local was = before.items[name] or 0\n if count > was then gained[#gained + 1] = { kind = 'item', text = ('item %s +%s'):format(name, count - was) } end\n end\n for _, field in ipairs({ 'job', 'gang', 'group' }) do\n if after[field] ~= before[field] and after[field] ~= nil then\n gained[#gained + 1] = { kind = 'field', text = ('%s %s'):format(field, after[field]) }\n end\n end\n if after.admin and not before.admin then gained[#gained + 1] = { kind = 'field', text = 'every command' } end\n table.sort(gained, byText)\n table.sort(lost)\n return gained, lost\nend\n\n--- Whether `changes` has any of `kind`.\nlocal function has(changes, kind)\n for _, change in ipairs(changes) do\n if change.kind == kind then return true end\n end\n return false\nend\n\n--- What `player` holds once it stays the same for 2 seconds, within 10, as\n--- frameworks give new characters their starter items a moment after they\n--- log in: QBCore once its other resources had a second to load the player.\nlocal function settled(player)\n local before, stable = holdings(player), 0\n for _ = 1, 20 do\n Wait(500)\n local now = holdings(player)\n local gained, lost = diff(before, now)\n stable = (#gained == 0 and #lost == 0) and stable + 1 or 0\n if stable == 4 then return now end\n before = now\n end\n return before\nend\n\n--- The rows of each table of the database, as JSON, by the names of the tables.\nlocal function tables()\n local rows = {}\n if not started('oxmysql') then return rows end\n pcall(function()\n for _, row in ipairs(exports.oxmysql:query_async('SHOW TABLES') or {}) do\n local _, name = next(row)\n rows[name] = json.encode(exports.oxmysql:query_async(('SELECT * FROM `%s`'):format(name)))\n end\n end)\n return rows\nend\n\n--- The tables whose rows differ from `before` to `after`.\nlocal function changed(before, after)\n local found = {}\n for name, rows in pairs(after) do\n if before[name] ~= rows then found[#found + 1] = name end\n end\n table.sort(found)\n return found\nend\n\nlocal function entities()\n return #GetAllVehicles() + #GetAllPeds() + #GetAllObjects()\nend\n\n--- An item that the server knows of, for arguments that name items.\nlocal function anItem()\n local name\n pcall(function()\n if oxInventory then\n name = next(exports.ox_inventory:Items())\n elseif framework == 'qb' then\n name = next(coreOf().Shared.Items)\n elseif framework == 'esx' then\n name = next(coreOf().Items)\n end\n end)\n return name or 'water'\nend\n\nit('audits the events that clients may trigger', function()\n while GetGameTimer() < 3000 do Wait(100) end\n local events = fiverunner.events()\n\n -- Which events clients may trigger. Each resource that handles one but not\n -- for net refuses it from clients, saying so, so a scout triggers them all at\n -- once, and those that every resource of theirs refused are closed. The scout\n -- leaves, so that what the events did to it is nothing of the player's.\n local scout, why = fiverunner.connect({ name = 'scout' })\n if not scout then\n tell({ type = 'refused', reason = why })\n return\n end\n local names = {}\n for _, event in ipairs(events) do\n if event.name ~= '*' then names[#names + 1] = event.name end\n end\n local from = #fiverunner.output() + 1\n scout:run('for _, name in ipairs(...) do TriggerServerEvent(name) end', names)\n Wait(500)\n local refusals = {}\n for _, line in ipairs(fiverunner.output(from)) do\n local name = line:match('[Ee]vent (.-) was not safe for net')\n if name then refusals[name] = (refusals[name] or 0) + 1 end\n end\n if GetPlayerName(scout.id) ~= nil then scout:disconnect() end\n\n local player\n player, why = join()\n if not player then\n tell({ type = 'refused', reason = why })\n return\n end\n local item = anItem()\n local payloads = {\n {},\n { 1000000 },\n { -1000000 },\n { 'money', 1000000 },\n { 'bank', 1000000 },\n { item, 100 },\n { 'police', 4 },\n { player.id, 1000000 },\n { { amount = 1000000, count = 100, item = item, money = 1000000, price = -1000000 } },\n }\n local openEvents = 0\n for _, event in ipairs(events) do\n if event.name ~= '*' and (refusals[event.name] or 0) < #event.resources then openEvents = openEvents + 1 end\n end\n tell({ type = 'start', framework = framework, events = #events, open = openEvents, loggedIn = frameworkPlayer(player.id) ~= nil })\n local RANK = { low = 1, medium = 2, high = 3 }\n\n local held, rows, count = settled(player), tables(), entities()\n local seen = #fiverunner.output()\n for _, event in ipairs(events) do\n local name, resources = event.name, event.resources\n local open = name ~= '*' and (refusals[name] or 0) < #resources\n -- What the arguments that did the most did, of all that the event got.\n local worst\n for _, payload in ipairs(open and payloads or {}) do\n player:emit(name, table.unpack(payload))\n Wait(100)\n local errors = {}\n -- Only what the server printed since it last read, which may be long.\n local output = fiverunner.output(seen + 1)\n for _, line in ipairs(output) do\n if line:find('SCRIPT ERROR', 1, true) and not line:find(MARK, 1, true) then\n errors[#errors + 1] = line\n end\n end\n seen = seen + #output\n local effects, severity = {}, nil\n local stayed = present(player)\n if stayed then\n local now = holdings(player)\n local gained, lost = diff(held, now)\n held = now\n -- Money that comes at once may be pay that comes on its own, such as\n -- paychecks, so it counts only when the same arguments bring more.\n if has(gained, 'money') then\n player:emit(name, table.unpack(payload))\n Wait(100)\n stayed = present(player)\n local again = stayed and holdings(player) or now\n if not has((diff(now, again)), 'money') then\n for i = #gained, 1, -1 do\n if gained[i].kind == 'money' then table.remove(gained, i) end\n end\n end\n held = again\n end\n for _, gain in ipairs(gained) do effects[#effects + 1] = gain.text end\n if #gained > 0 then\n -- What the player paid for, such as an item of a shop, is a trade.\n severity = #lost > 0 and 'medium' or 'high'\n for _, loss in ipairs(lost) do effects[#effects + 1] = loss end\n end\n end\n local nowCount = entities()\n if nowCount > count then\n effects[#effects + 1] = ('%d entities'):format(nowCount - count)\n severity = severity or 'medium'\n end\n count = nowCount\n if #errors > 0 then\n effects[#effects + 1] = 'error: ' .. errors[1]\n severity = severity or 'low'\n end\n if severity and (worst == nil or RANK[severity] > RANK[worst.severity]) then\n worst = { severity = severity, args = payload, effects = effects }\n end\n if not stayed then\n tell({ type = 'dropped', event = name, resources = resources, args = payload })\n player = join()\n if not player then return end\n payloads[8][1] = player.id\n -- What joining did is no effect of the event, whose other arguments\n -- would only drop the new player, such as by a ban, as anti-cheats do.\n held, rows, count = settled(player), tables(), entities()\n seen = seen + #fiverunner.output(seen + 1)\n break\n end\n end\n -- The rows of the database, once all the arguments went, as reading them\n -- takes far longer than the rest: whichever changed them, the event writes\n -- what clients send.\n if open then\n local nowRows = tables()\n local tablesChanged = changed(rows, nowRows)\n rows = nowRows\n if #tablesChanged > 0 then\n local effect = 'database: ' .. table.concat(tablesChanged, ', ')\n if worst and RANK[worst.severity] >= RANK.medium then\n worst.effects[#worst.effects + 1] = effect\n else\n worst = { severity = 'medium', effects = { effect, table.unpack(worst and worst.effects or {}) } }\n end\n end\n end\n if worst then\n tell({ type = 'finding', event = name, resources = resources, args = worst.args, severity = worst.severity, effects = worst.effects })\n end\n tell({ type = 'event', event = name, resources = resources, open = open })\n -- What the event left behind, such as copies of the objects of frameworks,\n -- is garbage that generational collection lets grow on servers of many resources.\n collectgarbage()\n end\n tell({ type = 'end' })\nend, 3600000)\n";
|
|
102764
|
+
var audit_default = "-- FiveRunner's audit, which `fiverunner audit` runs as a test of the project:\n-- it triggers each event of the server that clients may trigger, from a\n-- player, with the arguments that cheaters give, and tells what each changed\n-- of what the player has, of the database and of the world, as lines of JSON.\n\nlocal MARK = 'fiverunner:audit '\n\n--- Tells `fiverunner audit` of something, as a line of JSON.\nlocal function tell(record)\n print(MARK .. json.encode(record))\nend\n\nlocal function started(name)\n return GetResourceState(name) == 'started'\nend\n\n-- The framework that logs players in, and the inventory that holds their items.\nlocal framework = started('qbx_core') and 'qbx' or started('qb-core') and 'qb' or started('es_extended') and 'esx' or nil\nlocal oxInventory = started('ox_inventory')\n\nlocal CHARINFO = { firstname = 'Audit', lastname = 'Player', birthdate = '1990-01-01', gender = 0, nationality = 'Romania' }\n\nlocal core\n\n--- The shared object of QBCore or ESX, which exports copy whole, so once.\nlocal function coreOf()\n if core == nil then\n if framework == 'qb' then core = exports['qb-core']:GetCoreObject() end\n if framework == 'esx' then core = exports.es_extended:getSharedObject() end\n end\n return core\nend\n\n--- The object of the framework for a player, once it logged in.\nlocal function frameworkPlayer(id)\n local ok, found = pcall(function()\n if framework == 'qbx' then return exports.qbx_core:GetPlayer(id) end\n if framework == 'qb' then return coreOf().Functions.GetPlayer(id) end\n if framework == 'esx' then return coreOf().GetPlayerFromId(id) end\n end)\n return ok and found or nil\nend\n\n--- Whether the client of `player` sent the page of `resource` a message of `action`.\nlocal function sent(player, resource, action)\n for _, message in ipairs(player:nuiMessages(resource)) do\n if message.action == action then return true end\n end\n return false\nend\n\nlocal joined = 0\n\n--- Connects a player and logs it in with a new character, as the framework of the server has players do.\nlocal function join()\n joined = joined + 1\n local player, why = fiverunner.connect({ name = 'audit' .. joined })\n if not player then return nil, why end\n pcall(function()\n if framework == 'qbx' then\n exports.qbx_core:Login(player.id, nil, { charinfo = CHARINFO })\n elseif framework == 'qb' and started('qb-multicharacter') then\n fiverunner.waitFor(function() return sent(player, 'qb-multicharacter', 'ui') end, 10000)\n player:nuiCallback('qb-multicharacter', 'createNewCharacter', {\n firstname = 'Audit', lastname = 'Player', nationality = 'Romania', birthdate = '1990-01-01', gender = 'Male', cid = 1,\n })\n elseif framework == 'qb' then\n coreOf().Player.Login(player.id, false, { charinfo = CHARINFO })\n end\n end)\n if framework then\n pcall(fiverunner.waitFor, function() return frameworkPlayer(player.id) end, 10000)\n end\n return player\nend\n\n--- Whether `player` is still on the server, and still logged in to its framework.\nlocal function present(player)\n if GetPlayerName(player.id) == nil then return false end\n return framework == nil or frameworkPlayer(player.id) ~= nil\nend\n\n--- What `player` has: money by account, items by name, job, gang, group, and whether it may run every command.\nlocal function holdings(player)\n local held = { money = {}, items = {}, admin = IsPlayerAceAllowed(player.id, 'command') }\n local found = frameworkPlayer(player.id)\n pcall(function()\n if found and framework == 'esx' then\n for account, money in pairs(found.getAccounts(true)) do held.money[account] = money end\n if not oxInventory then\n for name, count in pairs(found.getInventory(true)) do held.items[name] = count end\n end\n local job = found.getJob()\n held.job = ('%s %s'):format(job.name, job.grade)\n held.group = found.getGroup()\n elseif found then\n local data = found.PlayerData\n for account, money in pairs(data.money or {}) do held.money[account] = money end\n if not oxInventory then\n for _, item in pairs(data.items or {}) do\n held.items[item.name] = (held.items[item.name] or 0) + (item.amount or item.count or 0)\n end\n end\n if data.job then held.job = ('%s %s'):format(data.job.name, data.job.grade and data.job.grade.level) end\n if data.gang then held.gang = ('%s %s'):format(data.gang.name, data.gang.grade and data.gang.grade.level) end\n end\n end)\n if oxInventory then\n pcall(function()\n for _, item in pairs(exports.ox_inventory:GetInventoryItems(player.id) or {}) do\n held.items[item.name] = (held.items[item.name] or 0) + item.count\n end\n end)\n end\n return held\nend\n\nlocal function byText(a, b)\n return a.text < b.text\nend\n\n--- What `player` gained from `before` to `after`, as { kind, text }, with\n--- kind money, item or field, and the money that it lost, as words.\nlocal function diff(before, after)\n local gained, lost = {}, {}\n for account, money in pairs(after.money) do\n local was = before.money[account] or 0\n if type(money) == 'number' and type(was) == 'number' then\n if money > was then\n gained[#gained + 1] = { kind = 'money', text = ('%s +%s'):format(account, money - was) }\n elseif money < was then\n lost[#lost + 1] = ('%s -%s'):format(account, was - money)\n end\n end\n end\n for name, count in pairs(after.items) do\n local was = before.items[name] or 0\n if count > was then gained[#gained + 1] = { kind = 'item', text = ('item %s +%s'):format(name, count - was) } end\n end\n for _, field in ipairs({ 'job', 'gang', 'group' }) do\n if after[field] ~= before[field] and after[field] ~= nil then\n gained[#gained + 1] = { kind = 'field', text = ('%s %s'):format(field, after[field]) }\n end\n end\n if after.admin and not before.admin then gained[#gained + 1] = { kind = 'field', text = 'every command' } end\n table.sort(gained, byText)\n table.sort(lost)\n return gained, lost\nend\n\n--- Whether `changes` has any of `kind`.\nlocal function has(changes, kind)\n for _, change in ipairs(changes) do\n if change.kind == kind then return true end\n end\n return false\nend\n\n--- What `player` holds once it stays the same for `reads` reads, half a\n--- second apart, within 10 seconds: 4 after it logs in, as frameworks give\n--- new characters their starter items a moment after, such as QBCore once\n--- its other resources had a second to load the player.\nlocal function settled(player, reads)\n local before, stable = holdings(player), 0\n for _ = 1, 20 do\n Wait(500)\n local now = holdings(player)\n local gained, lost = diff(before, now)\n stable = (#gained == 0 and #lost == 0) and stable + 1 or 0\n if stable == (reads or 4) then return now end\n before = now\n end\n return before\nend\n\n--- The rows of each table of the database, as JSON, by the names of the tables.\nlocal function tables()\n local rows = {}\n if not started('oxmysql') then return rows end\n pcall(function()\n for _, row in ipairs(exports.oxmysql:query_async('SHOW TABLES') or {}) do\n local _, name = next(row)\n rows[name] = json.encode(exports.oxmysql:query_async(('SELECT * FROM `%s`'):format(name)))\n end\n end)\n return rows\nend\n\n--- The tables whose rows differ from `before` to `after`.\nlocal function changed(before, after)\n local found = {}\n for name, rows in pairs(after) do\n if before[name] ~= rows then found[#found + 1] = name end\n end\n table.sort(found)\n return found\nend\n\nlocal function entities()\n return #GetAllVehicles() + #GetAllPeds() + #GetAllObjects()\nend\n\n--- An item that the server knows of, for arguments that name items.\nlocal function anItem()\n local name\n pcall(function()\n if oxInventory then\n name = next(exports.ox_inventory:Items())\n elseif framework == 'qb' then\n name = next(coreOf().Shared.Items)\n elseif framework == 'esx' then\n name = next(coreOf().Items)\n end\n end)\n return name or 'water'\nend\n\nit('audits the events that clients may trigger', function()\n while GetGameTimer() < 3000 do Wait(100) end\n local events = fiverunner.events()\n\n -- Which events clients may trigger. Each resource that handles one but not\n -- for net refuses it from clients, saying so, so a scout triggers them all at\n -- once, and those that every resource of theirs refused are closed. The scout\n -- leaves, so that what the events did to it is nothing of the player's.\n local scout, why = fiverunner.connect({ name = 'scout' })\n if not scout then\n tell({ type = 'refused', reason = why })\n return\n end\n local names = {}\n for _, event in ipairs(events) do\n if event.name ~= '*' then names[#names + 1] = event.name end\n end\n local from = #fiverunner.output() + 1\n scout:run('for _, name in ipairs(...) do TriggerServerEvent(name) end', names)\n Wait(500)\n local refusals = {}\n for _, line in ipairs(fiverunner.output(from)) do\n local name = line:match('[Ee]vent (.-) was not safe for net')\n if name then refusals[name] = (refusals[name] or 0) + 1 end\n end\n if GetPlayerName(scout.id) ~= nil then scout:disconnect() end\n\n local player\n player, why = join()\n if not player then\n tell({ type = 'refused', reason = why })\n return\n end\n local item = anItem()\n local payloads = {\n {},\n { 1000000 },\n { -1000000 },\n { 'money', 1000000 },\n { 'bank', 1000000 },\n { item, 100 },\n { 'police', 4 },\n { player.id, 1000000 },\n { { amount = 1000000, count = 100, item = item, money = 1000000, price = -1000000 } },\n }\n local openEvents = 0\n for _, event in ipairs(events) do\n if event.name ~= '*' and (refusals[event.name] or 0) < #event.resources then openEvents = openEvents + 1 end\n end\n tell({ type = 'start', framework = framework, events = #events, open = openEvents, loggedIn = frameworkPlayer(player.id) ~= nil })\n local RANK = { low = 1, medium = 2, high = 3 }\n\n local held, rows, count = settled(player), tables(), entities()\n local seen = #fiverunner.output()\n for _, event in ipairs(events) do\n local name, resources = event.name, event.resources\n local open = name ~= '*' and (refusals[name] or 0) < #resources\n -- What the arguments that did the most did, of all that the event got.\n local worst\n for _, payload in ipairs(open and payloads or {}) do\n player:emit(name, table.unpack(payload))\n Wait(100)\n local errors = {}\n -- Only what the server printed since it last read, which may be long.\n local output = fiverunner.output(seen + 1)\n for _, line in ipairs(output) do\n if line:find('SCRIPT ERROR', 1, true) and not line:find(MARK, 1, true) then\n errors[#errors + 1] = line\n end\n end\n seen = seen + #output\n local effects, severity = {}, nil\n local stayed = present(player)\n if stayed then\n local now = holdings(player)\n local gained, lost = diff(held, now)\n held = now\n -- Money that comes at once may be pay that comes on its own, such as\n -- paychecks, so it counts only when the same arguments bring more.\n if has(gained, 'money') then\n player:emit(name, table.unpack(payload))\n Wait(100)\n stayed = present(player)\n local again = stayed and holdings(player) or now\n if not has((diff(now, again)), 'money') then\n for i = #gained, 1, -1 do\n if gained[i].kind == 'money' then table.remove(gained, i) end\n end\n end\n held = again\n end\n for _, gain in ipairs(gained) do effects[#effects + 1] = gain.text end\n if #gained > 0 then\n -- What the player paid for, such as an item of a shop, is a trade.\n severity = #lost > 0 and 'medium' or 'high'\n for _, loss in ipairs(lost) do effects[#effects + 1] = loss end\n end\n end\n local nowCount = entities()\n if nowCount > count then\n effects[#effects + 1] = ('%d entities'):format(nowCount - count)\n severity = severity or 'medium'\n end\n count = nowCount\n if #errors > 0 then\n effects[#effects + 1] = 'error: ' .. errors[1]\n severity = severity or 'low'\n end\n if severity and (worst == nil or RANK[severity] > RANK[worst.severity]) then\n worst = { severity = severity, args = payload, effects = effects }\n end\n if not stayed then\n tell({ type = 'dropped', event = name, resources = resources, args = payload })\n player = join()\n if not player then return end\n payloads[8][1] = player.id\n -- What joining did is no effect of the event, whose other arguments\n -- would only drop the new player, such as by a ban, as anti-cheats do.\n held, rows, count = settled(player), tables(), entities()\n seen = seen + #fiverunner.output(seen + 1)\n break\n end\n end\n -- What comes after the last arguments, such as items that a loop of the\n -- event gives one by one with waits, is the event's, not the next one's.\n -- Money that comes then may be pay that comes on its own, such as\n -- paychecks, so only the rest counts.\n if open and present(player) then\n local later = settled(player, 2)\n local gained, lost = diff(held, later)\n held = later\n local effects = {}\n for _, gain in ipairs(gained) do\n if gain.kind ~= 'money' then effects[#effects + 1] = 'later: ' .. gain.text end\n end\n if #effects > 0 then\n local severity = #lost > 0 and 'medium' or 'high'\n for _, loss in ipairs(lost) do effects[#effects + 1] = 'later: ' .. loss end\n if worst and RANK[worst.severity] >= RANK[severity] then\n for _, effect in ipairs(effects) do worst.effects[#worst.effects + 1] = effect end\n else\n -- Which arguments it came of is not known: the event's, as a whole.\n for _, effect in ipairs(worst and worst.effects or {}) do effects[#effects + 1] = effect end\n worst = { severity = severity, effects = effects }\n end\n end\n end\n -- The rows of the database, once all the arguments went, as reading them\n -- takes far longer than the rest: whichever changed them, the event writes\n -- what clients send.\n if open then\n local nowRows = tables()\n local tablesChanged = changed(rows, nowRows)\n rows = nowRows\n if #tablesChanged > 0 then\n local effect = 'database: ' .. table.concat(tablesChanged, ', ')\n if worst and RANK[worst.severity] >= RANK.medium then\n worst.effects[#worst.effects + 1] = effect\n else\n worst = { severity = 'medium', effects = { effect, table.unpack(worst and worst.effects or {}) } }\n end\n end\n end\n if worst then\n tell({ type = 'finding', event = name, resources = resources, args = worst.args, severity = worst.severity, effects = worst.effects })\n end\n tell({ type = 'event', event = name, resources = resources, open = open })\n -- What the event left behind, such as copies of the objects of frameworks,\n -- is garbage that generational collection lets grow on servers of many resources.\n collectgarbage()\n end\n tell({ type = 'end' })\nend, 3600000)\n";
|
|
102758
102765
|
//#endregion
|
|
102759
102766
|
//#region src/cli/audit.ts
|
|
102760
102767
|
var USAGE$5 = `Usage: fiverunner audit
|
|
@@ -103239,7 +103246,8 @@ var types_default = "---@meta\n\n-- What the tests of FiveRunner have, for the L
|
|
|
103239
103246
|
var USAGE$3 = `Usage: fiverunner init
|
|
103240
103247
|
|
|
103241
103248
|
Adds tests to the project in this directory: a test file, which checks
|
|
103242
|
-
that the project starts without script errors,
|
|
103249
|
+
that the project starts without script errors, and on servers of Qbox,
|
|
103250
|
+
QBCore or ESX that a player logs in with a character, what the Lua language
|
|
103243
103251
|
server needs to know the functions of tests, and, at the root of a git
|
|
103244
103252
|
repository, a GitHub Actions workflow that runs the tests on each push.
|
|
103245
103253
|
It writes over nothing that is there.
|
|
@@ -103265,8 +103273,76 @@ var SETTINGS = `${JSON.stringify({
|
|
|
103265
103273
|
"runtime.version": "Lua 5.4",
|
|
103266
103274
|
"workspace.library": [".fiverunner"]
|
|
103267
103275
|
}, null, 2)}\n`;
|
|
103268
|
-
/**
|
|
103269
|
-
|
|
103276
|
+
/** The logins of the frameworks, as docs/testing.md tells them. */
|
|
103277
|
+
var LOGINS = {
|
|
103278
|
+
qbx: {
|
|
103279
|
+
framework: "Qbox",
|
|
103280
|
+
code: ` expect(exports.qbx_core:Login(player.id, nil, {
|
|
103281
|
+
charinfo = { firstname = 'Ann', lastname = 'Lee', birthdate = '1990-01-01', gender = 0, nationality = 'Romania' },
|
|
103282
|
+
})).toBe(true)
|
|
103283
|
+
`
|
|
103284
|
+
},
|
|
103285
|
+
qbMulticharacter: {
|
|
103286
|
+
framework: "QBCore",
|
|
103287
|
+
code: ` -- The page of qb-multicharacter creates the character once its menu shows, as players do.
|
|
103288
|
+
fiverunner.waitFor(function()
|
|
103289
|
+
for _, message in ipairs(player:nuiMessages('qb-multicharacter')) do
|
|
103290
|
+
if message.action == 'ui' then return true end
|
|
103291
|
+
end
|
|
103292
|
+
end, 10000)
|
|
103293
|
+
player:nuiCallback('qb-multicharacter', 'createNewCharacter', {
|
|
103294
|
+
firstname = 'Ann', lastname = 'Lee', nationality = 'Romania', birthdate = '1990-01-01', gender = 'Female', cid = 1,
|
|
103295
|
+
})
|
|
103296
|
+
local QBCore = exports['qb-core']:GetCoreObject()
|
|
103297
|
+
fiverunner.waitFor(function() return QBCore.Functions.GetPlayer(player.id) end, 10000)
|
|
103298
|
+
`
|
|
103299
|
+
},
|
|
103300
|
+
qb: {
|
|
103301
|
+
framework: "QBCore",
|
|
103302
|
+
code: ` expect(exports['qb-core']:GetCoreObject().Player.Login(player.id, false, {
|
|
103303
|
+
charinfo = { firstname = 'Ann', lastname = 'Lee', birthdate = '1990-01-01', gender = 0, nationality = 'Romania' },
|
|
103304
|
+
})).toBe(true)
|
|
103305
|
+
`
|
|
103306
|
+
},
|
|
103307
|
+
esx: {
|
|
103308
|
+
framework: "ESX",
|
|
103309
|
+
code: ` -- ESX logs players in as they join, when no multicharacter resource runs.
|
|
103310
|
+
local ESX = exports.es_extended:getSharedObject()
|
|
103311
|
+
fiverunner.waitFor(function()
|
|
103312
|
+
local xPlayer = ESX.GetPlayerFromId(player.id)
|
|
103313
|
+
return xPlayer and xPlayer.spawned
|
|
103314
|
+
end, 10000)
|
|
103315
|
+
`
|
|
103316
|
+
}
|
|
103317
|
+
};
|
|
103318
|
+
/** The names of the resources of a server, in its resources directory and the categories in it, as FiveM finds them. */
|
|
103319
|
+
function resourcesOf(source) {
|
|
103320
|
+
const names = /* @__PURE__ */ new Set();
|
|
103321
|
+
const visit = (path) => {
|
|
103322
|
+
for (const entry of source.list(path)) {
|
|
103323
|
+
if (!entry.directory) continue;
|
|
103324
|
+
const at = `${path}/${entry.name}`;
|
|
103325
|
+
if (isCategory(entry.name)) visit(at);
|
|
103326
|
+
else if (source.list(at).some(({ name, directory }) => !directory && /^(fxmanifest|__resource)\.lua$/.test(name))) names.add(entry.name);
|
|
103327
|
+
}
|
|
103328
|
+
};
|
|
103329
|
+
visit("resources");
|
|
103330
|
+
return names;
|
|
103331
|
+
}
|
|
103332
|
+
/** How the starter test logs a player in to the framework that a server has, if it has one that the test knows. */
|
|
103333
|
+
function loginOf(source) {
|
|
103334
|
+
const resources = resourcesOf(source);
|
|
103335
|
+
if (resources.has("qbx_core")) return LOGINS.qbx;
|
|
103336
|
+
if (resources.has("qb-core")) return resources.has("qb-multicharacter") ? LOGINS.qbMulticharacter : LOGINS.qb;
|
|
103337
|
+
if (resources.has("es_extended") && !resources.has("esx_multicharacter")) return LOGINS.esx;
|
|
103338
|
+
}
|
|
103339
|
+
/**
|
|
103340
|
+
* A test file of `subject`, a Lua expression of the name of the tests, whose
|
|
103341
|
+
* test checks the start of the project, on the server and on the client of a
|
|
103342
|
+
* player, and what `checks` says, and, with `login`, a test that logs a
|
|
103343
|
+
* player in with a character.
|
|
103344
|
+
*/
|
|
103345
|
+
function testFile(subject, checks, login) {
|
|
103270
103346
|
return `-- The tests of the project, which \`npx fiverunner test\` runs:
|
|
103271
103347
|
-- https://github.com/DariusHQ/fiverunner/blob/main/docs/testing.md
|
|
103272
103348
|
|
|
@@ -103289,7 +103365,16 @@ ${checks} -- Players reach servers once they started, which takes the big
|
|
|
103289
103365
|
expect(errors(fiverunner.output())).toEqual({})
|
|
103290
103366
|
expect(errors(player:output())).toEqual({})
|
|
103291
103367
|
end, 120000)
|
|
103292
|
-
|
|
103368
|
+
${login === void 0 ? "" : `
|
|
103369
|
+
it('logs a player in with a character of ${login.framework}', function()
|
|
103370
|
+
while GetGameTimer() < 3000 do Wait(100) end
|
|
103371
|
+
local player = fiverunner.connect({ name = 'Ann' })
|
|
103372
|
+
${login.code} -- Scripts load the character a moment after it logs in.
|
|
103373
|
+
Wait(3000)
|
|
103374
|
+
expect(errors(fiverunner.output())).toEqual({})
|
|
103375
|
+
expect(errors(player:output())).toEqual({})
|
|
103376
|
+
end, 120000)
|
|
103377
|
+
`}end)
|
|
103293
103378
|
`;
|
|
103294
103379
|
}
|
|
103295
103380
|
/**
|
|
@@ -103311,7 +103396,7 @@ function init(args, host) {
|
|
|
103311
103396
|
host.stderr("fiverunner: there is no FiveM project here: a resource has an fxmanifest.lua or a __resource.lua, and a server a resources directory\n");
|
|
103312
103397
|
return 2;
|
|
103313
103398
|
}
|
|
103314
|
-
const files = project.kind === "resource" ? [[`tests/${project.name}.test.lua`, testFile(JSON.stringify(project.name), ` expect(GetResourceState(${JSON.stringify(project.name)})).toBe('started')\n`)]] : [["tests/server.test.lua", testFile("'the server'", "")]];
|
|
103399
|
+
const files = project.kind === "resource" ? [[`tests/${project.name}.test.lua`, testFile(JSON.stringify(project.name), ` expect(GetResourceState(${JSON.stringify(project.name)})).toBe('started')\n`)]] : [["tests/server.test.lua", testFile("'the server'", "", loginOf(project.visible))]];
|
|
103315
103400
|
files.push([TYPES, types_default], [".luarc.json", SETTINGS]);
|
|
103316
103401
|
const repository = existsSync(join(host.cwd, ".git"));
|
|
103317
103402
|
if (repository) files.push([".github/workflows/fiverunner.yml", WORKFLOW]);
|
package/package.json
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "fiverunner",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.0",
|
|
4
4
|
"description": "Run FiveM resources (Lua, JavaScript and NUI) in your browser and in CI. No GTA V, no server, no restarts.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"fivem",
|
|
7
7
|
"cfx",
|
|
8
|
+
"fxserver",
|
|
9
|
+
"txadmin",
|
|
8
10
|
"gta5",
|
|
9
11
|
"qbcore",
|
|
10
12
|
"qbox",
|
|
11
13
|
"esx",
|
|
14
|
+
"ox_lib",
|
|
15
|
+
"oxmysql",
|
|
12
16
|
"lua",
|
|
13
17
|
"nui",
|
|
14
18
|
"emulator",
|
|
15
19
|
"testing",
|
|
16
|
-
"ci"
|
|
20
|
+
"ci",
|
|
21
|
+
"audit",
|
|
22
|
+
"security",
|
|
23
|
+
"mcp"
|
|
17
24
|
],
|
|
18
25
|
"homepage": "https://github.com/DariusHQ/fiverunner#readme",
|
|
19
26
|
"bugs": "https://github.com/DariusHQ/fiverunner/issues",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{t as e}from"./routes-DFIWFSAi.js";var t=`/__fiverunner/api/`;new TextDecoder;function n(e,t){let n=document.createElement(`label`);return n.append(t,e),n}function r(e,t){switch(e.type){case`TextBlock`:{let t=document.createElement(`p`);return t.textContent=e.text??``,t.classList.toggle(`large`,/large/i.test(e.size??``)),t.classList.toggle(`bold`,e.weight===`Bolder`),[t]}case`Input.Text`:case`Input.Number`:{let n=document.createElement(e.isMultiline?`textarea`:`input`);return n.placeholder=e.placeholder??``,n.value=e.value??``,n.ariaLabel=e.placeholder??e.id??``,t.set(e.id??``,()=>n.value),[n]}case`Input.Toggle`:{let r=document.createElement(`input`);r.type=`checkbox`;let i=e.valueOn??`true`;return r.checked=e.value===i,t.set(e.id??``,()=>r.checked?i:e.valueOff??`false`),[n(e.title??``,r)]}case`Input.ChoiceSet`:{let n=document.createElement(`select`);n.ariaLabel=e.id??``;for(let{title:t,value:r}of e.choices??[])n.add(new Option(t,r));return n.value=e.value??n.value,t.set(e.id??``,()=>n.value),[n]}case`Container`:case`Column`:return i(e.items??[],t);case`ColumnSet`:return i(e.columns??[],t);default:return}}function i(e,t){let n=e.map(e=>r(e,t));return n.every(e=>e!==void 0)?n.flat():void 0}function a(e,t){let n;try{n=JSON.parse(e)}catch{return}let r=new Map,a=i(n.body??[],r);if(a===void 0)return;let o=document.createElement(`form`);o.className=`adaptive`,o.addEventListener(`submit`,e=>e.preventDefault()),o.append(...a);for(let e of n.actions??[]){if(e.type!==`Action.Submit`)return;let n=document.createElement(`button`);n.textContent=e.title??`Submit`,n.addEventListener(`click`,()=>{let n=Object.fromEntries([...r].map(([e,t])=>[e,t()])),i=e.id===void 0?{}:{submitId:e.id};t(JSON.stringify({...n,...e.data,...i}))}),o.append(n)}return o}var o=[``,`red`,`green`,`yellow`,`blue`,`cyan`,`magenta`,``,`orange`,`gray`],s=2e3,c=class{element;constructor(e){this.element=e}add(e){this.entry(e.channel,e.text,`kind-${e.kind}`)}entry(e,t,n){let r=document.createElement(`div`);r.className=`line ${n}`;let i=document.createElement(`span`);i.className=`channel`,i.textContent=`[${e}] `,r.append(i,...u(t)),this.#e(r)}note(e){let t=document.createElement(`div`);t.className=`line note`,t.textContent=e,this.#e(t)}#e(e){let{element:t}=this,n=t.scrollHeight-t.scrollTop-t.clientHeight<4;for(t.append(e);t.childElementCount>s;)t.firstElementChild.remove();n&&(t.scrollTop=t.scrollHeight)}};function l(e){let t=[],n=0;return e.addEventListener(`keydown`,r=>{(r.key===`ArrowUp`||r.key===`ArrowDown`)&&(r.preventDefault(),n=Math.max(0,Math.min(t.length,n+(r.key===`ArrowUp`?-1:1))),e.value=t[n]??``)}),e=>{t.push(e),n=t.length}}function u(e){let t=[],n=``;for(let[r,i]of e.split(/\^(\d)/).entries())if(r%2==1)n=o[Number(i)]??``;else if(i!==``){let e=document.createElement(`span`);n!==``&&(e.className=`color-${n}`),e.textContent=i,t.push(e)}return t}var d=class{#e;#t;#n=new Map;constructor(e,t,n){this.#e=new c(e),this.#t=t.elements.namedItem(`target`);let r=t.elements.namedItem(`name`),i=t.elements.namedItem(`args`);t.addEventListener(`submit`,e=>{e.preventDefault();let t=f(this.#t.value);if(t===void 0||r.value.trim()===``)return;let a;try{a=JSON.parse(i.value.trim()===``?`[]`:i.value)}catch(e){this.#e.note(`The arguments are no JSON: ${String(e)}`);return}Array.isArray(a)?n.emit(r.value.trim(),a,t):this.#e.note(`The arguments are a JSON array, such as [100, "cash"]`)}),this.players([])}add({from:e,to:t,name:n,args:r}){this.#e.entry(`${this.#r(e)} -> ${this.#r(t)}`,`${n}(${r})`,`kind-event`)}note(e){this.#e.note(e)}players(e){this.#n.clear();for(let{client:t,name:n}of e)this.#n.set(t,n);let t=e.filter(({state:e})=>e===`joined`),n=[...t.map(({client:e,name:t})=>[`from:${e}`,`To the server, from ${t}`]),...t.map(({client:e,name:t})=>[`to:${e}`,`To ${t}, from the server`]),[`to:everyone`,`To every player, from the server`]],r=this.#t.value;this.#t.replaceChildren(...n.map(([e,t])=>{let n=document.createElement(`option`);return n.value=e,n.textContent=t,n})),n.some(([e])=>e===r)&&(this.#t.value=r)}#r(e){return e===`server`?`server`:this.#n.get(e)??`client ${e}`}};function f(e){let[t,n]=e.split(`:`);if(t===`to`&&n===`everyone`)return{to:`everyone`};let r=Number(n);if(!(!Number.isInteger(r)||r<1))return t===`from`?{from:r}:{to:r}}function p(e,t){if(t.length===0){let t=document.createElement(`p`);t.className=`empty`,t.textContent=`No state bag has keys.`,e.replaceChildren(t)}else e.replaceChildren(...t.map(({name:e,keys:t})=>{let n=document.createElement(`section`),r=document.createElement(`h3`);r.textContent=e;let i=document.createElement(`dl`);for(let{key:e,value:n}of t){let t=document.createElement(`dt`);t.textContent=e;let r=document.createElement(`dd`);r.textContent=n,i.append(t,r)}return n.append(r,i),n}))}var m=1e3,h=[[`Exports`,({exports:e})=>e],[`Events`,({events:e})=>e],[`NUI callbacks`,({nuiCallbacks:e})=>e],[`Commands`,({commands:e})=>e],[`Key mappings`,({keyMappings:e})=>e],[`KVP`,({kvp:e})=>e.map(({key:e,value:t})=>`${e} = ${t}`)]],g=e=>String(e),_=class{#e;#t;#n=new Map;#r;#i;#a=``;#o=``;constructor(e,t){this.#t=e,this.#e=t;let{process:n,form:r,code:i,filter:a}=e;this.players([]),n.addEventListener(`change`,()=>{this.#r=void 0,this.#c()});let o=l(i);r.addEventListener(`submit`,e=>{e.preventDefault(),i.value.trim()!==``&&this.#i!==void 0&&(t.evaluate(this.#s,this.#i,i.value),o(i.value),i.value=``)}),a.addEventListener(`input`,()=>this.#f()),setInterval(()=>this.#c(),m)}players(e){let{process:t}=this.#t,n=t.value,r=[[`server`,`Server`],...e.filter(({state:e})=>e===`joined`).map(({client:e,name:t})=>[g(e),t])];t.replaceChildren(...r.map(([e,t])=>{let n=document.createElement(`option`);return n.value=e,n.textContent=t,n})),t.value=r.some(([e])=>e===n)?n:`server`}show(e){if(e.process!==this.#s)return;this.#l(e),this.#r=e,this.#d();let t=JSON.stringify(e.convars);t!==this.#o&&(this.#o=t,this.#t.convars.replaceChildren(...e.convars.flatMap(({name:e,value:t})=>{let n=document.createElement(`dt`);n.textContent=e;let r=document.createElement(`dd`);return r.textContent=t,[n,r]})),this.#f())}get#s(){let{value:e}=this.#t.process;return e===`server`?e:Number(e)}#c(){document.hidden||this.#e.inspect(this.#s)}#l({resources:e,ticks:t}){let n=this.#t.resources,r=e.map(({name:e})=>e);r.join()!==[...this.#n.keys()].join()&&(this.#n.clear(),n.replaceChildren(...r.map(e=>this.#u(e))));let i=this.#r;for(let n of e){let e=this.#n.get(n.name);e.classList.toggle(`stopped`,n.state!==`started`),e.classList.toggle(`chosen`,n.name===this.#i);let r=i?.resources.find(({name:e})=>e===n.name),a=t-(i?.ticks??0);r!==void 0&&a>0&&(e.lastElementChild.textContent=`${((n.cpu-r.cpu)/a).toFixed(2)} ms`)}}#u(e){let t=document.createElement(`button`);t.type=`button`;let n=document.createElement(`span`);return n.textContent=e,t.append(n,document.createElement(`span`)),t.addEventListener(`click`,()=>{this.#i=e;for(let[t,n]of this.#n)n.classList.toggle(`chosen`,t===e);this.#d()}),this.#n.set(e,t),t}#d(){let e=this.#r?.resources.find(({name:e})=>e===this.#i),{details:t,code:n}=this.#t;n.disabled=e===void 0,n.placeholder=e===void 0?`Pick a resource to run code in it`:`Code to run in ${e.name}, such as GetNumResources()`;let r=JSON.stringify(e&&{...e,cpu:0});r!==this.#a&&(this.#a=r??``,e===void 0?t.textContent=`Pick a resource`:t.replaceChildren(...h.flatMap(([t,n])=>{let r=n(e);if(r.length===0)return[];let i=document.createElement(`h3`);i.textContent=`${t} (${r.length})`;let a=document.createElement(`ul`);return a.replaceChildren(...r.map(e=>{let t=document.createElement(`li`);return t.textContent=e,t})),[i,a]})))}#f(){let{convars:e,filter:t}=this.#t,n=t.value.trim().toLowerCase();for(let t of e.querySelectorAll(`dt`)){let e=!t.textContent.toLowerCase().includes(n);t.hidden=e,t.nextElementSibling.hidden=e}}},v=[657415,1708816,2497301,3351579,4140064,4994598,5914672,6834999,7755326,8675910,9662543,10649435,11570534,12360562,13085055,13743756,14336923,14864298,15326139,15721932,16051933,4004370,5382682,7023388,8729630,10370848,12078372,13393708,14251837,14914910,3874639,5580911,7485856,9523911,11894496,7149638,10231646,13184891,14899868,15765437,1780843,2311326,3106761,5215203,8830448,1003351,1407616,2073507,1923628,2787900,5749063,10802750,15255082,15769892,15232287,13185054,2829101,4474183,6250595,8158592,10263968,12369343,14343132,15987697],y=new Map([[8,`flag`],[40,`house`],[50,`car`],[52,`basket`],[56,`badge`],[59,`basket`],[60,`badge`],[61,`cross`],[67,`car`],[68,`lock`],[71,`scissors`],[72,`spray`],[73,`shirt`],[75,`heart`],[93,`bottle`],[102,`syringe`],[108,`dollar`],[110,`gun`],[198,`car`],[225,`car`],[273,`cutlery`],[326,`car`],[356,`boat`],[357,`parking`],[359,`plane`],[360,`plane`],[361,`fuel`],[366,`shirt`],[402,`wrench`],[403,`pill`],[423,`plane`],[424,`plane`],[427,`boat`],[477,`car`],[566,`anvil`],[729,`anchor`]]);function b(e){return y.get(e)}function x(e,t,n=!1){let r=0;for(let e=0;e<t.length;e+=2){let n=(e+2)%t.length;r+=t[e]*t[n+1]-t[n]*t[e+1]}let i=[...Array(t.length/2).keys()];r>0===n&&i.reverse(),i.forEach((n,r)=>{r===0?e.moveTo(t[2*n],t[2*n+1]):e.lineTo(t[2*n],t[2*n+1])}),e.closePath()}function S(e,t,n,r,i=!1){e.moveTo(t+r,n),e.arc(t,n,r,0,Math.PI*2,i),e.closePath()}function C(e,t){let n=new Path2D;return n.addPath(e,new DOMMatrix().rotate(t)),n}function w(e,t,n=0){let r=new Path2D;e(r);let i=n===0?r:C(r,n);return t===void 0?{path:i}:{path:i,width:t}}var T;function ee(){return{anchor:[w(e=>{S(e,0,-5.4,2.1),S(e,0,-5.4,1,!0),e.roundRect(-.95,-3.6,1.9,10.4,.6),e.roundRect(-3.8,-2.6,7.6,1.7,.85),x(e,[-7.4,1.2,-4.2,1.2,-5.8,3.6]),x(e,[7.4,1.2,4.2,1.2,5.8,3.6])}),w(e=>{e.moveTo(-5.8,2.4),e.quadraticCurveTo(-5,6.6,0,6.7),e.quadraticCurveTo(5,6.6,5.8,2.4)},1.7)],anvil:[w(e=>x(e,[-6.4,-4.4,4.2,-4.4,7.8,-3.4,4.6,-1.4,2.6,-1.4,2.6,1.6,4.8,4.4,4.8,6.2,-4.8,6.2,-4.8,4.4,-2.6,1.6,-2.6,-1.4,-6.4,-1.4]))],badge:[w(e=>{let t=[];for(let e=0;e<10;e++){let n=e*Math.PI/5-Math.PI/2,r=e%2==0?7.8:3.4;t.push(Math.cos(n)*r,Math.sin(n)*r+.6)}x(e,t)})],basket:[w(e=>{e.roundRect(-7.8,-2.4,15.6,2.4,1),x(e,[-6.8,-.4,6.8,-.4,5.2,6.6,-5.2,6.6]);for(let t of[-3.7,-.75,2.2])x(e,[t,1.2,t+1.5,1.2,t+1.5,5,t,5],!0)}),w(e=>{e.moveTo(-4.6,-2.4),e.arc(0,-2.4,4.6,Math.PI,Math.PI*2)},1.6)],boat:[w(e=>{x(e,[-7.6,2,7.6,2,5,6.6,-5,6.6]),x(e,[.6,-7.6,6,.8,.6,.8]),x(e,[-.6,-5.6,-.6,.8,-5,.8])})],bottle:[w(e=>{e.roundRect(-1.9,-7.8,3.8,1.6,.6),e.roundRect(-1.35,-6.6,2.7,3,.4),x(e,[-1.35,-4,1.35,-4,3.7,-1.4,-3.7,-1.4]),e.roundRect(-3.7,-2.4,7.4,10.2,1.8),x(e,[-2.3,.6,2.3,.6,2.3,4.2,-2.3,4.2],!0)})],car:[w(e=>{e.roundRect(-7.6,-1.6,15.2,5,1.8),x(e,[-4.8,-1.6,-2.9,-5.8,3.1,-5.8,5.2,-1.6]),x(e,[-2.9,-2.4,-.4,-2.4,-.4,-4.8,-2.1,-4.8],!0),x(e,[.5,-2.4,3.6,-2.4,2.6,-4.8,.5,-4.8],!0),S(e,-4.2,3.6,2.2),S(e,4.2,3.6,2.2)})],cross:[w(e=>{e.roundRect(-2.7,-7.4,5.4,14.8,1),e.roundRect(-7.4,-2.7,14.8,5.4,1)})],cutlery:[w(e=>{e.roundRect(-5.6,-3.4,5,2.6,1.3),x(e,[2,-7.6,4.9,-4.8,4.9,.6,2,.6])}),w(e=>{e.moveTo(-3.1,-1.4),e.lineTo(-3.1,7),e.moveTo(3.4,.6),e.lineTo(3.4,7)},1.9),w(e=>{for(let t of[-5,-3.1,-1.2])e.moveTo(t,-7.4),e.lineTo(t,-2.6)},1.1)],dollar:[w(e=>{e.moveTo(0,-7.6),e.lineTo(0,7.6)},1.6),w(e=>{e.moveTo(4.3,-3.9),e.bezierCurveTo(3.3,-6.3,-4.6,-6.3,-4.4,-2.6),e.bezierCurveTo(-4.2,.2,4.4,-.4,4.4,2.8),e.bezierCurveTo(4.4,6.5,-3.6,6.5,-4.6,3.8)},2.3)],flag:[w(e=>{e.roundRect(-5.4,-7.8,1.9,15.6,.9),e.moveTo(-3.8,-7.4),e.quadraticCurveTo(.8,-9.4,6.8,-6),e.quadraticCurveTo(.8,-2.4,-3.8,-1.2),e.closePath()})],fuel:[w(e=>{e.roundRect(-6.6,-7,8.6,14.4,1.6),x(e,[-5,-5.4,.4,-5.4,.4,-1.6,-5,-1.6],!0),e.roundRect(-7.6,5.6,10.6,1.8,.6)}),w(e=>{e.moveTo(2,-3.4),e.lineTo(4.6,-3.4),e.lineTo(5.8,-1.8),e.lineTo(5.8,4.2),e.quadraticCurveTo(5.8,5.4,4.6,5.2)},1.5)],gun:[w(e=>x(e,[-7.4,-4.6,7,-4.6,7,-1.4,-.4,-1.4,-1.1,1.8,-2.7,1.8,-3.6,6.6,-7.2,6.6,-5.7,-1.4,-7.4,-1.4])),w(e=>{e.moveTo(-.4,-1.4),e.quadraticCurveTo(.6,2.4,-2.4,2)},1.1)],heart:[w(e=>{S(e,-3.2,-2.4,3.8),S(e,3.2,-2.4,3.8),x(e,[-6.8,-1,6.8,-1,0,7])})],house:[w(e=>x(e,[0,-7.8,7.8,-.4,5.2,-.4,5.2,7.2,1.6,7.2,1.6,2.6,-1.6,2.6,-1.6,7.2,-5.2,7.2,-5.2,-.4,-7.8,-.4]))],lock:[w(e=>{e.moveTo(-3.7,-.6),e.lineTo(-3.7,-3.6),e.arc(0,-3.6,3.7,Math.PI,Math.PI*2),e.lineTo(3.7,-.6)},2),w(e=>{e.roundRect(-6.2,-1.8,12.4,9.4,1.8);let t=Math.sqrt(1.5**2-.6**2);e.moveTo(.6,1.8+t),e.arc(0,1.8,1.5,Math.atan2(t,.6),Math.atan2(t,-.6),!0),e.lineTo(-1,5.2),e.lineTo(1,5.2),e.closePath()})],parking:[w(e=>{e.roundRect(-7.2,-7.2,14.4,14.4,3),e.moveTo(-2.9,4.9),e.lineTo(-.8,4.9),e.lineTo(-.8,1.1),e.lineTo(.8,1.1),e.arc(.8,-1.9,3,Math.PI/2,-Math.PI/2,!0),e.lineTo(-2.9,-4.9),e.closePath(),e.moveTo(-.8,-3),e.lineTo(.7,-3),e.arc(.7,-1.9,1.1,-Math.PI/2,Math.PI/2),e.lineTo(-.8,-.8),e.closePath()})],pill:[w(e=>{e.roundRect(-3.1,-7.6,6.2,15.2,3.1),x(e,[-3.1,-.45,3.1,-.45,3.1,.45,-3.1,.45],!0)},void 0,45)],plane:[w(e=>{e.moveTo(0,-8),e.quadraticCurveTo(1.6,-7,1.6,-3),e.lineTo(8,1),e.lineTo(8,2.6),e.lineTo(1.6,.6),e.lineTo(1.1,5),e.lineTo(3.6,7),e.lineTo(3.6,8),e.lineTo(0,7),e.lineTo(-3.6,8),e.lineTo(-3.6,7),e.lineTo(-1.1,5),e.lineTo(-1.6,.6),e.lineTo(-8,2.6),e.lineTo(-8,1),e.lineTo(-1.6,-3),e.quadraticCurveTo(-1.6,-7,0,-8),e.closePath()})],scissors:[w(e=>{for(let t of[-3.5,3.5])S(e,t,4.3,2.8),S(e,t,4.3,1.35,!0);x(e,[-2.9,2,-1.3,2.5,3.9,-7.4,2.5,-7.8]),x(e,[2.9,2,1.3,2.5,-3.9,-7.4,-2.5,-7.8])})],shirt:[w(e=>{e.moveTo(-3,-7.2),e.lineTo(-7.8,-4.6),e.lineTo(-5.8,-.4),e.lineTo(-4.2,-1.4),e.lineTo(-4.2,7.2),e.lineTo(4.2,7.2),e.lineTo(4.2,-1.4),e.lineTo(5.8,-.4),e.lineTo(7.8,-4.6),e.lineTo(3,-7.2),e.quadraticCurveTo(0,-4.2,-3,-7.2),e.closePath()})],spray:[w(e=>{e.roundRect(-4.6,-3.2,7.2,11,1.6),x(e,[-3.4,0,1.4,0,1.4,3.4,-3.4,3.4],!0),e.roundRect(-3.2,-5.8,4.4,2.8,.8),e.roundRect(-1.8,-7.4,1.6,1.8,.4),S(e,2.6,-6.6,.9),S(e,4.6,-7.4,.8),S(e,4.8,-5.2,.9),S(e,6.8,-6.2,.8)})],syringe:[w(e=>{e.roundRect(-2.7,-4.2,5.4,8.2,.9),x(e,[-1.2,-2.8,1.2,-2.8,1.2,2.6,-1.2,2.6],!0),e.roundRect(-3.4,3.4,6.8,1.3,.5),e.roundRect(-.7,4.6,1.4,2.2,.3),e.roundRect(-2.6,6.6,5.2,1.3,.5),e.roundRect(-1,-5.4,2,1.4,.4),x(e,[-.55,-5.2,.55,-5.2,0,-8.4])},void 0,45)],wrench:[w(e=>{e.roundRect(-1.4,-1.4,2.8,9.4,1.4);let t=Math.sqrt(3.7**2-1.25**2);e.moveTo(1.25,-4.2-t),e.arc(0,-4.2,3.7,Math.atan2(-t,1.25),Math.atan2(-t,-1.25)+Math.PI*2),e.lineTo(-1.25,-3.5),e.lineTo(1.25,-3.5),e.closePath()},void 0,45)]}}function E(e,t,n,r=0){T??=ee();let i=T[t],a=n/16,o=e.fillStyle;if(e.save(),e.scale(a,a),e.lineJoin=`round`,e.lineCap=`round`,r>0)for(let{path:t,width:n}of i)e.lineWidth=(n??0)+r*2/a,e.stroke(t);e.strokeStyle=o;for(let{path:t,width:n}of i)n===void 0?e.fill(t):(e.lineWidth=n,e.stroke(t));e.restore()}var te=`#f0f0f0.#e04646.#6fcf6f.#5a9ef0.#f0f0f0.#f0d24a.#e57373.#b07ee0.#f080c0.#f0b070.#c8a070.#90e090.#80c8f0.#c8a0f0.#7050b0.#50d0d0.#f0e090.#f09030.#6aa8f0.#c05090.#c0a030.#d07020.#b0b0b0.#f0b0d0.#c0e050.#3a8a3a.#4060f0.#a040f0.#806050.#304090.#208080.#b09070.#90c0f0.#f0e8a0.#f0a8c0.#f08080.#e0d0a0.#f4f4f4.#3c78e0.#c0c0c0.#606060.#f06080.#4c8ce0.#a0e0a0.#f0c080.#f8f8f8.#e0b030.#f08c28.#f050a0.#d83c3c.#9070d0.#f09080.#2c7a3c.#a0d8f0.#3c6e7a.#c0c8d0.#8a5a30.#4a80e0.#4a5a8a.#e04848.#f0b040.#c04890.#d0d0d0.#3a7aa0.#c86020.#8a7a9a.#f0b440.#4a88e8.#5090e8.#58c058.#f0b848.#f0bc4c.#202020.#f0b040.#4888e0.#e04040.#a02828.#4888e8.#5090f0.#284080.#505050.#f0d840.#a0e040.#9050c0.#4878d8.#484848`.split(`.`),D=[`#f0a030`,`#4fd6e0`,`#d070f0`,`#5fd068`,`#ff5c5c`,`#5c8dff`],O=[10,25,50,100,250,500,1e3,2e3],ne=`Bahnschrift, 'Arial Narrow', 'Roboto Condensed', 'Helvetica Neue', Arial, sans-serif`,k=`'Nunito', 'Varela Round', 'Segoe UI', system-ui, sans-serif`;function re(e,t,n){let r=t*Math.min(n,1-n),i=t=>{let i=(t+e/30)%12,a=n-r*Math.max(-1,Math.min(i-3,9-i,1));return Math.round(a*255).toString(16).padStart(2,`0`)};return`#${i(0)}${i(8)}${i(4)}`}function A(e){return te[e]??re(e*137.5%360,.7,.62)}function j(e){return D[(e-1)%D.length]}function M(e){let t=Number.parseInt(e.slice(1,7),16);return[t>>16&255,t>>8&255,t&255]}function N(e,t){let[n,r,i]=M(e).map(e=>Math.round(t<0?e*(1+t):e+(255-e)*t));return`rgb(${n} ${r} ${i})`}function P(e){let[t,n,r]=M(e).map(e=>(e/255)**2.2);return .2126*t+.7152*n+.0722*r}function F(e,t,n,r=[],i=0){let{context:a,width:o,height:s}=e,c=O.find(t=>t*e.scale>=70)??O.at(-1),[l,u]=e.toWorld(0,0),[d,f]=e.toWorld(o,s);a.lineWidth=1,a.font=n,a.fillStyle=t.text,a.setLineDash(r);for(let n=Math.ceil(l/c)*c;n<=d;n+=c){let[r]=e.toScreen(n,0);a.strokeStyle=n===0?t.axis:t.line,a.beginPath(),a.moveTo(Math.round(r)+.5,0),a.lineTo(Math.round(r)+.5,s),a.stroke(),e.bare!==!0&&a.fillText(String(n),r+3,i+12)}for(let n=Math.ceil(f/c)*c;n<=u;n+=c){let[,r]=e.toScreen(0,n);a.strokeStyle=n===0?t.axis:t.line,a.beginPath(),a.moveTo(0,Math.round(r)+.5),a.lineTo(o,Math.round(r)+.5),a.stroke(),r>i+20&&e.bare!==!0&&a.fillText(String(n),3,r-3)}a.setLineDash([])}function I(e,t,n,r,i){let a=r.findIndex(([r,i])=>e.claim(r,i,t,n));if(a>=0)return a;if(!i)return;let o=r.map(([r,i])=>e.crowding(r,i,t,n)),s=o.indexOf(Math.min(...o));return e.claim(...r[s],t,n,!0),s}function L(e,t,n,r,i,a,o=!1){let{context:s}=e;s.font=a;let c=s.measureText(t).width,l=([e,,t])=>t===`center`?e-c/2:t===`right`?e-c:e,u=I(e,c+4,16,n.map(e=>[l(e)-2,e[1]-12]),o);if(u===void 0)return;let d=l(n[u]),f=n[u][1];s.lineJoin=`round`,s.lineWidth=3,s.strokeStyle=i,s.strokeText(t,d,f),s.fillStyle=r,s.fillText(t,d,f),s.lineWidth=1}var R=e=>-e.heading*Math.PI/180;function z(e,t){let n=Math.sin(e*127.1+t*311.7)*43758.5453;return n-Math.floor(n)}var ie=Float64Array.from({length:512},(e,t)=>{let n=Math.floor(t/2)/256*Math.PI*2;return t%2==0?Math.cos(n):Math.sin(n)});function ae(e,t){let n=Math.imul(e|0,668265261)^Math.imul(t|0,374761393);return n=Math.imul(n^n>>>15,2246822507),((n^n>>>13)&255)*2}function oe(e,t){let n=Math.floor(e),r=Math.floor(t),i=e=>e*e*e*(e*(e*6-15)+10),a=(n,r)=>{let i=ae(n,r);return ie[i]*(e-n)+ie[i+1]*(t-r)},o=i(e-n),s=i(t-r),c=a(n,r)+(a(n+1,r)-a(n,r))*o;return .5+(c+(a(n,r+1)+(a(n+1,r+1)-a(n,r+1))*o-c)*s)*.75}function se(e,t){return oe(e,t)*.68+oe((e*.8-t*.6)*2.1+31,(e*.6+t*.8)*2.1-7)*.32}function B(e,t){return 2**Math.round(Math.log2(t/e.scale))}function ce(e=1/0){let t,n=``;return(r,i,a=``)=>{let[o,s]=r.toWorld(0,0),c=`${r.width} ${r.height} ${r.ratio} ${o} ${s} ${r.scale} ${a}`;if(t??=document.createElement(`canvas`),c!==n){let a=Math.min(r.ratio,e),o=Math.round(r.width*a),s=Math.round(r.height*a);(t.width!==o||t.height!==s)&&(t.width=o,t.height=s);let l=t.getContext(`2d`);l.setTransform(1,0,0,1,0,0),l.clearRect(0,0,o,s),l.setTransform(a,0,0,a,0,0),i({...r,context:l,ratio:a}),n=c}r.context.drawImage(t,0,0,r.width,r.height)}}function le(e){let t=e.length;for(let{x:n,y:r}of e)t=(t*31+Math.round(n)*7+Math.round(r))%1e9;return String(t)}var V={name:`Classic`,animated:!1,background(e){e.context.clearRect(0,0,e.width,e.height),F(e,{line:`#1f232b`,axis:`#3a404c`,text:`#5a606c`},`11px ui-monospace, Consolas, monospace`)},area(e,t,n,r){let{context:i}=e;if(i.globalAlpha=t.alpha/255*.35,i.fillStyle=A(t.colour),i.beginPath(),t.shape===`radius`)i.arc(n,r,(t.radius??0)*e.scale,0,Math.PI*2);else{let a=(t.width??0)*e.scale,o=(t.height??0)*e.scale;i.rect(n-a/2,r-o/2,a,o)}i.fill(),i.globalAlpha=1},route(e,t,n,r){let{context:i}=e;i.strokeStyle=r,i.lineWidth=2,i.setLineDash([6,5]),i.beginPath(),i.moveTo(...t),i.lineTo(...n),i.stroke(),i.setLineDash([]),i.lineWidth=1},blip(e,t,n,r){let{context:i}=e;e.claim(n-6,r-6,12,12,!0),i.globalAlpha=Math.max(t.alpha/255,.25),t.sprite===8?(i.fillStyle=`#d070f0`,i.beginPath(),i.moveTo(n,r-9),i.lineTo(n+7,r),i.lineTo(n,r+9),i.lineTo(n-7,r),i.closePath(),i.fill()):t.shape!==`radius`&&t.shape!==`area`&&(i.fillStyle=A(t.colour),i.strokeStyle=`#0b0c10`,i.beginPath(),i.arc(n,r,5,0,Math.PI*2),i.fill(),i.stroke()),i.globalAlpha=1},label(e,t,n,r,i){L(e,t,[[n+8,r+4,`left`],[n-8,r+4,`right`]],`#c8ccd4`,`#0b0c10`,`12px system-ui, sans-serif`,i)},tag(e,t,n,r,i){L(e,t,[[r,i+22,`center`],[r,i-14,`center`]],n,`#0b0c10`,`12px system-ui, sans-serif`,!0)},entity(e,t,n,r,i,a){let{context:o}=e;if(t.kind===`player`){let i=a?.colour??`#d7dae0`;e.claim(n-8,r-10,16,18,!0),o.save(),o.translate(n,r),o.rotate(R(t)),o.fillStyle=i,o.strokeStyle=`#0b0c10`,o.beginPath(),o.moveTo(0,-10),o.lineTo(7,7),o.lineTo(0,3),o.lineTo(-7,7),o.closePath(),o.fill(),o.stroke(),o.restore()}else t.kind===`vehicle`?(o.save(),o.translate(n,r),o.rotate(R(t)),o.fillStyle=`#8a909c`,o.fillRect(-4,-7,8,14),o.restore()):(o.fillStyle=t.kind===`ped`?`#a8adb8`:`#5a606c`,o.beginPath(),o.arc(n,r,t.kind===`ped`?3.5:2.5,0,Math.PI*2),o.fill());return[n,r]}},H={grass:`#8fcf68`,light:[166,220,127],dark:[124,192,88],tuft:`#6eb24c`,ink:`#2b2d3a`,text:`#2d3142`},ue=[`#ef5b5b`,`#3f8efc`,`#ffc145`,`#34c38f`,`#a66cff`,`#ff8a3d`,`#f2f4f8`],U=[`#8d99ae`,`#e9c46a`,`#2a9d8f`,`#e76f51`,`#9b5de5`,`#577590`],W=[`#f8d5b5`,`#eab78e`,`#c98d62`,`#9c6644`,`#6f4630`],G=[`#3b2a20`,`#6b4423`,`#d8a93f`,`#a0522d`,`#23232b`,`#c8553d`],K=[`#3d4a6b`,`#e9c46a`,`#2a9d8f`,`#e76f51`,`#9b5de5`,`#577590`,`#f4f1de`,`#ef476f`,`#118ab2`,`#06d6a0`,`#ffd166`,`#264653`,`#8d99ae`,`#f78c6b`,`#2b2d42`,`#b5838d`],de=[`#f8d5b5`,`#f1c6a0`,`#eab78e`,`#d9a077`,`#c98d62`,`#b07650`,`#9c6644`,`#845437`,`#6f4630`];function fe(e){if(e===void 0)return;let t=([e,t],n)=>K[Math.abs(e*5+t*3+n)%K.length],n=e=>M(de[Math.abs(e)%de.length]),[r,i,a]=e.skin,[o,s]=[n(r),n(i)],c=o.map((e,t)=>Math.round(e+(s[t]-e)*a)),l=v[e.hair]??v[0];return{skin:`rgb(${c.join(` `)})`,hair:`#${l.toString(16).padStart(6,`0`)}`,top:t(e.top,1),legs:t(e.legs,0),shoes:t(e.shoes,14),long:e.hairStyle%2==1}}function q(e,t,n,r=1.6){e.lineWidth=r*2,e.strokeStyle=H.ink,e.stroke(t),e.fillStyle=n,e.fill(t)}function J(e,t,n,r,i,a=.22){e.fillStyle=`rgba(32, 70, 26, ${a})`,e.beginPath(),e.ellipse(t,n,r,i,0,0,Math.PI*2),e.fill()}function pe(e,t,n,r,i){J(e,t+4*i,n+1,12*i,4.5*i);let a=new Path2D;a.roundRect(t-2.2*i,n-9*i,4.4*i,10*i,1.6*i),q(e,a,`#9a6a45`,1.1);let o=new Path2D;if(r){for(let[e,r,a]of[[-30,7,-18],[-24,9.5,-12],[-18,11.5,-6]])o.moveTo(t,n+e*i),o.lineTo(t+r*i,n+a*i),o.lineTo(t-r*i,n+a*i),o.closePath();q(e,o,`#3f9a54`,1.1),e.fillStyle=`rgba(255, 255, 255, 0.18)`,e.beginPath(),e.moveTo(t,n-29*i),e.lineTo(t-5*i,n-20*i),e.lineTo(t-1*i,n-20*i),e.closePath(),e.fill()}else{for(let[e,r,a]of[[-6,-14,7],[6,-14,7],[0,-20,8.5]])o.moveTo(t+(e+a)*i,n+r*i),o.arc(t+e*i,n+r*i,a*i,0,Math.PI*2);q(e,o,`#4caf50`,1.1),e.fillStyle=`#7bd06b`,e.beginPath(),e.arc(t-3*i,n-22*i,3.6*i,0,Math.PI*2),e.arc(t-7.5*i,n-15.5*i,2.4*i,0,Math.PI*2),e.fill()}}function me(e,t,n,r){if(r<.12){J(e,t+2,n+1,9,3);let r=new Path2D;for(let[e,i,a]of[[-5,-4,4.6],[4.5,-4,4.6],[0,-7,5.4]])r.moveTo(t+e+a,n+i),r.arc(t+e,n+i,a,0,Math.PI*2);q(e,r,`#5cb85c`,1),e.fillStyle=`#86d176`,e.beginPath(),e.arc(t-1.5,n-8.5,2,0,Math.PI*2),e.fill()}else if(r<.19){let[i,a]=[[`#ffffff`,`#ffd23f`],[`#ff8fb1`,`#fff3b0`],[`#ffd23f`,`#f08a3c`]][Math.floor(r*1e3)%3];for(let[r,o]of[[0,0],[6,3],[-5,4]]){e.fillStyle=i,e.beginPath();for(let i=0;i<5;i++){let a=i*Math.PI*2/5;e.moveTo(t+r+Math.cos(a)*1.8+1.5,n+o+Math.sin(a)*1.8),e.arc(t+r+Math.cos(a)*1.8,n+o+Math.sin(a)*1.8,1.5,0,Math.PI*2)}e.fill(),e.fillStyle=a,e.beginPath(),e.arc(t+r,n+o,1.2,0,Math.PI*2),e.fill()}}else if(r<.215){J(e,t+2,n+1.5,7,2.5);let r=new Path2D;r.ellipse(t,n-2,6,4,0,0,Math.PI*2),q(e,r,`#c3ccd6`,1),e.fillStyle=`#e6ebf0`,e.beginPath(),e.ellipse(t-2,n-3.6,2.4,1.3,-.3,0,Math.PI*2),e.fill()}else{e.strokeStyle=H.tuft,e.lineWidth=1.8,e.lineCap=`round`,e.beginPath();for(let r of[-3,0,3])e.moveTo(t+r,n),e.quadraticCurveTo(t+r*1.1,n-3,t+r*1.7,n-6+Math.abs(r)*.4);e.stroke(),e.lineCap=`butt`}}function he(e,t){let{context:n,width:r,height:i}=e;n.fillStyle=H.grass,n.fillRect(0,0,r,i);let a=B(e,380),o=Math.ceil(r/16)+1,s=Math.ceil(i/16)+1,c=document.createElement(`canvas`);c.width=o,c.height=s;let l=c.getContext(`2d`),u=l.createImageData(o,s),[d,f]=e.toWorld(0,0);for(let t=0;t<s;t++)for(let n=0;n<o;n++){let r=se((d+n*16/e.scale)/a,(f-t*16/e.scale)/a),i=Math.min(Math.max((r-.55)/.09,0),1),s=Math.min(Math.max((.45-r)/.09,0),1),[c,l,p]=i>0?H.light:H.dark,m=i>0?i:s,h=(t*o+n)*4;u.data[h]=c,u.data[h+1]=l,u.data[h+2]=p,u.data[h+3]=Math.round(m*255)}l.putImageData(u,0,0),n.imageSmoothingQuality=`high`,n.drawImage(c,-8,-8,o*16,s*16);let p=new Set;for(let a of t){if(a.shape===`radius`||a.shape===`area`)continue;let[t,o]=e.toScreen(a.x,a.y);if(!(t<-30||o<-30||t>r+30||o>i+30)){for(let e=-1;e<=1;e++)for(let n=-1;n<=1;n++)p.add(`${Math.floor(t/30)+e} ${Math.floor(o/30)+n}`);e.scale>=.1&&a.sprite!==8&&(n.fillStyle=`rgba(244, 228, 178, 0.85)`,n.beginPath(),n.ellipse(t,o+6,19,8.5,0,0,Math.PI*2),n.fill(),n.fillStyle=`rgba(255, 246, 214, 0.7)`,n.beginPath(),n.ellipse(t,o+5,12,5,0,0,Math.PI*2),n.fill())}}let m=B(e,58),h=Math.log2(m),[g,_]=e.toWorld(-40,-40),[v,y]=e.toWorld(r+40,i+60),b=[];for(let t=Math.floor(g/m);t<=v/m;t++)for(let n=Math.floor(y/m);n<=_/m;n++){let r=z(t+h*7.3,n-h*3.1);if(r>.55)continue;let[i,a]=e.toScreen((t+.15+z(n,t+h)*.7)*m,(n+.15+z(t+3.7,n-h)*.7)*m);r<.215&&p.has(`${Math.floor(i/30)} ${Math.floor(a/30)}`)||b.push([i,a,r])}b.sort((e,t)=>e[1]-t[1]);for(let[e,t,r]of b)r<.07?pe(n,e,t,r<.025,.85+r*97%1*.35):me(n,e,t,r);F(e,{line:`rgba(255, 255, 255, 0.22)`,axis:`rgba(255, 255, 255, 0.6)`,text:`#3f6e2c`},`800 10px ${k}`,[2,6])}function ge(e){let{context:t,width:n,height:r,time:i}=e;t.fillStyle=`rgba(28, 60, 36, 0.05)`;for(let e=0;e<4;e++){let a=n+600,o=(e*.31*a+i*.012)%a-300,s=(e*.37+.12)%1*r+Math.sin(i/9e3+e)*24;t.beginPath();for(let[e,n,r,i]of[[0,0,120,52],[90,-20,90,44],[-80,14,80,38]])t.moveTo(o+e+r,s+n),t.ellipse(o+e,s+n,r,i,0,0,Math.PI*2);t.fill()}}function _e(e){return e.scale>=.1?12.5:e.scale>=.04?10.5:8.5}function ve(e){let t=P(e);return t>.8?`#5f6b7d`:t>.42?N(e,-.32):e}function ye(e,t,n,r,i,a){let{context:o}=e;o.font=`800 12px ${k}`;let s=Math.ceil(o.measureText(t).width)+16,c=r.map(([e,t])=>t?e:e-20),l=I(e,s,26,r.map(([,,e=0],t)=>[n+e-s/2,c[t]-3]),a);if(l===void 0)return;let u=c[l],[,d,f=0]=r[l],p=n+f,m=new Path2D;m.roundRect(p-s/2,u,s,20,10);let h=d?u:u+20;m.moveTo(p-5,h),m.lineTo(p,h+(d?-5:5)),m.lineTo(p+5,h),o.fillStyle=`rgba(30, 50, 30, 0.18)`,o.save(),o.translate(0,2.5),o.fill(m),o.restore(),o.fillStyle=i,o.fill(m),o.fillStyle=H.text,o.textAlign=`center`,o.fillText(t,p,u+14.5),o.textAlign=`left`}function be(e){return[`back`,`right`,`front`,`left`][Math.round((e%(Math.PI*2)+Math.PI*2)/(Math.PI/2))%4]}function xe(e,t,n,r,i,a,o=!1,s){let c=be(r),l=s?.skin??W[a%W.length],u=s?.hair??G[Math.floor(a/5)%G.length],d=s?.long??Math.floor(a/3)%2==0,f=t/105+a,p=n?Math.sin(f):0,m=n?-Math.abs(Math.sin(f))*2:Math.sin(t/420+a)*.5;o||J(e,0,.5,10-(n?Math.abs(p):0),3.6,.26),e.save(),e.translate(0,m);let h=c===`left`||c===`right`,g=c===`left`?-1:1,_=new Path2D,v=new Path2D;for(let[e,t]of[[-3,Math.max(0,p)],[3,Math.max(0,-p)]]){let n=h?p*(e<0?3:-3)*g:0,r=o?1.5:-t*2.6;_.roundRect((h?e*.35:e)-2.1+n,-8.5+r,4.2,8.5,2),v.roundRect((h?e*.35+g:e)-2.6+n,-2.8+r,5.2,3.2,1.5)}q(e,_,s?.legs??`#3d4a6b`,1.4),q(e,v,s?.shoes??`#2b2d42`,1.2);let y=new Path2D;for(let[e,t]of[[-8.2,-p],[8.2,p]]){if(h&&e*g<0)continue;let n=h?t*2.2*g:0;y.roundRect((h?1.5*g:e)-2+n,-18-(o?3:0)+t*1.2,4,8.5,2)}let b=new Path2D;b.roundRect(-7,-20,14,12.5,5),q(e,b,i,1.4),e.save(),e.clip(b),e.fillStyle=`rgba(0, 0, 0, 0.13)`,e.fillRect(h?-7*g:2,-20,h?6*g:5,13),e.restore(),q(e,y,N(i,-.08),1.4);let x=new Path2D;if(x.arc(0,-27.5,9,0,Math.PI*2),q(e,x,l,1.4),e.save(),e.clip(x),e.fillStyle=u,e.beginPath(),c===`back`?e.rect(-10,-40,20,16):h?(e.ellipse(-3*g,-32,9.5,6.5,0,0,Math.PI*2),e.rect(-10*g,-36,7*g,12)):e.ellipse(0,-33.5,11,6.5,0,0,Math.PI*2),e.fill(),e.restore(),d&&c!==`front`&&(e.fillStyle=u,e.strokeStyle=H.ink,e.lineWidth=1.4,e.beginPath(),e.roundRect(h?-9*g-2.5:-7,-28,5,10,2.5),h||e.roundRect(2,-28,5,10,2.5),e.fill(),e.stroke()),c!==`back`){let n=(t+a*977)%3800<130,r=h?[3.6*g]:[-3.2,3.2];e.fillStyle=H.ink,e.strokeStyle=H.ink,e.lineWidth=1.3;for(let t of r)e.beginPath(),n?(e.moveTo(t-1.4,-26.5),e.lineTo(t+1.4,-26.5),e.stroke()):(e.ellipse(t,-26.6,1.25,1.6,0,0,Math.PI*2),e.fill());e.fillStyle=`rgba(255, 120, 120, 0.35)`;for(let t of h?[2*g]:[-5.2,5.2])e.beginPath(),e.ellipse(t,-23.4,1.9,1.2,0,0,Math.PI*2),e.fill();h||(e.beginPath(),e.arc(0,-24,1.8,.15*Math.PI,.85*Math.PI),e.stroke())}e.restore()}function Se(e,t,n,r){let i=new Path2D;for(let[e,t]of[[-9,-11],[5.4,-11],[-9,5.5],[5.4,5.5]])i.roundRect(e,t,3.6,6.5,1.6);e.fillStyle=`#23232b`,e.fill(i);let a=new Path2D;a.roundRect(-8,-15.5,16,31,6.5),q(e,a,t,1.3),e.save(),e.clip(a),e.fillStyle=`rgba(255, 255, 255, 0.22)`,e.fillRect(-8,-15.5,4,31),e.fillStyle=`rgba(0, 0, 0, 0.12)`,e.fillRect(4.5,-15.5,4,31),e.restore();let o=e.createLinearGradient(0,-9,0,-3);o.addColorStop(0,`#d9f4ff`),o.addColorStop(1,`#7cc6ee`),e.fillStyle=o,e.strokeStyle=H.ink,e.lineWidth=1,e.beginPath(),e.roundRect(-6,-9.5,12,6,2),e.fill(),e.stroke(),e.fillStyle=N(t,.18),e.beginPath(),e.roundRect(-6,-2.5,12,9,2.5),e.fill(),e.stroke(),e.fillStyle=`#7cc6ee`,e.beginPath(),e.roundRect(-5.5,7.5,11,4,1.5),e.fill(),e.stroke(),e.strokeStyle=`rgba(255, 255, 255, 0.85)`,e.lineWidth=1.2,e.beginPath(),e.moveTo(-3.5,-8.5),e.lineTo(-1,-4.5),e.stroke();for(let[t,n,r]of[[-6,-15.4,`#ffe066`],[3.6,-15.4,`#ffe066`],[-6,13.6,`#ff6b6b`],[3.6,13.6,`#ff6b6b`]])e.fillStyle=r,e.beginPath(),e.roundRect(t,n,2.4,1.8,.8),e.fill();if(n)for(let t=0;t<3;t++){let n=(r/420+t/3)%1;e.fillStyle=`rgba(255, 255, 255, ${.55*(1-n)})`,e.beginPath(),e.arc(-3+Math.sin(t*2.1)*2,18+n*12,2+n*3,0,Math.PI*2),e.fill()}}function Ce(){let e=ce();return{name:`Cartoon`,animated:!0,background(t,n){e(t,e=>he(e,n),le(n)),ge(t)},area(e,t,n,r){let{context:i}=e,a=A(t.colour),o=new Path2D;if(t.shape===`radius`)o.arc(n,r,(t.radius??0)*e.scale,0,Math.PI*2);else{let i=(t.width??0)*e.scale,a=(t.height??0)*e.scale;o.roundRect(n-i/2,r-a/2,i,a,Math.min(16,i/4,a/4))}i.globalAlpha=t.alpha/255*.22,i.fillStyle=a,i.fill(o),i.globalAlpha=Math.max(t.alpha/255,.4),i.strokeStyle=N(a,-.15),i.lineWidth=2.5,i.setLineDash([8,6]),i.lineDashOffset=-e.time/45,i.stroke(o),i.setLineDash([]),i.lineDashOffset=0,i.globalAlpha=1,i.lineWidth=1},route(e,t,n,r){let{context:i,time:a}=e;i.strokeStyle=r,i.globalAlpha=.18,i.lineWidth=9,i.lineCap=`round`,i.beginPath(),i.moveTo(...t),i.lineTo(...n),i.stroke(),i.globalAlpha=1,i.lineCap=`butt`;let o=Math.hypot(n[0]-t[0],n[1]-t[1]),s=a/36%14;i.lineWidth=1.6,i.strokeStyle=N(r,-.25),i.fillStyle=`#ffffff`;for(let e=s;e<o-6;e+=14){let r=e/o;i.beginPath(),i.arc(t[0]+(n[0]-t[0])*r,t[1]+(n[1]-t[1])*r,3,0,Math.PI*2),i.fill(),i.stroke()}i.lineWidth=1},blip(e,t,n,r,i){let{context:a,time:o}=e,s=A(t.colour);if(a.globalAlpha=Math.max(t.alpha/255,.35),t.sprite===8){e.claim(n-3,r-30,22,32,!0);let t=o/1600%1;a.strokeStyle=`rgba(239, 71, 111, ${.7*(1-t)})`,a.lineWidth=2,a.beginPath(),a.ellipse(n,r,6+t*14,(6+t*14)*.4,0,0,Math.PI*2),a.stroke(),J(a,n+2,r,6,2.4);let i=new Path2D;i.roundRect(n-1.3,r-28,2.6,28,1.3),q(a,i,`#e8e2d4`,1);let s=new Path2D,c=e=>Math.sin(o/160-e/4)*1.6*(e/16);s.moveTo(n+1,r-27);for(let e=0;e<=16;e+=2)s.lineTo(n+1+e,r-27+c(e)+e*.06);for(let e=16;e>=0;e-=2)s.lineTo(n+1+e,r-17+c(e)-e*.06);s.closePath(),q(a,s,`#ef476f`,1)}else if(t.shape!==`radius`&&t.shape!==`area`){let c=_e(e);e.claim(n-c,r-c*1.35-1,c*2,c*2.1+2,!0);let l=i?5:0,u=Math.sin(o/700+t.handle*1.7)*1.1-l;J(a,n,r+c*.75,c*.85-l*.3,c*.32),a.save(),a.translate(n,r+u-c*.35),i&&a.scale(1.12,1.12),a.fillStyle=N(P(s)>.8?`#9aa5b4`:s,-.35),a.beginPath(),a.arc(0,2.6,c,0,Math.PI*2),a.fill(),a.fillStyle=`#ffffff`,a.beginPath(),a.arc(0,0,c,0,Math.PI*2),a.fill(),a.strokeStyle=P(s)>.8?`#9aa5b4`:s,a.lineWidth=c>10?3:2.4,a.beginPath(),a.arc(0,0,c-1.5,0,Math.PI*2),a.stroke();let d=b(t.sprite);a.fillStyle=ve(s),d===void 0?(a.font=`900 ${Math.round(c)}px ${k}`,a.textAlign=`center`,a.fillText((t.name??`•`).slice(0,1).toUpperCase(),0,c*.36),a.textAlign=`left`):E(a,d,c*1.18),a.restore()}a.globalAlpha=1,a.lineWidth=1},label(e,t,n,r,i){let a=_e(e);ye(e,t,n,[[r+a*.75+9,!0],[r-a*1.45-7,!1]],`#ffffff`,i)},tag(e,t,n,r,i){ye(e,t,r,[[i-47,!1],[i+10,!0],[i-47,!1,48],[i-47,!1,-48]],n,!0)},entity(e,t,n,r,i,a){let{context:o,time:s}=e;if(t.kind===`player`||t.kind===`ped`){let c=a?.colour??U[t.id%U.length],l=t.kind===`ped`?.86:1.08;if(e.claim(n-10*l,r-37*l,20*l,38*l,!0),a!==void 0){let e=s/2200%1;o.strokeStyle=c,o.lineWidth=2.5,o.beginPath(),o.ellipse(n,r,14,5.5,0,0,Math.PI*2),o.stroke(),o.globalAlpha=1-e,o.lineWidth=1.5,o.beginPath(),o.ellipse(n,r,14+e*12,5.5+e*4.5,0,0,Math.PI*2),o.stroke(),o.globalAlpha=1}o.save(),o.translate(n,r),o.scale(l,l);let u=fe(t.look);return xe(o,s,i,R(t),u?.top??c,(a?.client??t.id)*7,!1,u),o.restore(),[n,r-14*l]}if(t.kind===`vehicle`){let a=Math.min(Math.max(e.scale/6,.8),1.4),c=R(t),l=i?Math.sin(s/55)*.5:0;return o.save(),o.translate(n+3*a,r+4*a),o.rotate(c),o.scale(a,a),o.fillStyle=`rgba(32, 70, 26, 0.24)`,o.beginPath(),o.roundRect(-9,-15,18,31,7),o.fill(),o.restore(),o.save(),o.translate(n,r+l),o.rotate(c),o.scale(a,a),Se(o,ue[t.id%ue.length],i,s),o.restore(),o.lineWidth=1,[n,r]}J(o,n+2,r+5,8,3);let c=new Path2D;return c.roundRect(n-6,r-6,12,12,2),q(o,c,`#c8915a`,1.2),o.strokeStyle=`#8a5a30`,o.lineWidth=1.2,o.beginPath(),o.moveTo(n-4.5,r-4.5),o.lineTo(n+4.5,r+4.5),o.moveTo(n+4.5,r-4.5),o.lineTo(n-4.5,r+4.5),o.stroke(),o.lineWidth=1,[n,r]},dragging(e,t,n,r){let{context:i,time:a}=e;i.fillStyle=`#ffffff`;let o=Math.hypot(n[0]-t[0],n[1]-t[1]);for(let e=8;e<o-24;e+=12){let r=e/o;i.beginPath(),i.arc(t[0]+(n[0]-t[0])*r,t[1]+(n[1]-t[1])*r,2.2,0,Math.PI*2),i.fill()}J(i,n[0],n[1]+26,9,3.2,.3),i.save(),i.translate(n[0],n[1]+16+Math.sin(a/160)*1.5),i.rotate(Math.sin(a/240)*.08);let s=fe(r.look);xe(i,a,!1,Math.PI,s?.top??r.colour,r.client*7,!0,s),i.restore()},overlay(e){let{context:t,height:n,time:r}=e,i=n-34;t.fillStyle=`rgba(30, 50, 30, 0.2)`,t.beginPath(),t.arc(34,i+3,21,0,Math.PI*2),t.fill();let a=new Path2D;a.arc(34,i,21,0,Math.PI*2),q(t,a,`#ffffff`,1.2),t.save(),t.translate(34,i),t.rotate(Math.sin(r/900)*.07),t.fillStyle=`#ef476f`,t.beginPath(),t.moveTo(0,-15),t.lineTo(4.5,0),t.lineTo(-4.5,0),t.closePath(),t.fill(),t.fillStyle=`#b8c2cf`,t.beginPath(),t.moveTo(0,15),t.lineTo(4.5,0),t.lineTo(-4.5,0),t.closePath(),t.fill(),t.restore(),t.fillStyle=H.ink,t.beginPath(),t.arc(34,i,2,0,Math.PI*2),t.fill(),t.font=`900 9px ${k}`,t.textAlign=`center`,t.fillText(`N`,34,i-23-3);let o=[5,10,25,50,100,250,500,1e3,2500,5e3].find(t=>t*e.scale>=56)??5e3,s=o*e.scale,c=o>=1e3?`${o/1e3} km`:`${o} m`;t.font=`800 11px ${k}`;let l=Math.max(s,t.measureText(c).width)+20;t.fillStyle=`rgba(30, 50, 30, 0.2)`,t.beginPath(),t.roundRect(66,i-12+2.5,l,26,13),t.fill(),t.fillStyle=`#ffffff`,t.beginPath(),t.roundRect(66,i-12,l,26,13),t.fill(),t.fillStyle=H.text,t.fillText(c,66+l/2,i+1),t.fillStyle=H.ink,t.fillRect(66+(l-s)/2,i+6,s/2,3),t.fillStyle=`#b8c2cf`,t.fillRect(66+l/2,i+6,s/2,3),t.textAlign=`left`}}}var we=[[],[[3,2]],[[2,1]],[[3,1]],[[0,1]],[[0,3],[1,2]],[[0,2]],[[0,3]],[[0,3]],[[0,2]],[[0,1],[3,2]],[[0,1]],[[3,1]],[[1,2]],[[3,2]],[]];function Te(e){let{context:t,width:n,height:r}=e,i=B(e,520),a=Math.ceil(n/9)+1,o=Math.ceil(r/9)+1,[s,c]=e.toWorld(0,0),l=9/e.scale,u=new Float32Array(a*o);for(let e=0;e<o;e++)for(let t=0;t<a;t++)u[e*a+t]=se((s+t*l)/i,(c-e*l)/i);let d=.3,f=.04,p=Array.from({length:12},()=>new Path2D);for(let e=0;e<o-1;e++)for(let t=0;t<a-1;t++){let n=u[e*a+t],r=u[e*a+t+1],i=u[(e+1)*a+t+1],o=u[(e+1)*a+t],s=Math.max(n,r,i,o);for(let a=Math.max(Math.ceil((Math.min(n,r,i,o)-d)/f),0);a<p.length&&d+a*f<=s;a++){let s=d+a*f,c=a=>a===0?[(t+(s-n)/(r-n))*9,e*9]:a===1?[(t+1)*9,(e+(s-r)/(i-r))*9]:a===2?[(t+(s-o)/(i-o))*9,(e+1)*9]:[t*9,(e+(s-n)/(o-n))*9],l=(n>s?8:0)|(r>s?4:0)|(i>s?2:0)|o>s;for(let[e,t]of we[l])p[a].moveTo(...c(e)),p[a].lineTo(...c(t))}}t.lineWidth=1,p.forEach((e,n)=>{t.strokeStyle=n%4==3?`rgba(150, 200, 235, 0.13)`:`rgba(150, 200, 235, 0.055)`,t.stroke(e)})}function Ee(e){let t=`#c65ad8`,n=`#05080b`,r=(e,t=600)=>`semi-condensed ${t} ${e}px ${ne}`,i=e=>e>=760,a=ce(1),o=e=>{e.fillStyle=`rgba(0, 0, 0, 0.4)`,e.beginPath(),e.ellipse(0,0,4.5,1.8,0,0,Math.PI*2),e.fill();let r=new Path2D;r.moveTo(0,0),r.bezierCurveTo(-1.8,-5,-7,-8,-7,-13.5),r.arc(0,-13.5,7,Math.PI,0),r.bezierCurveTo(7,-8,1.8,-5,0,0),r.closePath(),e.lineWidth=3,e.lineJoin=`round`,e.strokeStyle=n,e.stroke(r),e.fillStyle=t,e.fill(r),e.fillStyle=`#ffffff`,e.beginPath(),e.arc(0,-13.5,2.6,0,Math.PI*2),e.fill()},s=(e,t)=>{let r=new Path2D;r.moveTo(0,-12),r.lineTo(8.5,9),r.lineTo(0,4.5),r.lineTo(-8.5,9),r.closePath(),e.lineJoin=`round`,e.lineWidth=3.5,e.strokeStyle=n,e.stroke(r),e.fillStyle=t,e.fill(r),e.fillStyle=`rgba(255, 255, 255, 0.35)`,e.beginPath(),e.moveTo(0,-12),e.lineTo(0,4.5),e.lineTo(-8.5,9),e.closePath(),e.fill()},c=(e,t,n,i)=>{e.strokeStyle=`#ffffff`,e.fillStyle=`#ffffff`,e.lineWidth=1.4,e.beginPath(),e.roundRect(t,n,11,16,5.5),e.stroke(),e.beginPath(),e.moveTo(t,n+6.5),e.lineTo(t+11,n+6.5),e.moveTo(t+5.5,n),e.lineTo(t+5.5,n+6.5),e.stroke(),e.beginPath(),i===`wheel`?e.roundRect(t+4.2,n+1.8,2.6,4,1.3):(e.moveTo(t+5.5,n+.7),e.lineTo(t+5.5,n+6.5),e.lineTo(t+.7,n+6.5),e.arc(t+5.5,n+5.5,4.8,Math.PI,Math.PI*1.5)),e.fill(),i===`twice`&&(e.font=r(9,700),e.fillText(`2`,t+13,n+6))};return{name:`GTA`,animated:!0,instructions:!0,insets:e=>({top:48,right:i(e)?260:0,bottom:42,left:0}),background(t){let{context:n,width:i,height:o}=t,s=n.createRadialGradient(i*.45,o*.55,0,i*.45,o*.55,Math.hypot(i,o)*.62);s.addColorStop(0,`#1d3448`),s.addColorStop(1,`#0c1824`),n.fillStyle=s,n.fillRect(0,0,i,o);let c=e();if(c!==void 0){let[e,r]=t.toScreen(c.left,c.top),[i,a]=t.toScreen(c.right,c.bottom);n.drawImage(c.image,e,r,i-e,a-r)}else a(t,Te);F(t,{line:`rgba(140, 180, 215, 0.09)`,axis:`rgba(140, 180, 215, 0.26)`,text:`rgba(180, 205, 228, 0.5)`},r(10),[],48);let l=n.createRadialGradient(i/2,o/2,Math.min(i,o)*.4,i/2,o/2,Math.hypot(i,o)*.6);l.addColorStop(0,`rgba(0, 0, 0, 0)`),l.addColorStop(1,`rgba(0, 0, 0, 0.45)`),n.fillStyle=l,n.fillRect(0,0,i,o)},area(e,t,n,r){let{context:i}=e,a=A(t.colour),o=new Path2D;if(t.shape===`radius`)o.arc(n,r,(t.radius??0)*e.scale,0,Math.PI*2);else{let i=(t.width??0)*e.scale,a=(t.height??0)*e.scale;o.rect(n-i/2,r-a/2,i,a)}i.globalAlpha=t.alpha/255*.3,i.fillStyle=a,i.fill(o),i.globalAlpha=Math.max(t.alpha/255,.3)*.7,i.strokeStyle=a,i.lineWidth=1.5,i.stroke(o),i.globalAlpha=1,i.lineWidth=1},route(e,n,r){let{context:i,time:a}=e;i.lineCap=`round`;for(let[e,a]of[[`#16081c`,8],[t,4.5]])i.strokeStyle=e,i.lineWidth=a,i.beginPath(),i.moveTo(...n),i.lineTo(...r),i.stroke();let o=Math.hypot(r[0]-n[0],r[1]-n[1]),s=Math.atan2(r[1]-n[1],r[0]-n[0]);i.strokeStyle=`rgba(255, 255, 255, 0.8)`,i.lineWidth=1.6;for(let e=a/24%26;e<o-14;e+=26){let t=e/o;i.save(),i.translate(n[0]+(r[0]-n[0])*t,n[1]+(r[1]-n[1])*t),i.rotate(s),i.beginPath(),i.moveTo(-1.8,-2.6),i.lineTo(1.4,0),i.lineTo(-1.8,2.6),i.stroke(),i.restore()}i.lineCap=`butt`,i.lineWidth=1},blip(e,t,r,i,a){let{context:s,time:c}=e;if(t.sprite===8?e.claim(r-8,i-22,16,24,!0):t.shape!==`radius`&&t.shape!==`area`&&e.claim(r-9,i-9,18,18,!0),s.globalAlpha=Math.max(t.alpha/255,.3),s.strokeStyle=n,s.save(),s.translate(r,i),t.sprite===8)o(s);else if(t.shape!==`radius`&&t.shape!==`area`){let e=b(t.sprite);s.fillStyle=A(t.colour),e===void 0?(s.lineWidth=3,s.beginPath(),s.arc(0,0,5.5,0,Math.PI*2),s.stroke(),s.fill()):E(s,e,17,1.6)}if(s.restore(),s.globalAlpha=1,a){let e=15+Math.sin(c/160);s.strokeStyle=`#ffffff`,s.lineWidth=2;for(let t=0;t<4;t++){let n=t*Math.PI/2+Math.PI/4;s.beginPath(),s.arc(r,i,e,n-.42,n+.42),s.stroke()}s.lineWidth=1}},label(e,t,i,a,o){L(e,t.toUpperCase(),[[i+12,a+4,`left`],[i-12,a+4,`right`],[i,a+22,`center`],[i,a-14,`center`]],`#ffffff`,n,r(11,700),o)},tag(e,t,n,i,a){let{context:o}=e;o.font=r(11,700);let s=t.toUpperCase(),c=Math.ceil(o.measureText(s).width)+15,l=[[i-c/2,a+16],[i-c/2,a-33],[i+15,a-8.5],[i-15-c,a-8.5]],u=l[I(e,c,17,l,!0)];o.fillStyle=`rgba(0, 0, 0, 0.8)`,o.fillRect(u[0],u[1],c,17),o.fillStyle=n,o.fillRect(u[0],u[1],3,17),o.fillStyle=`#ffffff`,o.fillText(s,u[0]+9,u[1]+12.5)},entity(e,t,r,i,a,o){let{context:c,time:l}=e;if(t.kind===`player`){let n=o?.colour??`#ffffff`;e.claim(r-10,i-12,20,22,!0),c.save(),c.translate(r,i),c.rotate(R(t));let a=c.createRadialGradient(0,0,0,0,0,44);a.addColorStop(0,`rgba(255, 255, 255, 0.32)`),a.addColorStop(1,`rgba(255, 255, 255, 0)`),c.fillStyle=a,c.globalAlpha=.8+Math.sin(l/500)*.2,c.beginPath(),c.moveTo(0,0),c.arc(0,0,44,-Math.PI/2-.55,-Math.PI/2+.55),c.closePath(),c.fill(),c.globalAlpha=1,s(c,n),c.restore(),c.lineWidth=1}else if(t.kind===`vehicle`){c.save(),c.translate(r,i),c.rotate(R(t));let e=new Path2D;e.roundRect(-5,-9,10,18,3),c.lineWidth=3,c.strokeStyle=n,c.stroke(e),c.fillStyle=`#dbe3ea`,c.fill(e),c.fillStyle=`#2b3743`,c.beginPath(),c.roundRect(-3.6,-5,7.2,3.4,1),c.roundRect(-3.6,3.6,7.2,2.4,1),c.fill(),c.restore(),c.lineWidth=1}else c.lineWidth=2.5,c.strokeStyle=n,c.fillStyle=t.kind===`ped`?`#c9d1d9`:`#8b98a5`,c.beginPath(),t.kind===`ped`?c.arc(r,i,3.8,0,Math.PI*2):c.rect(r-3.5,i-3.5,7,7),c.stroke(),c.fill(),c.lineWidth=1;return[r,i]},dragging(e,t,n,r){let{context:i}=e;i.strokeStyle=`rgba(255, 255, 255, 0.7)`,i.lineWidth=1.5,i.setLineDash([5,5]),i.beginPath(),i.moveTo(...t),i.lineTo(...n),i.stroke(),i.setLineDash([]),i.save(),i.translate(...n),i.globalAlpha=.7,s(i,r.colour),i.restore(),i.globalAlpha=1,i.lineWidth=1},overlay(e,t,a,o){let{context:s,width:l,height:u}=e,d=s.createLinearGradient(0,0,0,48);d.addColorStop(0,`rgba(3, 6, 9, 0.94)`),d.addColorStop(1,`rgba(3, 6, 9, 0.78)`),s.fillStyle=d,s.fillRect(0,0,l,48),s.fillStyle=`rgba(255, 255, 255, 0.12)`,s.fillRect(0,47,l,1),s.fillStyle=`#ffffff`,s.font=`italic ${r(25,700)}`,s.fillText(`FIVERUNNER`,18,33);let f=s.measureText(`FIVERUNNER`).width,p=a.find(({client:e})=>e===o)?.colour??`#f0a030`;s.font=r(13,700);let m=s.measureText(`MAP`).width+28,h=18+f+18;s.fillStyle=`#ffffff`,s.fillRect(h,12,m,26),s.fillStyle=p,s.fillRect(h,12,m,3),s.fillStyle=`#05080b`,s.fillText(`MAP`,h+14,30.5),s.textAlign=`right`;let g=l-18;s.fillStyle=`rgba(220, 230, 240, 0.7)`,s.font=r(12,600);let _=`${t.length} ${t.length===1?`BLIP`:`BLIPS`}`;s.fillText(_,g,29),g-=s.measureText(_).width+22;for(let e of[...a].reverse()){if(e.name===void 0)continue;let t=e.name.toUpperCase();s.font=r(13,700),s.fillStyle=o===void 0||o===e.client?`#ffffff`:`rgba(255, 255, 255, 0.45)`,s.fillText(t,g,29);let n=s.measureText(t).width;if(s.fillStyle=e.colour,s.beginPath(),s.arc(g-n-9,25,4,0,Math.PI*2),s.fill(),g-=n+30,g<h+m+40)break}if(s.textAlign=`left`,i(l)){let e=new Map;for(let n of t){if(n.name===void 0)continue;let t=e.get(n.name);t===void 0?e.set(n.name,{blip:n,count:1}):t.count++}if(e.size>0){let t=[...e.entries()].sort(([e],[t])=>e.localeCompare(t)),i=l-236-14,a=Math.max(Math.floor((u-62-28-30-36)/22),1),o=t.length>a?t.slice(0,a-1):t,c=t.length-o.length,d=36+(o.length+ +(c>0))*22+6;s.fillStyle=`rgba(3, 6, 9, 0.78)`,s.fillRect(i,62,236,d),s.fillStyle=p,s.fillRect(i,62,236,2),s.fillStyle=`#ffffff`,s.font=r(14,700),s.fillText(`LEGEND`,i+12,86),s.textAlign=`right`,s.fillStyle=`rgba(220, 230, 240, 0.6)`,s.font=r(12,600),s.fillText(String(e.size),i+236-12,86),s.textAlign=`left`,o.forEach(([e,{blip:t,count:a}],o)=>{let c=98+o*22;o%2==0&&(s.fillStyle=`rgba(255, 255, 255, 0.035)`,s.fillRect(i,c,236,22)),s.save(),s.translate(i+22,c+11),s.fillStyle=A(t.colour),s.strokeStyle=n;let l=b(t.sprite);l===void 0?(s.lineWidth=2.4,s.beginPath(),s.arc(0,0,4.5,0,Math.PI*2),s.stroke(),s.fill()):E(s,l,14,1.2),s.restore(),s.font=r(12,600);let u=e.toUpperCase();for(;u.length>1&&s.measureText(u).width>146;)u=u.slice(0,-1);u!==e.toUpperCase()&&(u=`${u.trimEnd()}…`),s.fillStyle=`#eef3f8`,s.fillText(u,i+40,c+15.5),s.textAlign=`right`,s.fillStyle=`rgba(200, 215, 230, 0.55)`,s.font=r(11,600),s.fillText(`×${a}`,i+236-12,c+15.5),s.textAlign=`left`}),c>0&&(s.fillStyle=`rgba(200, 215, 230, 0.6)`,s.font=r(11,700),s.fillText(`+ ${c} MORE`,i+40,98+o.length*22+15.5))}}let v=[[`left`,`MOVE PLAYER`],[`twice`,`WAYPOINT`],[`wheel`,`ZOOM`]];s.font=r(11,700);let y=v.map(([,e])=>s.measureText(e).width+36),x=l-14-y.reduce((e,t)=>e+t,0)-8,S=u-14-28;s.fillStyle=`rgba(3, 6, 9, 0.78)`,s.fillRect(x,S,l-14-x,28),x+=12,v.forEach(([e,t],n)=>{c(s,x,S+6,e),s.fillStyle=`#ffffff`,s.font=r(11,700),s.fillText(t,x+22,S+18.5),x+=y[n]}),s.lineWidth=1}}}var De=7,Y={left:-4e3,right:4500,bottom:-4e3,top:8e3},X={top:0,right:0,bottom:0,left:0},Oe=450,ke=`fiverunner:map-style`,Ae=`fiverunner:map-image`;function je(e){try{return localStorage.getItem(e)}catch{return null}}function Z(e,t){try{localStorage.setItem(e,t)}catch{}}var Me=class{element;#e;#t;#n;#r;#i;#a;#o;#s;#c;#l;#u;#d;#f={entities:[],blips:[]};#p=[];#m=(Y.left+Y.right)/2;#h=(Y.bottom+Y.top)/2;#g=.05;#_=!1;#v=[];#y=new Map;#b=new Map;#x=!1;#S=!0;#C;#w;constructor(e,t,n){this.element=e,this.#s=t,this.#l=n,this.#c=[V,Ce(),Ee(()=>this.#d)],this.#u=this.#c.find(({name:e})=>e===je(ke))??V;let r=document.createElement(`div`);r.className=`toolbar`;let i=document.createElement(`h2`);i.textContent=`Map`,this.#a=document.createElement(`select`),this.#a.setAttribute(`aria-label`,`Whose blips the map shows`),this.#a.addEventListener(`change`,()=>this.#R());let a=document.createElement(`select`);a.setAttribute(`aria-label`,`How the map looks`),a.append(...this.#c.map(({name:e})=>new Option(e,e))),a.value=this.#u.name,a.addEventListener(`change`,()=>{this.use(a.value),this.#s.styled?.(a.value)});let o=document.createElement(`button`);o.type=`button`,o.textContent=`Fit`,o.addEventListener(`click`,()=>{this.#_=!1,this.#M()}),this.#o=this.#E(),this.#i=document.createElement(`span`),this.#i.className=`hint`,this.#i.textContent=`Drag a player to move them, double-click to set their waypoint`,r.append(i,this.#a,a,o,this.#o,this.#i);let s=document.createElement(`div`);s.className=`view`,this.#n=s,this.#e=document.createElement(`canvas`),this.#t=this.#e.getContext(`2d`),this.#r=document.createElement(`div`),this.#r.className=`tooltip`,this.#r.hidden=!0,s.append(this.#e,this.#r),e.append(...n===void 0?[r,s]:[s]),new ResizeObserver(()=>this.#R()).observe(s),new IntersectionObserver(([e])=>{this.#S=e?.isIntersecting??!0,this.#T()}).observe(s),n===void 0&&this.#I(),this.use(this.#u.name)}show(e,t){let n=performance.now();for(let t of e.entities){let e=this.#b.get(t.id);if(this.#u.animated&&e!==void 0&&(e[0]!==t.x||e[1]!==t.y)){let[r,i]=this.#j(t.id,e,n);this.#y.set(t.id,{fromX:r,fromY:i,toX:t.x,toY:t.y,start:n})}this.#b.set(t.id,[t.x,t.y])}if(this.#f=e,t.map(({client:e,name:t})=>`${e} ${t}`).join()!==this.#p.map(({client:e,name:t})=>`${e} ${t}`).join()){let e=this.#a.value;this.#a.replaceChildren(new Option(`Blips of every player`,``),...t.map(({client:e,name:t})=>new Option(`Blips of ${t} (${e})`,String(e)))),this.#a.value=t.some(({client:t})=>String(t)===e)?e:``}this.#p=t,this.#_?this.#R():this.#M()}use(e){this.#u=this.#c.find(t=>t.name===e)??V,this.#l===void 0&&Z(ke,this.#u.name),this.#y.clear(),this.#o.hidden=this.#u.name!==`GTA`,this.#i.hidden=this.#u.instructions===!0,this.#n.dataset.style=this.#u.name,this.#_?this.#R():this.#M(),this.#T()}#T(){if(this.#x||!this.#u.animated||!this.#S)return;this.#x=!0;let e=()=>{!this.#u.animated||!this.#S?this.#x=!1:(this.#R(),requestAnimationFrame(e))};requestAnimationFrame(e)}#E(){let e=document.createElement(`details`);e.className=`map-image`;let t=document.createElement(`summary`);t.textContent=`Map image`;let n=document.createElement(`input`);n.type=`file`,n.accept=`image/*`,n.setAttribute(`aria-label`,`An image of the world to show under the map`);let r=JSON.parse(je(Ae)??`null`)??[Y.left,Y.top,Y.right,Y.bottom],i=[`Left`,`Top`,`Right`,`Bottom`].map((e,t)=>{let n=document.createElement(`input`);return n.type=`number`,n.value=String(r[t]),n.setAttribute(`aria-label`,`The ${e.toLowerCase()} edge of the image, in metres of the world`),n.title=`${e} edge, in metres`,n}),a,o=()=>{let[e,t,n,r]=i.map(e=>Number(e.value));Z(Ae,JSON.stringify([e,t,n,r])),this.#d=a===void 0?void 0:{image:a,left:e,top:t,right:n,bottom:r},this.#R()};n.addEventListener(`change`,()=>{let e=n.files?.[0];if(e===void 0)return;let t=new Image;t.addEventListener(`load`,()=>{a=t,o()}),t.src=URL.createObjectURL(e)});for(let e of i)e.addEventListener(`change`,o);return e.append(t,n,...i),e}get#D(){let e=this.#a.value;return e===``?this.#f.blips:this.#f.blips.filter(({client:t})=>String(t)===e)}get#O(){let e=this.#a.value;return e===``?void 0:Number(e)}get#k(){return this.#p.map(({client:e,name:t})=>{let n=this.#f.entities.find(({kind:t,owner:n})=>t===`player`&&n===e)?.look;return{client:e,name:t,colour:j(e),...n===void 0?{}:{look:n}}})}get#A(){let e=this.#a.value;return e===``?this.#p.find(({state:e})=>e===`joined`)?.client:Number(e)}#j(e,t,n){let r=this.#y.get(e);if(r===void 0)return[t[0],t[1]];let i=Math.min((n-r.start)/Oe,1);i===1&&this.#y.delete(e);let a=1-(1-i)**3;return[r.fromX+(r.toX-r.fromX)*a,r.fromY+(r.toY-r.fromY)*a]}#M(){if(this.#l!==void 0)return this.#R();let e=[...this.#D,...this.#f.entities],t=this.#e.getBoundingClientRect();if(t.width===0||t.height===0)return;let n=this.#u.insets?.(t.width,t.height)??X,r=Math.max(t.width-n.left-n.right,80),i=Math.max(t.height-n.top-n.bottom,80),a=Y.left,o=Y.right,s=Y.bottom,c=Y.top;e.length>0&&(a=Math.min(...e.map(({x:e})=>e)),o=Math.max(...e.map(({x:e})=>e)),s=Math.min(...e.map(({y:e})=>e)),c=Math.max(...e.map(({y:e})=>e)));let l=Math.max(o-a,c-s,200)*.15;this.#g=Math.min(r/(o-a+2*l),i/(c-s+2*l)),this.#m=(a+o)/2-(n.left-n.right)/2/this.#g,this.#h=(s+c)/2+(n.top-n.bottom)/2/this.#g,this.#R()}#N(){return this.#l??this.#e.getBoundingClientRect()}#P(e,t){let{width:n,height:r}=this.#N();return[(e-this.#m)*this.#g+n/2,(this.#h-t)*this.#g+r/2]}#F(e,t){let{width:n,height:r}=this.#N();return[(e-n/2)/this.#g+this.#m,this.#h-(t-r/2)/this.#g]}#I(){let e=this.#e,t=t=>{let n=e.getBoundingClientRect();return[t.clientX-n.left,t.clientY-n.top]};e.addEventListener(`wheel`,e=>{e.preventDefault(),this.#_=!0;let[n,r]=t(e),[i,a]=this.#F(n,r);this.#g=Math.min(Math.max(this.#g*(e.deltaY<0?1.25:.8),.005),40);let[o,s]=this.#F(n,r);this.#m+=i-o,this.#h+=a-s,this.#R()}),e.addEventListener(`mousedown`,e=>{let[n,r]=t(e),i=this.#L(n,r);i?.kind===`entity`&&i.entity.kind===`player`&&i.entity.owner!==void 0?(this.#_=!0,this.#w={kind:`player`,client:i.entity.owner,x:n,y:r}):this.#w={kind:`pan`,x:n,y:r,cx:this.#m,cy:this.#h}}),e.addEventListener(`mousemove`,e=>{let[n,r]=t(e),i=this.#w;i?.kind===`pan`?(this.#_=!0,this.#m=i.cx-(n-i.x)/this.#g,this.#h=i.cy+(r-i.y)/this.#g):i?.kind===`player`?(i.x=n,i.y=r):this.#C=this.#L(n,r)?.key,this.#R()}),e.addEventListener(`mouseup`,e=>{let n=this.#w;if(this.#w=void 0,n?.kind===`player`){let r=this.#L(...t(e),`blip`);r?.kind===`blip`?this.#s.teleport(n.client,r.blip.x,r.blip.y,r.blip.z):this.#s.teleport(n.client,...this.#F(...t(e)))}this.#R()}),e.addEventListener(`mouseleave`,()=>{this.#w=void 0,this.#C=void 0,this.#R()}),e.addEventListener(`dblclick`,e=>{let n=this.#A;if(n===void 0)return;let[r,i]=this.#F(...t(e));this.#s.waypoint(n,r,i)})}#L(e,t,n){let r,i=12;for(let a of this.#v){if(n!==void 0&&a.kind!==n)continue;let o=Math.hypot(a.sx-e,a.sy-t);o<=i&&(i=o,r=a)}return r}#R(){let e=this.#e,t=e.getBoundingClientRect();if(t.width===0||t.height===0)return;let{width:n,height:r}=this.#N(),i=devicePixelRatio*(t.width/n);(e.width!==Math.round(t.width*devicePixelRatio)||e.height!==Math.round(t.height*devicePixelRatio))&&(e.width=Math.round(t.width*devicePixelRatio),e.height=Math.round(t.height*devicePixelRatio));let a=performance.now(),o=this.#l;if(o!==void 0){let e=this.#f.entities.find(({kind:e,owner:t})=>e===`player`&&t===o.client);e!==void 0&&([this.#m,this.#h]=this.#j(e.id,[e.x,e.y],a)),this.#g=De}e.dataset.view=`${this.#m} ${this.#h} ${this.#g}`,e.dataset.players=JSON.stringify(this.#f.entities.flatMap(({kind:e,owner:t,x:n,y:r})=>e===`player`&&t!==void 0?[[t,n,r]]:[]));let s=this.#t;s.setTransform(i,0,0,i,0,0);let c=[],l={context:s,width:n,height:r,ratio:i,bare:o!==void 0,scale:this.#g,time:a,toScreen:(e,t)=>this.#P(e,t),toWorld:(e,t)=>this.#F(e,t),claim:(e,t,n,r,i=!1)=>{let a=!c.some(([i,a,o,s])=>e<i+o&&i<e+n&&t<a+s&&a<t+r);return(a||i)&&c.push([e,t,n,r]),a||i},crowding:(e,t,n,r)=>c.reduce((i,[a,o,s,c])=>i+Math.max(0,Math.min(e+n,a+s)-Math.max(e,a))*Math.max(0,Math.min(t+r,o+c)-Math.max(t,o)),0)},u=this.#u,d=this.#D,f=o===void 0?u.insets?.(n,r)??X:X;l.claim(0,0,n,f.top,!0),l.claim(n-f.right,0,f.right,r,!0),l.claim(0,r-f.bottom,n,f.bottom,!0),l.claim(0,0,f.left,r,!0),u.background(l,d),this.#v=[];let p=this.#f.entities.map(e=>{let t=this.#y.has(e.id),[n,r]=this.#j(e.id,[e.x,e.y],a);return{entity:e,moving:t,at:this.#P(n,r)}});for(let e of d)(e.shape===`radius`||e.shape===`area`)&&u.area(l,e,...this.#P(e.x,e.y));for(let e of d){if(!e.route)continue;let t=p.find(({entity:t})=>t.kind===`player`&&t.owner===e.client);t!==void 0&&u.route(l,t.at,this.#P(e.x,e.y),A(e.colour))}for(let e of d){let[t,n]=this.#P(e.x,e.y),r=`blip ${e.client} ${e.handle}`;this.#v.push({key:r,kind:`blip`,blip:e,sx:t,sy:n}),u.blip(l,e,t,n,this.#C===r)}let m=this.#k,h=[];for(let{entity:e,moving:t,at:n}of[...p].sort((e,t)=>e.at[1]-t.at[1])){let r=e.kind===`player`&&e.owner!==void 0?m.find(({client:t})=>t===e.owner)??{client:e.owner,name:void 0,colour:j(e.owner)}:void 0,[i,a]=u.entity(l,e,...n,t,r);this.#v.push({key:`entity ${e.id}`,kind:`entity`,entity:e,sx:i,sy:a}),r?.name!==void 0&&h.push([r.name,r.colour,...n])}for(let e of h)u.tag(l,...e);let g=this.#C,_=this.#v.filter(e=>e.kind===`blip`&&(e.key===g||this.#g>=.12));_.sort((e,t)=>Number(t.key===g)-Number(e.key===g));for(let e of _)e.kind===`blip`&&e.blip.name!==void 0&&u.label(l,e.blip.name,e.sx,e.sy,e.key===g);let v=this.#w;if(v?.kind===`player`){let e=p.find(({entity:e})=>e.kind===`player`&&e.owner===v.client)?.at,t=m.find(({client:e})=>e===v.client);u.dragging!==void 0&&e!==void 0&&t!==void 0?u.dragging(l,e,[v.x,v.y],t):(s.strokeStyle=j(v.client),s.setLineDash([4,4]),s.beginPath(),s.arc(v.x,v.y,9,0,Math.PI*2),s.stroke(),s.setLineDash([]))}o===void 0&&u.overlay?.(l,d,m,this.#O),this.#z()}#z(){let e=this.#w===void 0?this.#C:void 0,t=this.#v.find(({key:t})=>t===e);if(this.#r.hidden=t===void 0,t===void 0)return;let n=e=>this.#p.find(t=>t.client===e)?.name??`nobody`,r=(e,t)=>`${e.toFixed(1)}, ${t.toFixed(1)}`;this.#r.textContent=t.kind===`blip`?`${t.blip.name??(t.blip.sprite===8?`Waypoint`:`Blip`)}\n${r(t.blip.x,t.blip.y)}\nsprite ${t.blip.sprite}, colour ${t.blip.colour}\n${t.blip.script??`the player`}, on the map of ${n(t.blip.client)}`:`${t.entity.kind} ${t.entity.id}, model 0x${(t.entity.model>>>0).toString(16)}\n${r(t.entity.x,t.entity.y)}, z ${t.entity.z.toFixed(1)}, heading ${t.entity.heading.toFixed(0)}\nowned by ${n(t.entity.owner)}`,this.#r.style.left=`${t.sx+14}px`,this.#r.style.top=`${t.sy+14}px`}},Q=1920,Ne=1080,Pe=250,Fe={Escape:`ESCAPE`,Enter:`RETURN`,Backspace:`BACK`,Tab:`TAB`,Space:`SPACE`,CapsLock:`CAPITAL`,ShiftLeft:`LSHIFT`,ShiftRight:`RSHIFT`,ControlLeft:`LCONTROL`,ControlRight:`RCONTROL`,AltLeft:`LMENU`,AltRight:`RMENU`,ArrowUp:`UP`,ArrowDown:`DOWN`,ArrowLeft:`LEFT`,ArrowRight:`RIGHT`,PageUp:`PAGEUP`,PageDown:`PAGEDOWN`,Home:`HOME`,End:`END`,Insert:`INSERT`,Delete:`DELETE`,NumpadMultiply:`MULTIPLY`,NumpadAdd:`ADD`,NumpadSubtract:`SUBTRACT`,NumpadDecimal:`DECIMAL`,NumpadDivide:`DIVIDE`};function Ie(e){return/^Key[A-Z]$/.test(e)?e.slice(3):/^Digit\d$/.test(e)?e.slice(5):/^F\d{1,2}$/.test(e)?e:/^Numpad\d$/.test(e)?`NUMPAD${e.slice(6)}`:Fe[e]}var Le=class{element;world;#e;#t;#n;#r=new Map;#i=new Map;#a=new Map;#o=0;#s=[];#c=[];#l=1;#u=new Set;constructor(e,t){this.#n=t,this.element=document.createElement(`div`),this.element.className=`screen`,this.element.tabIndex=0;let n=document.createElement(`div`);n.className=`world`,this.world=new Me(n,{teleport:()=>{},waypoint:()=>{}},{client:e,width:Q/2,height:Ne/2}),this.#e=document.createElement(`div`),this.#e.className=`fade`,this.element.append(n,this.#e),this.#t=document.createElement(`div`),this.#t.className=`viewport`,this.#t.style.width=`${Q}px`,this.#t.style.height=`${Ne}px`,this.element.append(this.#t),new ResizeObserver(()=>{this.#l=this.element.clientWidth/Q,this.#t.style.transform=`scale(${this.#l})`}).observe(this.element),this.element.addEventListener(`keydown`,e=>this.#m(e,!0)),this.element.addEventListener(`keyup`,e=>this.#m(e,!1)),this.element.addEventListener(`blur`,()=>{for(let e of this.#u)this.#n.key(e,!1);this.#u.clear()}),this.element.addEventListener(`mousedown`,()=>this.element.focus()),this.element.addEventListener(`mousemove`,e=>{let t=this.#t.getBoundingClientRect();this.#h((e.clientX-t.left)/this.#l,(e.clientY-t.top)/this.#l)})}frameOf(e){for(let[t,n]of this.#r)if(n.contentWindow===e)return t}fade(e){this.#e.style.opacity=String(e)}blur(e){this.element.classList.toggle(`blurred`,e)}cursorOver(e,t){this.#h(e,t)}async create({resource:e,url:t}){let n=++this.#o;this.#a.set(e,n),this.#i.set(e,[]);let r=this.#n.frame(t);if(await this.#n.ready(r),this.#a.get(e)!==n)return;this.#a.delete(e);let i=document.createElement(`iframe`);i.name=e,i.style.visibility=`hidden`,i.allow=`microphone *; camera *; autoplay; payment 'none'; geolocation 'none';`,i.sandbox.value=`allow-forms allow-scripts allow-same-origin`,i.src=r,i.tabIndex=-1,i.addEventListener(`load`,()=>{i.style.visibility=`visible`,setTimeout(()=>{for(let t of this.#i.get(e)??[])this.#d(i,t);this.#i.delete(e)},Pe)}),this.#r.set(e,i),this.#s.push(e);let a=document.activeElement;this.#t.append(i),a instanceof HTMLIFrameElement&&a!==i&&a.focus()}destroy(e){this.#a.delete(e),this.#i.delete(e);let t=this.#r.get(e);t!==void 0&&(this.#s=this.#s.filter(t=>t!==e),t.remove(),this.#r.delete(e))}message(e,t){let n=this.#i.get(e),r=this.#r.get(e);n===void 0?r!==void 0&&this.#d(r,t):n.push(t)}#d(e,t){e.contentWindow?.postMessage(JSON.parse(t),`*`)}frameFocus(e,t){t?this.#f(e):this.#p(e)}zIndex(e,t){let n=this.#r.get(e);n!==void 0&&(n.style.zIndex=String(t))}focus(e,t){this.element.classList.toggle(`nui-cursor`,t),this.element.classList.toggle(`nui-focus`,e);let n=document.activeElement;!e&&n instanceof HTMLIFrameElement&&this.frameOf(n.contentWindow)&&this.element.focus()}#f(e){this.#s=[...this.#s.filter(t=>t!==e),e],this.#c=[e,...this.#c.filter(t=>t!==e)],this.#s.forEach((e,t)=>{let n=this.#r.get(e);n!==void 0&&(n.style.zIndex=String(t))});let t=this.#r.get(e);t!==void 0&&(t.style.zIndex=`99999`,t.contentWindow?.focus())}#p(e){this.#c=this.#c.filter(t=>t!==e),this.#r.get(e)?.contentWindow?.blur();let[t]=this.#c;t!==void 0&&this.#f(t)}#m(e,t){let n=Ie(e.code);if(n!==void 0&&e.target===this.element&&(e.preventDefault(),!(t&&e.repeat))){if(t)this.#u.add(n);else if(!this.#u.delete(n))return;this.#n.key(n,t)}}#h(e,t){this.#n.cursor(Math.round(e),Math.round(t))}};function $(e){return document.getElementById(e)}function Re({worker:e,frames:t,project:n,watch:r}){let i=t=>e.postMessage(t),o=$(`status`),s=$(`project`),u=new c($(`console`)),f=$(`resources-list`),m=$(`player-list`),h=new d($(`events`),$(`emit`),{emit:(e,t,n)=>i({type:`emit`,name:e,args:t,target:n})}),g=$(`bags`),v=new Me($(`map`),{teleport:(e,t,n,r)=>i({type:`teleport`,client:e,x:t,y:n,...r===void 0?{}:{z:r}}),waypoint:(e,t,n)=>i({type:`waypoint`,client:e,x:t,y:n}),styled:e=>{for(let t of b.values())t.screen.world.use(e)}}),y=new _({process:$(`inspected`),resources:$(`inspected-resources`),details:$(`inspected-details`),filter:$(`convar-filter`),convars:$(`convars`),form:$(`evaluate`),code:$(`code`)},{inspect:e=>i({type:`inspect`,process:e}),evaluate:(e,t,n)=>{(e===`server`?u:w(e).console).note(`${t}> ${n}`),i({type:`evaluate`,process:e,resource:t,code:n})}}),b=new Map,x=new Map,S=0;t.listen((e,t,n,r)=>{let a=S++;x.set(a,r),i({type:`ask`,id:a,client:e,host:t,ask:n})});function C(e,t){o.textContent=e,o.className=t}function w(e){let n=b.get(e);if(n!==void 0)return n;let r=document.createElement(`article`);r.className=`player`;let a=document.createElement(`header`),o=document.createElement(`span`);o.className=`info`;let s=document.createElement(`button`);s.textContent=`Enlarge`,s.addEventListener(`click`,()=>{let e=r.classList.toggle(`large`);s.textContent=e?`Shrink`:`Enlarge`});let l=document.createElement(`button`);l.textContent=`Disconnect`,l.addEventListener(`click`,()=>i({type:`disconnect`,client:e})),a.append(o,s,l);let u=document.createElement(`div`);u.className=`card`,u.hidden=!0;let d=new Le(e,{frame:n=>t.url(n,e),ready:e=>t.ready(e),cursor:(t,n)=>i({type:`cursor`,client:e,x:t,y:n}),key:(t,n)=>i({type:`key`,client:e,key:t,down:n})}),f=document.createElement(`div`);return f.className=`console small`,r.append(a,d.element,u,f),m.append(r),n={element:r,info:o,card:u,screen:d,console:new c(f),cardJson:void 0},b.set(e,n),n}function T(e,t,n){let r=n.state===`connecting`?n.card:void 0;if(t.cardJson===r||(t.cardJson=r,t.card.replaceChildren(),t.card.hidden=r===void 0,r===void 0))return;let o=a(r,t=>i({type:`submitCard`,client:e,json:t}));if(o!==void 0){t.card.append(o);return}let s=document.createElement(`pre`);s.textContent=r;let c=document.createElement(`form`),l=document.createElement(`textarea`);l.value=`{}`,l.setAttribute(`aria-label`,`What the card submits, as JSON`);let u=document.createElement(`button`);u.textContent=`Submit card`,c.append(l,u),c.addEventListener(`submit`,t=>{t.preventDefault(),i({type:`submitCard`,client:e,json:l.value})}),t.card.append(s,c)}function ee(e){f.replaceChildren(...e.resources.map(({name:e,state:t})=>{let n=document.createElement(`li`),r=document.createElement(`span`);r.textContent=e;let a=document.createElement(`span`);a.className=`state ${t}`,a.textContent=t,n.append(r,a);for(let r of t===`started`?[`restart`,`stop`]:[`start`]){let t=document.createElement(`button`);t.textContent=r,t.addEventListener(`click`,()=>i({type:`command`,line:`${r} "${e}"`})),n.append(t)}return n})),h.players(e.players),y.players(e.players),p(g,e.bags),v.show(e.map,e.players);for(let t of e.players){let n=w(t.client),r=t.state===`dropped`||t.state===`rejected`,i=t.state===`connecting`?t.message?.trim():void 0,a=t.rejection??i;n.info.textContent=`${t.name} (id ${t.id}) ${t.state}${a?`: ${a}`:``}`,n.element.classList.toggle(`gone`,r),n.screen.world.show(e.map,e.players),n.screen.fade(t.fade??0),n.screen.blur(t.blurred===!0),T(t.client,n,t)}}function E(e,t){let{screen:n}=w(e);switch(t.type){case`create`:n.create(t.frame);break;case`destroy`:n.destroy(t.resource);break;case`message`:n.message(t.resource,t.json);break;case`frameFocus`:n.frameFocus(t.resource,t.focused);break;case`focus`:n.focus(t.focus,t.cursor);break;case`zIndex`:n.zIndex(t.resource,t.zIndex)}}function te(e){let t=/^client (\d+)$/.exec(e.process)?.[1];t===void 0?u.add(e):w(Number(t)).console.add(e)}function D(e){C(`Starting`,`starting`),u.note(e),h.note(e);for(let e of b.values())e.element.remove();b.clear();let t=n();i({type:`start`,...t===void 0?{}:{project:t}})}e.addEventListener(`message`,e=>{let t=e.data;switch(t.type){case`started`:s.textContent=t.project.name,document.title=`${t.project.name} - FiveRunner`,C(`Running`,`running`);break;case`failed`:C(`Failed: ${t.message}`,`failed`),u.note(t.message);break;case`changed`:t.restarted===null?D(`Files changed`):t.restarted.length>0&&u.note(`Files changed: restarted ${t.restarted.join(`, `)}`);break;case`event`:{let{event:e}=t;e.type===`output`?te(e.line):e.type===`state`?ee(e.state):e.type===`nui`?E(e.client,e.event):e.type===`net`?h.add(e.event):(C(`Crashed`,`failed`),u.note(e.message));break}case`inspection`:y.show(t.inspection);break;case`answer`:x.get(t.id)?.(t.answer),x.delete(t.id)}}),addEventListener(`message`,e=>{for(let t of b.values()){let n=t.screen.frameOf(e.source);if(n===void 0)continue;let r=e.data;r.type===`fiverunner:cursor`&&typeof r.x==`number`&&typeof r.y==`number`?t.screen.cursorOver(r.x,r.y):r.type===`fiverunner:invokeNative`&&t.console.note(`${n} called invokeNative('${String(r.native)}', '${String(r.arg)}')`);return}}),$(`command`).addEventListener(`submit`,e=>{e.preventDefault();let t=$(`command-line`),n=t.value;n.trim()!==``&&(O(n),u.note(`> ${n}`),i({type:`command`,line:n}),t.value=``)});let O=l($(`command-line`));$(`connect`).addEventListener(`submit`,e=>{e.preventDefault();let t=$(`player-name`).value.trim();i({type:`connect`,name:t===``?`Player`:t})}),$(`restart`).addEventListener(`click`,()=>D(`Restarted`)),r(e=>i({type:`change`,paths:e})),D(`Started`)}var ze=`fiverunner.localhost`,Be=new TextEncoder,Ve=new TextDecoder;function He({host:e,client:t,tab:n}){let r=e.replace(/[A-Z]/g,e=>e.toLowerCase());return`${/^[a-z0-9_-]+$/.test(r)?r:`${Array.from(Be.encode(r),e=>e.toString(16).padStart(2,`0`)).join(``)}.x`}.c${t}.${n}.${ze}`}function Ue(e){let t=/^(.+)\.c([1-9][0-9]*)\.([a-z0-9]+)\.fiverunner\.localhost$/.exec(e);if(t===null)return;let[,n=``,r=``,i=``]=t,a=Number(r);if(/^[a-z0-9_-]+$/.test(n))return{host:n,client:a,tab:i};let o=/^((?:[0-9a-f]{2})+)\.x$/.exec(n)?.[1];if(o===void 0)return;let s=Uint8Array.from(o.match(/../g),e=>parseInt(e,16));return{host:Ve.decode(s),client:a,tab:i}}function We(e,t,n,r){let i=/^(?:nui:\/\/|https:\/\/(?=cfx-nui-))([^/?#]*)(.*)$/i.exec(e);if(i===null)return e;let[,a=``,o=``]=i,s=o.startsWith(`/`)?o:`/${o}`;return`http://${He({host:a,client:t,tab:n})}${r===``?``:`:${r}`}${s}`}function Ge(){let e=`fiverunner:tab`;try{let t=sessionStorage.getItem(e);if(t!==null&&/^[a-z0-9]{1,16}$/.test(t))return t;let n=Math.random().toString(36).slice(2,10);return sessionStorage.setItem(e,n),n}catch{return Math.random().toString(36).slice(2,10)}}var Ke=class{#e=Ge();#t;#n=new Map;#r=new Map;#i=()=>{};constructor(e){this.#t=e,addEventListener(`message`,e=>{let t=this.#n.get(e.origin);if(t===void 0||e.source!==t.frame.contentWindow)return;let n=e.data;n.type===`fiverunner:bridge`?this.#r.get(e.origin)?.():n.type===`fiverunner:ask`&&this.#a(e.origin,t.frame,n.id,n.ask)})}url(e,t){return We(e,t,this.#e,location.port)}ready(t){let n=new URL(t);if(Ue(n.hostname)===void 0)return Promise.resolve();let{origin:r}=n,i=this.#n.get(r);if(i===void 0){let t=document.createElement(`iframe`);t.src=`${r}${e}bridge.html`,t.title=`FiveRunner NUI bridge`,i={frame:t,ready:new Promise(e=>this.#r.set(r,e))},this.#n.set(r,i),this.#t.append(t)}return i.ready}listen(e){this.#i=e}#a(e,t,n,r){let i=Ue(new URL(e).hostname);i!==void 0&&i.tab===this.#e&&this.#i(i.client,i.host,r,r=>{let i={type:`fiverunner:answer`,id:n,answer:r};t.contentWindow?.postMessage(i,e)})}};Re({worker:new Worker(new URL(`/__fiverunner/assets/worker-BnznZQ2X.js`,``+import.meta.url),{type:`module`}),frames:new Ke(document.getElementById(`bridges`)),project:()=>void 0,watch(e){new EventSource(`${t}events`).addEventListener(`change`,t=>e(JSON.parse(t.data)))}});
|