PidorasiClient

PidorasiClient — Clean Architecture | Auto-Clan Accept | Custom Kill-Chat | Turret & Bull Insta | Auto-Trap | 4x Mills | Clan ESP

スクリプトをインストールするには、Tampermonkey, GreasemonkeyViolentmonkey のような拡張機能のインストールが必要です。

You will need to install an extension such as Tampermonkey or Violentmonkey to install this script.

スクリプトをインストールするには、TampermonkeyViolentmonkey のような拡張機能のインストールが必要です。

スクリプトをインストールするには、TampermonkeyUserscripts のような拡張機能のインストールが必要です。

このスクリプトをインストールするには、Tampermonkeyなどの拡張機能をインストールする必要があります。

このスクリプトをインストールするには、ユーザースクリプト管理ツールの拡張機能をインストールする必要があります。

(ユーザースクリプト管理ツールは設定済みなのでインストール!)

このスタイルをインストールするには、Stylusなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus などの拡張機能をインストールする必要があります。

このスタイルをインストールするには、Stylus tなどの拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

このスタイルをインストールするには、ユーザースタイル管理用の拡張機能をインストールする必要があります。

(ユーザースタイル管理ツールは設定済みなのでインストール!)

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         PidorasiClient
// @namespace    pidorasi-client
// @version      9.3
// @description  PidorasiClient — Clean Architecture | Auto-Clan Accept | Custom Kill-Chat | Turret & Bull Insta | Auto-Trap | 4x Mills | Clan ESP
// @match        *://moomoo.io/*
// @match        *://*.moomoo.io/*
// @require      https://greasyfork.org/scripts/423602-msgpack/code/msgpack.js
// @grant        none
// @author       xw5yt
// @icon         blob:https://gemini.google.com/bc214e5f-738a-4657-b038-4aad20733f22
// @run-at       document-start
// @license      MIT
// ==/UserScript==

/* global msgpack */

(function () {
    'use strict';

    // ==========================================
    // CONSTANTS & THEMES
    // ==========================================
    const THEME = {
        bg: 'rgba(0, 0, 0, 0.4)',
        surface: 'rgba(0, 0, 0, 0.45)',
        border: '1.5px solid rgba(255, 42, 42, 0.65)',
        borderLight: '1px solid rgba(255, 42, 42, 0.25)',
        shadow: '0 0 16px rgba(255, 0, 0, 0.25)',
        blur: 'blur(12px)',
        accent: '#ff4d6d',
        text: '#ffb3c1',
        title: '#ff1a1a',
        pink: '#ff85a2',
        clanLime: '#8ecc51'
    };

    const BULL = 7;
    const BOOSTER = 12;
    const MONKEY_TAIL = 11;
    const SOLDIER_HELMET = 6;
    const WINTER_CAP = 15;
    const TURRET_GEAR = 53;
    const MUSKET_ID = 15;
    const PIT_TRAP_ID = 15;

    const TICK_COOLDOWN = 135;

    // ==========================================
    // STATE VARIABLES
    // ==========================================
    let bullHat = false;
    let monkeyTail = false;
    let soldierHelmet = false;

    let userActiveHat = 0;
    let currentHatId = 0;
    let previousHatId = 0;
    let lastEquipTime = 0;

    let cameraZoom = 1.0;

    let predictMe = true;
    let predictPlayers = true;
    let predictMobs = true;
    let showBuildingOwners = true;

    let autoAimEnabled = true;
    let autoTrapEnabled = false;
    let lastTrapTime = 0;
    let isRightMouseDown = false;
    let isBreakingFast = false;
    let autoWindmillsEnabled = false;
    let isPlacingMills = false;

    let autoClanAccept = true;
    let killChatEnabled = true;
    let killChatMessage = localStorage.getItem('pcKillMsg') || 'PidorasiClient on top! GG';
    let myKills = 0;

    let autoHealEnabled = true;
    let myHealth = 100;
    let lastHealth = 100;
    let lastHealTime = 0;
    let isHealing = false;
    let isMouseDown = false;
    let isInstaShooting = false;

    // Плавный угол мыши без сетевых задержек
    let mouseX = window.innerWidth / 2;
    let mouseY = window.innerHeight / 2;
    let currentMouseAngle = 0;

    let autoBiomeHatEnabled = true;
    let isInWinter = false;

    window.myPlayer = { x: null, y: null, sid: null, team: null, dir: 0 };
    const nearbyEnemies = new Map();
    const nearbyMobs = new Map();
    const playerNames = new Map();
    const playerTeams = new Map();
    const placedBuildings = new Map();

    let activeSocket = null;
    let socketKey = null;
    let c2sTable = null;
    let s2cDecTable = {};
    let globalSeq = 0;
    let primaryWeapon = 0;
    let secondaryWeapon = 9;

    let cachedServers = [];
    let overlayCanvas = null;
    let overlayCtx = null;
    let currentTab = 'keybinds';

    // Keybinds Setup
    const DEFAULT_BINDS = {
        openMenu: 'ShiftRight',
        turretInsta: 'KeyT',
        instaMusket: 'KeyR',
        autoWindmills: 'KeyN',
        toggleAutoTrap: 'NONE',
        toggleHat: 'KeyV',
        toggleSoldier: 'KeyB',
        toggleTail: 'KeyC',
        toggleHeal: 'KeyH'
    };
    const userBinds = Object.assign({}, DEFAULT_BINDS, JSON.parse(localStorage.getItem('pcKeybinds') || '{}'));
    let rebindingAction = null;

    // ==========================================
    // DIRECT MOUSE TRACKING
    // ==========================================
    window.addEventListener('mousemove', (e) => {
        mouseX = e.clientX;
        mouseY = e.clientY;
        currentMouseAngle = Math.atan2(mouseY - (window.innerHeight / 2), mouseX - (window.innerWidth / 2));
    }, { capture: true, passive: true });

    window.addEventListener('mousedown', (e) => {
        if (e.button === 0) isMouseDown = true;
        if (e.button === 2) isRightMouseDown = true;
    }, { capture: true });

    window.addEventListener('mouseup', (e) => {
        if (e.button === 0) isMouseDown = false;
        if (e.button === 2) isRightMouseDown = false;
    }, { capture: true });

    // ==========================================
    // HELPER FUNCTIONS
    // ==========================================
    function sleep(ms) {
        return new Promise((resolve) => setTimeout(resolve, ms));
    }

    function saveBinds() {
        localStorage.setItem('pcKeybinds', JSON.stringify(userBinds));
    }

    function formatKey(code) {
        if (!code || code === 'NONE') return 'NONE';
        if (code.startsWith('Key')) return code.slice(3);
        if (code.startsWith('Digit')) return code.slice(5);
        if (code === 'ShiftRight') return 'R-Shift';
        if (code === 'ShiftLeft') return 'L-Shift';
        if (code === 'ControlRight') return 'R-Ctrl';
        if (code === 'ControlLeft') return 'L-Ctrl';
        if (code === 'AltRight') return 'R-Alt';
        if (code === 'AltLeft') return 'L-Alt';
        if (code === 'Backquote') return '~';
        return code;
    }

    function isPlayerInGame() {
        const gameUI = document.getElementById('gameUI');
        const diedText = document.getElementById('diedText');
        const mainMenu = document.getElementById('mainMenu');
        const isUIActive = gameUI && gameUI.style.display === 'block';
        const isDead = diedText && diedText.style.display === 'block';
        const isMenuHidden = mainMenu && (mainMenu.style.display === 'none' || mainMenu.classList.contains('hidden'));
        return isUIActive && !isDead && isMenuHidden;
    }

    function equipHat(id) {
        if (typeof window.storeEquip === 'function') {
            window.storeEquip(id, 0);
        }
    }

    function getFoodIndex() {
        const cheese = document.getElementById('actionBarItem18');
        if (cheese && cheese.style.display !== 'none') return 2;
        const cookie = document.getElementById('actionBarItem17');
        if (cookie && cookie.style.display !== 'none') return 1;
        return 0;
    }

    function getActiveSecondaryWeapon() {
        if (secondaryWeapon && secondaryWeapon >= 9) return secondaryWeapon;
        for (let id = 15; id >= 9; id--) {
            const el = document.getElementById('actionBarItem' + id);
            if (el && el.style.display !== 'none') return id;
        }
        return MUSKET_ID;
    }

    function getWindmillIndex() {
        const pm = document.getElementById('actionBarItem28');
        if (pm && pm.style.display !== 'none') return 12;
        const fm = document.getElementById('actionBarItem27');
        if (fm && fm.style.display !== 'none') return 11;
        return 10;
    }

    function getTrapIndex() {
        return PIT_TRAP_ID;
    }

    // ==========================================
    // CRYPTOGRAPHY & NETWORK PACKETS
    // ==========================================
    const bo = ["M", "D", "9", "e", "F", "z", "H", "K", "L", "N", "b", "P", "Q", "c", "6", "S", "0"];
    const To = ["A", "B", "C", "D", "E", "a", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "X", "Y", "Z", "g", "1", "2", "3", "4", "5", "6", "7", "8", "9", "0"];

    function Co(e) {
        return function () {
            e |= 0;
            e = e + 1831565813 | 0;
            let t = Math.imul(e ^ e >>> 15, 1 | e);
            return t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t,
            ((t ^ t >>> 14) >>> 0) / 4294967296;
        };
    }

    function Oi(e, t) {
        const i = e.length;
        const s = e.map((d, l) => l);
        const n = Co(t >>> 0);
        for (let d = i - 1; d > 0; d--) {
            const l = Math.floor(n() * (d + 1));
            const c = s[d];
            s[d] = s[l];
            s[l] = c;
        }
        const a = {};
        for (let d = 0; d < i; d++) a[e[d]] = s[d];
        return a;
    }

    function createTables(seed) {
        const t = (seed ^ Math.imul(1, 2654435761)) >>> 0;
        c2sTable = Oi(bo, t);

        const s2c_seed = (t ^ 2246822507) >>> 0;
        const s2c_len = To.length;
        const s = To.map((d, l) => l);
        const n = Co(s2c_seed);
        for (let d = s2c_len - 1; d > 0; d--) {
            const l = Math.floor(n() * (d + 1));
            const c = s[d];
            s[d] = s[l];
            s[l] = c;
        }
        s2cDecTable = {};
        for (let d = 0; d < s2c_len; d++) {
            s2cDecTable[s[d]] = To[d];
        }
    }

    function Ro(e) {
        const t = new Uint8Array(e.length / 2);
        for (let i = 0; i < t.length; i++) t[i] = parseInt(e.substr(i * 2, 2), 16);
        return t;
    }

    const Do = new Uint32Array([1116352408, 1899447441, 3049323471, 3921009573, 961987163, 1508970993, 2453635748, 2870763221, 3624381080, 310598401, 607225278, 1426881987, 1925078388, 2162078206, 2614888103, 3248222580, 3835390401, 4022224774, 264347078, 604807628, 770255983, 1249150122, 1555081692, 1996064986, 2554220882, 2821834349, 2952996808, 3210313671, 3336571891, 3584528711, 113926993, 338241895, 666307205, 773529912, 1294757372, 1396182291, 1695183700, 1986661051, 2177026350, 2456956037, 2730485921, 2820302411, 3259730800, 3345764771, 3516065817, 3600352804, 4094571909, 275423344, 430227734, 506948616, 659060556, 883997877, 958139571, 1322822218, 1537002063, 1747873779, 1955562222, 2024104815, 2227730452, 2361852424, 2428436474, 2756734187, 3204031479, 3329325298]);
    function j(e, t) { return e >>> t | e << 32 - t; }

    function Vt(e) {
        const t = new Uint32Array([1779033703, 3144134277, 1013904242, 2773480762, 1359893119, 2600822924, 528734635, 1541459225]);
        const i = e.length, s = i * 8, n = i + 9, a = new Uint8Array(Math.ceil(n / 64) * 64);
        a.set(e); a[i] = 128;
        const o = new DataView(a.buffer);
        o.setUint32(a.length - 4, s >>> 0, !1);
        o.setUint32(a.length - 8, Math.floor(s / 4294967296), !1);
        const d = new Uint32Array(64);
        for (let m = 0; m < a.length; m += 64) {
            for (let w = 0; w < 16; w++) d[w] = o.getUint32(m + w * 4, !1);
            for (let w = 16; w < 64; w++) {
                const T = j(d[w - 15], 7) ^ j(d[w - 15], 18) ^ d[w - 15] >>> 3;
                const A = j(d[w - 2], 17) ^ j(d[w - 2], 19) ^ d[w - 2] >>> 10;
                d[w] = d[w - 16] + T + d[w - 7] + A | 0;
            }
            let g = t[0], h = t[1], u = t[2], p = t[3], x = t[4], I = t[5], P = t[6], f = t[7];
            for (let w = 0; w < 64; w++) {
                const T = j(x, 6) ^ j(x, 11) ^ j(x, 25);
                const A = x & I ^ ~x & P;
                const V = f + T + A + Do[w] + d[w] | 0;
                const W = j(g, 2) ^ j(g, 13) ^ j(g, 22);
                const S = g & h ^ g & u ^ h & u;
                const H = W + S | 0;
                f = P; P = I; I = x; x = p + V | 0; p = u; u = h; h = g; g = V + H | 0;
            }
            t[0] = t[0] + g | 0; t[1] = t[1] + h | 0; t[2] = t[2] + u | 0; t[3] = t[3] + p | 0;
            t[4] = t[4] + x | 0; t[5] = t[5] + I | 0; t[6] = t[6] + P | 0; t[7] = t[7] + f | 0;
        }
        const l = new Uint8Array(32), c = new DataView(l.buffer);
        for (let m = 0; m < 8; m++) c.setUint32(m * 4, t[m], !1);
        return l;
    }

    function Ao(e, t) {
        let i = e;
        if (i.length > 64) i = Vt(i);
        const s = new Uint8Array(64); s.set(i);
        const n = new Uint8Array(64 + t.length), a = new Uint8Array(64 + 32);
        for (let o = 0; o < 64; o++) { n[o] = s[o] ^ 54; a[o] = s[o] ^ 92; }
        n.set(t, 64);
        a.set(Vt(n), 64);
        return Vt(a);
    }

    function Eo(e, t) { return Ao(e, t).subarray(0, 6); }

    function encodeSeq(seq) {
        if (seq < 128) {
            return new Uint8Array([seq]);
        } else if (seq < 256) {
            return new Uint8Array([0xcc, seq]);
        } else if (seq < 65536) {
            return new Uint8Array([0xcd, (seq >> 8) & 0xff, seq & 0xff]);
        } else {
            return new Uint8Array([0xce, (seq >> 24) & 0xff, (seq >> 16) & 0xff, (seq >> 8) & 0xff, seq & 0xff]);
        }
    }

    function handleIncomingData(ws, rawData) {
        try {
            if (rawData && typeof msgpack !== 'undefined') {
                const u8 = new Uint8Array(rawData);
                const decoded = msgpack.decode(u8);
                if (!decoded) return;

                const packetCode = decoded[0];
                const packetArgs = decoded[1];

                if (packetCode === "io-init") {
                    activeSocket = ws;
                    nearbyEnemies.clear();
                    nearbyMobs.clear();
                    placedBuildings.clear();
                    playerNames.clear();
                    playerTeams.clear();
                    myKills = 0;
                    const g = packetArgs;
                    if (g && g[3] === 1) {
                        socketKey = Ro(g[2]);
                        createTables(g[1] >>> 0);
                        globalSeq = 0;
                    }
                    return;
                }

                const opName = typeof packetCode === 'number' ? s2cDecTable[packetCode] : packetCode;

                if (opName === "C") {
                    window.myPlayer.sid = packetArgs[0];
                } else if (opName === "D") {
                    if (packetArgs[1]) {
                        window.myPlayer.sid = packetArgs[0][1];
                    }
                    if (packetArgs[0] && packetArgs[0][1] && packetArgs[0][2]) {
                        playerNames.set(packetArgs[0][1], packetArgs[0][2]);
                    }
                } else if (opName === "V") {
                    if (packetArgs[1]) {
                        const weapons = packetArgs[0];
                        if (Array.isArray(weapons)) {
                            if (weapons[0] !== undefined) primaryWeapon = weapons[0];
                            if (weapons[1] !== undefined) secondaryWeapon = weapons[1];
                        }
                    }
                } else if (opName === "3") {
                    window.myPlayer.team = packetArgs[0];
                } else if (opName === "2") {
                    // Auto-Clan Join Request Handler
                    if (autoClanAccept && packetArgs && packetArgs[0]) {
                        const requesterSid = packetArgs[0];
                        sendDirectPacket("P", [requesterSid, 1]);
                    }
                } else if (opName === "N") {
                    // Resource & Kill Tracker
                    if (packetArgs && packetArgs[0] === "kills") {
                        const newKills = packetArgs[1];
                        if (typeof newKills === 'number' && newKills > myKills) {
                            myKills = newKills;
                            if (killChatEnabled && killChatMessage) {
                                sendDirectPacket("6", [killChatMessage.slice(0, 30)]);
                            }
                        }
                    }
                } else if (opName === "P") {
                    nearbyEnemies.clear();
                    nearbyMobs.clear();
                    autoWindmillsEnabled = false;
                    myKills = 0;
                } else if (opName === "a") {
                    const data = packetArgs[0];
                    if (Array.isArray(data)) {
                        const activeSids = new Set();
                        for (let i = 0; i < data.length; i += 13) {
                            const sid = data[i];
                            const x = data[i + 1];
                            const y = data[i + 2];
                            const dir = data[i + 3];
                            const team = data[i + 7];
                            const skinId = data[i + 9];

                            activeSids.add(sid);
                            if (team) playerTeams.set(sid, team);

                            if (sid === window.myPlayer.sid) {
                                window.myPlayer.x = x;
                                window.myPlayer.y = y;
                                window.myPlayer.dir = dir;
                                checkBiome();

                                if (!isInstaShooting && skinId !== BULL && skinId !== TURRET_GEAR && skinId !== WINTER_CAP) {
                                    userActiveHat = skinId;
                                    currentHatId = skinId;
                                }
                            } else {
                                nearbyEnemies.set(sid, {
                                    x, y, dir, team,
                                    isTeammate: Boolean(window.myPlayer.team && team === window.myPlayer.team),
                                    lastSeen: Date.now()
                                });
                            }
                        }

                        for (const sid of nearbyEnemies.keys()) {
                            if (!activeSids.has(sid)) nearbyEnemies.delete(sid);
                        }
                    }
                } else if (opName === "I") {
                    const data = packetArgs[0];
                    if (Array.isArray(data)) {
                        const activeMobSids = new Set();
                        for (let i = 0; i < data.length; i += 7) {
                            const sid = data[i];
                            const x = data[i + 2];
                            const y = data[i + 3];
                            const dir = data[i + 4];

                            activeMobSids.add(sid);
                            nearbyMobs.set(sid, { x, y, dir, lastSeen: Date.now() });
                        }

                        for (const sid of nearbyMobs.keys()) {
                            if (!activeMobSids.has(sid)) nearbyMobs.delete(sid);
                        }
                    }
                } else if (opName === "H") {
                    const data = packetArgs[0];
                    if (Array.isArray(data)) {
                        for (let i = 0; i < data.length; i += 8) {
                            const objSid = data[i];
                            const x = data[i + 1];
                            const y = data[i + 2];
                            const ownerSid = data[i + 7];
                            if (ownerSid >= 0) {
                                placedBuildings.set(objSid, { x, y, ownerSid });
                            }
                        }
                    }
                } else if (opName === "Q") {
                    placedBuildings.delete(packetArgs[0]);
                } else if (opName === "R") {
                    const ownerSid = packetArgs[0];
                    for (const [sid, obj] of placedBuildings.entries()) {
                        if (obj.ownerSid === ownerSid) placedBuildings.delete(sid);
                    }
                }
            }
        } catch (e) {}
    }

    const nativeSend = WebSocket.prototype.send;
    WebSocket.prototype.send = function (data) {
        if (this.readyState === WebSocket.OPEN) {
            activeSocket = this;
        }

        if (data instanceof Uint8Array || data instanceof ArrayBuffer) {
            const u8 = new Uint8Array(data);
            if (u8.length > 6 && socketKey && c2sTable) {
                try {
                    const payload = u8.subarray(6);
                    const decoded = msgpack.decode(payload);

                    if (Array.isArray(decoded) && typeof decoded[2] === 'number') {
                        if (decoded[2] <= globalSeq) {
                            globalSeq++;

                            const oldSeq = decoded[2];
                            const oldSeqLen = oldSeq < 128 ? 1 : (oldSeq < 256 ? 2 : (oldSeq < 65536 ? 3 : 5));
                            const basePayload = payload.subarray(0, payload.length - oldSeqLen);
                            const newSeqBytes = encodeSeq(globalSeq);

                            const newPayload = new Uint8Array(basePayload.length + newSeqBytes.length);
                            newPayload.set(basePayload, 0);
                            newPayload.set(newSeqBytes, basePayload.length);

                            const newHmac = Eo(socketKey, newPayload);
                            const newBuf = new Uint8Array(6 + newPayload.length);
                            newBuf.set(newHmac, 0);
                            newBuf.set(newPayload, 6);
                            return nativeSend.call(this, newBuf);
                        } else {
                            globalSeq = decoded[2];
                        }

                        if (decoded[0] === c2sTable["c"]) {
                            const args = decoded[1];
                            if (args && args[0] === 0 && args[2] === 0 && !isInstaShooting) {
                                userActiveHat = args[1];
                                currentHatId = args[1];
                            }
                        }

                        if (decoded[0] === c2sTable["z"]) {
                            const args = decoded[1];
                            if (args && (args[1] === true || args[1] === 1)) {
                                if (args[0] < 9) {
                                    primaryWeapon = args[0];
                                } else {
                                    secondaryWeapon = args[0];
                                }
                            }
                        }
                    }
                } catch (e) {}
            }
        }
        return nativeSend.apply(this, arguments);
    };

    try {
        const desc = Object.getOwnPropertyDescriptor(WebSocket.prototype, 'onmessage');
        Object.defineProperty(WebSocket.prototype, 'onmessage', {
            configurable: true,
            enumerable: true,
            get: function () {
                return desc ? desc.get.call(this) : this._customOnMessage;
            },
            set: function (fn) {
                const wrapped = (event) => {
                    handleIncomingData(this, event.data);
                    if (typeof fn === 'function') fn.call(this, event);
                };
                this._customOnMessage = wrapped;
                if (desc && desc.set) {
                    desc.set.call(this, wrapped);
                } else {
                    this.addEventListener('message', wrapped);
                }
            }
        });
    } catch (e) {}

    const nativeAddEventListener = WebSocket.prototype.addEventListener;
    WebSocket.prototype.addEventListener = function (type, listener, options) {
        if (type === 'message') {
            const wrapped = (event) => {
                handleIncomingData(this, event.data);
                if (typeof listener === 'function') listener.call(this, event);
            };
            return nativeAddEventListener.call(this, type, wrapped, options);
        }
        return nativeAddEventListener.apply(this, arguments);
    };

    function sendDirectPacket(type, argsArray) {
        if (!activeSocket || activeSocket.readyState !== WebSocket.OPEN) return;
        if (!c2sTable || !socketKey) return;
        try {
            const opcode = c2sTable[type];
            if (opcode === undefined) return;
            globalSeq++;

            let rawEncoded = msgpack.encode([opcode, argsArray, globalSeq]);
            const payload = rawEncoded instanceof Uint8Array ? rawEncoded : new Uint8Array(rawEncoded.buffer || rawEncoded);

            const hmac = Eo(socketKey, payload);
            const fullBuf = new Uint8Array(6 + payload.length);
            fullBuf.set(hmac, 0);
            fullBuf.set(payload, 6);

            nativeSend.call(activeSocket, fullBuf);
        } catch (e) {}
    }

    // ==========================================
    // AUTO-AIM ALGORITHM (REFINED)
    // ==========================================
    function getAutoAimTargetAngle() {
        if (!autoAimEnabled || typeof window.myPlayer.x !== 'number') return currentMouseAngle;

        const myX = window.myPlayer.x;
        const myY = window.myPlayer.y;

        let closestTarget = null;
        let closestDist = Infinity;

        for (const [sid, p] of nearbyEnemies.entries()) {
            if (p.isTeammate || Date.now() - p.lastSeen > 650) continue;

            const dx = p.x - myX;
            const dy = p.y - myY;
            const dist = Math.hypot(dx, dy);

            // Радиус поиска цели (до 600 юнитов)
            if (dist <= 600 && dist < closestDist) {
                closestDist = dist;
                closestTarget = p;
            }
        }

        if (closestTarget) {
            return Math.atan2(closestTarget.y - myY, closestTarget.x - myX);
        }

        return currentMouseAngle;
    }

    // ==========================================
    // COMBAT & AUTOMATION ENGINES
    // ==========================================
    async function executeFastInstaCombo() {
        if (isInstaShooting || !isPlayerInGame()) return;
        isInstaShooting = true;

        try {
            const secWep = getActiveSecondaryWeapon();
            const hatToRestore = userActiveHat;
            const shootAngle = getAutoAimTargetAngle();

            equipHat(BULL);
            sendDirectPacket("D", [shootAngle]);
            sendDirectPacket("z", [secWep, true]);
            sendDirectPacket("F", [1, shootAngle]);

            await sleep(115);

            sendDirectPacket("F", [0, shootAngle]);
            sendDirectPacket("z", [primaryWeapon, true]);

            sendDirectPacket("F", [1, shootAngle]);
            await sleep(35);
            sendDirectPacket("F", [0, shootAngle]);

            equipHat(isInWinter ? WINTER_CAP : (hatToRestore || 0));
            currentHatId = isInWinter ? WINTER_CAP : (hatToRestore || 0);

            if (isMouseDown) {
                await sleep(15);
                sendDirectPacket("F", [1, currentMouseAngle]);
            }
        } catch (err) {
        } finally {
            isInstaShooting = false;
        }
    }

    async function executeTurretInstaCombo() {
        if (isInstaShooting || !isPlayerInGame()) return;
        isInstaShooting = true;

        try {
            const secWep = getActiveSecondaryWeapon();
            const hatToRestore = userActiveHat;
            const shootAngle = getAutoAimTargetAngle();

            equipHat(TURRET_GEAR);
            sendDirectPacket("D", [shootAngle]);
            sendDirectPacket("z", [secWep, true]);
            sendDirectPacket("F", [1, shootAngle]);

            await sleep(115);

            sendDirectPacket("F", [0, shootAngle]);
            sendDirectPacket("z", [primaryWeapon, true]);

            sendDirectPacket("F", [1, shootAngle]);
            await sleep(35);
            sendDirectPacket("F", [0, shootAngle]);

            equipHat(isInWinter ? WINTER_CAP : (hatToRestore || 0));
            currentHatId = isInWinter ? WINTER_CAP : (hatToRestore || 0);

            if (isMouseDown) {
                await sleep(15);
                sendDirectPacket("F", [1, currentMouseAngle]);
            }
        } catch (err) {
        } finally {
            isInstaShooting = false;
        }
    }

    async function executeAutoTrap() {
        if (!autoTrapEnabled || isPlacingMills || isInstaShooting || isHealing || isBreakingFast || !isPlayerInGame()) return;
        const now = Date.now();
        if (now - lastTrapTime < 300) return;

        const myX = window.myPlayer.x;
        const myY = window.myPlayer.y;
        if (typeof myX !== 'number') return;

        const trapId = getTrapIndex();

        for (const [sid, p] of nearbyEnemies.entries()) {
            if (p.isTeammate || Date.now() - p.lastSeen > 600) continue;
            const dx = p.x - myX;
            const dy = p.y - myY;
            const dist = Math.hypot(dx, dy);

            if (dist <= 175 && dist >= 45) {
                lastTrapTime = now;
                const angle = Math.atan2(dy, dx);
                sendDirectPacket("z", [trapId, false]);
                sendDirectPacket("F", [1, angle]);
                sendDirectPacket("F", [0, angle]);
                sendDirectPacket("z", [primaryWeapon, true]);

                if (isMouseDown) {
                    sendDirectPacket("F", [1, null]);
                }
                break;
            }
        }
    }

    async function executeFastBreak() {
        if (isBreakingFast || isHealing || isInstaShooting || !isPlayerInGame()) return;
        isBreakingFast = true;

        try {
            sendDirectPacket("D", [currentMouseAngle]);
            sendDirectPacket("F", [1, null]);
            await sleep(25);
            sendDirectPacket("F", [0, null]);
            await sleep(25);
        } catch (e) {
        } finally {
            isBreakingFast = false;
        }
    }

    async function placeSingleWindmill(millId, angle) {
        sendDirectPacket("z", [millId, false]);
        await sleep(12);
        sendDirectPacket("F", [1, angle]);
        await sleep(12);
        sendDirectPacket("F", [0, angle]);
    }

    async function executeDenseWindmills() {
        if (!autoWindmillsEnabled || isPlacingMills || isHealing || isInstaShooting || !isPlayerInGame()) return;
        isPlacingMills = true;

        try {
            const millId = getWindmillIndex();
            const back = currentMouseAngle + Math.PI;

            const angles = [back - 1.05, back - 0.35, back + 0.35, back + 1.05];

            for (const ang of angles) {
                await placeSingleWindmill(millId, ang);
                await sleep(10);
            }

            sendDirectPacket("z", [primaryWeapon, true]);

            if (isMouseDown) {
                await sleep(15);
                sendDirectPacket("F", [1, null]);
            }

            await sleep(100);
        } catch (e) {
        } finally {
            isPlacingMills = false;
        }
    }

    async function executeHeal(count) {
        if (isHealing) return;
        isHealing = true;

        try {
            const foodIdx = getFoodIndex();

            for (let i = 0; i < count; i++) {
                sendDirectPacket("z", [foodIdx, false]);
                await sleep(25);

                sendDirectPacket("F", [1, currentMouseAngle]);
                await sleep(25);

                sendDirectPacket("F", [0, currentMouseAngle]);
                await sleep(25);

                sendDirectPacket("z", [primaryWeapon, true]);

                if (isMouseDown) {
                    await sleep(15);
                    sendDirectPacket("F", [1, null]);
                }

                if (i < count - 1) {
                    await sleep(TICK_COOLDOWN);
                }
            }
        } catch (err) {
        } finally {
            isHealing = false;
        }
    }

    function triggerHeal(dmg) {
        const now = Date.now();
        if (now - lastHealTime < TICK_COOLDOWN || isHealing) return;
        lastHealTime = now;

        const count = Math.min(2, Math.max(1, Math.ceil(dmg / 25)));
        executeHeal(count);
    }

    function onHealthDetected(currentHp) {
        myHealth = currentHp;

        if (currentHp < lastHealth && currentHp > 0) {
            const dmg = lastHealth - currentHp;
            if (autoHealEnabled && dmg >= 4) {
                triggerHeal(dmg);
            }
        }
        lastHealth = currentHp;
    }

    // ==========================================
    // CANVAS HOOKS
    // ==========================================
    try {
        let _nativeRoundRect = CanvasRenderingContext2D.prototype.roundRect;
        Object.defineProperty(CanvasRenderingContext2D.prototype, 'roundRect', {
            get: function () {
                return function (x, y, w, h, r) {
                    if (this.canvas && this.canvas.id === 'gameCanvas' && h <= 18) {
                        const fs = String(this.fillStyle).toLowerCase();
                        if (fs === '#8ecc51' || fs === 'rgb(142, 204, 81)' || fs === '#4bb6c4') {
                            const hp = Math.max(0, Math.min(100, Math.round(w)));
                            onHealthDetected(hp);
                        }
                    }
                    if (typeof _nativeRoundRect === 'function') {
                        return _nativeRoundRect.apply(this, arguments);
                    }
                };
            },
            set: function (fn) {
                _nativeRoundRect = fn;
            },
            configurable: true
        });
    } catch (e) {}

    const origSetTransform = CanvasRenderingContext2D.prototype.setTransform;
    CanvasRenderingContext2D.prototype.setTransform = function (a, b, c, d, e, f) {
        if (this.canvas && this.canvas.id === 'gameCanvas' && arguments.length === 6) {
            a *= cameraZoom;
            d *= cameraZoom;
            e = (this.canvas.width - 1920 * a) / 2;
            f = (this.canvas.height - 1080 * d) / 2;
        }
        return origSetTransform.call(this, a, b, c, d, e, f);
    };

    function applyZoom() {
        const canvas = document.getElementById('gameCanvas');
        if (!canvas) return;
        const ctx = canvas.getContext('2d');
        if (!ctx) return;

        const cw = canvas.width || (window.innerWidth * (window.devicePixelRatio || 1));
        const ch = canvas.height || (window.innerHeight * (window.devicePixelRatio || 1));
        const De = window.innerWidth;
        const Ae = window.innerHeight;
        const Pe = window.devicePixelRatio || 1;

        const baseScale = Math.max(De / 1920, Ae / 1080) * Pe;
        const e = baseScale * cameraZoom;

        origSetTransform.call(ctx, e, 0, 0, e, (cw - 1920 * e) / 2, (ch - 1080 * e) / 2);
    }

    const origClearRect = CanvasRenderingContext2D.prototype.clearRect;
    CanvasRenderingContext2D.prototype.clearRect = function (x, y, w, h) {
        origClearRect.apply(this, arguments);

        if (this.canvas && this.canvas.id === 'mapDisplay') {
            const cw = this.canvas.width || 300;
            const ch = this.canvas.height || 300;

            const snowH = (2400 / 14400) * ch;
            this.fillStyle = 'rgba(255, 255, 255, 0.45)';
            this.fillRect(0, 0, cw, snowH);

            const riverY = (6838 / 14400) * ch;
            const riverH = (724 / 14400) * ch;
            this.fillStyle = 'rgba(80, 155, 235, 0.55)';
            this.fillRect(0, riverY, cw, riverH);

            const desertY = (12000 / 14400) * ch;
            const desertH = ch - desertY;
            this.fillStyle = 'rgba(195, 140, 75, 0.45)';
            this.fillRect(0, desertY, cw, desertH);

            if (nearbyEnemies.size > 0) {
                this.save();
                for (const [sid, enemy] of nearbyEnemies.entries()) {
                    if (Date.now() - enemy.lastSeen > 1200 || enemy.isTeammate) continue;
                    const ex = (enemy.x / 14400) * cw;
                    const ey = (enemy.y / 14400) * ch;

                    this.beginPath();
                    this.arc(ex, ey, 5.5, 0, 2 * Math.PI);
                    this.fillStyle = '#ff2a2a';
                    this.fill();
                    this.lineWidth = 1.5;
                    this.strokeStyle = '#ffffff';
                    this.stroke();
                }
                this.restore();
            }
        }
    };

    function checkBiome() {
        if (!autoBiomeHatEnabled || typeof window.myPlayer.y !== 'number' || !isPlayerInGame()) return;

        const now = Date.now();
        if (now - lastEquipTime < 200) return;

        const isSnowZone = window.myPlayer.y < 2400;

        if (isSnowZone) {
            isInWinter = true;
            if (currentHatId !== WINTER_CAP) {
                previousHatId = userActiveHat;
                currentHatId = WINTER_CAP;
                equipHat(WINTER_CAP);
                lastEquipTime = now;
                updateStatus();
            }
        } else {
            isInWinter = false;
            if (currentHatId === WINTER_CAP) {
                currentHatId = userActiveHat || previousHatId || 0;
                equipHat(currentHatId);
                lastEquipTime = now;
                updateStatus();
            }
        }
    }

    // ==========================================
    // OVERLAY ENGINE (PREDICTIONS)
    // ==========================================
    function resizeOverlay() {
        if (!overlayCanvas) return;
        overlayCanvas.width = window.innerWidth;
        overlayCanvas.height = window.innerHeight;
    }
    window.addEventListener('resize', resizeOverlay, true);

    function initOverlayCanvas() {
        if (overlayCanvas) return;
        overlayCanvas = document.createElement('canvas');
        overlayCanvas.id = 'pc-predict-overlay';
        overlayCanvas.style.cssText = `
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            pointer-events: none;
            z-index: 10;
        `;
        document.body.appendChild(overlayCanvas);
        overlayCtx = overlayCanvas.getContext('2d');
        resizeOverlay();
    }

    function drawPredictLine(ctx, sx, sy, dir, length, color, dotColor) {
        const ex = sx + Math.cos(dir) * length;
        const ey = sy + Math.sin(dir) * length;

        ctx.save();
        ctx.beginPath();
        ctx.moveTo(sx, sy);
        ctx.lineTo(ex, ey);
        ctx.strokeStyle = color;
        ctx.lineWidth = 2.5;
        ctx.setLineDash([7, 4]);
        ctx.stroke();

        ctx.setLineDash([]);
        ctx.beginPath();
        ctx.arc(ex, ey, 4.5, 0, 2 * Math.PI);
        ctx.fillStyle = dotColor || color;
        ctx.fill();
        ctx.lineWidth = 1.5;
        ctx.strokeStyle = '#ffffff';
        ctx.stroke();
        ctx.restore();
    }

    function renderPredictLoop() {
        if (overlayCtx && overlayCanvas) {
            overlayCtx.clearRect(0, 0, overlayCanvas.width, overlayCanvas.height);

            if (isPlayerInGame() && typeof window.myPlayer.x === 'number') {
                const cx = overlayCanvas.width / 2;
                const cy = overlayCanvas.height / 2;
                const myX = window.myPlayer.x;
                const myY = window.myPlayer.y;

                const baseScale = Math.max(overlayCanvas.width / 1920, overlayCanvas.height / 1080);
                const scale = baseScale * cameraZoom;

                // Линия игрока
                if (predictMe) {
                    drawPredictLine(overlayCtx, cx, cy, currentMouseAngle, 130 * scale, 'rgba(255, 77, 109, 0.95)', '#27c93f');
                }

                // Линии врагов
                if (predictPlayers) {
                    for (const [sid, p] of nearbyEnemies.entries()) {
                        if (Date.now() - p.lastSeen > 800) continue;
                        const screenX = cx + (p.x - myX) * scale;
                        const screenY = cy + (p.y - myY) * scale;
                        const color = p.isTeammate ? 'rgba(75, 182, 196, 0.9)' : 'rgba(255, 42, 42, 0.95)';
                        drawPredictLine(overlayCtx, screenX, screenY, p.dir, 120 * scale, color, '#ffffff');
                    }
                }

                // Линии мобов
                if (predictMobs) {
                    for (const [sid, m] of nearbyMobs.entries()) {
                        if (Date.now() - m.lastSeen > 800) continue;
                        const screenX = cx + (m.x - myX) * scale;
                        const screenY = cy + (m.y - myY) * scale;
                        drawPredictLine(overlayCtx, screenX, screenY, m.dir, 95 * scale, 'rgba(255, 189, 46, 0.9)', '#ffbd2e');
                    }
                }

                // Владельцы построек
                if (showBuildingOwners && placedBuildings.size > 0) {
                    overlayCtx.save();
                    overlayCtx.font = `bold ${Math.max(10, Math.round(13 * scale))}px 'Hammersmith One', Arial, sans-serif`;
                    overlayCtx.textAlign = 'center';
                    overlayCtx.textBaseline = 'middle';

                    for (const [sid, bldg] of placedBuildings.entries()) {
                        const screenX = cx + (bldg.x - myX) * scale;
                        const screenY = cy + (bldg.y - myY) * scale;

                        if (screenX >= -50 && screenX <= overlayCanvas.width + 50 && screenY >= -50 && screenY <= overlayCanvas.height + 50) {
                            const isSelf = bldg.ownerSid === window.myPlayer.sid;
                            const isClan = isSelf || (window.myPlayer.team && playerTeams.get(bldg.ownerSid) === window.myPlayer.team);
                            const rawName = playerNames.get(bldg.ownerSid) || (isSelf ? 'YOU' : `[ID:${bldg.ownerSid}]`);

                            if (isClan) {
                                overlayCtx.fillStyle = THEME.clanLime;
                                overlayCtx.fillText(`[CLAN MEMBER] ${rawName}`, screenX, screenY - 22 * scale);
                            } else {
                                overlayCtx.fillStyle = 'rgba(255, 255, 255, 0.45)';
                                overlayCtx.fillText(rawName, screenX, screenY - 22 * scale);
                            }
                        }
                    }
                    overlayCtx.restore();
                }
            }
        }

        if (autoTrapEnabled) {
            executeAutoTrap();
        }

        if (autoWindmillsEnabled) {
            executeDenseWindmills();
        }

        if (isRightMouseDown && !isMouseDown) {
            executeFastBreak();
        }

        requestAnimationFrame(renderPredictLoop);
    }

    // ==========================================
    // SERVER FETCHER & UI
    // ==========================================
    function renderServerListUI() {
        const listContainer = document.getElementById('pc-server-list');
        if (!listContainer || cachedServers.length === 0) return;

        const byPlayers = [...cachedServers].sort((a, b) => b.players - a.players).slice(0, 3);
        const playerVals = new Set(byPlayers.map(s => s.val));

        const byPing = [...cachedServers]
            .filter(s => !playerVals.has(s.val))
            .sort((a, b) => a.ping - b.ping)
            .slice(0, 3);
        const pingVals = new Set(byPing.map(s => s.val));

        const others = cachedServers.filter(s => !playerVals.has(s.val) && !pingVals.has(s.val));

        const renderItem = (s) => `
            <div class="pc-server-item ${s.selected ? 'active' : ''}" data-val="${s.val}" style="
                display: flex; justify-content: space-between; align-items: center;
                background: ${s.selected ? 'rgba(255, 42, 42, 0.35)' : 'rgba(0, 0, 0, 0.35)'};
                border: 1px solid ${s.selected ? '#ff4d6d' : 'rgba(255, 42, 42, 0.2)'};
                padding: 6px 8px; border-radius: 6px; cursor: pointer; transition: 0.15s; font-size: 11px;
            ">
                <div style="font-weight: bold; color: ${s.selected ? '#fff' : THEME.text};">${s.name}</div>
                <div style="display: flex; gap: 8px; font-size: 10px;">
                    <span style="color: ${s.players >= s.max ? '#ff4d6d' : '#fff'}">[${s.players}/${s.max}]</span>
                    <span style="color: ${s.ping < 80 ? '#27c93f' : s.ping < 150 ? '#ffbd2e' : '#ff5f56'}">${s.ping !== 999 ? s.ping + 'ms' : '?'}</span>
                </div>
            </div>
        `;

        listContainer.innerHTML = `
            <div style="font-size: 10px; font-weight: bold; color: rgba(255,255,255,0.5); letter-spacing: 1px;">// BY PLAYERS</div>
            ${byPlayers.map(renderItem).join('')}

            <div style="font-size: 10px; font-weight: bold; color: rgba(255,255,255,0.5); letter-spacing: 1px; margin-top: 6px;">// LOWEST PING</div>
            ${byPing.map(renderItem).join('')}

            ${others.length > 0 ? `
                <div style="font-size: 10px; font-weight: bold; color: rgba(255,255,255,0.5); letter-spacing: 1px; margin-top: 6px;">// ALL SERVERS</div>
                ${others.map(renderItem).join('')}
            ` : ''}
        `;

        listContainer.querySelectorAll('.pc-server-item').forEach(item => {
            item.addEventListener('click', () => {
                const targetVal = item.getAttribute('data-val');
                const select = document.querySelector('#serverBrowser select');
                if (select) {
                    select.value = targetVal;
                    select.dispatchEvent(new Event('change', { bubbles: true }));
                }
                window.location.href = `/?server=${encodeURIComponent(targetVal)}`;
            });
        });
    }

    function parseFromSelectFallback() {
        const select = document.querySelector('#serverBrowser select');
        if (!select) return;
        const options = Array.from(select.options);
        if (options.length === 0) return;

        cachedServers = options.filter(opt => opt.value && !opt.disabled).map(opt => {
            const text = opt.textContent || '';
            const match = text.match(/^(.*?)\s*\[(\d+)\/(\d+)\](?:\s*\[(\d+)ms\])?/);
            return {
                val: opt.value,
                name: match ? match[1].trim() : opt.value,
                players: match ? parseInt(match[2]) || 0 : 0,
                max: match ? parseInt(match[3]) || 40 : 40,
                ping: match && match[4] ? parseInt(match[4]) : 999,
                selected: opt.selected
            };
        });

        renderServerListUI();
    }

    async function loadServersFromApi() {
        const isSandbox = location.hostname.includes('sandbox');
        const apiUrl = isSandbox ? 'https://api-sandbox.moomoo.io/servers?v=1.27' : 'https://api.moomoo.io/servers?v=1.27';

        try {
            const res = await fetch(apiUrl);
            const data = await res.json();
            const urlParams = new URLSearchParams(window.location.search);
            const currentSelected = urlParams.get('server') || 'frankfurt:AZ';

            const parsedList = [];
            data.forEach(s => {
                let cleanRegion = (s.region || '').replace(/^(vultr|do):/, '');
                let totalPlayers = typeof s.playerCount === 'number' ? s.playerCount : 0;
                let maxPlayers = s.playerCapacity || 40;

                if (Array.isArray(s.games)) {
                    s.games.forEach(g => {
                        totalPlayers = Math.max(totalPlayers, g.playerCount || 0);
                        maxPlayers = g.playerCapacity || maxPlayers;
                    });
                }

                parsedList.push({
                    val: `${s.region}:${s.name}`,
                    name: `${cleanRegion.toUpperCase()} ${s.name}`,
                    region: cleanRegion,
                    players: totalPlayers,
                    max: maxPlayers,
                    ping: s.ping || (cleanRegion.includes('frankfurt') ? 45 : (cleanRegion.includes('us') ? 95 : 140)),
                    selected: currentSelected === `${s.region}:${s.name}`
                });
            });

            cachedServers = parsedList;
            renderServerListUI();
        } catch (err) {
            parseFromSelectFallback();
        }
    }

    function toggleHat() {
        if (typeof window.storeEquip !== 'function') return;
        soldierHelmet = false;
        bullHat = !bullHat;
        const target = bullHat ? BULL : BOOSTER;
        userActiveHat = target;
        currentHatId = target;
        previousHatId = target;
        equipHat(target);
        updateStatus();
    }

    function toggleSoldierHelmet() {
        if (typeof window.storeEquip !== 'function') return;
        soldierHelmet = !soldierHelmet;
        const target = soldierHelmet ? SOLDIER_HELMET : 0;
        userActiveHat = target;
        currentHatId = target;
        previousHatId = target;
        equipHat(target);
        updateStatus();
    }

    function toggleMonkeyTail() {
        if (typeof window.storeEquip !== 'function') return;
        monkeyTail = !monkeyTail;
        const target = monkeyTail ? MONKEY_TAIL : 0;
        window.storeEquip(target, 1);
        updateStatus();
    }

    function updateCoordDisplay() {
        let element = document.getElementById('pc-coords-box');
        const leaderboard = document.getElementById('leaderboard');

        if (!isPlayerInGame() || !leaderboard) {
            if (element) element.style.display = 'none';
            return;
        }

        if (!element) {
            element = document.createElement('div');
            element.id = 'pc-coords-box';
            element.style.cssText = `
                position: fixed;
                z-index: 99999;
                background: ${THEME.bg};
                backdrop-filter: ${THEME.blur};
                -webkit-backdrop-filter: ${THEME.blur};
                color: #fff;
                padding: 6px 10px;
                border-radius: 8px;
                border: ${THEME.border};
                box-shadow: ${THEME.shadow};
                font-family: 'Hammersmith One', Arial, sans-serif;
                text-align: center;
                pointer-events: none;
                box-sizing: border-box;
                letter-spacing: 0.5px;
            `;
            document.body.appendChild(element);
        }

        element.style.display = 'block';
        const rect = leaderboard.getBoundingClientRect();
        element.style.top = (rect.bottom + 65) + 'px';
        element.style.right = (window.innerWidth - rect.right) + 'px';
        element.style.width = rect.width + 'px';

        const x = typeof window.myPlayer.x === 'number' ? window.myPlayer.x : '—';
        const y = typeof window.myPlayer.y === 'number' ? window.myPlayer.y : '—';

        let biome = '🌲 PLAINS';
        let biomeColor = '#b4db62';
        if (typeof window.myPlayer.y === 'number') {
            if (window.myPlayer.y < 2400) { biome = '❄️ SNOW'; biomeColor = '#a8e6cf'; }
            else if (window.myPlayer.y > 12000) { biome = '🏜️ DESERT'; biomeColor = '#ffd3b6'; }
            else if (window.myPlayer.y >= 6838 && window.myPlayer.y <= 7562) { biome = '🌊 RIVER'; biomeColor = '#91b2db'; }
            else { biome = '🌲 PLAINS'; biomeColor = '#b4db62'; }
        }

        element.innerHTML = `
            <div style="font-size: 13px; font-weight: normal; color: rgba(255, 255, 255, 0.95); font-family: 'Hammersmith One', Arial, sans-serif;">
                X: <span style="color: ${THEME.pink};">${x}</span> | Y: <span style="color: ${THEME.pink};">${y}</span>
            </div>
            <div style="font-size: 11px; margin-top: 2px; color: ${biomeColor}; text-shadow: 0 0 4px rgba(0,0,0,0.6); font-family: 'Hammersmith One', Arial, sans-serif;">
                ${biome}
            </div>
        `;
    }

    function createStatus() {
        if (document.getElementById('pc-status')) return;
        const element = document.createElement('div');
        element.id = 'pc-status';
        element.style.cssText = `
            display: none;
            position: fixed;
            bottom: 220px;
            left: 14px;
            z-index: 999999;
            background: ${THEME.bg};
            backdrop-filter: ${THEME.blur};
            -webkit-backdrop-filter: ${THEME.blur};
            color: ${THEME.text};
            font-family: 'Hammersmith One', Arial, sans-serif;
            font-size: 13px;
            padding: 10px 14px;
            border-radius: 8px;
            border: ${THEME.border};
            box-shadow: ${THEME.shadow};
            pointer-events: none;
            line-height: 1.5;
            min-width: 190px;
        `;
        document.body.appendChild(element);
        updateStatus();
    }

    function updateStatus() {
        const element = document.getElementById('pc-status');
        if (!element) return;

        if (!isPlayerInGame()) {
            element.style.display = 'none';
            const macMenu = document.getElementById('pc-macos-window');
            if (macMenu) macMenu.style.display = 'none';
            return;
        }

        const zoomPercent = Math.round(cameraZoom * 100);

        element.style.display = 'block';
        element.innerHTML = `
            <div style="color:${THEME.accent};font-size:12px;margin-bottom:4px;letter-spacing:1px;font-family:'Hammersmith One',Arial,sans-serif">PIDORASI CLIENT v9.3</div>
            <div style="color:${THEME.pink}">● Auto-Heal (${formatKey(userBinds.toggleHeal)}) <span style="opacity:.8;color:${autoHealEnabled ? '#27c93f' : '#ff5f56'}">[${autoHealEnabled ? 'ON' : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Fast-Break <span style="opacity:.8;color:#27c93f">[HOLD ПКМ]</span></div>
            <div style="color:${THEME.pink}">● Turret-Insta (${formatKey(userBinds.turretInsta)}) <span style="opacity:.8;color:#ff4d6d">[TURRET+SHOT]</span></div>
            <div style="color:${THEME.pink}">● Bull-Insta (${formatKey(userBinds.instaMusket)}) <span style="opacity:.8;color:#27c93f">[BULL+SHOT]</span></div>
            <div style="color:${THEME.pink}">● Auto-Trap (${formatKey(userBinds.toggleAutoTrap)}) <span style="opacity:.8;color:${autoTrapEnabled ? '#27c93f' : '#ff5f56'}">[${autoTrapEnabled ? 'ON' : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Auto-Aim <span style="opacity:.8;color:${autoAimEnabled ? '#27c93f' : '#ff5f56'}">[${autoAimEnabled ? 'ON' : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Auto-Clan Accept <span style="opacity:.8;color:${autoClanAccept ? '#27c93f' : '#ff5f56'}">[${autoClanAccept ? 'ON' : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Kill-Chat <span style="opacity:.8;color:${killChatEnabled ? '#27c93f' : '#ff5f56'}">[${killChatEnabled ? 'ON' : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Auto-Windmills (${formatKey(userBinds.autoWindmills)}) <span style="opacity:.8;color:${autoWindmillsEnabled ? '#27c93f' : '#ff5f56'}">[${autoWindmillsEnabled ? 'ON' : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Hat (${formatKey(userBinds.toggleHat)}) <span style="opacity:.8;color:#fff">[${bullHat ? 'Bull' : 'Booster'}]</span></div>
            <div style="color:${THEME.pink}">● Soldier (${formatKey(userBinds.toggleSoldier)}) <span style="opacity:.8;color:#fff">[${soldierHelmet ? 'ON' : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Tail (${formatKey(userBinds.toggleTail)}) <span style="opacity:.8;color:#fff">[${monkeyTail ? 'ON' : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Auto-Winter <span style="opacity:.8;color:#fff">[${autoBiomeHatEnabled ? (isInWinter ? 'SNOW' : 'ON') : 'OFF'}]</span></div>
            <div style="color:${THEME.pink}">● Zoom (- / +) <span style="opacity:.8;color:#fff">[${zoomPercent}%]</span></div>
        `;
    }

    // ==========================================
    // MAC OS GUI
    // ==========================================
    function renderBindRow(label, action) {
        const isRebinding = rebindingAction === action;
        return `
            <div style="
                display: flex; justify-content: space-between; align-items: center; background: rgba(0, 0, 0, 0.3);
                padding: 8px 12px; border-radius: 8px; border: 1px solid rgba(255, 42, 42, 0.2);
            ">
                <span style="font-size: 13px; color: #fff;">${label}</span>
                <button class="pc-bind-btn" data-action="${action}" title="Left-Click: Rebind | Right-Click: Unbind" style="
                    padding: 5px 14px; border-radius: 6px; border: 1px solid ${isRebinding ? '#ffbd2e' : 'rgba(255, 42, 42, 0.5)'};
                    background: ${isRebinding ? 'rgba(255, 189, 46, 0.3)' : 'rgba(0, 0, 0, 0.5)'}; color: ${isRebinding ? '#ffbd2e' : THEME.pink};
                    font-family: inherit; font-size: 12px; font-weight: bold; cursor: pointer; min-width: 85px; text-align: center;
                ">${isRebinding ? 'Press key...' : formatKey(userBinds[action])}</button>
            </div>
        `;
    }

    function attachBindEvents(content) {
        content.querySelectorAll('.pc-bind-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                const action = btn.getAttribute('data-action');
                rebindingAction = action;
                btn.textContent = 'Press key...';
                btn.style.background = 'rgba(255, 189, 46, 0.4)';
                btn.style.borderColor = '#ffbd2e';
            });

            btn.addEventListener('contextmenu', (e) => {
                e.preventDefault();
                e.stopPropagation();
                const action = btn.getAttribute('data-action');
                userBinds[action] = 'NONE';
                saveBinds();
                renderTabs();
                updateStatus();
            });
        });

        content.querySelector('#gui-aim-btn')?.addEventListener('click', () => {
            autoAimEnabled = !autoAimEnabled;
            renderTabs();
            updateStatus();
        });
        content.querySelector('#gui-autotrap-btn')?.addEventListener('click', () => {
            autoTrapEnabled = !autoTrapEnabled;
            renderTabs();
            updateStatus();
        });
        content.querySelector('#gui-clanaccept-btn')?.addEventListener('click', () => {
            autoClanAccept = !autoClanAccept;
            renderTabs();
            updateStatus();
        });
        content.querySelector('#gui-killchat-btn')?.addEventListener('click', () => {
            killChatEnabled = !killChatEnabled;
            renderTabs();
            updateStatus();
        });
        content.querySelector('#gui-killchat-msg')?.addEventListener('input', (e) => {
            killChatMessage = e.target.value;
            localStorage.setItem('pcKillMsg', killChatMessage);
        });
        content.querySelector('#gui-pred-me')?.addEventListener('click', () => {
            predictMe = !predictMe;
            renderTabs();
        });
        content.querySelector('#gui-pred-players')?.addEventListener('click', () => {
            predictPlayers = !predictPlayers;
            renderTabs();
        });
        content.querySelector('#gui-esp-owners')?.addEventListener('click', () => {
            showBuildingOwners = !showBuildingOwners;
            renderTabs();
        });
        content.querySelector('#gui-heal-btn')?.addEventListener('click', () => {
            autoHealEnabled = !autoHealEnabled;
            renderTabs();
            updateStatus();
        });
        content.querySelector('#gui-biome-btn')?.addEventListener('click', () => {
            autoBiomeHatEnabled = !autoBiomeHatEnabled;
            renderTabs();
            updateStatus();
        });
    }

    function renderTabs() {
        const win = document.getElementById('pc-macos-window');
        if (!win) return;

        win.querySelectorAll('.pc-tab-btn').forEach(btn => {
            const tab = btn.getAttribute('data-tab');
            if (tab === currentTab) {
                btn.style.background = 'rgba(255, 42, 42, 0.25)';
                btn.style.border = '1px solid rgba(255, 42, 42, 0.6)';
                btn.style.color = '#fff';
            } else {
                btn.style.background = 'transparent';
                btn.style.border = '1px solid transparent';
                btn.style.color = 'rgba(255, 255, 255, 0.6)';
            }
        });

        const content = win.querySelector('#pc-tab-content');
        if (!content) return;

        if (currentTab === 'keybinds') {
            content.innerHTML = `
                <div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 12px;">
                    <div style="font-size: 14px; font-weight: bold; color: ${THEME.accent}; text-transform: uppercase;">Keybind Configuration</div>
                    <div style="font-size: 10px; color: rgba(255,255,255,0.45);">[Right-Click = Unbind]</div>
                </div>

                <div style="display: flex; flex-direction: column; gap: 8px; margin-bottom: 16px;">
                    ${renderBindRow('Open GUI Window', 'openMenu')}
                    ${renderBindRow('Turret Insta-Kill', 'turretInsta')}
                    ${renderBindRow('Bull Insta-Kill', 'instaMusket')}
                    ${renderBindRow('Auto-Trap Toggle', 'toggleAutoTrap')}
                    ${renderBindRow('Auto-Windmills (4 Dense Arc)', 'autoWindmills')}
                    ${renderBindRow('Hat Toggle (Bull / Booster)', 'toggleHat')}
                    ${renderBindRow('Soldier Helmet', 'toggleSoldier')}
                    ${renderBindRow('Monkey Tail', 'toggleTail')}
                    ${renderBindRow('Auto-Heal Toggle', 'toggleHeal')}
                </div>

                <div style="font-size: 14px; font-weight: bold; color: ${THEME.accent}; margin-bottom: 10px; text-transform: uppercase;">Visual & Aim Settings</div>
                <div style="display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 16px;">
                    <button id="gui-aim-btn" style="
                        padding: 8px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 11px; font-weight: bold;
                        background: ${autoAimEnabled ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">AUTO-AIM: ${autoAimEnabled ? 'ON' : 'OFF'}</button>

                    <button id="gui-esp-owners" style="
                        padding: 8px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 11px; font-weight: bold;
                        background: ${showBuildingOwners ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">CLAN ESP: ${showBuildingOwners ? 'ON' : 'OFF'}</button>

                    <button id="gui-pred-me" style="
                        padding: 8px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 11px; font-weight: bold;
                        background: ${predictMe ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">PREDICT ME: ${predictMe ? 'ON' : 'OFF'}</button>

                    <button id="gui-pred-players" style="
                        padding: 8px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 11px; font-weight: bold;
                        background: ${predictPlayers ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">PLAYERS: ${predictPlayers ? 'ON' : 'OFF'}</button>
                </div>

                <div style="font-size: 14px; font-weight: bold; color: ${THEME.accent}; margin-bottom: 10px; text-transform: uppercase;">Automation & Clan Modules</div>
                <div style="display: flex; flex-direction: column; gap: 8px; margin-bottom: 14px;">
                    <button id="gui-clanaccept-btn" style="
                        width: 100%; padding: 10px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: bold;
                        background: ${autoClanAccept ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">AUTO-CLAN ACCEPT: ${autoClanAccept ? 'ENABLED' : 'DISABLED'}</button>

                    <button id="gui-autotrap-btn" style="
                        width: 100%; padding: 10px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: bold;
                        background: ${autoTrapEnabled ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">AUTO-TRAP: ${autoTrapEnabled ? 'ENABLED' : 'DISABLED'}</button>

                    <button id="gui-heal-btn" style="
                        width: 100%; padding: 10px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: bold;
                        background: ${autoHealEnabled ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">Auto-Heal: ${autoHealEnabled ? 'ENABLED' : 'DISABLED'}</button>

                    <button id="gui-biome-btn" style="
                        width: 100%; padding: 10px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 13px; font-weight: bold;
                        background: ${autoBiomeHatEnabled ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">Auto-Biome Hat: ${autoBiomeHatEnabled ? 'ENABLED' : 'DISABLED'}</button>
                </div>

                <div style="font-size: 14px; font-weight: bold; color: ${THEME.accent}; margin-bottom: 10px; text-transform: uppercase;">Kill-Chat Notification</div>
                <div style="display: flex; flex-direction: column; gap: 8px; background: rgba(0,0,0,0.3); padding: 10px; border-radius: 8px; border: 1px solid rgba(255,42,42,0.2);">
                    <button id="gui-killchat-btn" style="
                        width: 100%; padding: 8px; border-radius: 6px; cursor: pointer; font-family: inherit; font-size: 12px; font-weight: bold;
                        background: ${killChatEnabled ? 'rgba(31,122,58,0.7)' : 'rgba(139,0,0,0.7)'}; color: #fff; border: 1px solid ${THEME.accent};
                    ">KILL-CHAT: ${killChatEnabled ? 'ENABLED' : 'DISABLED'}</button>

                    <input id="gui-killchat-msg" type="text" maxlength="30" value="${killChatMessage}" placeholder="Kill message (max 30 chars)..." style="
                        width: 100%; background: rgba(0, 0, 0, 0.5); border: 1px solid rgba(255, 42, 42, 0.4); border-radius: 6px;
                        color: #fff; padding: 7px 10px; font-family: inherit; font-size: 12px; box-sizing: border-box; text-align: center;
                    " />
                </div>
            `;

            attachBindEvents(content);

        } else if (currentTab === 'changelog') {
            content.innerHTML = `
                <div style="font-size: 14px; font-weight: bold; color: ${THEME.accent}; margin-bottom: 12px; text-transform: uppercase;">Full Version History</div>

                <div style="display: flex; flex-direction: column; gap: 12px; font-size: 12px; line-height: 1.4;">
                    <div style="background: rgba(0,0,0,0.3); padding: 10px; border-radius: 8px; border-left: 3px solid #ff4d6d;">
                        <div style="font-weight: bold; color: #fff; margin-bottom: 4px;">v9.3: Clan & Kill-Chat Release</div>
                        <div style="color: ${THEME.text};">● Добавлен модуль Auto-Clan Accept (авто-прием заявок в клан).</div>
                        <div style="color: ${THEME.text};">● Добавлен кастомный Kill-Chat с настройкой фразы в GUI.</div>
                        <div style="color: ${THEME.text};">● Полностью вырезан спинбот и лишняя вкладка Fun.</div>
                        <div style="color: ${THEME.text};">● Переписан и улучшен Auto-Aim для идеальных попаданий комбо.</div>
                    </div>
                </div>
            `;
        }
    }

    function createMacGui() {
        if (document.getElementById('pc-macos-window')) return;

        const win = document.createElement('div');
        win.id = 'pc-macos-window';
        win.style.cssText = `
            display: none;
            position: fixed;
            top: calc(50% - 175px);
            left: calc(50% - 270px);
            z-index: 1000000;
            width: 550px;
            height: 440px;
            border-radius: 12px;
            background: rgba(15, 0, 0, 0.78);
            backdrop-filter: blur(10px);
            -webkit-backdrop-filter: blur(10px);
            border: ${THEME.border};
            box-shadow: 0 8px 32px rgba(255, 0, 0, 0.25);
            color: #fff;
            font-family: 'Hammersmith One', Arial, sans-serif;
            user-select: none;
            overflow: hidden;
            flex-direction: column;
        `;

        win.innerHTML = `
            <div id="pc-mac-titlebar" style="
                height: 38px;
                background: rgba(0, 0, 0, 0.5);
                border-bottom: ${THEME.borderLight};
                display: flex;
                align-items: center;
                padding: 0 14px;
                cursor: grab;
                position: relative;
            ">
                <div style="display: flex; gap: 7px; align-items: center;">
                    <div id="pc-mac-close" style="width: 12px; height: 12px; border-radius: 50%; background: #ff5f56; cursor: pointer; border: 1px solid #e0443e;" title="Close"></div>
                    <div style="width: 12px; height: 12px; border-radius: 50%; background: #ffbd2e; border: 1px solid #dea123;"></div>
                    <div style="width: 12px; height: 12px; border-radius: 50%; background: #27c93f; border: 1px solid #1aab29;"></div>
                </div>

                <div style="
                    position: absolute;
                    left: 0;
                    right: 0;
                    text-align: center;
                    font-size: 13px;
                    letter-spacing: 1px;
                    color: ${THEME.accent};
                    font-weight: bold;
                    pointer-events: none;
                ">Pidorasi Client // by xw5yt</div>
            </div>

            <div style="flex: 1; display: flex; overflow: hidden;">
                <div style="
                    width: 150px;
                    background: rgba(0, 0, 0, 0.25);
                    border-right: ${THEME.borderLight};
                    display: flex;
                    flex-direction: column;
                    padding: 12px 8px;
                    gap: 6px;
                ">
                    <button class="pc-tab-btn" data-tab="keybinds" style="
                        padding: 10px 12px; border-radius: 8px; border: none; background: transparent; color: #fff;
                        font-family: inherit; font-size: 13px; cursor: pointer; text-align: left; transition: 0.2s;
                    ">⌨️ Keybinds</button>

                    <button class="pc-tab-btn" data-tab="changelog" style="
                        padding: 10px 12px; border-radius: 8px; border: none; background: transparent; color: #fff;
                        font-family: inherit; font-size: 13px; cursor: pointer; text-align: left; transition: 0.2s;
                    ">📜 Changelog</button>
                </div>

                <div id="pc-tab-content" style="flex: 1; padding: 16px 14px 16px 16px; overflow-y: auto;"></div>
            </div>
        `;

        document.body.appendChild(win);

        const titlebar = win.querySelector('#pc-mac-titlebar');
        let isDragging = false;
        let startX = 0;
        let startY = 0;
        let initLeft = 0;
        let initTop = 0;

        titlebar.addEventListener('mousedown', e => {
            if (e.target.id === 'pc-mac-close') return;
            isDragging = true;
            titlebar.style.cursor = 'grabbing';
            startX = e.clientX;
            startY = e.clientY;
            const rect = win.getBoundingClientRect();
            initLeft = rect.left;
            initTop = rect.top;
        });

        document.addEventListener('mousemove', e => {
            if (!isDragging) return;
            win.style.left = (initLeft + e.clientX - startX) + 'px';
            win.style.top = (initTop + e.clientY - startY) + 'px';
        }, true);

        document.addEventListener('mouseup', () => {
            if (isDragging) {
                isDragging = false;
                titlebar.style.cursor = 'grab';
            }
        }, true);

        win.querySelector('#pc-mac-close').addEventListener('click', () => {
            win.style.display = 'none';
        });

        win.querySelectorAll('.pc-tab-btn').forEach(btn => {
            btn.addEventListener('click', () => {
                currentTab = btn.getAttribute('data-tab');
                renderTabs();
            });
        });

        renderTabs();
    }

    function setupTriCardLayout() {
        const holder = document.getElementById('menuCardHolder');
        if (!holder) return;

        let skinCard = document.getElementById('pc-skin-card');
        if (!skinCard) {
            skinCard = document.createElement('div');
            skinCard.id = 'pc-skin-card';
            skinCard.style.cssText = `
                width: 170px;
                height: 210px;
                background: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 10px !important;
                box-shadow: ${THEME.shadow} !important;
                padding: 12px 8px;
                display: flex;
                flex-direction: column;
                align-items: center;
                justify-content: flex-start;
                box-sizing: border-box;
            `;
            skinCard.innerHTML = `<div style="font-size: 12px; font-weight: bold; color: ${THEME.accent}; margin-bottom: 10px; text-transform: uppercase; letter-spacing: 0.5px;">Skin Color</div><div id="pc-skin-insert"></div>`;
            holder.insertBefore(skinCard, holder.firstChild);
        }

        const origSkinHolder = document.getElementById('skinColorHolder');
        const insertTarget = document.getElementById('pc-skin-insert');
        if (origSkinHolder && insertTarget && origSkinHolder.parentNode !== insertTarget) {
            insertTarget.appendChild(origSkinHolder);
            origSkinHolder.style.cssText = `display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; justify-items: center; width: 100%;`;
        }

        const playCard = document.querySelector('.menuCard:not(#guideCard)');
        if (playCard && !playCard._titled) {
            playCard._titled = true;
            const title = document.createElement('div');
            title.style.cssText = `font-size: 12px; font-weight: bold; color: ${THEME.accent}; text-transform: uppercase; letter-spacing: 0.5px; text-align: center;`;
            title.textContent = 'Player';
            playCard.insertBefore(title, playCard.firstChild);
        }

        const guideCard = document.getElementById('guideCard');
        if (guideCard && !guideCard._rebuilt) {
            guideCard._rebuilt = true;
            guideCard.style.cssText = `
                width: 320px;
                height: 280px;
                background: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 10px !important;
                box-shadow: ${THEME.shadow} !important;
                padding: 12px;
                display: flex;
                flex-direction: column;
                box-sizing: border-box;
                overflow: hidden;
            `;
            guideCard.innerHTML = `
                <div style="font-size: 12px; font-weight: bold; color: ${THEME.accent}; margin-bottom: 8px; text-transform: uppercase; letter-spacing: 0.5px;">Server Browser</div>
                <div id="pc-server-list" style="flex: 1; overflow-y: auto; padding-right: 4px; display: flex; flex-direction: column; gap: 5px;"></div>
            `;
        }
    }

    function applyVisuals() {
        const style = document.createElement('style');
        style.innerHTML = `
            .material-icons { font-family: 'Material Icons' !important; }

            #userscript-warning, #ad-container, #pre-content-container,
            div[id*="warning"], div[class*="warning"], div[id*="error"] {
                display: none !important;
                visibility: hidden !important;
                opacity: 0 !important;
                pointer-events: none !important;
            }

            #mainMenu:not([style*="display: none"]) {
                position: absolute !important;
                inset: 0 !important;
                width: 100vw !important;
                height: 100vh !important;
                display: flex !important;
                flex-direction: column !important;
                align-items: center !important;
                justify-content: center !important;
                background: transparent !important;
                box-sizing: border-box !important;
            }

            #mainMenu[style*="display: none"] {
                display: none !important;
            }

            #menuCardHolder {
                display: flex !important;
                flex-direction: row !important;
                align-items: flex-start !important;
                justify-content: center !important;
                margin: 0 auto !important;
                gap: 16px !important;
                border: none !important;
                background: transparent !important;
                box-shadow: none !important;
            }

            .menuCard:not(#guideCard) {
                width: 250px !important;
                height: 210px !important;
                background: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 10px !important;
                box-shadow: ${THEME.shadow} !important;
                color: #fff !important;
                padding: 12px 14px !important;
                display: flex !important;
                flex-direction: column !important;
                justify-content: space-between !important;
                box-sizing: border-box !important;
                margin: 0 !important;
            }

            #nameInput {
                background: rgba(0, 0, 0, 0.4) !important;
                border: 1px solid rgba(255, 42, 42, 0.4) !important;
                border-radius: 8px !important;
                color: #fff !important;
                font-family: 'Hammersmith One', Arial, sans-serif !important;
                font-size: 16px !important;
                text-align: center !important;
                padding: 7px !important;
                box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.5) !important;
                width: 100% !important;
                box-sizing: border-box !important;
            }

            #turnstileWidget {
                display: flex !important;
                justify-content: center !important;
                align-items: center !important;
                background: rgba(0, 0, 0, 0.3) !important;
                backdrop-filter: blur(5px) !important;
                -webkit-backdrop-filter: blur(5px) !important;
                border: 1px solid rgba(255, 42, 42, 0.35) !important;
                border-radius: 8px !important;
                padding: 2px !important;
                margin: 2px 0 !important;
                overflow: hidden !important;
                box-shadow: inset 0 2px 4px rgba(0, 0, 0, 0.4) !important;
                height: 52px !important;
                width: 100% !important;
                box-sizing: border-box !important;
            }
            #turnstileWidget > div, #turnstileWidget iframe {
                transform: scale(0.72) !important;
                transform-origin: center center !important;
                border-radius: 6px !important;
            }

            #enterGame {
                background: linear-gradient(90deg, #8b0000, #ff1a1a) !important;
                border: 1.5px solid ${THEME.accent} !important;
                border-radius: 8px !important;
                box-shadow: 0 0 14px rgba(255, 0, 0, 0.45) !important;
                color: #fff !important;
                font-weight: bold !important;
                font-family: 'Hammersmith One', Arial, sans-serif !important;
                letter-spacing: 1.5px !important;
                padding: 10px !important;
                cursor: pointer !important;
                transition: 0.15s !important;
                width: 100% !important;
            }
            #enterGame:hover {
                transform: scale(1.02) !important;
                box-shadow: 0 0 22px rgba(255, 0, 0, 0.75) !important;
            }

            #serverBrowser {
                position: absolute !important;
                opacity: 0 !important;
                pointer-events: none !important;
                width: 0 !important;
                height: 0 !important;
                overflow: hidden !important;
            }
            #guideCard h2, #guideCard h3, #guideCard p { display: none !important; }

            .skinColorItem {
                border: 2px solid rgba(255, 255, 255, 0.2) !important;
                border-radius: 50% !important;
                width: 26px !important;
                height: 26px !important;
                transition: 0.15s !important;
            }
            .skinColorItem:hover, .activeSkin {
                border-color: ${THEME.accent} !important;
                box-shadow: 0 0 10px rgba(255, 77, 109, 0.8) !important;
                transform: scale(1.15) !important;
            }

            #leaderboard {
                background: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 8px !important;
                box-shadow: ${THEME.shadow} !important;
                color: ${THEME.text} !important;
            }
            #allianceButton, #storeButton, #chatButton, #settingsButton, #leaderboardButton {
                background: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 8px !important;
                box-shadow: ${THEME.shadow} !important;
            }
            #mapDisplay {
                background: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 8px !important;
                box-shadow: ${THEME.shadow} !important;
            }
            #scoreDisplay, #foodDisplay, #woodDisplay, #stoneDisplay, #killCounter, .resourceDisplay {
                background: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 6px !important;
                box-shadow: ${THEME.shadow} !important;
                padding: 4px 10px !important;
                color: #fff !important;
            }
            .actionBarItem {
                background-color: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 8px !important;
                box-shadow: ${THEME.shadow} !important;
            }
            #ageBarContainer {
                background: transparent !important;
                border: none !important;
                box-shadow: none !important;
                backdrop-filter: none !important;
                -webkit-backdrop-filter: none !important;
            }
            #ageBar {
                background: ${THEME.bg} !important;
                backdrop-filter: ${THEME.blur} !important;
                -webkit-backdrop-filter: ${THEME.blur} !important;
                border: ${THEME.border} !important;
                border-radius: 6px !important;
                box-shadow: ${THEME.shadow} !important;
                overflow: hidden !important;
            }
            #ageBarBody { background: linear-gradient(90deg, #8b0000, #ff1a1a) !important; }

            #pc-server-list::-webkit-scrollbar, #pc-macos-window *::-webkit-scrollbar { width: 5px; }
            #pc-server-list::-webkit-scrollbar-track, #pc-macos-window *::-webkit-scrollbar-track { background: rgba(0, 0, 0, 0.2); border-radius: 8px; }
            #pc-server-list::-webkit-scrollbar-thumb, #pc-macos-window *::-webkit-scrollbar-thumb {
                background: linear-gradient(180deg, rgba(255, 77, 109, 0.7), rgba(255, 26, 26, 0.5));
                border-radius: 8px;
            }
        `;
        document.head.appendChild(style);

        const gameName = document.getElementById('gameName');
        if (gameName) {
            gameName.innerHTML = 'PidorasiClient';
            gameName.style.cssText = `
                color: ${THEME.title};
                text-shadow: 0 0 18px #ff0000, 0 0 35px #ff4d6d;
                font-size: 90px;
                text-align: center;
                font-family: 'Hammersmith One', Arial, sans-serif;
                margin-bottom: 24px;
                width: 100%;
            `;
        }

        const enterBtn = document.getElementById('enterGame');
        if (enterBtn) {
            enterBtn.innerHTML = '<span>→ PLAY ←</span>';
        }

        const died = document.getElementById('diedText');
        if (died) {
            died.innerHTML = "You have been хвайт'ед";
            died.style.color = THEME.accent;
            died.style.textShadow = '0 0 25px #ff0000, 0 0 45px #ff4d6d';
            died.style.fontFamily = "'Hammersmith One', Arial, sans-serif";
            died.style.letterSpacing = '1px';
        }

        document.getElementById('promoImgHolder')?.remove();
    }

    // ==========================================
    // KEYDOWN LISTENER
    // ==========================================
    document.addEventListener('keydown', event => {
        if (rebindingAction) {
            event.preventDefault();
            if (event.code === 'Escape') {
                rebindingAction = null;
            } else {
                userBinds[rebindingAction] = event.code;
                saveBinds();
                rebindingAction = null;
            }
            renderTabs();
            updateStatus();
            return;
        }

        if (event.code === userBinds.openMenu && userBinds.openMenu !== 'NONE') {
            event.preventDefault();
            if (!isPlayerInGame()) return;
            const win = document.getElementById('pc-macos-window');
            if (win) {
                const isHidden = win.style.display === 'none' || !win.style.display;
                win.style.display = isHidden ? 'flex' : 'none';
            }
            return;
        }

        const tag = document.activeElement?.tagName;
        if (tag === 'INPUT' || tag === 'TEXTAREA') return;
        if (!isPlayerInGame()) return;

        const isZoomOut = event.code === 'Minus' || event.key === '-' || event.key === '_' || event.keyCode === 189 || event.keyCode === 173;
        const isZoomIn = event.code === 'Equal' || event.key === '=' || event.key === '+' || event.keyCode === 187 || event.keyCode === 61;

        if (isZoomOut) {
            event.preventDefault();
            event.stopPropagation();
            cameraZoom = Math.max(0.25, Math.round((cameraZoom - 0.1) * 100) / 100);
            applyZoom();
            updateStatus();
            return;
        }

        if (isZoomIn) {
            event.preventDefault();
            event.stopPropagation();
            cameraZoom = Math.min(2.5, Math.round((cameraZoom + 0.1) * 100) / 100);
            applyZoom();
            updateStatus();
            return;
        }

        if (userBinds.turretInsta !== 'NONE' && event.code === userBinds.turretInsta) {
            executeTurretInstaCombo();
        }

        if (userBinds.instaMusket !== 'NONE' && event.code === userBinds.instaMusket) {
            executeFastInstaCombo();
        }

        if (userBinds.toggleAutoTrap !== 'NONE' && event.code === userBinds.toggleAutoTrap) {
            autoTrapEnabled = !autoTrapEnabled;
            updateStatus();
            renderTabs();
        }

        if (userBinds.autoWindmills !== 'NONE' && event.code === userBinds.autoWindmills) {
            autoWindmillsEnabled = !autoWindmillsEnabled;
            updateStatus();
        }

        if (userBinds.toggleHat !== 'NONE' && event.code === userBinds.toggleHat) toggleHat();
        if (userBinds.toggleSoldier !== 'NONE' && event.code === userBinds.toggleSoldier) toggleSoldierHelmet();
        if (userBinds.toggleTail !== 'NONE' && event.code === userBinds.toggleTail) toggleMonkeyTail();
        if (userBinds.toggleHeal !== 'NONE' && event.code === userBinds.toggleHeal) {
            autoHealEnabled = !autoHealEnabled;
            renderTabs();
            updateStatus();
        }
    }, true);

    // ==========================================
    // INITIALIZATION
    // ==========================================
    function init() {
        if (!document.body) return setTimeout(init, 40);
        applyVisuals();
        createStatus();
        createMacGui();
        initOverlayCanvas();
        requestAnimationFrame(renderPredictLoop);
        loadServersFromApi();

        setInterval(() => {
            document.querySelectorAll('div').forEach(el => {
                if (el.textContent && el.textContent.includes('disabling all of your browser extensions')) {
                    el.remove();
                }
            });

            const mainMenu = document.getElementById('mainMenu');
            const gameUI = document.getElementById('gameUI');
            if (gameUI && gameUI.style.display === 'block') {
                if (mainMenu && mainMenu.style.display !== 'none') {
                    mainMenu.style.display = 'none';
                }
            }

            setupTriCardLayout();
            if (cachedServers.length === 0) {
                loadServersFromApi();
            }
            updateStatus();
            updateCoordDisplay();

            const died = document.getElementById('diedText');
            if (died && died.innerHTML !== "You have been хвайт'ед") {
                died.innerHTML = "You have been хвайт'ед";
            }
        }, 150);

        setInterval(loadServersFromApi, 5000);
    }

    if (document.readyState === 'loading') document.addEventListener('DOMContentLoaded', init);
    else init();
})();