diff --git a/fx.bundle.js b/fx.bundle.js
index fb9f122..aa31aa5 100644
--- a/fx.bundle.js
+++ b/fx.bundle.js
@@ -1,2 +1,2 @@
-const buildTimestamp = "1742545895995"; const dictionary = {"gIsTeamGame":"hP","game":"aC","playerId":"eK","playerData":"af","playerNames":"zT","gameState":"ys","fontSize":"fontSize","x":"eh","y":"ej","canvas":"hX","gHumans":"jp","playerStates":"a2I","fontGeneratorFunction":"b8.pb.rQ","rawPlayerNames":"zZ","playerBalances":"gb","playerTerritories":"gN","gLobbyMaxJoin":"w6","data":"data","playerCount":"playerCount","gBots":"kA","strs":"a9L","gIsSingleplayer":"k8","uiSizes":"ba","gap":"gap","gMaxPlayers":"eX","i":"aA","MenuManager":"aZ","getState":"a05"};
+const buildTimestamp = "1742712803394"; const dictionary = {"gIsTeamGame":"hP","game":"aC","playerId":"eK","playerData":"af","playerNames":"zT","gameState":"ys","fontSize":"fontSize","x":"eh","y":"ej","canvas":"hX","gHumans":"jp","playerStates":"a2I","fontGeneratorFunction":"b8.pb.rQ","rawPlayerNames":"zZ","playerBalances":"gb","playerTerritories":"gN","gLobbyMaxJoin":"w6","data":"data","playerCount":"playerCount","gBots":"kA","strs":"a9L","gIsSingleplayer":"k8","uiSizes":"ba","gap":"gap","gMaxPlayers":"eX","i":"aA","MenuManager":"aZ","getState":"a05"};
 (()=>{"use strict";function e(e){const t=document.createElement("p");t.innerText="Attack Percentage Keybinds";const n=document.createElement("div");n.className="arrayinput";const o=document.createElement("button");return o.innerText="Add",e.append(t,n,o),e.className="keybinds-input",this.container=n,this.keys=["key","type","value"],this.objectArray=[],this.addObject=function(){this.objectArray.push({key:"",type:"absolute",value:.8}),this.displayObjects(),o.scrollIntoView(!1)},this.update=function(e){this.objectArray=e.attackPercentageKeybinds,this.displayObjects()},o.addEventListener("click",this.addObject.bind(this)),this.displayObjects=function(){if(this.container.innerHTML="",0===this.objectArray.length)return this.container.innerText="No custom attack percentage keybinds added";for(var e=0;e<this.objectArray.length;e++){var t=document.createElement("div");this.keys.forEach((function(n){let o=document.createElement("type"===n?"select":"input");if("type"===n)o.innerHTML='<option value="absolute">Absolute</option><option value="relative">Relative</option>',o.addEventListener("change",this.updateObject.bind(this,e,n));else if("key"===n)o.type="text",o.setAttribute("readonly",""),o.setAttribute("placeholder","No key set"),o.addEventListener("click",this.startKeyInput.bind(this,e,n));else{const t="absolute"===this.objectArray[e].type;o.type=t?"text":"number",t?o.addEventListener("click",this.convertIntoNumberInput.bind(this,e,n),{once:!0}):o.setAttribute("step","0.1"),o.addEventListener("input",this.updateObject.bind(this,e,n))}"value"===n&&"absolute"===this.objectArray[e].type?o.value=100*this.objectArray[e][n]+"%":o.value=this.objectArray[e][n],t.appendChild(o)}),this);var n=document.createElement("button");n.textContent="Delete",n.addEventListener("click",this.deleteObject.bind(this,e)),t.appendChild(n),this.container.appendChild(t)}},this.startKeyInput=function(e,t,n){n.target.value="Press any key";const o=this.updateObject.bind(this,e,t);n.target.addEventListener("keydown",o,{once:!0}),n.target.addEventListener("blur",(()=>{n.target.removeEventListener("keydown",o),n.target.value=this.objectArray[e][t]}),{once:!0})},this.convertIntoNumberInput=function(e,t,n){n.target.value=n.target.value.slice(0,-1),n.target.type="number",n.target.addEventListener("blur",(()=>{this.displayObjects()}),{once:!0})},this.updateObject=function(e,t,n){if(e>=this.objectArray.length)return;const o="value"===t?"absolute"===this.objectArray[e].type?parseFloat(n.target.value)/100:parseFloat(n.target.value):"key"===t?n.key:n.target.value;this.objectArray[e][t]=o,"key"===t&&this.displayObjects()},this.deleteObject=function(e){this.objectArray.splice(e,1),this.displayObjects()},this}const t={count:0,removeWins:function(){confirm("Do you really want to reset your wins?")&&(t.count=0,localStorage.removeItem("fx_winCount"),alert("Successfully reset wins"))}};null!==localStorage.getItem("fx_winCount")&&(t.count=localStorage.getItem("fx_winCount"));const n=t;var o={};const a=document.getElementById("windowContainer");function i(e){o[e.name]=e,o[e.name].isOpen=!1}function s(e){!1!==o[e].isOpen&&(o[e].isOpen=!1,o[e].element.style.display="none",void 0!==o[e].onClose&&o[e].onClose())}function l(){Object.values(o).forEach((function(e){!1!==e.closable&&s(e.name)}))}document.addEventListener("mousedown",(e=>{a.contains(e.target)||l(),y().useFullscreenMode&&h()}),{passive:!0,capture:!0}),document.getElementById("canvasA").addEventListener("touchstart",l,{passive:!0}),document.addEventListener("keydown",(e=>{"Escape"===e.key&&l()}));const r={create:function(e){const t=document.createElement("div");return e.element=t,t.className="window"+(void 0!==e.classes?" "+e.classes:" scrollable selectable"),t.style.display="none",a.appendChild(t),i(e),t},add:i,openWindow:function(e,...t){!0!==o[e].isOpen&&(void 0!==o[e].beforeOpen&&o[e].beforeOpen(...t),o[e].isOpen=!0,o[e].element.style.display=null)},closeWindow:s,closeAll:l};window.__fx=window.__fx||{};const c=window.__fx;var d={displayWinCounter:!0,useFullscreenMode:!1,hoveringTooltip:!0,realisticNames:!1,showPlayerDensity:!0,coloredDensity:!0,densityDisplayStyle:"percentage",hideBotNames:!1,highlightClanSpawns:!1,detailedTeamPercentage:!1,customBackgroundUrl:"",keybindButtons:!1,attackPercentageKeybinds:[]};c.settings=d;const u=["hideAllLinks","fontName"];c.makeMainMenuTransparent=!1;const p=new function(){const t=[{for:"displayWinCounter",type:"checkbox",label:"Display win counter",note:"The win counter tracks multiplayer solo wins (not in team games)"},{type:"button",text:"Reset win counter",action:n.removeWins},{for:"useFullscreenMode",type:"checkbox",label:"Use fullscreen mode",note:"Note: fullscreen mode will trigger after you click anywhere on the page due to browser policy restrictions."},{for:"hoveringTooltip",type:"checkbox",label:"Hovering tooltip",note:"Display map territory info constantly (on mouse hover) instead of only when right clicking on the map"},{for:"realisticNames",type:"checkbox",label:"Realistic Bot Names"},{for:"showPlayerDensity",type:"checkbox",label:"Show player density"},{for:"coloredDensity",type:"checkbox",label:"Colored density",note:"Display the density with a color between red and green depending on the density value"},{for:"densityDisplayStyle",type:"selectMenu",label:"Density value display style:",tooltip:"Controls how the territorial density value should be rendered",options:[{value:"percentage",label:"Percentage"},{value:"absoluteQuotient",label:"Value from 0 to 150 (BetterTT style)"}]},{for:"hideBotNames",type:"checkbox",label:"Hide bot names"},{for:"highlightClanSpawns",type:"checkbox",label:"Highlight clan spawnpoints",note:"Increases the spawnpoint glow size for members of your clan"},{for:"detailedTeamPercentage",type:"checkbox",label:"Detailed team pie chart percentage",note:"For example: this would show 25.82% instead of 26% on the pie chart in team games"},{for:"customBackgroundUrl",type:"textInput",label:"Custom main menu background:",placeholder:"Enter an image URL here",tooltip:"A custom image to be shown as the main menu background instead of the currently selected map."},e,{for:"keybindButtons",type:"checkbox",label:"Keybind buttons",note:"Show keybind buttons above the troop selector (max 6)"}],o=document.querySelector(".settings .scrollable");var a={},i={},s=[];t.forEach((e=>{if("function"==typeof e){const t=document.createElement("div");return s.push(new e(t)),o.append(t)}const t=document.createElement("label");e.tooltip&&(t.title=e.tooltip);const n=e.type.endsWith("Input"),l=document.createElement(n||"checkbox"===e.type?"input":"selectMenu"===e.type?"select":"button");if("textInput"===e.type&&(l.type="text"),e.placeholder&&(l.placeholder=e.placeholder),(n||"selectMenu"===e.type)&&(a[e.for]=l),e.text&&(l.innerText=e.text),e.action&&l.addEventListener("click",e.action),e.label&&t.append(e.label+" "),e.note){const n=document.createElement("small");n.innerText=e.note,t.append(document.createElement("br"),n)}if(e.options&&e.options.forEach((e=>{const t=document.createElement("option");t.setAttribute("value",e.value),t.innerText=e.label,l.append(t)})),t.append(l),"checkbox"===e.type){l.type="checkbox";const n=document.createElement("span");n.className="checkmark",t.className="checkbox",t.append(n),i[e.for]=l}else t.append(document.createElement("br"));o.append(t,document.createElement("br"))})),this.save=function(){Object.keys(a).forEach((function(e){d[e]=a[e].value.trim()})),Object.keys(i).forEach((function(e){d[e]=i[e].checked})),this.applySettings(),r.closeWindow("settings"),u.forEach((e=>delete d[e])),localStorage.setItem("fx_settings",JSON.stringify(d)),window.location.reload()};const l=document.createElement("input");function p(e){const t=e.target,n=t.files[0];if(!n)return;if(t.removeEventListener("change",p),t.value="",!n.name.endsWith(".json"))return alert("Invalid file format");const o=new FileReader;o.onload=function(){let e;try{e=JSON.parse(o.result),confirm('Warning: This will override all current settings, click "OK" to confirm')&&(c.settings=d=e),localStorage.setItem("fx_settings",JSON.stringify(d)),window.location.reload()}catch(e){alert("Error\n"+e)}},o.readAsText(n)}l.type="file",this.importFromFile=function(){l.click(),l.addEventListener("change",p)},this.exportToFile=function(){var e,t,n;e=JSON.stringify(d),t=document.createElement("a"),n=new Blob([e],{type:"application/json"}),t.href=URL.createObjectURL(n),t.download="FX_client_settings.json",t.click(),URL.revokeObjectURL(t.href)},this.syncFields=function(){Object.keys(a).forEach((function(e){a[e].value=d[e]})),Object.keys(i).forEach((function(e){i[e].checked=d[e]})),s.forEach((e=>e.update(d)))},this.resetAll=function(){confirm("Are you Really SURE you want to RESET ALL SETTINGS back to the default?")&&(localStorage.removeItem("fx_settings"),window.location.reload())},this.applySettings=function(){""!==d.customBackgroundUrl&&(document.body.style.backgroundImage="url("+d.customBackgroundUrl+")",document.body.style.backgroundSize="cover",document.body.style.backgroundPosition="center"),c.makeMainMenuTransparent=""!==d.customBackgroundUrl},d.useFullscreenMode&&h()};function h(){null===document.fullscreenElement&&document.fullscreenEnabled&&document.documentElement.requestFullscreen({navigationUI:"hide"}).then((()=>{console.log("Fullscreen mode activated")})).catch((e=>{console.warn("Could not enter fullscreen mode:",e)}))}r.add({name:"settings",element:document.querySelector(".settings"),beforeOpen:function(){p.syncFields()}}),null!==localStorage.getItem("fx_settings")&&(c.settings=d={...d,...JSON.parse(localStorage.getItem("fx_settings"))}),p.applySettings();const m=p;function y(){return d}const b=["playerTerritories","playerBalances","rawPlayerNames"],f=["playerId","gIsTeamGame","gHumans","gLobbyMaxJoin","gameState","gIsSingleplayer"],g=e=>b.includes(e)?window[dictionary.playerData]?.[dictionary[e]]:f.includes(e)?window[dictionary.game]?.[dictionary[e]]:window[dictionary[e]],v=()=>Math.floor(window[dictionary.uiSizes]?.[dictionary.gap]??10),w=new function(){this.playersToInclude=[],this.tabLabels=["ALL","CLAN"],this.filteredLeaderboard=[],this.tabBarOffset=0,this.windowWidth=0,this.verticalClickThreshold=1e3,this.hoveringOverTabs=!1,this.scrollToTop=()=>{},this.repaintLeaderboard=()=>{},this.setUpdateFlag=()=>{},this.parseClanFromPlayerName=()=>{console.warn("parse function not set")},this.selectedTab=0,this.tabHovering=-1,this.enabled=!1,this.drawTabs=function(e,t,n,o){e.textBaseline="middle",e.textAlign="center";const a=t/this.tabLabels.length,i=n+this.tabBarOffset/2;this.tabLabels.forEach(((t,s)=>{0!==s&&e.fillRect(a*s,n,1,this.tabBarOffset),this.selectedTab===s&&(e.fillStyle=o,e.fillRect(a*s,n,a,this.tabBarOffset),e.fillStyle="rgb(255,255,255)"),this.tabHovering===s&&(e.fillStyle="rgba(255,255,255,0.3)",e.fillRect(a*s,n,a,this.tabBarOffset),e.fillStyle="rgb(255,255,255)"),e.fillText(t,a*s+a/2,i)}))},this.setHovering=(e,t)=>{let n=!1;if(e){const e=Math.floor(t/(this.windowWidth/this.tabLabels.length));this.tabHovering!==e&&(this.tabHovering=e,n=!0)}return e!==this.hoveringOverTabs&&(this.hoveringOverTabs=e,!1===e&&(this.tabHovering=-1),e||(n=!0)),n&&this.repaintLeaderboard(),e},this.handleMouseDown=e=>{const t=Math.floor(e/(this.windowWidth/this.tabLabels.length));return this.selectedTab!==t&&(this.selectedTab=t,0===this.selectedTab?this.clearFilter():1===this.selectedTab&&(this.filterByOwnClan(),this.setUpdateFlag()),this.repaintLeaderboard()),!0},this.filterByOwnClan=()=>{this.playersToInclude=[];const e=g("playerId"),t=this.parseClanFromPlayerName(g("rawPlayerNames")[e]);g("rawPlayerNames").forEach(((n,o)=>{o!==e&&this.parseClanFromPlayerName(n)!==t||this.playersToInclude.push(o)})),this.enabled=!0,this.scrollToTop()},this.clearFilter=()=>{this.enabled=!1},this.reset=()=>{this.enabled=!1,this.selectedTab=0,E.refresh()}},E=new function(){this.inOwnClan=new Array(512),this.inOwnClan.fill(!1),this.refresh=()=>{const e=g("gHumans"),t=w.parseClanFromPlayerName(g("rawPlayerNames")[g("playerId")]);null===t?this.inOwnClan.fill(!1):g("rawPlayerNames").forEach(((n,o)=>{this.inOwnClan[o]=o<e&&w.parseClanFromPlayerName(n)===t}))}};function k(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#039;")}r.add({name:"donationHistory",element:document.querySelector("#donationhistory"),beforeOpen:function(e){document.getElementById("donationhistory_note").style.display="none"},onClose:function(){x.openedWindowPlayerID=null}});const x=new function(){function e(e,t,n,o){const a=g("rawPlayerNames"),i=document.createElement("tr");o&&i.setAttribute("class","new");let s=`<td><span class="color-light-gray">${t}.</span> `;return n===e[1]?s+=`Received <span class="color-green">${e[2]}</span> resources from ${k(a[e[0]])}`:s+=`Sent <span class="color-red">${e[2]}</span> resources to ${k(a[e[1]])}`,s+="</td>",i.innerHTML=s,i}this.openedWindowPlayerID=null,this.contentElement=document.querySelector("#donationhistory_content"),this.donationHistory=Array(512),this.getHistoryOf=function(e){return this.donationHistory[e].toReversed()},this.reset=function(){for(var e=0;e<512;e++)this.donationHistory[e]=[]},this.logDonation=function(t,n,o){const a=[t,n,o];if(this.donationHistory[n].push(a),this.donationHistory[t].push(a),this.openedWindowPlayerID===t||this.openedWindowPlayerID===n){const o=this.donationHistory[this.openedWindowPlayerID===t?t:n].length;this.contentElement.prepend(e(a,o,this.openedWindowPlayerID,!0))}},this.displayHistory=function(t,n=g("rawPlayerNames"),o=g("gIsSingleplayer")){var a=x.getHistoryOf(t);console.log("History for "+n[t]+":"),console.log(a),document.querySelector("#donationhistory h1").innerHTML="Donation history for "+k(n[t]),this.contentElement.innerHTML="",a.length>0?a.forEach(((n,o)=>{this.contentElement.appendChild(e(n,a.length-o,t))})):this.contentElement.innerText="Nothing to display",this.openedWindowPlayerID=t,r.openWindow("donationHistory",o)}},L=x,T=new function(){const e=document.createElement("img");e.setAttribute("src","assets/players_icon.png"),document.getElementById("playerlist_content").addEventListener("click",(e=>{const t=e.target.closest("tr[data-player-id]")?.getAttribute("data-player-id");t&&g("gIsTeamGame")&&(r.closeWindow("playerList"),L.displayHistory(t))})),this.display=function(e){const t=g("gHumans"),n=g("gLobbyMaxJoin");let o=`<h3>Players (${t})</h3>`;for(let a=0;a<n;a++)a===t&&(o+=`<h3>Bots (${n-t})</h3>`),o+=`<tr data-player-id="${a}"><td><span class="color-light-gray">${a+1}.</span> ${k(e[a])}</td></tr>`;document.getElementById("playerlist_content").innerHTML=o,document.getElementById("playerlist_content").setAttribute("class",g("gIsTeamGame")?"clickable":""),r.openWindow("playerList")},this.hoveringOverButton=!1,this.drawButton=(t,n,o,a)=>{t.fillRect(n,o,a,a),t.fillStyle=this.hoveringOverButton?"#aaaaaaaa":"#000000aa",t.clearRect(n+1,o+1,a-2,a-2),t.fillRect(n+1,o+1,a-2,a-2),t.fillStyle="#ffffff",t.imageSmoothingEnabled=!0,t.drawImage(e,n+2,o+2,a-4,a-4),t.imageSmoothingEnabled=!1}};r.add({name:"playerList",element:document.getElementById("playerlist")});const I=T,S=new function(){this.getMaxTroops=function(e,t){return(150*e[t]).toString()},this.getDensity=function(e,t=g("playerBalances"),n=g("playerTerritories")){return"percentage"===y().densityDisplayStyle?(t[e]/(150*(0===n[e]?1:n[e]))*100).toFixed(1)+"%":(t[e]/(0===n[e]?1:n[e])).toFixed(1)},this.isPointInRectangle=function(e,t,n,o,a,i){return e>=n&&e<=n+a&&t>=o&&t<=o+i},this.fillTextMultiline=function(e,t,n,o,a){const i=parseInt(e.font.split(" ").find((e=>e.endsWith("px"))).slice(0,-2));t.split("\n").forEach(((t,s)=>e.fillText(t,n,o+s*i,a)))},this.textStyleBasedOnDensity=function(e){const t=g("playerBalances"),n=g("playerTerritories");return`hsl(${t[e]/(1.5*n[e])}, 100%, 50%, 1)`}},O=S,B=new function(){let e=!1;function t(t){if(!y().hoveringTooltip||!g("gameState")||e)return;let n,o;if(t.type.includes("touch")){const{touches:e,changedTouches:a}=t.originalEvent??t,i=e[0]??a[0];n=i.pageX,o=i.pageY}else t.type.includes("mouse")&&(n=t.clientX,o=t.clientY);e=!0;try{this.display(this.canvasPixelScale*n,this.canvasPixelScale*o)}catch(t){console.error(t)}setTimeout((()=>e=!1),100)}this.display=()=>{},this.canvasPixelScale=1,document.getElementById("canvasA").addEventListener("mousemove",t.bind(this)),document.getElementById("canvasA").addEventListener("touchstart",t.bind(this))},A={setAbsolute:()=>{},setRelative:()=>{},repaintAttackPercentageBar:()=>{}};function C(e){"absolute"===e.type?A.setAbsolute(e.value):A.setRelative(e.value),A.repaintAttackPercentageBar()}let N,M=0,H=0;const P={setSize:(e,t,n)=>{if(!0!==y().keybindButtons)return;M=e,H=t,N=document.createElement("canvas"),N.width=e,N.height=t;const o=N.getContext("2d"),a=n.font.split("px ",2)[1];o.font="bold "+t/2+"px "+a,o.textAlign="center",o.textBaseline="middle";const i=y().attackPercentageKeybinds.slice(0,6),s=v()/4,l=(e-5*s)/6;i.forEach(((e,n)=>{o.fillStyle="rgba(0, 0, 0, 0.8)",o.fillRect(n*(l+s),0,l,t),o.fillStyle="white";const a="absolute"===e.type?(100*e.value).toFixed()+"%":"x "+Math.round(100*e.value)/100;o.fillText(a,(n+.5)*(l+s),t/2)}))},click:e=>{if(e<0||e>M)return!1;const t=y().attackPercentageKeybinds,n=Math.floor(e/M*6);return!(n>=t.length||(C(t[n]),0))},draw:(e,t,n)=>{e.drawImage(N,t,n-(H+v()/4))}};let j=!1,W="",F=()=>{},D=()=>{},_=(e,t)=>{};const R=new TextEncoder,U=new TextDecoder;r.add({name:"lobbyJoinMenu",element:document.getElementById("customLobbyJoinMenu")});const J=r.create({name:"customLobby",classes:"scrollable selectable flex-column text-align-center",closable:!1}),G=document.createElement("h2");G.textContent="Custom Lobby";const $=document.createElement("div");$.className="customlobby-main";const K=document.createElement("div"),q=document.createElement("p");q.textContent="0 Players";const V=document.createElement("div");K.append(q,V);const z=document.createElement("div");z.className="text-align-left";const X={mode:{label:"Mode:",type:"selectMenu",options:[{value:0,label:"2 Teams"},{value:1,label:"3 Teams"},{value:2,label:"4 Teams"},{value:3,label:"5 Teams"},{value:4,label:"6 Teams"},{value:5,label:"7 Teams"},{value:6,label:"8 Teams"},{value:7,label:"Battle Royale"},{value:10,label:"No Fullsend Battle Royale"},{value:9,label:"Zombie mode"}]},map:{label:"Map:",type:"selectMenu"},difficulty:{label:"Difficulty:",type:"selectMenu",options:[{value:0,label:"Very Easy (Default)"},{value:1,label:"Easy (1v1)"},{value:2,label:"Normal"},{value:3,label:"Hard"},{value:4,label:"Very Hard"},{value:5,label:"Impossible"}]},spawnSelection:{label:"Spawn selection",type:"checkbox"},botCount:{label:"Bot & player count:",type:"numberInput",attributes:{min:"1",max:"512"}}},Y={},Q={};function Z(e,t){"checkbox"===X[e].type?Y[e].checked=0!==t:Y[e].value=t.toString(),Q[e]=t}function ee(e,t){se("options",[e,parseInt(t.target.value)])}function te(e,t){se("options",[e,t.target.checked?1:0])}Object.entries(X).forEach((([e,t])=>{const n=document.createElement("label");t.tooltip&&(n.title=t.tooltip);const o=t.type.endsWith("Input"),a=document.createElement(o||"checkbox"===t.type?"input":"selectMenu"===t.type?"select":"button");if(Y[e]=a,"textInput"===t.type&&(a.type="text"),"numberInput"===t.type&&(a.type="number"),t.placeholder&&(a.placeholder=t.placeholder),(o||"selectMenu"===t.type)&&a.addEventListener("change",ee.bind(void 0,e)),t.text&&(a.innerText=t.text),t.action&&a.addEventListener("click",t.action),t.label&&n.append(t.label+" "),t.note){const e=document.createElement("small");e.innerText=t.note,n.append(document.createElement("br"),e)}if(t.options&&ie(t.options,a),t.attributes&&Object.entries(t.attributes).forEach((([e,t])=>a.setAttribute(e,t))),n.append(a),"checkbox"===t.type){a.type="checkbox";const t=document.createElement("span");t.className="checkmark",n.className="checkbox",n.append(t),a.addEventListener("change",te.bind(void 0,e))}else n.append(document.createElement("br"));z.append(n)})),$.append(K,z);const ne=document.createElement("footer");ne.style.marginTop="10px";const oe=document.createElement("button"),ae=document.createElement("button");function ie(e,t){e.forEach((e=>{const n=document.createElement("option");n.setAttribute("value",e.value),n.textContent=e.label,t.append(n)}))}function se(e,t){const n=void 0!==t?{t:e,d:t}:{t:e},o=R.encode(JSON.stringify(n)),a=new ArrayBuffer(o.length+1);new DataView(a).setUint8(0,120),new Uint8Array(a,1).set(o),_(1,a)}oe.textContent="Start game",ae.textContent="Leave lobby",oe.addEventListener("click",(function(){r.closeWindow("customLobby"),se("startGame")})),ae.addEventListener("click",(()=>D())),ne.append(oe,ae),J.append(G,$,ne),document.getElementById("lobbyCode").addEventListener("input",(({target:e})=>{5===e.value.length&&(W=e.value.toLowerCase(),e.value="",r.closeWindow("lobbyJoinMenu"),j=!0,F())})),document.getElementById("createLobbyButton").addEventListener("click",(()=>{W="",r.closeWindow("lobbyJoinMenu"),j=!0,F()}));let le,re=!1,ce=[];function de(e,t){const n=document.createElement("span");return n.textContent=e,n.className=t?"":"d-none",n}function ue(e){const t=document.createElement("div");t.className="lobby-player",t.textContent=e.name;const n=document.createElement("button");n.textContent="Kick",n.className=re&&!e.isHost?"":"d-none",n.addEventListener("click",pe);const o=de("Host",e.isHost),a=de("In Game",e.inGame);t.append(o,a,n),V.append(t),ce.push({element:t,hostBadge:o,inGameBadge:a,kickButton:n,isHost:e.isHost,inGame:e.inGame})}function pe(e){const t=e.target;for(let e=0;e<ce.length;e++)if(ce[e].kickButton===t){se("kick",e);break}}function he(){q.textContent=`${ce.length} Player${1===ce.length?"":"s"}`}const me={gameInfo:Q,showJoinPrompt:function(){r.openWindow("lobbyJoinMenu")},isCustomMessage:function(e){if(120!==e[0])return!1;if(1===e.length)return!0;const t=new Uint8Array(e.buffer,1),n=JSON.parse(U.decode(t)),{t:o,d:a}=n;if("lobby"===o)r.openWindow("customLobby"),G.textContent="Custom Lobby "+a.code,W=a.code,re=a.isHost,oe.disabled=!re,re?z.classList.remove("disabled"):z.classList.add("disabled"),Object.entries(a.options).forEach((([e,t])=>Z(e,t))),i=a.players,s=a.id,ce=[],V.innerHTML="",i.forEach(ue),le=ce[s],he();else if("addPlayer"===o)ue({name:a.name,inGame:!1,isHost:!1}),he();else if("removePlayer"===o){const e=a;ce[e].element.remove(),ce.splice(e,1),he()}else if("inLobby"===o){const e=a;ce[e].inGame=!1,ce[e].inGameBadge.className="d-none"}else if("options"===o){const[e,t]=a;Z(e,t)}else if("setHost"===o){const e=a;ce[e].isHost=!0,ce[e].hostBadge.className=""}else"host"===o?(re=!0,oe.disabled=!1,z.classList.remove("disabled"),ce.forEach((e=>{e.isHost||(e.kickButton.className="")}))):"serverMessage"===o&&alert(a);var i,s;return!0},getSocketURL:function(){return"wss://fx.peshomir.workers.dev/"+(""===W?"create":"join?"+W)},getPlayerId:function(){let e=0;for(let t=0;t<ce.length;t++){const n=ce[t];if(n===le)return e;!1===n.inGame&&e++}},setJoinFunction:function(e){F=e},setLeaveFunction:function(e){D=e},setSendFunction:function(e){_=e},setMapInfo:function(e){setTimeout((()=>ie(e.map(((e,t)=>({value:t.toString(),label:e.name}))),Y.map)),0)},rejoinLobby:function(){F()},hideWindow:function(){r.closeWindow("customLobby")},isActive:()=>j,setActive:function(e){j=e,!1===e&&r.closeWindow("customLobby")}},ye="0.6.7.4";"serviceWorker"in navigator&&(navigator.serviceWorker.addEventListener("message",(e=>{const t=e.data;"activate"===t.event&&buildTimestamp!==t.version&&(document.getElementById("updateNotification").style.display="block")})),navigator.serviceWorker.register("./sw.js")),localStorage.getItem("fx_version")!==ye&&localStorage.setItem("fx_version",ye),window.__fx=window.__fx||{};const be=window.__fx;be.version=ye+" Mar 8",be.settingsManager=m,be.leaderboardFilter=w,be.utils=O,be.WindowManager=r,be.keybindFunctions=A,be.keybindHandler=e=>{const t=y().attackPercentageKeybinds.find((t=>t.key===e));return void 0!==t&&(0!==g("gameState")&&C(t),!0)},be.mobileKeybinds=P,be.donationsTracker=L,be.playerList=I,be.hoveringTooltip=B,be.clanFilter=E,be.wins=n,be.customLobby=me,console.log("Successfully loaded FX Client")})();
\ No newline at end of file
diff --git a/game.js b/game.js
index 392bb9f..484ac5b 100644
--- a/game.js
+++ b/game.js
@@ -72,10 +72,10 @@ function bo(bp) {
 }
 
 function dA() {
-	this.dg = 1095, this.n = 2065, this.rVersion = 9, this.dU = function() {
+	this.dg = 1096, this.n = 2066, this.rVersion = 9, this.dU = function() {
 		this.dh = 2;
 		var di = bJ.dj(this.n, 10) % 100;
-		this.dk = "21 Mar 2025 [" + bJ.dj(this.n, 1e3) + "." + (di < 10 ? "0" : "") + di + "." + this.n % 10 + "]", this.a8 = true, this.a9 = function() {
+		this.dk = "23 Mar 2025 [" + bJ.dj(this.n, 1e3) + "." + (di < 10 ? "0" : "") + di + "." + this.n % 10 + "]", this.a8 = true, this.a9 = function() {
 			try {
 				return window.self !== window.top
 			} catch (e) {
@@ -5226,7 +5226,9 @@ function aBC() {
 			[1.4, 1.2],
 			[1.4, 1.2]
 		],
-		aBs = ["Your account is too new!", "The server couldn't process your request.", "Spam detected!", "You are muted!", "Player couldn't be found.", "You don't have permission for this operation!", "Not enough gold!", "Action cancelled!"];
+		aBs = ["Your account is too new!", "The server couldn't process your request.", "Spam detected!", "You are muted!", "Player couldn't be found.", "You don't have permission for this operation!", "Not enough gold!", "Action cancelled!",
+			"User received this punishment already!", "Lobby restarts in 1 minute!", "Lobby restarts in 10 seconds!"
+		];
 
 	function aC5(qh, ro) {
 		for (var eu = qh.length - 1; 0 <= eu; eu--) {
@@ -5455,8 +5457,8 @@ function aBG() {
 	}
 	this.aCp = function(aBt) {
 		var pT;
-		2 === aBt.id && 3 === aBt.aBv ? bl.ql.aC4(aBt.ro) : (pT = bl.ql.qm(aBt, bl.ql.qn(aBt)), 5 === aBt.id || 6 === aBt.id ? s.aCO(29).aCz().qp(pT) : (pT = bd.e9 < aCx + 2e4, aCw !== aCv.length - 1 && pT || (aCw = aCv.length), aCv.push(aBt), bh
-			.e7.data[14].value || bn.play(), aCu && (bh.e7.data[13].value || aCy && pT ? aCu.r4(aCv.length) : aD0())))
+		2 === aBt.id && 3 === aBt.aBv ? bl.ql.aC4(aBt.ro) : (pT = bl.ql.qm(aBt, bl.ql.qn(aBt)), (5 !== aBt.id && 6 !== aBt.id || (s.aCO(29).aCz().qp(pT), 5 === aBt.id)) && (pT = bd.e9 < aCx + 2e4, aCw !== aCv.length - 1 && pT || (aCw = aCv
+			.length), aCv.push(aBt), bh.e7.data[14].value || bn.play(), aCu) && (bh.e7.data[13].value || aCy && pT ? aCu.r4(aCv.length) : aD0()))
 	}, this.show = function() {
 		aD1()
 	}, this.qs = function() {
@@ -7750,10 +7752,10 @@ function aKr(data) {
 			function(pW) {
 				var aLV = new pE,
 					aLt = data.uq,
-					aLu = (aLV.pH(L(217)), aLV.pN(L(218, [aLt ? "[" + data.uo + "]" : "-"])), aLV.pN(L(219, [b8.zX.a32(aLt, .01, 2)])), aLV.pN(L(220, [data.us + 1 + " / " + data.um])), data.ut),
+					aLu = (aLV.pH(L(217)), aLV.pN(L(218, [data.uo.length ? "[" + data.uo + "]" : "-"])), aLV.pN(L(219, [b8.zX.a32(aLt, .01, 2)])), aLV.pN(L(220, [data.us + 1 + " / " + data.um])), data.ut),
 					aLv = (aLV.pN(L(221, [b8.zX.a32(aLu, .1, 1)])), data.uv);
-				aLV.pN(L(222, [aLv])), aLV.pN(L(223, [b8.zX.a32(aLu / Math.max(aLv, 1), .1, 2)])), aLt = data.ur, aLV.pH(L(224), "0.8em"), aLV.pN(L(218, [aLt ? "[" + data.up + "]" : "-"])), aLV.pN(L(219, [b8.zX.a32(aLt, .01, 2)])), aLu = data
-					.uu, aLV.pN(L(221, [b8.zX.a32(aLu, .1, 1)])), aLv = data.uw, aLV.pN(L(222, [aLv])), aLV.pN(L(223, [b8.zX.a32(aLu / Math.max(aLv, 1), .1, 2)])), data.aLE || (aLV.pJ(L(225)), aLV.pJ(L(226)));
+				aLV.pN(L(222, [aLv])), aLV.pN(L(223, [b8.zX.a32(aLu / Math.max(aLv, 1), .1, 2)])), aLt = data.ur, aLV.pH(L(224), "0.8em"), aLV.pN(L(218, [data.up.length ? "[" + data.up + "]" : "-"])), aLV.pN(L(219, [b8.zX.a32(aLt, .01, 2)])),
+					aLu = data.uu, aLV.pN(L(221, [b8.zX.a32(aLu, .1, 1)])), aLv = data.uw, aLV.pN(L(222, [aLv])), aLV.pN(L(223, [b8.zX.a32(aLu / Math.max(aLv, 1), .1, 2)])), data.aLE || (aLV.pJ(L(225)), aLV.pJ(L(226)));
 				pW.push(aLV)
 			}(pW),
 			function(pW) {
@@ -9716,7 +9718,7 @@ function aPi() {
 			target: bF.oc(30)
 		} : 5 === id ? {
 			id: id,
-			aBv: bF.oc(3)
+			aBv: bF.oc(6)
 		} : 6 === id ? {
 			id: id,
 			value: bF.oc(17)
diff --git a/index.html b/index.html
index cf6e0ec..c610482 100644
--- a/index.html
+++ b/index.html
@@ -35,7 +35,7 @@
     <meta itemprop="image" content="https://fxclient.github.io/FXclient/assets/logo.png">
     
     <!-- FX Client CSS -->
-    <link rel="stylesheet" href="main.css?1742545895995">
+    <link rel="stylesheet" href="main.css?1742712803394">
     <!-- Game CSS -->
     <style>
         html,
@@ -89,8 +89,8 @@
       <button onclick="window.location.reload()">Reload</button>
       <button onclick="document.getElementById('updateNotification').style.display = 'none'">Dismiss</button>
     </div></span>
-    <script src="variables.js?1742545895995"></script>
-    <script src="fx.bundle.js?1742545895995"></script>
-    <script src="game.js?1742545895995"></script>
+    <script src="variables.js?1742712803394"></script>
+    <script src="fx.bundle.js?1742712803394"></script>
+    <script src="game.js?1742712803394"></script>
 </body>
 </html>
diff --git a/sw.js b/sw.js
index b3d447e..924accf 100644
--- a/sw.js
+++ b/sw.js
@@ -1,4 +1,4 @@
-const cacheName = "1742545895995"; // this gets replaced by the build script
+const cacheName = "1742712803394"; // this gets replaced by the build script
 
 self.addEventListener("install", (e) => {
   console.log("[Service Worker] Install");