MICHAEL GUN

Original Aimbot, Silent Aim, 2-Tab Radar, Item Tracer Settings, Full Dictionary

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

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

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

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

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

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

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

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

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

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

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

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

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

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

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name        MICHAEL GUN
// @namespace   http://tampermonkey.net/
// @match       https://voxiom.io/*
// @run-at      document-start
// @grant       none
// @version     1.3
// @author      Michael GUN and AlanKoss(fixed bugs)
// @description Original Aimbot, Silent Aim, 2-Tab Radar, Item Tracer Settings, Full Dictionary
// @license     GPL
// @require     https://cdn.jsdelivr.net/npm/[email protected]/dist/lil-gui.umd.min.js
// @require     https://unpkg.com/[email protected]/build/three.min.js
// @icon        https://www.google.com/s2/favicons?sz=64&domain=voxiom.io
// ==/UserScript==

// ==========================================
// WEBGL ATTACK CORE (NEW WALLHACK X-RAY)
// ==========================================
const getContext = HTMLCanvasElement.prototype.getContext;
HTMLCanvasElement.prototype.getContext = function() {
    const ctx = getContext.apply(this, arguments);
    if (ctx && (arguments[0] === 'webgl' || arguments[0] === 'webgl2' || arguments[0] === 'experimental-webgl')) {
        const originalDrawElements = ctx.drawElements;
        const originalDrawArrays = ctx.drawArrays;

        ctx.drawElements = function(mode, count, type, offset) {
            const isPlayer = count > 500 && count <= 10000;
            if (isPlayer && typeof espConfig !== 'undefined' && espConfig.wireframe === 1) {
                ctx.disable(ctx.DEPTH_TEST);
                originalDrawElements.apply(this, arguments);
                ctx.enable(ctx.DEPTH_TEST);
                return;
            }
            return originalDrawElements.apply(this, arguments);
        };

        ctx.drawArrays = function(mode, first, count) {
            const isPlayer = count > 500 && count <= 10000;
            if (isPlayer && typeof espConfig !== 'undefined' && espConfig.wireframe === 1) {
                ctx.disable(ctx.DEPTH_TEST);
                originalDrawArrays.apply(this, arguments);
                ctx.enable(ctx.DEPTH_TEST);
                return;
            }
            return originalDrawArrays.apply(this, arguments);
        };
    }
    return ctx;
};

// ==========================================
// 1. 2-TAB RADAR UI (PLAYERS / ITEMS)
// ==========================================
if (!document.getElementById('side-player-list')) {
    const listUI = document.createElement('div');
    listUI.id = 'side-player-list';
    listUI.style = `
        position: fixed; top: 230px; left: 0px; width: 300px;
        background: rgba(0, 0, 0, 0.85);
        border-left: 5px solid #00ff00;
        color: white;
        font-family: 'Segoe UI', sans-serif;
        font-size: 16px;
        z-index: 10001; padding: 15px; border-radius: 0 10px 10px 0;
        pointer-events: none;
        box-shadow: 8px 8px 20px rgba(0,0,0,0.6);
        transition: border-left-color 0.2s ease;
    `;

    const styleSheet = document.createElement("style");
    styleSheet.innerText = `
        .player-row {
            display: flex; align-items: center; margin-bottom: 8px; transition: all 0.2s; padding: 2px 5px; border-radius: 4px;
        }
        .player-row.selected {
            background: rgba(255, 255, 0, 0.3) !important;
            border: 1px solid yellow;
        }
        .dist-text {
            margin-left: auto; color: #00ffff !important; font-size: 13px; font-weight: bold; opacity: 1 !important; text-shadow: 1px 1px 2px #000;
        }
        /* Scrollbar colors matching active tabs */
        #list-content::-webkit-scrollbar { width: 4px; }
        #list-content.tab-players::-webkit-scrollbar-thumb { background: #00ff00; border-radius: 4px; }
        #list-content.tab-items::-webkit-scrollbar-thumb { background: #0088ff; border-radius: 4px; }
        #list-content.tab-marks::-webkit-scrollbar-thumb { background: #ff0044; border-radius: 4px; }
    `;
    document.head.appendChild(styleSheet);

    listUI.innerHTML = `
        <div id="radar-header" style="color:#00ff00; font-weight:bold; margin-bottom:8px; border-bottom:1px solid #00ff00; padding-bottom:5px; font-size:12px; letter-spacing:1px; text-transform: uppercase; transition: all 0.2s ease;">
            📡 RADAR (<span id="radar-count" style="color: #00ff00; transition: color 0.2s ease;">0</span>)
        </div>
        <div style="display: flex; gap: 5px; margin-bottom: 10px; pointer-events: auto;">
            <button id="btn-radar-players" onclick="window.setRadarMode('players')" style="flex:1; background: #00ff00; color: black; border: 1px solid #00ff00; border-radius: 4px; font-weight: bold; cursor: pointer; font-size: 10px; padding: 4px 0; transition: all 0.2s ease;">PLAYERS</button>
            <button id="btn-radar-items" onclick="window.setRadarMode('items')" style="flex:1; background: transparent; color: #0088ff; border: 1px solid #0088ff; border-radius: 4px; font-weight: bold; cursor: pointer; font-size: 10px; padding: 4px 0; transition: all 0.2s ease;">ITEMS</button>
            <button id="btn-radar-marks" onclick="window.setRadarMode('marks')" style="flex:1; background: transparent; color: #ff0044; border: 1px solid #ff0044; border-radius: 4px; font-weight: bold; cursor: pointer; font-size: 10px; padding: 4px 0; transition: all 0.2s ease;">MARKS</button>
        </div>
            <div id="list-content" class="tab-players" style="pointer-events: auto; max-height: calc(100vh - 380px); overflow-y: auto; overflow-x: hidden; padding-right: 2px;"></div>
    `;
    document.body.appendChild(listUI);
}

// ==========================================
// GLOBAL ITEM DICTIONARY
// ==========================================
window.globalItemDict = {
    "6876": { name: "ELITE ASSAULT RIFLE", useLightColor: true, str: "#ffaa00" },
    "1047": { name: "MAX SHIELD POTION", str: "#CC0099" },
    "1320_#ffd375": { name: "ASSAULT RIFLE AMMO", str: "#FFFF66" },
    "898_#ef130f":  { name: "RED APPLE", str: "#FF0000" },
    "3577": { name: "AK RIFLE", useLightColor: true, str: "#ff0000" },
    "5528": { name: "HEAVY SNIPER RIFLE", useLightColor: true, str: "#ffaa00" },
    "2481": { name: "SURGE ASSAULT RIFLE", useLightColor: true, str: "#00ffff" },
    "220":  { name: "SHOVEL", useLightColor: true, str: "#95a5a6" },
    "3609": { name: "REVOLVER", useLightColor: true, str: "#00ff00" },
    "832":  { name: "SNIPER AMMO", str: "#F88456" },
    "898_#ef6100":  { name: "GOLDEN APPLE", str: "#FFAE0D" },
    "24":   { name: "BLOCK", str: "#1874FC" },
    "1765": { name: "STRIKE PISTOL", useLightColor: true, str: "#ffffff" },
    "601":  { name: "MINI SHIELD POTION", str: "#FF9900" },
    "5119": { name: "SHOTGUN", useLightColor: true, str: "#ff00ff" },
    "276":  { name: "MEDICAL KIT", str: "#CC0099" },
    "624":  { name: "HEALTH PILL", str: "#FF0000" },
    "1320_#a9361b": { name: "SMG AMMO", str: "#C5C5C5" },
    "1440": { name: "PISTOL AMMO", str: "#FFFF66" },
    "4035": { name: "COMPACT SMG", useLightColor: true, str: "#ffffff" },
    "4395": { name: "LIGHT SNIPER RIFLE", useLightColor: true, str: "#ffffff" },
    "432":  { name: "SHOTGUN AMMO", str: "#CC0000" },
    "4460": { name: "LIGHT SMG", useLightColor: true, str: "#ffffff" },
    "3685": { name: "TACTICAL ASSAULT RIFLE", useLightColor: true, str: "#ffffff" },
    "447":  { name: "PREMIUM SHIELD POTION", str: "#3366FF" },
    "72":   { name: "IRON", str: "#FFFFFF" },
    "88":   { name: "EMERALD", str: "#00FF00" },
    "54":   { name: "SULFUR", str: "#CC6600" }
};

// RADAR SYSTEM VARIABLES
window.playerMap = new Map();
window.nearbyItemCounts = new Map(); // Count nearby items
window.lastPositions = new Map();
window.ignoredPlayers = new Set();
window.radarMode = 'players';
window.tracedItemKeys = new Set(); // Multi-selection Set for tracers

window.savedMarks = [];

window.toggleMark = function(id) {
    let m = window.savedMarks.find(x => x.id === id);
    if(m) { m.active = !m.active; window.playClickSound(); }
};
// LOCK BUTTON
window.toggleLock = function(id) {
    let m = window.savedMarks.find(x => x.id === id);
    if(m) { m.isLocked = !m.isLocked; window.playClickSound(); }
};
// RENAME BUTTON
window.renameMark = function(id) {
    let m = window.savedMarks.find(x => x.id === id);
    if(m) {
        let newName = prompt("Enter new name for this mark:", m.name);
        if (newName && newName.trim() !== "") {
            m.name = newName.trim();
            // Update 3D Sprite in game
            if (m.sprite && typeof scene !== 'undefined') scene.remove(m.sprite);
            if (typeof makeTextSprite === 'function') {
                m.sprite = makeTextSprite(m.name, "#ff0044");
                if (typeof scene !== 'undefined') scene.add(m.sprite);
            }
            window.playClickSound();
        }
    }
};
// DELETE BUTTON (WITH LOCK CHECK)
window.deleteMark = function(id) {
    let m = window.savedMarks.find(x => x.id === id);
    if (m && !m.isLocked) { // Only delete if unlocked
        if (m.sprite && typeof scene !== 'undefined') scene.remove(m.sprite);
        window.savedMarks = window.savedMarks.filter(x => x.id !== id);
        window.playClickSound();
    }
};
// CLEAR ALL (KEEPS LOCKED MARKS)
window.clearAllMarks = function() {
    let lockedMarks = window.savedMarks.filter(m => m.isLocked);
    let unlockedMarks = window.savedMarks.filter(m => !m.isLocked);

    unlockedMarks.forEach(m => { if(m.sprite && typeof scene !== 'undefined') scene.remove(m.sprite); });
    window.savedMarks = lockedMarks; // Keep only locked
    window.playClickSound();
    notifyStatus("Mark", "DELETED UNLOCKED MARKS");
};

window.setRadarMode = function(mode) {
    window.radarMode = mode;
    window.playClickSound();

    const btnP = document.getElementById('btn-radar-players');
    const btnI = document.getElementById('btn-radar-items');
    const btnM = document.getElementById('btn-radar-marks');
    const listUI = document.getElementById('side-player-list');
    const header = document.getElementById('radar-header');
    const count = document.getElementById('radar-count');

    btnP.style.background = 'transparent'; btnP.style.color = '#00ff00';
    btnI.style.background = 'transparent'; btnI.style.color = '#0088ff';
    if(btnM) { btnM.style.background = 'transparent'; btnM.style.color = '#ff0044'; }

    const contentBox = document.getElementById('list-content');

    if (mode === 'players') {
        btnP.style.background = '#00ff00'; btnP.style.color = 'black';
        listUI.style.borderLeftColor = '#00ff00'; header.style.color = '#00ff00'; count.style.color = '#00ff00'; header.style.borderBottomColor = '#00ff00';
        if (contentBox) contentBox.className = 'tab-players'; // Attach green class
    } else if (mode === 'items') {
        btnI.style.background = '#0088ff'; btnI.style.color = 'white';
        listUI.style.borderLeftColor = '#0088ff'; header.style.color = '#0088ff'; count.style.color = '#0088ff'; header.style.borderBottomColor = '#0088ff';
        if (contentBox) contentBox.className = 'tab-items'; // Attach blue class
    } else if (mode === 'marks') {
        btnM.style.background = '#ff0044'; btnM.style.color = 'white';
        listUI.style.borderLeftColor = '#ff0044'; header.style.color = '#ff0044'; count.style.color = '#ff0044'; header.style.borderBottomColor = '#ff0044';
        if (contentBox) contentBox.className = 'tab-marks'; // Attach red class
    }
};
window.toggleItemTracer = function(key, tierColor = null) {
    window.playClickSound();
    let filterKey = tierColor ? `${key}_${tierColor}` : key;

    if (window.tracedItemKeys.has(filterKey)) {
        window.tracedItemKeys.delete(filterKey);
    } else {
        window.tracedItemKeys.add(filterKey);
    }
};

window.resetTracers = function() {
    window.playClickSound();
    window.tracedItemKeys.clear();
    notifyStatus("Item Tracers", "ALL DISABLED");
};

window.playClickSound = function() {
    try {
        if (!window.sharedAudioCtx) window.sharedAudioCtx = new (window.AudioContext || window.webkitAudioContext)();
        const audioCtx = window.sharedAudioCtx;
        const oscillator = audioCtx.createOscillator();
        const gainNode = audioCtx.createGain();
        oscillator.connect(gainNode);
        gainNode.connect(audioCtx.destination);
        oscillator.type = 'sine';
        oscillator.frequency.setValueAtTime(1200, audioCtx.currentTime);
        gainNode.gain.setValueAtTime(0.05, audioCtx.currentTime);
        gainNode.gain.exponentialRampToValueAtTime(0.01, audioCtx.currentTime + 0.1);
        oscillator.start();
        oscillator.stop(audioCtx.currentTime + 0.1);
    } catch (e) {}
};

window.handlePlayerAction = function(name) {
    window.playClickSound();
    if (window.ignoredPlayers.has(name)) {
        window.ignoredPlayers.delete(name);
    } else {
        window.ignoredPlayers.add(name);
    }
};

const statusNotify = document.createElement('div');
statusNotify.id = 'status-notify';
statusNotify.style = `
    position: fixed; bottom: 50px; left: -300px; padding: 10px 20px;
    background: rgba(0, 0, 0, 0.9); color: #00ff00; border-left: 5px solid #00ff00;
    font-family: 'Segoe UI', sans-serif; font-size: 13px; font-weight: bold;
    z-index: 10005; pointer-events: none; border-radius: 0 4px 4px 0;
    box-shadow: 5px 0 15px rgba(0,0,0,0.5); text-transform: uppercase; transition: left 0.3s ease-out;
`;
document.body.appendChild(statusNotify);

let statusTimer;
function notifyStatus(label, value) {
    statusNotify.innerHTML = `${label}: <span style="color:white">${value}</span>`;
    statusNotify.style.left = '0px';
    clearTimeout(statusTimer);
    statusTimer = setTimeout(() => {
        statusNotify.style.left = '-300px';
    }, 2000);
}

const matchDetection = /^function\(\){\w+\['\w+'\]\(\);}$/;
const setIntervalHandler = {
  apply: function(target, thisArg, argumentsList) {
    const callback = argumentsList[0];
    const delay = argumentsList[1];
    if (delay === 1000 && callback && callback.toString().match(matchDetection)) {
      return null;
    }
    return Reflect.apply(...arguments);
  }
};
window.setInterval = new Proxy(window.setInterval, setIntervalHandler);

// ==========================================
// 2. LIL-GUI MENU
// ==========================================
const lilGuiContainer = document.createElement('div');
lilGuiContainer.id = 'lil-gui';
document.body.appendChild(lilGuiContainer);

const GUI = lil.GUI;
const gui = new GUI({ container: lilGuiContainer, title: 'MICHAEL_GUN VIP' });

gui.onFinishChange(() => {
    const configToSave = gui.save();
    localStorage.setItem('espConfig', JSON.stringify(configToSave));
});

let espConfig = {
    aimbot: 2,
    silentAim: true,
    noRecoil: true,
    triggerBot: 2,
    allEnnemies: false,
    isSniper: false,
    aimbotIgnoreWall: false,
    maxAngleInRadians: 0.5,
    unlimitedAngle: false,
    heightLine: 1.16,
    sneakHeight: 0.4,
    showPlayer: 2,
    nameScaling: true,
    showPlayerNames: true,
    showEnemyNames: true,
    showRadar: true,
    showLine: 1,
    showOutline: 0,
    showBox: 0,
    ennemyDistance: 50,
    wireframe: 0,
    rainbow: false,
    showAimRadius: false,
    mapZoom: 100,
    mapOffsetZ: 0,
    autoClaimAds: false,
    antiAFK: false,
    sit: false,
    lockAimbotTriggerBot: false,
    triggerSound: false,
    triggerSoundType: 'water_drop',
    triggerSoundVolume: 0.5,
    showItems: true,
    showItemNames: true,
    markPosition: false,
    markKey: 'u',
    freecam: false,
    fcSpeed: 0.5,
    ghostESP: true,
    ghostTracers: true,
    zoomLevel: 20,
    isZooming: false,
    fZoomEnabled: false,
    aimbotKey: 'b', triggerBotKey: 't', toggleUIKey: '.', silentAimKey: '\\',
    antiAFKKey: 'k', rainbowKey: '=', showItemsKey: 'i', showItemNamesKey: 'n',
    freecamKey: 'alt', ghostKey: 'o', tracerKey: 'u', zoomKey: 'z'
};

const aimbotFolder = gui.addFolder('Aimbot 🎯');
aimbotFolder.add(espConfig, 'aimbot').name(`Aimbot (${espConfig.aimbotKey})`).options({Off: 0, LeftClick: 1, RightClick: 2, Always: 3}).listen();
aimbotFolder.add(espConfig, 'silentAim').name('Silent Aim ( \\ )      ').listen();
aimbotFolder.add(espConfig, 'noRecoil').name('No Recoil');
aimbotFolder.add(espConfig, 'triggerBot').name(`TriggerBot (${espConfig.triggerBotKey})`).options({Off: 0, LeftClick: 1, RightClick: 2, Always: 3}).listen();
aimbotFolder.add(espConfig, 'allEnnemies').name("All Enemies (L)").listen();
aimbotFolder.add(espConfig, 'isSniper');

const advancedAimbotFolder = aimbotFolder.addFolder('Advanced ⚙');
advancedAimbotFolder.close();
advancedAimbotFolder.add(espConfig, 'aimbotIgnoreWall');
advancedAimbotFolder.add(espConfig, 'showAimRadius');
advancedAimbotFolder.add(espConfig, 'maxAngleInRadians', 0.01, 0.5, 0.01);
advancedAimbotFolder.add(espConfig, 'unlimitedAngle').name('Unlimited Angle');
advancedAimbotFolder.add(espConfig, 'heightLine', .5, 1.25, 0.01);
advancedAimbotFolder.add(espConfig, 'sneakHeight', 0, 1, 0.01);

const chamsFolder = gui.addFolder('Chams 👁');
chamsFolder.close();
chamsFolder.add(espConfig, 'nameScaling').name('Auto Scale Names');
chamsFolder.add(espConfig, 'showPlayerNames').name('Show Team Names');
chamsFolder.add(espConfig, 'showEnemyNames').name('Show Enemy Names');
chamsFolder.add(espConfig, 'showRadar').name("Show Radar Panel 📡 ( ' )").listen();
chamsFolder.add(espConfig, 'showPlayer').options({Off: 0, Ennemies: 1, All: 2});
chamsFolder.add(espConfig, 'showLine').options({Off: 0, Ennemies: 1, All: 2});
chamsFolder.add(espConfig, 'showOutline').options({Off: 0, Ennemies: 1, All: 2});
chamsFolder.add(espConfig, 'showBox').options({Off: 0, Ennemies: 1, All: 2});
chamsFolder.add(espConfig, 'ennemyDistance', 10, 100, 1);
chamsFolder.add(espConfig, 'wireframe', { 'Off': 0, 'WebGL X-Ray': 1, 'Old Wireframe': 2 }).name("View Mode ( ; )").listen();
chamsFolder.add(espConfig, 'rainbow').name("Rainbow ( = )").listen();
chamsFolder.add(espConfig, 'mapZoom', 20, 100, 1);
chamsFolder.add(espConfig, 'mapOffsetZ', -50, 50, 1);
chamsFolder.add(espConfig, 'showItems').name(`Show Items (${espConfig.showItemsKey})`);
chamsFolder.add(espConfig, 'showItemNames').name(`Show Item Names (${espConfig.showItemNamesKey})`);

const fcFolder = gui.addFolder('Freecam 🎥');
fcFolder.add(espConfig, 'freecam').name(`Freecam 📹 (${espConfig.freecamKey.toUpperCase()})`).listen();
fcFolder.add(espConfig, 'ghostESP').name('Show Ghost Pos').listen();
fcFolder.add(espConfig, 'ghostTracers').name('Ghost Pos Tracer').listen();
fcFolder.add(espConfig, 'fcSpeed', 0.1, 5.0, 0.1).name('Fly Speed').listen();

const soundFolder = gui.addFolder('Sound 🔊');
soundFolder.close();
soundFolder.add(espConfig, 'triggerSound').name('Triggerbot Sound');
soundFolder.add(espConfig, 'triggerSoundType', [
    'water_drop', 'bubble', 'plop', 'ocean_ping', 'wood_block', 'marimba', 'bamboo', 'kalimba',
    'glass_tap', 'chime', 'tiny_bell', 'coin', 'flute', 'harp', 'mellow', 'ambient',
    'soft_pop', 'ui_click', 'tick', 'hollow'
]).name('Sound Type');
soundFolder.add(espConfig, 'triggerSoundVolume', 0.1, 1, 0.1).name('Volume');

const zoomFolder = gui.addFolder('Zoom Features 🔍');
zoomFolder.add(espConfig, 'isZooming').name('Zooming (Z)').listen();
zoomFolder.add(espConfig, 'zoomLevel', 1, 178, 1).name('Zoom Level (FOV)').listen();
zoomFolder.add(espConfig, 'fZoomEnabled').name('Enable F Zoom').listen();
zoomFolder.add(espConfig, 'zoomKey').name('Zoom Key');

const toolsFolder = gui.addFolder('Tools 🛠');
toolsFolder.close();
toolsFolder.add(espConfig, 'autoClaimAds');
toolsFolder.add(espConfig, 'antiAFK').name(`Anti-AFK & auto dig (${espConfig.antiAFKKey})`).listen();
toolsFolder.add(espConfig, 'sit').name('Sit Mode (V)');
toolsFolder.add(espConfig, 'lockAimbotTriggerBot');
toolsFolder.add(espConfig, 'markPosition').name('Allow (U) to Mark').listen();

const savedConfig = localStorage.getItem('espConfig');
if (savedConfig) {
    gui.load(JSON.parse(savedConfig));
    if (espConfig.wireframe === true) espConfig.wireframe = 2;
    if (espConfig.wireframe === false) espConfig.wireframe = 0;
}

// FORCE CLOSE MENUS ON START
gui.close();
aimbotFolder.close();
fcFolder.close();
zoomFolder.close();

// ==========================================
// 3. KEY BINDINGS & FREECAM HANDLING
// ==========================================
let fcYaw = 0, fcPitch = 0;
let fcKeys = { w: false, a: false, s: false, d: false, space: false, shift: false };
const savedGhostPos = new THREE.Vector3();
let savedGhostRot = 0;

let savedMarkPos = null;
let markSprite = null;

const fcCamera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
fcCamera.rotation.order = 'YXZ';

document.addEventListener('keydown', (e) => {
    const isInputField = e.target && (e.target.isContentEditable || e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement);
    if (isInputField) return;

    const key = e.key;
    const keyL = e.key.toLowerCase();
    const modes = ["OFF", "LeftClick", "RightClick", "Always"];

    if (keyL === espConfig.freecamKey.toLowerCase()) {
        e.preventDefault();
        espConfig.freecam = !espConfig.freecam;
        fcKeys = { w: false, a: false, s: false, d: false, space: false, shift: false };
        notifyStatus("Freecam", espConfig.freecam ? "ON" : "OFF");
    }

    switch (keyL) {
        case espConfig.markKey:
            // If checkbox is off -> Break, no actions or notifications
            if (!espConfig.markPosition) break;

            // If allowed -> Process the mark normally
            if (typeof camera !== 'undefined' && camera.position) {
                let pos = camera.position.clone();
                pos.y -= 1;
                let id = Date.now();
                let sprite = null;
                let pointName = `📍 MARK NO. ${window.savedMarks.length + 1}`;
                if (typeof makeTextSprite === 'function') {
                    sprite = makeTextSprite(pointName, "#ff0044");
                    if (typeof scene !== 'undefined') scene.add(sprite);
                }
                window.savedMarks.push({ id: id, pos: pos, sprite: sprite, active: true, name: pointName, isLocked: false });
                notifyStatus("Mark", "ADDED 1 NEW MARK");
                window.playClickSound();
            }
            break;

        case espConfig.rainbowKey: espConfig.rainbow = !espConfig.rainbow; notifyStatus("Rainbow", espConfig.rainbow ? "ON" : "OFF"); break;
        case 'n':
            espConfig.showItemNames = !espConfig.showItemNames;
            notifyStatus("Show Item Names", espConfig.showItemNames ? "ON" : "OFF");
            break;
        case '\\':
            espConfig.silentAim = !espConfig.silentAim;
            notifyStatus("Silent Aim", espConfig.silentAim ? "ON" : "OFF");
            break;
        case 'k': espConfig.antiAFK = !espConfig.antiAFK; notifyStatus("Anti-AFK", espConfig.antiAFK ? "ON" : "OFF"); break;
        case 'i': espConfig.showItems = !espConfig.showItems; notifyStatus("Show Items", espConfig.showItems ? "ON" : "OFF"); break;
        case 'b': if (!espConfig.lockAimbotTriggerBot) { espConfig.aimbot = (espConfig.aimbot + 1) % 4; notifyStatus("Aimbot", modes[espConfig.aimbot]); } break;
        case espConfig.zoomKey.toLowerCase(): espConfig.isZooming = true; break;
        case 't': if (!espConfig.lockAimbotTriggerBot) { espConfig.triggerBot = (espConfig.triggerBot + 1) % 4; notifyStatus("TriggerBot", modes[espConfig.triggerBot]); } break;
        case 'l': espConfig.allEnnemies = !espConfig.allEnnemies; notifyStatus("All Enemies", espConfig.allEnnemies ? "ON" : "OFF"); break;
        case 'f': if (espConfig.fZoomEnabled) espConfig.isZooming = true; break;
        case ';':
            espConfig.wireframe = (espConfig.wireframe + 1) % 3;
            let wfMode = espConfig.wireframe === 0 ? "OFF" : (espConfig.wireframe === 1 ? "WEBGL X-RAY" : "OLD WIREFRAME");
            notifyStatus("View Mode", wfMode);
            break;
        case 'v': espConfig.sit = !espConfig.sit; notifyStatus("Sit Mode", espConfig.sit ? "ON" : "OFF"); break;
        case "'":
            espConfig.showRadar = !espConfig.showRadar; notifyStatus("Radar", espConfig.showRadar ? "ON" : "OFF");
            const radar = document.getElementById('side-player-list');
            if (radar) radar.style.display = espConfig.showRadar ? 'block' : 'none';
            break;
        case espConfig.toggleUIKey: lilGuiContainer.style.display = lilGuiContainer.style.display === 'none' ? 'block' : 'none'; break;
        case 'e': if (espConfig.autoClaimAds) setTimeout(claimAds, 100); break;
    }
    if (typeof gui !== 'undefined') gui.controllersRecursive().forEach(c => c.updateDisplay());
});

window.addEventListener('keydown', (e) => {
    if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') return;
    if (espConfig.freecam) {
        if (e.code === 'KeyW') { fcKeys.w = true; e.stopImmediatePropagation(); }
        if (e.code === 'KeyA') { fcKeys.a = true; e.stopImmediatePropagation(); }
        if (e.code === 'KeyS') { fcKeys.s = true; e.stopImmediatePropagation(); }
        if (e.code === 'KeyD') { fcKeys.d = true; e.stopImmediatePropagation(); }
        if (e.code === 'Space') { fcKeys.space = true; e.stopImmediatePropagation(); }
        if (e.code === 'ShiftLeft' || e.code === 'ShiftRight') { fcKeys.shift = true; e.stopImmediatePropagation(); }
    }
}, true);
window.addEventListener('keyup', (e) => {
    if (espConfig.freecam) {
        if (e.code === 'KeyW') { fcKeys.w = false; e.stopImmediatePropagation(); }
        if (e.code === 'KeyA') { fcKeys.a = false; e.stopImmediatePropagation(); }
        if (e.code === 'KeyS') { fcKeys.s = false; e.stopImmediatePropagation(); }
        if (e.code === 'KeyD') { fcKeys.d = false; e.stopImmediatePropagation(); }
        if (e.code === 'Space') { fcKeys.space = false; e.stopImmediatePropagation(); }
        if (e.code === 'ShiftLeft' || e.code === 'ShiftRight') { fcKeys.shift = false; e.stopImmediatePropagation(); }
    }
}, true);
document.addEventListener('mousemove', (e) => {
    if (!espConfig.freecam || document.pointerLockElement == null) return;
    fcYaw -= e.movementX * 0.002; fcPitch -= e.movementY * 0.002;
    fcPitch = Math.max(-Math.PI / 2, Math.min(Math.PI / 2, fcPitch));
    fcCamera.quaternion.setFromEuler(new THREE.Euler(fcPitch, fcYaw, 0, 'YXZ'));
    e.stopImmediatePropagation();
}, true);

// ==========================================
// 4. SOUND & MOUSE INPUTS
// ==========================================
let audioContext = null;
let lastSoundTime = 0;
function createTriggerSound(type, volume) {
    if (!audioContext) audioContext = new (window.AudioContext || window.webkitAudioContext)();
    if (Date.now() - lastSoundTime < 80) return;
    lastSoundTime = Date.now();
    const t = audioContext.currentTime;
    const gainNode = audioContext.createGain();
    const oscillator = audioContext.createOscillator();
    gainNode.gain.setValueAtTime(volume, t);
    gainNode.gain.exponentialRampToValueAtTime(0.001, t + 0.15);
    gainNode.connect(audioContext.destination);
    oscillator.connect(gainNode);

    switch(type) {
        case 'water_drop': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(800, t); break;
        case 'bubble': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(400, t); oscillator.frequency.exponentialRampToValueAtTime(600, t + 0.1); break;
        case 'plop': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(600, t); oscillator.frequency.exponentialRampToValueAtTime(300, t + 0.1); break;
        case 'ocean_ping': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(1200, t); break;
        case 'wood_block': oscillator.type = 'triangle'; oscillator.frequency.setValueAtTime(600, t); break;
        case 'marimba': oscillator.type = 'triangle'; oscillator.frequency.setValueAtTime(450, t); break;
        case 'bamboo': oscillator.type = 'triangle'; oscillator.frequency.setValueAtTime(1000, t); break;
        case 'kalimba': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(850, t); break;
        case 'glass_tap': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(2000, t); break;
        case 'chime': oscillator.type = 'triangle'; oscillator.frequency.setValueAtTime(1400, t); break;
        case 'tiny_bell': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(2500, t); break;
        case 'coin': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(1800, t); oscillator.frequency.linearRampToValueAtTime(1750, t + 0.1); break;
        case 'flute': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(900, t); break;
        case 'harp': oscillator.type = 'triangle'; oscillator.frequency.setValueAtTime(1100, t); break;
        case 'mellow': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(250, t); break;
        case 'ambient': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(1600, t); break;
        case 'soft_pop': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(700, t); oscillator.frequency.exponentialRampToValueAtTime(400, t + 0.05); break;
        case 'ui_click': oscillator.type = 'sine'; oscillator.frequency.setValueAtTime(1500, t); gainNode.gain.exponentialRampToValueAtTime(0.001, t + 0.05); break;
        case 'tick': oscillator.type = 'triangle'; oscillator.frequency.setValueAtTime(3000, t); gainNode.gain.exponentialRampToValueAtTime(0.001, t + 0.03); break;
        case 'hollow': oscillator.type = 'square'; oscillator.frequency.setValueAtTime(350, t); gainNode.gain.exponentialRampToValueAtTime(0.001, t + 0.08); break;
    }
    oscillator.start(t);
    oscillator.stop(t + 0.15);
}
function playTriggerSound() {
    if (espConfig.triggerSound) createTriggerSound(espConfig.triggerSoundType, espConfig.triggerSoundVolume);
}

let isLeftClick = false; let isRightClick = false;
document.addEventListener('mousedown', (e) => { if (e.button === 0) isLeftClick = true; if (e.button === 2) isRightClick = true; });
document.addEventListener('mouseup', (e) => { if (e.button === 0) isLeftClick = false; if (e.button === 2) isRightClick = false; });

// ==========================================
// SAFE NO RECOIL FIX (100% NO CRASH)
// ==========================================
let foundRecoil = false;
let originalRecoilVal = 0.3;
Array.prototype.push = new Proxy(Array.prototype.push, {
  apply: function(target, thisArg, argumentsList) {
    if (!foundRecoil && argumentsList.length === 1 && typeof argumentsList[0] === 'object') {
      const item = argumentsList[0];
      if (item && Object.keys(item).length === 44) {
        for (const key in item) {
            if (item[key] === 0.3) {
                foundRecoil = true;
                Object.defineProperty(Object.prototype, key, {
                    get: () => espConfig.noRecoil ? 0 : originalRecoilVal,
                    set: (v) => { originalRecoilVal = v; }
                });
                break;
            }
        }
      }
    }
    return Reflect.apply(...arguments);
  }
});

// ==========================================
// 5. THREE.JS & GHOST OVERLAY SETUP
// ==========================================
let worldScene = null, childrenKey = null, worldCamera = null;
let projectionMatrixKey = null, matrixWorldKey = null, matrixElKey = null;

let originalCameraRotation = new THREE.Euler();
let isSilentSnapped = false;

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.rotation.order = 'YXZ';

let saveViewport = new THREE.Vector4();
let saveScissor = new THREE.Vector4();
let minimapViewport = new THREE.Vector4(20, window.innerHeight - 250 - 20, 250, 250);
const minimapCamera = new THREE.OrthographicCamera(-espConfig.mapZoom, espConfig.mapZoom, espConfig.mapZoom, -espConfig.mapZoom, 0.1, 1000);
minimapCamera.rotation.order = 'YXZ';
minimapCamera.position.set(0, 50, 0); minimapCamera.lookAt(0, 0, 0);

const renderer = new THREE.WebGLRenderer({ alpha: true, antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.domElement.id = 'overlayCanvas';
document.body.appendChild(renderer.domElement);

const ghostGroup = new THREE.Group();
ghostGroup.frustumCulled = false;
const boxGeo = new THREE.BoxGeometry(0.55, 1.4, 0.55).translate(0, 0.7, 0);
const ghostMesh = new THREE.Mesh(boxGeo, new THREE.MeshBasicMaterial({ color: 0xffff00, transparent: true, opacity: 0.35, depthTest: false }));
ghostMesh.frustumCulled = false; ghostGroup.add(ghostMesh);
const ghostEdges = new THREE.LineSegments(new THREE.EdgesGeometry(boxGeo), new THREE.LineBasicMaterial({ color: 0xffff00, depthTest: false, linewidth: 2 }));
ghostEdges.frustumCulled = false; ghostGroup.add(ghostEdges);

function createGhostSprite() {
    const canvas = document.createElement('canvas'); const ctx = canvas.getContext('2d');
    const fontsize = 120; ctx.font = "Bold " + fontsize + "px Arial"; const text = "ORIGINAL POS";
    const metrics = ctx.measureText(text); canvas.width = metrics.width + 60; canvas.height = fontsize * 1.5;
    ctx.font = "Bold " + fontsize + "px Arial"; ctx.textBaseline = "middle"; ctx.textAlign = "center";
    ctx.fillStyle = "rgba(0, 0, 0, 0.6)"; ctx.fillRect(0, 0, canvas.width, canvas.height);
    ctx.fillStyle = "#ffcc00"; ctx.fillText(text, canvas.width / 2, canvas.height / 2);
    const texture = new THREE.CanvasTexture(canvas); texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter;
    const sprite = new THREE.Sprite(new THREE.SpriteMaterial({ map: texture, depthTest: false }));
    const ratio = canvas.width / canvas.height; sprite.scale.set(0.6 * ratio, 0.6, 1); sprite.frustumCulled = false;
    return sprite;
}
ghostGroup.add(createGhostSprite().translateY(1.9));

const viewArrow = new THREE.ArrowHelper(new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 1.4, 0), 1.2, 0xffff00, 0.4, 0.3);
viewArrow.line.material.depthTest = false; viewArrow.cone.material.depthTest = false;
viewArrow.line.frustumCulled = false; viewArrow.cone.frustumCulled = false;
ghostGroup.add(viewArrow); scene.add(ghostGroup);

const lineGeometry = new THREE.BufferGeometry();
const lineMaterial = new THREE.LineBasicMaterial({ vertexColors: true, transparent: true });
const line = new THREE.LineSegments(lineGeometry, lineMaterial);
line.frustumCulled = false; scene.add(line);

function setTransform(target, transform, isMatrix = true) {
    const matrix = new THREE.Matrix4().fromArray(isMatrix ? transform : transform[matrixWorldKey][matrixElKey]);
    matrix.decompose(target.position, target.quaternion, target.scale);
}

// ==========================================
// 6. GAME CORE HOOK (SILENT AIM INTEGRATION)
// ==========================================
function checkWorldCamera(object) {
    if (worldCamera && object.uuid === worldCamera.uuid) return;
    let hasProjectionMatrix = false;
    for (const key in object) {
        const element = object[key];
        if (!element) continue;
        if (typeof element == 'object') {
            const valueKey = Object.keys(element)[0];
            if (Array.isArray(element[valueKey]) && element[valueKey][11] === -1) {
                hasProjectionMatrix = true; matrixElKey = valueKey; projectionMatrixKey = key;
            }
        } else if (typeof element === 'function') {
            const match = /verse'\]\(this\['([^']+)'\]\);/.exec(element.toString());
            if (match) matrixWorldKey = match[1];
        }

        if (hasProjectionMatrix && matrixWorldKey) {
            worldCamera = object;
            object[projectionMatrixKey] = new Proxy(object[projectionMatrixKey], {
                get: function(target, prop) {

                    if (espConfig.silentAim && isSilentSnapped && worldCamera) {
                        worldCamera.rotation.copy(originalCameraRotation);
                        worldCamera.updateMatrixWorld(true);
                        isSilentSnapped = false;
                    }

                    camera.near = worldCamera.near; camera.far = worldCamera.far;
                    camera.aspect = window.innerWidth / window.innerHeight;
                    camera.fov = espConfig.isZooming ? espConfig.zoomLevel : (worldCamera.fov || 60);
                    camera.updateProjectionMatrix();

                    if (!espConfig.freecam) {
                        setTransform(camera, worldCamera, false);
                    } else {
                        camera.position.copy(fcCamera.position); camera.quaternion.copy(fcCamera.quaternion);
                        camera.updateMatrixWorld(true);
                    }
                    camera.matrixWorldInverse.copy(camera.matrixWorld).invert();
                    window.worldCamera = object;
                    return Reflect.get(...arguments);
                }
            });

            const realElements = object[matrixWorldKey][matrixElKey];
            object[matrixWorldKey][matrixElKey] = new Proxy(realElements, {
                get: function(target, prop) {
                    if (espConfig.freecam && typeof prop !== 'symbol' && !isNaN(prop)) {
                        const idx = Number(prop);
                        if (idx >= 0 && idx < 16) return fcCamera.matrixWorld.elements[idx];
                    }
                    return target[prop];
                }
            });
            break;
        }
    }
}

function checkWorldScene(object) {
    if (worldScene || object instanceof THREE.Scene) return;
    for (const key in object) {
        const element = object[key];
        if (!element) continue;
        if (Array.isArray(element) && element.length === 9 && element[0] && element[0].hasOwnProperty('uuid')) childrenKey = key;

        if (childrenKey) {
            worldScene = object; window.worldScene = object;
            renderer.setAnimationLoop(animate);
            break;
        }
    }
}

Object.defineProperty( Object.prototype, 'overrideMaterial', {
    get: function() { checkWorldScene(this); return this._overrideMaterial; }, set: function(value) { this._overrideMaterial = value; }
});
Object.defineProperty( Object.prototype, 'far', {
    get: function() { checkWorldCamera(this); return this._far; }, set: function(value) { this._far = value; }
});

function isPlayer(entity) { try { return entity[childrenKey].length > 2 || !entity[childrenKey][1].geometry; } catch { return false; } }

function isItem(entity) { try { return !isPlayer(entity) && entity[childrenKey] && entity[childrenKey].some(c => c.geometry || (c[childrenKey] && c[childrenKey].length > 0)); } catch { return false; } }

function claimAds() {
    document.querySelectorAll('svg').forEach(svg => { if (svg.getAttribute('data-icon') === 'play-circle') svg.closest('div').click(); });
}

// [NEW UPDATE] FIX CANVAS NAME READING
CanvasRenderingContext2D.prototype.fillText = new Proxy(CanvasRenderingContext2D.prototype.fillText, {
    apply: function(target, thisArg, argumentsList) {
        if (thisArg && thisArg.canvas) {
            let text = String(argumentsList[0]);
            if (text && text.trim().length > 0) {
                if (!thisArg.canvas.txtH) thisArg.canvas.txtH = [];
                // Save last 5 lines to prevent overrides like "Press E"
                if (thisArg.canvas.txtH[thisArg.canvas.txtH.length - 1] !== text) {
                    thisArg.canvas.txtH.push(text);
                    if (thisArg.canvas.txtH.length > 5) thisArg.canvas.txtH.shift();
                }
            }
        }
        return Reflect.apply(...arguments);
    }
});

function isEnnemy(entity) {
    for (const child of entity[childrenKey]) {
        try {
            if (child.material.map.image instanceof HTMLCanvasElement) {
                // Game player label is different, safe to keep original style here
                entity.playerName = child.material.map.image.txtH ? child.material.map.image.txtH[child.material.map.image.txtH.length-1] : "Unknown";
                return false;
            }
        } catch {}
    }
    return true;
}

let lastFiringState = false;
function setFiring(shouldFire) {
    if (setFiring.firing === shouldFire) return;
    setFiring.firing = shouldFire;
    if (shouldFire && !lastFiringState) playTriggerSound();
    lastFiringState = shouldFire;

    if (shouldFire) { document.dispatchEvent(new MouseEvent('mousedown', { buttons: 3 }));
    } else { document.dispatchEvent(new MouseEvent('mouseup', { buttons: 0 })); }
}

const colors = { ennemy: new THREE.Color(0xff0000), player: new THREE.Color(0x00ff00), blue: new THREE.Color(0x0000ff) };
const outlineMats = { ennemy: new THREE.LineBasicMaterial({ color: colors.ennemy }), player: new THREE.LineBasicMaterial({ color: colors.player }) };
const meshMats = {
    ennemy: new THREE.MeshBasicMaterial({ color: colors.ennemy, transparent: true, opacity: 0.5 }),
    player: new THREE.MeshBasicMaterial({ color: colors.player, transparent: true, opacity: 0.5 })
};

// ==========================================
// ITEM BOX MATERIAL SETUP (AUTO COLOR)
// ==========================================
const glassBoxGeo = new THREE.BoxGeometry(0.3, 0.3, 0.3);
const glassEdgesGeo = new THREE.EdgesGeometry(glassBoxGeo);

const itemColorMap = [
    { keywords: ["mythic"], hex: 0xff0000, str: "#ff0000" },      // Red
    { keywords: ["legendary", "gold"], hex: 0xffaa00, str: "#ffaa00" }, // Gold
    { keywords: ["epic"], hex: 0xaa00ff, str: "#aa00ff" },        // Purple
    { keywords: ["rare"], hex: 0x0088ff, str: "#0088ff" },        // Blue
    { keywords: ["uncommon"], hex: 0x00ff00, str: "#00ff00" },    // Green
    { keywords: ["shield", "potion", "medical"], hex: 0x00ffcc, str: "#00ffcc" }, // Health/Shield
    { keywords: ["ammo"], hex: 0xffff00, str: "#ffff00" },        // Ammo (Yellow)
    { keywords: ["rifle", "shotgun", "pistol", "sniper", "submachine", "gun", "shovel", "pickaxe"], hex: 0xff5500, str: "#ff5500" } // Weapons & Tools (Orange)
];
const defaultColor = { hex: 0xffffff, str: "#ffffff" }; // Default White
// ==========================================
const raycaster = new THREE.Raycaster();
const edgesGeometry = new THREE.EdgesGeometry(new THREE.BoxGeometry(1, 1, 1).translate(0, 0.5, 0));
const dummyLookAt = new THREE.PerspectiveCamera(); const color = new THREE.Color();
const chunkMaterial = new THREE.MeshNormalMaterial(); const boxPlayerGeometry = new THREE.BoxGeometry(.25, 1.25, 0.25);
const crosshair = new THREE.LineLoop(new THREE.CircleGeometry(.5, 32), new THREE.LineBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.2 }));
camera.add(crosshair); scene.add(camera);

const myCenterArrowGroup = new THREE.Group();
const myArrow = new THREE.ArrowHelper(new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 0, 0), 2, 0xffffff, 1.2, 1);
myArrow.line.material.depthTest = false;
myArrow.cone.material.depthTest = false;
myCenterArrowGroup.add(myArrow);
myCenterArrowGroup.visible = false;
scene.add(myCenterArrowGroup);

function calculateValue(maxAngleInRadians) { return -79.83 * Math.exp(-30.06 * maxAngleInRadians) - 0.90; }

function makeTextSprite(message, colorStr) {
    const canvas = document.createElement('canvas'); const context = canvas.getContext('2d');
    const fontsize = 120; context.font = "Bold " + fontsize + "px Arial";
    const metrics = context.measureText(message);
    canvas.width = metrics.width + 60; canvas.height = fontsize * 1.5;
    context.font = "Bold " + fontsize + "px Arial"; context.textBaseline = "middle"; context.textAlign = "center";
    context.fillStyle = "rgba(0, 0, 0, 0.7)"; context.fillRect(0, 0, canvas.width, canvas.height);
    context.fillStyle = colorStr; context.fillText(message, canvas.width / 2, canvas.height / 2);
    const texture = new THREE.CanvasTexture(canvas); texture.minFilter = THREE.LinearFilter; texture.magFilter = THREE.LinearFilter;
    const sprite = new THREE.Sprite(new THREE.SpriteMaterial({ map: texture, depthTest: false, depthWrite: false }));
    sprite.initialRatio = (canvas.width / canvas.height); return sprite;
}
function createItemSprite(text, colorStr) { return makeTextSprite(text, colorStr); }

// ==========================================
// 7. ANIMATE LOOP (MAIN RENDERER)
// ==========================================
function animate(time) {
    const now = Date.now();

    // 1. CLEAR COUNTER EVERY FRAME (Crucial for static Radar)
    window.nearbyItemCounts.clear();

    // FIX SILENT AIM: Save real angle before anything
    if (worldCamera && !isSilentSnapped) {
        originalCameraRotation.copy(worldCamera.rotation);
    }

    if (worldCamera && matrixWorldKey && matrixElKey) {
        if (!espConfig.freecam) {
            const rawMatrix = worldCamera[matrixWorldKey][matrixElKey];
            const camMat = new THREE.Matrix4().fromArray(rawMatrix);
            savedGhostPos.setFromMatrixPosition(camMat);
            savedGhostRot = new THREE.Euler().setFromRotationMatrix(camMat, 'YXZ').y;
            fcCamera.position.copy(savedGhostPos); fcCamera.quaternion.setFromRotationMatrix(camMat);
            fcYaw = savedGhostRot; fcPitch = new THREE.Euler().setFromRotationMatrix(camMat, 'YXZ').x;
            ghostGroup.visible = false;
        } else {
            let direction = new THREE.Vector3();
            if (fcKeys.w) direction.z -= 1; if (fcKeys.s) direction.z += 1;
            if (fcKeys.a) direction.x -= 1; if (fcKeys.d) direction.x += 1;
            direction.normalize(); direction.applyEuler(new THREE.Euler(0, fcYaw, 0, 'YXZ'));
            direction.multiplyScalar(espConfig.fcSpeed); fcCamera.position.add(direction);
            if (fcKeys.space) fcCamera.position.y += espConfig.fcSpeed;
            if (fcKeys.shift) fcCamera.position.y -= espConfig.fcSpeed;
            fcCamera.updateMatrixWorld();
            if (espConfig.ghostESP) {
                ghostGroup.visible = true; ghostGroup.position.set(savedGhostPos.x, savedGhostPos.y - 1.4, savedGhostPos.z);
                ghostGroup.rotation.set(0, savedGhostRot, 0); ghostGroup.updateMatrixWorld(true);
            } else { ghostGroup.visible = false; }
        }
    }

    camera.updateMatrixWorld(true);

    const lineOrigin = camera.localToWorld(new THREE.Vector3(0, 0, -2));
    const entities = childrenKey ? worldScene[childrenKey][5][childrenKey] : [];
    const linePositions = [];
    crosshair.position.z = calculateValue(espConfig.maxAngleInRadians);
    crosshair.visible = espConfig.showAimRadius && !espConfig.unlimitedAngle;

    const colorArray = [];
    const aimbotTarget = { angleDifference: Infinity, priority: -1, target: null };
    const chunks = [];
    const gameChunks = childrenKey ? worldScene[childrenKey][4][childrenKey] : [];

    if (espConfig.freecam && espConfig.ghostTracers) {
        linePositions.push(lineOrigin.x, lineOrigin.y, lineOrigin.z);
        linePositions.push(savedGhostPos.x, savedGhostPos.y - 0.7, savedGhostPos.z);
        colorArray.push(1, 1, 0, 0.8, 1, 1, 0, 0.8);
    }

    if (espConfig.markPosition && window.savedMarks.length > 0) {
        window.savedMarks.forEach(m => {
            if (m.sprite) {
                m.sprite.visible = m.active;
                if (m.active) {
                    m.sprite.position.copy(m.pos);
                    m.sprite.position.y += 1.5;
                    let distToMark = camera.position.distanceTo(m.pos);
                    let finalScale = distToMark * 0.05; if (finalScale < 0.8) finalScale = 0.8;
                    m.sprite.scale.set(finalScale * m.sprite.initialRatio, finalScale, 1);
                }
            }
            if (m.active) {
                linePositions.push(lineOrigin.x, lineOrigin.y, lineOrigin.z);
                linePositions.push(m.pos.x, m.pos.y, m.pos.z);
                colorArray.push(1, 0, 0.3, 0.8, 1, 0, 0.3, 0.8);
            }
        });
    }

    for (const chunk of gameChunks) {
        if (!chunk || !chunk.geometry || !chunk.geometry.attributes.position.array.length) continue;
        if (!chunk.myChunk) {
            const geometry = new THREE.BufferGeometry();
            geometry.setAttribute('position', new THREE.Float32BufferAttribute(chunk.geometry.attributes.position.array, 3));
            geometry.setIndex(new THREE.BufferAttribute(chunk.geometry.index.array, 1));
            geometry.computeVertexNormals(); geometry.computeBoundingBox();
            chunk.myChunk = new THREE.Mesh(geometry, chunkMaterial);
            chunk.myChunk.box = new THREE.Box3();
        }
        const myChunk = chunk.myChunk;

        if (chunk.material) chunk.material.wireframe = (espConfig.wireframe === 2);

        setTransform(myChunk, chunk, false);
        myChunk.updateMatrixWorld();
        myChunk.box.copy(myChunk.geometry.boundingBox).applyMatrix4(myChunk.matrixWorld);
        chunks.push(myChunk);
    }

    chunks.sort((a, b) => b.position.distanceTo(camera.position) - a.position.distanceTo(camera.position));
    const shouldAimbot = espConfig.aimbot === 3 || (espConfig.aimbot === 1 && isLeftClick) || (espConfig.aimbot === 2 && isRightClick);

    entities.forEach(entity => {
        if (!entity || !entity.parent) return;

        if (!entity.myObject3D) {
            entity.myObject3D = new THREE.Object3D(); entity.myObject3D.frustumCulled = false;
            entity.discovered = now; entity.loaded = false; entity.logged = false; entity.ennemy = null; return;
        }
        if (typeof entity.visible === 'boolean' && !entity.visible) { entity.myObject3D.visible = false; return; }
        if (!entity.loaded && now - entity.discovered < 500) return;
        entity.loaded = true;

        if (entity.myObject3D) {
            const entityKey = entity.id || entity.playerName || "unknown";
            const currentPos = entity.myObject3D.position.clone();
            if (window.lastPositions.has(entityKey)) {
                const lastPos = window.lastPositions.get(entityKey);
                if (!entity.velocity) entity.velocity = new THREE.Vector3(0, 0, 0);
                entity.velocity.lerp(new THREE.Vector3().subVectors(currentPos, lastPos), 0.4);
            }
            window.lastPositions.set(entityKey, currentPos.clone());
        }

        if (isPlayer(entity)) {
            if (!entity.logged) {
                const skinnedMesh = entity[childrenKey][1][childrenKey][3];
                entity.isPlayer = true; entity.logged = true; entity.ennemy = isEnnemy(entity);
                const playerMesh = new THREE.Mesh(skinnedMesh.geometry, entity.ennemy ? meshMats.ennemy : meshMats.player);
                entity.myObject3D.add(playerMesh); entity.myObject3D.playerMesh = playerMesh;
                const playerMiniMap = new THREE.Mesh(skinnedMesh.geometry, entity.ennemy ? meshMats.ennemy : meshMats.player);
                playerMiniMap.visible = false; entity.myObject3D.add(playerMiniMap); entity.myObject3D.playerMiniMap = playerMiniMap;
                const outline = new THREE.LineSegments(edgesGeometry, entity.ennemy ? outlineMats.ennemy : outlineMats.player);
                outline.scale.set(0.5, 1.25, 0.5); outline.frustumCulled = false; entity.myObject3D.add(outline); entity.myObject3D.outline = outline;
                const boxMesh = new THREE.Mesh(boxPlayerGeometry, entity.ennemy ? meshMats.ennemy : meshMats.player);
                boxMesh.position.y = 0.625; entity.myObject3D.add(boxMesh); entity.myObject3D.boxMesh = boxMesh;
                playerMiniMap.add(new THREE.ArrowHelper(new THREE.Vector3(0, 0, -1), new THREE.Vector3(0, 1, 0), 1, entity.ennemy ? colors.ennemy : colors.player, 0.5, .4));
                setTransform(entity.myObject3D, entity, false); scene.add(entity.myObject3D);
            }

            if (entity.playerName) {
                const dist = Math.round(camera.position.distanceTo(entity.myObject3D.position));
                let playerColor = entity.playerName.toLowerCase().includes("soldier#") ? "#ff0000" : (entity.ennemy ? "#ff4444" : "#44ff44");
                let playerArrow = "•";
                try {
                    const dirX = entity.myObject3D.position.x - camera.position.x; const dirZ = entity.myObject3D.position.z - camera.position.z;
                    const camDir = new THREE.Vector3(); camera.getWorldDirection(camDir);
                    let angle = Math.atan2(dirX, dirZ) - Math.atan2(camDir.x, camDir.z);
                    let deg = angle * (180 / Math.PI); if (deg < 0) deg += 360;
                    if (deg > 337.5 || deg <= 22.5) playerArrow = "↑";
                    else if (deg > 22.5 && deg <= 67.5) playerArrow = "↗";
                    else if (deg > 67.5 && deg <= 112.5) playerArrow = "→";
                    else if (deg > 112.5 && deg <= 157.5) playerArrow = "↘";
                    else if (deg > 157.5 && deg <= 202.5) playerArrow = "↓";
                    else if (deg > 202.5 && deg <= 247.5) playerArrow = "↙";
                    else if (deg > 247.5 && deg <= 292.5) playerArrow = "←";
                    else if (deg > 292.5 && deg <= 337.5) playerArrow = "↖";
                } catch(err) {}
                window.playerMap.set(entity.playerName, { dist, color: playerColor, arrow: playerArrow });
            }

            try {
                entity.myObject3D.playerMesh.rotation.y = -entity[childrenKey][1].rotation._y;
                entity.myObject3D.playerMiniMap.rotation.y = -entity[childrenKey][1].rotation._y;
                const isSneak = entity[childrenKey][1][childrenKey][3].skeleton.bones[4].rotation._x > 0.1;
                entity.myObject3D.boxMesh.scale.set(1, isSneak ? .4 : 1, 1);
                entity.myObject3D.outline.scale.set(0.5, isSneak ? .9 : 1.25, 0.5);
                entity.myObject3D.playerMesh.scale.set(1, isSneak ? .7 : 1, 1);

                entity.myObject3D.visible = true;
                entity.myObject3D.playerMesh.visible = espConfig.showPlayer === 2 || (espConfig.showPlayer === 1 && !entity.ennemy);
                entity.myObject3D.boxMesh.visible = espConfig.showBox === 2 || (espConfig.showBox === 1 && entity.ennemy);
                entity.myObject3D.outline.visible = espConfig.showOutline === 2 || (espConfig.showOutline === 1 && entity.ennemy);

                setTransform(entity.myObject3D, entity, false);

                // --- START WEAPON PRIORITY SENSOR ---
                let totalHeldSize = 0;
                const scanWeapon = (obj) => {
                    if (obj === entity.myObject3D) return;
                    if (obj.material && obj.material.map && obj.material.map.image instanceof HTMLCanvasElement) return;
                    if (obj.type === 'Sprite' || obj.isSprite) return;

                    if (obj.geometry && obj.geometry.attributes && obj.geometry.attributes.position) {
                        totalHeldSize += obj.geometry.attributes.position.count;
                    }
                    if (obj && obj[childrenKey] && obj[childrenKey].length > 0) {
                        for (let child of obj[childrenKey]) scanWeapon(child);
                    }
                };
                scanWeapon(entity);

                let currentPriority = 1;
                const aimbotPriority1 = [7533, 5619, 6823, 6451, 8257, 6715];
                const aimbotPriority2 = [7598, 7173, 4903, 6747, 8666];

                let checkSizes = [totalHeldSize, totalHeldSize - 462, totalHeldSize - 224];
                for (let s of checkSizes) {
                    if (aimbotPriority1.includes(s)) { currentPriority = 3; break; }
                    if (aimbotPriority2.includes(s)) { currentPriority = 2; break; }
                }
                // --- END WEAPON PRIORITY SENSOR ---

                // --- SHOW NAME & EQUIPPED WEAPON ---
                // CHECK IF ENABLED IN MENU
                let shouldShowName = (entity.ennemy && espConfig.showEnemyNames) || (!entity.ennemy && espConfig.showPlayerNames);

                if (shouldShowName) {

                    // ORIGINAL CUSTOM WEAPON DICTIONARY
                    const customHeldDict = {
                        "4185": "MAX SHIELD POTION", "3414": "MEDICAL KIT", "7533": "LIGHT SNIPER RIFLE ❗",
                        "4036": "APPLE", "7598": "LIGHT SMG ❗", "3762": "HEALTH PILL",
                        "5619": "SURGE ASSAULT RIFLE ❗❗", "3210": "IRON", "7173": "COMPACT SMG ❗",
                        "3162": "BLOCK", "3226": "EMERALD", "6823": "TACTICAL ASSAULT RIFLE ❗",
                        "3358": "SHOVEL", "6451": "ELITE ASSAULT RIFLE ❗", "3739": "MINI SHIELD POTION",
                        "4903": "STRIKE PISTOL ❗", "3585": "PREMIUM SHIELD POTION", "8257": "SHOTGUN ❗",
                        "3192": "SULFUR", "6715": "AK RIFLE ❗", "6747": "REVOLVER ❗"
                    };

                    let weaponName = "";

                    if (totalHeldSize === 3138 || totalHeldSize === 3600 || totalHeldSize === 3362 || totalHeldSize === 2728 || totalHeldSize === 0) {
                        weaponName = "UNARMED";
                    }
                    else {
                        if (customHeldDict[totalHeldSize.toString()]) {
                            weaponName = customHeldDict[totalHeldSize.toString()];
                        }
                        else if (customHeldDict[(totalHeldSize - 462).toString()]) {
                            weaponName = customHeldDict[(totalHeldSize - 462).toString()];
                        }
                        else if (customHeldDict[(totalHeldSize - 224).toString()]) {
                            weaponName = customHeldDict[(totalHeldSize - 224).toString()];
                        }
                        else {
                            let found = false;
                            const bases = [3138, 3600, 3362, 2728, 0];
                            for (let b of bases) {
                                let pure = totalHeldSize - b;
                                if (window.globalItemDict[pure.toString()]) {
                                    weaponName = window.globalItemDict[pure.toString()].name;
                                    if (weaponName.includes("RIFLE") || weaponName.includes("GUN") || weaponName.includes("PISTOL") || weaponName.includes("SMG") || weaponName.includes("SNIPER") || weaponName.includes("REVOLVER")) weaponName += " ❗";
                                    found = true; break;
                                }
                            }
                            if (!found) weaponName = `Unknown Size: ${totalHeldSize}`;
                        }
                    }

                    // --- DISPLAY TEXT: ENEMIES SHOW WEAPONS ONLY, TEAMMATES SHOW NAME + WEAPON ---
                    let fullTextString = "";
                    if (entity.ennemy) {
                        fullTextString = `HOLDING [${weaponName}]`;
                    } else {
                        let pName = entity.playerName ? entity.playerName : "TEAMMATE";
                        fullTextString = `${pName} | HOLDING [${weaponName}]`;
                    }

                    // Draw text above head
                    if (!entity.myObject3D.nameSprite || entity.myObject3D.lastNameString !== fullTextString) {
                        if (entity.myObject3D.nameSprite) {
                            entity.myObject3D.remove(entity.myObject3D.nameSprite);
                        }
                        const sprite = makeTextSprite(fullTextString, entity.ennemy ? "#ff3333" : "#33ff33");
                        entity.myObject3D.add(sprite);
                        entity.myObject3D.nameSprite = sprite;
                        entity.myObject3D.lastNameString = fullTextString;
                    }

                    // --- ADJUST TEXT SIZE (BASED ON SETTING) ---
                    const nameSprite = entity.myObject3D.nameSprite;
                    nameSprite.visible = true;
                    nameSprite.position.y = isSneak ? 2.0 : 2.8;

                    let baseScale = entity.ennemy ? 5.0 : 2.0;
                    let finalScale = baseScale;

                    if (espConfig.nameScaling) {
                        const activeCameraPos = espConfig.freecam ? fcCamera.position : camera.position;
                        const dist = entity.myObject3D.position.distanceTo(activeCameraPos);

                        let multiplier = entity.ennemy ? 0.02 : 0.05;
                        finalScale = dist * multiplier;

                        let minSize = entity.ennemy ? 0.3 : 0.3;
                        if (finalScale < minSize) finalScale = minSize;
                    }
                    nameSprite.scale.set(finalScale * nameSprite.initialRatio, finalScale, 1);

                } else {
                    // IF DISABLED IN MENU -> HIDE
                    if (entity.myObject3D.nameSprite) {
                        entity.myObject3D.nameSprite.visible = false;
                    }
                }
                // --- END NAME & WEAPON DISPLAY ---

                const pos = entity.myObject3D.position.clone();
                pos.y -= isSneak ? espConfig.sneakHeight : 0;

                if (espConfig.showLine === 2 || (espConfig.showLine === 1 && entity.ennemy)) {
                    if (espConfig.rainbow) { color.setHSL(time % 2000 / 2000, 1, 0.5); }
                    else if (entity.ennemy) { color.lerpColors(colors.ennemy, colors.player, pos.distanceTo(camera.position) / espConfig.ennemyDistance); color.a = .8; }
                    else { color.set(colors.blue); color.a = .3; }
                    linePositions.push(lineOrigin.x, lineOrigin.y, lineOrigin.z); pos.y += 1.25;
                    linePositions.push(pos.x, pos.y, pos.z); pos.y -= 1.25;
                    colorArray.push(color.r, color.g, color.b, color.a, color.r, color.g, color.b, color.a);
                }
                pos.y += espConfig.heightLine;

                if (shouldAimbot && (entity.ennemy || espConfig.allEnnemies)) {
                    if (entity.playerName && window.ignoredPlayers.has(entity.playerName)) return;
                    const distance = pos.distanceTo(camera.position); let target = pos.clone();
                    if (entity.velocity) { target.add(new THREE.Vector3(entity.velocity.x, 0, entity.velocity.z).multiplyScalar(1.5)); if (entity.velocity.y > 0.01) target.y -= 0.02; }
                    setTransform(dummyLookAt, worldCamera, false); dummyLookAt.lookAt(target);
                    const cameraVector = new THREE.Vector3(0, 0, -1).applyQuaternion(camera.quaternion);
                    const targetVector = new THREE.Vector3(0, 0, -1).applyQuaternion(dummyLookAt.quaternion);
                    const angleDifference = cameraVector.angleTo(targetVector);

                    // UPDATED TO USE PRIORITY
                    if (angleDifference < (espConfig.unlimitedAngle ? Math.PI : espConfig.maxAngleInRadians)) {
                        if (currentPriority > aimbotTarget.priority || (currentPriority === aimbotTarget.priority && angleDifference < aimbotTarget.angleDifference)) {
                            raycaster.set(camera.position, new THREE.Vector3().subVectors(target, camera.position).normalize());
                            let behindBlock = false;
                            if (!espConfig.aimbotIgnoreWall) {
                                for (const chunk of chunks) {
                                    if (raycaster.ray.intersectsBox(chunk.box)) {
                                        const hit = raycaster.intersectObject(chunk)[0];
                                        if (hit && hit.distance < distance) { behindBlock = true; break; }
                                    }
                                }
                            }
                            if (espConfig.aimbotIgnoreWall || !behindBlock) {
                                aimbotTarget.priority = currentPriority;
                                aimbotTarget.angleDifference = angleDifference;
                                aimbotTarget.target = target;
                                color.setHSL(time % 2000 / 2000, 1, 0.5);
                            }
                        }
                    }
                }
            } catch (err) {}
        }
        // ===============================================
        // DISPLAY ITEMS & AUTO COLOR (WITH TRACERS)
        // ===============================================
        else if (isItem(entity) && espConfig.showItems) {
            if (!entity.itemBox) {
                const innerMat = new THREE.MeshBasicMaterial({ color: 0xffffff, transparent: true, opacity: 0.15, depthTest: false });
                const edgeMat = new THREE.LineBasicMaterial({ color: 0xffffff, linewidth: 2, transparent: true, opacity: 0.9, depthTest: false });

                entity.itemBox = new THREE.Mesh(glassBoxGeo, innerMat);
                entity.itemBox.frustumCulled = false;
                const edges = new THREE.LineSegments(glassEdgesGeo, edgeMat);
                edges.frustumCulled = false;
                entity.itemBox.add(edges);
                scene.add(entity.itemBox);
                entity.lastTag = "";
            }

            // SENSOR PARAMETERS
            let voxelCount = 0;
            let itemColor = "";
            let lightColor = "";

            const toHex = (c) => {
                let val = Math.max(0, Math.min(1, c));
                return Math.round(val * 255).toString(16).padStart(2, '0');
            };

            try {
                const scanItem = (obj) => {
                    if (obj.geometry && obj.geometry.attributes && obj.geometry.attributes.position) {
                        const vCount = obj.geometry.attributes.position.count;

                        if (vCount > 10) {
                            voxelCount += vCount;
                            if (!itemColor && obj.geometry.attributes.color) {
                                const cArr = obj.geometry.attributes.color.array;
                                if (cArr.length >= 3) {
                                    let r = cArr[0], g = cArr[1], b = cArr[2];
                                    if (r > 1 || g > 1 || b > 1) { r /= 255; g /= 255; b /= 255; }
                                    itemColor = "#" + toHex(r) + toHex(g) + toHex(b);
                                }
                            } else if (!itemColor && obj.material && obj.material.color && !obj.material.map) {
                                itemColor = "#" + obj.material.color.getHexString();
                            }
                        } else if (vCount <= 10) {
                            if (obj.material && obj.material.color) {
                                lightColor = "#" + obj.material.color.getHexString();
                            }
                        }
                    }

                    if (obj.isLight && obj.color) {
                        lightColor = "#" + obj.color.getHexString();
                    }
                    if (obj.type === 'Sprite' && obj.material && obj.material.color) {
                        lightColor = "#" + obj.material.color.getHexString();
                    }

                    if (obj[childrenKey] && obj[childrenKey].length > 0) {
                        for (const sub of obj[childrenKey]) scanItem(sub);
                    }
                };
                for (const child of entity[childrenKey]) scanItem(child);
            } catch(e) {}

            if (!itemColor) itemColor = "#ffffff";
            if (!lightColor) lightColor = "#000000";

            const lookupKeyExact = voxelCount + "_" + itemColor;
            const lookupKeyVoxel = voxelCount.toString();

            let targetStr = "#ffffff";
            let baseName = "Loading...";
            let isKnownItem = false;
            let foundKey = null;

            if (window.globalItemDict[lookupKeyExact]) {
                foundKey = lookupKeyExact;
            } else if (window.globalItemDict[lookupKeyVoxel]) {
                foundKey = lookupKeyVoxel;
            }

            if (voxelCount === 0) {
                baseName = "Loading...";
                targetStr = "#aaaaaa";
                isKnownItem = true;
            }
            else if (foundKey) {
                let foundItem = window.globalItemDict[foundKey];
                baseName = foundItem.name;
                isKnownItem = true;
                if (foundItem.useLightColor) {
                    targetStr = (lightColor !== "#000000") ? lightColor : "#ffffff";
                } else {
                    targetStr = foundItem.str;
                }
                // INCREMENT DICTIONARY COUNTER
                window.nearbyItemCounts.set(foundKey, (window.nearbyItemCounts.get(foundKey) || 0) + 1);
            }
            else {
                isKnownItem = false;
                targetStr = (lightColor !== "#000000") ? lightColor : "#ffffff";
                if (voxelCount < 30) { baseName = "New Ammo"; targetStr = "#00ffff"; }
                else if (voxelCount >= 30 && voxelCount < 150) { baseName = "New Item"; }
                else if (voxelCount >= 150 && voxelCount < 5000) { baseName = "New Weapon"; }
                else { baseName = "New Big Item"; }
            }

            let targetHex = parseInt(targetStr.replace("#", ""), 16) || 0xffffff;
            let displayName = isKnownItem ? baseName : `${baseName} [V:${voxelCount} | C:${itemColor} | L:${lightColor}]`;

            entity.itemBox.material.color.setHex(targetHex);
            entity.itemBox.children[0].material.color.setHex(targetHex);

            const currentTag = targetStr + displayName;

            if (espConfig.showItemNames && entity.lastTag !== currentTag) {
                if (entity.itemNameSprite) entity.itemBox.remove(entity.itemNameSprite);

                const canvas = document.createElement('canvas');
                const ctx = canvas.getContext('2d');
                ctx.font = "Bold 70px Arial";
                const metrics = ctx.measureText(displayName);
                canvas.width = metrics.width + 40;
                canvas.height = 100;
                ctx.font = "Bold 70px Arial";
                ctx.textBaseline = "middle";
                ctx.textAlign = "center";

                ctx.lineWidth = 6;
                ctx.strokeStyle = "black";
                ctx.strokeText(displayName, canvas.width / 2, canvas.height / 2);

                ctx.fillStyle = targetStr;
                ctx.fillText(displayName, canvas.width / 2, canvas.height / 2);

                const tex = new THREE.CanvasTexture(canvas);
                const newSprite = new THREE.Sprite(new THREE.SpriteMaterial({ map: tex, depthTest: false }));

                const textScale = 0.2;
                newSprite.scale.set(textScale * (canvas.width / canvas.height), textScale, 1);
                newSprite.position.y = 0.4;

                entity.itemBox.add(newSprite);
                entity.itemNameSprite = newSprite;
                entity.lastTag = currentTag;
            }

            if (!espConfig.showItemNames && entity.itemNameSprite) {
                entity.itemBox.remove(entity.itemNameSprite);
                entity.itemNameSprite = null;
                entity.lastTag = "";
            }

            setTransform(entity.itemBox, entity, false);
            entity.itemBox.visible = true;

            // DRAW TRACERS (NEW - MULTI SELECTION & TIER COLORS)
            let shouldTrace = false;

            if (foundKey && voxelCount !== 0) {
                // Draw line if "Select All" for this item is checked
                if (window.tracedItemKeys.has(foundKey)) {
                    shouldTrace = true;
                } else {
                    // If weapon, determine tier color
                    let tHex = targetStr.toLowerCase();
                    let uiColor = tHex;

                    // Normalize color
                    if (tHex === '#00ff00' || tHex === '#2ecc71') uiColor = '#2ecc71'; // Good
                    else if (tHex === '#0088ff' || tHex === '#3498db' || tHex === '#0000ff' || tHex === '#00ffff') uiColor = '#3498db'; // Rare
                    else if (tHex === '#aa00ff' || tHex === '#9b59b6' || tHex === '#ff00ff') uiColor = '#9b59b6'; // Epic
                    else if (tHex === '#ffaa00' || tHex === '#f1c40f' || tHex === '#ffff00') uiColor = '#f1c40f'; // Legendary
                    else if (tHex !== '#ffffff' && tHex !== '#aaaaaa') uiColor = '#ff0000'; // Strange colors -> Mythic

                    // Draw line if specific tier is active
                    if (window.tracedItemKeys.has(`${foundKey}_${uiColor}`)) {
                        shouldTrace = true;
                    }
                }
            }

            if (shouldTrace) {
                let r = (targetHex >> 16 & 255) / 255;
                let g = (targetHex >> 8 & 255) / 255;
                let b = (targetHex & 255) / 255;
                linePositions.push(lineOrigin.x, lineOrigin.y, lineOrigin.z);
                linePositions.push(entity.itemBox.position.x, entity.itemBox.position.y, entity.itemBox.position.z);
                colorArray.push(r, g, b, 0.8, r, g, b, 0.8);
            }

        } else if (entity.itemBox) {
            entity.itemBox.visible = false;
            if (entity.itemNameSprite) entity.itemNameSprite.visible = false;
        }
    });

    if (espConfig.aimbot && shouldAimbot && aimbotTarget.target) {
        setTransform(dummyLookAt, worldCamera, false);
        dummyLookAt.lookAt(aimbotTarget.target);

        if (espConfig.silentAim) {
            // Original rotation saved at beginning of function
            worldCamera.rotation.set(dummyLookAt.rotation.x, dummyLookAt.rotation.y, dummyLookAt.rotation.z);
            worldCamera.updateMatrixWorld(true);
            isSilentSnapped = true;
        } else {
            worldCamera.rotation.set(dummyLookAt.rotation.x, dummyLookAt.rotation.y, dummyLookAt.rotation.z);
            isSilentSnapped = false;
        }
    } else {
        // Release mouse or lost target -> restore view
        if (isSilentSnapped && worldCamera) {
            worldCamera.rotation.copy(originalCameraRotation);
            worldCamera.updateMatrixWorld(true);
            isSilentSnapped = false;
        }
    }

    let isTriggerActive = espConfig.triggerBot === 3 || (espConfig.triggerBot === 1 && isLeftClick) || (espConfig.triggerBot === 2 && isRightClick);

    if (isTriggerActive) {
        let hasHit = false;

        if (espConfig.aimbot > 0 && shouldAimbot && aimbotTarget.target) {
            if (!espConfig.aimbotIgnoreWall) {
                hasHit = true;
            } else {
                let dirToTarget = new THREE.Vector3().subVectors(aimbotTarget.target, camera.position).normalize();
                raycaster.set(camera.position, dirToTarget);

                let hitWall = false;
                let distToTarget = camera.position.distanceTo(aimbotTarget.target);

                for (const chunk of chunks) {
                    if (raycaster.ray.intersectsBox(chunk.box)) {
                        const hitBlock = raycaster.intersectObject(chunk)[0];
                        if (hitBlock && hitBlock.distance < distToTarget) {
                            hitWall = true;
                            break;
                        }
                    }
                }
                if (!hitWall) hasHit = true;
            }
        }

        if (!hasHit) {
            raycaster.set(camera.position, camera.getWorldDirection(new THREE.Vector3()));
            for (const entity of entities) {
                if (!entity.myObject3D?.visible || !entity.isPlayer || (!entity.ennemy && !espConfig.allEnnemies)) continue;

                const hit = raycaster.intersectObject(entity.myObject3D.playerMesh);
                if (hit.length) {
                    hasHit = true;
                    const distance = hit[0].distance;
                    for (const chunk of chunks) {
                        if (raycaster.ray.intersectsBox(chunk.box)) {
                            const hitBlock = raycaster.intersectObject(chunk)[0];
                            if (hitBlock && hitBlock.distance < distance) {
                                hasHit = false;
                                break;
                            }
                        }
                    }
                    if (hasHit) break;
                }
            }
        }

        setFiring(hasHit);
    } else {
        setFiring(false);
    }

    line.geometry.setAttribute('color', new THREE.Float32BufferAttribute(colorArray, 4));
    line.geometry.setAttribute('position', new THREE.Float32BufferAttribute(linePositions, 3));
    line.visible = espConfig.showLine > 0 || espConfig.markPosition || window.tracedItemKeys.size > 0;

    renderer.render(scene, camera);

    entities.forEach(entity => {
        if (entity.isPlayer) {
            entity.myObject3D.playerMesh.visible = false; entity.myObject3D.boxMesh.visible = false; entity.myObject3D.outline.visible = false;
            if (entity.myObject3D.nameSprite) entity.myObject3D.nameSprite.visible = false;
            entity.myObject3D.playerMiniMap.visible = true; entity.myObject3D.playerMiniMap.scale.set(espConfig.mapZoom/3, 1, espConfig.mapZoom/3);
        }
        if (entity.itemBox) entity.itemBox.visible = false;
    });

    if (worldCamera) {
        line.visible = false; crosshair.visible = false;

        // === UPDATE WHITE ARROW POSITION & DIR ===
        myCenterArrowGroup.position.copy(camera.position);
        myCenterArrowGroup.rotation.y = camera.rotation.y;
        myCenterArrowGroup.scale.set(espConfig.mapZoom/10, espConfig.mapZoom/40, espConfig.mapZoom/30);
        myCenterArrowGroup.visible = true;
        // =================================================

        minimapCamera.left = -espConfig.mapZoom; minimapCamera.right = espConfig.mapZoom;
        minimapCamera.top = espConfig.mapZoom; minimapCamera.bottom = -espConfig.mapZoom;
        minimapCamera.position.copy(camera.position); minimapCamera.position.y += 50; minimapCamera.position.z += espConfig.mapOffsetZ;
        minimapCamera.rotation.y = camera.rotation.y; minimapCamera.updateProjectionMatrix();

        renderer.getViewport(saveViewport); renderer.getScissor(saveScissor);
        let saveScissorTest = renderer.getScissorTest();
        renderer.setViewport(minimapViewport); renderer.setScissor(minimapViewport); renderer.setScissorTest(true);
        renderer.render(scene, minimapCamera);
        renderer.setViewport(saveViewport); renderer.setScissor(saveScissor); renderer.setScissorTest(saveScissorTest);
    }

    entities.forEach(entity => { if (entity.isPlayer) entity.myObject3D.playerMiniMap.visible = false; });
    scene.children.forEach(child => { if (child.type === 'Object3D') child.visible = false; });

    // === HIDE WHITE ARROW ===
    myCenterArrowGroup.visible = false;
}

window.addEventListener('resize', () => { renderer.setSize( window.innerWidth, window.innerHeight ); });

const style = document.createElement('style');
style.innerHTML = `
#overlayCanvas { position: absolute; top: 0; left: 0; width: 100%; height: 100%; pointer-events: none; z-index: 1000; }
#lil-gui { position: absolute; top: 50%; right: 0; z-index: 1001; transform: translateY(-50%); }
.lil-gui { --background-color: rgba(0, 0, 0, 0.5); --title-background-color: #228b22; --number-color: #00ff33; }
`; document.head.appendChild(style);

setInterval(() => {
    if (espConfig.antiAFK) {
        document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 87 }));
        document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 67 }));
        document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 70 }));
    }
}, 20);

setInterval(() => {
    if (espConfig.sit) {
        document.dispatchEvent(new KeyboardEvent('keydown', { keyCode: 67 }));
        setTimeout(() => { document.dispatchEvent(new KeyboardEvent('keyup', { keyCode: 67 })); }, 5);
    }
}, 0);

window.addEventListener('load', () => { if (espConfig.autoClaimAds) setTimeout(claimAds, 500); });

// ==========================================
// UPDATE STATIC RADAR 2-TABS FOR ITEMS
// ==========================================
setInterval(() => {
    const radarContainer = document.getElementById('side-player-list');
    if (!radarContainer) return;
    if (!espConfig.showRadar) { radarContainer.style.display = 'none'; return; } else { radarContainer.style.display = 'block'; }
    const content = document.getElementById('list-content');
    const countElement = document.getElementById('radar-count');
    if (!content || !countElement) return;

    let html = '';

    // PROCESS PLAYER RADAR
    if (window.radarMode === 'players') {
        countElement.innerText = window.playerMap ? window.playerMap.size : 0;
        if (!window.playerMap || window.playerMap.size === 0) {
            html = '<div style="color:#ffcc00; font-size:12px; font-weight:bold; text-align:center; padding: 10px;">🔍 NO ONE IN SIGHT...</div>';
        } else {
            const sortedPlayers = Array.from(window.playerMap.entries()).map(([name, data]) => ({ name, ...data })).sort((a, b) => a.dist - b.dist);
            sortedPlayers.forEach((p, index) => {
                const isSoldier = p.color === "#ff0000";
                const shadow = isSoldier ? "1px 1px 0px #000, -1px -1px 0px #000, 1px -1px 0px #000, -1px 1px 0px #000, 0px 0px 3px #ffffff" : "1px 1px 1px #000";
                const isIgnored = window.ignoredPlayers && window.ignoredPlayers.has(p.name);
                const btnColor = isIgnored ? "#00ff00" : "#555"; const btnText = isIgnored ? "✔" : "+";
                const isSelected = (index === window.selectedPlayerIndex);
                html += `
                    <div class="player-row ${isSelected ? 'selected' : ''}" style="color:${p.color}; text-shadow: ${shadow};">
                        <span style="width:25px; text-align:center; font-size:18px; margin-right:5px; flex-shrink:0;">${p.arrow || "•"}</span>
                        <button onmousedown="window.handlePlayerAction('${p.name}')" style="pointer-events: auto; margin-right: 10px; background: ${btnColor}; color: white; border: 1px solid rgba(255,255,255,0.3); border-radius: 4px; width: 26px; height: 26px; cursor: pointer; font-size: 16px; font-weight: bold; flex-shrink: 0; display: flex; align-items: center; justify-content: center;">${btnText}</button>
                        <span style="flex-grow:1; overflow:hidden; text-overflow:ellipsis; font-weight:900;">${p.name}</span>
                        <span class="dist-text" style="margin-left:auto; color:#00ffff; font-weight:bold; font-size:12px;">${p.dist}m</span>
                    </div>
                `;
            });
        }
    }
    // PROCESS ITEM RADAR (MULTI SELECTION)
    else if (window.radarMode === 'items') {
        const totalItems = Object.keys(window.globalItemDict).length;
        countElement.innerText = totalItems;

        // --- DISABLE TRACER BUTTON ---
        html += `
            <div style="margin-bottom: 10px; pointer-events: auto; width: 100%;">
                <button onclick="window.resetTracers()" style="width: 100%; background: rgba(255, 0, 0, 0.2); color: #ff4444; border: 1px solid #ff0000; border-radius: 4px; font-weight: bold; cursor: pointer; font-size: 11px; padding: 6px 0; transition: all 0.2s ease;" title="Clear all tracer selections">❌ DISABLE ALL ITEM TRACERS</button>
            </div>
        `;
        // -----------------------------------------

        for (const key in window.globalItemDict) {
            const itemDef = window.globalItemDict[key];
            const count = window.nearbyItemCounts.get(key) || 0;
            const isTraced = window.tracedItemKeys.has(key);

            const btnColor = isTraced ? "#2dd000" : "#555";
            const btnText = isTraced ? "👁" : "📌";
            const itemColor = itemDef.str || "#ffffff";

            const opacity = count > 0 ? "1" : "0.5";
            const countHtml = count > 0 ? `<span style="color:#00ff00;">[${count}]</span>` : `<span style="color:#777;">[0]</span>`;

            // Check if weapon or shovel, exclude ammo
            const nameUpper = itemDef.name.toUpperCase();
            const isWeapon = (nameUpper.includes("RIFLE") || nameUpper.includes("GUN") || nameUpper.includes("PISTOL") || nameUpper.includes("SMG") || nameUpper.includes("SNIPER") || nameUpper.includes("REVOLVER") || nameUpper.includes("SHOVEL")) && !nameUpper.includes("AMMO");

            html += `
                <div class="player-row" style="flex-direction: column; align-items: stretch; opacity: ${opacity}; transition: opacity 0.2s;">
                    <div style="display: flex; align-items: center; width: 100%;">
                        <button onmousedown="window.toggleItemTracer('${key}')" style="pointer-events: auto; margin-right: 10px; background: ${btnColor}; color: white; border: 1px solid ${itemColor}; border-radius: 4px; width: 26px; height: 26px; cursor: pointer; font-size: 14px; font-weight: bold; flex-shrink: 0; display: flex; align-items: center; justify-content: center;" title="Draw tracer to all items of this type">${btnText}</button>
                        <span style="flex-grow:1; overflow:hidden; text-overflow:ellipsis; font-weight:bold; color:${itemColor}; text-shadow: 1px 1px 2px #000;">${itemDef.name}</span>
                        <span class="dist-text" style="margin-left:auto; font-weight:bold; font-size:12px;">${countHtml}</span>
                    </div>
            `;

            // Insert sub-buttons for rarity colors if weapon
            if (isWeapon) {
                const tiers = [
                    { name: 'Good', color: '#2ecc71' },
                    { name: 'Rare', color: '#3498db' },
                    { name: 'Epic', color: '#9b59b6' },
                    { name: 'Legend', color: '#f1c40f' },
                    { name: 'Mythic', color: '#ff0000' }
                ];

                html += `<div style="display:flex; gap:4px; margin-left: 36px; margin-top: 4px; pointer-events: auto;">`;
                tiers.forEach(t => {
                    const fKey = `${key}_${t.color}`;
                    const isActive = window.tracedItemKeys.has(fKey);

                    html += `<button onmousedown="window.toggleItemTracer('${key}', '${t.color}')" style="background:${isActive ? t.color : 'transparent'}; color:${isActive ? '#fff' : t.color}; border:1px solid ${t.color}; border-radius:3px; font-size:10px; font-weight:bold; padding:2px 4px; cursor:pointer; transition: all 0.2s;">${t.name}</button>`;
                });
                html += `</div>`;
            }
            html += `</div>`;
        }
    }
    // PROCESS MARKS RADAR
    else if (window.radarMode === 'marks') {
        countElement.innerText = window.savedMarks.length;

        html += `
            <div style="margin-bottom: 10px; pointer-events: auto; width: 100%;">
                <button onclick="window.clearAllMarks()" style="width: 100%; background: rgba(255, 0, 0, 0.2); color: #ff4444; border: 1px solid #ff0000; border-radius: 4px; font-weight: bold; cursor: pointer; font-size: 11px; padding: 6px 0; transition: all 0.2s ease;" title="Delete all marks">❌ CLEAR ALL SAVED MARKS</button>
            </div>
        `;

        if (window.savedMarks.length === 0) {
            html += '<div style="color:#ffcc00; font-size:12px; font-weight:bold; text-align:center; padding: 10px;">📍 NO MARKS YET...<br>(Press U in-game to save)</div>';
        } else {
                 window.savedMarks.forEach(m => {
                const dist = typeof camera !== 'undefined' ? Math.round(camera.position.distanceTo(m.pos)) : 0;
                const btnEye = m.active ? "👁" : "➖";
                const eyeColor = m.active ? "#ff0044" : "#555";
                const opacity = m.active ? "1" : "0.5";

                // Lock & Delete States
                const btnLock = m.isLocked ? "🔒" : "🔓";
                const lockColor = m.isLocked ? "#ffaa00" : "#555"; // Orange if locked
                const deleteCursor = m.isLocked ? "not-allowed" : "pointer";
                const deleteOpacity = m.isLocked ? "0.3" : "1"; // Dim X if locked

                html += `
                    <div class="player-row" style="display: flex; align-items: center; width: 100%; opacity: ${opacity}; transition: opacity 0.2s;">
                        <button onmousedown="window.toggleMark(${m.id})" style="pointer-events: auto; margin-right: 4px; background: ${eyeColor}; color: white; border: 1px solid #ff0044; border-radius: 4px; width: 23px; height: 23px; cursor: pointer; font-size: 12px; font-weight: bold; flex-shrink: 0; display: flex; align-items: center; justify-content: center;" title="Show / Hide this mark">${btnEye}</button>

                        <button onmousedown="window.toggleLock(${m.id})" style="pointer-events: auto; margin-right: 4px; background: ${lockColor}; color: white; border: 1px solid #ffaa00; border-radius: 4px; width: 23px; height: 23px; cursor: pointer; font-size: 12px; font-weight: bold; flex-shrink: 0; display: flex; align-items: center; justify-content: center;" title="Lock / Unlock">${btnLock}</button>

                        <button onmousedown="window.renameMark(${m.id})" style="pointer-events: auto; margin-right: 4px; background: #3498db; color: white; border: 1px solid #2980b9; border-radius: 4px; width: 23px; height: 23px; cursor: pointer; font-size: 12px; font-weight: bold; flex-shrink: 0; display: flex; align-items: center; justify-content: center;" title="Rename this mark">✏</button>

                        <button onmousedown="window.deleteMark(${m.id})" style="pointer-events: auto; margin-right: 8px; background: #222; color: #ff4444; border: 1px solid #ff0000; border-radius: 4px; width: 23px; height: 23px; cursor: ${deleteCursor}; font-size: 10px; font-weight: bold; flex-shrink: 0; display: flex; align-items: center; justify-content: center; opacity: ${deleteOpacity};" title="${m.isLocked ? 'Currently locked' : 'Delete this mark'}">❌</button>

                        <span style="flex-grow:1; overflow:hidden; text-overflow:ellipsis; font-weight:bold; color:#ff0044; text-shadow: 1px 1px 2px #000;">${m.name}</span>
                        <span class="dist-text" style="margin-left:auto; font-weight:bold; font-size:12px; color:#ffffff !important;">${dist}m</span>
                    </div>
                `;
            });
        }
    }

    content.innerHTML = html;

    // Clear player map for next scan
    if (window.playerMap) window.playerMap.clear();
}, 250);

window.selectedPlayerIndex = -1; let hideTimer = null;
if (!document.getElementById('selection-style')) {
    const s = document.createElement('style'); s.id = 'selection-style';
    s.innerHTML = `.player-row { border: 1.5px solid transparent; transition: all 0.1s; padding: 2px 5px; border-radius: 5px; } .player-row.selected { background: rgba(0, 255, 0, 0.2) !important; border-color: #00ff00 !important; box-shadow: 0 0 10px #00ff00; } .player-row.clicked { background: rgba(255, 255, 0, 0.5) !important; border-color: yellow !important; }`;
    document.head.appendChild(s);
}

window.addEventListener('keydown', (e) => {
    if (document.activeElement.tagName === 'INPUT' || document.activeElement.tagName === 'TEXTAREA') return;
    const rows = document.querySelectorAll('.player-row'); if (rows.length === 0) return;
    if (e.key === '[') { window.selectedPlayerIndex = (window.selectedPlayerIndex <= 0) ? rows.length - 1 : window.selectedPlayerIndex - 1; e.preventDefault(); }
    else if (e.key === ']') { window.selectedPlayerIndex = (window.selectedPlayerIndex >= rows.length - 1) ? 0 : window.selectedPlayerIndex + 1; e.preventDefault(); }
    else if (e.key === '/') {
        if (window.selectedPlayerIndex >= 0 && rows[window.selectedPlayerIndex]) {
            const row = rows[window.selectedPlayerIndex]; const btn = row.querySelector('button');
            if (btn) btn.onmousedown(); row.classList.add('clicked'); setTimeout(() => row.classList.remove('clicked'), 200);
        }
        e.preventDefault();
    } else { return; }
    clearTimeout(hideTimer); hideTimer = setTimeout(() => { window.selectedPlayerIndex = -1; }, 3000);
});

window.addEventListener('keyup', (e) => {
    const keyL = e.key.toLowerCase();
    if (keyL === espConfig.zoomKey.toLowerCase() || (keyL === 'f' && espConfig.fZoomEnabled)) {
        espConfig.isZooming = false; if (typeof gui !== 'undefined') gui.controllersRecursive().forEach(c => c.updateDisplay());
    }
});

window.addEventListener('wheel', (e) => {
    if (espConfig.freecam) { espConfig.fcSpeed = e.deltaY < 0 ? Math.min(5.0, espConfig.fcSpeed + 0.1) : Math.max(0.1, espConfig.fcSpeed - 0.1); e.stopImmediatePropagation(); e.preventDefault(); return; }
    if (espConfig.isZooming) {
        e.preventDefault(); espConfig.zoomLevel = e.deltaY < 0 ? Math.max(1, espConfig.zoomLevel - 3) : Math.min(178, espConfig.zoomLevel + 3);
        if (typeof gui !== 'undefined') gui.controllersRecursive().forEach(c => { if (c.property === 'zoomLevel') c.updateDisplay(); });
    }
}, { passive: false, capture: true });

Object.defineProperty(Object.prototype, 'fov', {
    get: function() { return (this.isPerspectiveCamera && espConfig.isZooming) ? espConfig.zoomLevel : this._fov; },
    set: function(v) { this._fov = v; }, configurable: true
});