cheatmoggle

premium omoggle script

2026-05-31 기준 버전입니다. 최신 버전을 확인하세요.

이 스크립트를 설치하려면 Tampermonkey, Greasemonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램을 설치해야 합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Violentmonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey 또는 Userscripts와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 Tampermonkey와 같은 확장 프로그램이 필요합니다.

이 스크립트를 설치하려면 유저 스크립트 관리자 확장 프로그램이 필요합니다.

(이미 유저 스크립트 관리자가 설치되어 있습니다. 설치를 진행합니다!)

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 Stylus와 같은 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

이 스타일을 설치하려면 유저 스타일 관리자 확장 프로그램이 필요합니다.

(이미 유저 스타일 관리자가 설치되어 있습니다. 설치를 진행합니다!)

// ==UserScript==
// @name         cheatmoggle
// @namespace    https://omoggle.com/
// @version      13.3.0
// @description  premium omoggle script
// @match        https://omoggle.com/*
// @match        https://*.omoggle.com/*
// @grant        unsafeWindow
// @run-at       document-start
// ==/UserScript==

(function () {
    'use strict';

    // Use unsafeWindow to access the page's real window object (for Tampermonkey compatibility)
    const _window = (typeof unsafeWindow !== 'undefined') ? unsafeWindow : window;

    const DEFAULT_CONFIG = {
        enabled: true,
        scoreEnabled: true,
        scoreMode: 'range',
        fixedScore: 94000,
        scoreRangeMin: 85000,
        scoreRangeMax: 95000,
        resultEnabled: true,
        myFinalScore: "94000",
        finalScoreMode: 'fixed',
        finalScoreRangeMin: 85000,
        finalScoreRangeMax: 97000,
        holdBtnSize: 54,
        debug: true,
        wmAlpha: 20,
        wmFontSize: 9,
        wmPaddingH: 14,
        wmPaddingV: 6,
        wmBorder: true,
        wmBg: true,
        theme: 'crimson'
    };

    function loadConfig() {
        try {
            const saved = localStorage.getItem('cheatmoggle_config');
            if (saved) return { ...DEFAULT_CONFIG, ...JSON.parse(saved) };
        } catch (e) {}
        return { ...DEFAULT_CONFIG };
    }

    function saveConfig() {
        try {
            localStorage.setItem('cheatmoggle_config', JSON.stringify(CONFIG));
        } catch (e) {}
    }

    const CONFIG = loadConfig();

    const THEMES = {
        amoled: {
            name: 'AMOLED',
            primary: '#000000',
            primaryRgb: '0,0,0',
            secondary: '#171717',
            accent: '#ffffff',
            accentRgb: '255,255,255',
            success: '#22c55e',
            warning: '#eab308',
            danger: '#ef4444',
            bgDark: '#000000',
            bgCard: '#0a0a0a',
            bgElevated: '#141414',
            border: 'rgba(255,255,255,0.15)',
            text: '#ffffff',
            textMuted: '#a1a1aa'
        },
        neon: {
            name: 'Neon',
            primary: '#00ff88',
            primaryRgb: '0,255,136',
            secondary: '#00cc6a',
            accent: '#7dffb3',
            accentRgb: '125,255,179',
            success: '#00ff88',
            warning: '#ffcc00',
            danger: '#ff4444',
            bgDark: '#0a0f0c',
            bgCard: '#0d1a12',
            bgElevated: '#132218',
            border: 'rgba(0,255,136,0.15)',
            text: '#e0ffe8',
            textMuted: '#7da88a'
        },
        matrix: {
            name: 'Matrix',
            primary: '#00ff00',
            primaryRgb: '0,255,0',
            secondary: '#00cc00',
            accent: '#66ff66',
            accentRgb: '102,255,102',
            success: '#00ff00',
            warning: '#ccff00',
            danger: '#ff3333',
            bgDark: '#000800',
            bgCard: '#001a00',
            bgElevated: '#002200',
            border: 'rgba(0,255,0,0.12)',
            text: '#ccffcc',
            textMuted: '#669966'
        },
        toxic: {
            name: 'Toxic',
            primary: '#39ff14',
            primaryRgb: '57,255,20',
            secondary: '#7fff00',
            accent: '#adff2f',
            accentRgb: '173,255,47',
            success: '#39ff14',
            warning: '#ffff00',
            danger: '#ff6347',
            bgDark: '#080a05',
            bgCard: '#101408',
            bgElevated: '#181f0c',
            border: 'rgba(57,255,20,0.12)',
            text: '#e8ffe0',
            textMuted: '#8faa7d'
        },
        midnight: {
            name: 'Midnight',
            primary: '#6366f1',
            primaryRgb: '99,102,241',
            secondary: '#8b5cf6',
            accent: '#22d3ee',
            accentRgb: '34,211,238',
            success: '#10b981',
            warning: '#f59e0b',
            danger: '#ef4444',
            bgDark: '#0a0a0f',
            bgCard: '#12121a',
            bgElevated: '#1a1a24',
            border: 'rgba(255,255,255,0.08)',
            text: '#e4e4e7',
            textMuted: '#71717a'
        },
        crimson: {
            name: 'Crimson',
            primary: '#dc2626',
            primaryRgb: '220,38,38',
            secondary: '#f43f5e',
            accent: '#fb7185',
            accentRgb: '251,113,133',
            success: '#10b981',
            warning: '#f59e0b',
            danger: '#ef4444',
            bgDark: '#0f0505',
            bgCard: '#1a0a0a',
            bgElevated: '#241010',
            border: 'rgba(255,100,100,0.1)',
            text: '#fecaca',
            textMuted: '#a8a29e'
        }
    };

    let playerMapping = null;
    let _isRanked = window.location.pathname.startsWith('/ranked');
    let _matchStartTime = null;
    let _finalScoreAppliedThisMatch = false;

    const _origPushState = history.pushState;
    history.pushState = function(...args) {
        _origPushState.apply(this, args);
        _isRanked = window.location.pathname.startsWith('/ranked');
    };
    window.addEventListener('popstate', () => {
        _isRanked = window.location.pathname.startsWith('/ranked');
    });

    function tryDecode(data) {
        try {
            const bytes = data instanceof ArrayBuffer ? new Uint8Array(data) : data;
            if (!(bytes instanceof Uint8Array)) return null;
            const text = new TextDecoder().decode(bytes);
            const jsonMatch = text.match(/\{[^}]+\}/);
            if (jsonMatch) return { json: JSON.parse(jsonMatch[0]), bytes, fullText: text };
        } catch (e) {}
        return null;
    }

    function rewriteBytes(originalBytes, oldJSON, newJSON) {
        const originalText = new TextDecoder().decode(originalBytes);
        const newText = originalText.replace(JSON.stringify(oldJSON), JSON.stringify(newJSON));
        return new TextEncoder().encode(newText);
    }

    const originalSend = RTCDataChannel.prototype.send;
    RTCDataChannel.prototype.send = function (data) {
        const parsed = tryDecode(data);
        if (parsed?.json) {
            const { json, bytes } = parsed;

            const hasP = typeof json.p !== 'undefined';
            const hasQ = typeof json.q !== 'undefined';
            const isNormalFrame = hasP && hasQ && json.m === undefined && !json.type;
            const isRankedFrame = hasP && hasQ && json.m !== undefined;

            if (isRankedFrame && !_isRanked) {
                _isRanked = true;
                log('Locked: RANKED mode (m field detected in frame)');
            }

            if (isNormalFrame || isRankedFrame) {
                if (json.p <= 2 && _matchStartTime === null) {
                    _matchStartTime = Date.now();
                    _finalScoreAppliedThisMatch = false;
                    log(`Match started - tracking time from now`);
                }

                if (!playerMapping && json.q > 0) {
                    playerMapping = { myKey: 'q' };
                    log(`q confirmed as your score [${isRankedFrame ? 'RANKED' : 'NORMAL'} frame]`);
                }
                if (json.q > 0) {
                    if (!CONFIG.scoreEnabled) {
                        return originalSend.call(this, data);
                    }

                    const modified = { ...json };
                    let newScore;

                    const matchElapsed = _matchStartTime ? (Date.now() - _matchStartTime) / 1000 : 0;
                    const shouldUseFinalScore = CONFIG.resultEnabled && matchElapsed >= 14;

                    if (shouldUseFinalScore) {
                        newScore = _getFinalTarget();
                        if (!_finalScoreAppliedThisMatch) {
                            _finalScoreAppliedThisMatch = true;
                            log(`[FINAL SCORE] Match at ${matchElapsed.toFixed(1)}s - switching to final score: ${newScore} (${newScore/10000})`);
                        }
                    } else if (CONFIG.scoreMode === 'fixed') {
                        newScore = CONFIG.fixedScore;
                        log(`[FIXED MODE] Using fixed score: ${newScore} (${newScore/10000})`);
                    } else {
                        if (_dynamicCap === null) {
                            _dynamicCap = Math.round((CONFIG.scoreRangeMin + CONFIG.scoreRangeMax) / 2000) * 1000;
                        }
                        if (Math.random() < 0.5) {
                            _dynamicCap += 1000;
                        } else {
                            _dynamicCap -= 1000;
                        }
                        _dynamicCap = Math.max(CONFIG.scoreRangeMin, Math.min(CONFIG.scoreRangeMax, _dynamicCap));
                        newScore = _dynamicCap;
                    }

                    modified.q = newScore;
                    if (json.m !== undefined) modified.m = json.m;
                    if (json.type !== undefined) modified.type = json.type;

                    log(`[${isRankedFrame ? 'RANKED' : 'NORMAL'}] frame=${json.p} q: ${json.q}→${modified.q} (${(json.q/10000).toFixed(2)}→${(modified.q/10000).toFixed(2)})`);
                    _lastSpoofedScore = modified.q / 10000;
                    spoofPanel();
                    return originalSend.call(this, rewriteBytes(bytes, json, modified));
                }
            }

            const isRankedScoreType = json.type === "RANKED_SCORE" && typeof json.score !== "undefined";
            if (isRankedScoreType && CONFIG.scoreEnabled) {
                const modified = { ...json };
                if (CONFIG.scoreMode === 'fixed') {
                    modified.score = CONFIG.fixedScore / 10000;
                } else {
                    if (_dynamicCap === null) {
                        _dynamicCap = Math.round((CONFIG.scoreRangeMin + CONFIG.scoreRangeMax) / 2000) * 1000;
                    }
                    modified.score = _dynamicCap / 10000;
                }
                modified.score = Math.min(modified.score, 10);
                _lastSpoofedScore = modified.score;
                log(`[RANKED_SCORE type] score: ${json.score}→${modified.score}`);
                spoofPanel();
                return originalSend.call(this, rewriteBytes(bytes, json, modified));
            }
        }
        return originalSend.call(this, data);
    };

    const origOnMessageDesc = Object.getOwnPropertyDescriptor(RTCDataChannel.prototype, 'onmessage');
    if (origOnMessageDesc) {
        Object.defineProperty(RTCDataChannel.prototype, 'onmessage', {
            set(fn) {
                origOnMessageDesc.set.call(this, function(event) {
                    const parsed = tryDecode(event.data);
                    if (parsed?.json) {
                        const { json } = parsed;
                        if (typeof json.p !== 'undefined' && typeof json.q !== 'undefined' && !json.type && json.q > 0) {
                            log(`OPP frame=${json.p} score=${(json.q/10000).toFixed(2)}`);
                        }
                    }
                    return fn.call(this, event);
                });
            },
            get: origOnMessageDesc.get,
            configurable: true
        });
    }

    const originalAEL = RTCDataChannel.prototype.addEventListener;
    RTCDataChannel.prototype.addEventListener = function (type, listener, options) {
        if (type !== 'message' || typeof listener !== 'function')
            return originalAEL.call(this, type, listener, options);

        const wrapped = function (event) {
            const parsed = tryDecode(event.data);
            if (parsed?.json) {
                const { json } = parsed;
                if (typeof json.p !== 'undefined' && typeof json.q !== 'undefined' && !json.type && json.q > 0) {
                    log(`OPP (AEL) frame=${json.p} score=${(json.q/10000).toFixed(2)}`);
                }
            }
            return listener.call(this, event);
        };
        return originalAEL.call(this, type, wrapped, options);
    };

    // ─── FINALIZE SCORE FIELDS (matches actual payload structure) ───────────
    const FINALIZE_SCORE_FIELDS = [
        'selfScore', 'player1Score', 'player2Score',
        'hostScore', 'actualScore', 'verifiedScore',
        'serverScore', 'realFinalScore', 'clientScore',
        'adjustedScore', 'opponentScore'
    ];

    const origFetch = _window.fetch;
    _window.fetch = async function(url, options) {
        const urlStr = typeof url === 'string' ? url : (url?.url || '');

        if (urlStr.includes('/api/match/finalize') || urlStr.includes('/api/ranked/finalize')) {
            if (options?.body && CONFIG.resultEnabled) {
                try {
                    const body = JSON.parse(options.body);
                    log('FINALIZE (original):', JSON.stringify(body).substring(0, 500));

                    const finalTarget = _getFinalTarget();
                    const finalFloat = finalTarget / 10000;

                    let patched = false;

                    // Strategy 1: legacy nested score object (body.u or body.i)
                    const scoreObj = body.u || body.i;
                    if (scoreObj && scoreObj.e !== undefined) {
                        const realE = parseInt(scoreObj.e) || 0;
                        scoreObj.e = String(finalTarget);
                        if (body.i) _isRanked = true;
                        log(`[LEGACY] score.e: ${realE} → ${scoreObj.e}`);
                        patched = true;
                    }

                    // Strategy 2: flat score fields on body (new structure from logs)
                    for (const field of FINALIZE_SCORE_FIELDS) {
                        if (field in body && body[field] !== undefined) {
                            // Only patch "my" score fields, not opponent's
                            if (field === 'opponentScore' || field === 'rivalScore') continue;
                            const old = body[field];
                            // Values are stored as raw ints (e.g. 94000) or floats (9.4)
                            // Detect which format by magnitude
                            if (typeof old === 'number') {
                                body[field] = old > 100 ? finalTarget : finalFloat;
                                log(`[FLAT] ${field}: ${old} → ${body[field]}`);
                                patched = true;
                            } else if (typeof old === 'string') {
                                body[field] = String(old > '100' ? finalTarget : finalFloat);
                                log(`[FLAT STR] ${field}: ${old} → ${body[field]}`);
                                patched = true;
                            }
                        }
                    }

                    // Strategy 3: settlement / hud scores arrays
                    if (body.settlement?.scores && Array.isArray(body.settlement.scores)) {
                        const s = body.settlement.scores;
                        const myIdx = s[0] >= s[1] ? 0 : 1;
                        const old = s[myIdx];
                        s[myIdx] = old > 100 ? finalTarget : finalFloat;
                        log(`[SETTLEMENT] scores[${myIdx}]: ${old} → ${s[myIdx]}`);
                        patched = true;
                    }
                    if (body.hud?.scores && Array.isArray(body.hud.scores)) {
                        const s = body.hud.scores;
                        const myIdx = s[0] >= s[1] ? 0 : 1;
                        const old = s[myIdx];
                        s[myIdx] = old > 100 ? finalTarget : finalFloat;
                        log(`[HUD] scores[${myIdx}]: ${old} → ${s[myIdx]}`);
                        patched = true;
                    }

                    if (!patched) {
                        log('[FINALIZE] No known score fields found in body — sending as-is');
                    }

                    options = { ...options, body: JSON.stringify(body) };
                    log('FINALIZE REQUEST (modified):', JSON.stringify(body));
                } catch(e) {
                    log('Could not parse finalize body:', e);
                }
            }

            const response = await origFetch.call(this, url, options);
            const clone = response.clone();
            clone.json().then(data => {
                log('FINALIZE RESPONSE:', JSON.stringify(data));
                if (response.ok) {
                    _lockedFinalTarget = null;
                    _finalApplied = false;
                    _lastSpoofedScore = null;
                    _matchStartTime = null;
                    _finalScoreAppliedThisMatch = false;
                }
            }).catch(() => {});
            return response;
        }

        // ── BOOSTED_STATS: only keep is_pro, no fake ELO/wins/streaks ──────
        const BOOSTED_STATS = {
            is_pro: true,
        };

        if (urlStr.includes('supabase.co/rest/v1/profiles')) {
            const response = await origFetch.call(this, url, options);
            const clone = response.clone();
            try {
                const data = await clone.json();
                if (Array.isArray(data) && data.length > 0) {
                    const modified = data.map(profile => ({ ...profile, ...BOOSTED_STATS }));
                    const newHeaders = new Headers(response.headers);
                    newHeaders.set('content-type', 'application/json');
                    return new Response(JSON.stringify(modified), {
                        status: response.status,
                        statusText: response.statusText,
                        headers: newHeaders
                    });
                }
            } catch(e) {}
            return response;
        }

        if (urlStr.includes('/api/profiles/public/')) {
            const response = await origFetch.call(this, url, options);
            const clone = response.clone();
            try {
                const data = await clone.json();
                if (data && data.profile) {
                    const modified = {
                        ...data,
                        profile: {
                            ...data.profile,
                            is_pro: true,
                        }
                    };
                    return new Response(JSON.stringify(modified), {
                        status: response.status,
                        statusText: response.statusText,
                        headers: response.headers
                    });
                }
            } catch(e) {}
            return response;
        }

        if (urlStr.includes('/api/profile/ranked-stats')) {
            const response = await origFetch.call(this, url, options);
            return response;
        }

        if (urlStr.includes('/api/profile/world-rank')) {
            const response = await origFetch.call(this, url, options);
            return response;
        }

        if (urlStr.includes('/api/profile/lobby-summary')) {
            const response = await origFetch.call(this, url, options);
            const clone = response.clone();
            try {
                const data = await clone.json();
                if (data && typeof data === 'object') {
                    const modified = {
                        ...data,
                        is_pro: true,
                    };
                    return new Response(JSON.stringify(modified), {
                        status: response.status,
                        statusText: response.statusText,
                        headers: response.headers
                    });
                }
            } catch(e) {}
            return response;
        }

        if (urlStr === '/api/profile' || urlStr.endsWith('/api/profile')) {
            const response = await origFetch.call(this, url, options);
            const clone = response.clone();
            try {
                const data = await clone.json();
                if (data && data.profile) {
                    const modified = {
                        ...data,
                        profile: {
                            ...data.profile,
                            is_pro: true,
                        }
                    };
                    return new Response(JSON.stringify(modified), {
                        status: response.status,
                        statusText: response.statusText,
                        headers: response.headers
                    });
                }
            } catch(e) {}
            return response;
        }

        return origFetch.call(this, url, options);
    };

    let _lockedFinalTarget = null;
    let _lastFinalMode = null;
    let _finalApplied = false;

    function _getFinalTarget() {
        if (_lockedFinalTarget === null || _lastFinalMode !== CONFIG.finalScoreMode) {
            _finalApplied = false;
            _lastFinalMode = CONFIG.finalScoreMode;
            if (CONFIG.finalScoreMode === 'range') {
                _lockedFinalTarget = Math.round(CONFIG.finalScoreRangeMin + Math.random() * (CONFIG.finalScoreRangeMax - CONFIG.finalScoreRangeMin));
            } else {
                _lockedFinalTarget = parseInt(CONFIG.myFinalScore);
            }
            log(`_getFinalTarget locked: ${_lockedFinalTarget} (${CONFIG.finalScoreMode})`);
        }
        if (CONFIG.finalScoreMode === 'fixed') {
            return parseInt(CONFIG.myFinalScore);
        }
        return _lockedFinalTarget;
    }

    // ─── ZUSTAND STORE PATCH ────────────────────────────────────────────────
    function patchZustandStore() {
        try {
            const wpChunk = _window.webpackChunk_N_E || _window.webpackChunknextjs_app || _window.webpackChunk;
            if (!wpChunk) return false;
            let req;
            try {
                req = wpChunk.push([[Symbol()], {}, e => e]);
            } catch(e) { return false; }
            if (typeof req !== 'function') return false;

            let store = null;
            try {
                const mod = req(16225);
                if (mod) {
                    store = Object.values(mod).find(val =>
                        val && typeof val.getState === 'function' &&
                        'selfScore' in (val.getState() || {})
                    );
                }
            } catch(e) {}

            if (!store && req.m) {
                for (const id of Object.keys(req.m)) {
                    try {
                        const mod = req(id);
                        if (!mod || typeof mod !== 'object') continue;
                        const found = Object.values(mod).find(val =>
                            val && typeof val.getState === 'function' &&
                            'selfScore' in (val.getState() || {})
                        );
                        if (found) {
                            store = found;
                            log(`Found Zustand store via scan in module ${id}`);
                            break;
                        }
                    } catch(e) {}
                }
            }

            if (!store) return false;
            return patchStore(store);
        } catch(e) {
            log('patchZustandStore error:', e);
            return false;
        }
    }

    function patchStore(store) {
        try {
            const state = store.getState();

            const origSetMyScore = state.setMyScore;
            if (origSetMyScore && !origSetMyScore.__patched) {
                store.setState({
                    setMyScore: function(score) {
                        if (!CONFIG.scoreEnabled) return origSetMyScore.call(this, score);
                        let boosted;
                        if (CONFIG.scoreMode === 'fixed') {
                            boosted = CONFIG.fixedScore / 10000;
                        } else {
                            if (_dynamicCap === null) {
                                _dynamicCap = Math.round((CONFIG.scoreRangeMin + CONFIG.scoreRangeMax) / 2000) * 1000;
                            }
                            boosted = _dynamicCap / 10000;
                        }
                        log(`setMyScore: ${score.toFixed(2)} → ${boosted.toFixed(2)}`);
                        _lastSpoofedScore = boosted;
                        spoofPanel();
                        return origSetMyScore.call(this, boosted);
                    }
                });
                store.getState().setMyScore.__patched = true;
                log('setMyScore patched');
            }

            const origApply = state.applyFinalScores;
            if (origApply && !origApply.__patched) {
                store.setState({
                    applyFinalScores: function(p1, p2, iAmPlayer1) {
                        log('applyFinalScores called — injecting final target');
                        const target = _getFinalTarget();
                        const myScore = target / 10000;
                        const newP1 = iAmPlayer1 ? myScore : p1;
                        const newP2 = iAmPlayer1 ? p2 : myScore;
                        log(`applyFinalScores → p1=${newP1} p2=${newP2} iAmPlayer1=${iAmPlayer1}`);
                        _finalApplied = true;
                        _lastSpoofedScore = null;
                        return origApply.call(this, newP1, newP2, iAmPlayer1);
                    }
                });
                store.getState().applyFinalScores.__patched = true;
                log('applyFinalScores patched');
            }

            return true;
        } catch(e) {
            log('patchStore error:', e);
            return false;
        }
    }

    let patchAttempts = 0;
    const patchPoll = setInterval(() => {
        patchAttempts++;
        if (patchZustandStore()) {
            clearInterval(patchPoll);
            log(`Zustand store patched after ${patchAttempts} attempts`);
        } else if (patchAttempts % 50 === 0) {
            log(`Still looking for Zustand store... (attempt ${patchAttempts})`);
        }
    }, 200);

    // ── TIER_MAP: Adam removed, Slayer is now the top tier ─────────────────
    const TIER_MAP = [
        { name: 'Slayer',   emoji: '☠️', hexColor: '#f472b6', textShadow: '0 0 12px rgba(244,114,182,0.9)',   min: 9.5 },
        { name: 'Chad',     emoji: '👑', hexColor: '#fb923c', textShadow: '0 0 10px rgba(251,146,60,0.8)',    min: 8.9 },
        { name: 'Chadlite', emoji: '⚜️', hexColor: '#facc15', textShadow: '0 0 8px rgba(250,204,21,0.8)',     min: 8.3 },
        { name: 'HTN',      emoji: '🌟', hexColor: '#a3e635', textShadow: '0 0 8px rgba(163,230,53,0.8)',     min: 7.0 },
        { name: 'MTN',      emoji: '⭐', hexColor: '#86efac', textShadow: '0 0 6px rgba(134,239,172,0.7)',    min: 5.6 },
        { name: 'LTN',      emoji: '🌙', hexColor: '#34d399', textShadow: '0 0 6px rgba(52,211,153,0.6)',     min: 3.1 },
        { name: 'Sub3',     emoji: '🦀', hexColor: '#b45309', textShadow: '0 0 6px rgba(180,83,9,0.7)',       min: 0.1 },
    ];

    let _lastSpoofedScore = null;
    let _dynamicCap = null;

    function getTierForScore(score) {
        for (const tier of TIER_MAP) {
            if (score >= tier.min) return tier;
        }
        return TIER_MAP[TIER_MAP.length - 1];
    }

    function spoofPanel() {
        if (_lastSpoofedScore === null) return;
        const displayScore = _lastSpoofedScore;
        const tier = getTierForScore(displayScore);

        const myPanel = document.querySelector('.glass-panel.absolute.top-5') ||
            document.querySelector('.glass-panel.absolute.top-8') ||
            document.querySelector('[class*="glass-panel"][class*="absolute"][class*="left"]') ||
            document.querySelector('[class*="glass-panel"][class*="absolute"][class*="top"]') ||
            document.querySelector('[class*="ranked"][class*="score"]') ||
            document.querySelector('[class*="player-score"]') ||
            document.querySelector('[class*="my-score"]') ||
            (() => {
                const allPanels = document.querySelectorAll('[class*="glass"], [class*="panel"], [class*="score-card"]');
                for (const p of allPanels) {
                    const spans = p.querySelectorAll('span.font-mono');
                    for (const s of spans) {
                        if (/^\d+\.?\d*$/.test(s.textContent.trim())) return p;
                    }
                }
                return null;
            })();
        if (!myPanel) return;

        const allMono = myPanel.querySelectorAll('span.font-mono');
        let scoreSpan = null;
        for (const s of allMono) {
            if (/^\d+\.?\d*$/.test(s.textContent.trim())) {
                scoreSpan = s;
                break;
            }
        }
        if (!scoreSpan) return;

        if (scoreSpan.textContent.trim() !== displayScore.toFixed(1)) {
            scoreSpan.textContent = displayScore.toFixed(1);
        }

        const tierSpan = scoreSpan.nextElementSibling;
        if (tierSpan) {
            const want = `${tier.emoji} ${tier.name}`;
            if (tierSpan.textContent !== want) tierSpan.textContent = want;
            if (tierSpan.style.color !== tier.hexColor) tierSpan.style.color = tier.hexColor;
            if (tierSpan.style.textShadow !== tier.textShadow) tierSpan.style.textShadow = tier.textShadow;
        }

        const allSpans = myPanel.querySelectorAll('span');
        for (const span of allSpans) {
            if (span === scoreSpan) continue;
            const t = span.textContent.trim();
            const tierNames = ['Slayer','Chad','Chadlite','HTN','MTN','LTN','Sub3'];
            if (tierNames.some(n => t.includes(n)) && !t.includes(tier.name)) {
                span.textContent = `${tier.emoji} ${tier.name}`;
                span.style.color = tier.hexColor;
                span.style.textShadow = tier.textShadow;
            }
            if (span.style.color && span.style.color !== tier.hexColor) {
                const tierColors = ['#f472b6','#fb923c','#facc15','#a3e635','#86efac','#34d399','#b45309'];
                if (tierColors.includes(span.style.color)) {
                    span.style.color = tier.hexColor;
                    span.style.textShadow = tier.textShadow;
                }
            }
        }
    }

    const _panelObserver = new MutationObserver(spoofPanel);
    let _observedPanel = null;

    function attachPanelObserver() {
        const myPanel = document.querySelector('.glass-panel.absolute.top-5') ||
            document.querySelector('.glass-panel.absolute.top-8') ||
            document.querySelector('[class*="glass-panel"][class*="absolute"][class*="left"]') ||
            document.querySelector('[class*="glass-panel"][class*="absolute"][class*="top"]') ||
            document.querySelector('[class*="ranked"][class*="score"]') ||
            document.querySelector('[class*="player-score"]') ||
            document.querySelector('[class*="my-score"]') ||
            (() => {
                const allPanels = document.querySelectorAll('[class*="glass"], [class*="panel"], [class*="score-card"]');
                for (const p of allPanels) {
                    const spans = p.querySelectorAll('span.font-mono');
                    for (const s of spans) {
                        if (/^\d+\.?\d*$/.test(s.textContent.trim())) return p;
                    }
                }
                return null;
            })();
        if (myPanel && myPanel !== _observedPanel) {
            if (_observedPanel) _panelObserver.disconnect();
            _panelObserver.observe(myPanel, { childList: true, subtree: true, characterData: true });
            _observedPanel = myPanel;
        }
    }

    setInterval(() => { attachPanelObserver(); spoofPanel(); }, 16);

    const OriginalWebSocket = _window.WebSocket;
    _window.WebSocket = function(...args) {
        const ws = new OriginalWebSocket(...args);
        ws.addEventListener('message', function(event) {
            if (typeof event.data === 'string') {
                if (event.data.includes('FINAL_SCORES') || event.data.includes('elo') || event.data.includes('score')) {
                    log('WS TEXT:', event.data);
                }
                return;
            }
            const buf = event.data instanceof ArrayBuffer ? event.data : null;
            if (!buf) return;
            const bytes = new Uint8Array(buf);
            const size = bytes.length;
            const text = new TextDecoder('utf-8', { fatal: false }).decode(bytes);
            const strings = text.match(/[\x20-\x7E]{4,}/g) || [];
            if (size === 108 || size > 50) {
                log(`WS RECV binary [${size} bytes] strings:`, strings);
                strings.forEach(s => {
                    if (/\d\.\d/.test(s) || s.includes('score') || s.includes('win') || s.includes('elo')) {
                        log('   Possible score string:', s);
                    }
                });
            }
        });
        return ws;
    };
    Object.setPrototypeOf(_window.WebSocket, OriginalWebSocket);
    _window.WebSocket.prototype = OriginalWebSocket.prototype;
    ['CONNECTING','OPEN','CLOSING','CLOSED'].forEach(k => {
        try {
            Object.defineProperty(_window.WebSocket, k, {
                value: OriginalWebSocket[k],
                writable: false,
                configurable: true
            });
        } catch(e) {}
    });

    log('v13.3 cheatmoggle loaded');

    const _trueOriginalGetUserMedia = navigator.mediaDevices.getUserMedia.bind(navigator.mediaDevices);

    let _camSpoofActive = false;
    let _camStream = null;

    navigator.mediaDevices.getUserMedia = async function(constraints) {
        if (_camSpoofActive && _camStream && constraints && (constraints.video || constraints.video === true)) {
            log('[CAM SPOOF] Intercepting getUserMedia - returning spoofed stream');
            setTimeout(() => {
                const scannerVid = document.querySelector('video.scanner-video');
                if (scannerVid) scannerVid.srcObject = _camStream;
                if (window._mogPCs) {
                    const fakeTrack = _camStream.getVideoTracks()[0];
                    for (const pc of window._mogPCs) {
                        try {
                            pc.getSenders().forEach(sender => {
                                if (sender.track?.kind === 'video') {
                                    sender.replaceTrack(fakeTrack).catch(() => {});
                                }
                            });
                        } catch(e) {}
                    }
                }
            }, 100);

            if (constraints.audio) {
                try {
                    const realAudio = await _trueOriginalGetUserMedia({ audio: constraints.audio });
                    return new MediaStream([
                        ..._camStream.getVideoTracks(),
                        ...realAudio.getAudioTracks()
                    ]);
                } catch(e) {
                    return _camStream;
                }
            }
            return _camStream;
        }
        const stream = await _trueOriginalGetUserMedia(constraints);
        stream.getVideoTracks().forEach(t => {
            t.addEventListener('ended', () => log('VIDEO TRACK ENDED:', t.label));
            t.addEventListener('mute',  () => log('VIDEO TRACK MUTED:', t.label));
        });
        return stream;
    };

    const _OrigRTCPC = window.RTCPeerConnection;
    window.RTCPeerConnection = function(...args) {
        const pc = new _OrigRTCPC(...args);
        const _origAddTrack = pc.addTrack.bind(pc);
        pc.addTrack = function(track, ...streams) {
            return _origAddTrack(track, ...streams);
        };
        return pc;
    };
    Object.setPrototypeOf(window.RTCPeerConnection, _OrigRTCPC);
    window.RTCPeerConnection.prototype = _OrigRTCPC.prototype;

    // ══════════════════════════════════════════════════════════════════════════
    // CHEATMOGGLE UI
    // ══════════════════════════════════════════════════════════════════════════

    function buildMenu() {
        if (document.getElementById('cm-root')) return;

        function applyTheme(themeName) {
            const theme = THEMES[themeName] || THEMES.midnight;
            CONFIG.theme = themeName;
            document.documentElement.style.setProperty('--cm-primary', theme.primary);
            document.documentElement.style.setProperty('--cm-primary-rgb', theme.primaryRgb);
            document.documentElement.style.setProperty('--cm-secondary', theme.secondary);
            document.documentElement.style.setProperty('--cm-accent', theme.accent);
            document.documentElement.style.setProperty('--cm-accent-rgb', theme.accentRgb);
            document.documentElement.style.setProperty('--cm-success', theme.success);
            document.documentElement.style.setProperty('--cm-warning', theme.warning);
            document.documentElement.style.setProperty('--cm-danger', theme.danger);
            document.documentElement.style.setProperty('--cm-bg-dark', theme.bgDark);
            document.documentElement.style.setProperty('--cm-bg-card', theme.bgCard);
            document.documentElement.style.setProperty('--cm-bg-elevated', theme.bgElevated);
            document.documentElement.style.setProperty('--cm-border', theme.border);
            document.documentElement.style.setProperty('--cm-text', theme.text);
            document.documentElement.style.setProperty('--cm-text-muted', theme.textMuted);
            saveConfig();
        }

        const style = document.createElement('style');
        style.textContent = `
            @import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=Space+Grotesk:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap');

            :root {
                --cm-primary: #00ff88;
                --cm-primary-rgb: 0,255,136;
                --cm-secondary: #00cc6a;
                --cm-accent: #7dffb3;
                --cm-accent-rgb: 125,255,179;
                --cm-success: #00ff88;
                --cm-warning: #ffcc00;
                --cm-danger: #ff4444;
                --cm-bg-dark: #0a0f0c;
                --cm-bg-card: #0d1a12;
                --cm-bg-elevated: #132218;
                --cm-border: rgba(0,255,136,0.15);
                --cm-text: #e0ffe8;
                --cm-text-muted: #7da88a;
                --cm-glow: 0 0 30px rgba(var(--cm-primary-rgb),0.3);
            }

            #cm-toggle-btn {
                position: fixed;
                top: 16px;
                right: 16px;
                z-index: 999999;
                width: 32px;
                height: 32px;
                border-radius: 8px;
                background: linear-gradient(135deg, var(--cm-primary), var(--cm-secondary));
                border: none;
                cursor: grab;
                display: flex;
                align-items: center;
                justify-content: center;
                box-shadow: 0 2px 12px rgba(var(--cm-primary-rgb),0.3), 0 1px 4px rgba(0,0,0,0.2);
                transition: transform 0.15s, box-shadow 0.15s;
                user-select: none;
                touch-action: none;
            }
            #cm-toggle-btn:active { cursor: grabbing; }
            #cm-toggle-btn:hover {
                transform: scale(1.05);
                box-shadow: 0 4px 16px rgba(var(--cm-primary-rgb),0.4), 0 2px 6px rgba(0,0,0,0.3);
            }
            #cm-toggle-btn.dragging { cursor: grabbing; transition: none; }
            #cm-toggle-btn svg {
                width: 22px;
                height: 22px;
                fill: white;
                filter: drop-shadow(0 1px 2px rgba(0,0,0,0.3));
            }

            #cm-root {
                position: fixed;
                top: 70px;
                right: 16px;
                z-index: 999998;
                width: 280px;
                min-width: 220px;
                max-width: 90vw;
                max-height: 70vh;
                min-height: 200px;
                background: var(--cm-bg-dark);
                border-radius: 12px;
                font-family: 'Inter', -apple-system, sans-serif;
                color: var(--cm-text);
                border: 1px solid var(--cm-border);
                box-shadow: 0 0 40px rgba(var(--cm-primary-rgb),0.1), 0 15px 30px rgba(0,0,0,0.4);
                display: none;
                opacity: 0;
                overflow: hidden;
                transition: opacity 0.2s ease, transform 0.2s ease;
                transform: translateY(-10px) scale(0.98);
                resize: both;
            }
            #cm-root.visible {
                display: flex;
                flex-direction: column;
                opacity: 1;
                transform: translateY(0) scale(1);
            }
            #cm-root.dragging { transition: none; user-select: none; }

            .cm-header {
                padding: 8px 10px 6px;
                background: linear-gradient(180deg, rgba(var(--cm-primary-rgb),0.08) 0%, transparent 100%);
                border-bottom: 1px solid var(--cm-border);
                cursor: grab;
                user-select: none;
                flex-shrink: 0;
            }
            .cm-header:active { cursor: grabbing; }

            .cm-title-row {
                display: flex;
                align-items: center;
                justify-content: space-between;
                margin-bottom: 6px;
            }
            .cm-logo { display: flex; align-items: center; gap: 6px; }
            .cm-logo-icon {
                width: 24px; height: 24px;
                border-radius: 6px;
                background: linear-gradient(135deg, var(--cm-primary), var(--cm-secondary));
                display: flex; align-items: center; justify-content: center;
                box-shadow: 0 2px 8px rgba(var(--cm-primary-rgb),0.3);
            }
            .cm-logo-icon svg { width: 14px; height: 14px; fill: white; }
            .cm-title {
                font-family: 'Space Grotesk', sans-serif;
                font-size: 13px; font-weight: 700; letter-spacing: -0.02em;
                background: linear-gradient(135deg, #fff 0%, var(--cm-accent) 100%);
                -webkit-background-clip: text; -webkit-text-fill-color: transparent;
            }
            .cm-version {
                font-size: 8px; font-weight: 600; color: var(--cm-text-muted);
                background: var(--cm-bg-elevated); padding: 1px 4px; border-radius: 3px; margin-left: 4px;
            }
            .cm-status-row { display: flex; align-items: center; gap: 4px; }
            .cm-pill {
                padding: 2px 5px; border-radius: 4px;
                font-size: 8px; font-weight: 700;
                text-transform: uppercase; letter-spacing: 0.04em;
            }
            .cm-pill.active {
                background: rgba(16,185,129,0.2); color: var(--cm-success);
                border: 1px solid rgba(16,185,129,0.3);
            }
            .cm-pill.mode {
                background: rgba(var(--cm-primary-rgb),0.2); color: var(--cm-primary);
                border: 1px solid rgba(var(--cm-primary-rgb),0.3);
            }

            .cm-discord-link {
                display: flex; align-items: center; gap: 6px;
                padding: 6px 10px;
                background: linear-gradient(135deg, #5865F2 0%, #7289da 100%);
                border-radius: 8px; font-size: 10px; font-weight: 600;
                color: white; text-decoration: none; transition: all 0.2s ease; margin-left: auto;
            }
            .cm-discord-link:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(88,101,242,0.4); }
            .cm-discord-link svg { width: 14px; height: 14px; fill: currentColor; }

            .cm-tabs {
                display: flex; gap: 2px;
                background: var(--cm-bg-card); padding: 2px; border-radius: 6px;
            }
            .cm-tab {
                flex: 1; padding: 5px 4px; border-radius: 4px;
                font-size: 9px; font-weight: 600; text-align: center;
                cursor: pointer; transition: all 0.15s ease;
                color: var(--cm-text-muted); background: transparent; border: none; white-space: nowrap;
            }
            .cm-tab:hover { color: var(--cm-text); background: rgba(255,255,255,0.03); }
            .cm-tab.active {
                background: var(--cm-bg-elevated); color: white;
                box-shadow: 0 1px 4px rgba(0,0,0,0.2);
            }

            .cm-body { padding: 8px; overflow-y: auto; flex: 1; }
            .cm-body::-webkit-scrollbar { width: 4px; }
            .cm-body::-webkit-scrollbar-track { background: transparent; }
            .cm-body::-webkit-scrollbar-thumb { background: rgba(var(--cm-primary-rgb),0.3); border-radius: 2px; }

            .cm-panel { display: none; }
            .cm-panel.active { display: block; animation: cmFadeIn 0.2s ease; }
            @keyframes cmFadeIn { from { opacity: 0; transform: translateY(6px); } to { opacity: 1; transform: translateY(0); } }

            .cm-section { margin-bottom: 8px; }
            .cm-section:last-child { margin-bottom: 0; }
            .cm-section-title {
                font-size: 8px; font-weight: 700;
                text-transform: uppercase; letter-spacing: 0.1em;
                color: var(--cm-text-muted); margin-bottom: 4px;
                display: flex; align-items: center; gap: 4px; justify-content: space-between;
            }
            .cm-section-title > span { display: flex; align-items: center; gap: 4px; }
            .cm-section-title > span::after {
                content: ''; width: 20px; height: 1px;
                background: linear-gradient(90deg, var(--cm-border), transparent);
            }
            .cm-section-toggle { transform: scale(0.7); }
            .cm-section-disabled { opacity: 0.4; pointer-events: none; }
            .cm-divider { height: 1px; background: var(--cm-border); margin: 10px 0; }

            .cm-card {
                background: var(--cm-bg-card); border-radius: 8px;
                padding: 6px; border: 1px solid var(--cm-border);
            }

            .cm-live-score {
                text-align: center; padding: 8px 6px;
                background: linear-gradient(135deg, rgba(var(--cm-primary-rgb),0.08), rgba(var(--cm-accent-rgb),0.05));
                border-radius: 8px;
            }
            .cm-score-value {
                font-family: 'JetBrains Mono', monospace;
                font-size: 24px; font-weight: 800; letter-spacing: -0.02em; line-height: 1; margin-bottom: 2px;
            }
            .cm-score-tier { font-size: 9px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.06em; }

            .cm-row {
                display: flex; align-items: center; justify-content: space-between;
                padding: 4px 0; border-bottom: 1px solid var(--cm-border);
            }
            .cm-row:last-child { border-bottom: none; }
            .cm-label { font-size: 10px; font-weight: 500; color: var(--cm-text); }
            .cm-value { font-family: 'JetBrains Mono', monospace; font-size: 9px; font-weight: 600; color: var(--cm-text); }

            .cm-slider-row { display: flex; flex-direction: column; gap: 2px; padding: 4px 0; border-bottom: 1px solid var(--cm-border); }
            .cm-slider-row:last-child { border-bottom: none; }
            .cm-slider-header { display: flex; justify-content: space-between; align-items: center; }
            .cm-slider-label { font-size: 9px; font-weight: 500; }
            .cm-slider-value {
                font-family: 'JetBrains Mono', monospace; font-size: 9px; font-weight: 600; color: var(--cm-text);
                background: var(--cm-bg-elevated); border: 1px solid var(--cm-border); padding: 1px 4px; border-radius: 3px;
            }
            .cm-slider-track {
                position: relative; height: 4px;
                background: var(--cm-bg-elevated); border-radius: 2px; overflow: hidden; border: 1px solid var(--cm-border);
            }
            .cm-slider-fill {
                position: absolute; top: 0; left: 0; height: 100%;
                background: var(--cm-text-muted); border-radius: 2px; transition: width 0.1s ease; opacity: 0.4;
            }
            .cm-slider {
                position: absolute; top: 0; left: 0; width: 100%; height: 100%;
                -webkit-appearance: none; background: transparent; cursor: pointer; margin: 0;
            }
            .cm-slider::-webkit-slider-thumb {
                -webkit-appearance: none; width: 14px; height: 14px; border-radius: 50%;
                background: var(--cm-text); cursor: pointer;
                box-shadow: 0 2px 6px rgba(0,0,0,0.4); transition: transform 0.15s ease, box-shadow 0.15s ease;
            }
            .cm-slider::-webkit-slider-thumb:hover { transform: scale(1.15); box-shadow: 0 2px 10px rgba(0,0,0,0.5); }

            .cm-toggle { position: relative; width: 32px; height: 18px; cursor: pointer; }
            .cm-toggle input { opacity: 0; width: 0; height: 0; }
            .cm-toggle-track {
                position: absolute; inset: 0; border-radius: 11px;
                background: var(--cm-bg-elevated); border: 1px solid var(--cm-border); transition: all 0.25s ease;
            }
            .cm-toggle input:checked + .cm-toggle-track { background: var(--cm-text); border-color: var(--cm-text); }
            .cm-toggle-thumb {
                position: absolute; top: 2px; left: 2px; width: 14px; height: 14px; border-radius: 50%;
                background: var(--cm-text); box-shadow: 0 1px 3px rgba(0,0,0,0.3);
                transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);
            }
            .cm-toggle input:checked ~ .cm-toggle-thumb { left: 16px; background: var(--cm-bg-dark); }

            .cm-btn-group { display: flex; gap: 3px; background: var(--cm-bg-elevated); padding: 2px; border-radius: 6px; }
            .cm-btn-opt {
                padding: 6px 10px; border-radius: 6px; font-size: 10px; font-weight: 700;
                text-transform: uppercase; letter-spacing: 0.03em; cursor: pointer; transition: all 0.15s ease;
                background: transparent; color: var(--cm-text-muted); border: none;
            }
            .cm-btn-opt:hover { color: var(--cm-text); }
            .cm-btn-opt.active { background: var(--cm-text); color: var(--cm-bg-dark); box-shadow: 0 2px 6px rgba(0,0,0,0.3); }

            .cm-preview {
                margin-top: 12px; padding: 16px;
                background: linear-gradient(135deg, rgba(var(--cm-primary-rgb),0.08), rgba(var(--cm-accent-rgb),0.05));
                border-radius: 10px; text-align: center; border: 1px solid rgba(var(--cm-primary-rgb),0.15);
            }
            .cm-preview-score { font-family: 'JetBrains Mono', monospace; font-size: 32px; font-weight: 800; }
            .cm-preview-tier { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: 0.08em; margin-top: 4px; }

            .cm-file-picker {
                display: flex; align-items: center; gap: 8px; padding: 8px;
                background: var(--cm-bg-elevated); border: 1px dashed var(--cm-border);
                border-radius: 6px; cursor: pointer; transition: all 0.15s ease;
            }
            .cm-file-picker:hover { border-color: var(--cm-text); background: rgba(var(--cm-accent-rgb),0.05); }
            .cm-file-icon {
                width: 28px; height: 28px; border-radius: 6px;
                background: var(--cm-bg-card); display: flex; align-items: center; justify-content: center;
            }
            .cm-file-icon svg { width: 14px; height: 14px; fill: var(--cm-text-muted); }
            .cm-file-name { font-size: 10px; color: var(--cm-text-muted); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
            .cm-file-name.selected { color: var(--cm-success); }

            .cm-preset-section { margin-top: 6px; padding-top: 6px; border-top: 1px solid var(--cm-border); }
            .cm-preset-label { font-size: 8px; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: var(--cm-text-muted); display: block; margin-bottom: 4px; }
            .cm-preset-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
            .cm-preset-btn {
                padding: 4px 6px; font-size: 8px; font-weight: 500;
                border: 1px solid var(--cm-border); border-radius: 4px;
                background: var(--cm-bg-elevated); color: var(--cm-text); cursor: pointer; transition: all 0.15s ease; text-align: center;
            }
            .cm-preset-btn:hover { background: var(--cm-text); color: var(--cm-bg-dark); border-color: var(--cm-text); }
            .cm-preset-btn.active { background: var(--cm-text); color: var(--cm-bg-dark); border-color: var(--cm-text); }

            .cm-color-row { display: flex; align-items: center; gap: 10px; }
            .cm-color-input { width: 32px; height: 32px; border-radius: 8px; border: none; cursor: pointer; padding: 0; background: none; }

            .cm-input {
                background: var(--cm-bg-elevated); border: 1px solid var(--cm-border);
                border-radius: 6px; padding: 6px 10px;
                font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--cm-text);
                outline: none; transition: all 0.2s ease;
            }
            .cm-input:focus { border-color: var(--cm-primary); box-shadow: 0 0 0 2px rgba(var(--cm-primary-rgb),0.2); }
            .cm-score-input {
                -moz-appearance: textfield;
            }
            .cm-score-input::-webkit-outer-spin-button,
            .cm-score-input::-webkit-inner-spin-button {
                -webkit-appearance: none;
                margin: 0;
            }
            .cm-select {
                background: var(--cm-bg-elevated); border: 1px solid var(--cm-border);
                border-radius: 6px; padding: 6px 10px;
                font-family: 'JetBrains Mono', monospace; font-size: 11px; color: var(--cm-text);
                outline: none; cursor: pointer; transition: all 0.2s ease;
            }
            .cm-select:focus { border-color: var(--cm-primary); box-shadow: 0 0 0 2px rgba(var(--cm-primary-rgb),0.2); }
            .cm-select option { background: var(--cm-bg-dark); color: var(--cm-text); }
            .cm-btn-small {
                background: linear-gradient(135deg, var(--cm-primary), var(--cm-secondary));
                border: none; border-radius: 4px; padding: 4px 10px;
                font-family: 'Inter', sans-serif; font-size: 10px; font-weight: 600;
                color: white; cursor: pointer; transition: all 0.2s ease;
            }
            .cm-btn-small:hover { transform: scale(1.02); filter: brightness(1.1); }

            .cm-shapes { display: flex; gap: 4px; }
            .cm-shape-btn {
                width: 32px; height: 32px; border-radius: 8px;
                border: 1px solid var(--cm-border); background: var(--cm-bg-elevated);
                cursor: pointer; font-size: 14px; display: flex; align-items: center; justify-content: center; transition: all 0.15s ease;
            }
            .cm-shape-btn:hover { background: rgba(var(--cm-primary-rgb),0.15); }
            .cm-shape-btn.active { background: linear-gradient(135deg, var(--cm-primary), var(--cm-secondary)); border-color: transparent; }

            .cm-theme-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; margin-top: 4px; }
            .cm-theme-btn {
                padding: 6px 4px; border-radius: 6px; border: 1px solid var(--cm-border);
                background: var(--cm-bg-elevated); cursor: pointer; transition: all 0.15s ease; text-align: center;
            }
            .cm-theme-btn:hover { border-color: rgba(var(--cm-primary-rgb),0.4); }
            .cm-theme-btn.active { border-color: var(--cm-text); box-shadow: 0 0 8px rgba(var(--cm-primary-rgb),0.2); }
            .cm-theme-preview { width: 16px; height: 16px; border-radius: 4px; margin: 0 auto 3px; }
            .cm-theme-name { font-size: 8px; font-weight: 600; color: var(--cm-text); }

            .cm-panic-btn {
                width: 100%; padding: 6px 10px; font-size: 9px; font-weight: 600;
                border: 1px solid var(--cm-danger); border-radius: 4px;
                background: rgba(239,68,68,0.1); color: var(--cm-danger); cursor: pointer; transition: all 0.15s ease;
            }
            .cm-panic-btn:hover { background: var(--cm-danger); color: white; }

            #cm-root.stream-hidden,
            #cm-toggle-btn.stream-hidden { display: none !important; opacity: 0 !important; pointer-events: none !important; }

#cm-watermark {
                position: fixed; bottom: 16px; right: 16px; z-index: 999990;
                padding: 6px 12px; border-radius: 8px;
                background: rgba(var(--cm-primary-rgb),0.1); backdrop-filter: blur(8px);
                border: 1px solid rgba(var(--cm-primary-rgb),0.2);
                font-family: 'JetBrains Mono', monospace; font-size: 9px; font-weight: 600;
                color: rgba(255,255,255,0.35); letter-spacing: 0.05em; cursor: grab; user-select: none;
            }

            /* Smoother animations */
            .cm-toggle-track, .cm-toggle-thumb, .cm-btn-opt, .cm-tab, .cm-card, .cm-section,
            .cm-file-picker, .cm-theme-btn, .cm-panic-btn, .cm-input, .cm-slider-fill {
                transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1) !important;
            }
            .cm-card:hover { transform: translateY(-1px); box-shadow: 0 4px 12px rgba(0,0,0,0.15); }
            .cm-btn-opt:active, .cm-tab:active { transform: scale(0.96); }
            .cm-toggle input:checked ~ .cm-toggle-thumb { transform: translateX(0); }
            #cm-root { transition: opacity 0.3s ease, transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), visibility 0.3s ease; }
            #cm-root:not(.visible) { opacity: 0; transform: translateX(20px) scale(0.95); visibility: hidden; pointer-events: none; }
            #cm-root.visible { opacity: 1; transform: translateX(0) scale(1); visibility: visible; }

            /* Disclaimer popup */
            #cm-disclaimer {
                position: fixed; bottom: 16px; left: 16px; z-index: 999999;
                padding: 10px 14px; border-radius: 8px;
                background: rgba(234, 179, 8, 0.15); backdrop-filter: blur(10px);
                border: 1px solid rgba(234, 179, 8, 0.4);
                font-family: 'Inter', -apple-system, sans-serif; font-size: 11px; font-weight: 500;
                color: #eab308; display: flex; align-items: center; gap: 10px;
                animation: cm-slide-in 0.4s cubic-bezier(0.4, 0, 0.2, 1);
            }
            #cm-disclaimer.hiding {
                animation: cm-slide-out 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;
            }
            @keyframes cm-slide-in {
                from { opacity: 0; transform: translateY(20px); }
                to { opacity: 1; transform: translateY(0); }
            }
            @keyframes cm-slide-out {
                from { opacity: 1; transform: translateY(0); }
                to { opacity: 0; transform: translateY(20px); }
            }
            #cm-disclaimer-close {
                background: none; border: none; color: #eab308; cursor: pointer;
                padding: 2px; display: flex; align-items: center; justify-content: center;
                border-radius: 4px; transition: all 0.2s ease;
            }
            #cm-disclaimer-close:hover { background: rgba(234, 179, 8, 0.2); }
            #cm-disclaimer-close svg { width: 14px; height: 14px; }
        `;
        document.head.appendChild(style);

        applyTheme(CONFIG.theme || 'crimson');

        const btn = document.createElement('button');
        btn.id = 'cm-toggle-btn';
        btn.innerHTML = `<svg viewBox="0 0 24 24"><text x="12" y="17" text-anchor="middle" font-size="16" font-weight="bold" fill="white" font-family="Arial, sans-serif">C</text></svg>`;
        document.body.appendChild(btn);

        const root = document.createElement('div');
        root.id = 'cm-root';
        root.innerHTML = `
            <div class="cm-header">
                <div class="cm-title-row">
                    <div class="cm-logo">
                        <div class="cm-logo-icon">
                            <svg viewBox="0 0 24 24"><text x="12" y="17" text-anchor="middle" font-size="14" font-weight="bold" fill="currentColor" font-family="Arial, sans-serif">C</text></svg>
                        </div>
                        <div>
                            <span class="cm-title">cheatmoggle</span>
                            <span class="cm-version">v13.3</span>
                        </div>
                    </div>
                    <a href="https://discord.gg/f8GwCMHhD9" target="_blank" class="cm-discord-link">
                        <svg viewBox="0 0 24 24"><path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028 14.09 14.09 0 0 0 1.226-1.994.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/></svg>
                        Join Discord
                    </a>
                </div>
                <div style="display:flex;align-items:center;justify-content:space-between;margin-bottom:12px;">
                    <div class="cm-status-row">
                        <span class="cm-pill active" id="cm-status-pill">ON</span>
                        <span class="cm-pill mode" id="cm-mode-pill">NORMAL</span>
                    </div>
                </div>
                <div class="cm-tabs">
                    <button class="cm-tab active" data-tab="home">Home</button>
                    <button class="cm-tab" data-tab="score">Score</button>
                    <button class="cm-tab" data-tab="effects">Effects</button>
                    <button class="cm-tab" data-tab="camera">Camera</button>
                    <button class="cm-tab" data-tab="settings">Settings</button>
                </div>
            </div>

            <div class="cm-body">
                <!-- HOME PANEL -->
                <div class="cm-panel active" data-panel="home">
                    <div class="cm-section">
                        <div class="cm-section-title">System Status</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Master Switch</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-enable-toggle" checked>
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Power Status</span>
                                <span class="cm-value" id="cm-enabled-val" style="color: var(--cm-success)">ACTIVE</span>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Match Type</span>
                                <span class="cm-value" id="cm-mode-val">NORMAL</span>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Hook Status</span>
                                <span class="cm-value" id="cm-zustand-val" style="color: var(--cm-warning)">PENDING</span>
                            </div>
                        </div>
                    </div>
                    <div class="cm-section">
                        <div class="cm-section-title">Current Rating</div>
                        <div class="cm-card cm-live-score">
                            <div class="cm-score-value" id="cm-live-score">--</div>
                            <div class="cm-score-tier" id="cm-live-tier">Awaiting match data...</div>
                        </div>
                    </div>
                </div>

                <!-- SCORE PANEL -->
                <div class="cm-panel" data-panel="score">
                    <div class="cm-section">
                        <div class="cm-section-title">
                            <span>Score Control</span>
                            <label class="cm-toggle cm-section-toggle">
                                <input type="checkbox" id="cm-score-enabled" checked>
                                <div class="cm-toggle-track"></div>
                                <div class="cm-toggle-thumb"></div>
                            </label>
                        </div>
                        <div class="cm-card" id="cm-score-content">
                            <div class="cm-row">
                                <span class="cm-label">Mode</span>
                                <div class="cm-btn-group">
                                    <button class="cm-btn-opt active" data-smode="range">Range</button>
                                    <button class="cm-btn-opt" data-smode="fixed">Fixed</button>
                                </div>
                            </div>
                            <div id="cm-score-fixed" style="display:none;">
                                <div class="cm-slider-row">
                                    <div class="cm-slider-header">
                                        <span class="cm-slider-label">Score (1-10)</span>
                                        <input type="number" class="cm-input cm-score-input" id="cm-fixed-score" min="1" max="10" step="0.1" value="9.4" style="width:60px;text-align:center;">
                                    </div>
                                </div>
                            </div>
                            <div id="cm-score-range">
                                <div class="cm-slider-row">
                                    <div class="cm-slider-header">
                                        <span class="cm-slider-label">Min (1-10)</span>
                                        <input type="number" class="cm-input cm-score-input" id="cm-score-min" min="1" max="10" step="0.1" value="8.5" style="width:60px;text-align:center;">
                                    </div>
                                </div>
                                <div class="cm-slider-row">
                                    <div class="cm-slider-header">
                                        <span class="cm-slider-label">Max (1-10)</span>
                                        <input type="number" class="cm-input cm-score-input" id="cm-score-max" min="1" max="10" step="0.1" value="9.5" style="width:60px;text-align:center;">
                                    </div>
                                </div>
                            </div>
                        </div>
                    </div>

                    <div class="cm-section">
                        <div class="cm-section-title">
                            <span>Result Settings</span>
                            <label class="cm-toggle cm-section-toggle">
                                <input type="checkbox" id="cm-result-enabled" checked>
                                <div class="cm-toggle-track"></div>
                                <div class="cm-toggle-thumb"></div>
                            </label>
                        </div>
                        <div class="cm-card" id="cm-result-content">
                            <div class="cm-row">
                                <span class="cm-label">Type</span>
                                <div class="cm-btn-group">
                                    <button class="cm-btn-opt active" data-fmode="fixed">Static</button>
                                    <button class="cm-btn-opt" data-fmode="range">Dynamic</button>
                                </div>
                            </div>
                            <div id="cm-final-fixed">
                                <div class="cm-slider-row">
                                    <div class="cm-slider-header">
                                        <span class="cm-slider-label">Target (1-10)</span>
                                        <input type="number" class="cm-input cm-score-input" id="cm-final-score" min="1" max="10" step="0.1" value="9.4" style="width:60px;text-align:center;">
                                    </div>
                                </div>
                            </div>
                            <div id="cm-final-range" style="display:none;">
                                <div class="cm-slider-row">
                                    <div class="cm-slider-header">
                                        <span class="cm-slider-label">Lower Bound (1-10)</span>
                                        <input type="number" class="cm-input cm-score-input" id="cm-final-range-min" min="1" max="10" step="0.1" value="8.5" style="width:60px;text-align:center;">
                                    </div>
                                </div>
                                <div class="cm-slider-row">
                                    <div class="cm-slider-header">
                                        <span class="cm-slider-label">Upper Bound (1-10)</span>
                                        <input type="number" class="cm-input cm-score-input" id="cm-final-range-max" min="1" max="10" step="0.1" value="9.7" style="width:60px;text-align:center;">
                                    </div>
                                </div>
                            </div>
                        </div>
                        <div class="cm-preview">
                            <div class="cm-preview-score" id="cm-score-preview-num" style="color:#f472b6">9.6</div>
                            <div class="cm-preview-tier" id="cm-score-preview-tier" style="color:#f472b6">Slayer</div>
                        </div>
                    </div>
                </div>

                <!-- EFFECTS PANEL -->
                <div class="cm-panel" data-panel="effects">
                    <div class="cm-section">
                        <div class="cm-section-title">Ambient Particles</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Activate Particles</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-particles-toggle">
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Glow Aura</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-particles-glow" checked>
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Shape Style</span>
                                <div class="cm-shapes">
                                    <button class="cm-shape-btn active" data-shape="circle">&#x25cf;</button>
                                    <button class="cm-shape-btn" data-shape="star">&#x2605;</button>
                                    <button class="cm-shape-btn" data-shape="square">&#x25a0;</button>
                                    <button class="cm-shape-btn" data-shape="heart">&#x2665;</button>
                                </div>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Tint</span>
                                <div class="cm-color-row">
                                    <input type="color" class="cm-color-input" id="cm-particles-color" value="#ffffff">
                                    <span class="cm-label" style="font-size:11px">Spectrum</span>
                                    <label class="cm-toggle">
                                        <input type="checkbox" id="cm-particles-rainbow">
                                        <div class="cm-toggle-track"></div>
                                        <div class="cm-toggle-thumb"></div>
                                    </label>
                                </div>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Density</span>
                                    <span class="cm-slider-value" id="cm-particles-count-val">80</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-particles-count-fill" style="width:24%"></div>
                                    <input type="range" class="cm-slider" id="cm-particles-count" min="10" max="300" step="10" value="80">
                                </div>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Scale</span>
                                    <span class="cm-slider-value" id="cm-particles-size-val">5px</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-particles-size-fill" style="width:21%"></div>
                                    <input type="range" class="cm-slider" id="cm-particles-size" min="1" max="20" step="1" value="5">
                                </div>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Velocity</span>
                                    <span class="cm-slider-value" id="cm-particles-speed-val">1.0x</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-particles-speed-fill" style="width:17%"></div>
                                    <input type="range" class="cm-slider" id="cm-particles-speed" min="0.2" max="5.0" step="0.2" value="1.0">
                                </div>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- CAMERA PANEL -->
                <div class="cm-panel" data-panel="camera">
                    <div class="cm-section">
                        <div class="cm-section-title">Virtual Camera</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Activate Spoof</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-camspoof-toggle">
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Flip Horizontal</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-cammirror-toggle">
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Repeat Playback</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-camloop-toggle" checked>
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Media Type</span>
                                <div class="cm-btn-group">
                                    <button class="cm-btn-opt active" data-src="video">Clip</button>
                                    <button class="cm-btn-opt" data-src="image">Photo</button>
                                </div>
                            </div>
                            <div id="cm-src-video">
                                <div class="cm-row" style="margin-bottom:8px;">
                                    <span class="cm-label">Source</span>
                                    <div class="cm-btn-group">
                                        <button class="cm-btn-opt active" data-videosrc="file">File</button>
                                        <button class="cm-btn-opt" data-videosrc="url">URL</button>
                                        <button class="cm-btn-opt" data-videosrc="history">History</button>
                                    </div>
                                </div>
                                <div id="cm-video-file-src">
                                    <div class="cm-file-picker" id="cm-video-picker">
                                        <div class="cm-file-icon"><svg viewBox="0 0 24 24"><path d="M15 8v8H5V8h10m1-2H4c-.55 0-1 .45-1 1v10c0 .55.45 1 1 1h12c.55 0 1-.45 1-1v-3.5l4 4v-11l-4 4V7c0-.55-.45-1-1-1z"/></svg></div>
                                        <span class="cm-file-name" id="cm-video-name">Choose video file...</span>
                                    </div>
                                    <input type="file" id="cm-video-input" accept="video/*" style="display:none">
                                </div>
                                <div id="cm-video-url-src" style="display:none;">
                                    <input type="text" class="cm-input" id="cm-video-url" placeholder="Enter video URL..." style="width:100%;margin-bottom:8px;">
                                    <button class="cm-btn-small" id="cm-video-url-load">Load URL</button>
                                </div>
                                <div id="cm-video-history-src" style="display:none;">
                                    <select class="cm-select" id="cm-video-history-select" style="width:100%;">
                                        <option value="">Select from history...</option>
                                    </select>
                                </div>
                                <div class="cm-row" style="margin-top:8px;">
                                    <span class="cm-label">Random Start Time</span>
                                    <label class="cm-toggle">
                                        <input type="checkbox" id="cm-random-start">
                                        <div class="cm-toggle-track"></div>
                                        <div class="cm-toggle-thumb"></div>
                                    </label>
                                </div>
                            </div>
                            <div id="cm-src-image" style="display:none;">
                                <div class="cm-row" style="margin-bottom:8px;">
                                    <span class="cm-label">Source</span>
                                    <div class="cm-btn-group">
                                        <button class="cm-btn-opt active" data-imgsrc="file">File</button>
                                        <button class="cm-btn-opt" data-imgsrc="url">URL</button>
                                        <button class="cm-btn-opt" data-imgsrc="history">History</button>
                                    </div>
                                </div>
                                <div id="cm-image-file-src">
                                    <div class="cm-file-picker" id="cm-image-picker">
                                        <div class="cm-file-icon"><svg viewBox="0 0 24 24"><path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/></svg></div>
                                        <span class="cm-file-name" id="cm-image-name">Choose image file...</span>
                                    </div>
                                    <input type="file" id="cm-image-input" accept="image/*" style="display:none">
                                </div>
                                <div id="cm-image-url-src" style="display:none;">
                                    <input type="text" class="cm-input" id="cm-image-url" placeholder="Enter image URL..." style="width:100%;margin-bottom:8px;">
                                    <button class="cm-btn-small" id="cm-image-url-load">Load URL</button>
                                </div>
                                <div id="cm-image-history-src" style="display:none;">
                                    <select class="cm-select" id="cm-image-history-select" style="width:100%;">
                                        <option value="">Select from history...</option>
                                    </select>
                                </div>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Play Rate</span>
                                    <span class="cm-slider-value" id="cm-camspeed-val">1.0x</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-camspeed-fill" style="width:27%"></div>
                                    <input type="range" class="cm-slider" id="cm-camspeed" min="0.25" max="3.0" step="0.25" value="1.0">
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="cm-section">
                        <div class="cm-section-title">Camera Overlay Text</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Enable Text</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-camtext-toggle">
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row" style="margin-top:8px;">
                                <span class="cm-label">Text</span>
                                <input type="text" class="cm-input" id="cm-camtext-input" value="Your Text Here" style="width:140px;text-align:center;">
                            </div>
                            <div class="cm-row" style="margin-top:8px;">
                                <span class="cm-label">Color</span>
                                <input type="color" class="cm-color-input" id="cm-camtext-color" value="#ffffff">
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Font Size</span>
                                    <span class="cm-slider-value" id="cm-camtext-size-val">24px</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-camtext-size-fill" style="width:30%"></div>
                                    <input type="range" class="cm-slider" id="cm-camtext-size" min="12" max="72" step="2" value="24">
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="cm-section">
                        <div class="cm-section-title">Audio Spoof</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Enable Audio Spoof</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-audiospoof-toggle">
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row" style="margin-bottom:8px;">
                                <span class="cm-label">Source</span>
                                <div class="cm-btn-group">
                                    <button class="cm-btn-opt active" data-audiosrc="file">File</button>
                                    <button class="cm-btn-opt" data-audiosrc="url">URL</button>
                                    <button class="cm-btn-opt" data-audiosrc="history">History</button>
                                </div>
                            </div>
                            <div id="cm-audio-file-src">
                                <div class="cm-file-picker" id="cm-audio-picker">
                                    <div class="cm-file-icon"><svg viewBox="0 0 24 24"><path d="M12 3v10.55c-.59-.34-1.27-.55-2-.55-2.21 0-4 1.79-4 4s1.79 4 4 4 4-1.79 4-4V7h4V3h-6z"/></svg></div>
                                    <span class="cm-file-name" id="cm-audio-name">Choose audio file...</span>
                                </div>
                                <input type="file" id="cm-audio-input" accept="audio/*" style="display:none">
                            </div>
                            <div id="cm-audio-url-src" style="display:none;">
                                <input type="text" class="cm-input" id="cm-audio-url" placeholder="Enter audio URL..." style="width:100%;margin-bottom:8px;">
                                <button class="cm-btn-small" id="cm-audio-url-load">Load URL</button>
                            </div>
                            <div id="cm-audio-history-src" style="display:none;">
                                <select class="cm-select" id="cm-audio-history-select" style="width:100%;">
                                    <option value="">Select from history...</option>
                                </select>
                            </div>
                            <div class="cm-row" style="margin-top:8px;">
                                <span class="cm-label">Loop Audio</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-audioloop-toggle" checked>
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Audio Speed</span>
                                    <span class="cm-slider-value" id="cm-audiospeed-val">1.0x</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-audiospeed-fill" style="width:27%"></div>
                                    <input type="range" class="cm-slider" id="cm-audiospeed" min="0.25" max="3.0" step="0.25" value="1.0">
                                </div>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Audio Volume</span>
                                    <span class="cm-slider-value" id="cm-audiovolume-val">100%</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-audiovolume-fill" style="width:100%"></div>
                                    <input type="range" class="cm-slider" id="cm-audiovolume" min="0" max="100" step="5" value="100">
                                </div>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Bass Boost</span>
                                    <span class="cm-slider-value" id="cm-audiobass-val">0 dB</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-audiobass-fill" style="width:50%"></div>
                                    <input type="range" class="cm-slider" id="cm-audiobass" min="-12" max="12" step="1" value="0">
                                </div>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Treble</span>
                                    <span class="cm-slider-value" id="cm-audiotreble-val">0 dB</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-audiotreble-fill" style="width:50%"></div>
                                    <input type="range" class="cm-slider" id="cm-audiotreble" min="-12" max="12" step="1" value="0">
                                </div>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Warmth</span>
                                    <span class="cm-slider-value" id="cm-audiowarmth-val">0 dB</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-audiowarmth-fill" style="width:50%"></div>
                                    <input type="range" class="cm-slider" id="cm-audiowarmth" min="-12" max="12" step="1" value="0">
                                </div>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Status</span>
                                <span class="cm-value" id="cm-audio-status" style="color:var(--cm-text-muted)">Inactive</span>
                            </div>
                        </div>
                    </div>
                    <div class="cm-section">
                        <div class="cm-section-title">Screen Effects</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Fake Ban Screen</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-ban-overlay-toggle">
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Fake Loading</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-loading-overlay-toggle">
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Current Effect</span>
                                <span class="cm-value" id="cm-overlay-status">None</span>
                            </div>
                        </div>
                    </div>
                </div>

                <!-- SETTINGS PANEL -->
                <div class="cm-panel" data-panel="settings">
                    <div class="cm-section">
                        <div class="cm-section-title">Developer</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Console Logs</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-debug-toggle" checked>
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                        </div>
                    </div>
                    <div class="cm-section">
                        <div class="cm-section-title">Hotkeys</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Open Panel</span>
                                <input type="text" class="cm-input" id="cm-menukey" value="h" style="width:50px;text-align:center;">
                            </div>
                        </div>
                    </div>
                    <div class="cm-section">
                        <div class="cm-section-title">Stream Proof</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Panic Key</span>
                                <input type="text" class="cm-input" id="cm-panic-key" value="p" style="width:50px;text-align:center;">
                            </div>
                            <div class="cm-row">
                                <span class="cm-label">Mobile: Triple-tap button</span>
                                <span class="cm-value" style="font-size:8px;color:var(--cm-text-muted);">to hide/show</span>
                            </div>
                            <div class="cm-row">
                                <button class="cm-panic-btn" id="cm-panic-now">Hide All Now</button>
                            </div>
                            <div class="cm-row" style="margin-top:6px;border-top:1px solid var(--cm-border);padding-top:6px;">
                                <span class="cm-label">Iframe Mode (OBS)</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-iframe-mode">
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-row">
                                <span class="cm-label" style="font-size:8px;color:var(--cm-text-muted);">Hides GUI from screen capture</span>
                            </div>
                        </div>
                    </div>
                    <div class="cm-section">
                        <div class="cm-section-title">Branding</div>
                        <div class="cm-card">
                            <div class="cm-row">
                                <span class="cm-label">Display Badge</span>
                                <label class="cm-toggle">
                                    <input type="checkbox" id="cm-wm-show" checked>
                                    <div class="cm-toggle-track"></div>
                                    <div class="cm-toggle-thumb"></div>
                                </label>
                            </div>
                            <div class="cm-slider-row">
                                <div class="cm-slider-header">
                                    <span class="cm-slider-label">Visibility</span>
                                    <span class="cm-slider-value" id="cm-wm-alpha-val">20%</span>
                                </div>
                                <div class="cm-slider-track">
                                    <div class="cm-slider-fill" id="cm-wm-alpha-fill" style="width:20%"></div>
                                    <input type="range" class="cm-slider" id="cm-wm-alpha" min="0" max="100" step="5" value="20">
                                </div>
                            </div>
                        </div>
                    </div>
                    <div class="cm-section">
                        <div class="cm-section-title">Appearance</div>
                        <div class="cm-card">
                            <div class="cm-theme-grid" id="cm-theme-grid"></div>
                        </div>
                    </div>
                </div>
            </div>
        `;
        document.body.appendChild(root);

        // Build theme grid
        const themeGrid = document.getElementById('cm-theme-grid');
        Object.entries(THEMES).forEach(([key, theme]) => {
            const tbtn = document.createElement('button');
            tbtn.className = 'cm-theme-btn' + (key === (CONFIG.theme || 'crimson') ? ' active' : '');
            tbtn.dataset.theme = key;
            tbtn.innerHTML = `
                <div class="cm-theme-preview" style="background: linear-gradient(135deg, ${theme.primary}, ${theme.secondary})"></div>
                <div class="cm-theme-name">${theme.name}</div>
            `;
            tbtn.addEventListener('click', function() {
                themeGrid.querySelectorAll('.cm-theme-btn').forEach(b => b.classList.remove('active'));
                this.classList.add('active');
                applyTheme(key);
            });
            themeGrid.appendChild(tbtn);
        });

        // Toggle menu
        let _btnDragged = false;
        function _toggleMenu() {
            if (_btnDragged) { _btnDragged = false; return; }
            root.classList.toggle('visible');
        }
        btn.addEventListener('click', _toggleMenu);

        // Toggle button drag
        let _btnDragging = false, _btnDragOffX = 0, _btnDragOffY = 0, _btnStartX = 0, _btnStartY = 0;
        btn.addEventListener('mousedown', function(e) {
            _btnDragging = true; _btnDragged = false;
            _btnStartX = e.clientX; _btnStartY = e.clientY;
            const rect = btn.getBoundingClientRect();
            _btnDragOffX = e.clientX - rect.left; _btnDragOffY = e.clientY - rect.top;
            btn.classList.add('dragging'); e.preventDefault();
        });
        document.addEventListener('mousemove', function(e) {
            if (!_btnDragging) return;
            if (Math.abs(e.clientX - _btnStartX) > 5 || Math.abs(e.clientY - _btnStartY) > 5) _btnDragged = true;
            btn.style.left = (e.clientX - _btnDragOffX) + 'px';
            btn.style.top = (e.clientY - _btnDragOffY) + 'px';
            btn.style.right = 'auto';
        });
        document.addEventListener('mouseup', function() {
            if (_btnDragging) { _btnDragging = false; btn.classList.remove('dragging'); }
        });

        btn.addEventListener('touchstart', function(e) {
            const touch = e.touches[0];
            _btnDragging = true; _btnDragged = false;
            _btnStartX = touch.clientX; _btnStartY = touch.clientY;
            const rect = btn.getBoundingClientRect();
            _btnDragOffX = touch.clientX - rect.left; _btnDragOffY = touch.clientY - rect.top;
            btn.classList.add('dragging');
        }, { passive: true });
        document.addEventListener('touchmove', function(e) {
            if (!_btnDragging) return;
            const touch = e.touches[0];
            if (Math.abs(touch.clientX - _btnStartX) > 5 || Math.abs(touch.clientY - _btnStartY) > 5) _btnDragged = true;
            btn.style.left = (touch.clientX - _btnDragOffX) + 'px';
            btn.style.top = (touch.clientY - _btnDragOffY) + 'px';
            btn.style.right = 'auto';
        }, { passive: true });
        document.addEventListener('touchend', function() {
            if (_btnDragging) { _btnDragging = false; btn.classList.remove('dragging'); }
        });

        let _menuKey = 'KeyH';
        let _panicKey = 'KeyP';
        let _streamHidden = false;

        function toggleStreamProof() {
            _streamHidden = !_streamHidden;
            root.classList.toggle('stream-hidden', _streamHidden);
            btn.classList.toggle('stream-hidden', _streamHidden);
            log('[STREAM PROOF] ' + (_streamHidden ? 'Hidden' : 'Visible'));
        }

        document.addEventListener('keydown', function(e) {
            if (e.code === _menuKey && !e.target.matches('input[type="text"], input[type="search"], textarea')) {
                _toggleMenu();
            }
            if (e.code === _panicKey && !e.target.matches('input[type="text"], input[type="search"], textarea')) {
                toggleStreamProof();
            }
        });

        // Menu drag
        let _menuDragging = false, _menuDragOffX = 0, _menuDragOffY = 0;
        const _menuHeader = root.querySelector('.cm-header');
        _menuHeader.addEventListener('mousedown', function(e) {
            if (e.target.matches('input, button, label, .cm-tab, a')) return;
            _menuDragging = true; root.classList.add('dragging');
            const rect = root.getBoundingClientRect();
            _menuDragOffX = e.clientX - rect.left; _menuDragOffY = e.clientY - rect.top;
            e.preventDefault();
        });
        document.addEventListener('mousemove', function(e) {
            if (!_menuDragging) return;
            root.style.left = (e.clientX - _menuDragOffX) + 'px';
            root.style.top = (e.clientY - _menuDragOffY) + 'px';
            root.style.right = 'auto';
        });
        document.addEventListener('mouseup', function() {
            if (_menuDragging) { _menuDragging = false; root.classList.remove('dragging'); }
        });
        _menuHeader.addEventListener('touchstart', function(e) {
            if (e.target.matches('input, button, label, .cm-tab, a')) return;
            const touch = e.touches[0];
            _menuDragging = true; root.classList.add('dragging');
            const rect = root.getBoundingClientRect();
            _menuDragOffX = touch.clientX - rect.left; _menuDragOffY = touch.clientY - rect.top;
        }, { passive: true });
        document.addEventListener('touchmove', function(e) {
            if (!_menuDragging) return;
            const touch = e.touches[0];
            root.style.left = (touch.clientX - _menuDragOffX) + 'px';
            root.style.top = (touch.clientY - _menuDragOffY) + 'px';
            root.style.right = 'auto';
        }, { passive: true });
        document.addEventListener('touchend', function() {
            if (_menuDragging) { _menuDragging = false; root.classList.remove('dragging'); }
        });

        // Tab switching
        root.querySelectorAll('.cm-tab').forEach(tab => {
            tab.addEventListener('click', function() {
                root.querySelectorAll('.cm-tab').forEach(t => t.classList.remove('active'));
                root.querySelectorAll('.cm-panel').forEach(p => p.classList.remove('active'));
                this.classList.add('active');
                root.querySelector(`[data-panel="${this.dataset.tab}"]`).classList.add('active');
            });
        });

        function updateSliderFill(slider, fill, min, max) {
            const pct = ((slider.value - min) / (max - min)) * 100;
            fill.style.width = pct + '%';
        }

        // Enable toggle
        document.getElementById('cm-enable-toggle').addEventListener('change', function() {
            CONFIG.enabled = this.checked;
            document.getElementById('cm-enabled-val').textContent = this.checked ? 'ACTIVE' : 'OFF';
            document.getElementById('cm-enabled-val').style.color = this.checked ? 'var(--cm-success)' : 'var(--cm-danger)';
            document.getElementById('cm-status-pill').textContent = this.checked ? 'ON' : 'OFF';
            document.getElementById('cm-status-pill').classList.toggle('active', this.checked);
        });

        document.getElementById('cm-score-enabled').addEventListener('change', function() {
            CONFIG.scoreEnabled = this.checked;
            document.getElementById('cm-score-content').classList.toggle('cm-section-disabled', !this.checked);
            saveConfig();
        });
        document.getElementById('cm-result-enabled').addEventListener('change', function() {
            CONFIG.resultEnabled = this.checked;
            document.getElementById('cm-result-content').classList.toggle('cm-section-disabled', !this.checked);
            saveConfig();
        });

        function setScoreModeUI(mode) {
            CONFIG.scoreMode = mode;
            document.querySelectorAll('[data-smode]').forEach(b => b.classList.toggle('active', b.dataset.smode === mode));
            document.getElementById('cm-score-fixed').style.display = mode === 'fixed' ? 'block' : 'none';
            document.getElementById('cm-score-range').style.display = mode === 'range' ? 'block' : 'none';
            _dynamicCap = null;
            saveConfig();
        }
        document.querySelectorAll('[data-smode]').forEach(b => {
            b.addEventListener('click', function() { setScoreModeUI(this.dataset.smode); });
        });

        const fixedScoreInput = document.getElementById('cm-fixed-score');
        fixedScoreInput.addEventListener('input', function() {
            let val = parseFloat(this.value);
            if (isNaN(val)) val = 1;
            val = Math.max(1, Math.min(10, val));
            CONFIG.fixedScore = Math.round(val * 10000);
            saveConfig();
        });

        const scoreMinInput = document.getElementById('cm-score-min');
        scoreMinInput.addEventListener('input', function() {
            let val = parseFloat(this.value);
            if (isNaN(val)) val = 1;
            val = Math.max(1, Math.min(10, val));
            CONFIG.scoreRangeMin = Math.round(val * 10000);
            _dynamicCap = null; saveConfig();
        });
        const scoreMaxInput = document.getElementById('cm-score-max');
        scoreMaxInput.addEventListener('input', function() {
            let val = parseFloat(this.value);
            if (isNaN(val)) val = 1;
            val = Math.max(1, Math.min(10, val));
            CONFIG.scoreRangeMax = Math.round(val * 10000);
            _dynamicCap = null; saveConfig();
        });

        const finalInput = document.getElementById('cm-final-score');
        finalInput.addEventListener('input', function() {
            let val = parseFloat(this.value);
            if (isNaN(val)) val = 1;
            val = Math.max(1, Math.min(10, val));
            CONFIG.myFinalScore = String(Math.round(val * 10000));
            updateScorePreview(); saveConfig();
        });

        function setFinalModeUI(mode) {
            CONFIG.finalScoreMode = mode;
            document.querySelectorAll('[data-fmode]').forEach(b => b.classList.toggle('active', b.dataset.fmode === mode));
            document.getElementById('cm-final-fixed').style.display = mode === 'fixed' ? 'block' : 'none';
            document.getElementById('cm-final-range').style.display = mode === 'range' ? 'block' : 'none';
            updateScorePreview(); saveConfig();
        }
        document.querySelectorAll('[data-fmode]').forEach(b => {
            b.addEventListener('click', function() { setFinalModeUI(this.dataset.fmode); });
        });

        const finalMinInput = document.getElementById('cm-final-range-min');
        finalMinInput.addEventListener('input', function() {
            let val = parseFloat(this.value);
            if (isNaN(val)) val = 1;
            val = Math.max(1, Math.min(10, val));
            CONFIG.finalScoreRangeMin = Math.round(val * 10000);
            updateScorePreview(); saveConfig();
        });
        const finalMaxInput = document.getElementById('cm-final-range-max');
        finalMaxInput.addEventListener('input', function() {
            let val = parseFloat(this.value);
            if (isNaN(val)) val = 1;
            val = Math.max(1, Math.min(10, val));
            CONFIG.finalScoreRangeMax = Math.round(val * 10000);
            updateScorePreview(); saveConfig();
        });

        function updateScorePreview() {
            let score;
            if (CONFIG.finalScoreMode === 'range') {
                score = Math.round(CONFIG.finalScoreRangeMin + Math.random() * (CONFIG.finalScoreRangeMax - CONFIG.finalScoreRangeMin)) / 10000;
            } else {
                score = parseInt(CONFIG.myFinalScore) / 10000;
            }
            const tier = getTierForScore(score);
            const numEl = document.getElementById('cm-score-preview-num');
            const tierEl = document.getElementById('cm-score-preview-tier');
            numEl.textContent = score.toFixed(1);
            numEl.style.color = tier.hexColor;
            numEl.style.textShadow = tier.textShadow;
            tierEl.textContent = `${tier.emoji} ${tier.name}`;
            tierEl.style.color = tier.hexColor;
        }
        updateScorePreview();
        setInterval(() => { if (CONFIG.finalScoreMode === 'range') updateScorePreview(); }, 2000);

        function restoreUIFromConfig() {
            document.getElementById('cm-score-enabled').checked = CONFIG.scoreEnabled;
            document.getElementById('cm-score-content').classList.toggle('cm-section-disabled', !CONFIG.scoreEnabled);
            document.getElementById('cm-result-enabled').checked = CONFIG.resultEnabled;
            document.getElementById('cm-result-content').classList.toggle('cm-section-disabled', !CONFIG.resultEnabled);
            setScoreModeUI(CONFIG.scoreMode);
            document.getElementById('cm-fixed-score').value = (CONFIG.fixedScore / 10000).toFixed(1);
            document.getElementById('cm-score-min').value = (CONFIG.scoreRangeMin / 10000).toFixed(1);
            document.getElementById('cm-score-max').value = (CONFIG.scoreRangeMax / 10000).toFixed(1);
            setFinalModeUI(CONFIG.finalScoreMode);
            document.getElementById('cm-final-score').value = (parseInt(CONFIG.myFinalScore) / 10000).toFixed(1);
            document.getElementById('cm-final-range-min').value = (CONFIG.finalScoreRangeMin / 10000).toFixed(1);
            document.getElementById('cm-final-range-max').value = (CONFIG.finalScoreRangeMax / 10000).toFixed(1);
            if (CONFIG.theme && THEMES[CONFIG.theme]) applyTheme(CONFIG.theme);
        }
        restoreUIFromConfig();

        // Menu keybind
        const menuKeyInput = document.getElementById('cm-menukey');
        let _menuKeyListening = false;
        menuKeyInput.addEventListener('focus', function() {
            _menuKeyListening = true; this.value = 'press';
            this.style.borderColor = 'var(--cm-primary)';
        });
        menuKeyInput.addEventListener('keydown', function(e) {
            if (!_menuKeyListening) return;
            e.preventDefault();
            _menuKey = e.code;
            this.value = e.key === ' ' ? 'Space' : e.key;
            this.style.borderColor = 'var(--cm-success)';
            _menuKeyListening = false; this.blur();
        });

        // Panic keybind
        const panicKeyInput = document.getElementById('cm-panic-key');
        let _panicKeyListening = false;
        panicKeyInput.addEventListener('focus', function() {
            _panicKeyListening = true; this.value = 'press';
            this.style.borderColor = 'var(--cm-primary)';
        });
        panicKeyInput.addEventListener('keydown', function(e) {
            if (!_panicKeyListening) return;
            e.preventDefault();
            _panicKey = e.code;
            this.value = e.key === ' ' ? 'Space' : e.key;
            this.style.borderColor = 'var(--cm-success)';
            _panicKeyListening = false; this.blur();
        });

        document.getElementById('cm-panic-now').addEventListener('click', toggleStreamProof);

        // Mobile triple-tap
        let _tripleTapCount = 0, _tripleTapTimer = null;
        btn.addEventListener('touchend', function(e) {
            if (_btnDragged) return;
            _tripleTapCount++;
            if (_tripleTapCount === 1) {
                _tripleTapTimer = setTimeout(() => { _tripleTapCount = 0; }, 500);
            }
            if (_tripleTapCount === 3) {
                clearTimeout(_tripleTapTimer); _tripleTapCount = 0;
                toggleStreamProof(); e.preventDefault();
            }
        });

        // Iframe mode
        let _iframeMode = false, _iframeWrapper = null;

        function enableIframeMode() {
            if (_iframeWrapper) return;
            _iframeWrapper = document.createElement('div');
            _iframeWrapper.id = 'cm-iframe-wrapper';
            _iframeWrapper.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:999996;';
            const iframe = document.createElement('iframe');
            iframe.id = 'cm-stream-iframe';
            iframe.style.cssText = 'position:fixed;top:0;left:0;width:100%;height:100%;border:none;background:transparent;pointer-events:none;';
            iframe.setAttribute('allowtransparency', 'true');
            _iframeWrapper.appendChild(iframe);
            document.body.appendChild(_iframeWrapper);
            setTimeout(() => {
                try {
                    const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                    iframeDoc.open();
                    iframeDoc.write('<!DOCTYPE html><html><head><style>body{margin:0;background:transparent;overflow:hidden;}</style></head><body></body></html>');
                    iframeDoc.close();
                    const styles = document.createElement('style');
                    styles.textContent = Array.from(document.styleSheets).map(sheet => {
                        try { return Array.from(sheet.cssRules).map(r => r.cssText).join('\n'); } catch(e) { return ''; }
                    }).join('\n');
                    iframeDoc.head.appendChild(styles);
                    btn.style.pointerEvents = 'auto';
                    root.style.pointerEvents = 'auto';
                    iframeDoc.body.appendChild(btn);
                    iframeDoc.body.appendChild(root);
                    iframe.style.pointerEvents = 'auto';
                    iframeDoc.addEventListener('keydown', function(e) {
                        if (e.code === _menuKey) _toggleMenu();
                        if (e.code === _panicKey) toggleStreamProof();
                    });
                    log('[IFRAME MODE] Enabled');
                } catch(err) {
                    log('[IFRAME MODE] Error:', err);
                    disableIframeMode();
                }
            }, 100);
        }

        function disableIframeMode() {
            if (!_iframeWrapper) return;
            try {
                const iframe = document.getElementById('cm-stream-iframe');
                if (iframe) {
                    const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                    if (iframeDoc.body.contains(btn)) document.body.appendChild(btn);
                    if (iframeDoc.body.contains(root)) document.body.appendChild(root);
                }
            } catch(e) {}
            btn.style.position = ''; btn.style.top = ''; btn.style.left = ''; btn.style.right = '';
            root.style.position = ''; root.style.top = ''; root.style.left = ''; root.style.right = '';
            _iframeWrapper.remove(); _iframeWrapper = null;
            log('[IFRAME MODE] Disabled');
        }

        document.getElementById('cm-iframe-mode').addEventListener('change', function() {
            _iframeMode = this.checked;
            if (_iframeMode) enableIframeMode(); else disableIframeMode();
        });

        document.getElementById('cm-debug-toggle').addEventListener('change', function() {
            CONFIG.debug = this.checked;
        });

// Watermark
        const _wm = document.createElement('div');
        _wm.id = 'cm-watermark';
        _wm.textContent = 'cheatmoggle v13.3';
        document.body.appendChild(_wm);

        // Disclaimer popup
        const _disclaimer = document.createElement('div');
        _disclaimer.id = 'cm-disclaimer';
        _disclaimer.innerHTML = `
            <span>⚠️ This script only works for ranked mode</span>
            <button id="cm-disclaimer-close">
                <svg viewBox="0 0 24 24" fill="currentColor"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
            </button>
        `;
        document.body.appendChild(_disclaimer);
        document.getElementById('cm-disclaimer-close').addEventListener('click', function() {
            _disclaimer.classList.add('hiding');
            setTimeout(() => _disclaimer.remove(), 300);
        });

        function applyWmStyle() { _wm.style.opacity = CONFIG.wmAlpha / 100; }
        applyWmStyle();

        document.getElementById('cm-wm-show').addEventListener('change', function() {
            _wm.style.display = this.checked ? 'block' : 'none';
        });
        const wmAlphaSlider = document.getElementById('cm-wm-alpha');
        const wmAlphaFill = document.getElementById('cm-wm-alpha-fill');
        wmAlphaSlider.addEventListener('input', function() {
            CONFIG.wmAlpha = parseInt(this.value);
            document.getElementById('cm-wm-alpha-val').textContent = this.value + '%';
            updateSliderFill(this, wmAlphaFill, 0, 100);
            applyWmStyle();
        });

        // Watermark drag
        let _wmDragging = false, _wmDragOffX = 0, _wmDragOffY = 0;
        _wm.addEventListener('mousedown', function(e) {
            _wmDragging = true;
            _wmDragOffX = e.clientX - _wm.getBoundingClientRect().left;
            _wmDragOffY = e.clientY - _wm.getBoundingClientRect().top;
            _wm.style.cursor = 'grabbing'; e.preventDefault();
        });
        document.addEventListener('mousemove', function(e) {
            if (!_wmDragging) return;
            _wm.style.left = (e.clientX - _wmDragOffX) + 'px';
            _wm.style.top = (e.clientY - _wmDragOffY) + 'px';
            _wm.style.bottom = 'auto'; _wm.style.right = 'auto';
        });
        document.addEventListener('mouseup', function() {
            if (_wmDragging) { _wmDragging = false; _wm.style.cursor = 'grab'; }
        });

        // Live status updater
        setInterval(() => {
            document.getElementById('cm-mode-pill').textContent = _isRanked ? 'RANKED' : 'NORMAL';
            document.getElementById('cm-mode-val').textContent = _isRanked ? 'RANKED' : 'NORMAL';
            if (_lastSpoofedScore !== null) {
                const tier = getTierForScore(_lastSpoofedScore);
                const liveScore = document.getElementById('cm-live-score');
                const liveTier = document.getElementById('cm-live-tier');
                if (liveScore) {
                    liveScore.textContent = _lastSpoofedScore.toFixed(2);
                    liveScore.style.color = tier.hexColor;
                    liveScore.style.textShadow = tier.textShadow;
                }
                if (liveTier) {
                    liveTier.textContent = `${tier.emoji} ${tier.name}`;
                    liveTier.style.color = tier.hexColor;
                }
            }
        }, 200);

// ── CAMERA SPOOF ───────────────────────────────────────────────────
        let _camSrcType = 'video';
        let _camVideoFile = null;
        let _camImageFile = null;
        let _camMirror = false;
        let _camLoop = true;
        let _camSpeed = 1.0;
        let _camVideoEl = null;
        let _camCanvasEl = null;
        let _origAddTrack = null;
        let _camSrcObjPatch = null;
        let _camDrawRAF = null;
        let _camImageEl = null;

        // Camera text overlay settings
        let _camTextEnabled = false;
        let _camTextContent = 'Your Text Here';
        let _camTextColor = '#ffffff';
        let _camTextSize = 24;

        window._mogPCs = window._mogPCs || [];
        const _OrigPC2 = window.RTCPeerConnection;
        window.RTCPeerConnection = function(...args) {
            const pc = new _OrigPC2(...args);
            window._mogPCs.push(pc);
            pc.addEventListener('connectionstatechange', () => {
                if (pc.connectionState === 'closed') {
                    const idx = window._mogPCs.indexOf(pc);
                    if (idx > -1) window._mogPCs.splice(idx, 1);
                }
            });
            return pc;
        };
        Object.setPrototypeOf(window.RTCPeerConnection, _OrigPC2);
        window.RTCPeerConnection.prototype = _OrigPC2.prototype;

        document.querySelectorAll('[data-src]').forEach(b => {
            b.addEventListener('click', function() {
                _camSrcType = this.dataset.src;
                document.querySelectorAll('[data-src]').forEach(x => x.classList.toggle('active', x.dataset.src === _camSrcType));
                document.getElementById('cm-src-video').style.display = _camSrcType === 'video' ? 'block' : 'none';
                document.getElementById('cm-src-image').style.display = _camSrcType === 'image' ? 'block' : 'none';
            });
        });

        // File history storage
        let _videoHistory = JSON.parse(localStorage.getItem('cm_video_history') || '[]');
        let _imageHistory = JSON.parse(localStorage.getItem('cm_image_history') || '[]');
        let _audioHistory = JSON.parse(localStorage.getItem('cm_audio_history') || '[]');
        let _camVideoUrl = null;
        let _camImageUrl = null;
        let _audioUrl = null;

        function addToHistory(type, name, url) {
            let history = type === 'video' ? _videoHistory : type === 'image' ? _imageHistory : _audioHistory;
            const existing = history.findIndex(h => h.name === name || h.url === url);
            if (existing !== -1) history.splice(existing, 1);
            history.unshift({ name, url, date: Date.now() });
            if (history.length > 10) history.pop();
            localStorage.setItem('cm_' + type + '_history', JSON.stringify(history));
            updateHistorySelect(type);
        }

        function updateHistorySelect(type) {
            const history = type === 'video' ? _videoHistory : type === 'image' ? _imageHistory : _audioHistory;
            const select = document.getElementById('cm-' + type + '-history-select');
            if (!select) return;
            select.innerHTML = '<option value="">Select from history...</option>';
            history.forEach((item, i) => {
                const opt = document.createElement('option');
                opt.value = i;
                opt.textContent = item.name || item.url.substring(0, 40) + '...';
                select.appendChild(opt);
            });
        }

        // Video source type switching
        document.querySelectorAll('[data-videosrc]').forEach(btn => {
            btn.addEventListener('click', function() {
                const srcType = this.dataset.videosrc;
                document.querySelectorAll('[data-videosrc]').forEach(x => x.classList.toggle('active', x.dataset.videosrc === srcType));
                document.getElementById('cm-video-file-src').style.display = srcType === 'file' ? 'block' : 'none';
                document.getElementById('cm-video-url-src').style.display = srcType === 'url' ? 'block' : 'none';
                document.getElementById('cm-video-history-src').style.display = srcType === 'history' ? 'block' : 'none';
            });
        });

        // Image source type switching
        document.querySelectorAll('[data-imgsrc]').forEach(btn => {
            btn.addEventListener('click', function() {
                const srcType = this.dataset.imgsrc;
                document.querySelectorAll('[data-imgsrc]').forEach(x => x.classList.toggle('active', x.dataset.imgsrc === srcType));
                document.getElementById('cm-image-file-src').style.display = srcType === 'file' ? 'block' : 'none';
                document.getElementById('cm-image-url-src').style.display = srcType === 'url' ? 'block' : 'none';
                document.getElementById('cm-image-history-src').style.display = srcType === 'history' ? 'block' : 'none';
            });
        });

        // Audio source type switching
        document.querySelectorAll('[data-audiosrc]').forEach(btn => {
            btn.addEventListener('click', function() {
                const srcType = this.dataset.audiosrc;
                document.querySelectorAll('[data-audiosrc]').forEach(x => x.classList.toggle('active', x.dataset.audiosrc === srcType));
                document.getElementById('cm-audio-file-src').style.display = srcType === 'file' ? 'block' : 'none';
                document.getElementById('cm-audio-url-src').style.display = srcType === 'url' ? 'block' : 'none';
                document.getElementById('cm-audio-history-src').style.display = srcType === 'history' ? 'block' : 'none';
            });
        });

        document.getElementById('cm-video-picker').addEventListener('click', () => document.getElementById('cm-video-input').click());
        document.getElementById('cm-video-input').addEventListener('change', function() {
            if (this.files[0]) {
                _camVideoFile = this.files[0];
                _camVideoUrl = null;
                document.getElementById('cm-video-name').textContent = this.files[0].name;
                document.getElementById('cm-video-name').classList.add('selected');
                addToHistory('video', this.files[0].name, URL.createObjectURL(this.files[0]));
            }
        });

        // Video URL loading
        document.getElementById('cm-video-url-load').addEventListener('click', function() {
            const url = document.getElementById('cm-video-url').value.trim();
            if (url) {
                _camVideoUrl = url;
                _camVideoFile = null;
                document.getElementById('cm-video-name').textContent = 'URL: ' + url.substring(0, 30) + '...';
                document.getElementById('cm-video-name').classList.add('selected');
                addToHistory('video', 'URL: ' + url.substring(0, 30), url);
                log('[CAM] Video URL set:', url);
            }
        });

        // Video history selection
        document.getElementById('cm-video-history-select').addEventListener('change', function() {
            if (this.value !== '') {
                const item = _videoHistory[parseInt(this.value)];
                if (item) {
                    _camVideoUrl = item.url;
                    _camVideoFile = null;
                    document.getElementById('cm-video-name').textContent = item.name;
                    document.getElementById('cm-video-name').classList.add('selected');
                    log('[CAM] Video loaded from history:', item.name);
                }
            }
        });

        // Image URL loading
        document.getElementById('cm-image-url-load').addEventListener('click', function() {
            const url = document.getElementById('cm-image-url').value.trim();
            if (url) {
                _camImageUrl = url;
                _camImageFile = null;
                document.getElementById('cm-image-name').textContent = 'URL: ' + url.substring(0, 30) + '...';
                document.getElementById('cm-image-name').classList.add('selected');
                addToHistory('image', 'URL: ' + url.substring(0, 30), url);
                log('[CAM] Image URL set:', url);
            }
        });

        // Image history selection
        document.getElementById('cm-image-history-select').addEventListener('change', function() {
            if (this.value !== '') {
                const item = _imageHistory[parseInt(this.value)];
                if (item) {
                    _camImageUrl = item.url;
                    _camImageFile = null;
                    document.getElementById('cm-image-name').textContent = item.name;
                    document.getElementById('cm-image-name').classList.add('selected');
                    log('[CAM] Image loaded from history:', item.name);
                }
            }
        });

        // Audio URL loading
        document.getElementById('cm-audio-url-load').addEventListener('click', function() {
            const url = document.getElementById('cm-audio-url').value.trim();
            if (url) {
                _audioUrl = url;
                _audioFile = null;
                document.getElementById('cm-audio-name').textContent = 'URL: ' + url.substring(0, 30) + '...';
                document.getElementById('cm-audio-name').classList.add('selected');
                addToHistory('audio', 'URL: ' + url.substring(0, 30), url);
                log('[AUDIO] Audio URL set:', url);
                if (_audioSpoofActive) { stopAudioSpoof(); startAudioSpoof(); }
            }
        });

        // Audio history selection
        document.getElementById('cm-audio-history-select').addEventListener('change', function() {
            if (this.value !== '') {
                const item = _audioHistory[parseInt(this.value)];
                if (item) {
                    _audioUrl = item.url;
                    _audioFile = null;
                    document.getElementById('cm-audio-name').textContent = item.name;
                    document.getElementById('cm-audio-name').classList.add('selected');
                    log('[AUDIO] Audio loaded from history:', item.name);
                    if (_audioSpoofActive) { stopAudioSpoof(); startAudioSpoof(); }
                }
            }
        });

        // Initialize history selects
        updateHistorySelect('video');
        updateHistorySelect('image');
        updateHistorySelect('audio');

        let _camRandomStart = false;

        document.getElementById('cm-random-start').addEventListener('change', function() { _camRandomStart = this.checked; });
        document.getElementById('cm-image-picker').addEventListener('click', () => document.getElementById('cm-image-input').click());
        document.getElementById('cm-image-input').addEventListener('change', function() {
            if (this.files[0]) {
                _camImageFile = this.files[0];
                _camImageUrl = null;
                document.getElementById('cm-image-name').textContent = this.files[0].name;
                document.getElementById('cm-image-name').classList.add('selected');
                addToHistory('image', this.files[0].name, URL.createObjectURL(this.files[0]));
            }
        });

        document.getElementById('cm-camloop-toggle').addEventListener('change', function() {
            _camLoop = this.checked;
            if (_camVideoEl) _camVideoEl.loop = _camLoop;
        });
        const camSpeedSlider = document.getElementById('cm-camspeed');
        const camSpeedFill = document.getElementById('cm-camspeed-fill');
        camSpeedSlider.addEventListener('input', function() {
            _camSpeed = parseFloat(this.value);
            document.getElementById('cm-camspeed-val').textContent = _camSpeed.toFixed(2) + 'x';
            updateSliderFill(this, camSpeedFill, 0.25, 3.0);
            if (_camVideoEl) _camVideoEl.playbackRate = _camSpeed;
        });
        document.getElementById('cm-cammirror-toggle').addEventListener('change', function() { _camMirror = this.checked; });

        // Camera text overlay handlers
        document.getElementById('cm-camtext-toggle').addEventListener('change', function() {
            _camTextEnabled = this.checked;
        });
        document.getElementById('cm-camtext-input').addEventListener('input', function() {
            _camTextContent = this.value;
        });
        document.getElementById('cm-camtext-color').addEventListener('input', function() {
            _camTextColor = this.value;
        });
        const camTextSizeSlider = document.getElementById('cm-camtext-size');
        const camTextSizeFill = document.getElementById('cm-camtext-size-fill');
        camTextSizeSlider.addEventListener('input', function() {
            _camTextSize = parseInt(this.value);
            document.getElementById('cm-camtext-size-val').textContent = _camTextSize + 'px';
            updateSliderFill(this, camTextSizeFill, 12, 72);
        });

        function buildFakeStream() {
            if (_camDrawRAF) cancelAnimationFrame(_camDrawRAF);
            if (_camVideoEl) { _camVideoEl.pause(); _camVideoEl.src = ''; }
            _camCanvasEl = document.createElement('canvas');
            _camCanvasEl.width = 640; _camCanvasEl.height = 480;
            const ctx = _camCanvasEl.getContext('2d');

            function drawLoop() {
                if (!_camSpoofActive) { _camDrawRAF = null; return; }
                ctx.fillStyle = '#000';
                ctx.fillRect(0, 0, 640, 480);
                ctx.save();
                if (_camMirror) { ctx.translate(640, 0); ctx.scale(-1, 1); }
                if (_camSrcType === 'video' && _camVideoEl && _camVideoEl.readyState >= 2) {
                    ctx.drawImage(_camVideoEl, 0, 0, 640, 480);
                } else if (_camSrcType === 'image' && _camImageEl && _camImageEl.complete) {
                    ctx.drawImage(_camImageEl, 0, 0, 640, 480);
                }
                ctx.restore();
                // Draw text overlay at bottom (after restore so it's not mirrored)
                if (_camTextEnabled && _camTextContent) {
                    ctx.save();
                    ctx.font = 'bold ' + _camTextSize + 'px Arial, sans-serif';
                    ctx.fillStyle = _camTextColor;
                    ctx.textAlign = 'center';
                    ctx.textBaseline = 'bottom';
                    ctx.shadowColor = 'rgba(0,0,0,0.8)';
                    ctx.shadowBlur = 6;
                    ctx.shadowOffsetX = 2;
                    ctx.shadowOffsetY = 2;
                    ctx.fillText(_camTextContent, 320, 465);
                    ctx.restore();
                }
                _camDrawRAF = requestAnimationFrame(drawLoop);
            }

            if (_camSrcType === 'video' && (_camVideoFile || _camVideoUrl)) {
                _camVideoEl = document.createElement('video');
                _camVideoEl.src = _camVideoFile ? URL.createObjectURL(_camVideoFile) : _camVideoUrl;
                _camVideoEl.loop = _camLoop;
                _camVideoEl.muted = true;
                _camVideoEl.playsInline = true;
                _camVideoEl.crossOrigin = 'anonymous';
                _camVideoEl.playbackRate = _camSpeed;
                if (_camRandomStart) {
                    _camVideoEl.addEventListener('loadedmetadata', function() {
                        if (_camVideoEl.duration > 0) {
                            const t = Math.random() * _camVideoEl.duration;
                            _camVideoEl.currentTime = t;
                            log('[CAM] Random start at:', t.toFixed(2) + 's');
                        }
                    }, { once: true });
                }
                _camVideoEl.play().catch(() => {});
                drawLoop();
            } else if (_camSrcType === 'image' && (_camImageFile || _camImageUrl)) {
                _camImageEl = new Image();
                _camImageEl.crossOrigin = 'anonymous';
                _camImageEl.src = _camImageFile ? URL.createObjectURL(_camImageFile) : _camImageUrl;
                _camImageEl.onload = () => drawLoop();
                drawLoop();
            } else {
                log('[CAM] No source selected');
                return null;
            }

            return _camCanvasEl.captureStream(30);
        }

        function startCamSpoof() {
            const fakeStream = buildFakeStream();
            if (!fakeStream) return;
            _camStream = fakeStream;

            const _srcObjDesc = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'srcObject');
            if (!_camSrcObjPatch) {
                _camSrcObjPatch = function(stream) {
                    if (this.classList?.contains('scanner-video') && stream && _camSpoofActive && _camStream) {
                        _srcObjDesc.set.call(this, _camStream); return;
                    }
                    _srcObjDesc.set.call(this, stream);
                };
                Object.defineProperty(HTMLMediaElement.prototype, 'srcObject', {
                    get() { return _srcObjDesc.get.call(this); },
                    set: _camSrcObjPatch,
                    configurable: true
                });
            }

            const scannerVid = document.querySelector('video.scanner-video');
            if (scannerVid) scannerVid.srcObject = _camStream;

            if (!_origAddTrack) {
                _origAddTrack = RTCPeerConnection.prototype.addTrack;
                RTCPeerConnection.prototype.addTrack = function(track, ...streams) {
                    if (track.kind === 'video' && _camSpoofActive && _camStream) {
                        const fakeTrack = _camStream.getVideoTracks()[0];
                        if (fakeTrack) return _origAddTrack.call(this, fakeTrack, ...streams);
                    }
                    return _origAddTrack.call(this, track, ...streams);
                };
            }

            try {
                const fakeTrack = _camStream.getVideoTracks()[0];
                if (fakeTrack && window._mogPCs) {
                    for (const pc of window._mogPCs) {
                        pc.getSenders().forEach(sender => {
                            if (sender.track?.kind === 'video') sender.replaceTrack(fakeTrack).catch(() => {});
                        });
                    }
                }
            } catch(e) {}
        }

        function stopCamSpoof() {
            if (_camDrawRAF) { cancelAnimationFrame(_camDrawRAF); _camDrawRAF = null; }
            if (_camVideoEl) { _camVideoEl.pause(); _camVideoEl.src = ''; _camVideoEl = null; }
            if (_camImageEl) _camImageEl = null;
            if (_camStream) { _camStream.getTracks().forEach(t => t.stop()); _camStream = null; }
            _trueOriginalGetUserMedia({ video: true }).then(realStream => {
                const realTrack = realStream.getVideoTracks()[0];
                const scannerVid = document.querySelector('video.scanner-video');
                if (scannerVid) scannerVid.srcObject = realStream;
                if (realTrack && window._mogPCs) {
                    for (const pc of window._mogPCs) {
                        pc.getSenders().forEach(sender => {
                            if (sender.track?.kind === 'video') sender.replaceTrack(realTrack).catch(() => {});
                        });
                    }
                }
            }).catch(() => {});
        }

        document.getElementById('cm-camspoof-toggle').addEventListener('change', function() {
            _camSpoofActive = this.checked;
            if (_camSpoofActive) startCamSpoof(); else stopCamSpoof();
        });

        // ── AUDIO SPOOF ────────────────────────────────────────────────────
        let _audioSpoofActive = false;
        let _audioFile = null;
        let _audioEl = null;
        let _audioLoop = true;
        let _audioSpeed = 1.0;
        let _audioVolume = 1.0;
        let _audioStream = null;
        let _audioContext = null;
        let _audioSource = null;
        let _audioDestination = null;
        let _audioBassFilter = null;
        let _audioTrebleFilter = null;
        let _audioWarmthFilter = null;
        let _audioBass = 0;
        let _audioTreble = 0;
        let _audioWarmth = 0;

        document.getElementById('cm-audio-picker').addEventListener('click', () => document.getElementById('cm-audio-input').click());
        document.getElementById('cm-audio-input').addEventListener('change', function() {
            if (this.files[0]) {
                _audioFile = this.files[0];
                _audioUrl = null;
                document.getElementById('cm-audio-name').textContent = this.files[0].name;
                document.getElementById('cm-audio-name').classList.add('selected');
                addToHistory('audio', this.files[0].name, URL.createObjectURL(this.files[0]));
                if (_audioSpoofActive) {
                    stopAudioSpoof();
                    startAudioSpoof();
                }
            }
        });

        document.getElementById('cm-audioloop-toggle').addEventListener('change', function() {
            _audioLoop = this.checked;
            if (_audioEl) _audioEl.loop = _audioLoop;
        });

        const audioSpeedSlider = document.getElementById('cm-audiospeed');
        const audioSpeedFill = document.getElementById('cm-audiospeed-fill');
        audioSpeedSlider.addEventListener('input', function() {
            _audioSpeed = parseFloat(this.value);
            document.getElementById('cm-audiospeed-val').textContent = _audioSpeed.toFixed(2) + 'x';
            updateSliderFill(this, audioSpeedFill, 0.25, 3.0);
            if (_audioEl) _audioEl.playbackRate = _audioSpeed;
        });

        const audioVolumeSlider = document.getElementById('cm-audiovolume');
        const audioVolumeFill = document.getElementById('cm-audiovolume-fill');
        audioVolumeSlider.addEventListener('input', function() {
            _audioVolume = parseInt(this.value) / 100;
            document.getElementById('cm-audiovolume-val').textContent = this.value + '%';
            updateSliderFill(this, audioVolumeFill, 0, 100);
            if (_audioEl) _audioEl.volume = _audioVolume;
        });

        const audioBassSlider = document.getElementById('cm-audiobass');
        const audioBassFill = document.getElementById('cm-audiobass-fill');
        audioBassSlider.addEventListener('input', function() {
            _audioBass = parseInt(this.value);
            document.getElementById('cm-audiobass-val').textContent = _audioBass + ' dB';
            updateSliderFill(this, audioBassFill, -12, 12);
            if (_audioBassFilter) _audioBassFilter.gain.value = _audioBass;
        });

        const audioTrebleSlider = document.getElementById('cm-audiotreble');
        const audioTrebleFill = document.getElementById('cm-audiotreble-fill');
        audioTrebleSlider.addEventListener('input', function() {
            _audioTreble = parseInt(this.value);
            document.getElementById('cm-audiotreble-val').textContent = _audioTreble + ' dB';
            updateSliderFill(this, audioTrebleFill, -12, 12);
            if (_audioTrebleFilter) _audioTrebleFilter.gain.value = _audioTreble;
        });

        const audioWarmthSlider = document.getElementById('cm-audiowarmth');
        const audioWarmthFill = document.getElementById('cm-audiowarmth-fill');
        audioWarmthSlider.addEventListener('input', function() {
            _audioWarmth = parseInt(this.value);
            document.getElementById('cm-audiowarmth-val').textContent = _audioWarmth + ' dB';
            updateSliderFill(this, audioWarmthFill, -12, 12);
            if (_audioWarmthFilter) _audioWarmthFilter.gain.value = _audioWarmth;
        });

        function startAudioSpoof() {
            if (!_audioFile && !_audioUrl) {
                document.getElementById('cm-audio-status').textContent = 'No file selected';
                document.getElementById('cm-audio-status').style.color = 'var(--cm-warning)';
                return;
            }

            try {
                _audioEl = document.createElement('audio');
                _audioEl.src = _audioFile ? URL.createObjectURL(_audioFile) : _audioUrl;
                _audioEl.crossOrigin = 'anonymous';
                _audioEl.loop = _audioLoop;
                _audioEl.playbackRate = _audioSpeed;
                _audioEl.volume = _audioVolume;

                _audioContext = new (window.AudioContext || window.webkitAudioContext)();
                _audioSource = _audioContext.createMediaElementSource(_audioEl);
                
                // Create EQ filters
                // Bass filter (lowshelf at 150Hz)
                _audioBassFilter = _audioContext.createBiquadFilter();
                _audioBassFilter.type = 'lowshelf';
                _audioBassFilter.frequency.value = 150;
                _audioBassFilter.gain.value = _audioBass;

                // Treble filter (highshelf at 4000Hz)
                _audioTrebleFilter = _audioContext.createBiquadFilter();
                _audioTrebleFilter.type = 'highshelf';
                _audioTrebleFilter.frequency.value = 4000;
                _audioTrebleFilter.gain.value = _audioTreble;

                // Warmth filter (peaking at 500Hz for mid warmth)
                _audioWarmthFilter = _audioContext.createBiquadFilter();
                _audioWarmthFilter.type = 'peaking';
                _audioWarmthFilter.frequency.value = 500;
                _audioWarmthFilter.Q.value = 1;
                _audioWarmthFilter.gain.value = _audioWarmth;

                _audioDestination = _audioContext.createMediaStreamDestination();
                
                // Chain: source -> bass -> warmth -> treble -> destination
                _audioSource.connect(_audioBassFilter);
                _audioBassFilter.connect(_audioWarmthFilter);
                _audioWarmthFilter.connect(_audioTrebleFilter);
                _audioTrebleFilter.connect(_audioDestination);
                _audioTrebleFilter.connect(_audioContext.destination); // also play locally for feedback

                _audioStream = _audioDestination.stream;

                _audioEl.play().catch(e => {
                    log('[AUDIO SPOOF] Play error:', e);
                });

                document.getElementById('cm-audio-status').textContent = 'Active';
                document.getElementById('cm-audio-status').style.color = 'var(--cm-success)';
                log('[AUDIO SPOOF] Started with file:', _audioFile.name);
            } catch(e) {
                log('[AUDIO SPOOF] Error:', e);
                document.getElementById('cm-audio-status').textContent = 'Error';
                document.getElementById('cm-audio-status').style.color = 'var(--cm-danger)';
            }
        }

        function stopAudioSpoof() {
            if (_audioEl) {
                _audioEl.pause();
                _audioEl.src = '';
                _audioEl = null;
            }
            if (_audioContext) {
                _audioContext.close().catch(() => {});
                _audioContext = null;
            }
            _audioSource = null;
            _audioDestination = null;
            _audioBassFilter = null;
            _audioTrebleFilter = null;
            _audioWarmthFilter = null;
            _audioStream = null;
            document.getElementById('cm-audio-status').textContent = 'Inactive';
            document.getElementById('cm-audio-status').style.color = 'var(--cm-text-muted)';
            log('[AUDIO SPOOF] Stopped');
        }

        document.getElementById('cm-audiospoof-toggle').addEventListener('change', function() {
            _audioSpoofActive = this.checked;
            if (_audioSpoofActive) startAudioSpoof(); else stopAudioSpoof();
        });

        // Patch getUserMedia to inject spoofed audio
        const _origGetUserMediaForAudio = navigator.mediaDevices.getUserMedia;
        navigator.mediaDevices.getUserMedia = async function(constraints) {
            if (_audioSpoofActive && _audioStream && constraints && constraints.audio) {
                log('[AUDIO SPOOF] Intercepting getUserMedia - injecting spoofed audio');
                const realStream = await _trueOriginalGetUserMedia(constraints);

                if (constraints.video) {
                    // Combine real video with spoofed audio
                    const combinedTracks = [
                        ...realStream.getVideoTracks(),
                        ..._audioStream.getAudioTracks()
                    ];
                    return new MediaStream(combinedTracks);
                } else {
                    // Audio only request
                    return _audioStream;
                }
            }
            return _origGetUserMediaForAudio.call(navigator.mediaDevices, constraints);
        };

        // Cam spoof enforcer
        setInterval(() => {
            if (!_camSpoofActive || !_camStream) return;
            const scannerVid = document.querySelector('video.scanner-video');
            if (scannerVid && scannerVid.srcObject !== _camStream) {
                log('[CAM SPOOF] Re-applying spoof to scanner-video');
                scannerVid.srcObject = _camStream;
            }
            const fakeTrack = _camStream.getVideoTracks()[0];
            if (fakeTrack && window._mogPCs) {
                for (const pc of window._mogPCs) {
                    try {
                        pc.getSenders().forEach(sender => {
                            if (sender.track?.kind === 'video' && sender.track !== fakeTrack) {
                                sender.replaceTrack(fakeTrack).catch(() => {});
                            }
                        });
                    } catch(e) {}
                }
            }
        }, 500);

        // Watch for new scanner-video
        const camSpoofObserver = new MutationObserver((mutations) => {
            if (!_camSpoofActive || !_camStream) return;
            for (const mutation of mutations) {
                for (const node of mutation.addedNodes) {
                    if (node.nodeType === 1) {
                        const sv = node.classList?.contains('scanner-video') ? node : node.querySelector?.('video.scanner-video');
                        if (sv && sv.srcObject !== _camStream) {
                            log('[CAM SPOOF] New scanner-video detected, applying spoof');
                            sv.srcObject = _camStream;
                        }
                    }
                }
            }
        });
        camSpoofObserver.observe(document.body, { childList: true, subtree: true });

        // ── PARTICLE ENGINE ────────────────────────────────────────────────
        const _particleCfg = {
            active: false, count: 80, size: 5, speed: 1.0, drift: 0.5,
            opacity: 70, color: '#ffffff', rainbow: false, shape: 'circle', glow: true, wobble: true
        };
        let _particleCanvas = null, _particleCtx = null, _particleRAF = null, _particles = [];

        function _makeParticle() {
            return {
                x: Math.random() * window.innerWidth,
                y: -20 - Math.random() * window.innerHeight,
                r: (_particleCfg.size * 0.5) + Math.random() * _particleCfg.size * 0.8,
                vy: (1.0 + Math.random() * 1.5) * _particleCfg.speed,
                vx: (Math.random() - 0.5) * _particleCfg.drift,
                wobblePhase: Math.random() * Math.PI * 2,
                wobbleSpeed: 0.01 + Math.random() * 0.03,
                wobbleAmp: 0.5 + Math.random() * 2.0,
                hue: Math.random() * 360,
                alpha: 0.3 + Math.random() * 0.7
            };
        }

        function _drawShape(ctx, p, color) {
            const s = p.r;
            ctx.fillStyle = color; ctx.strokeStyle = color;
            if (_particleCfg.glow) { ctx.shadowColor = color; ctx.shadowBlur = s * 2.5; }
            else { ctx.shadowBlur = 0; }
            ctx.beginPath();
            switch (_particleCfg.shape) {
                case 'circle': ctx.arc(p.x, p.y, s, 0, Math.PI * 2); ctx.fill(); break;
                case 'square': ctx.fillRect(p.x - s, p.y - s, s * 2, s * 2); break;
                case 'star': {
                    const spikes = 5, outer = s, inner = s * 0.45;
                    let rot = (Math.PI / 2) * 3;
                    const step = Math.PI / spikes;
                    ctx.moveTo(p.x, p.y - outer);
                    for (let i = 0; i < spikes; i++) {
                        ctx.lineTo(p.x + Math.cos(rot) * outer, p.y + Math.sin(rot) * outer); rot += step;
                        ctx.lineTo(p.x + Math.cos(rot) * inner, p.y + Math.sin(rot) * inner); rot += step;
                    }
                    ctx.lineTo(p.x, p.y - outer); ctx.fill(); break;
                }
                case 'heart': {
                    const hs = s * 0.9;
                    ctx.moveTo(p.x, p.y + hs * 0.6);
                    ctx.bezierCurveTo(p.x - hs * 1.2, p.y - hs * 0.4, p.x - hs * 2.2, p.y + hs * 0.6, p.x, p.y + hs * 1.8);
                    ctx.bezierCurveTo(p.x + hs * 2.2, p.y + hs * 0.6, p.x + hs * 1.2, p.y - hs * 0.4, p.x, p.y + hs * 0.6);
                    ctx.fill(); break;
                }
            }
        }

        function _particleLoop() {
            if (!_particleCfg.active) return;
            const W = window.innerWidth, H = window.innerHeight;
            if (_particleCanvas.width !== W) _particleCanvas.width = W;
            if (_particleCanvas.height !== H) _particleCanvas.height = H;
            _particleCtx.clearRect(0, 0, W, H);
            while (_particles.length < _particleCfg.count) _particles.push(_makeParticle());
            while (_particles.length > _particleCfg.count) _particles.pop();
            for (const p of _particles) {
                p.wobblePhase += p.wobbleSpeed;
                if (_particleCfg.wobble) p.x += Math.sin(p.wobblePhase) * p.wobbleAmp;
                p.x += p.vx; p.y += p.vy;
                if (p.y > H + 30) {
                    p.y = -20; p.x = Math.random() * W;
                    p.vx = (Math.random() - 0.5) * _particleCfg.drift;
                    p.hue = Math.random() * 360;
                }
                const baseAlpha = (_particleCfg.opacity / 100) * p.alpha;
                let color;
                if (_particleCfg.rainbow) {
                    color = `hsla(${p.hue},100%,70%,${baseAlpha})`;
                    p.hue = (p.hue + 0.3) % 360;
                } else {
                    const hex = _particleCfg.color;
                    const r = parseInt(hex.slice(1,3),16);
                    const g = parseInt(hex.slice(3,5),16);
                    const b = parseInt(hex.slice(5,7),16);
                    color = `rgba(${r},${g},${b},${baseAlpha})`;
                }
                _particleCtx.globalAlpha = 1;
                _drawShape(_particleCtx, p, color);
            }
            _particleRAF = requestAnimationFrame(_particleLoop);
        }

        function startParticles() {
            if (_particleCanvas) stopParticles();
            _particleCanvas = document.createElement('canvas');
            _particleCanvas.style.cssText = 'position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:999980;';
            document.body.appendChild(_particleCanvas);
            _particleCtx = _particleCanvas.getContext('2d');
            _particles = Array.from({ length: _particleCfg.count }, _makeParticle);
            _particles.forEach(p => { p.y = Math.random() * window.innerHeight; });
            _particleCfg.active = true;
            _particleLoop();
        }

        function stopParticles() {
            _particleCfg.active = false;
            if (_particleRAF) { cancelAnimationFrame(_particleRAF); _particleRAF = null; }
            if (_particleCanvas) { _particleCanvas.remove(); _particleCanvas = null; _particleCtx = null; }
            _particles = [];
        }

        document.getElementById('cm-particles-toggle').addEventListener('change', function() {
            if (this.checked) startParticles(); else stopParticles();
        });
        const particlesCountSlider = document.getElementById('cm-particles-count');
        const particlesCountFill = document.getElementById('cm-particles-count-fill');
        particlesCountSlider.addEventListener('input', function() {
            _particleCfg.count = parseInt(this.value);
            document.getElementById('cm-particles-count-val').textContent = this.value;
            updateSliderFill(this, particlesCountFill, 10, 300);
        });
        const particlesSizeSlider = document.getElementById('cm-particles-size');
        const particlesSizeFill = document.getElementById('cm-particles-size-fill');
        particlesSizeSlider.addEventListener('input', function() {
            _particleCfg.size = parseInt(this.value);
            document.getElementById('cm-particles-size-val').textContent = this.value + 'px';
            updateSliderFill(this, particlesSizeFill, 1, 20);
        });
        const particlesSpeedSlider = document.getElementById('cm-particles-speed');
        const particlesSpeedFill = document.getElementById('cm-particles-speed-fill');
        particlesSpeedSlider.addEventListener('input', function() {
            _particleCfg.speed = parseFloat(this.value);
            document.getElementById('cm-particles-speed-val').textContent = parseFloat(this.value).toFixed(1) + 'x';
            updateSliderFill(this, particlesSpeedFill, 0.2, 5.0);
            _particles.forEach(p => { p.vy = (1.0 + Math.random() * 1.5) * _particleCfg.speed; });
        });
        document.getElementById('cm-particles-color').addEventListener('input', function() { _particleCfg.color = this.value; });
        document.getElementById('cm-particles-rainbow').addEventListener('change', function() { _particleCfg.rainbow = this.checked; });
        document.getElementById('cm-particles-glow').addEventListener('change', function() { _particleCfg.glow = this.checked; });
        document.querySelectorAll('.cm-shape-btn').forEach(b => {
            b.addEventListener('click', function() {
                _particleCfg.shape = this.dataset.shape;
                document.querySelectorAll('.cm-shape-btn').forEach(x => x.classList.toggle('active', x.dataset.shape === _particleCfg.shape));
            });
        });

        // ── OVERLAY IMAGES ─────────────────────────────────────────────────
        const OVERLAY_URLS = {
            ban:     'https://raw.githubusercontent.com/sevkabevka/sevkabevka.github.io/main/ChatGPT%20Image%2023%20%D0%BC%D0%B0%D1%8F%202026%20%D0%B3.,%2019_13_02.png',
            loading: 'https://raw.githubusercontent.com/sevkabevka/sevkabevka.github.io/main/ChatGPT%20Image%2023%20%D0%BC%D0%B0%D1%8F%202026%20%D0%B3.,%2017_59_13_Nero_AI_Image_Upscaler_Photo_Face.png'
        };

        let _overlayActive = null;
        let _overlayImg = { ban: null, loading: null };
        let _overlayCanvas = null, _overlayStream = null, _overlayRAF = null;

        ['ban', 'loading'].forEach(key => {
            const img = new Image();
            img.crossOrigin = 'anonymous';
            img.src = OVERLAY_URLS[key];
            img.onload = () => { _overlayImg[key] = img; };
        });

        function _pushTrackToAll(stream) {
            const track = stream ? stream.getVideoTracks()[0] : null;
            if (!track) return;
            const scannerVid = document.querySelector('video.scanner-video');
            if (scannerVid) scannerVid.srcObject = stream;
            if (window._mogPCs) {
                for (const pc of window._mogPCs) {
                    try {
                        pc.getSenders().forEach(sender => {
                            if (sender.track?.kind === 'video') sender.replaceTrack(track).catch(() => {});
                        });
                    } catch(e) {}
                }
            }
        }

        function startOverlay(key) {
            if (_overlayRAF) { cancelAnimationFrame(_overlayRAF); _overlayRAF = null; }
            if (_overlayStream) { _overlayStream.getTracks().forEach(t => t.stop()); _overlayStream = null; }
            _overlayCanvas = null; _overlayActive = null;
            const img = _overlayImg[key];
            if (!img) { document.getElementById('cm-overlay-status').textContent = 'Loading...'; return; }
            _overlayActive = key;
            _overlayCanvas = document.createElement('canvas');
            _overlayCanvas.width = 640; _overlayCanvas.height = 480;
            const ctx = _overlayCanvas.getContext('2d');
            function drawOverlay() {
                if (!_overlayActive) return;
                ctx.save(); ctx.translate(640, 0); ctx.scale(-1, 1);
                ctx.drawImage(img, 0, 0, 640, 480);
                ctx.restore();
                _overlayRAF = requestAnimationFrame(drawOverlay);
            }
            drawOverlay();
            _overlayStream = _overlayCanvas.captureStream(30);
            _pushTrackToAll(_overlayStream);
            document.getElementById('cm-overlay-status').textContent = key.toUpperCase();
            document.getElementById('cm-overlay-status').style.color = key === 'ban' ? 'var(--cm-danger)' : 'var(--cm-accent)';
        }

        function stopOverlay() {
            if (_overlayRAF) { cancelAnimationFrame(_overlayRAF); _overlayRAF = null; }
            if (_overlayStream) { _overlayStream.getTracks().forEach(t => t.stop()); _overlayStream = null; }
            _overlayActive = null; _overlayCanvas = null;
            if (_camSpoofActive && _camStream) {
                _pushTrackToAll(_camStream);
            } else {
                _trueOriginalGetUserMedia({ video: true }).then(realStream => { _pushTrackToAll(realStream); }).catch(() => {});
            }
            document.getElementById('cm-overlay-status').textContent = 'None';
            document.getElementById('cm-overlay-status').style.color = 'var(--cm-text-muted)';
        }

        document.getElementById('cm-ban-overlay-toggle').addEventListener('change', function() {
            document.getElementById('cm-loading-overlay-toggle').checked = false;
            if (this.checked) startOverlay('ban'); else stopOverlay();
        });
        document.getElementById('cm-loading-overlay-toggle').addEventListener('change', function() {
            document.getElementById('cm-ban-overlay-toggle').checked = false;
            if (this.checked) startOverlay('loading'); else stopOverlay();
        });
    }

    // ── ZUSTAND STATUS BADGE ──────────────────────────���─────────────────────
    const _zustandInterval = setInterval(() => {
        const badge = document.getElementById('cm-zustand-val');
        if (!badge) return;
        try {
            const wpChunk = _window.webpackChunk_N_E || _window.webpackChunknextjs_app || _window.webpackChunk;
            if (!wpChunk) return;
            let req;
            try { req = wpChunk.push([[Symbol()], {}, e => e]); } catch(e) { return; }
            if (typeof req !== 'function') return;

            let store = null;
            try {
                const mod = req(16225);
                if (mod) {
                    store = Object.values(mod).find(v =>
                        v && typeof v.getState === 'function' && 'selfScore' in (v.getState() || {})
                    );
                }
            } catch(e) {}

            if (!store && req.m) {
                for (const id of Object.keys(req.m)) {
                    try {
                        const mod = req(id);
                        if (!mod || typeof mod !== 'object') continue;
                        const found = Object.values(mod).find(v =>
                            v && typeof v.getState === 'function' && 'selfScore' in (v.getState() || {})
                        );
                        if (found) { store = found; break; }
                    } catch(e) {}
                }
            }

            if (store && store.getState().setMyScore?.__patched) {
                badge.textContent = 'HOOKED';
                badge.style.color = 'var(--cm-success)';
                clearInterval(_zustandInterval);
            }
        } catch(e) {}
    }, 500);

    function log(...args) {
        if (CONFIG.debug) console.log('[cheatmoggle]', ...args);
    }

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

})();