hlviewer.js
Version:
View GoldSrc maps and replays in browser
1 lines • 121 kB
JavaScript
(function(H,G){typeof exports=="object"&&typeof module<"u"?G(exports):typeof define=="function"&&define.amd?define(["exports"],G):(H=typeof globalThis<"u"?globalThis:H||self,G(H.HLViewer={}))})(this,function(H){"use strict";var fi=Object.defineProperty;var di=(H,G,ue)=>G in H?fi(H,G,{enumerable:!0,configurable:!0,writable:!0,value:ue}):H[G]=ue;var f=(H,G,ue)=>di(H,typeof G!="symbol"?G+"":G,ue);let G=()=>({emit(e,...t){for(let s=this.events[e]||[],n=0,i=s.length;n<i;n++)s[n](...t)},events:{},on(e,t){var s;return((s=this.events)[e]||(s[e]=[])).push(t),()=>{var n;this.events[e]=(n=this.events[e])==null?void 0:n.filter(i=>t!==i)}}});const ue=performance.now.bind(performance),dt=e=>{const t=Math.floor(e/60),s=Math.floor(e-t*60),n=t<10?`0${t}`:t.toString(),i=s<10?`0${s}`:s.toString();return`${n}:${i}`},Ct=new AudioContext;class $t{constructor(){f(this,"context");f(this,"channels");f(this,"masterGain");f(this,"preMuteVolume");f(this,"events");this.context=Ct,this.events=G();const t=Number.parseFloat(localStorage.getItem("volume")||"0.3");localStorage.setItem("volume",t.toString()),this.channels=[],this.preMuteVolume=1,this.masterGain=this.context.createGain(),this.masterGain.gain.value=t,this.masterGain.connect(this.context.destination);for(let s=0;s<8;++s)this.channels.push({source:null,gain:this.context.createGain()}),this.channels[s].gain.connect(this.masterGain)}static getContext(){return Ct}play(t,s,n){this.stop(s);const i=this.channels[s].gain;i.gain.value=Math.max(0,Math.min(1,n));const o=this.context.createBufferSource();o.buffer=t.buffer,o.connect(i),o.start(0),this.channels[s].source=o}stop(t){const s=this.channels[t].source;s&&s.stop(0)}getVolume(){return this.masterGain.gain.value}setVolume(t){const s=this.masterGain.gain.value;s>0&&t===0&&(this.preMuteVolume=s),this.masterGain.gain.value=t,localStorage.setItem("volume",t.toString()),this.events.emit("volumeChange",t)}toggleMute(){this.getVolume()===0?this.setVolume(this.preMuteVolume):this.setVolume(0)}}class mt{constructor(t){f(this,"index");f(this,"name");f(this,"buffer");this.index=-1,this.name="",this.buffer=t}static create(t){return new Promise((s,n)=>{$t.getContext().decodeAudioData(t,i=>{s(new mt(i))},i=>{n(i)})})}}function Gt(e,t){return e.slice(e.lastIndexOf("/")+1).replace(t||"","")}function Ts(e){const t=e.lastIndexOf("/"),s=e.lastIndexOf(".");return t<s?e.slice(s):""}var O=(e=>(e[e.UByte=0]="UByte",e[e.Byte=1]="Byte",e[e.UShort=2]="UShort",e[e.Short=3]="Short",e[e.UInt=4]="UInt",e[e.Int=5]="Int",e[e.Float=6]="Float",e[e.Double=7]="Double",e[e.NString=8]="NString",e[e.String=9]="String",e))(O||{});class he{constructor(t){f(this,"data");f(this,"offset");this.data=new DataView(t),this.offset=0}length(){return this.data.byteLength}tell(){return this.offset}seek(t){this.offset=Math.max(0,t)}skip(t){this.seek(this.tell()+t)}b(){const t=this.data.getInt8(this.offset);return this.skip(1),t}ub(){const t=this.data.getUint8(this.offset);return this.skip(1),t}s(t=!0){const s=this.data.getInt16(this.offset,t);return this.skip(2),s}us(t=!0){const s=this.data.getUint16(this.offset,t);return this.skip(2),s}i(t=!0){const s=this.data.getInt32(this.tell(),t);return this.skip(4),s}ui(t=!0){const s=this.data.getUint32(this.tell(),t);return this.skip(4),s}f(t=!0){const s=this.data.getFloat32(this.tell(),t);return this.skip(4),s}lf(t=!0){const s=this.data.getFloat64(this.tell(),t);return this.skip(8),s}str(){let t=this.ub(),s="";for(;t!==0;)s+=String.fromCharCode(t),t=this.ub();return s}nstr(t){let s=t;if(s<0)return"";let n="";for(;s>0;){s-=1;const i=this.ub();if(i===0)break;n+=String.fromCharCode(i)}return s!==0&&this.skip(s),n}arr(t,s){let n=t;s.bind(this);const i=[];for(;n-- >0;)i.push(s());return i}arrx(t,s,n=0){switch(s){case 0:{const i=new Uint8Array(this.data.buffer,this.tell(),t);return this.skip(t),i}case 1:{const i=new Int8Array(this.data.buffer,this.tell(),t);return this.skip(t),i}case 2:{const i=new Uint16Array(this.data.buffer,this.tell(),t);return this.skip(t*2),i}case 3:{const i=new Int16Array(this.data.buffer,this.tell(),t);return this.skip(t*2),i}case 4:{const i=new Uint32Array(this.data.buffer,this.tell(),t);return this.skip(t*4),i}case 5:{const i=new Int32Array(this.data.buffer,this.tell(),t);return this.skip(t*4),i}case 6:{const i=new Float32Array(this.data.buffer,this.tell(),t);return this.skip(t*4),i}case 7:{const i=new Float64Array(this.data.buffer,this.tell(),t);return this.skip(t*8),i}case 8:{let i=t;const o=[];for(;i-- >0;)o.push(this.nstr(n));return o}case 9:{let i=t;const o=[];for(;i-- >0;)o.push(this.str());return o}}}}class gt{constructor(t,s,n,i){f(this,"name");f(this,"width");f(this,"height");f(this,"data");this.name=t,this.width=s,this.height=n,this.data=i}static parse(t,s){const n=new he(t),i={idLength:n.ub(),colorMapType:n.ub(),imageType:n.ub(),colorMap:{firstEntryIndex:n.us(),length:n.us(),size:n.ub()},image:{xOrigin:n.us(),yOrigin:n.us(),width:n.us(),height:n.us(),depth:n.ub(),descriptor:n.ub()}};if(i.idLength&&n.arrx(i.idLength,O.UByte),i.colorMapType)throw new Error("Not implemented");const o=i.image.width,a=i.image.height,r=o*a;let l=new Uint8Array(0);if(i.imageType===2){const c=r*i.image.depth/8;if(l=n.arrx(c,O.UByte),i.image.depth===24){const u=new Uint8Array(r*4);for(let h=0;h<a;++h)for(let m=0;m<o;++m){const g=(a-1-h)*o+m;u[g*4]=l[(h*o+m)*3+2],u[g*4+1]=l[(h*o+m)*3+1],u[g*4+2]=l[(h*o+m)*3],u[g*4+3]=255}l=u}else if(i.image.depth===32){const u=new Uint8Array(r*4);for(let h=0;h<a;++h)for(let m=0;m<o;++m){const g=(a-1-h)*o+m;u[g*4]=l[(h*o+m)*4+2],u[g*4+1]=l[(h*o+m)*4+1],u[g*4+2]=l[(h*o+m)*4],u[g*4+3]=255}l=u}}else if(i.imageType===10&&(l=new Uint8Array(r*4),i.image.depth===24))for(let c=0;c<a;++c)for(let u=0;u<o;){let h=n.ub();if(h&128){h=(h&127)+1;const m=n.ub(),g=n.ub(),d=n.ub();for(;u<o&&h;){const p=(a-1-c)*o+u;l[p*4]=d,l[p*4+1]=g,l[p*4+2]=m,l[p*4+3]=255,++u,--h}}else for(h=(h&127)+1;u<o&&h;){const m=(a-1-c)*o+u;l[m*4+2]=n.ub(),l[m*4+1]=n.ub(),l[m*4]=n.ub(),l[m*4+3]=255,++u,--h}}return new gt(s,i.image.width,i.image.height,l)}}function Fe(e,t){const s=new Uint8Array(e.length*4),n=e.length;for(let i=0;i<n;++i)s[i*4]=t[e[i]*3],s[i*4+1]=t[e[i]*3+1],s[i*4+2]=t[e[i]*3+2],s[i*4+3]=255;return s}function Me(e,t){const s=new Uint8Array(e.length*4),n=e.length;for(let i=0;i<n;++i)e[i]===255?s[i*4+3]=0:(s[i*4]=t[e[i]*3],s[i*4+1]=t[e[i]*3+1],s[i*4+2]=t[e[i]*3+2],s[i*4+3]=255);return s}function vs(e){const t=e.nstr(16),s=e.ui(),n=e.ui();e.skip(4*4);const i=s*n,o=e.arrx(i,O.UByte);e.skip(21*(i/64)),e.skip(2);const a=e.arrx(768,O.UByte),r=t[0]==="{"?Me(o,a):Fe(o,a);return{type:"decal",name:t,width:s,height:n,data:r}}const xs=(e,t)=>({type:"cache",name:t.name});function ws(e){const t=e.nstr(16),s=e.ui(),n=e.ui();e.skip(4*4);const i=s*n,o=e.arrx(i,O.UByte);e.skip(21*(i/64)),e.skip(2);const a=e.arrx(768,O.UByte),r=t[0]==="{"?Me(o,a):Fe(o,a);return{type:"texture",name:t,width:s,height:n,data:r}}function bs(e,t){const s=e.ui()&&256,n=e.ui(),i=e.ui(),o=e.ui(),a=[];for(let u=0;u<256;++u){const h=e.us(),m=e.us();a.push({x:h%s,y:Math.floor(h/s)/o*o,width:m,height:o})}const r=s*n,l=e.arrx(r,O.UByte);e.skip(2);const c=e.arrx(256*3,O.UByte);return{type:"font",name:t.name,width:s,height:n,rowCount:i,rowHeight:o,glyphs:a,data:Me(l,c)}}const ys=(e,t)=>({type:"unknown",name:t.name,data:e.arrx(t.length,O.UByte)});function ks(e,t){switch(e.seek(t.offset),t.type){case 64:return vs(e);case 66:return xs(e,t);case 67:return ws(e);case 70:return bs(e,t);default:return ys(e,t)}}class pt{constructor(t){f(this,"entries");this.entries=t}static parse(t){const s=new he(t);if(s.nstr(4)!=="WAD3")throw new Error("Invalid WAD file format");const i=s.ui(),o=s.ui();s.seek(o);const a=[];for(let l=0;l<i;++l){const c={offset:s.ui(),diskLength:s.ui(),length:s.ui(),type:s.b(),isCompressed:s.b(),name:""};s.skip(2),c.name=s.nstr(16),a.push(c)}const r=a.map(l=>ks(s,l));return new pt(r)}}class Et{constructor(t){f(this,"name");f(this,"chunks");f(this,"resources");this.name=Gt(t,".bsp"),this.chunks=[],this.resources={sounds:[],skins:[],models:[],decals:[],custom:[],events:[]}}setResources(t){for(const s of t)switch(s.type){case 0:{s.used=!1,this.resources.sounds.push(s);break}case 1:{this.resources.skins.push(s);break}case 2:{this.resources.models.push(s);break}case 3:{this.resources.decals.push(s);break}case 4:{this.resources.custom.push(s);break}case 5:{this.resources.events.push(s);break}}}addChunk(t){this.chunks.push(t)}}class Tt{constructor(t,s){f(this,"state");f(this,"startTime");f(this,"timeLength");f(this,"data");f(this,"reader");this.state=t.clone(),this.startTime=s,this.timeLength=10,this.data=null,this.reader=null}setData(t){this.data=new Uint8Array(t.length);for(let s=0;s<t.length;++s)this.data[s]=t[s];this.reader=new he(this.data.buffer)}}class Ce{constructor(t=null){f(this,"cameraPos");f(this,"cameraRot");f(this,"entities");t?(this.cameraPos=JSON.parse(JSON.stringify(t.cameraPos)),this.cameraRot=JSON.parse(JSON.stringify(t.cameraRot)),this.entities=JSON.parse(JSON.stringify(t.entities))):(this.cameraPos=[0,0,0],this.cameraRot=[0,0,0],this.entities=[])}feedFrame(t){switch(t.type){case 0:case 1:{this.cameraPos[0]=t.camera.position[0],this.cameraPos[1]=t.camera.position[1],this.cameraPos[2]=t.camera.position[2],this.cameraRot[0]=t.camera.orientation[0],this.cameraRot[1]=t.camera.orientation[1],this.cameraRot[2]=t.camera.orientation[2];break}}}clone(){return new Ce(this)}}function vt(e){const t=e.readBits(1),s=e.readBits(1);if(!t&&!s)return 0;const n=e.readBits(1);let i=0,o=0;t&&(i=e.readBits(12)),s&&(o=e.readBits(3));let a=i+o/32;return n&&(a=-a),a}var B=(e=>(e[e.DT_BYTE=1]="DT_BYTE",e[e.DT_SHORT=2]="DT_SHORT",e[e.DT_FLOAT=4]="DT_FLOAT",e[e.DT_INTEGER=8]="DT_INTEGER",e[e.DT_ANGLE=16]="DT_ANGLE",e[e.DT_TIMEWINDOW_8=32]="DT_TIMEWINDOW_8",e[e.DT_TIMEWINDOW_BIG=64]="DT_TIMEWINDOW_BIG",e[e.DT_STRING=128]="DT_STRING",e[e.DT_SIGNED=-2147483648]="DT_SIGNED",e))(B||{});function ne(e,t){const s={},n=e.readBits(3),i=[];for(let a=0;a<n;++a)i.push(e.readBits(8));let o=!1;for(let a=0;a<n;++a){for(let r=0;r<8;++r){const l=r+a*8;if(l===t.length){o=!0;break}if(i[a]&1<<r)if(t[l].flags&B.DT_BYTE)if(t[l].flags&B.DT_SIGNED){const c=e.readBits(1)?-1:1,u=e.readBits(t[l].bits-1),h=t[l].divisor;s[t[l].name]=c*u/h}else{const c=e.readBits(t[l].bits),u=t[l].divisor;s[t[l].name]=c/u}else if(t[l].flags&B.DT_SHORT)if(t[l].flags&B.DT_SIGNED){const c=e.readBits(1)?-1:1,u=e.readBits(t[l].bits-1),h=t[l].divisor;s[t[l].name]=c*u/h}else{const c=e.readBits(t[l].bits),u=t[l].divisor;s[t[l].name]=c/u}else if(t[l].flags&B.DT_INTEGER)if(t[l].flags&B.DT_SIGNED){const c=e.readBits(1)?-1:1,u=e.readBits(t[l].bits-1),h=t[l].divisor;s[t[l].name]=c*u/h}else{const c=e.readBits(t[l].bits),u=t[l].divisor;s[t[l].name]=c/u}else if(t[l].flags&B.DT_FLOAT||t[l].flags&B.DT_TIMEWINDOW_8||t[l].flags&B.DT_TIMEWINDOW_BIG)if(t[l].flags&B.DT_SIGNED){const c=e.readBits(1)?-1:1,u=e.readBits(t[l].bits-1),h=t[l].divisor;s[t[l].name]=c*u/h}else{const c=e.readBits(t[l].bits),u=t[l].divisor;s[t[l].name]=c/u}else if(t[l].flags&B.DT_ANGLE){const c=e.readBits(t[l].bits),u=360/(1<<t[l].bits);s[t[l].name]=c*u}else t[l].flags&B.DT_STRING&&(s[t[l].name]=e.readString())}if(o)break}return s}const As={delta_description_t:[{name:"flags",bits:32,divisor:1,flags:B.DT_INTEGER},{name:"name",bits:8,divisor:1,flags:B.DT_STRING},{name:"offset",bits:16,divisor:1,flags:B.DT_INTEGER},{name:"size",bits:8,divisor:1,flags:B.DT_INTEGER},{name:"bits",bits:8,divisor:1,flags:B.DT_INTEGER},{name:"divisor",bits:32,divisor:4e3,flags:B.DT_FLOAT},{name:"preMultiplier",bits:32,divisor:4e3,flags:B.DT_FLOAT}]},Xt=()=>({...As}),Ee=class Ee{constructor(t){f(this,"view");this.view=new Uint8Array(t,0,t.byteLength)}getBits(t,s,n=!1){let i=t;const o=this.view.length*8-i;if(s>o)throw new Error("Bits out of bounds");let a=0;for(let r=0;r<s;){const l=s-r,c=i&7,u=this.view[i>>3],h=Math.min(l,8-c),m=(1<<h)-1,g=u>>c&m;a|=g<<r,i+=h,r+=h}return n?(s!==32&&a&1<<s-1&&(a|=-1^(1<<s)-1),a):a>>>0}getInt8(t){return this.getBits(t,8,!0)}getUint8(t){return this.getBits(t,8,!1)}getInt16(t){return this.getBits(t,16,!0)}getUint16(t){return this.getBits(t,16,!1)}getInt32(t){return this.getBits(t,32,!0)}getUint32(t){return this.getBits(t,32,!1)}getFloat32(t){return Ee.scratch.setUint32(0,this.getUint32(t)),Ee.scratch.getFloat32(0)}getFloat64(t){return Ee.scratch.setUint32(0,this.getUint32(t)),Ee.scratch.setUint32(4,this.getUint32(t+32)),Ee.scratch.getFloat64(0)}};f(Ee,"scratch",new DataView(new ArrayBuffer(8)));let xt=Ee;class ee{constructor(t){f(this,"view");f(this,"index");this.view=new xt(t),this.index=0}readBits(t,s=!1){const n=this.view.getBits(this.index,t,s);return this.index+=t,n}readInt8(){const t=this.view.getInt8(this.index);return this.index+=8,t}readUint8(){const t=this.view.getUint8(this.index);return this.index+=8,t}readInt16(){const t=this.view.getInt16(this.index);return this.index+=16,t}readUint16(){const t=this.view.getUint16(this.index);return this.index+=16,t}readInt32(){const t=this.view.getInt32(this.index);return this.index+=32,t}readUint32(){const t=this.view.getUint32(this.index);return this.index+=32,t}readFloat32(){const t=this.view.getFloat32(this.index);return this.index+=32,t}readFloat64(){const t=this.view.getFloat64(this.index);return this.index+=64,t}readString(t=0,s=!1){let n=0;const i=[];let o=!0;for(;!t||t&&n<t;){const r=this.readUint8();if(r===0&&(o=!1,!t))break;o&&i.push(r),n++}const a=String.fromCharCode.apply(null,i);if(s)try{return decodeURIComponent(a)}catch{return a}else return a}}const T={bad(){throw new Error("Invalid message type")},nop(){return null},disconnect(e){return{reason:e.str()}},event(e,t){const s=new ee(e.data.buffer);s.index=e.tell()*8;const n=[],i=s.readBits(5);for(let o=0;o<i;++o){const a={index:s.readBits(10)};s.readBits(1)&&(a.packetIndex=s.readBits(11),s.readBits(1)&&(a.delta=ne(s,t.event_t))),s.readBits(1)&&(a.fireTime=s.readBits(16)),n.push(a)}return s.index%8>0?e.seek(Math.floor(s.index/8)+1):e.seek(s.index/8),{events:n}},version(e){return{version:e.ui()}},setView(e){return{entityIndex:e.s()}},sound(e){const t=new ee(e.data.buffer);t.index=e.tell()*8;const s=t.readBits(9);let n=1;(s&1)!==0&&(n=t.readBits(8)/255);let i=1;(s&2)!==0&&(i=t.readBits(8)/64);const o=t.readBits(3),a=t.readBits(11);let r;(s&4)!==0?r=t.readBits(16):r=t.readBits(8);const l=t.readBits(1),c=t.readBits(1),u=t.readBits(1);let h=0,m=0,g=0;l&&(h=vt(t)),c&&(m=vt(t)),u&&(g=vt(t));let d=1;return(s&8)!==0&&(d=t.readBits(8)),t.index%8>0?e.seek(Math.floor(t.index/8)+1):e.seek(t.index/8),{flags:s,volume:n,attenuation:i,channel:o,entityIndex:a,soundIndex:r,xPosition:h,yPosition:m,zPosition:g,pitch:d}},time(e){return{time:e.f()}},print(e){return{message:e.str()}},stuffText(e){return{commands:e.str().split(";").map(n=>{const i=n.split(/\s*("[^"]+"|[^\s"]+)/).map(r=>r.replace(/^"(.*)"$/,"$1").trim()).filter(r=>r),o=i[0],a=i.slice(1);return{func:o,params:a}})}},setAngle(e){return{pitch:e.s(),yaw:e.s(),roll:e.s()}},serverInfo(e){const t={protocol:e.i(),spawnCount:e.i(),mapCrc:e.i(),clientDllHash:e.arrx(16,O.UByte),maxPlayers:e.ub(),playerIndex:e.ub(),isDeathmatch:e.ub(),gameDir:e.str(),hostName:e.str(),mapFileName:e.str(),mapCycle:e.str()};return e.skip(1),t},lightStyle(e){return{index:e.ub(),lightInfo:e.str()}},updateUserInfo(e){return{clientIndex:e.ub(),clientUserId:e.ui(),clientUserInfo:e.str(),clientCdKeyHash:e.arrx(16,O.UByte)}},deltaDescription(e,t){const s={name:e.str(),fields:[]},n=new ee(e.data.buffer),i=e.us();n.index=e.tell()*8;for(let o=0;o<i;++o)s.fields.push(ne(n,t.delta_description_t));return t[s.name]=s.fields,n.index%8>0?e.seek(Math.floor(n.index/8)+1):e.seek(n.index/8),s},clientData(e,t){const s=new ee(e.data.buffer);s.index=e.tell()*8,s.readBits(1)&&(s.index+=8);const i=t.clientdata_t,o=ne(s,i),a=t.weapon_data_t;for(;s.readBits(1);)s.index+=6,ne(s,a);return s.index%8>0?e.seek(Math.floor(s.index/8)+1):e.seek(s.index/8),{clientData:o}},stopSound(e){return{entityIndex:e.s()}},pings(e){const t=new ee(e.data.buffer);t.index=e.tell()*8;const s=[];for(;t.readBits(1);)s.push({slot:t.readBits(8),ping:t.readBits(8),loss:t.readBits(8)});return t.index%8>0?e.seek(Math.floor(t.index/8)+1):e.seek(t.index/8),s},particle(e){return{position:[e.s()/8,e.s()/8,e.s()/8],direction:[e.b(),e.b(),e.b()],count:e.ub(),color:e.ub()}},damage(){return null},spawnStatic(e){const t={modelIndex:e.s(),sequence:e.b(),frame:e.b(),colorMap:e.s(),skin:e.b(),position:[],rotation:[]};return t.position[0]=e.s()/8,t.rotation[0]=e.b()*(360/256),t.position[1]=e.s()/8,t.rotation[1]=e.b()*(360/256),t.position[2]=e.s()/8,t.rotation[2]=e.b()*(360/256),t.renderMode=e.b(),t.renderMode&&(t.renderAmt=e.b(),t.renderColor=[e.ub(),e.ub(),e.ub()],t.renderFx=e.b()),t},eventReliable(e,t){const s=new ee(e.data.buffer);s.index=e.tell()*8;const n=s.readBits(10),i=ne(s,t.event_t),o=s.readBits(1);let a=0;return o&&(a=s.readBits(16)),s.index%8>0?e.seek(Math.floor(s.index/8)+1):e.seek(s.index/8),{eventIndex:n,eventData:i,delayBit:o,delay:a}},spawnBaseLine(e,t){const s=new ee(e.data.buffer);s.index=e.tell()*8;const n=[];for(;;){const r=s.readBits(11);if(r===2047)break;const l=s.readBits(2);let c;l&1?r>0&&r<=32?c="entity_state_player_t":c="entity_state_t":c="custom_entity_state_t",n[r]=ne(s,t[c])}if(s.readBits(5)!==31)throw new Error("Bad spawnbaseline");const o=s.readBits(6),a=[];for(let r=0;r<o;++r)a.push(ne(s,t.entity_state_t));return s.index%8>0?e.seek(Math.floor(s.index/8)+1):e.seek(s.index/8),{entities:n,extraData:a}},tempEntity(e){const hi=e.ub(),Y={};switch(hi){case 0:{e.skip(24);break}case 1:{e.skip(20);break}case 2:{e.skip(6);break}case 3:{e.skip(11);break}case 4:{e.skip(6);break}case 5:{e.skip(10);break}case 6:{e.skip(12);break}case 7:{e.skip(17);break}case 8:{e.skip(16);break}case 9:{e.skip(6);break}case 10:{e.skip(6);break}case 11:{e.skip(6);break}case 12:{e.skip(8);break}case 13:{e.skip(8),e.s()&&e.skip(2);break}case 14:{e.skip(9);break}case 15:{e.skip(19);break}case 17:{e.skip(10);break}case 18:{e.skip(16);break}case 19:{e.skip(24);break}case 20:{e.skip(24);break}case 21:{e.skip(24);break}case 22:{e.skip(10);break}case 23:{e.skip(11);break}case 24:{e.skip(16);break}case 25:{e.skip(19);break}case 27:{e.skip(12);break}case 28:{e.skip(16);break}case 29:{Y.channel=e.b(),Y.x=e.s(),Y.y=e.s(),Y.effect=e.b(),Y.textColor=[e.ub(),e.ub(),e.ub(),e.ub()],Y.effectColor=[e.ub(),e.ub(),e.ub(),e.ub()],Y.fadeInTime=e.s(),Y.fadeOutTime=e.s(),Y.holdTime=e.s(),Y.effect&&(Y.effectTime=e.s()),Y.message=e.str();break}case 30:{e.skip(17);break}case 31:{e.skip(17);break}case 99:{e.skip(2);break}case 100:{e.skip(10);break}case 101:{e.skip(14);break}case 102:{e.skip(12);break}case 103:{e.skip(14);break}case 104:{e.skip(9);break}case 105:{e.skip(5);break}case 106:{e.skip(17);break}case 107:{e.skip(13);break}case 108:{e.skip(24);break}case 109:{e.skip(9);break}case 110:{e.skip(17);break}case 111:{e.skip(7);break}case 112:{e.skip(10);break}case 113:{e.skip(19);break}case 114:{e.skip(19);break}case 115:{e.skip(12);break}case 116:{e.skip(7);break}case 117:{e.skip(7);break}case 118:{e.skip(9);break}case 119:{e.skip(16);break}case 120:{e.skip(18);break}case 121:{e.skip(5);break}case 122:{e.skip(10);break}case 123:{e.skip(9);break}case 124:{e.skip(7);break}case 125:{e.skip(1);break}case 126:{e.skip(18);break}case 127:{e.skip(15);break}default:throw new Error("Unknown temp entity type")}return Y},setPause(e){return{isPaused:e.b()}},signOnNum(e){return{sign:e.b()}},centerPrint(e){return{message:e.str()}},killedMonster(){return null},foundSecret(){return null},spawnStaticSound(e){return{position:[e.s()/8,e.s()/8,e.s()/8],soundIndex:e.us(),volume:e.ub()/255,attenuation:e.ub()/64,entityIndex:e.us(),pitch:e.ub(),flags:e.ub()}},intermission(){return null},finale(e){return{text:e.str()}},cdTrack(e){return{track:e.b(),loopTrack:e.b()}},restore(e){const t=e.str(),s=e.ub(),n=[];for(let i=0;i<s;++i)n.push(e.str());return{saveName:t,maps:n}},cutscene(e){return{text:e.str()}},weaponAnim(e){return{sequenceNumber:e.b(),weaponModelBodyGroup:e.b()}},decalName(e){return{positionIndex:e.ub(),decalName:e.str()}},roomType(e){return{type:e.us()}},addAngle(e){return{angleToAdd:e.s()/(360/65536)}},newUserMsg(e){return{index:e.ub(),size:e.b(),name:e.nstr(16)}},packetEntities(e,t){const s=new ee(e.data.buffer);s.index=e.tell()*8;const n=[];s.readBits(16);let i=0;for(;s.readBits(16)!==0;){s.index-=16,s.readBits(1)?i++:s.readBits(1)?i=s.readBits(11):i+=s.readBits(6);const r=s.readBits(1);s.readBits(1)&&(s.index+=6);let c="entity_state_t";i>0&&i<=32?c="entity_state_player_t":r&&(c="custom_entity_state_t"),n.push(ne(s,t[c]))}return s.index%8>0?e.seek(Math.floor(s.index/8)+1):e.seek(s.index/8),{entityStates:n}},deltaPacketEntities(e,t){const s=new ee(e.data.buffer);s.index=e.tell()*8,s.readBits(16),s.index+=8;const n=[];let i=0;for(;s.readBits(16)!==0;){s.index-=16;const a=s.readBits(1);if(s.readBits(1)?i=s.readBits(11):i+=s.readBits(6),a)continue;const l=s.readBits(1);let c="entity_state_t";i>0&&i<32?c="entity_state_player_t":l&&(c="custom_entity_state_t"),n[i]=ne(s,t[c])}return s.index%8>0?e.seek(Math.floor(s.index/8)+1):e.seek(s.index/8),{entityStates:n}},choke(){return null},resourceList(e){const t=new ee(e.data.buffer);t.index=e.tell()*8;const s=[],n=t.readBits(12);for(let i=0;i<n;++i){const o={type:t.readBits(4),name:t.readString(),index:t.readBits(12),size:t.readBits(24)};t.readBits(3)&4&&(t.index+=128),t.readBits(1)&&(t.index+=256),s.push(o)}if(t.readBits(1))for(;t.readBits(1);){const i=t.readBits(1)?5:10;t.index+=i}return t.index%8>0?e.seek(Math.floor(t.index/8)+1):e.seek(t.index/8),s},newMoveVars(e){return{gravity:e.f(),stopSpeed:e.f(),maxSpeed:e.f(),spectatorMaxSpeed:e.f(),acceleration:e.f(),airAcceleration:e.f(),waterAcceleration:e.f(),friction:e.f(),edgeFriction:e.f(),waterFriction:e.f(),entityGravity:e.f(),bounce:e.f(),stepSize:e.f(),maxVelocity:e.f(),zMax:e.f(),waveHeight:e.f(),footsteps:e.b(),rollAngle:e.f(),rollSpeed:e.f(),skyColor:[e.f(),e.f(),e.f()],skyVec:[e.f(),e.f(),e.f()],skyName:e.str()}},resourceRequest(e){const t={spawnCount:e.i()};return e.skip(4),t},customization(e){const t=e.ub(),s=e.ub(),n=e.str(),i=e.us(),o=e.ui(),a=e.ub();let r=null;return a&4&&(r=[e.i(),e.i(),e.i(),e.i()]),{playerIndex:t,type:s,name:n,index:i,downloadSize:o,flags:a,md5hash:r}},crosshairAngle(e){return{pitch:e.b(),yaw:e.b()}},soundFade(e){return{initialPercent:e.ub(),holdTime:e.ub(),fadeOutTime:e.ub(),fadeInTime:e.ub()}},fileTxferFailed(e){return{filename:e.str()}},hltv(e){return{mode:e.ub()}},director(e){const t=e.ub();return{flag:e.ub(),message:e.nstr(t-1)}},voiceInit(e){return{codecName:e.str(),quality:e.b()}},voiceData(e){const t=e.ub(),s=e.us(),n=e.arrx(s,O.UByte);return{playerIndex:t,data:n}},sendExtraInfo(e){return{fallbackDir:e.str(),canCheat:e.ub()}},timeScale(e){return{timeScale:e.f()}},resourceLocation(e){return{url:e.str()}},sendCvarValue(e){return{name:e.str()}},sendCvarValue2(e){return{requestId:e.ui(),name:e.str()}}},Is=[T.bad,T.nop,T.disconnect,T.event,T.version,T.setView,T.sound,T.time,T.print,T.stuffText,T.setAngle,T.serverInfo,T.lightStyle,T.updateUserInfo,T.deltaDescription,T.clientData,T.stopSound,T.pings,T.particle,T.damage,T.spawnStatic,T.eventReliable,T.spawnBaseLine,T.tempEntity,T.setPause,T.signOnNum,T.centerPrint,T.killedMonster,T.foundSecret,T.spawnStaticSound,T.intermission,T.finale,T.cdTrack,T.restore,T.cutscene,T.weaponAnim,T.decalName,T.roomType,T.addAngle,T.newUserMsg,T.packetEntities,T.deltaPacketEntities,T.choke,T.resourceList,T.newMoveVars,T.resourceRequest,T.customization,T.crosshairAngle,T.soundFade,T.fileTxferFailed,T.hltv,T.director,T.voiceInit,T.voiceData,T.sendExtraInfo,T.timeScale,T.resourceLocation,T.sendCvarValue,T.sendCvarValue2];function Ht(e,t,s){if(t===0)return null;const n=Is[t];return n?n(e,s):null}var fe=(e=>(e[e.BAD=0]="BAD",e[e.NOP=1]="NOP",e[e.DISCONNECT=2]="DISCONNECT",e[e.EVENT=3]="EVENT",e[e.VERSION=4]="VERSION",e[e.SETVIEW=5]="SETVIEW",e[e.SOUND=6]="SOUND",e[e.TIME=7]="TIME",e[e.PRINT=8]="PRINT",e[e.STUFFTEXT=9]="STUFFTEXT",e[e.SETANGLE=10]="SETANGLE",e[e.SERVERINFO=11]="SERVERINFO",e[e.LIGHTSTYLE=12]="LIGHTSTYLE",e[e.UPDATEUSERINFO=13]="UPDATEUSERINFO",e[e.DELTADESCRIPTION=14]="DELTADESCRIPTION",e[e.CLIENTDATA=15]="CLIENTDATA",e[e.STOPSOUND=16]="STOPSOUND",e[e.PINGS=17]="PINGS",e[e.PARTICLE=18]="PARTICLE",e[e.DAMAGE=19]="DAMAGE",e[e.SPAWN=20]="SPAWN",e[e.EVENT_RELIABLE=21]="EVENT_RELIABLE",e[e.SPAWNBASELINE=22]="SPAWNBASELINE",e[e.TEMPENTITY=23]="TEMPENTITY",e[e.SETPAUSE=24]="SETPAUSE",e[e.SIGNONNUM=25]="SIGNONNUM",e[e.CENTERPRINT=26]="CENTERPRINT",e[e.KILLEDMONSTER=27]="KILLEDMONSTER",e[e.FOUNDSECRET=28]="FOUNDSECRET",e[e.SPAWNSTATICSOUND=29]="SPAWNSTATICSOUND",e[e.INTERMISSION=30]="INTERMISSION",e[e.FINALE=31]="FINALE",e[e.CDTRACK=32]="CDTRACK",e[e.RESTORE=33]="RESTORE",e[e.CUTSCENE=34]="CUTSCENE",e[e.WEAPONANIM=35]="WEAPONANIM",e[e.DECALNAME=36]="DECALNAME",e[e.ROOMTYPE=37]="ROOMTYPE",e[e.ADDANGLE=38]="ADDANGLE",e[e.NEWUSERMSG=39]="NEWUSERMSG",e[e.PACKETENTITIES=40]="PACKETENTITIES",e[e.DELTAPACKETENTITIES=41]="DELTAPACKETENTITIES",e[e.CHOKE=42]="CHOKE",e[e.RESOURCELIST=43]="RESOURCELIST",e[e.NEWMOVEVARS=44]="NEWMOVEVARS",e[e.RESOURCEREQUEST=45]="RESOURCEREQUEST",e[e.CUSTOMIZATION=46]="CUSTOMIZATION",e[e.CROSSHAIRANGLE=47]="CROSSHAIRANGLE",e[e.SOUNDFADE=48]="SOUNDFADE",e[e.FILETXFERFAILED=49]="FILETXFERFAILED",e[e.HLTV=50]="HLTV",e[e.DIRECTOR=51]="DIRECTOR",e[e.VOICEINIT=52]="VOICEINIT",e[e.VOICEDATA=53]="VOICEDATA",e[e.SENDEXTRAINFO=54]="SENDEXTRAINFO",e[e.TIMESCALE=55]="TIMESCALE",e[e.RESOURCELOCATION=56]="RESOURCELOCATION",e[e.SENDCVARVALUE=57]="SENDCVARVALUE",e[e.SENDCVARVALUE2=58]="SENDCVARVALUE2",e))(fe||{});const _s=e=>e.nstr(8)==="HLDEMO",Wt=e=>({demoProtocol:e.ui(),netProtocol:e.ui(),mapName:e.nstr(260),modName:e.nstr(260),mapCrc:e.i(),dirOffset:e.ui()}),jt=(e,t)=>{e.seek(t);const s=e.ui(),n=[];for(let i=0;i<s;++i)n.push({id:e.ui(),name:e.nstr(64),flags:e.ui(),cdTrack:e.i(),time:e.f(),frames:e.ui(),offset:e.ui(),length:e.ui()});return n},Ms=(e,t,s)=>{const n=e.ui(),i=e.tell()+n,o=[];for(;e.tell()<i;){const a=e.ub();if(a===1)continue;if(a>=64){s[a]&&s[a].size>-1?e.skip(s[a].size):e.skip(e.ub());continue}const r=Ht(e,a,t);r?(a===39&&(s[r.index]=r),o.push({type:a,data:r})):e.seek(i)}return e.seek(i),o},$e=(e,t,s)=>{const n={type:e.ub(),time:e.f(),tick:e.ui()};switch(n.type){case 0:case 1:{e.skip(4),n.camera={position:[e.f(),e.f(),e.f()],orientation:[e.f(),e.f(),e.f()]},e.skip(436),n.data=Ms(e,t,s);break}case 2:break;case 3:{n.command=e.nstr(64);break}case 4:{e.skip(32);break}case 5:break;case 6:{e.skip(84);break}case 7:{e.skip(8);break}case 8:{n.sound={channel:e.i(),sample:e.nstr(e.ui()),attenuation:e.f(),volume:e.f(),flags:e.ui(),pitch:e.i()};break}case 9:{e.skip(e.ui());break}default:{n.error=!0;break}}return n};class xe{constructor(t,s){f(this,"header");f(this,"mapName");f(this,"directories");this.header=t,this.mapName=this.header.mapName,this.directories=s}static parseFromArrayBuffer(t){const s=new he(t);if(s.nstr(8)!=="HLDEMO")throw new Error("Invalid replay format");const i={};i.demoProtocol=s.ui(),i.netProtocol=s.ui(),i.mapName=s.nstr(260),i.modName=s.nstr(260),i.mapCrc=s.i(),i.dirOffset=s.ui(),s.seek(i.dirOffset);const o=s.ui(),a=[];for(let r=0;r<o;++r)a.push({id:s.ui(),name:s.nstr(64),flags:s.ui(),cdTrack:s.i(),time:s.f(),frames:s.ui(),offset:s.ui(),length:s.ui(),macros:[]});for(let r=0;r<a.length;++r){s.seek(a[r].offset);let l=!1;for(;!l;){const c={type:s.b(),time:s.f(),frame:s.ui()};switch(c.type){case 0:case 1:{s.skip(4),c.camera={position:[s.f(),s.f(),s.f()],orientation:[s.f(),s.f(),s.f()]},s.skip(436),s.skip(s.ui());break}case 2:break;case 3:{c.command=s.nstr(64);break}case 4:{s.skip(32);break}case 5:{l=!0;break}case 6:{s.skip(84);break}case 7:{s.skip(8);break}case 8:{s.skip(4),s.skip(s.ui()+16);break}case 9:{s.skip(s.ui());break}default:{const u=Number(s.tell()-9).toString(16),h=[`Unexpected macro (${c.type})`,` at offset = ${u}.`].join("");throw new Error(h)}}a[r].macros.push(c)}}return new xe(i,a)}static parseFullFromArrayBuffer(t){const s=new he(t);if(s.nstr(8)!=="HLDEMO")throw new Error("Invalid replay format");const i={};i.demoProtocol=s.ui(),i.netProtocol=s.ui(),i.mapName=s.nstr(260),i.modName=s.nstr(260),i.mapCrc=s.i(),i.dirOffset=s.ui(),s.seek(i.dirOffset);const o=s.ui(),a=[];for(let c=0;c<o;++c)a.push({id:s.ui(),name:s.nstr(64),flags:s.ui(),cdTrack:s.i(),time:s.f(),frames:s.ui(),offset:s.ui(),length:s.ui(),macros:[]});const r=Xt(),l=[];for(let c=0;c<a.length;++c){s.seek(a[c].offset);let u=!1;for(;!u;){const h={type:s.b(),time:s.f(),frame:s.ui()};switch(h.type){case 0:case 1:{s.skip(4),h.camera={position:[s.f(),s.f(),s.f()],orientation:[s.f(),s.f(),s.f()],forward:[s.f(),s.f(),s.f()],right:[s.f(),s.f(),s.f()],up:[s.f(),s.f(),s.f()]},h.RefParams={frametime:s.f(),time:s.f(),intermission:s.i(),paused:s.i(),spectator:s.i(),onground:s.i(),waterlevel:s.i(),velocity:[s.f(),s.f(),s.f()],origin:[s.f(),s.f(),s.f()],viewHeight:[s.f(),s.f(),s.f()],idealPitch:s.f(),viewAngles:[s.f(),s.f(),s.f()],health:s.i(),crosshairAngle:[s.f(),s.f(),s.f()],viewSize:s.f(),punchAngle:[s.f(),s.f(),s.f()],maxClients:s.i(),viewEntity:s.i(),playerCount:s.i(),maxEntities:s.i(),demoPlayback:s.i(),hardware:s.i(),smoothing:s.i(),ptr_cmd:s.i(),ptr_movevars:s.i(),viewport:[s.i(),s.i(),s.i(),s.i()],nextView:s.i(),onlyClientDraw:s.i()},h.UserCmd={lerp_msec:s.s(),msec:s.ub(),UNUSED1:s.ub(),viewAngles:[s.f(),s.f(),s.f()],forwardMove:s.f(),sideMove:s.f(),upMove:s.f(),lightLevel:s.b(),UNUSED2:s.ub(),buttons:s.us(),impulse:s.b(),weaponSelect:s.b(),UNUSED:s.s(),impactIndex:s.i(),impactPosition:[s.f(),s.f(),s.f()]},h.MoveVars={gravity:s.f(),stopSpeed:s.f(),maxSpeed:s.f(),spectatorMaxSpeed:s.f(),acceleration:s.f(),airAcceleration:s.f(),waterAcceleration:s.f(),friction:s.f(),edgeFriction:s.f(),waterFriction:s.f(),entityGravity:s.f(),bounce:s.f(),stepSize:s.f(),maxVelocity:s.f(),zMax:s.f(),waveHeight:s.f(),footsteps:s.i(),skyName:s.nstr(32),rollAngle:s.f(),rollSpeed:s.f(),skyColor:[s.f(),s.f(),s.f()],skyVec:[s.f(),s.f(),s.f()]},h.view=[s.f(),s.f(),s.f()],h.viewModel=s.i(),h.incoming_sequence=s.i(),h.incoming_acknowledged=s.i(),h.incoming_reliable_acknowledged=s.i(),h.incoming_reliable_sequence=s.i(),h.outgoing_sequence=s.i(),h.reliable_sequence=s.i(),h.last_reliable_sequence=s.i();const g=s.ui()+s.tell();for(h.frameData=[];s.tell()<g;){const d=s.ub();if(d===1)continue;if(d>=64){l[d]&&l[d].size>-1?s.skip(l[d].size):s.skip(s.ub());continue}const p=Ht(s,d,r);p?(d===39&&(l[p.index]=p),h.frameData.push({type:d,frameData:p})):s.seek(g)}s.seek(g);break}case 2:break;case 3:{h.command=s.nstr(64);break}case 4:{h.clientData={position:[s.f(),s.f(),s.f()],rotation:[s.f(),s.f(),s.f()],weaponFlags:s.ui(),fov:s.f()};break}case 5:{u=!0;break}case 6:{h.event={flags:s.ui(),index:s.ui(),delay:s.f(),args:{flags:s.ui(),entityIndex:s.ui(),position:[s.f(),s.f(),s.f()],rotation:[s.f(),s.f(),s.f()],velocity:[s.f(),s.f(),s.f()],ducking:s.ui(),fparam1:s.f(),fparam2:s.f(),iparam1:s.i(),iparam2:s.i(),bparam1:s.i(),bparam2:s.i()}};break}case 7:{h.weaponAnimation={animation:s.i(),body:s.i()};break}case 8:{h.sound={channel:s.i(),sample:s.nstr(s.ui()),attenuation:s.f(),volume:s.f(),flags:s.ui(),pitch:s.i()};break}case 9:{s.skip(s.ui());break}default:{const m=Number(s.tell()-9).toString(16),g=`Unexpected macro (${h.type}) at offset = ${m}`;throw new Error(g)}}a[c].macros.push(h)}}return new xe(i,a)}static parseIntoChunks(t){const s=new he(t);if(!_s(s))throw new Error("Invalid replay file format");const n=[],i=Xt(),o=[],a=Wt(s),r=jt(s,a.dirOffset);let l,c,u,h;const m=new Ce;let g=r[0].offset+r[0].length;for(s.seek(r[0].offset);s.tell()<g;){const d=$e(s,i,o);if(m.feedFrame(d),d.error)throw new Error("Encountered error while reading replay");if(d.type<2){const p=d.data.find(v=>v.type===fe.SERVERINFO);p&&(l=new Et(p.data.mapFileName),n.push(l));const E=d.data.find(v=>v.type===fe.RESOURCELIST);E&&l&&l.setResources(E.data)}}if(!(l instanceof Et))throw new Error("Error while parsing replay.");for(h=s.tell(),c=new Tt(m,0),l.addChunk(c),g=r[1].offset+r[1].length,s.seek(r[1].offset);;){const d=s.tell();if(d>=g){const E=u.time-c.startTime;c.timeLength=E;const v=d-h;s.seek(h),c.setData(s.arrx(v,O.UByte)),s.seek(d);break}const p=$e(s,i,o);if(m.feedFrame(p),u=p,p.error)throw new Error("Encountered error while reading replay");if(p.type<2){const E=p.data.find(x=>x.type===fe.SERVERINFO);if(E){l=new Et(E.data.mapFileName),n.push(l);const x=u.time-c.startTime;c.timeLength=x;const b=d-h,w=s.tell();s.seek(h),c.setData(s.arrx(b,O.UByte)),s.seek(w),h=d,c=new Tt(m,p.time),l.addChunk(c)}const v=p.data.find(x=>x.type===fe.RESOURCELIST);if(v&&l.setResources(v.data),E)continue;for(let x=0;x<p.data.length;++x){const b=p.data[x];if(b.type===fe.SOUND||b.type===fe.SPAWNSTATICSOUND){const w=l.resources.sounds.find(S=>S.index===b.data.soundIndex);w&&(w.used=!0)}else if(b.type===fe.STUFFTEXT){const w=l.resources.sounds,S=b.data.commands;for(let C=0;C<S.length;++C){const I=S[C],y=I.func;if((y==="speak"||y==="spk")&&I.params.length===1){const k=`${I.params[0]}.wav`,A=w.find(F=>F.name===k);A&&(A.used=!0)}}}}}else if(p.type===8){const E=l.resources.sounds.find(v=>v.name===p.sound.sample);E&&(E.used=!0)}if(c.startTime+10<p.time){const E=d-h,v=s.tell();s.seek(h),c.setData(s.arrx(E,O.UByte)),s.seek(v),h=d,c=new Tt(m,p.time),l.addChunk(c)}}return{length:r[1].time,maps:n,deltaDecoders:i,customMessages:o}}static readHeader(t){return Wt(t)}static readDirectories(t,s){return jt(t,s)}static readFrame(t,s,n){return $e(t,s,n)}static readFrameData(t,s,n){return $e(t,s,n)}}var Q=(e=>(e[e.VP_PARALLEL_UPRIGHT=0]="VP_PARALLEL_UPRIGHT",e[e.FACING_UPRIGHT=1]="FACING_UPRIGHT",e[e.VP_PARALLEL=2]="VP_PARALLEL",e[e.ORIENTED=3]="ORIENTED",e[e.VP_PARALLEL_ORIENTED=4]="VP_PARALLEL_ORIENTED",e))(Q||{});class wt{constructor(t,s){f(this,"header");f(this,"frames");this.header=t,this.frames=s}static parse(t){const s=new he(t);if(s.nstr(4)!=="IDSP")throw new Error("Invalid sprite file format");const i={version:s.i(),type:s.i(),alphaType:s.i(),radius:s.f(),width:s.i(),height:s.i(),frameCount:s.i(),beamLength:s.f(),syncType:s.i()},o=s.s(),a=s.arrx(o*3,O.UByte),r=[];for(let l=0;l<i.frameCount;++l){const c={group:s.i(),position:[s.i(),s.i()],width:s.i(),height:s.i(),data:new Uint8Array(i.width*i.height*4)},u=s.arrx(i.width*i.height,O.UByte);i.alphaType===3?c.data=Me(u,a):c.data=Fe(u,a),r.push(c)}return new wt(i,r)}}function we(e,t){const s=t.method||"GET",n=t.isBinary,i=t.progressCallback;if(!e)throw new Error("Url parameter missing");return new Promise((o,a)=>{const r=new XMLHttpRequest;n&&(r.responseType="arraybuffer"),n&&i&&r.addEventListener("progress",l=>{if(l.lengthComputable)i(r,l.loaded/l.total);else{const c=r.getResponseHeader("content-length");let u=0;c&&(u=Number.parseFloat(c));const h=r.getResponseHeader("content-encoding");if(u&&h&&h.indexOf("gzip")>-1){u*=4;const m=Math.min(.99,l.loaded/u);i(r,m)}else i(r,0)}}),r.addEventListener("readystatechange",()=>{r.readyState===4&&(r.status===200?(i&&i(r,1),o(r.response)):a({status:r.status}))}),r.open(s,e,!0),r.send()})}var de=typeof Float32Array<"u"?Float32Array:Array,Rs=Math.PI/180;function Ge(e){return e*Rs}Math.hypot||(Math.hypot=function(){for(var e=0,t=arguments.length;t--;)e+=arguments[t]*arguments[t];return Math.sqrt(e)});function bt(){var e=new de(16);return de!=Float32Array&&(e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[11]=0,e[12]=0,e[13]=0,e[14]=0),e[0]=1,e[5]=1,e[10]=1,e[15]=1,e}function be(e){return e[0]=1,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=1,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[10]=1,e[11]=0,e[12]=0,e[13]=0,e[14]=0,e[15]=1,e}function Re(e,t,s){var n=s[0],i=s[1],o=s[2],a,r,l,c,u,h,m,g,d,p,E,v;return t===e?(e[12]=t[0]*n+t[4]*i+t[8]*o+t[12],e[13]=t[1]*n+t[5]*i+t[9]*o+t[13],e[14]=t[2]*n+t[6]*i+t[10]*o+t[14],e[15]=t[3]*n+t[7]*i+t[11]*o+t[15]):(a=t[0],r=t[1],l=t[2],c=t[3],u=t[4],h=t[5],m=t[6],g=t[7],d=t[8],p=t[9],E=t[10],v=t[11],e[0]=a,e[1]=r,e[2]=l,e[3]=c,e[4]=u,e[5]=h,e[6]=m,e[7]=g,e[8]=d,e[9]=p,e[10]=E,e[11]=v,e[12]=a*n+u*i+d*o+t[12],e[13]=r*n+h*i+p*o+t[13],e[14]=l*n+m*i+E*o+t[14],e[15]=c*n+g*i+v*o+t[15]),e}function zt(e,t,s){var n=s[0],i=s[1],o=s[2];return e[0]=t[0]*n,e[1]=t[1]*n,e[2]=t[2]*n,e[3]=t[3]*n,e[4]=t[4]*i,e[5]=t[5]*i,e[6]=t[6]*i,e[7]=t[7]*i,e[8]=t[8]*o,e[9]=t[9]*o,e[10]=t[10]*o,e[11]=t[11]*o,e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15],e}function Te(e,t,s){var n=Math.sin(s),i=Math.cos(s),o=t[4],a=t[5],r=t[6],l=t[7],c=t[8],u=t[9],h=t[10],m=t[11];return t!==e&&(e[0]=t[0],e[1]=t[1],e[2]=t[2],e[3]=t[3],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[4]=o*i+c*n,e[5]=a*i+u*n,e[6]=r*i+h*n,e[7]=l*i+m*n,e[8]=c*i-o*n,e[9]=u*i-a*n,e[10]=h*i-r*n,e[11]=m*i-l*n,e}function Xe(e,t,s){var n=Math.sin(s),i=Math.cos(s),o=t[0],a=t[1],r=t[2],l=t[3],c=t[8],u=t[9],h=t[10],m=t[11];return t!==e&&(e[4]=t[4],e[5]=t[5],e[6]=t[6],e[7]=t[7],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[0]=o*i-c*n,e[1]=a*i-u*n,e[2]=r*i-h*n,e[3]=l*i-m*n,e[8]=o*n+c*i,e[9]=a*n+u*i,e[10]=r*n+h*i,e[11]=l*n+m*i,e}function z(e,t,s){var n=Math.sin(s),i=Math.cos(s),o=t[0],a=t[1],r=t[2],l=t[3],c=t[4],u=t[5],h=t[6],m=t[7];return t!==e&&(e[8]=t[8],e[9]=t[9],e[10]=t[10],e[11]=t[11],e[12]=t[12],e[13]=t[13],e[14]=t[14],e[15]=t[15]),e[0]=o*i+c*n,e[1]=a*i+u*n,e[2]=r*i+h*n,e[3]=l*i+m*n,e[4]=c*i-o*n,e[5]=u*i-a*n,e[6]=h*i-r*n,e[7]=m*i-l*n,e}function Ls(e,t,s,n,i){var o=1/Math.tan(t/2),a;return e[0]=o/s,e[1]=0,e[2]=0,e[3]=0,e[4]=0,e[5]=o,e[6]=0,e[7]=0,e[8]=0,e[9]=0,e[11]=-1,e[12]=0,e[13]=0,e[15]=0,i!=null&&i!==1/0?(a=1/(n-i),e[10]=(i+n)*a,e[14]=2*i*n*a):(e[10]=-1,e[14]=-2*n),e}var Ps=Ls;function me(){var e=new de(3);return de!=Float32Array&&(e[0]=0,e[1]=0,e[2]=0),e}function Ss(e){var t=new de(3);return t[0]=e[0],t[1]=e[1],t[2]=e[2],t}function ie(e,t,s){var n=new de(3);return n[0]=e,n[1]=t,n[2]=s,n}function Ns(e,t,s){return e[0]=t[0]+s[0],e[1]=t[1]+s[1],e[2]=t[2]+s[2],e}function qt(e,t,s){return e[0]=t[0]*s,e[1]=t[1]*s,e[2]=t[2]*s,e}function Os(e,t){var s=t[0]-e[0],n=t[1]-e[1],i=t[2]-e[2];return Math.hypot(s,n,i)}var Ds=Os;(function(){var e=me();return function(t,s,n,i,o,a){var r,l;for(s||(s=3),n||(n=0),i?l=Math.min(i*s+n,t.length):l=t.length,r=n;r<l;r+=s)e[0]=t[r],e[1]=t[r+1],e[2]=t[r+2],o(e,e,a),t[r]=e[0],t[r+1]=e[1],t[r+2]=e[2];return t}})();function Le(){var e=new de(2);return de!=Float32Array&&(e[0]=0,e[1]=0),e}(function(){var e=Le();return function(t,s,n,i,o,a){var r,l;for(s||(s=2),n||(n=0),i?l=Math.min(i*s+n,t.length):l=t.length,r=n;r<l;r+=s)e[0]=t[r],e[1]=t[r+1],o(e,e,a),t[r]=e[0],t[r+1]=e[1];return t}})();function Bs(e){let t=0,s="",n="";const i=[];for(let o=0;o<e.length;++o){const a=e[o];switch(t){case 0:{if(/\s/.test(a))continue;if(a==="{")i.push({}),t=1;else return[];break}case 1:{if(/\s/.test(a))continue;if(a==="}")t=0;else if(a==='"')s="",t=2;else return[];break}case 2:{a==='"'?t=3:s+=a;break}case 3:{if(/\s/.test(a))continue;a==='"'&&(n="",t=4);break}case 4:{a==='"'?(i[i.length-1][s]=n,t=1):n+=a;break}}}return i}class Us{constructor(t,s,n,i,o){f(this,"name");f(this,"entities");f(this,"textures");f(this,"models");f(this,"lightmap");f(this,"skies",[]);f(this,"sprites",{});this.name=t,this.entities=s,this.textures=n,this.models=i,this.lightmap=o}}const V=class V{constructor(t){f(this,"lightmap");f(this,"texture");f(this,"block",new Uint16Array(V.TEXTURE_SIZE));this.lightmap=t,this.texture=new Uint8Array(V.TEXTURE_SIZE*V.TEXTURE_SIZE*4),this.texture[this.texture.length-4]=255,this.texture[this.texture.length-3]=255,this.texture[this.texture.length-2]=255,this.texture[this.texture.length-1]=255}static init(t){return new V(t)}getTexture(){return this.texture}processFace(t,s,n){const i=this.getDimensions(t),o=this.readLightmap(n,i.width,i.height);if(o)for(let a=0;a<t.length/7;++a){let r=t[a*7]*s.s[0]+t[a*7+1]*s.s[1]+t[a*7+2]*s.s[2]+s.sShift-i.minU;r+=o.x*16+8,r/=V.TEXTURE_SIZE*16;let l=t[a*7]*s.t[0]+t[a*7+1]*s.t[1]+t[a*7+2]*s.t[2]+s.tShift-i.minV;l+=o.y*16+8,l/=V.TEXTURE_SIZE*16,t[a*7+5]=r,t[a*7+6]=l}}getDimensions(t){let s=Math.floor(t[3]),n=Math.floor(t[4]),i=Math.floor(t[3]),o=Math.floor(t[4]);for(let a=1;a<t.length/7;++a)Math.floor(t[a*7+3])<s&&(s=Math.floor(t[a*7+3])),Math.floor(t[a*7+4])<n&&(n=Math.floor(t[a*7+4])),Math.floor(t[a*7+3])>i&&(i=Math.floor(t[a*7+3])),Math.floor(t[a*7+4])>o&&(o=Math.floor(t[a*7+4]));return{width:Math.ceil(i/16)-Math.floor(s/16)+1,height:Math.ceil(o/16)-Math.floor(n/16)+1,minU:Math.floor(s),minV:Math.floor(n)}}readLightmap(t,s,n){if(n<=0||s<=0)return null;const i=this.findFreeSpace(s,n);if(i){const o=[i.x,i.y],a=[s,n],r=[V.TEXTURE_SIZE,V.TEXTURE_SIZE],l=s*n;for(let c=0;c<l;++c){const u=o[1]*r[0]+o[0]+r[0]*Math.floor(c/a[0])+c%a[0];this.texture[u*4]=Math.min(255,this.lightmap[t+c*3]*2),this.texture[u*4+1]=Math.min(255,this.lightmap[t+c*3+1]*2),this.texture[u*4+2]=Math.min(255,this.lightmap[t+c*3+2]*2),this.texture[u*4+3]=255}}return i}findFreeSpace(t,s){let n=0,i=0,o=V.TEXTURE_SIZE;for(let a=0;a<this.block.length-t;++a){let r=0,l=0;for(;l<t&&!(this.block[a+l]>=o);++l)this.block[a+l]>r&&(r=this.block[a+l]);l===t&&(n=a,i=o=r)}if(o+s>V.TEXTURE_SIZE)return null;for(let a=0;a<t;++a)this.block[n+a]=o+s;return{x:n,y:i}}};f(V,"TEXTURE_SIZE",1024);let Pe=V;function Fs(e,t,s,n,i,o,a,r){const l=[];for(let c=0;c<e.length;++c){const u=e[c],h=[],m=new Float32Array(3),g=new Float32Array(3),d=new Float32Array(3),p=new Float32Array(2),E=new Float32Array(2),v=new Float32Array(2),x=new Float32Array(2),b=new Float32Array(2),w=new Float32Array(2),S=c===0?[0,0,0]:[0,0,0].map((I,y)=>(u.maxs[y]-u.mins[y])/2+u.mins[y]),C=ie(S[0],S[1],S[2]);for(let I=u.firstFace;I<u.firstFace+u.faceCount;++I){const y={buffer:new Float32Array((t[I].edgeCount-2)*21),textureIndex:-1},k=o[t[I].textureInfo],A=a[k.textureIndex],F=n.slice(t[I].firstEdge,t[I].firstEdge+t[I].edgeCount),Z=s[Math.abs(F[0])][F[0]>0?0:1];m[0]=i[Z][0],m[1]=i[Z][1],m[2]=i[Z][2],p[0]=m[0]*k.s[0]+m[1]*k.s[1]+m[2]*k.s[2]+k.sShift,p[1]=m[0]*k.t[0]+m[1]*k.t[1]+m[2]*k.t[2]+k.tShift,x[0]=0,x[1]=0;const $=s[Math.abs(F[1])][F[1]>0?0:1];g[0]=i[$][0],g[1]=i[$][1],g[2]=i[$][2],E[0]=g[0]*k.s[0]+g[1]*k.s[1]+g[2]*k.s[2]+k.sShift,E[1]=g[0]*k.t[0]+g[1]*k.t[1]+g[2]*k.t[2]+k.tShift,b[0]=0,b[1]=.999;let _=0;for(let U=2;U<t[I].edgeCount;++U){const K=s[Math.abs(F[U])][F[U]>0?0:1];d[0]=i[K][0],d[1]=i[K][1],d[2]=i[K][2],v[0]=d[0]*k.s[0]+d[1]*k.s[1]+d[2]*k.s[2]+k.sShift,v[1]=d[0]*k.t[0]+d[1]*k.t[1]+d[2]*k.t[2]+k.tShift,w[0]=.999,w[1]=.999,y.buffer[_++]=m[0],y.buffer[_++]=m[1],y.buffer[_++]=m[2],y.buffer[_++]=p[0],y.buffer[_++]=p[1],y.buffer[_++]=x[0],y.buffer[_++]=x[1],y.buffer[_++]=g[0],y.buffer[_++]=g[1],y.buffer[_++]=g[2],y.buffer[_++]=E[0],y.buffer[_++]=E[1],y.buffer[_++]=b[0],y.buffer[_++]=b[1],y.buffer[_++]=d[0],y.buffer[_++]=d[1],y.buffer[_++]=d[2],y.buffer[_++]=v[0],y.buffer[_++]=v[1],y.buffer[_++]=w[0],y.buffer[_++]=w[1],g[0]=d[0],g[1]=d[1],g[2]=d[2],E[0]=v[0],E[1]=v[1],b[0]=w[0],b[1]=w[1]}(k.flags===0||k.flags===-65536)&&r.processFace(y.buffer,k,t[I].lightmapOffset),y.textureIndex=k.textureIndex;for(let U=0;U<y.buffer.length/7;++U)y.buffer[U*7]-=C[0],y.buffer[U*7+1]-=C[1],y.buffer[U*7+2]-=C[2],y.buffer[U*7+3]/=A.width,y.buffer[U*7+4]/=A.height;h.push(y)}l.push({origin:C,faces:h})}return l}const Cs={parse(e,t){const s=new he(t);if(s.ui()!==30)throw new Error("Invalid map version");const i=[];for(let E=0;E<15;++E)i.push({offset:s.ui(),length:s.ui()});const o=this.loadEntities(s,i[0].offset,i[0].length),a=this.loadTextures(s,i[2].offset),r=this.loadModels(s,i[14].offset,i[14].length),l=this.loadFaces(s,i[7].offset,i[7].length),c=this.loadEdges(s,i[12].offset,i[12].length),u=this.loadSurfEdges(s,i[13].offset,i[13].length),h=this.loadVertices(s,i[3].offset,i[3].length),m=this.loadTexInfo(s,i[6].offset,i[6].length),g=this.loadLightmap(s,i[8].offset,i[8].length),d=Pe.init(g),p=Fs(r,l,c,u,h,m,a,d);return new Us(e,o,a,p,{width:Pe.TEXTURE_SIZE,height:Pe.TEXTURE_SIZE,data:d.getTexture()})},loadFaces(e,t,s){e.seek(t);const n=[];for(let i=0;i<s/20;++i)n.push({plane:e.us(),planeSide:e.us(),firstEdge:e.ui(),edgeCount:e.us(),textureInfo:e.us(),styles:[e.ub(),e.ub(),e.ub(),e.ub()],lightmapOffset:e.ui()});return n},loadModels(e,t,s){e.seek(t);const n=[];for(let i=0;i<s/64;++i)n.push({mins:[e.f(),e.f(),e.f()],maxs:[e.f(),e.f(),e.f()],origin:ie(e.f(),e.f(),e.f()),headNodes:[e.i(),e.i(),e.i(),e.i()],visLeaves:e.i(),firstFace:e.i(),faceCount:e.i()});return n},loadEdges(e,t,s){e.seek(t);const n=[];for(let i=0;i<s/4;++i)n.push([e.us(),e.us()]);return n},loadSurfEdges(e,t,s){e.seek(t);const n=[];for(let i=0;i<s/4;++i)n.push(e.i());return n},loadVertices(e,t,s){e.seek(t);const n=[];for(let i=0;i<s/12;++i)n.push([e.f(),e.f(),e.f()]);return n},loadTexInfo(e,t,s){e.seek(t);const n=[];for(let i=0;i<s/40;++i)n.push({s:[e.f(),e.f(),e.f()],sShift:e.f(),t:[e.f(),e.f(),e.f()],tShift:e.f(),textureIndex:e.i(),flags:e.i()});return n},loadLightmap(e,t,s){return e.seek(t),e.arrx(s,O.UByte)},loadTextureData(e){const t=e.nstr(16),s=e.ui(),n=e.ui(),i=!e.ui();if(i){const c=new Uint8Array(4);return c[0]=c[1]=c[2]=c[3]=255,{name:t,width:s,height:n,data:c,isExternal:i}}e.skip(3*4);const o=s*n,a=e.arrx(o,O.UByte);e.skip(21*(o/64)),e.skip(2);const r=e.arrx(768,O.UByte),l=t[0]==="{"?Me(a,r):Fe(a,r);return{name:t,width:s,height:n,data:l,isExternal:i}},loadTextures(e,t){e.seek(t);const s=e.ui(),n=[];for(let o=0;o<s;++o)n.push(e.ui());const i=[];for(let o=0;o<s;++o)n[o]===4294967295?i.push({name:"ERROR404",width:1,height:1,data:new Uint8Array([0,255,0,255]),isExternal:!1}):(e.seek(t+n[o]),i.push(this.loadTextureData(e)));return i},loadEntities(e,t,s){e.seek(t);const n=Bs(e.nstr(s)),i=["origin","angles","_diffuse_light","_light","rendercolor","avelocity"],o=["renderamt","rendermode","scale"],a=n[0];a.classname==="worldspawn"&&(a.model="*0",a.wad=a.wad||"",a.wad=a.wad.split(";").filter(r=>r.length).map(r=>r.replace(/\\/g,"/")).map(r=>Gt(r)));for(const r of n){r.model&&(typeof r.renderamt>"u"&&(r.renderamt=0),typeof r.rendermode>"u"&&(r.rendermode=0),typeof r.renderfx>"u"&&(r.renderfx=0),typeof r.rendercolor>"u"&&(r.rendercolor="0 0 0"));for(const l of i)r[l]&&(r[l]=r[l].split(" ").map(c=>Number.parseFloat(c)));for(const l of o)r[l]&&(r[l]=Number.parseFloat(r[l]))}return n}};class ye{constructor(t){f(this,"name");f(this,"progress");f(this,"status");f(this,"data");this.name=t,this.progress=0,this.status=1,this.data=null}isLoading(){return this.status===1}skip(){this.status=2}isSkipped(){return this.status===2}error(){this.status=3}isError(){return this.status===3}done(t){this.status=4,this.data=t}isDone(){return this.status===4}}class $s extends ye{constructor(){super(...arguments);f(this,"type","replay")}}class Gs extends ye{constructor(){super(...arguments);f(this,"type","bsp")}}class Xs extends ye{constructor(){super(...arguments);f(this,"type","sky")}}class Hs extends ye{constructor(){super(...arguments);f(this,"type","wad")}}class Ws extends ye{constructor(){super(...arguments);f(this,"type","sound")}}class js extends ye{constructor(){super(...arguments);f(this,"type","sprite")}}class zs{constructor(t){f(this,"config");f(this,"replay");f(this,"map");f(this,"skies");f(this,"wads");f(this,"sounds");f(this,"sprites",{});f(this,"events");this.config=t,this.replay=void 0,this.map=void 0,this.skies=[],this.wads=[],this.sounds=[],this.events=G(),this.events.on("error",s=>{console.error(s)})}clear(){this.replay=void 0,this.map=void 0,this.skies.length=0,this.wads.length=0,this.sounds.length=0,this.sprites={}}checkStatus(){if(this.replay&&!this.replay.isDone()||this.map&&!this.map.isDone())return;for(let s=0;s<this.skies.length;++s)if(this.skies[s].isLoading())return;for(let s=0;s<this.wads.length;++s)if(this.wads[s].isLoading())return;for(let s=0;s<this.sounds.length;++s)if(this.sounds[s].isLoading())return;const t=Object.entries(this.sprites);for(let s=0;s<t.length;++s)if(t[s][1].isLoading())return;this.events.emit("loadall",this)}load(t){const s=Ts(t);s===".dem"?this.loadReplay(t):s===".bsp"?this.loadMap(t):this.events.emit("error","Invalid file extension",t)}async loadReplay(t){this.replay=new $s(t),this.events.emit("loadstart",this.replay);const s=(r,l)=>{this.replay&&(this.replay.progress=l),this.events.emit("progress",this.replay)},n=this.config.getReplaysPath(),i=await we(`${n}/${t}`,{method:"GET",isBinary:!0,progressCallback:s}).catch(r=>{this.replay&&this.replay.error(),this.events.emit("error",r,this.replay)});if(this.replay.isError())return;const o=xe.parseIntoChunks(i);this.replay.done(o),this.loadMap(`${o.maps[0].name}.bsp`);const a=o.maps[0].resources.sounds;for(const r of a)r.used&&this.loadSound(r.name,r.index);this.events.emit("load",this.replay),this.checkStatus()}async loadMap(t){this.map=new Gs(t),this.events.emit("loadstart",this.map);const s=(r,l)=>{this.map&&(this.map.progress=l),this.events.emit("progress",this.map)},n=this.config.getMapsPath(),i=await we(`${n}/${t}`,{method:"GET",isBinary:!0,progressCallback:s}).catch(r=>{this.map&&this.map.error(),this.events.emit("error",r,this.map)});if(this.map.isError())return;const o=Cs.parse(t,i);this.map.done(o),o.entities.map(r=>{if(typeof r.model=="string"&&r.model.indexOf(".spr")>-1)return r.model}).filter((r,l,c)=>r&&c.indexOf(r)===l).map(r=>r&&this.loadSprite(r));const a=o.entities[0].skyname;if(a&&["bk","dn","ft","lf","rt","up"].map(l=>`${a}${l}`).map(l=>this.loadSky(l)),o.textures.find(r=>r.isExternal)){const l=o.entities[0].wad.map(c=>this.loadWad(c));await Promise.all(l)}this.events.emit("load",this.map),this.checkStatus()}async loadSprite(t){const s=new js(t);this.sprites[t]=s,this.events.emit("loadstart",s);const n=(a,r)=>{s.progress=r,this.events.emit("progress",s)},i=await we(`${this.config.getBasePath()}/${t}`,{method:"GET",isBinary:!0,progressCallback:n}).catch(a=>{s.error(),this.events.emit("error",a,s),this.checkStatus()});if(s.isError())return;const o=wt.parse(i);s.done(o),this.events.emit("load",s),this.checkStatus()}async loadSky(t){const s=new Xs(t);this.skies.push(s),this.events.emit("loadstart",s);const n=(r,l)=>{s.progress=l,this.events.emit("progress",s)},i=this.config.getSkiesPath(),o=await we(`${i}/${t}.tga`,{method:"GET",isBinary:!0,progressCallback:n}).catch(r