SLITHER.IO STANDALONE CHAT MOD (NOW TALK WITH SLITHER GAMERS!)

Adds the 143X chat with a redesigned, professional settings panel and all previous features.

Versión del día 19/7/2025. Echa un vistazo a la versión más reciente.

Tendrás que instalar una extensión para tu navegador como Tampermonkey, Greasemonkey o Violentmonkey si quieres utilizar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Violentmonkey para instalar este script.

Necesitarás instalar una extensión como Tampermonkey o Userscripts para instalar este script.

Necesitará instalar una extensión como Tampermonkey para instalar este script.

Necesitarás instalar una extensión para administrar scripts de usuario si quieres instalar este script.

(Ya tengo un administrador de scripts de usuario, déjame instalarlo)

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión como Stylus para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

Necesitará instalar una extensión del gestor de estilos de usuario para instalar este estilo.

(Ya tengo un administrador de estilos de usuario, déjame instalarlo)

// ==UserScript==
// @name         SLITHER.IO STANDALONE CHAT MOD (NOW TALK WITH SLITHER GAMERS!)
// @namespace    http://tampermonkey.net/
// @version      11.0
// @description  Adds the 143X chat with a redesigned, professional settings panel and all previous features.
// @author       dxxthly & waynesg
// @match        http://slither.io/
// @match        https://slither.io/
// @match        http://slither.com/io
// @match        https://slither.com/io
// @grant        none
// @icon         https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcQUNcRl2Rh40pZLhgffYGFDRLbYJ4qfMNwddQ&s
// ==/UserScript==

(function() {
    'use strict';

    let hasInitialized = false;

    const initChecker = setInterval(() => {
        if (document.getElementById('login') && !hasInitialized) {
            hasInitialized = true;
            clearInterval(initChecker);
            main();
        }
    }, 100);

    function main() {
        let isChatVisible = true;

        const config = {
            giphyApiKey: 'xWBhUx8jBtCxxjPHvtUzHLZlPGYBUTFq',
            chatMaxMessages: 75,
            firebaseConfig: { apiKey: "AIzaSyCtTloqGNdhmI3Xt0ta11vF0MQJHiKpO7Q", authDomain: "chatforslither.firebaseapp.com", databaseURL: "https://chatforslither-default-rtdb.firebaseio.com", projectId: "chatforslither", storageBucket: "chatforslither.appspot.com", messagingSenderId: "1045559625491", appId: "1:1045559625491:web:79eb8200eb87edac00bce6" },
            devList: [{ uid: "CiOpgh1RLBg3l5oXn0SAho66Po93" }, { uid: "PZA5qgKWsPTXc278pyx7NwROf313" }, { uid: "P75eMwh756Rb6h1W6iqQfHN2Dm92" }],
            vipMembers: [{ uid: "crcOY9hoRrfayStCxMVm7Zdx2W92", name: "stevao" }, { uid: "DhGhICAZwkRa7wuMsyquM9a5uO92", name: "LUANBLAYNER" }]
        };

        const style = document.createElement('style');
        style.textContent = `
            #chat-container { position: fixed; left: 20px; top: 100px; width: 380px; height: 400px; z-index: 9999; display: flex; flex-direction: column; background: rgba(28, 28, 32, 0.97); border: 1px solid #4CAF50; border-radius: 8px; box-shadow: 0 5px 20px rgba(0,0,0,0.3); overflow: hidden; user-select: none; resize: both; min-width: 320px; min-height: 250px; }
            #chat-header { display: flex; align-items: center; border-bottom: 1px solid #4CAF50; background: rgba(0,0,0,0.2); cursor: move; }
            .chat-tab { flex: 1; padding: 10px 12px; text-align: center; cursor: pointer; font-weight: 500; transition: background 0.2s, color 0.2s; }
            #chat-tab-main { background: rgba(76, 175, 80, 0.25); color: #fff; } #chat-tab-users { background: transparent; color: #ccc; }
            #chat-settings-btn, #chat-hide-btn { background: none; border: none; color: #ccc; font-size: 20px; padding: 0 12px; cursor: pointer; transition: color 0.2s; border-left: 1px solid rgba(255,255,255,0.1); }
            #chat-settings-btn:hover, #chat-hide-btn:hover { color: white; }
            #chat-area { flex: 1; display: flex; flex-direction: column; overflow: hidden; position: relative; }
            #chat-body, #online-users { flex: 1; padding: 10px 15px; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; scrollbar-width: thin; scrollbar-color: #4CAF50 rgba(0,0,0,0.2); }
            #online-users { display: none; gap: 0; }
            #chat-input-container { display: flex; align-items: center; border-top: 1px solid #4CAF50; background-color: #1c1c20; }
            #chat-input { flex-grow: 1; padding: 12px 15px; border: none; background: transparent; color: #e0e0e0; outline: none; font-size: 14px; }
            .chat-action-btn { background: transparent; border: none; border-left: 1px solid #333; color: #aaa; font-size: 14px; cursor: pointer; padding: 0 12px; font-weight: bold; }
            .chat-action-btn:hover { background: #333; color: #fff; }
            .chat-message { line-height: 1.5; word-break: break-word; background: rgba(255,255,255,0.04); padding: 8px 12px; border-radius: 6px; color: #e0e0e0; }
            .chat-message a { color: #3498db; text-decoration: none; font-weight: bold; } .chat-message a:hover { text-decoration: underline; }
            .chat-image-preview { max-width: 90%; max-height: 180px; border-radius: 6px; margin-top: 8px; cursor: pointer; border: 1px solid #444; }
            .chat-username { font-weight: bold; cursor: pointer; text-decoration: underline dotted; }
            .chat-modal-overlay { display: none; position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; z-index: 10001; background: rgba(0,0,0,0.8); align-items: center; justify-content: center; backdrop-filter: blur(4px); }
            .chat-modal-content { background: #2E2E34; border-radius: 12px; padding: 0; width: 480px; display: flex; flex-direction: column; border: 1px solid #555; box-shadow: 0 8px 30px rgba(0,0,0,0.4); }
            .chat-modal-content h2 { margin: 0; padding: 15px 20px; font-size: 1.4em; color: #4CAF50; text-align: center; background-color: rgba(0,0,0,0.2); border-bottom: 1px solid #444; }
            .settings-grid { padding: 25px; display: grid; grid-template-columns: 1fr 1fr; gap: 20px; }
            .settings-field { display: flex; flex-direction: column; gap: 8px; }
            .settings-field label { color: #bbb; font-size: 0.9em; font-weight: bold; }
            .settings-field input[type="text"] { width: 100%; box-sizing: border-box; padding: 10px; background: #222; border: 1px solid #555; border-radius: 5px; color: #eee; font-size: 1em; transition: border-color 0.2s, box-shadow 0.2s; }
            .settings-field input[type="text"]:focus { outline: none; border-color: #4CAF50; box-shadow: 0 0 0 2px rgba(76, 175, 80, 0.3); }
            .color-input-wrapper { display: flex; align-items: center; gap: 10px; }
            #settings-name-color { width: 40px; height: 40px; border: 1px solid #555; border-radius: 5px; background: none; cursor: pointer; padding: 0; }
            #settings-name-color-hex { flex-grow: 1; }
            #avatar-preview { width: 64px; height: 64px; border-radius: 50%; background-color: #222; background-size: cover; background-position: center; border: 2px solid #555; }
            .modal-buttons { display: flex; justify-content: flex-end; gap: 10px; padding: 15px 25px; background-color: rgba(0,0,0,0.2); border-top: 1px solid #444; }
            .modal-btn { padding: 9px 20px; border: none; border-radius: 5px; font-size: 0.95em; cursor: pointer; font-weight: bold; }
            #settings-save-btn { background: #4CAF50; color: #fff; } #settings-cancel-btn { background: #555; color: #fff; }
            #get-full-mod-btn { background-color: #333; color: #4CAF50; border: 1px solid #4CAF50; border-radius: 5px; padding: 8px; margin-top: 10px; cursor: pointer; transition: background-color 0.2s; } #get-full-mod-btn:hover { background-color: #444; }
            #show-chat-button { display: none; position: fixed; bottom: 20px; left: 20px; z-index: 9998; width: 50px; height: 50px; background-color: #2E2E34; color: #fff; border: 1px solid #4CAF50; border-radius: 50%; font-size: 24px; cursor: pointer; text-align: center; line-height: 50px; box-shadow: 0 4px 15px rgba(0,0,0,0.4); transition: transform 0.2s; } #show-chat-button:hover { transform: scale(1.1); }
            #gif-picker-modal { display: none; position: absolute; bottom: 50px; right: 10px; width: 320px; height: 350px; background: #2E2E34; border: 1px solid #4CAF50; border-radius: 8px; box-shadow: 0 5px 20px rgba(0,0,0,0.4); z-index: 10002; flex-direction: column; overflow: hidden; }
            #gif-picker-header { padding: 8px; border-bottom: 1px solid #444; } #gif-search-input { width: 100%; box-sizing: border-box; background: #222; border: 1px solid #555; color: #eee; border-radius: 4px; padding: 6px 8px; outline: none; }
            #gif-results-container { flex-grow: 1; overflow-y: auto; padding: 8px; display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; }
            #gif-results-container img { width: 100%; height: 120px; object-fit: cover; cursor: pointer; border-radius: 4px; border: 2px solid transparent; } #gif-results-container img:hover { border-color: #4CAF50; }
            .profile-popup { position: fixed; z-index: 10002; display: flex; flex-direction: column; align-items: center; left: 50%; top: 50%; transform: translate(-50%, -50%); min-width: 280px; background: #2A2A2F; color: #e0e0e0; border-radius: 12px; border: 1px solid #4CAF50; box-shadow: 0 8px 32px rgba(0,0,0,0.35); padding: 24px 30px; }
            .profile-popup .avatar { width: 72px; height: 72px; border-radius: 50%; object-fit: cover; border: 3px solid #4CAF50; margin-bottom: 16px; }
            .profile-popup .close-btn { position: absolute; top: 12px; right: 12px; background: none; border: none; color: #aaa; font-size: 1.6em; cursor: pointer; }
        `;
        document.head.appendChild(style);

        const escapeHTML = (str) => { const p = document.createElement('p'); p.appendChild(document.createTextNode(str)); return p.innerHTML; };
        const isDev = (uid) => config.devList.some(dev => dev.uid === uid);
        const isVip = (uid, name) => config.vipMembers.some(vip => vip.uid === uid && vip.name.toLowerCase() === (name || '').toLowerCase());
        const rainbowTextStyle = (name) => name.split('').map((char, i) => `<span style="color:${["#ef3550","#f48fb1","#7e57c2","#2196f3","#26c6da","#43a047","#eeff41","#f9a825","#ff5722"][i % 9]}; font-weight: bold;">${char}</span>`).join('');
        const vipGlowStyle = (name, color) => `<span style="color:#fff;font-weight:bold;text-shadow:0 0 5px #fff, 0 0 10px ${color}, 0 0 15px ${color};">${name}</span>`;

        const chatContainer = document.createElement('div'); chatContainer.id = 'chat-container';
        chatContainer.innerHTML = `<div id="chat-header"><div id="chat-tab-main" class="chat-tab">143X Chat</div><div id="chat-tab-users" class="chat-tab">Online Users</div><button id="chat-settings-btn" title="Settings">⚙️</button><button id="chat-hide-btn" title="Minimize Chat (Key: C)">×</button></div><div id="chat-area"><div id="chat-body"><p style="color:#888;text-align:center;">Initializing...</p></div><div id="online-users"></div><div id="chat-input-container"><input id="chat-input" type="text" placeholder="Connecting..." disabled><button id="gif-btn" class="chat-action-btn">GIF</button></div></div>`;
        document.body.appendChild(chatContainer);
        makeDraggable(chatContainer, document.getElementById('chat-header'));

        const settingsModal = document.createElement('div'); settingsModal.id = 'settings-modal-overlay'; settingsModal.className = 'chat-modal-overlay';
        settingsModal.innerHTML = `
            <div id="settings-modal" class="chat-modal-content">
                <h2>Chat & Profile Settings</h2>
                <div class="settings-grid">
                    <div class="settings-field">
                        <label for="settings-nickname">Nickname</label>
                        <input type="text" id="settings-nickname" maxlength="20">
                    </div>
                    <div class="settings-field">
                        <label>Chat Name Color</label>
                        <div class="color-input-wrapper">
                           <input type="color" id="settings-name-color">
                           <input type="text" id="settings-name-color-hex" maxlength="7">
                        </div>
                    </div>
                    <div class="settings-field" style="grid-column: 1 / -1;">
                        <label for="settings-avatar">Profile Avatar URL</label>
                        <div style="display: flex; align-items: center; gap: 15px;">
                            <input type="text" id="settings-avatar" style="flex-grow: 1;">
                            <div id="avatar-preview"></div>
                        </div>
                    </div>
                    <div class="settings-field" style="grid-column: 1 / -1;">
                        <label for="settings-motto">Profile Motto</label>
                        <input type="text" id="settings-motto" maxlength="60">
                    </div>
                </div>
                <div class="modal-buttons">
                    <button id="settings-cancel-btn" class="modal-btn">Cancel</button>
                    <button id="settings-save-btn" class="modal-btn">Save</button>
                </div>
            </div>`;
        document.body.appendChild(settingsModal);

        const promoModal = document.createElement('div'); promoModal.id = 'promo-modal-overlay'; promoModal.className = 'chat-modal-overlay';
        promoModal.innerHTML = `<div class="chat-modal-content" style="text-align:center;width:400px;"><h2>Want the Full Mod?</h2><p>Get features like Zoom, AFK Bot, Neon Line, Auto Boost, and more!</p><p>Visit <a href="https://dsc.gg/143x" target="_blank">DSC.GG/143X</a> to download the full mod today!</p><div class="modal-buttons" style="justify-content: center;"><button id="promo-okay-btn" class="modal-btn">Okay</button></div></div>`;
        document.body.appendChild(promoModal);
        const gifPickerModal = document.createElement('div'); gifPickerModal.id = 'gif-picker-modal';
        gifPickerModal.innerHTML = `<div id="gif-picker-header"><input type="text" id="gif-search-input" placeholder="Search GIPHY..."></div><div id="gif-results-container"></div>`;
        document.getElementById('chat-area').appendChild(gifPickerModal);
        const showChatButton = document.createElement('div'); showChatButton.id = 'show-chat-button'; showChatButton.title = "Show Chat (Key: C)"; showChatButton.innerHTML = '💬';
        document.body.appendChild(showChatButton);

        function toggleChatVisibility() { isChatVisible = !isChatVisible; chatContainer.style.display = isChatVisible ? 'flex' : 'none'; showChatButton.style.display = isChatVisible ? 'none' : 'block'; }
        
        function loadFirebaseAndInit(){const s1=document.createElement('script');s1.src='https://www.gstatic.com/firebasejs/8.10.0/firebase-app.js';s1.onload=()=>{const s2=document.createElement('script');s2.src='https://www.gstatic.com/firebasejs/8.10.0/firebase-database.js';s2.onload=()=>{const s3=document.createElement('script');s3.src='https://www.gstatic.com/firebasejs/8.10.0/firebase-auth.js';s3.onload=()=>initializeChat(window.firebase);document.head.appendChild(s3);};document.head.appendChild(s2);};document.head.appendChild(s1);}
        function initializeChat(firebase){if(!firebase.apps.length)firebase.initializeApp(config.firebaseConfig);const auth=firebase.auth();const db=firebase.database();auth.signInAnonymously().then(()=>{auth.onAuthStateChanged(user=>{if(user){const ci=document.getElementById('chat-input');ci.disabled=false;ci.placeholder='Type and press Enter...';document.getElementById('chat-body').innerHTML='';let n=localStorage.getItem("slitherChatNickname");if(!n){n=prompt("Welcome! Please enter a nickname:","Player")||"Anon";localStorage.setItem("slitherChatNickname",n);}const ur=db.ref("onlineUsers/"+user.uid);ur.onDisconnect().remove();const ld={name:n,chatNameColor:localStorage.getItem("slitherChatNameColor")||"#FFD700",profileAvatar:localStorage.getItem("slitherChatAvatar")||"",profileMotto:localStorage.getItem("slitherChatMotto")||""};ur.update({...ld,uid:user.uid,lastActive:firebase.database.ServerValue.TIMESTAMP});setInterval(()=>ur.update({lastActive:Date.now()}),45000);listenForMessages(db,user.uid);listenForOnlineUsers(db,user.uid);setupEventListeners(db,user.uid);}})}).catch(err=>console.error("Firebase Sign-In Error:",err));}
        function listenForMessages(db,currentUid){const cb=document.getElementById('chat-body');db.ref("slitherChat").orderByChild("time").limitToLast(config.chatMaxMessages).on("child_added",snap=>{try{if(cb.children.length>=config.chatMaxMessages)cb.removeChild(cb.firstChild);renderChatMessage(snap.val(),cb,currentUid,true);}catch(e){console.error("Failed to render message:",e,snap.val());}});}

        function renderChatMessage(msg,container,currentUid,shouldScroll){
            if(!msg||typeof msg.text!=='string')return;
            const uc=msg.chatNameColor||'#FFD700';const idb=msg.uid==='discord_bot';
            let dn=escapeHTML(msg.name||'Anon');if(idb)dn=escapeHTML((dn.match(/^Discord\((.*)\)$/)||['','User'])[1]);
            let nh,rt='';
            if(idb){rt=` <span style="background:#7289DA;color:#fff;padding:1px 5px;border-radius:3px;font-size:0.8em;">DISCORD</span>`;nh=`<span class="chat-username" data-uid="${msg.uid}" style="color:${uc}">${dn}</span>`;}
            else if(isDev(msg.uid)){rt=` <span style="background:#E91E63;color:#fff;padding:1px 5px;border-radius:3px;font-size:0.8em;">DEV</span>`;nh=`<span class="chat-username" data-uid="${msg.uid}">${rainbowTextStyle(dn)}</span>`;}
            else if(isVip(msg.uid,msg.name)){rt=` <span style="background:#9C27B0;color:#fff;padding:1px 5px;border-radius:3px;font-size:0.8em;">VIP</span>`;nh=`<span class="chat-username" data-uid="${msg.uid}">${vipGlowStyle(dn,uc)}</span>`;}
            else{nh=`<span class="chat-username" data-uid="${msg.uid}" style="color:${uc}">${dn}</span>`;}
            let messageContent = '';
            const imageRegex = /(https?:\/\/[^\s]+\.(?:png|jpg|jpeg|gif|webp))/i;
            const linkRegex = /(https?:\/\/[^\s]+)/gi;
            if (imageRegex.test(msg.text)) {
                const imageUrl = msg.text.match(imageRegex)[0];
                messageContent = `<img src="${imageUrl}" class="chat-image-preview" onclick="window.open('${imageUrl}', '_blank')">`;
            } else {
                let sanitizedText = escapeHTML(msg.text);
                sanitizedText = sanitizedText.replace(linkRegex, '<a href="https://dsc.gg/143x" target="_blank">dsc.gg/143x</a>');
                sanitizedText = sanitizedText.replace(/<b>/g, '<b>').replace(/<\/b>/g, '</b>');
                messageContent = sanitizedText;
            }
            const el=document.createElement('div');el.className='chat-message';if(msg.uid===currentUid)el.style.background='rgba(76,175,80,0.1)';
            el.innerHTML=`<b>${nh}${rt}:</b> ${messageContent}`;container.appendChild(el);
            if(shouldScroll)container.scrollTop=container.scrollHeight;
        }

        function listenForOnlineUsers(db,currentUid){const oue=document.getElementById('online-users');db.ref("onlineUsers").on("value",snap=>{const users=snap.val()||{};const au=Object.values(users).filter(u=>Date.now()-(u.lastActive||0)<300000);let ulh=au.map(user=>{let dn=escapeHTML(user.name||'Anon');if(isDev(user.uid))dn=rainbowTextStyle(dn);const st=user.uid===currentUid?' (You)':'';return `<div style="padding:5px 2px;border-bottom:1px solid rgba(255,255,255,0.08);"><span style="color:lime;">●</span> <span class="chat-username" data-uid="${user.uid}" style="color:${user.chatNameColor||'#FFD700'}">${dn}</span><span style="color:#8f8;font-size:0.9em;">${st}</span></div>`;}).join('');ulh+=`<button id="get-full-mod-btn">Get Full Mod</button>`;oue.innerHTML=ulh||`<p style="text-align:center;color:#888;">No users online.</p><button id="get-full-mod-btn">Get Full Mod</button>`;});}
        async function showUserProfile(db,uid){document.querySelector('.profile-popup')?.remove();try{const us=await db.ref("onlineUsers/"+uid).once('value');if(!us.exists())return;const d=us.val();const p=document.createElement('div');p.className='profile-popup';p.innerHTML=`<button class="close-btn" onclick="this.parentElement.remove();">×</button><img class="avatar" src="${d.profileAvatar||`https://api.dicebear.com/7.x/identicon/svg?seed=${uid}`}" onerror="this.src='https://api.dicebear.com/7.x/identicon/svg?seed=${uid}'" style="border-color:${d.chatNameColor||'#FFD700'}"><h3 style="margin:0;">${d.name}</h3><p style="font-style:italic;color:#ccc;margin-top:10px;">${d.profileMotto||'No motto.'}</p>`;document.body.appendChild(p);}catch(err){console.error("Error fetching profile:",err);}}
        function makeDraggable(el,handle){let p1=0,p2=0,p3=0,p4=0;handle.onmousedown=(e)=>{e.preventDefault();p3=e.clientX;p4=e.clientY;document.onmouseup=()=>{document.onmouseup=null;document.onmousemove=null;};document.onmousemove=(e)=>{e.preventDefault();p1=p3-e.clientX;p2=p4-e.clientY;p3=e.clientX;p4=e.clientY;el.style.top=(el.offsetTop-p2)+"px";el.style.left=(el.offsetLeft-p1)+"px";};};}
        async function openGifPicker(){const picker=document.getElementById('gif-picker-modal');const results=document.getElementById('gif-results-container');picker.style.display='flex';results.innerHTML='Loading...';try{const res=await fetch(`https://api.giphy.com/v1/gifs/trending?api_key=${config.giphyApiKey}&limit=20&rating=pg-13`);const json=await res.json();displayGifs(json.data);}catch(e){results.innerHTML='Could not load GIFs.';}}
        async function searchGifs(){const query=document.getElementById('gif-search-input').value.trim();const results=document.getElementById('gif-results-container');if(!query)return;results.innerHTML=`Searching...`;try{const res=await fetch(`https://api.giphy.com/v1/gifs/search?api_key=${config.giphyApiKey}&q=${encodeURIComponent(query)}&limit=30&rating=pg-13`);const json=await res.json();displayGifs(json.data);}catch(e){results.innerHTML='Search failed.';}}
        function displayGifs(data){const results=document.getElementById('gif-results-container');results.innerHTML='';if(!data||data.length===0){results.innerHTML='No results.';return;}data.forEach(gif=>{const img=document.createElement('img');img.src=gif.images.fixed_height_small.url;img.dataset.fullUrl=gif.images.original.url;img.alt=gif.title;results.appendChild(img);});}
        function sendGifToChat(db,uid,url){const name=localStorage.getItem("slitherChatNickname");const color=localStorage.getItem("slitherChatNameColor")||"#FFD700";const payload={uid,name,text:url,time:firebase.database.ServerValue.TIMESTAMP,chatNameColor:color};db.ref("slitherChat").push(payload);db.ref("discordBridge").push(payload);document.getElementById('gif-picker-modal').style.display='none';}

        function setupEventListeners(db, uid) {
            document.getElementById('chat-tab-main').addEventListener('click', () => { document.getElementById('chat-body').style.display = 'flex'; document.getElementById('online-users').style.display = 'none'; document.getElementById('chat-tab-main').style.background = 'rgba(76, 175, 80, 0.25)'; document.getElementById('chat-tab-users').style.background = 'transparent'; });
            document.getElementById('chat-tab-users').addEventListener('click', () => { document.getElementById('chat-body').style.display = 'none'; document.getElementById('online-users').style.display = 'flex'; document.getElementById('chat-tab-users').style.background = 'rgba(76, 175, 80, 0.25)'; document.getElementById('chat-tab-main').style.background = 'transparent'; });
            document.getElementById('chat-input').addEventListener('keydown', (e) => { if (e.key === 'Enter') { e.preventDefault(); e.stopPropagation(); const text = e.target.value.trim(); if (text) { const payload = { uid, name: localStorage.getItem("slitherChatNickname"), text, time: firebase.database.ServerValue.TIMESTAMP, chatNameColor: localStorage.getItem("slitherChatNameColor") || "#FFD700" }; db.ref("slitherChat").push(payload); db.ref("discordBridge").push(payload); e.target.value = ''; } } });
            const settingsOverlay = document.getElementById('settings-modal-overlay');
            const avatarPreview = document.getElementById('avatar-preview');
            const avatarInput = document.getElementById('settings-avatar');
            avatarInput.addEventListener('input', () => { avatarPreview.style.backgroundImage = `url(${avatarInput.value})`; });
            document.getElementById('chat-settings-btn').addEventListener('click', () => { document.getElementById('settings-nickname').value = localStorage.getItem("slitherChatNickname") || ''; document.getElementById('settings-name-color').value = document.getElementById('settings-name-color-hex').value = localStorage.getItem("slitherChatNameColor") || '#FFD700'; avatarInput.value = localStorage.getItem("slitherChatAvatar") || ''; avatarPreview.style.backgroundImage = `url(${avatarInput.value})`; document.getElementById('settings-motto').value = localStorage.getItem("slitherChatMotto") || ''; settingsOverlay.style.display = 'flex'; });
            document.getElementById('settings-cancel-btn').addEventListener('click', () => settingsOverlay.style.display = 'none');
            const cPicker = document.getElementById('settings-name-color'), hInput = document.getElementById('settings-name-color-hex');
            cPicker.addEventListener('input', () => hInput.value = cPicker.value); hInput.addEventListener('input', () => { if (/^#[0-9A-F]{6}$/i.test(hInput.value)) cPicker.value = hInput.value; });
            document.getElementById('settings-save-btn').addEventListener('click', () => { const newData = { name: document.getElementById('settings-nickname').value.trim().slice(0, 20) || 'Anon', chatNameColor: cPicker.value, profileAvatar: document.getElementById('settings-avatar').value.trim(), profileMotto: document.getElementById('settings-motto').value.trim() }; localStorage.setItem("slitherChatNickname", newData.name); localStorage.setItem("slitherChatNameColor", newData.chatNameColor); localStorage.setItem("slitherChatAvatar", newData.profileAvatar); localStorage.setItem("slitherChatMotto", newData.profileMotto); db.ref("onlineUsers/" + uid).update(newData); settingsOverlay.style.display = 'none'; });
            document.getElementById('promo-okay-btn').addEventListener('click', () => document.getElementById('promo-modal-overlay').style.display = 'none');
            document.getElementById('chat-hide-btn').addEventListener('click', toggleChatVisibility);
            showChatButton.addEventListener('click', toggleChatVisibility);
            document.getElementById('gif-btn').addEventListener('click', (e) => { e.stopPropagation(); openGifPicker(); });
            document.getElementById('gif-search-input').addEventListener('keydown', (e) => { if (e.key === 'Enter') searchGifs(); });
            document.getElementById('gif-results-container').addEventListener('click', (e) => { if (e.target.tagName === 'IMG') sendGifToChat(db, uid, e.target.dataset.fullUrl); });
            document.body.addEventListener('click', e => {
                if (e.target.closest('.chat-username')) { showUserProfile(db, e.target.closest('.chat-username').dataset.uid); }
                if (e.target.id === 'get-full-mod-btn') { document.getElementById('promo-modal-overlay').style.display = 'flex'; }
                if (gifPickerModal && !gifPickerModal.contains(e.target) && e.target.id !== 'gif-btn') { gifPickerModal.style.display = 'none'; }
            });
            document.addEventListener('keydown', (e) => {
                const activeEl = document.activeElement;
                if (e.key.toLowerCase() === 'c' && activeEl.tagName !== 'INPUT' && activeEl.tagName !== 'TEXTAREA') { toggleChatVisibility(); }
            });
        }

        loadFirebaseAndInit();
    }
})();