Gartic Bots

Sistema avançado com clique preciso 100% sincronizado, controle de rede robusto e multi-salas sem limites

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

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

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

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

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

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

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

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

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

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

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

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

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

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

このスクリプトの質問や評価の投稿はこちら通報はこちらへお寄せください
// ==UserScript==
// @name         Gartic Bots
// @namespace    http://tampermonkey.net/
// @version      2.3
// @description  Sistema avançado com clique preciso 100% sincronizado, controle de rede robusto e multi-salas sem limites
// @author       TheEnd
// @match        https://gartic.com.br/*
// @grant        none
// ==/UserScript==

(function() {
    'use strict';

    // =============================================
    // SISTEMA DE SALVAMENTO DE CONFIGURAÇÕES
    // =============================================

    class ConfigManager {
        constructor() {
            this.config = {
                nickPrefix: 'Player',
                lastRoom: null,
                menuMinimized: false,
                defaultTabCount: 5,
                useExternalTabs: false,
                externalTabCount: 0,
                multiRoomIframeCount: 0,
                multiRoomExternalCount: 0,
                selectedRooms: [],
                disableRandomNumbers: false,
                // NOVO: Configurações avançadas
                syncPrecision: 'high',
                networkControlMode: 'advanced',
                maxTabLimit: 1000,
                autoRetryAttempts: 3,
                preventMultipleClicks: true,
                clickDelayRange: [0, 10],
                useRequestAnimationFrame: true,
                usePerformanceNow: true,
                randomRoomSelection: true,
                maxRandomRooms: 30,
                intelligentDistribution: true,
                // NOVA OPÇÃO: Filtrar apenas salas vazias (desativado por padrão)
                onlyEmptyRooms: false
            };
            this.loadConfig();
        }

        loadConfig() {
            try {
                const saved = localStorage.getItem('garticMultiConfig');
                if (saved) {
                    this.config = { ...this.config, ...JSON.parse(saved) };
                }
            } catch (e) {
                console.log('❌ Erro ao carregar configurações:', e);
            }
        }

        saveConfig() {
            try {
                localStorage.setItem('garticMultiConfig', JSON.stringify(this.config));
            } catch (e) {
                console.log('❌ Erro ao salvar configurações:', e);
            }
        }

        get(key) {
            return this.config[key];
        }

        set(key, value) {
            this.config[key] = value;
            this.saveConfig();
        }

        // NOVO: Métodos para configurações de sincronização
        getSyncPrecisionValue() {
            const precisionMap = {
                'low': { delay: 50, useRAF: false, usePN: false },
                'medium': { delay: 20, useRAF: true, usePN: false },
                'high': { delay: 5, useRAF: true, usePN: true },
                'ultra': { delay: 0, useRAF: true, usePN: true }
            };
            return precisionMap[this.config.syncPrecision] || precisionMap.high;
        }
    }

    // =============================================
    // SISTEMA DE SINCRONIZAÇÃO AVANÇADO (NOVO)
    // =============================================

    class PrecisionSyncSystem {
        constructor() {
            this.clickQueue = [];
            this.isSyncing = false;
            this.syncOperations = new Map();
            this.clickTimestamps = new Map();
            this.MAX_SYNC_ATTEMPTS = 2;
            this.MIN_SYNC_INTERVAL = 100;
        }

        async executeUltraPreciseSync(elements, roomId = null) {
            if (this.isSyncing) {
                console.warn('⚠️ Sincronização já em andamento');
                return 0;
            }

            this.isSyncing = true;
            const startTime = performance.now();
            
            try {
                console.log(`⚡ INICIANDO SINCRONIZAÇÃO ULTRA-PRECISA (${elements.length} elementos)`);
                
                // Fase 1: Preparação
                await this.prepareAllElements(elements);
                
                // Fase 2: Execução sincronizada
                const results = await this.executeSynchronizedClicks(elements);
                
                const successCount = results.filter(r => r.success).length;
                const totalTime = performance.now() - startTime;
                
                console.log(`✅ SINCRONIZAÇÃO CONCLUÍDA: ${successCount}/${elements.length} em ${totalTime.toFixed(1)}ms`);
                
                return successCount;
            } catch (error) {
                console.error('❌ ERRO NA SINCRONIZAÇÃO:', error);
                return 0;
            } finally {
                this.isSyncing = false;
            }
        }

        async prepareAllElements(elements) {
            const promises = elements.map((element, index) => {
                return new Promise(resolve => {
                    requestAnimationFrame(() => {
                        this.ensureElementReady(element);
                        resolve(true);
                    });
                });
            });
            
            await Promise.all(promises);
            await this.delay(10);
        }

        async executeSynchronizedClicks(elements) {
            const config = window.configManager ? window.configManager.getSyncPrecisionValue() : { delay: 5, useRAF: true, usePN: true };
            const results = [];
            
            const clickPromises = elements.map((element, index) => {
                return new Promise(async (resolve) => {
                    const delay = config.delay + (Math.random() * 10);
                    
                    await this.delay(delay);
                    
                    const success = await this.executePrecisionClick(element, index);
                    
                    results.push({
                        element,
                        index,
                        success,
                        timestamp: performance.now()
                    });
                    
                    resolve(success);
                });
            });
            
            await Promise.all(clickPromises);
            return results;
        }

        async executePrecisionClick(elementData, index) {
            try {
                const elementId = `click-${Date.now()}-${index}`;
                
                if (this.isAlreadyInRoom(elementData)) {
                    console.log(`✅ Elemento ${index} já está na sala`);
                    return true;
                }

                let clickSuccess = false;
                
                if (elementData.type === 'iframe' || elementData.type === 'multiRoomIframe') {
                    clickSuccess = this.executeIframePrecisionClick(elementData.data, index);
                } else if (elementData.type === 'externalTab' || elementData.type === 'multiRoomExternalTab') {
                    clickSuccess = this.executeTabPrecisionClick(elementData.data, index);
                }

                if (clickSuccess) {
                    elementData.data.clicked = true;
                    elementData.data.clickTimestamp = Date.now();
                    this.clickTimestamps.set(elementId, Date.now());
                }
                
                return clickSuccess;
            } catch (error) {
                console.error(`💥 Erro no clique preciso ${index}:`, error);
                return false;
            }
        }

        executeIframePrecisionClick(iframeData, index) {
            try {
                const iframe = iframeData.iframe;
                const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;
                
                if (!iframeDoc) return false;

                const playButton = this.findPlayButtonAdvanced(iframeDoc);
                if (!playButton) {
                    console.warn(`❌ Botão não encontrado no iframe ${index + 1}`);
                    return false;
                }

                this.performCompleteClick(playButton, iframe.contentWindow);
                
                console.log(`🎯 Clique ultra-preciso no iframe ${index + 1}`);
                return true;
            } catch (error) {
                console.error(`💥 Erro crítico no iframe ${index + 1}:`, error);
                return false;
            }
        }

        executeTabPrecisionClick(tabData, index) {
            try {
                if (tabData.window && tabData.window.closed) {
                    console.warn(`❌ Aba ${index + 1} foi fechada`);
                    return false;
                }

                const tabDoc = tabData.window.document;
                if (!tabDoc) return false;

                const playButton = this.findPlayButtonAdvanced(tabDoc);
                if (!playButton) {
                    console.warn(`❌ Botão não encontrado na aba ${index + 1}`);
                    return false;
                }

                try {
                    tabData.window.focus();
                } catch (e) {}

                this.performCompleteClick(playButton, tabData.window);
                
                console.log(`🎯 Clique ultra-preciso na aba ${index + 1}`);
                return true;
            } catch (error) {
                console.error(`💥 Erro crítico na aba ${index + 1}:`, error);
                return false;
            }
        }

        findPlayButtonAdvanced(doc) {
            const buttonSelectors = [
                'input[value*="Jogar" i]',
                'input[value*="Play" i]',
                'input[type="submit"]',
                'button[type="submit"]',
                '#btnJogar',
                '#btnPlay',
                '#playButton',
                '.play-button',
                '.btn-play',
                '.jogar-btn',
                '[onclick*="jogar" i]',
                '[onclick*="play" i]',
                '[onclick*="entrar" i]',
                'button:contains("Jogar")',
                'button:contains("Play")',
                'input[value*="Entrar"]',
                'form button:last-child',
                'form input[type="submit"]:last-child'
            ];

            for (const selector of buttonSelectors) {
                try {
                    const element = doc.querySelector(selector);
                    if (element && this.isElementClickable(element)) {
                        return element;
                    }
                } catch (e) {}
            }

            const allButtons = doc.querySelectorAll('button, input[type="button"], input[type="submit"]');
            for (const button of allButtons) {
                if (this.isElementClickable(button) && 
                    (button.textContent.includes('Jogar') || 
                     button.textContent.includes('Play') ||
                     button.value.includes('Jogar') ||
                     button.value.includes('Play'))) {
                    return button;
                }
            }

            return null;
        }

        performCompleteClick(element, targetWindow = window) {
            try {
                const rect = element.getBoundingClientRect();
                const centerX = rect.left + rect.width / 2;
                const centerY = rect.top + rect.height / 2;

                const events = [
                    new MouseEvent('mousedown', {
                        bubbles: true,
                        cancelable: true,
                        view: targetWindow,
                        clientX: centerX,
                        clientY: centerY,
                        button: 0
                    }),
                    new MouseEvent('mouseup', {
                        bubbles: true,
                        cancelable: true,
                        view: targetWindow,
                        clientX: centerX,
                        clientY: centerY,
                        button: 0
                    }),
                    new MouseEvent('click', {
                        bubbles: true,
                        cancelable: true,
                        view: targetWindow,
                        clientX: centerX,
                        clientY: centerY,
                        button: 0
                    }),
                    new FocusEvent('focus', { bubbles: true }),
                    new FocusEvent('focusin', { bubbles: true })
                ];

                events.forEach(event => {
                    try {
                        element.dispatchEvent(event);
                    } catch (e) {}
                });

                try {
                    element.click();
                } catch (e) {
                    console.warn('⚠️ Clique nativo falhou, usando eventos simulados');
                }

                ['input', 'change'].forEach(eventType => {
                    try {
                        const event = new Event(eventType, { bubbles: true });
                        element.dispatchEvent(event);
                    } catch (e) {}
                });

                return true;
            } catch (error) {
                console.error('❌ Erro no clique completo:', error);
                return false;
            }
        }

        isElementClickable(element) {
            if (!element) return false;
            
            const style = window.getComputedStyle(element);
            if (style.display === 'none' || 
                style.visibility === 'hidden' || 
                style.opacity === '0' ||
                element.offsetWidth === 0 ||
                element.offsetHeight === 0) {
                return false;
            }
            
            if (element.disabled || element.readOnly) {
                return false;
            }
            
            if (style.pointerEvents === 'none') {
                return false;
            }
            
            return true;
        }

        isAlreadyInRoom(elementData) {
            try {
                let doc;
                if (elementData.type === 'iframe' || elementData.type === 'multiRoomIframe') {
                    doc = elementData.data.iframe.contentDocument || elementData.data.iframe.contentWindow.document;
                } else {
                    if (elementData.data.window.closed) return true;
                    doc = elementData.data.window.document;
                }

                if (!doc) return false;

                const roomIndicators = [
                    '.game-container',
                    '.drawing-area',
                    'canvas',
                    '.palette',
                    '.room-content',
                    '#gameArea',
                    '.game-area',
                    '.draw-container',
                    '[class*="game"]',
                    '[class*="room"]'
                ];

                for (const selector of roomIndicators) {
                    try {
                        const element = doc.querySelector(selector);
                        if (element && this.isElementVisible(element)) {
                            return true;
                        }
                    } catch (e) {}
                }

                return false;
            } catch (e) {
                return false;
            }
        }

        isElementVisible(element) {
            return element && 
                   element.offsetWidth > 0 && 
                   element.offsetHeight > 0 &&
                   window.getComputedStyle(element).display !== 'none';
        }

        ensureElementReady(element) {
            if (element.type.includes('iframe')) {
                try {
                    const iframe = element.data.iframe;
                    if (iframe.contentWindow) {
                        iframe.contentWindow.focus();
                    }
                } catch (e) {}
            } else {
                try {
                    if (element.data.window && !element.data.window.closed) {
                        element.data.window.focus();
                    }
                } catch (e) {}
            }
        }

        async delay(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        resetSyncData() {
            this.clickQueue = [];
            this.syncOperations.clear();
            this.clickTimestamps.clear();
            this.isSyncing = false;
        }
    }

    // =============================================
    // CONTROLADOR DE REDE PROFISSIONAL (NOVO)
    // =============================================

    class ProfessionalNetworkController {
        constructor() {
            this.isBlocked = false;
            this.originalNetworkAPI = {};
            this.blockStartTime = 0;
            this.MAX_BLOCK_TIME = 5000;
            this.blockHistory = [];
        }

        blockNetwork() {
            if (this.isBlocked) {
                console.log('🔒 Rede já está bloqueada');
                return true;
            }

            try {
                this.saveOriginalAPIs();
                
                this.blockFetch();
                this.blockXMLHttpRequest();
                this.blockWebSocket();
                this.blockEventSource();
                this.blockSendBeacon();
                this.blockNavigatorOnline();
                
                this.isBlocked = true;
                this.blockStartTime = Date.now();
                this.blockHistory.push({
                    start: this.blockStartTime,
                    duration: 0,
                    type: 'manual'
                });
                
                console.log('🔒 REDE BLOQUEADA PROFISSIONALMENTE');
                
                setTimeout(() => {
                    if (this.isBlocked && (Date.now() - this.blockStartTime) > this.MAX_BLOCK_TIME) {
                        console.warn('⚠️ Restauração automática da rede (timeout de segurança)');
                        this.restoreNetwork();
                    }
                }, this.MAX_BLOCK_TIME + 1000);
                
                return true;
            } catch (error) {
                console.error('❌ Erro ao bloquear rede profissional:', error);
                return false;
            }
        }

        saveOriginalAPIs() {
            this.originalNetworkAPI = {
                fetch: window.fetch,
                XMLHttpRequest: {
                    open: XMLHttpRequest.prototype.open,
                    send: XMLHttpRequest.prototype.send,
                    setRequestHeader: XMLHttpRequest.prototype.setRequestHeader
                },
                WebSocket: window.WebSocket,
                EventSource: window.EventSource,
                navigator: {
                    sendBeacon: navigator.sendBeacon,
                    onLine: navigator.onLine
                }
            };
        }

        blockFetch() {
            window.fetch = function() {
                return Promise.reject(new Error('Network blocked by Gartic Pro System'));
            };
        }

        blockXMLHttpRequest() {
            const originalOpen = XMLHttpRequest.prototype.open;
            const originalSend = XMLHttpRequest.prototype.send;
            
            XMLHttpRequest.prototype.open = function() {
                this._blocked = true;
                return originalOpen.apply(this, arguments);
            };
            
            XMLHttpRequest.prototype.send = function(data) {
                if (this._blocked) {
                    if (this.onerror) {
                        setTimeout(() => {
                            try {
                                this.onerror(new ProgressEvent('error'));
                            } catch (e) {}
                        }, 1);
                    }
                    if (this.onloadend) {
                        setTimeout(() => {
                            try {
                                this.onloadend(new ProgressEvent('loadend'));
                            } catch (e) {}
                        }, 1);
                    }
                    return;
                }
                return originalSend.call(this, data);
            };
        }

        blockWebSocket() {
            if (window.WebSocket) {
                window.WebSocket = class MockWebSocket {
                    constructor(url) {
                        this.url = url;
                        this.readyState = 3;
                        this._listeners = {};
                    }
                    addEventListener(type, listener) {
                        if (!this._listeners[type]) this._listeners[type] = [];
                        this._listeners[type].push(listener);
                    }
                    removeEventListener(type, listener) {
                        if (this._listeners[type]) {
                            const idx = this._listeners[type].indexOf(listener);
                            if (idx > -1) this._listeners[type].splice(idx, 1);
                        }
                    }
                    close() {
                        this.readyState = 3;
                    }
                    send() {
                        throw new Error('WebSocket blocked');
                    }
                };
            }
        }

        blockEventSource() {
            if (window.EventSource) {
                window.EventSource = class MockEventSource {
                    constructor(url) {
                        this.url = url;
                        this.readyState = 2;
                    }
                    close() {}
                    addEventListener() {}
                };
            }
        }

        blockSendBeacon() {
            if (navigator.sendBeacon) {
                navigator.sendBeacon = function() {
                    return false;
                };
            }
        }

        blockNavigatorOnline() {
            Object.defineProperty(navigator, 'onLine', {
                get: function() { return false; },
                configurable: false
            });
        }

        restoreNetwork() {
            if (!this.isBlocked) {
                console.log('🔓 Rede já está restaurada');
                return true;
            }

            try {
                if (this.originalNetworkAPI.fetch) {
                    window.fetch = this.originalNetworkAPI.fetch;
                }

                if (this.originalNetworkAPI.XMLHttpRequest) {
                    XMLHttpRequest.prototype.open = this.originalNetworkAPI.XMLHttpRequest.open;
                    XMLHttpRequest.prototype.send = this.originalNetworkAPI.XMLHttpRequest.send;
                    XMLHttpRequest.prototype.setRequestHeader = this.originalNetworkAPI.XMLHttpRequest.setRequestHeader;
                }

                if (this.originalNetworkAPI.WebSocket) {
                    window.WebSocket = this.originalNetworkAPI.WebSocket;
                }

                if (this.originalNetworkAPI.EventSource) {
                    window.EventSource = this.originalNetworkAPI.EventSource;
                }

                if (this.originalNetworkAPI.navigator?.sendBeacon) {
                    navigator.sendBeacon = this.originalNetworkAPI.navigator.sendBeacon;
                }

                if (this.originalNetworkAPI.navigator?.onLine !== undefined) {
                    Object.defineProperty(navigator, 'onLine', {
                        get: function() { return true; },
                        configurable: true
                    });
                }

                this.isBlocked = false;
                const blockDuration = Date.now() - this.blockStartTime;
                
                if (this.blockHistory.length > 0) {
                    this.blockHistory[this.blockHistory.length - 1].duration = blockDuration;
                }
                
                console.log(`🔓 REDE RESTAURADA (bloqueio: ${blockDuration}ms)`);

                this.originalNetworkAPI = {};
                
                return true;
            } catch (error) {
                console.error('❌ Erro ao restaurar rede profissional:', error);
                return false;
            }
        }

        async performNetworkCycle() {
            console.log('🔄 INICIANDO CICLO DE REDE OTIMIZADO...');
            
            try {
                const blockSuccess = this.blockNetwork();
                if (!blockSuccess) {
                    throw new Error('Falha ao bloquear rede');
                }

                await this.delay(80);

                const restoreSuccess = this.restoreNetwork();
                if (!restoreSuccess) {
                    throw new Error('Falha ao restaurar rede');
                }

                await this.delay(40);

                console.log('✅ CICLO DE REDE CONCLUÍDO');
                return true;
            } catch (error) {
                console.error('❌ Erro no ciclo de rede:', error);
                this.restoreNetwork();
                return false;
            }
        }

        async delay(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        checkNetworkStatus() {
            return {
                isBlocked: this.isBlocked,
                blockDuration: this.isBlocked ? Date.now() - this.blockStartTime : 0,
                blockHistory: [...this.blockHistory]
            };
        }

        async testNetwork() {
            try {
                const testUrl = 'https://gartic.com.br/favicon.ico?t=' + Date.now();
                const response = await fetch(testUrl, { mode: 'no-cors' });
                return response !== undefined;
            } catch (e) {
                return false;
            }
        }
    }

    // =============================================
    // SISTEMA DE SELEÇÃO ALEATÓRIA DE SALAS (NOVO)
    // =============================================

    class RandomRoomSelector {
        constructor() {
            this.selectedRooms = new Set();
            this.roomElements = new Map();
            this.maxRooms = 1000;
        }

        getAllAvailableRooms() {
            const rooms = [];
            
            const roomSelectors = [
                '.sala',
                '[onclick*="selecionaSala"]',
                '.room',
                '[class*="room"]',
                '[id*="sala"]',
                '[data-room]',
                '[data-sala]'
            ];

            roomSelectors.forEach(selector => {
                document.querySelectorAll(selector).forEach(element => {
                    const roomId = this.extractRoomId(element);
                    if (roomId && !rooms.includes(roomId)) {
                        rooms.push(roomId);
                        this.roomElements.set(roomId, element);
                    }
                });
            });

            const roomList = document.getElementById('roomList');
            if (roomList) {
                roomList.querySelectorAll('div[data-room-id]').forEach(element => {
                    const roomId = element.getAttribute('data-room-id');
                    if (roomId && !rooms.includes(roomId)) {
                        rooms.push(roomId);
                        this.roomElements.set(roomId, element);
                    }
                });
            }

            return rooms;
        }

        // NOVO: Método para verificar se a sala está vazia
        isRoomEmpty(roomId) {
            const roomElement = this.roomElements.get(roomId);
            if (!roomElement) return false;
            
            const quantElement = roomElement.querySelector('.sala_quant');
            if (quantElement) {
                const quantText = quantElement.textContent;
                const playerCount = parseInt(quantText) || 0;
                return playerCount === 0;
            }
            return false;
        }

        selectRandomRooms(count) {
            const allRooms = this.getAllAvailableRooms();
            const onlyEmptyRooms = configManager ? configManager.get('onlyEmptyRooms') : false;
            
            // Filtrar salas com base na opção onlyEmptyRooms
            let availableRooms = allRooms;
            if (onlyEmptyRooms) {
                availableRooms = allRooms.filter(roomId => this.isRoomEmpty(roomId));
                console.log(`🔍 Filtrando apenas salas vazias: ${availableRooms.length}/${allRooms.length} salas vazias encontradas`);
            }
            
            if (availableRooms.length === 0) {
                if (onlyEmptyRooms) {
                    alert('⚠️ Nenhuma sala vazia encontrada! Desative o filtro "Mostrar apenas salas vazias" para selecionar outras salas.');
                } else {
                    alert('⚠️ Nenhuma sala disponível para seleção!');
                }
                console.warn('⚠️ Nenhuma sala disponível para seleção');
                return [];
            }

            let selected = [];
            if (count >= availableRooms.length) {
                selected = [...availableRooms];
            } else {
                const shuffled = [...availableRooms].sort(() => Math.random() - 0.5);
                selected = shuffled.slice(0, count);
            }

            this.selectedRooms = new Set(selected);
            this.updateRoomCheckboxes();
            
            console.log(`✅ ${this.selectedRooms.size} salas selecionadas aleatoriamente ${onlyEmptyRooms ? '(apenas vazias)' : ''}`);
            return Array.from(this.selectedRooms);
        }

        extractRoomId(element) {
            const onclick = element.getAttribute('onclick') || '';
            const text = element.textContent || '';
            
            const onclickMatch = onclick.match(/\d+/);
            if (onclickMatch) return onclickMatch[0];
            
            const textMatch = text.match(/\d+/);
            if (textMatch) return textMatch[0];
            
            const dataRoom = element.getAttribute('data-room') || element.getAttribute('data-sala');
            if (dataRoom) return dataRoom;
            
            return null;
        }

        updateRoomCheckboxes() {
            this.selectedRooms.forEach(roomId => {
                const checkbox = document.querySelector(`input[data-room-id="${roomId}"]`);
                if (checkbox) {
                    checkbox.checked = true;
                }
            });
        }

        clearSelection() {
            this.selectedRooms.clear();
            this.updateRoomCheckboxes();
            console.log('🧹 Seleção de salas limpa');
        }

        getSelectedCount() {
            return this.selectedRooms.size;
        }

        getSelectedRooms() {
            return Array.from(this.selectedRooms);
        }

        distributeTabsAmongRooms(totalTabs, distributionMode = 'balanced') {
            const rooms = this.getSelectedRooms();
            if (rooms.length === 0) return [];

            let distribution = [];
            
            switch(distributionMode) {
                case 'balanced':
                    const baseTabsPerRoom = Math.floor(totalTabs / rooms.length);
                    const extraTabs = totalTabs % rooms.length;
                    
                    for (let i = 0; i < rooms.length; i++) {
                        const tabsForThisRoom = baseTabsPerRoom + (i < extraTabs ? 1 : 0);
                        for (let j = 0; j < tabsForThisRoom; j++) {
                            distribution.push({
                                roomIndex: i,
                                roomId: rooms[i],
                                tabIndex: distribution.length
                            });
                        }
                    }
                    break;

                case 'random':
                    for (let i = 0; i < totalTabs; i++) {
                        const roomIndex = Math.floor(Math.random() * rooms.length);
                        distribution.push({
                            roomIndex: roomIndex,
                            roomId: rooms[roomIndex],
                            tabIndex: i
                        });
                    }
                    break;

                case 'sequential':
                    for (let i = 0; i < totalTabs; i++) {
                        const roomIndex = i % rooms.length;
                        distribution.push({
                            roomIndex: roomIndex,
                            roomId: rooms[roomIndex],
                            tabIndex: i
                        });
                    }
                    break;
            }

            distribution = distribution.sort(() => Math.random() - 0.5);
            
            return distribution;
        }
    }

    // =============================================
    // SISTEMA DE VERIFICAÇÃO DE VAGAS (100% DO SCRIPT 2)
    // =============================================

    class VacancySystem {
        constructor() {
            this.isChecking = false;
            this.vacancyCheckInterval = null;
            this.maxPlayers = 10;
        }

        async checkRoomVacancy(roomId) {
            try {
                const endpoints = [
                    `https://gartic.com.br/info_sala.php?id_sala=${roomId}&t=${Date.now()}`,
                    `https://gartic.com.br/sala_vagas.php?id=${roomId}&t=${Date.now()}`,
                    `https://gartic.com.br/sala${roomId}.php?t=${Date.now()}`
                ];

                for (const endpoint of endpoints) {
                    try {
                        const response = await fetch(endpoint);
                        if (response.ok) {
                            const data = await response.json();

                            if (data.jogadores && Array.isArray(data.jogadores)) {
                                const currentPlayers = data.jogadores.length;
                                const hasVacancy = currentPlayers < this.maxPlayers;
                                console.log(`👥 Sala ${roomId}: ${currentPlayers}/${this.maxPlayers} jogadores`);
                                return { hasVacancy, currentPlayers, maxPlayers: this.maxPlayers };
                            }

                            if (data.v !== undefined) {
                                const hasVacancy = data.v > 0;
                                console.log(`👥 Sala ${roomId}: ${data.v} vagas disponíveis`);
                                return { hasVacancy, currentPlayers: this.maxPlayers - data.v, maxPlayers: this.maxPlayers };
                            }
                        }
                    } catch (e) {
                        console.log(`⚠️ Endpoint falhou: ${endpoint}`);
                    }
                }

                console.log('⚠️ Não foi possível verificar vagas, assumindo que há vaga');
                return { hasVacancy: true, currentPlayers: 0, maxPlayers: this.maxPlayers };

            } catch (error) {
                console.error('❌ Erro ao verificar vagas:', error);
                return { hasVacancy: true, currentPlayers: 0, maxPlayers: this.maxPlayers };
            }
        }

        startVacancyCheck(roomId, callback) {
            if (this.isChecking) {
                this.stopVacancyCheck();
            }

            this.isChecking = true;
            updateStatus('🔍 VERIFICANDO VAGAS NA SALA...');

            this.vacancyCheckInterval = setInterval(async () => {
                const vacancyInfo = await this.checkRoomVacancy(roomId);

                if (vacancyInfo.hasVacancy) {
                    this.stopVacancyCheck();
                    updateStatus(`✅ VAGA ENCONTRADA! (${vacancyInfo.currentPlayers}/${vacancyInfo.maxPlayers} jogadores)`);
                    callback(true);
                } else {
                    updateStatus(`⏳ AGUARDANDO VAGA... (${vacancyInfo.currentPlayers}/${vacancyInfo.maxPlayers} jogadores)`);
                }
            }, 2000);
        }

        stopVacancyCheck() {
            if (this.vacancyCheckInterval) {
                clearInterval(this.vacancyCheckInterval);
                this.vacancyCheckInterval = null;
            }
            this.isChecking = false;
        }

        isCheckingVacancy() {
            return this.isChecking;
        }
    }

    // =============================================
    // CONTROLADOR DE REDE (100% DO SCRIPT 2)
    // =============================================

    class AdvancedNetworkController {
        constructor() {
            this.isBlocked = false;
            this.originalFetch = null;
            this.originalXHROpen = null;
            this.originalXHRSend = null;
        }

        blockNetwork() {
            if (this.isBlocked) return true;

            try {
                this.originalFetch = window.fetch;
                window.fetch = function() {
                    throw new Error('Network blocked by Gartic Multi-Abas');
                };

                this.originalXHROpen = XMLHttpRequest.prototype.open;
                this.originalXHRSend = XMLHttpRequest.prototype.send;

                XMLHttpRequest.prototype.open = function() {
                    this._url = arguments[1];
                    return this.originalXHROpen.apply(this, arguments);
                };

                XMLHttpRequest.prototype.send = function(data) {
                    if (this.onerror) {
                        setTimeout(() => {
                            try {
                                this.onerror(new ProgressEvent('error'));
                            } catch (e) {}
                        }, 10);
                    }
                    if (this.onloadend) {
                        setTimeout(() => {
                            try {
                                this.onloadend(new ProgressEvent('loadend'));
                            } catch (e) {}
                        }, 10);
                    }
                    return null;
                };

                this.isBlocked = true;
                console.log('🔒 REDE BLOQUEADA');
                return true;
            } catch (error) {
                console.error('❌ Erro ao bloquear rede:', error);
                return false;
            }
        }

        restoreNetwork() {
            if (!this.isBlocked) return true;

            try {
                if (this.originalFetch) {
                    window.fetch = this.originalFetch;
                }

                if (this.originalXHROpen) {
                    XMLHttpRequest.prototype.open = this.originalXHROpen;
                }
                if (this.originalXHRSend) {
                    XMLHttpRequest.prototype.send = this.originalXHRSend;
                }

                this.isBlocked = false;
                console.log('🔓 REDE RESTAURADA');
                return true;
            } catch (error) {
                console.error('❌ Erro ao restaurar rede:', error);
                return false;
            }
        }
    }

    // =============================================
    // SISTEMA DE GERENCIAMENTO DE MÚLTIPLAS SALAS (100% DO SCRIPT 2)
    // =============================================

    class MultiRoomManager {
        constructor() {
            this.selectedRooms = [];
            this.roomCheckboxes = new Map();
            this.config = {
                multiRoomIframeCount: 0,
                multiRoomExternalCount: 0
            };
        }

        addRoom(roomId) {
            if (!this.selectedRooms.includes(roomId)) {
                this.selectedRooms.push(roomId);
                console.log(`✅ Sala ${roomId} adicionada à seleção`);
            }
        }

        removeRoom(roomId) {
            const index = this.selectedRooms.indexOf(roomId);
            if (index > -1) {
                this.selectedRooms.splice(index, 1);
                console.log(`❌ Sala ${roomId} removida da seleção`);
            }
        }

        clearRooms() {
            this.selectedRooms = [];
            this.roomCheckboxes.forEach((checkbox, roomId) => {
                checkbox.checked = false;
            });
            console.log('🧹 Todas as salas foram desmarcadas');
        }

        getRoomForIndex(index) {
            if (this.selectedRooms.length === 0) return null;
            return this.selectedRooms[index % this.selectedRooms.length];
        }

        hasRooms() {
            return this.selectedRooms.length > 0;
        }

        getRoomCount() {
            return this.selectedRooms.length;
        }

        distributeTabsAmongRooms(totalTabs) {
            const roomCount = this.selectedRooms.length;
            if (roomCount === 0) return [];

            const tabsPerRoom = Math.floor(totalTabs / roomCount);
            const extraTabs = totalTabs % roomCount;

            const distribution = [];
            let tabIndex = 0;

            for (let i = 0; i < roomCount; i++) {
                const tabsForThisRoom = tabsPerRoom + (i < extraTabs ? 1 : 0);
                for (let j = 0; j < tabsForThisRoom; j++) {
                    distribution.push({
                        roomIndex: i,
                        roomId: this.selectedRooms[i],
                        tabIndex: tabIndex++
                    });
                }
            }

            return distribution;
        }
    }

    // =============================================
    // VISUALIZAÇÃO EM TEMPO REAL (ATUALIZADA)
    // =============================================

    class RealTimeViewer {
        constructor() {
            this.container = null;
            this.iframes = new Map();
            this.externalTabs = new Map();
            this.isVisible = false;
            this.isMinimized = false;
            this.maxIframes = 1000;
            this.maxMultiRoomIframes = 1000;

            this.multiRoomIframes = new Map();
            this.multiRoomExternalTabs = new Map();
        }

        createViewer() {
            if (this.container) {
                this.closeViewer();
            }

            this.container = document.createElement('div');
            this.container.id = 'gartic-real-time-viewer';
            this.container.style.cssText = `
                position: fixed;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                width: 95%;
                height: 90%;
                background: rgba(0, 0, 0, 0.95);
                border: 3px solid #8A2BE2;
                border-radius: 15px;
                z-index: 19999;
                display: none;
                flex-direction: column;
                padding: 15px;
                box-shadow: 0 0 50px rgba(0,0,0,0.8);
                backdrop-filter: blur(10px);
            `;

            const header = document.createElement('div');
            header.style.cssText = `
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 10px 15px;
                background: #8A2BE2;
                color: white;
                border-radius: 10px 10px 0 0;
                margin: -15px -15px 15px -15px;
                cursor: move;
            `;
            header.innerHTML = `
                <h3 style="margin:0; font-size:16px;">👁️ VISUALIZAÇÃO EM TEMPO REAL</h3>
                <div>
                    <button id="minimizeViewerBtn" style="background:#FF9800; color:white; border:none; border-radius:5px; padding:5px 10px; cursor:pointer; font-weight:bold; margin-right:5px;">−</button>
                    <button id="closeViewerBtn" style="background:#ff4444; color:white; border:none; border-radius:5px; padding:5px 10px; cursor:pointer; font-weight:bold;">X</button>
                </div>
            `;
            this.container.appendChild(header);

            const iframesGrid = document.createElement('div');
            iframesGrid.id = 'iframes-grid';
            iframesGrid.style.cssText = `
                display: grid;
                grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
                gap: 10px;
                height: 100%;
                overflow-y: auto;
                padding: 10px;
            `;
            this.container.appendChild(iframesGrid);

            const externalTabsSection = document.createElement('div');
            externalTabsSection.style.cssText = `
                margin-top: 15px;
                padding: 10px;
                background: rgba(139, 69, 19, 0.1);
                border-radius: 8px;
                border: 2px solid #8B4513;
            `;
            externalTabsSection.innerHTML = `
                <h4 style="margin:0 0 10px 0; color: #8B4513; font-size:14px;">🌐 ABAS EXTERNAS</h4>
                <div id="external-tabs-status" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 5px;"></div>
            `;
            this.container.appendChild(externalTabsSection);

            const multiRoomSection = document.createElement('div');
            multiRoomSection.style.cssText = `
                margin-top: 15px;
                padding: 10px;
                background: rgba(0, 100, 0, 0.1);
                border-radius: 8px;
                border: 2px solid #006400;
            `;
            multiRoomSection.innerHTML = `
                <h4 style="margin:0 0 10px 0; color: #006400; font-size:14px;">🎯 SISTEMAS MULTI-SALA</h4>
                <div style="display: grid; grid-template-columns: 1fr 1fr; gap: 10px;">
                    <div>
                        <h5 style="margin:0 0 5px 0; color: #FF6B00; font-size:12px;">🪟 Iframes Multi-Sala</h5>
                        <div id="multi-room-iframes-status" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 3px;"></div>
                    </div>
                    <div>
                        <h5 style="margin:0 0 5px 0; color: #FF6B00; font-size:12px;">🌐 Abas Multi-Sala</h5>
                        <div id="multi-room-external-status" style="display: grid; grid-template-columns: repeat(auto-fill, minmax(180px, 1fr)); gap: 3px;"></div>
                    </div>
                </div>
            `;
            this.container.appendChild(multiRoomSection);

            document.body.appendChild(this.container);

            document.getElementById('closeViewerBtn').onclick = () => this.closeViewer();
            document.getElementById('minimizeViewerBtn').onclick = () => this.toggleMinimize();

            this.makeDraggable(header, this.container);

            document.addEventListener('keydown', (e) => {
                if (e.key === 'Escape' && this.isVisible) {
                    this.closeViewer();
                }
            });

            return this.container;
        }

        createMultiRoomIframe(nick, index, roomIds, roomIndex = null) {
            if (!this.container) {
                this.createViewer();
            }

            const roomId = roomIds[roomIndex !== null ? roomIndex : index % roomIds.length];
            const iframesGrid = document.getElementById('iframes-grid');
            const iframeContainer = document.createElement('div');
            iframeContainer.style.cssText = `
                background: #2a2a2a;
                border: 2px solid #FF6B00;
                border-radius: 8px;
                padding: 8px;
                display: flex;
                flex-direction: column;
                min-height: 300px;
            `;

            const iframeHeader = document.createElement('div');
            iframeHeader.style.cssText = `
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 5px;
                background: #333;
                border-radius: 5px;
                margin-bottom: 5px;
                font-size: 12px;
                color: white;
            `;
            iframeHeader.innerHTML = `
                <span>🎯 ${nick} (Sala ${roomId})</span>
                <span id="multi-iframe-status-${index}" style="color: #ff9800;">⏳ CARREGANDO</span>
            `;
            iframeContainer.appendChild(iframeHeader);

            const iframe = document.createElement('iframe');
            iframe.src = `https://gartic.com.br/0${roomId}`;
            iframe.style.cssText = `
                width: 100%;
                height: 250px;
                border: 1px solid #555;
                border-radius: 5px;
                background: white;
                flex: 1;
            `;

            iframe.setAttribute('allow', 'autoplay; microphone; camera');
            iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups');

            iframeContainer.appendChild(iframe);
            iframesGrid.appendChild(iframeContainer);

            const tabData = {
                iframe: iframe,
                nick: nick,
                roomId: roomId,
                ready: false,
                loaded: false,
                nickFilled: false,
                inRoom: false,
                attempts: 0,
                maxAttempts: 3
            };

            iframe.onload = () => {
                this.monitorMultiRoomIframe(iframe, tabData, index);
            };

            iframe.onerror = () => {
                console.warn(`⚠️ Erro ao carregar iframe multi-sala ${index + 1}`);
                this.retryMultiRoomIframeLoad(iframe, tabData, index, roomId);
            };

            this.multiRoomIframes.set(index, {
                container: iframeContainer,
                iframe: iframe,
                tabData: tabData
            });

            this.updateMultiRoomIframeStatus(index, '⏳ CARREGANDO', '#FF9800');

            return tabData;
        }

        monitorMultiRoomIframe(iframe, tabData, index) {
            const checkIframe = () => {
                try {
                    const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

                    if (iframeDoc.readyState === 'complete' && iframeDoc.body) {
                        const nickInput = this.findNickInput(iframeDoc);
                        if (nickInput && !tabData.nickFilled) {
                            this.fillNickname(nickInput, tabData.nick);
                            tabData.nickFilled = true;
                            console.log(`✅ Nick preenchido no iframe multi-sala ${index + 1}: ${tabData.nick}`);
                        }

                        const playBtn = this.findPlayButton(iframeDoc);
                        const isReady = playBtn && this.isElementVisible(playBtn);

                        if (isReady && !tabData.ready) {
                            tabData.ready = true;
                            tabData.loaded = true;
                            this.updateMultiRoomIframeStatus(index, '✅ PRONTA', '#4CAF50');
                            console.log(`🎯 Iframe multi-sala ${index + 1} PRONTO!`);
                        }

                        if (this.isInRoom(iframeDoc) && !tabData.inRoom) {
                            tabData.inRoom = true;
                            this.updateMultiRoomIframeStatus(index, '🎉 NA SALA!', '#4CAF50');
                            iframe.style.border = '2px solid #4CAF50';
                        }
                    }
                } catch (e) {
                }

                if (!tabData.inRoom) {
                    setTimeout(checkIframe, 1000);
                }
            };

            setTimeout(checkIframe, 2000);
        }

        retryMultiRoomIframeLoad(iframe, tabData, index, roomId) {
            if (tabData.attempts < tabData.maxAttempts) {
                tabData.attempts++;
                console.log(`🔄 Tentativa ${tabData.attempts}/${tabData.maxAttempts} para iframe multi-sala ${index + 1}`);

                setTimeout(() => {
                    iframe.src = `https://gartic.com.br/0${roomId}?t=${Date.now()}`;
                }, 2000);
            } else {
                this.updateMultiRoomIframeStatus(index, '❌ FALHA AO CARREGAR', '#f44336');
            }
        }

        updateMultiRoomIframeStatus(index, status, color) {
            const statusElement = document.getElementById(`multi-iframe-status-${index}`);
            if (statusElement) {
                statusElement.textContent = status;
                statusElement.style.color = color;
            }

            this.updateMultiRoomStatusDisplay();
        }

        createMultiRoomExternalTab(nick, index, roomIds, roomIndex = null) {
            const roomId = roomIds[roomIndex !== null ? roomIndex : index % roomIds.length];
            const tabId = `multi-external-tab-${index}`;

            const newTab = window.open(`https://gartic.com.br/0${roomId}`, `multiroom${index}`);

            if (!newTab) {
                console.warn(`❌ Não foi possível abrir aba externa multi-sala ${index + 1}. Verifique bloqueador de pop-ups.`);
                return null;
            }

            const tabData = {
                window: newTab,
                nick: nick,
                roomId: roomId,
                ready: false,
                loaded: false,
                nickFilled: false,
                inRoom: false,
                attempts: 0,
                maxAttempts: 3,
                tabId: tabId
            };

            this.multiRoomExternalTabs.set(index, tabData);

            this.updateMultiRoomExternalStatus(index, '⏳ ABRINDO...', '#FF9800');

            this.monitorMultiRoomExternalTab(tabData, index);

            return tabData;
        }

        monitorMultiRoomExternalTab(tabData, index) {
            const checkTab = () => {
                try {
                    if (tabData.window.closed) {
                        this.updateMultiRoomExternalStatus(index, '❌ FECHADA', '#f44336');
                        return;
                    }

                    const tabDoc = tabData.window.document;

                    if (tabDoc.readyState === 'complete' && tabDoc.body) {
                        const nickInput = this.findNickInput(tabDoc);
                        if (nickInput && !tabData.nickFilled) {
                            this.fillNickname(nickInput, tabData.nick);
                            tabData.nickFilled = true;
                            this.updateMultiRoomExternalStatus(index, '✅ NICK PREENCHIDO', '#4CAF50');
                            console.log(`✅ Nick preenchido na aba multi-sala ${index + 1}: ${tabData.nick}`);
                        }

                        const playBtn = this.findPlayButton(tabDoc);
                        const isReady = playBtn && this.isElementVisible(playBtn);

                        if (isReady && !tabData.ready) {
                            tabData.ready = true;
                            tabData.loaded = true;
                            this.updateMultiRoomExternalStatus(index, '✅ PRONTA', '#4CAF50');
                            console.log(`🎯 Aba externa multi-sala ${index + 1} PRONTA!`);
                        }

                        if (this.isInRoom(tabDoc) && !tabData.inRoom) {
                            tabData.inRoom = true;
                            this.updateMultiRoomExternalStatus(index, '🎉 NA SALA!', '#4CAF50');
                        }
                    }
                } catch (e) {
                    if (tabData.attempts < tabData.maxAttempts) {
                        tabData.attempts++;
                        setTimeout(checkTab, 1000);
                    } else {
                        this.updateMultiRoomExternalStatus(index, '❌ ERRO AO CARREGAR', '#f44336');
                    }
                    return;
                }

                if (!tabData.inRoom) {
                    setTimeout(checkTab, 1000);
                }
            };

            setTimeout(checkTab, 2000);
        }

        updateMultiRoomExternalStatus(index, status, color) {
            this.updateMultiRoomStatusDisplay();
        }

        updateMultiRoomStatusDisplay() {
            const iframesStatusContainer = document.getElementById('multi-room-iframes-status');
            const externalStatusContainer = document.getElementById('multi-room-external-status');

            if (!iframesStatusContainer || !externalStatusContainer) return;

            iframesStatusContainer.innerHTML = '';
            externalStatusContainer.innerHTML = '';

            this.multiRoomIframes.forEach((iframeData, index) => {
                const statusElement = document.createElement('div');
                statusElement.id = `multi-iframe-status-display-${index}`;
                statusElement.style.cssText = `
                    padding: 4px;
                    background: #2a2a2a;
                    border-radius: 3px;
                    font-size: 9px;
                    text-align: center;
                    border: 1px solid #FF6B00;
                    margin-bottom: 2px;
                `;

                const status = iframeData.tabData.inRoom ? '🎉 NA SALA!' :
                             iframeData.tabData.ready ? '✅ PRONTA' : '⏳ CARREGANDO';
                const color = iframeData.tabData.inRoom ? '#4CAF50' :
                            iframeData.tabData.ready ? '#4CAF50' : '#FF9800';

                statusElement.innerHTML = `<strong>${index + 1}. ${iframeData.tabData.nick} (Sala ${iframeData.tabData.roomId})</strong><br>${status}`;
                statusElement.style.color = color;
                iframesStatusContainer.appendChild(statusElement);
            });

            this.multiRoomExternalTabs.forEach((tabData, index) => {
                const statusElement = document.createElement('div');
                statusElement.id = `multi-external-status-${index}`;
                statusElement.style.cssText = `
                    padding: 4px;
                    background: #2a2a2a;
                    border-radius: 3px;
                    font-size: 9px;
                    text-align: center;
                    border: 1px solid #FF6B00;
                    margin-bottom: 2px;
                `;

                const status = tabData.inRoom ? '🎉 NA SALA!' :
                             tabData.ready ? '✅ PRONTA' :
                             tabData.window.closed ? '❌ FECHADA' : '⏳ CARREGANDO';
                const color = tabData.inRoom ? '#4CAF50' :
                            tabData.ready ? '#4CAF50' :
                            tabData.window.closed ? '#f44336' : '#FF9800';

                statusElement.innerHTML = `<strong>${index + 1}. ${tabData.nick} (Sala ${tabData.roomId})</strong><br>${status}`;
                statusElement.style.color = color;
                externalStatusContainer.appendChild(statusElement);
            });
        }

        createExternalTab(nick, index, roomId) {
            const tabId = `external-tab-${index}`;

            const newTab = window.open(`https://gartic.com.br/0${roomId}`, `_blank${index}`);

            if (!newTab) {
                console.warn(`❌ Não foi possível abrir aba externa ${index + 1}. Verifique bloqueador de pop-ups.`);
                return null;
            }

            const tabData = {
                window: newTab,
                nick: nick,
                ready: false,
                loaded: false,
                nickFilled: false,
                inRoom: false,
                attempts: 0,
                maxAttempts: 3,
                tabId: tabId
            };

            this.externalTabs.set(index, tabData);
            this.updateExternalTabStatus(index, '⏳ ABRINDO...', '#FF9800');
            this.monitorExternalTab(tabData, index);

            return tabData;
        }

        monitorExternalTab(tabData, index) {
            const checkTab = () => {
                try {
                    if (tabData.window.closed) {
                        this.updateExternalTabStatus(index, '❌ FECHADA', '#f44336');
                        return;
                    }

                    const tabDoc = tabData.window.document;

                    if (tabDoc.readyState === 'complete' && tabDoc.body) {
                        const nickInput = this.findNickInput(tabDoc);
                        if (nickInput && !tabData.nickFilled) {
                            this.fillNickname(nickInput, tabData.nick);
                            tabData.nickFilled = true;
                            this.updateExternalTabStatus(index, '✅ NICK PREENCHIDO', '#4CAF50');
                        }

                        const playBtn = this.findPlayButton(tabDoc);
                        const isReady = playBtn && this.isElementVisible(playBtn);

                        if (isReady && !tabData.ready) {
                            tabData.ready = true;
                            tabData.loaded = true;
                            this.updateExternalTabStatus(index, '✅ PRONTA', '#4CAF50');
                        }

                        if (this.isInRoom(tabDoc) && !tabData.inRoom) {
                            tabData.inRoom = true;
                            this.updateExternalTabStatus(index, '🎉 NA SALA!', '#4CAF50');
                        }
                    }
                } catch (e) {
                    if (tabData.attempts < tabData.maxAttempts) {
                        tabData.attempts++;
                        setTimeout(checkTab, 1000);
                    } else {
                        this.updateExternalTabStatus(index, '❌ ERRO AO CARREGAR', '#f44336');
                    }
                    return;
                }

                if (!tabData.inRoom) {
                    setTimeout(checkTab, 1000);
                }
            };

            setTimeout(checkTab, 2000);
        }

        createDirectIframe(nick, index, roomId) {
            if (!this.container) {
                this.createViewer();
            }

            const iframesGrid = document.getElementById('iframes-grid');
            const iframeContainer = document.createElement('div');
            iframeContainer.style.cssText = `
                background: #2a2a2a;
                border: 2px solid #4CAF50;
                border-radius: 8px;
                padding: 8px;
                display: flex;
                flex-direction: column;
                min-height: 300px;
            `;

            const iframeHeader = document.createElement('div');
            iframeHeader.style.cssText = `
                display: flex;
                justify-content: space-between;
                align-items: center;
                padding: 5px;
                background: #333;
                border-radius: 5px;
                margin-bottom: 5px;
                font-size: 12px;
                color: white;
            `;
            iframeHeader.innerHTML = `
                <span>🔰 ${nick}</span>
                <span id="status-${index}" style="color: #ff9800;">⏳ CARREGANDO</span>
            `;
            iframeContainer.appendChild(iframeHeader);

            const iframe = document.createElement('iframe');
            iframe.src = `https://gartic.com.br/0${roomId}`;
            iframe.style.cssText = `
                width: 100%;
                height: 250px;
                border: 1px solid #555;
                border-radius: 5px;
                background: white;
                flex: 1;
            `;

            iframe.setAttribute('allow', 'autoplay; microphone; camera');
            iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin allow-forms allow-popups');

            iframeContainer.appendChild(iframe);
            iframesGrid.appendChild(iframeContainer);

            const tabData = {
                iframe: iframe,
                nick: nick,
                ready: false,
                loaded: false,
                nickFilled: false,
                inRoom: false,
                attempts: 0,
                maxAttempts: 3
            };

            iframe.onload = () => {
                this.monitorIframe(iframe, tabData, index);
            };

            iframe.onerror = () => {
                console.warn(`⚠️ Erro ao carregar iframe ${index + 1}`);
                this.retryIframeLoad(iframe, tabData, index, roomId);
            };

            this.iframes.set(index, {
                container: iframeContainer,
                iframe: iframe,
                tabData: tabData
            });

            return tabData;
        }

        monitorIframe(iframe, tabData, index) {
            const checkIframe = () => {
                try {
                    const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

                    if (iframeDoc.readyState === 'complete' && iframeDoc.body) {
                        const nickInput = this.findNickInput(iframeDoc);
                        if (nickInput && !tabData.nickFilled) {
                            this.fillNickname(nickInput, tabData.nick);
                            tabData.nickFilled = true;
                            console.log(`✅ Nick preenchido no iframe ${index + 1}: ${tabData.nick}`);
                        }

                        const playBtn = this.findPlayButton(iframeDoc);
                        const isReady = playBtn && this.isElementVisible(playBtn);

                        if (isReady && !tabData.ready) {
                            tabData.ready = true;
                            tabData.loaded = true;
                            this.updateIframeStatus(index, '✅ PRONTA', '#4CAF50');
                            console.log(`🎯 Iframe ${index + 1} PRONTO!`);
                        }

                        if (this.isInRoom(iframeDoc) && !tabData.inRoom) {
                            tabData.inRoom = true;
                            this.updateIframeStatus(index, '🎉 NA SALA!', '#4CAF50');
                            iframe.style.border = '2px solid #4CAF50';
                        }
                    }
                } catch (e) {
                }

                if (!tabData.inRoom) {
                    setTimeout(checkIframe, 1000);
                }
            };

            setTimeout(checkIframe, 2000);
        }

        retryIframeLoad(iframe, tabData, index, roomId) {
            if (tabData.attempts < tabData.maxAttempts) {
                tabData.attempts++;
                console.log(`🔄 Tentativa ${tabData.attempts}/${tabData.maxAttempts} para iframe ${index + 1}`);

                setTimeout(() => {
                    iframe.src = `https://gartic.com.br/0${roomId}?t=${Date.now()}`;
                }, 2000);
            } else {
                this.updateIframeStatus(index, '❌ FALHA AO CARREGAR', '#f44336');
            }
        }

        fillNickname(nickInput, nick) {
            try {
                nickInput.value = nick;

                const events = ['input', 'change', 'keydown', 'keyup', 'blur'];
                events.forEach(eventType => {
                    const event = new Event(eventType, { bubbles: true });
                    nickInput.dispatchEvent(event);
                });
            } catch (e) {
                console.warn('⚠️ Erro ao preencher nick:', e);
            }
        }

        updateExternalTabStatus(index, status, color) {
            const externalTabsStatus = document.getElementById('external-tabs-status');
            if (!externalTabsStatus) return;

            let statusElement = document.getElementById(`external-tab-status-${index}`);
            if (!statusElement) {
                statusElement = document.createElement('div');
                statusElement.id = `external-tab-status-${index}`;
                statusElement.style.cssText = `
                    padding: 5px;
                    background: #2a2a2a;
                    border-radius: 4px;
                    font-size: 10px;
                    text-align: center;
                    border: 1px solid #8B4513;
                `;
                externalTabsStatus.appendChild(statusElement);
            }

            statusElement.innerHTML = `<strong>${index + 1}. ${this.externalTabs.get(index)?.nick || 'N/A'}</strong><br>${status}`;
            statusElement.style.color = color;
        }

        updateIframeStatus(index, status, color) {
            const statusElement = document.getElementById(`status-${index}`);
            if (statusElement) {
                statusElement.textContent = status;
                statusElement.style.color = color;
            }
        }

        makeDraggable(header, element) {
            let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

            header.onmousedown = dragMouseDown;

            function dragMouseDown(e) {
                e = e || window.event;
                e.preventDefault();
                pos3 = e.clientX;
                pos4 = e.clientY;
                document.onmouseup = closeDragElement;
                document.onmousemove = elementDrag;
            }

            function elementDrag(e) {
                e = e || window.event;
                e.preventDefault();
                pos1 = pos3 - e.clientX;
                pos2 = pos4 - e.clientY;
                pos3 = e.clientX;
                pos4 = e.clientY;
                element.style.top = (element.offsetTop - pos2) + "px";
                element.style.left = (element.offsetLeft - pos1) + "px";
                element.style.transform = 'none';
            }

            function closeDragElement() {
                document.onmouseup = null;
                document.onmousemove = null;
            }
        }

        toggleMinimize() {
            if (!this.container) return;

            const iframesGrid = document.getElementById('iframes-grid');
            const externalTabsSection = this.container.querySelector('#external-tabs-status').parentElement;
            const multiRoomSection = this.container.querySelector('#multi-room-iframes-status').parentElement.parentElement;

            if (this.isMinimized) {
                iframesGrid.style.display = 'grid';
                externalTabsSection.style.display = 'block';
                multiRoomSection.style.display = 'block';
                this.container.style.height = '90%';
                this.isMinimized = false;
            } else {
                iframesGrid.style.display = 'none';
                externalTabsSection.style.display = 'none';
                multiRoomSection.style.display = 'none';
                this.container.style.height = 'auto';
                this.isMinimized = true;
            }
        }

        openViewer() {
            if (!this.container) {
                this.createViewer();
            }

            this.container.style.display = 'flex';
            this.isVisible = true;
            this.isMinimized = false;
        }

        closeViewer() {
            if (this.container) {
                this.container.style.display = 'none';
                this.isVisible = false;
            }
        }

        closeAllExternalTabs() {
            this.externalTabs.forEach((tabData, index) => {
                try {
                    if (!tabData.window.closed) {
                        tabData.window.close();
                    }
                } catch (e) {
                    console.warn(`⚠️ Erro ao fechar aba externa ${index + 1}:`, e);
                }
            });
            this.externalTabs.clear();

            const externalTabsStatus = document.getElementById('external-tabs-status');
            if (externalTabsStatus) {
                externalTabsStatus.innerHTML = '';
            }
        }

        getAllMultiRoomReadyElements() {
            const readyElements = [];

            this.multiRoomIframes.forEach((iframeData, index) => {
                if (iframeData.tabData.ready) {
                    readyElements.push({
                        type: 'multiRoomIframe',
                        data: iframeData.tabData,
                        index: index
                    });
                }
            });

            this.multiRoomExternalTabs.forEach((tabData, index) => {
                if (tabData.ready && !tabData.window.closed) {
                    readyElements.push({
                        type: 'multiRoomExternalTab',
                        data: tabData,
                        index: index
                    });
                }
            });

            return readyElements;
        }

        closeAllMultiRoomElements() {
            this.multiRoomIframes.forEach((iframeData, index) => {
                if (iframeData.container && iframeData.container.parentNode) {
                    iframeData.container.parentNode.removeChild(iframeData.container);
                }
            });
            this.multiRoomIframes.clear();

            this.multiRoomExternalTabs.forEach((tabData, index) => {
                try {
                    if (!tabData.window.closed) {
                        tabData.window.close();
                    }
                } catch (e) {
                    console.warn(`⚠️ Erro ao fechar aba externa multi-sala ${index + 1}:`, e);
                }
            });
            this.multiRoomExternalTabs.clear();

            this.updateMultiRoomStatusDisplay();
        }

        clearViewer() {
            if (this.container) {
                this.container.remove();
                this.container = null;
            }
            this.iframes.clear();
            this.closeAllExternalTabs();
            this.closeAllMultiRoomElements();
            this.isVisible = false;
            this.isMinimized = false;
        }

        getReadyIframes() {
            const readyIframes = [];
            this.iframes.forEach((iframeData, index) => {
                if (iframeData.tabData.ready) {
                    readyIframes.push(iframeData.tabData);
                }
            });
            return readyIframes;
        }

        getReadyExternalTabs() {
            const readyTabs = [];
            this.externalTabs.forEach((tabData, index) => {
                if (tabData.ready && !tabData.window.closed) {
                    readyTabs.push(tabData);
                }
            });
            return readyTabs;
        }

        getAllReadyElements() {
            const readyElements = [];

            this.iframes.forEach((iframeData, index) => {
                if (iframeData.tabData.ready) {
                    readyElements.push({
                        type: 'iframe',
                        data: iframeData.tabData,
                        index: index
                    });
                }
            });

            this.externalTabs.forEach((tabData, index) => {
                if (tabData.ready && !tabData.window.closed) {
                    readyElements.push({
                        type: 'externalTab',
                        data: tabData,
                        index: index
                    });
                }
            });

            return readyElements;
        }

        findNickInput(doc) {
            const selectors = [
                '#nick',
                'input[name="login"]',
                'input[placeholder*="nick" i]',
                'input[placeholder*="nome" i]',
                'input[type="text"]'
            ];

            for (const selector of selectors) {
                const element = doc.querySelector(selector);
                if (element) return element;
            }
            return null;
        }

        findPlayButton(doc) {
            const selectors = [
                'input[value*="Jogar" i]',
                'input[value*="Play" i]',
                'input[type="submit"]',
                'button[type="submit"]'
            ];

            for (const selector of selectors) {
                const element = doc.querySelector(selector);
                if (element && this.isElementVisible(element)) return element;
            }
            return null;
        }

        isElementVisible(element) {
            return element &&
                   element.offsetWidth > 0 &&
                   element.offsetHeight > 0 &&
                   element.style.display !== 'none' &&
                   element.style.visibility !== 'hidden';
        }

        isInRoom(doc) {
            try {
                const roomIndicators = [
                    '.game-container',
                    '.drawing-area',
                    '.palette',
                    'canvas',
                    '[class*="game"]',
                    '[class*="sala"]'
                ];

                return roomIndicators.some(selector => {
                    const element = doc.querySelector(selector);
                    return element && this.isElementVisible(element);
                });
            } catch (e) {
                return false;
            }
        }
    }

    // =============================================
    // CONTROLADOR DE SINCRONIZAÇÃO (100% DO SCRIPT 2 - ORDEM CORRETA)
    // =============================================

    class IframeSyncController {
        constructor() {
            this.networkController = new AdvancedNetworkController();
            this.vacancySystem = new VacancySystem();
            this.clickQueue = [];
            this.realTimeViewer = new RealTimeViewer();
            this.isProcessing = false;
        }

        async prepareMultiRoomClicks(readyElements) {
            this.updateSyncStatus('⚡ PREPARANDO SINCRONIZAÇÃO MULTI-SALA...');

            this.clickQueue = [];
            readyElements.forEach((element, index) => {
                this.clickQueue.push({
                    element: element,
                    index: index,
                    executed: false,
                    success: false
                });
            });

            this.updateSyncStatus(`🎯 ${readyElements.length} ELEMENTOS MULTI-SALA PREPARADOS`);
            return this.clickQueue.length;
        }

        async executeMultiRoomClicks() {
            if (this.clickQueue.length === 0) {
                this.updateSyncStatus('❌ NENHUM ELEMENTO MULTI-SALA NA FILA');
                return 0;
            }

            if (this.isProcessing) {
                this.updateSyncStatus('⚠️ JÁ EXISTE UMA OPERAÇÃO EM ANDAMENTO');
                return 0;
            }

            this.isProcessing = true;

            try {
                this.updateSyncStatus('🔒 BLOQUEANDO CONEXÃO...');
                this.networkController.blockNetwork();
                await this.delay(500);

                this.updateSyncStatus('⚡ EXECUTANDO CLIQUES MULTI-SALA...');

                const clickPromises = this.clickQueue.map((clickItem, index) => {
                    return new Promise((resolve) => {
                        requestAnimationFrame(() => {
                            const result = this.executeMultiRoomElementClick(clickItem.element, index);
                            resolve(result);
                        });
                    });
                });

                const results = await Promise.all(clickPromises);
                const successfulClicks = results.filter(result => result === true).length;

                this.updateSyncStatus('🔓 RESTAURANDO CONEXÃO...');
                await this.delay(300);
                this.networkController.restoreNetwork();

                this.updateSyncStatus(`✅ ${successfulClicks}/${this.clickQueue.length} MULTI-SALA CONCLUÍDO`);

                this.isProcessing = false;
                return successfulClicks;

            } catch (error) {
                console.error('💥 ERRO NA SINCRONIZAÇÃO MULTI-SALA:', error);
                this.networkController.restoreNetwork();
                this.updateSyncStatus('❌ FALHA NA SINCRONIZAÇÃO MULTI-SALA');
                this.isProcessing = false;
                return 0;
            }
        }

        executeMultiRoomElementClick(elementData, index) {
            try {
                if (elementData.type === 'multiRoomIframe') {
                    return this.executeMultiRoomIframeClick(elementData.data, index);
                } else if (elementData.type === 'multiRoomExternalTab') {
                    return this.executeMultiRoomExternalTabClick(elementData.data, index);
                }
                return false;
            } catch (error) {
                console.error(`💥 Erro crítico no elemento multi-sala ${index + 1}:`, error);
                return false;
            }
        }

        executeMultiRoomIframeClick(iframeData, index) {
            try {
                const iframe = iframeData.iframe;
                const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

                if (this.isInRoom(iframeDoc)) {
                    console.log(`✅ Iframe multi-sala ${index + 1} já está na sala ${iframeData.roomId}`);
                    return true;
                }

                const playBtn = this.findPlayButton(iframeDoc);
                if (!playBtn) {
                    console.warn(`❌ Botão não encontrado no iframe multi-sala ${index + 1}`);
                    return false;
                }

                try {
                    playBtn.click();

                    ['mousedown', 'mouseup', 'click'].forEach(eventType => {
                        try {
                            const event = new MouseEvent(eventType, {
                                bubbles: true,
                                cancelable: true,
                                view: iframe.contentWindow
                            });
                            playBtn.dispatchEvent(event);
                        } catch (e) {}
                    });

                } catch (error) {
                    console.warn(`⚠️ Erro no clique iframe multi-sala ${index + 1}:`, error);
                    return false;
                }

                console.log(`🎯 Clique executado no iframe multi-sala ${index + 1} (Sala ${iframeData.roomId})`);
                this.realTimeViewer.updateMultiRoomIframeStatus(index, '⚡ CLICADO!', '#FF9800');

                return true;

            } catch (error) {
                console.error(`💥 Erro crítico no iframe multi-sala ${index + 1}:`, error);
                return false;
            }
        }

        executeMultiRoomExternalTabClick(tabData, index) {
            try {
                if (tabData.window.closed) {
                    console.warn(`❌ Aba externa multi-sala ${index + 1} foi fechada`);
                    return false;
                }

                const tabDoc = tabData.window.document;

                if (this.isInRoom(tabDoc)) {
                    console.log(`✅ Aba externa multi-sala ${index + 1} já está na sala ${tabData.roomId}`);
                    return true;
                }

                const playBtn = this.findPlayButton(tabDoc);
                if (!playBtn) {
                    console.warn(`❌ Botão não encontrado na aba externa multi-sala ${index + 1}`);
                    return false;
                }

                try {
                    tabData.window.focus();

                    playBtn.click();

                    ['mousedown', 'mouseup', 'click'].forEach(eventType => {
                        try {
                            const event = new MouseEvent(eventType, {
                                bubbles: true,
                                cancelable: true,
                                view: tabData.window
                            });
                            playBtn.dispatchEvent(event);
                        } catch (e) {}
                    });

                } catch (error) {
                    console.warn(`⚠️ Erro no clique aba externa multi-sala ${index + 1}:`, error);
                    return false;
                }

                console.log(`🎯 Clique executado na aba externa multi-sala ${index + 1} (Sala ${tabData.roomId})`);
                this.realTimeViewer.updateMultiRoomExternalStatus(index, '⚡ CLICADO!', '#FF9800');

                return true;

            } catch (error) {
                console.error(`💥 Erro crítico na aba externa multi-sala ${index + 1}:`, error);
                return false;
            }
        }

        async prepareAllClicks(readyElements) {
            this.updateSyncStatus('⚡ PREPARANDO SINCRONIZAÇÃO...');

            this.clickQueue = [];
            readyElements.forEach((element, index) => {
                this.clickQueue.push({
                    element: element,
                    index: index,
                    executed: false,
                    success: false
                });
            });

            this.updateSyncStatus(`🎯 ${readyElements.length} ELEMENTOS PREPARADOS`);
            return this.clickQueue.length;
        }

        async executeAllClicksWithVacancyCheck(roomId) {
            if (this.clickQueue.length === 0) {
                this.updateSyncStatus('❌ NENHUM ELEMENTO NA FILA');
                return 0;
            }

            if (this.isProcessing) {
                this.updateSyncStatus('⚠️ JÁ EXISTE UMA OPERAÇÃO EM ANDAMENTO');
                return 0;
            }

            this.isProcessing = true;

            try {
                // FASE 1: VERIFICAR VAGAS (100% DO SCRIPT 2)
                this.updateSyncStatus('🔍 VERIFICANDO VAGAS...');
                const vacancyInfo = await this.vacancySystem.checkRoomVacancy(roomId);

                if (!vacancyInfo.hasVacancy) {
                    this.updateSyncStatus('⏳ AGUARDANDO VAGA...');

                    await new Promise((resolve) => {
                        this.vacancySystem.startVacancyCheck(roomId, (hasVacancy) => {
                            if (hasVacancy) {
                                resolve();
                            }
                        });
                    });
                }

                // FASE 2: BLOQUEIO TOTAL DA CONEXÃO
                this.updateSyncStatus('🔒 BLOQUEANDO CONEXÃO...');
                this.networkController.blockNetwork();
                await this.delay(500);

                // FASE 3: EXECUTAR TODOS OS CLIQUES SIMULTANEAMENTE
                this.updateSyncStatus('⚡ EXECUTANDO CLIQUES...');

                const clickPromises = this.clickQueue.map((clickItem, index) => {
                    return new Promise((resolve) => {
                        requestAnimationFrame(() => {
                            const result = this.executeElementClick(clickItem.element, index);
                            resolve(result);
                        });
                    });
                });

                const results = await Promise.all(clickPromises);
                const successfulClicks = results.filter(result => result === true).length;

                // FASE 4: RESTAURAR CONEXÃO IMEDIATAMENTE
                this.updateSyncStatus('🔓 RESTAURANDO CONEXÃO...');
                await this.delay(300);
                this.networkController.restoreNetwork();

                this.updateSyncStatus(`✅ ${successfulClicks}/${this.clickQueue.length} CONCLUÍDO`);

                this.isProcessing = false;
                return successfulClicks;

            } catch (error) {
                console.error('💥 ERRO NA SINCRONIZAÇÃO:', error);
                this.networkController.restoreNetwork();
                this.vacancySystem.stopVacancyCheck();
                this.updateSyncStatus('❌ FALHA NA SINCRONIZAÇÃO');
                this.isProcessing = false;
                return 0;
            }
        }

        executeElementClick(elementData, index) {
            try {
                if (elementData.type === 'iframe') {
                    return this.executeIframeClick(elementData.data, index);
                } else if (elementData.type === 'externalTab') {
                    return this.executeExternalTabClick(elementData.data, index);
                }
                return false;
            } catch (error) {
                console.error(`💥 Erro crítico no elemento ${index + 1}:`, error);
                return false;
            }
        }

        executeIframeClick(iframeData, index) {
            try {
                const iframe = iframeData.iframe;
                const iframeDoc = iframe.contentDocument || iframe.contentWindow.document;

                if (this.isInRoom(iframeDoc)) {
                    console.log(`✅ Iframe ${index + 1} já está na sala`);
                    return true;
                }

                const playBtn = this.findPlayButton(iframeDoc);
                if (!playBtn) {
                    console.warn(`❌ Botão não encontrado no iframe ${index + 1}`);
                    return false;
                }

                try {
                    playBtn.click();

                    ['mousedown', 'mouseup', 'click'].forEach(eventType => {
                        try {
                            const event = new MouseEvent(eventType, {
                                bubbles: true,
                                cancelable: true,
                                view: iframe.contentWindow
                            });
                            playBtn.dispatchEvent(event);
                        } catch (e) {}
                    });

                } catch (error) {
                    console.warn(`⚠️ Erro no clique iframe ${index + 1}:`, error);
                    return false;
                }

                console.log(`🎯 Clique executado no iframe ${index + 1}`);
                this.realTimeViewer.updateIframeStatus(index, '⚡ CLICADO!', '#FF9800');

                return true;

            } catch (error) {
                console.error(`💥 Erro crítico no iframe ${index + 1}:`, error);
                return false;
            }
        }

        executeExternalTabClick(tabData, index) {
            try {
                if (tabData.window.closed) {
                    console.warn(`❌ Aba externa ${index + 1} foi fechada`);
                    return false;
                }

                const tabDoc = tabData.window.document;

                if (this.isInRoom(tabDoc)) {
                    console.log(`✅ Aba externa ${index + 1} já está na sala`);
                    return true;
                }

                const playBtn = this.findPlayButton(tabDoc);
                if (!playBtn) {
                    console.warn(`❌ Botão não encontrado na aba externa ${index + 1}`);
                    return false;
                }

                try {
                    tabData.window.focus();

                    playBtn.click();

                    ['mousedown', 'mouseup', 'click'].forEach(eventType => {
                        try {
                            const event = new MouseEvent(eventType, {
                                bubbles: true,
                                cancelable: true,
                                view: tabData.window
                            });
                            playBtn.dispatchEvent(event);
                        } catch (e) {}
                    });

                } catch (error) {
                    console.warn(`⚠️ Erro no clique aba externa ${index + 1}:`, error);
                    return false;
                }

                console.log(`🎯 Clique executado na aba externa ${index + 1}`);
                this.realTimeViewer.updateExternalTabStatus(index, '⚡ CLICADO!', '#FF9800');

                return true;

            } catch (error) {
                console.error(`💥 Erro crítico na aba externa ${index + 1}:`, error);
                return false;
            }
        }

        findPlayButton(doc) {
            const selectors = [
                'input[value*="Jogar" i]',
                'input[value*="Play" i]',
                'input[type="submit"]',
                'button[type="submit"]'
            ];

            for (const selector of selectors) {
                try {
                    const element = doc.querySelector(selector);
                    if (element && this.isElementVisible(element)) return element;
                } catch (e) {}
            }
            return null;
        }

        isElementVisible(element) {
            return element && element.offsetWidth > 0 && element.offsetHeight > 0;
        }

        isInRoom(doc) {
            try {
                const indicators = [
                    '.game-container',
                    '.drawing-area',
                    'canvas',
                    '.room-container',
                    '#game',
                    '.palette'
                ];
                return indicators.some(selector => doc.querySelector(selector));
            } catch (e) {
                return false;
            }
        }

        delay(ms) {
            return new Promise(resolve => setTimeout(resolve, ms));
        }

        updateSyncStatus(msg) {
            if (typeof window.updateSyncStatus === 'function') {
                window.updateSyncStatus(msg);
            } else {
                console.log('SYNC STATUS:', msg);
            }
        }

        stopVacancyCheck() {
            this.vacancySystem.stopVacancyCheck();
        }
    }

    // =============================================
    // VARIÁVEIS GLOBAIS E INICIALIZAÇÃO
    // =============================================

    let selectedRoom = null;
    let configManager = new ConfigManager();
    let iframeController = new IframeSyncController();
    let multiRoomManager = new MultiRoomManager();
    
    // NOVO: Instanciar sistemas avançados
    let precisionSyncSystem = new PrecisionSyncSystem();
    let proNetworkController = new ProfessionalNetworkController();
    let randomRoomSelector = new RandomRoomSelector();
    
    window.configManager = configManager;
    window.precisionSyncSystem = precisionSyncSystem;
    window.proNetworkController = proNetworkController;
    window.randomRoomSelector = randomRoomSelector;

    let botCount = configManager.get('defaultTabCount') || 5;
    let useExternalTabs = configManager.get('useExternalTabs') || false;
    let externalTabCount = configManager.get('externalTabCount') || 0;
    let nickPrefix = configManager.get('nickPrefix');
    let disableRandomNumbers = configManager.get('disableRandomNumbers') || false;
    let onlyEmptyRooms = configManager.get('onlyEmptyRooms') || false; // NOVA VARIÁVEL
    selectedRoom = configManager.get('lastRoom');

    const savedRooms = configManager.get('selectedRooms');
    if (savedRooms && Array.isArray(savedRooms)) {
        multiRoomManager.selectedRooms = savedRooms;
        randomRoomSelector.selectedRooms = new Set(savedRooms);
    }

    // =============================================
    // FUNÇÕES DO SCRIPT ORIGINAL
    // =============================================

    function loadRooms() {
        const roomList = document.getElementById('roomList');
        const rooms = document.querySelectorAll('.sala, [onclick*="selecionaSala"], .room, [class*="room"]');

        roomList.innerHTML = '';

        if (rooms.length === 0) {
            roomList.innerHTML = '<div style="padding:10px;text-align:center;color:#666;font-size:10px;">Nenhuma sala encontrada<br>Recarregue a página</div>';
            return;
        }

        rooms.forEach((room, index) => {
            const roomElement = document.createElement('div');
            roomElement.style.cssText = `
                display: flex;
                align-items: center;
                padding: 6px 8px;
                cursor: pointer;
                border-bottom: 1px solid #eee;
                font-size: 10px;
                transition: all 0.2s;
            `;

            const roomText = room.textContent.trim();
            const onclickAttr = room.getAttribute('onclick');
            let roomId = null;

            if (onclickAttr) {
                const roomMatch = onclickAttr.match(/\d+/);
                if (roomMatch) {
                    roomId = roomMatch[0];
                }
            }

            // Verificar quantidade de pessoas na sala
            let playerCount = 0;
            const quantElement = room.querySelector('.sala_quant');
            if (quantElement) {
                const quantText = quantElement.textContent;
                playerCount = parseInt(quantText) || 0;
            }
            
            const isEmpty = playerCount === 0;
            const shouldHide = onlyEmptyRooms && !isEmpty;

            const checkbox = document.createElement('input');
            checkbox.type = 'checkbox';
            checkbox.style.marginRight = '8px';
            checkbox.style.transform = 'scale(0.8)';
            checkbox.setAttribute('data-room-id', roomId || '');

            if (roomId) {
                if (multiRoomManager.selectedRooms.includes(roomId) || 
                    randomRoomSelector.selectedRooms.has(roomId)) {
                    checkbox.checked = true;
                }
                
                multiRoomManager.roomCheckboxes.set(roomId, checkbox);
                randomRoomSelector.roomElements.set(roomId, room);
            }

            checkbox.onchange = function(e) {
                e.stopPropagation();
                if (roomId) {
                    if (checkbox.checked) {
                        multiRoomManager.addRoom(roomId);
                        randomRoomSelector.selectedRooms.add(roomId);
                    } else {
                        multiRoomManager.removeRoom(roomId);
                        randomRoomSelector.selectedRooms.delete(roomId);
                    }
                    configManager.set('selectedRooms', multiRoomManager.selectedRooms);
                    updateSelectedRoomsList();
                }
            };

            roomElement.appendChild(checkbox);

            const roomTextElement = document.createElement('span');
            const playerInfo = isEmpty ? ' 🟢' : ` 👥 ${playerCount}`;
            roomTextElement.textContent = `${index + 1}. ${roomText.substring(0, 30)}${roomText.length > 30 ? '...' : ''}${playerInfo}`;
            
            if (isEmpty) {
                roomTextElement.style.color = '#4CAF50';
                roomTextElement.style.fontWeight = 'bold';
            } else if (playerCount > 0) {
                roomTextElement.style.color = '#FF9800';
            }
            
            roomElement.appendChild(roomTextElement);

            if (shouldHide) {
                roomElement.style.display = 'none';
            }

            roomElement.onmouseenter = () => {
                roomElement.style.background = '#f0f0f0';
            };
            roomElement.onmouseleave = () => {
                if (!roomElement.style.background.includes('#8A2BE2')) {
                    roomElement.style.background = '';
                }
            };

            roomElement.onclick = (e) => {
                if (e.target !== checkbox) {
                    document.querySelectorAll('#roomList div').forEach(el => {
                        el.style.background = '';
                        el.style.color = '';
                    });
                    roomElement.style.background = '#8A2BE2';
                    roomElement.style.color = 'white';

                    if (roomId) {
                        selectedRoom = roomId;
                        configManager.set('lastRoom', selectedRoom);
                        updateStatus(`🎯 Sala ${selectedRoom} selecionada`);
                    }
                }
            };

            if (roomId) {
                multiRoomManager.roomCheckboxes.set(roomId, checkbox);
            }

            roomList.appendChild(roomElement);
        });

        updateSelectedRoomsList();
    }

    function filterRooms(searchText) {
        document.querySelectorAll('#roomList div').forEach(room => {
            const shouldShow = room.textContent.toLowerCase().includes(searchText);
            const isEmptyVisible = room.textContent.includes('🟢');
            
            if (onlyEmptyRooms && !isEmptyVisible && !shouldShow) {
                room.style.display = 'none';
            } else {
                room.style.display = shouldShow ? 'flex' : 'none';
            }
        });
    }

    function generateNicks(totalCount) {
        const nicks = [];

        for (let i = 0; i < totalCount; i++) {
            if (disableRandomNumbers) {
                nicks.push(nickPrefix);
            } else {
                const usedNumbers = new Set();
                let randomNum;
                do {
                    randomNum = Math.floor(Math.random() * 9000) + 1000;
                } while (usedNumbers.has(randomNum));

                usedNumbers.add(randomNum);
                nicks.push(`${nickPrefix}${randomNum}`);
            }
        }
        return nicks;
    }

    window.updateSyncStatus = function(msg) {
        const syncStatus = document.getElementById('syncStatus');
        if (syncStatus) {
            syncStatus.textContent = msg;
            syncStatus.style.color = msg.includes('✅') ? '#4CAF50' :
                                   msg.includes('❌') ? '#f44336' :
                                   msg.includes('⚡') ? '#FFEB3B' : '#c8e6c9';
        }
    };

    function updateStatus(msg) {
        const status = document.getElementById('status');
        if (status) {
            status.textContent = msg;
            status.style.color = msg.includes('✅') || msg.includes('🎉') ? '#4CAF50' :
                               msg.includes('❌') ? '#f44336' :
                               msg.includes('🚀') || msg.includes('⚡') ? '#2196F3' : 'white';
        }
    }

    function updateTabStatus() {
        const tabStatus = document.getElementById('tabStatus');
        if (tabStatus) {
            const totalIframes = iframeController.realTimeViewer.iframes.size;
            const readyIframes = iframeController.realTimeViewer.getReadyIframes().length;
            const totalExternalTabs = iframeController.realTimeViewer.externalTabs.size;
            const readyExternalTabs = iframeController.realTimeViewer.getReadyExternalTabs().length;

            tabStatus.textContent = `Iframes: ${totalIframes} | Prontos: ${readyIframes} | Abas: ${totalExternalTabs} | Prontas: ${readyExternalTabs}`;
            tabStatus.style.color = (readyIframes + readyExternalTabs) === (totalIframes + totalExternalTabs) && (totalIframes + totalExternalTabs) > 0 ? '#4CAF50' : '#e0e0e0';
        }
    }

    // =============================================
    // NOVO: FUNÇÕES PARA OS SISTEMAS MULTI-SALA
    // =============================================

    function createMultiRoomIframes() {
        if (!multiRoomManager.hasRooms() && randomRoomSelector.getSelectedCount() === 0) {
            alert('Selecione pelo menos uma sala primeiro!');
            return;
        }

        const iframeCount = parseInt(document.getElementById('multiRoomIframeCount').value) || 0;
        if (iframeCount === 0) {
            alert('Configure a quantidade de iframes!');
            return;
        }

        updateStatus('🚀 CRIANDO IFRAMES MULTI-SALA...');
        const nicks = generateNicks(iframeCount);
        
        const rooms = randomRoomSelector.getSelectedCount() > 0 ? 
                     randomRoomSelector.getSelectedRooms() : 
                     multiRoomManager.selectedRooms;

        for (let i = 0; i < iframeCount; i++) {
            const roomId = rooms[i % rooms.length];
            iframeController.realTimeViewer.createMultiRoomIframe(nicks[i], i, [roomId], 0);
        }

        iframeController.realTimeViewer.openViewer();
        updateStatus(`✅ ${iframeCount} IFRAMES MULTI-SALA CRIADOS!`);
        updateMultiRoomStatus();
    }

    function createMultiRoomExternalTabs() {
        if (!multiRoomManager.hasRooms() && randomRoomSelector.getSelectedCount() === 0) {
            alert('Selecione pelo menos uma sala primeiro!');
            return;
        }

        const externalCount = parseInt(document.getElementById('multiRoomExternalCount').value) || 0;
        if (externalCount === 0) {
            alert('Configure a quantidade de abas externas!');
            return;
        }

        updateStatus('🚀 CRIANDO ABAS EXTERNAS MULTI-SALA...');
        const nicks = generateNicks(externalCount);
        
        const rooms = randomRoomSelector.getSelectedCount() > 0 ? 
                     randomRoomSelector.getSelectedRooms() : 
                     multiRoomManager.selectedRooms;

        for (let i = 0; i < externalCount; i++) {
            const roomId = rooms[i % rooms.length];
            iframeController.realTimeViewer.createMultiRoomExternalTab(nicks[i], i, [roomId], 0);
        }

        iframeController.realTimeViewer.openViewer();
        updateStatus(`✅ ${externalCount} ABAS MULTI-SALA CRIADAS!`);
        updateMultiRoomStatus();
    }

    function createMultiRoomTabs() {
        if (!multiRoomManager.hasRooms() && randomRoomSelector.getSelectedCount() === 0) {
            alert('Selecione pelo menos uma sala primeiro!');
            return;
        }

        const iframeCount = parseInt(document.getElementById('multiRoomIframeCount').value) || 0;
        const externalCount = parseInt(document.getElementById('multiRoomExternalCount').value) || 0;

        if (iframeCount === 0 && externalCount === 0) {
            alert('Configure pelo menos um dos contadores (iframes ou abas externas)!');
            return;
        }

        updateStatus('🚀 CRIANDO ABAS MULTI-SALA...');
        const totalCount = iframeCount + externalCount;
        const nicks = generateNicks(totalCount);
        
        const rooms = randomRoomSelector.getSelectedCount() > 0 ? 
                     randomRoomSelector.getSelectedRooms() : 
                     multiRoomManager.selectedRooms;

        let iframeIndex = 0;
        let externalTabIndex = 0;

        for (let i = 0; i < totalCount; i++) {
            const roomId = rooms[i % rooms.length];
            
            if (i < iframeCount) {
                iframeController.realTimeViewer.createMultiRoomIframe(nicks[i], iframeIndex, [roomId], 0);
                iframeIndex++;
            } else {
                iframeController.realTimeViewer.createMultiRoomExternalTab(nicks[i], externalTabIndex, [roomId], 0);
                externalTabIndex++;
            }
        }

        iframeController.realTimeViewer.openViewer();
        updateStatus(`✅ ${totalCount} ABAS MULTI-SALA CRIADAS!`);
        updateMultiRoomStatus();
    }

    async function playMultiRoomElements() {
        const readyElements = iframeController.realTimeViewer.getAllMultiRoomReadyElements();

        if (readyElements.length === 0) {
            alert('Nenhum elemento multi-sala está pronto! Aguarde o carregamento.');
            return;
        }

        updateStatus('⚡ INICIANDO MULTI-SALA...');
        window.updateSyncStatus(`Preparando ${readyElements.length} elementos multi-sala...`);

        try {
            await iframeController.prepareMultiRoomClicks(readyElements);
            const results = await iframeController.executeMultiRoomClicks();

            if (results > 0) {
                updateStatus(`🎉 ${results} ELEMENTOS MULTI-SALA ENTRARAM!`);
                window.updateSyncStatus('✅ SINCRONIZAÇÃO MULTI-SALA CONCLUÍDA!');
            } else {
                updateStatus('❌ FALHA NA SINCRONIZAÇÃO MULTI-SALA');
            }

        } catch (error) {
            console.error('💥 ERRO MULTI-SALA:', error);
            updateStatus('❌ Erro na sincronização multi-sala');
        }
    }

    function clearMultiRoomElements() {
        iframeController.realTimeViewer.closeAllMultiRoomElements();
        updateStatus('🧹 ELEMENTOS MULTI-SALA LIMPOS');
        updateMultiRoomStatus();
    }

    function updateMultiRoomStatus() {
        const iframeStatus = document.getElementById('multiRoomIframeStatus');
        const externalStatus = document.getElementById('multiRoomExternalStatus');

        if (iframeStatus) {
            const iframeCount = iframeController.realTimeViewer.multiRoomIframes.size;
            const readyIframes = Array.from(iframeController.realTimeViewer.multiRoomIframes.values())
                .filter(data => data.tabData.ready).length;
            iframeStatus.textContent = `Iframes: ${iframeCount} | Prontos: ${readyIframes}`;
        }

        if (externalStatus) {
            const externalCount = iframeController.realTimeViewer.multiRoomExternalTabs.size;
            const readyExternal = Array.from(iframeController.realTimeViewer.multiRoomExternalTabs.values())
                .filter(data => data.ready && !data.window.closed).length;
            externalStatus.textContent = `Abas: ${externalCount} | Prontas: ${readyExternal}`;
        }
    }

    function updateSelectedRoomsList() {
        const selectedRoomsList = document.getElementById('selectedRoomsList');
        if (!selectedRoomsList) return;

        const rooms = multiRoomManager.selectedRooms.length > 0 ? 
                     multiRoomManager.selectedRooms : 
                     randomRoomSelector.getSelectedRooms();

        if (rooms.length === 0) {
            selectedRoomsList.innerHTML = 'Nenhuma sala selecionada';
            selectedRoomsList.style.color = '#666';
        } else {
            selectedRoomsList.innerHTML = rooms.map(roomId =>
                `<span style="display:inline-block;background:#8A2BE2;color:white;padding:2px 6px;margin:1px;border-radius:3px;font-size:9px;">Sala ${roomId}</span>`
            ).join('');
            selectedRoomsList.style.color = '#333';
        }
    }

    // =============================================
    // FUNÇÕES EXISTENTES DO SISTEMA ORIGINAL
    // =============================================

    function createInterface() {
        if (document.getElementById('gartic-multi-menu')) return;

        const menu = document.createElement('div');
        menu.id = 'gartic-multi-menu';
        menu.style.cssText = `
            position: fixed;
            top: 20px;
            right: 20px;
            background: white;
            padding: 15px;
            border: 3px solid #8A2BE2;
            border-radius: 12px;
            z-index: 20000;
            width: 550px;
            max-width: 90vw;
            box-shadow: 0 6px 20px rgba(0,0,0,0.2);
            font-family: Arial, sans-serif;
            transition: all 0.3s ease;
        `;

        const menuContent = document.createElement('div');
        menuContent.id = 'menu-content';
        menuContent.innerHTML = `
            <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px;">
                <div>
                    <label style="font-size:11px;display:block;font-weight:bold;margin-bottom:3px;">Prefixo:</label>
                    <input type="text" id="nickPrefix" value="${nickPrefix}" style="width:100%;padding:6px;border:2px solid #8A2BE2;border-radius:5px;font-size:12px;">
                </div>
                <div>
                    <label style="font-size:11px;display:block;font-weight:bold;margin-bottom:3px;">Iframes:</label>
                    <input type="number" id="botCount" value="${botCount}" min="1" max="1000" style="width:100%;padding:6px;border:2px solid #8A2BE2;border-radius:5px;font-size:12px;">
                </div>
            </div>

            <!-- NOVO: BOTÃO PARA DESATIVAR NÚMEROS ALEATÓRIOS -->
            <div style="margin-bottom:12px;">
                <label style="font-size:11px;display:block;font-weight:bold;margin-bottom:3px;">
                    <input type="checkbox" id="disableRandomNumbers" ${disableRandomNumbers ? 'checked' : ''} style="margin-right:5px;">
                    Desativar números aleatórios no nick
                </label>
                <div style="font-size:9px;color:#666;margin-top:2px;">
                    ${disableRandomNumbers ? '✅ Nick será apenas o prefixo' : '✅ Nick será prefixo + 4 números aleatórios'}
                </div>
            </div>

            <!-- NOVA OPÇÃO: Filtrar apenas salas vazias -->
            <div style="margin-bottom:12px;">
                <label style="font-size:11px;display:block;font-weight:bold;margin-bottom:3px;">
                    <input type="checkbox" id="onlyEmptyRooms" ${onlyEmptyRooms ? 'checked' : ''} style="margin-right:5px;">
                    🔄 Mostrar apenas salas VAZIAS (com 0 pessoas)
                </label>
                <div style="font-size:9px;color:#666;margin-top:2px;">
                    ${onlyEmptyRooms ? '✅ Filtrando apenas salas vazias' : '⭕ Mostrando todas as salas'}
                </div>
            </div>

            <div style="display:grid;grid-template-columns:1fr 1fr;gap:10px;margin-bottom:12px;">
                <div>
                    <label style="font-size:11px;display:block;font-weight:bold;margin-bottom:3px;">
                        <input type="checkbox" id="useExternalTabs" ${useExternalTabs ? 'checked' : ''} style="margin-right:5px;">
                        Usar Abas Externas
                    </label>
                </div>
                <div>
                    <label style="font-size:11px;display:block;font-weight:bold;margin-bottom:3px;">Quant. Abas:</label>
                    <input type="number" id="externalTabCount" value="${externalTabCount}" min="0" max="1000" style="width:100%;padding:6px;border:2px solid #8B4513;border-radius:5px;font-size:12px;" ${!useExternalTabs ? 'disabled' : ''}>
                </div>
            </div>

            <!-- NOVO: SEÇÃO DE CONTROLES AVANÇADOS -->
            <div style="background:linear-gradient(135deg,#0066cc,#0099ff);padding:12px;border-radius:8px;margin-bottom:12px;border:2px solid #0066cc;">
                <h4 style="margin:0 0 10px 0;color:white;font-size:13px;text-align:center;">⚡ SISTEMA AVANÇADO PRO</h4>
                
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:8px;">
                    <button id="advancedSyncBtn" style="padding:8px;background:#FF6B00;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;font-weight:bold;">🎯 Sincronização Avançada</button>
                    <button id="testNetworkBtn" style="padding:8px;background:#2196F3;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;font-weight:bold;">🌐 Testar Rede</button>
                </div>
                
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;">
                    <button id="selectRandomRoomsBtn" style="padding:8px;background:#9C27B0;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;font-weight:bold;">🎲 Salas Aleatórias</button>
                    <button id="intelligentTabsBtn" style="padding:8px;background:#4CAF50;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;font-weight:bold;">🚀 Abas Inteligentes</button>
                </div>
            </div>

            <!-- NOVO: SISTEMA MULTI-SALA UNIFICADO -->
            <div style="background:linear-gradient(135deg,#FF6B00,#FFA500);padding:10px;border-radius:8px;margin-bottom:12px;">
                <h4 style="margin:0 0 8px 0;color:white;font-size:12px;text-align:center;">🎯 SISTEMA MULTI-SALA</h4>

                <!-- Contadores -->
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:8px;">
                    <div>
                        <label style="font-size:10px;display:block;font-weight:bold;margin-bottom:2px;color:white;">Iframes:</label>
                        <input type="number" id="multiRoomIframeCount" value="${configManager.get('multiRoomIframeCount') || 0}" min="0" max="1000" style="width:100%;padding:4px;border:1px solid white;border-radius:3px;font-size:11px;">
                    </div>
                    <div>
                        <label style="font-size:10px;display:block;font-weight:bold;margin-bottom:2px;color:white;">Abas Externas:</label>
                        <input type="number" id="multiRoomExternalCount" value="${configManager.get('multiRoomExternalCount') || 0}" min="0" max="1000" style="width:100%;padding:4px;border:1px solid white;border-radius:3px;font-size:11px;">
                    </div>
                </div>

                <!-- Botão único para criar abas -->
                <div style="display:grid;grid-template-columns:1fr;gap:6px;">
                    <button id="createMultiRoomTabsBtn" style="width:100%;padding:8px;background:white;color:#FF6B00;border:none;border-radius:4px;cursor:pointer;font-weight:bold;font-size:11px;">🚀 Criar Abas Multi-Sala</button>
                </div>

                <!-- Status -->
                <div style="display:grid;grid-template-columns:1fr 1fr;gap:5px;margin-top:5px;">
                    <div style="font-size:9px;color:white;text-align:center;">
                        <span id="multiRoomIframeStatus">Iframes: 0 | Prontos: 0</span>
                    </div>
                    <div style="font-size:9px;color:white;text-align:center;">
                        <span id="multiRoomExternalStatus">Abas: 0 | Prontas: 0</span>
                    </div>
                </div>
            </div>

            <!-- BOTÕES DE CONTROLE MULTI-SALA -->
            <div style="display:grid;grid-template-columns:1fr 1fr;gap:6px;margin-bottom:12px;">
                <button id="playMultiRoomBtn" style="padding:8px;background:#FF6B00;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;font-weight:bold;">⚡ Jogar MULTI-SALA</button>
                <button id="clearMultiRoomBtn" style="padding:8px;background:#f44336;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;font-weight:bold;">❌ Limpar MULTI-SALA</button>
            </div>

            <div style="margin-bottom:12px;">
                <label style="font-size:11px;display:block;font-weight:bold;margin-bottom:3px;">Pesquisar sala:</label>
                <input type="text" id="searchRoom" placeholder="Digite para filtrar..." style="width:100%;padding:6px;border:1px solid #ddd;border-radius:5px;font-size:12px;">
            </div>

            <div style="max-height:150px;overflow-y:auto;border:1px solid #ccc;margin-bottom:12px;border-radius:5px;background:#fafafa;">
                <div id="roomList" style="font-size:11px;"></div>
            </div>

            <!-- NOVO: SELEÇÃO DE MÚLTIPLAS SALAS -->
            <div style="margin-bottom:12px;">
                <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:5px;">
                    <label style="font-size:11px;font-weight:bold;">Salas Selecionadas:</label>
                    <div>
                        <button id="clearSelectedRoomsBtn" style="padding:3px 8px;background:#f44336;color:white;border:none;border-radius:3px;cursor:pointer;font-size:9px;margin-right:5px;">Limpar</button>
                        <button id="autoSelectRoomsBtn" style="padding:3px 8px;background:#9C27B0;color:white;border:none;border-radius:3px;cursor:pointer;font-size:9px;">Auto</button>
                    </div>
                </div>
                <div id="selectedRoomsList" style="font-size:10px;color:#666;min-height:20px;padding:5px;background:#f5f5f5;border-radius:3px;border:1px dashed #ccc;">
                    Nenhuma sala selecionada
                </div>
            </div>

            <div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:12px;">
                <button id="createIframesBtn" style="padding:10px;background:#2196F3;color:white;border:none;border-radius:6px;cursor:pointer;font-weight:bold;font-size:12px;">🪟 Criar Iframes/Abas</button>
                <button id="playAllBtn" style="padding:10px;background:#4CAF50;color:white;border:none;border-radius:6px;cursor:pointer;font-weight:bold;font-size:12px;">⚡ Jogar TODOS</button>
            </div>

            <div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:6px;margin-bottom:12px;">
                <button id="toggleViewerBtn" style="padding:8px;background:#9C27B0;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;">👁️ Mostrar/Ocultar</button>
                <button id="testSyncBtn" style="padding:8px;background:#FF9800;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;">🎯 Teste</button>
                <button id="closeAllBtn" style="padding:8px;background:#f44336;color:white;border:none;border-radius:5px;cursor:pointer;font-size:10px;">❌ Limpar Tudo</button>
            </div>

            <div style="background:linear-gradient(135deg,#667eea,#764ba2);padding:10px;border-radius:6px;margin-bottom:8px;">
                <div id="status" style="font-size:12px;text-align:center;font-weight:bold;color:white;">✅ SISTEMA MULTI-SALA ATIVADO</div>
                <div id="tabStatus" style="font-size:10px;color:#e0e0e0;text-align:center;margin-top:3px;">Iframes: 0 | Prontos: 0 | Abas: 0 | Prontas: 0</div>
                <div id="syncStatus" style="font-size:9px;color:#c8e6c9;text-align:center;margin-top:5px;"></div>
            </div>
        `;

        const menuHeader = document.createElement('div');
        menuHeader.style.cssText = `
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin: -15px -15px 15px -15px;
            padding: 10px 15px;
            background: #8A2BE2;
            color: white;
            border-radius: 8px 8px 0 0;
            cursor: move;
        `;
        menuHeader.innerHTML = `
            <h3 style="margin:0; font-size:16px;">🎯 GARTIC PRO v25.03 - CLIQUE 100% SINCRONIZADO</h3>
            <div>
                <button id="minimizeMenuBtn" style="background:#FF9800; color:white; border:none; border-radius:5px; padding:5px 10px; cursor:pointer; font-weight:bold; margin-right:5px;">−</button>
                <button id="closeMenuBtn" style="background:#ff4444; color:white; border:none; border-radius:5px; padding:5px 10px; cursor:pointer; font-weight:bold;">X</button>
            </div>
        `;

        menu.appendChild(menuHeader);
        menu.appendChild(menuContent);
        document.body.appendChild(menu);

        loadRooms();
        setupEvents();
        setupMenuDrag(menuHeader, menu);
        updateStatus('✅ SISTEMA PRO ATIVADO - CLIQUE 100% SINCRONIZADO');

        if (configManager.get('menuMinimized')) {
            toggleMenuMinimize();
        }
    }

    // =============================================
    // NOVO: FUNÇÕES AVANÇADAS
    // =============================================

    async function executeAdvancedSync(elements, roomId = null) {
        if (elements.length === 0) {
            updateStatus('❌ Nenhum elemento pronto para sincronização');
            return 0;
        }

        updateStatus('⚡ EXECUTANDO SINCRONIZAÇÃO AVANÇADA...');
        
        try {
            const successCount = await precisionSyncSystem.executeUltraPreciseSync(elements, roomId);
            
            if (successCount > 0) {
                updateStatus(`🎉 ${successCount}/${elements.length} ENTRARAM COM SUCESSO!`);
            } else {
                updateStatus('⚠️ Nenhum elemento conseguiu entrar');
            }
            
            return successCount;
        } catch (error) {
            console.error('❌ ERRO NA SINCRONIZAÇÃO AVANÇADA:', error);
            updateStatus('❌ Falha na sincronização avançada');
            return 0;
        }
    }

    function testNetworkSystem() {
        updateStatus('🔧 TESTANDO SISTEMA DE REDE...');
        
        const status = proNetworkController.checkNetworkStatus();
        const networkStatus = status.isBlocked ? 'BLOQUEADA' : 'ATIVA';
        
        setTimeout(async () => {
            const isWorking = await proNetworkController.testNetwork();
            updateStatus(`🌐 Rede: ${networkStatus} | Funcional: ${isWorking ? '✅' : '❌'}`);
        }, 1000);
    }

    function selectRandomRoomsUI() {
        const count = parseInt(prompt('Quantas salas deseja selecionar aleatoriamente?', '30')) || 0;
        if (count > 0) {
            const selected = randomRoomSelector.selectRandomRooms(count);
            
            multiRoomManager.selectedRooms = selected;
            configManager.set('selectedRooms', selected);
            
            updateStatus(`✅ ${selected.length} salas selecionadas aleatoriamente ${onlyEmptyRooms ? '(apenas vazias)' : ''}`);
            updateSelectedRoomsList();
            loadRooms(); // Recarregar para atualizar os checkboxes
        }
    }

    function createIntelligentTabs() {
        if (!multiRoomManager.hasRooms() && randomRoomSelector.getSelectedCount() === 0) {
            alert('Selecione salas primeiro ou use a seleção aleatória!');
            return;
        }

        const iframeCount = parseInt(document.getElementById('multiRoomIframeCount').value) || 0;
        const externalCount = parseInt(document.getElementById('multiRoomExternalCount').value) || 0;

        if (iframeCount === 0 && externalCount === 0) {
            alert('Configure pelo menos um dos contadores!');
            return;
        }

        updateStatus('🚀 CRIANDO ABAS COM DISTRIBUIÇÃO INTELIGENTE...');
        
        const totalTabs = iframeCount + externalCount;
        const nicks = generateNicks(totalTabs);
        
        const rooms = randomRoomSelector.getSelectedCount() > 0 ? 
                     randomRoomSelector.getSelectedRooms() : 
                     multiRoomManager.selectedRooms;
        
        if (rooms.length === 0) {
            updateStatus('❌ Nenhuma sala selecionada');
            return;
        }

        const distribution = randomRoomSelector.distributeTabsAmongRooms(totalTabs, 'balanced');
        
        for (let i = 0; i < distribution.length; i++) {
            const { roomId, tabIndex } = distribution[i];
            const nick = nicks[tabIndex];
            
            if (i < iframeCount) {
                iframeController.realTimeViewer.createMultiRoomIframe(nick, tabIndex, [roomId], 0);
            } else {
                iframeController.realTimeViewer.createMultiRoomExternalTab(nick, tabIndex, [roomId], 0);
            }
            
            if (i % 10 === 0 && i > 0) {
                setTimeout(() => {}, 50);
            }
        }

        iframeController.realTimeViewer.openViewer();
        updateStatus(`✅ ${totalTabs} abas criadas com distribuição inteligente!`);
    }

    // =============================================
    // ATUALIZAÇÃO DO SETUP DE EVENTOS (100% DO SCRIPT 2)
    // =============================================

    function setupEvents() {
        document.getElementById('nickPrefix').addEventListener('input', function(e) {
            nickPrefix = e.target.value || 'Player';
            configManager.set('nickPrefix', nickPrefix);
        });

        document.getElementById('botCount').addEventListener('input', function(e) {
            botCount = Math.max(1, Math.min(1000, parseInt(e.target.value) || 5));
            configManager.set('defaultTabCount', botCount);
        });

        document.getElementById('disableRandomNumbers').addEventListener('change', function(e) {
            disableRandomNumbers = e.target.checked;
            configManager.set('disableRandomNumbers', disableRandomNumbers);
            updateStatus(disableRandomNumbers ?
                '✅ Números aleatórios DESATIVADOS' :
                '✅ Números aleatórios ATIVADOS');
        });

        // NOVO: Evento para filtrar apenas salas vazias
        document.getElementById('onlyEmptyRooms').addEventListener('change', function(e) {
            onlyEmptyRooms = e.target.checked;
            configManager.set('onlyEmptyRooms', onlyEmptyRooms);
            updateStatus(onlyEmptyRooms ?
                '✅ Filtrando apenas salas VAZIAS (com 0 pessoas)' :
                '✅ Mostrando todas as salas');
            loadRooms(); // Recarregar a lista com o novo filtro
        });

        document.getElementById('useExternalTabs').addEventListener('change', function(e) {
            useExternalTabs = e.target.checked;
            configManager.set('useExternalTabs', useExternalTabs);
            const externalTabCountInput = document.getElementById('externalTabCount');
            externalTabCountInput.disabled = !useExternalTabs;
        });

        document.getElementById('externalTabCount').addEventListener('input', function(e) {
            externalTabCount = Math.max(0, Math.min(1000, parseInt(e.target.value) || 0));
            configManager.set('externalTabCount', externalTabCount);
        });

        // NOVO: Botões avançados
        document.getElementById('advancedSyncBtn').onclick = async function() {
            const readyElements = iframeController.realTimeViewer.getAllReadyElements();
            if (readyElements.length === 0) {
                alert('Nenhuma aba está pronta para sincronização!');
                return;
            }
            await executeAdvancedSync(readyElements, selectedRoom);
        };

        document.getElementById('testNetworkBtn').onclick = testNetworkSystem;
        document.getElementById('selectRandomRoomsBtn').onclick = selectRandomRoomsUI;
        document.getElementById('autoSelectRoomsBtn').onclick = selectRandomRoomsUI;
        document.getElementById('intelligentTabsBtn').onclick = createIntelligentTabs;

        // Eventos multi-sala
        document.getElementById('multiRoomIframeCount').addEventListener('input', function(e) {
            const value = Math.max(0, Math.min(1000, parseInt(e.target.value) || 0));
            configManager.set('multiRoomIframeCount', value);
        });

        document.getElementById('multiRoomExternalCount').addEventListener('input', function(e) {
            const value = Math.max(0, Math.min(1000, parseInt(e.target.value) || 0));
            configManager.set('multiRoomExternalCount', value);
        });

        document.getElementById('createMultiRoomTabsBtn').onclick = createMultiRoomTabs;
        document.getElementById('playMultiRoomBtn').onclick = playMultiRoomElements;
        document.getElementById('clearMultiRoomBtn').onclick = clearMultiRoomElements;
        document.getElementById('clearSelectedRoomsBtn').onclick = function() {
            multiRoomManager.clearRooms();
            randomRoomSelector.clearSelection();
            configManager.set('selectedRooms', []);
            updateSelectedRoomsList();
            loadRooms(); // Recarregar para atualizar os checkboxes
        };

        // Eventos existentes (100% DO SCRIPT 2)
        document.getElementById('searchRoom').addEventListener('input', function(e) {
            filterRooms(e.target.value.toLowerCase());
        });

        document.getElementById('createIframesBtn').onclick = createIframesAndTabs;
        
        // CORREÇÃO CRÍTICA: Alterado para usar o sistema de vagas (100% do Script 2)
        document.getElementById('playAllBtn').onclick = playAllElements;
        
        document.getElementById('toggleViewerBtn').onclick = toggleViewer;
        document.getElementById('testSyncBtn').onclick = testSync;
        document.getElementById('closeAllBtn').onclick = closeAll;

        document.getElementById('minimizeMenuBtn').onclick = toggleMenuMinimize;
        document.getElementById('closeMenuBtn').onclick = closeMenu;
    }

    // =============================================
    // FUNÇÕES EXISTENTES MANTIDAS
    // =============================================

    function createIframesAndTabs() {
        if (!selectedRoom) {
            alert('Selecione uma sala primeiro!');
            return;
        }

        closeAll();

        const totalElements = botCount + (useExternalTabs ? externalTabCount : 0);
        if (totalElements === 0) {
            alert('Configure pelo menos 1 iframe ou aba externa!');
            return;
        }

        updateStatus('🚀 CRIANDO IFRAMES E ABAS...');
        const nicks = generateNicks(totalElements);

        let nickIndex = 0;

        for (let i = 0; i < botCount; i++) {
            iframeController.realTimeViewer.createDirectIframe(nicks[nickIndex], nickIndex, selectedRoom);
            nickIndex++;
        }

        if (useExternalTabs && externalTabCount > 0) {
            for (let i = 0; i < externalTabCount; i++) {
                iframeController.realTimeViewer.createExternalTab(nicks[nickIndex], nickIndex, selectedRoom);
                nickIndex++;
            }
        }

        iframeController.realTimeViewer.openViewer();

        updateStatus(`✅ ${totalElements} ELEMENTOS CRIADOS!`);
        updateTabStatus();
    }

    // CORREÇÃO CRÍTICA: Função playAllElements 100% do Script 2
    async function playAllElements() {
        const readyElements = iframeController.realTimeViewer.getAllReadyElements();

        if (readyElements.length === 0) {
            alert('Nenhum elemento está pronto! Aguarde o carregamento.');
            return;
        }

        if (!selectedRoom) {
            alert('Selecione uma sala primeiro!');
            return;
        }

        updateStatus('🔍 VERIFICANDO VAGAS...');
        window.updateSyncStatus(`Preparando ${readyElements.length} elementos...`);

        try {
            await iframeController.prepareAllClicks(readyElements);
            const results = await iframeController.executeAllClicksWithVacancyCheck(selectedRoom);

            if (results > 0) {
                updateStatus(`🎉 ${results} ELEMENTOS ENTRARAM NA SALA!`);
                window.updateSyncStatus('✅ SINCRONIZAÇÃO CONCLUÍDA!');

                if (results < readyElements.length) {
                    setTimeout(() => {
                        updateStatus(`⚠️ ${results}/${readyElements.length} entraram`);
                    }, 2000);
                }
            } else {
                updateStatus('❌ FALHA NA SINCRONIZAÇÃO');
                window.updateSyncStatus('💡 Tente novamente');
            }

        } catch (error) {
            console.error('💥 ERRO:', error);
            updateStatus('❌ Erro na sincronização');
        }
    }

    function toggleViewer() {
        if (iframeController.realTimeViewer.isVisible) {
            iframeController.realTimeViewer.closeViewer();
        } else {
            iframeController.realTimeViewer.openViewer();
        }
    }

    function testSync() {
        updateStatus('🧪 TESTANDO SISTEMA...');
        window.updateSyncStatus('🔧 Verificando sincronização...');

        setTimeout(() => {
            updateStatus('✅ SISTEMA OPERACIONAL');
            window.updateSyncStatus('⚡ Pronto para uso');
        }, 2000);
    }

    function closeAll() {
        iframeController.networkController.restoreNetwork();
        iframeController.stopVacancyCheck();
        iframeController.realTimeViewer.clearViewer();
        updateStatus('🔄 SISTEMA REINICIADO');
        window.updateSyncStatus('');
        updateTabStatus();
        updateMultiRoomStatus();
    }

    function toggleMenuMinimize() {
        const menuContent = document.getElementById('menu-content');
        const menu = document.getElementById('gartic-multi-menu');
        const isMinimized = menuContent.style.display === 'none';

        if (isMinimized) {
            menuContent.style.display = 'block';
            menu.style.height = 'auto';
            menu.style.width = '550px';
            configManager.set('menuMinimized', false);
        } else {
            menuContent.style.display = 'none';
            menu.style.height = 'auto';
            menu.style.width = '250px';
            configManager.set('menuMinimized', true);
        }
    }

    function closeMenu() {
        const menu = document.getElementById('gartic-multi-menu');
        if (menu) {
            menu.style.display = 'none';
        }
    }

    function setupMenuDrag(header, element) {
        let pos1 = 0, pos2 = 0, pos3 = 0, pos4 = 0;

        header.onmousedown = dragMouseDown;

        function dragMouseDown(e) {
            e = e || window.event;
            e.preventDefault();
            pos3 = e.clientX;
            pos4 = e.clientY;
            document.onmouseup = closeDragElement;
            document.onmousemove = elementDrag;
        }

        function elementDrag(e) {
            e = e || window.event;
            e.preventDefault();
            pos1 = pos3 - e.clientX;
            pos2 = pos4 - e.clientY;
            pos3 = e.clientX;
            pos4 = e.clientY;
            element.style.top = (element.offsetTop - pos2) + "px";
            element.style.left = (element.offsetLeft - pos1) + "px";
        }

        function closeDragElement() {
            document.onmouseup = null;
            document.onmousemove = null;
        }
    }

    // =============================================
    // INICIALIZAÇÃO AVANÇADAS
    // =============================================

    function initializeAdvancedSystems() {
        console.log('🚀 INICIALIZANDO SISTEMAS AVANÇADOS...');
        
        iframeController.realTimeViewer.maxIframes = configManager.get('maxTabLimit');
        iframeController.realTimeViewer.maxMultiRoomIframes = configManager.get('maxTabLimit');
        
        precisionSyncSystem.resetSyncData();
        
        setTimeout(() => {
            proNetworkController.testNetwork().then(isWorking => {
                console.log(`🌐 Conexão inicial: ${isWorking ? '✅' : '⚠️'}`);
            });
        }, 2000);
        
        console.log('✅ SISTEMAS AVANÇADOS INICIALIZADOS');
    }

    // =============================================
    // INICIALIZAÇÃO PRINCIPAL
    // =============================================

    setInterval(updateMultiRoomStatus, 2000);
    setInterval(loadRooms, 10000);
    setInterval(updateTabStatus, 2000);

    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', function() {
            setTimeout(createInterface, 500);
            setTimeout(initializeAdvancedSystems, 1000);
        });
    } else {
        setTimeout(createInterface, 1000);
        setTimeout(initializeAdvancedSystems, 1500);
    }

    setTimeout(() => {
        const menu = document.getElementById('gartic-multi-menu');
        if (!menu) {
            createInterface();
            initializeAdvancedSystems();
        }
    }, 3000);

})();