🛠️ PopControl

Popmundo scriptlerini tek panelden yönetmenizi sağlayan merkezi modül

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey, Greasemonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да инсталирате разширение, като например Tampermonkey .

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Violentmonkey.

За да инсталирате този скрипт, трябва да имате инсталирано разширение като Tampermonkey или Userscripts.

За да инсталирате скрипта, трябва да инсталирате разширение като Tampermonkey.

За да инсталирате този скрипт, трябва да имате инсталиран скриптов мениджър.

(Вече имам скриптов мениджър, искам да го инсталирам!)

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да инсталирате разширение като Stylus.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

За да инсталирате този стил, трябва да имате инсталиран мениджър на потребителски стилове.

(Вече имам инсталиран мениджър на стиловете, искам да го инсталирам!)

// ==UserScript==
// @name        🛠️ PopControl
// @name:tr     🛠️ PopControl
// @name:en     🛠️ PopControl
// @name:pt-BR  🛠️ PopControl
// @namespace   popmundo.popcontrol
// @version     2.3
// @description Popmundo scriptlerini tek panelden yönetmenizi sağlayan merkezi modül
// @description:tr Popmundo scriptlerini tek panelden yönetmenizi sağlayan merkezi modül
// @description:tr Popmundo scriptlerini tek panelden yönetmenizi sağlayan merkezi modül
// @description:en Central hub to manage all Popmundo scripts from one panel
// @description:pt-BR Módulo central para gerenciar todos os scripts do Popmundo
// @author      luke-james-gibson
// @license     MIT
// @match       https://*.popmundo.com/*
// @run-at      document-end
// @grant       unsafeWindow
// @grant       GM_getValue
// @grant       GM_setValue
// @grant       GM_deleteValue
// ==/UserScript==

(function () {
'use strict';

// ─── CORE UTILS ────────────────────────────────────────────────────────────────
const DEBUG = localStorage.getItem('ppc_debug') === 'true';
const log = (...args) => DEBUG && console.log('[PopControl]', ...args);

const CK = {
    get: k => { const m = document.cookie.match(new RegExp('(?:^|; )' + k + '=([^;]*)')); return m ? decodeURIComponent(m[1]) : null; },
    set: (k, v) => { document.cookie = `${k}=${encodeURIComponent(v)};domain=.popmundo.com;path=/;max-age=31536000`; }
};

const LS = {
    get: (k, d) => { try { const v = localStorage.getItem(k); return v !== null ? JSON.parse(v) : d; } catch { return d; } },
    set: (k, v) => { try { localStorage.setItem(k, JSON.stringify(v)); } catch {} },
};

const mk = (tag, cls, txt) => { 
    const e = document.createElement(tag); 
    if (cls) e.className = cls; 
    if (txt != null) e.textContent = txt; 
    return e; 
};

const mkB = (txt, cls, fn) => Object.assign(mk('button', cls, txt), { onclick: fn, type: 'button' });

// ─── LANGUAGE & STRINGS ────────────────────────────────────────────────────────
const LANG = CK.get('ppm_lang') || 'TR';
const _D = (tr, en, pt) => ({ TR: tr, EN: en, PT: pt }[LANG] || tr);
const STR = {
    posLabel:    _D('Konum',            'Position',          'Posição'),
    posBottom:   _D('⬇ Alt',           '⬇ Bottom',         '⬇ Baixo'),
    posTop:      _D('⬆ Üst',           '⬆ Top',            '⬆ Cima'),
    posLeft:     _D('◀ Sol',           '◀ Left',           '◀ Esquerda'),
    posRight:    _D('▶ Sağ',           '▶ Right',          '▶ Direita'),
    langLabel:   _D('Dil',              'Language',          'Idioma'),
    scripts:     _D('Scriptler',        'Scripts',           'Scripts'),
    order:       _D('Sıra',             'Order',             'Ordem'),
    orderHint:   _D('Barda butonları sürükleyip bırakarak sıralayabilirsiniz.',
                    'Drag & drop buttons on the bar to reorder.',
                    'Arraste os botões na barra para reordenar.'),
    colorBar:    _D('Bar Rengi',        'Bar Color',         'Cor da Barra'),
    colorText:   _D('Yazı Rengi',       'Text Color',        'Cor do Texto'),
    shortcut:    _D('Paneli Aç/Kapat - Alt + P', 'Toggle Panel - Alt + P', 'Alternar Painel - Alt + P'),
    close:       _D('Kapat',            'Close',             'Fechar'),
};

// ─── STORAGE & STATE ───────────────────────────────────────────────────────────
const _getEnabledObj = () => { try { return JSON.parse(GM_getValue('ppc_enabled', '{}')); } catch { return {}; } };
const _saveEnabledObj = o => GM_setValue('ppc_enabled', JSON.stringify(o));
const _isEnabled = id => _getEnabledObj()[id] !== false;
const _setEnabled = (id, v) => { const e = _getEnabledObj(); e[id] = v; _saveEnabledObj(e); };

const _getPos = () => GM_getValue('ppc_pos', 'bottom');
const _setPos = p => GM_setValue('ppc_pos', p);

const _getOrder = () => { try { return JSON.parse(GM_getValue('ppc_order', '[]')); } catch { return []; } };
const _setOrder = o => GM_setValue('ppc_order', JSON.stringify(o));

const _getColBg = () => GM_getValue('ppc_bg', '#f5f0ff');
const _getColFg = () => GM_getValue('ppc_fg', '#5a30a0');
const _setColBg = v => GM_setValue('ppc_bg', v);
const _setColFg = v => GM_setValue('ppc_fg', v);

const _registry = [];
const _plugins = [];
let _collapsed = false;
const _setCollapsed = v => { _collapsed = v; GM_setValue('ppc_collapsed', v); };

function _sortedRegistry() {
    const order = _getOrder();
    if (!order.length) return [..._registry];
    const res = [];
    order.forEach(id => { const e = _registry.find(r => r.id === id); if (e) res.push(e); });
    _registry.forEach(e => { if (!res.includes(e)) res.push(e); });
    return res;
}

// ─── COLORS & GEOMETRY ─────────────────────────────────────────────────────────
const PRESET_BG = ['#f5f0ff','#fff','#1a1035','#2c3e50','#0d1117','#fff0f5','#f0fff4','#f0f8ff','#fffde7','#f3e5f5'];
const PRESET_FG = ['#5a30a0','#6f42c1','#fff','#ecf0f1','#ccc','#e83e8c','#28a745','#007bff','#fd7e14','#ffc107'];

function _mainGeom() {
    const m = document.getElementById('ppm-main') || document.getElementById('ppm-footer');
    if (!m) return { left: 0, width: window.innerWidth, right: window.innerWidth };
    const r = m.getBoundingClientRect();
    return { left: Math.round(r.left), width: m.offsetWidth, right: Math.round(r.right) };
}

function _applyPush(size) {
    document.getElementById('ppc-push')?.remove();
    if (!size) return;
    const s = document.createElement('style'); s.id = 'ppc-push';
    s.textContent = `#ppm-main{margin-top:${65 + size}px!important}#character-tools,#header-logo{margin-top:${size}px!important}`;
    document.head.appendChild(s);
}

function _positionFab(fab) {
    const footer = document.getElementById('ppm-footer');
    if (footer && window.innerWidth >= 768) {
        const r = footer.getBoundingClientRect();
        fab.style.bottom = (window.innerHeight - r.bottom + 8) + 'px';
        fab.style.right = (window.innerWidth - r.right + 8) + 'px';
    }
}

function _shadeHex(hex, amt) {
    try {
        let h = hex.replace('#','');
        if (h.length === 3) h = h[0]+h[0]+h[1]+h[1]+h[2]+h[2];
        const r = Math.max(0,Math.min(255,parseInt(h.slice(0,2),16)+amt));
        const g = Math.max(0,Math.min(255,parseInt(h.slice(2,4),16)+amt));
        const b = Math.max(0,Math.min(255,parseInt(h.slice(4,6),16)+amt));
        return '#'+[r,g,b].map(x=>x.toString(16).padStart(2,'0')).join('');
    } catch { return hex; }
}
            // ─── UI BUILDING ───────────────────────────────────────────────────────────────
let _dragId = null;
let _rebuildTimer = null;

const _queueRebuild = () => { 
    clearTimeout(_rebuildTimer); 
    _rebuildTimer = setTimeout(() => {
        log('Rebuilding UI...');
        _rebuild();
    }, 50); 
};

function _rebuild() {
    document.getElementById('ppc-bar')?.remove();
    document.getElementById('ppc-fab')?.remove();
    document.getElementById('ppc-push')?.remove();

    const pos = _getPos();
    const g = _mainGeom();
    const mob = window.innerWidth < 768;
    const vert = pos === 'left' || pos === 'right';
    const BG = _getColBg();
    const BDR = '1px solid ' + _shadeHex(BG, -25);
    const FG = _getColFg();
    const SZ = 46;
    const sortedReg = _sortedRegistry();

    // FAB (collapsed)
    const fab = mk('button'); fab.id = 'ppc-fab'; fab.type = 'button';
    fab.textContent = '⚙️';
    fab.style.cssText = [
        'position:fixed;bottom:16px;right:16px;z-index:9996',
        `background:${BG};border:${BDR};border-radius:50%`,
        `width:${SZ}px;height:${SZ}px;font-size:20px;cursor:pointer`,
        'box-shadow:0 2px 10px rgba(0,0,0,.25);display:none;align-items:center;justify-content:center',
        'font-family:inherit'
    ].join(';');
    fab.onclick = () => { _setCollapsed(false); _rebuild(); };
    document.body.appendChild(fab);

    // Main bar
    const bar = mk('div'); bar.id = 'ppc-bar';

    if (vert) {
        const side = pos === 'left' ? `left:${mob ? 0 : Math.max(0, g.left - SZ)}px` : `right:${mob ? 0 : Math.max(0, window.innerWidth - g.right - SZ)}px`;
        const shadow = pos === 'left' ? '2px 0 8px rgba(0,0,0,.12)' : '-2px 0 8px rgba(0,0,0,.12)';
        bar.style.cssText = [
            `position:fixed;${side};top:65px;bottom:0;z-index:9990`,
            `background:${BG};border:${BDR};box-shadow:${shadow}`,
            `border-radius:${pos==='left'?'0 8px 8px 0':'8px 0 0 8px'}`,
            `width:${SZ}px;overflow-y:auto;overflow-x:hidden;scrollbar-width:none`,
            `display:flex;flex-direction:column;align-items:center;padding:4px 0;gap:0`,
        ].join(';');
    } else {
        const side = pos === 'bottom' ? 'bottom:0' : 'top:0';
        const xPos = mob ? 'left:0;right:0' : `left:${g.left}px;width:${g.width}px`;
        const zIdx = pos === 'top' ? 99990 : 9990;
        const shadow = pos === 'bottom' ? '0 -2px 8px rgba(0,0,0,.12)' : '0 2px 8px rgba(0,0,0,.12)';
        bar.style.cssText = [
            `position:fixed;${xPos};${side};z-index:${zIdx}`,
            `background:${BG};border:${BDR};box-shadow:${shadow}`,
            `border-radius:${pos==='bottom'?'8px 8px 0 0':'0 0 8px 8px'}`,
            `display:flex;flex-direction:row;flex-wrap:nowrap;align-items:stretch`,
        ].join(';');
    }

    // Button factory
    const BTN_W = vert ? SZ : 52;
    const mkBtn = (icon, label, onClick, draggable) => {
        const b = mk('button'); b.type = 'button';
        if (draggable) b.draggable = true;
        b.style.cssText = [
            `display:flex;flex-direction:column;align-items:center;justify-content:center`,
            vert ? `width:${BTN_W}px;min-height:${SZ}px;padding:4px 2px;gap:2px;flex-shrink:0` : `min-width:48px;flex:1;min-height:${SZ}px;padding:4px 6px;gap:2px`,
            `background:transparent;border:none;border-radius:4px;cursor:pointer;font-family:inherit;transition:all 0.2s ease`
        ].join(';');
        
        b.addEventListener('mouseenter', () => {
            b.style.transform = 'scale(1.05)';
            b.style.background = 'rgba(0,0,0,.07)';
        });
        
        b.addEventListener('mouseleave', () => {
            b.style.transform = 'scale(1)';
            b.style.background = 'none';
        });
        
        const ico = mk('span'); ico.textContent = icon;
        ico.style.cssText = 'font-size:18px;line-height:1;pointer-events:none;flex-shrink:0';
        const lbl = mk('span'); lbl.textContent = label;
        lbl.dataset.ppcLbl = '1';
        lbl.style.cssText = `font-size:9px;color:${FG};font-weight:700;white-space:nowrap;text-align:center;line-height:1.15;pointer-events:none;`;
        b.append(ico, lbl);
        b.onclick = onClick;
        return b;
    };

    const mkSep = () => {
        const d = mk('div');
        d.style.cssText = vert
            ? `height:1px;background:${_shadeHex(BG,-18)};margin:2px 6px;width:${SZ-12}px;flex-shrink:0`
            : `width:1px;background:${_shadeHex(BG,-18)};margin:5px 0;flex-shrink:0;align-self:stretch`;
        return d;
    };

    // Drag & drop
    function _attachDrag(btn, groupId) {
        btn.addEventListener('dragstart', e => {
            _dragId = groupId;
            e.dataTransfer.effectAllowed = 'move';
            setTimeout(() => btn.style.opacity = '.4', 0);
        });
        btn.addEventListener('dragend', () => { _dragId = null; btn.style.opacity = '1'; });
        btn.addEventListener('dragover', e => { e.preventDefault(); btn.style.outline = '2px dashed ' + FG; });
        btn.addEventListener('dragleave', () => btn.style.outline = '');
        btn.addEventListener('drop', e => {
            e.preventDefault(); btn.style.outline = '';
            if (!_dragId || _dragId === groupId) return;
            const order = sortedReg.map(r => r.id);
            const from = order.indexOf(_dragId), to = order.indexOf(groupId);
            if (from < 0 || to < 0) return;
            order.splice(to, 0, order.splice(from, 1)[0]);
            _setOrder(order); _rebuild();
        });
    }

    // Touch drag for mobile
    function _attachTouchDrag(container) {
        let dragEl = null, ghost = null, lastOver = null;
        let startX = 0, startY = 0, origLeft = 0, origTop = 0;
        let pressTimer = null, isDragging = false;

        container.addEventListener('touchstart', e => {
            const h = e.target.closest('[data-ppc-drag]');
            if (!h) return;
            dragEl = h;
            startX = e.touches[0].clientX;
            startY = e.touches[0].clientY;

            pressTimer = setTimeout(() => {
                isDragging = true;
                const r = dragEl.getBoundingClientRect();
                origLeft = r.left; origTop = r.top;
                ghost = dragEl.cloneNode(true);
                ghost.style.cssText = `position:fixed;left:${origLeft}px;top:${origTop}px;width:${r.width}px;height:${r.height}px;opacity:.8;pointer-events:none;z-index:99999;border:2px dashed ${FG};border-radius:6px;background:${BG};box-shadow:0 10px 20px rgba(0,0,0,0.3);transform:scale(1.05);transition:transform 0.1s;`;
                document.body.appendChild(ghost);
                dragEl.style.opacity = '.3';
            }, 300);
        }, { passive: true });

        container.addEventListener('touchmove', e => {
            if (!dragEl) return;
            if (!isDragging) {
                clearTimeout(pressTimer);
                dragEl = null;
                return;
            }
            e.preventDefault();
            const t = e.touches[0];
            ghost.style.left = (origLeft + t.clientX - startX) + 'px';
            ghost.style.top = (origTop + t.clientY - startY) + 'px';

            const over = document.elementFromPoint(t.clientX, t.clientY)?.closest('[data-ppc-drag]');
            if (lastOver && lastOver !== dragEl) lastOver.style.outline = '';
            if (over && over !== dragEl) { over.style.outline = '2px dashed ' + FG; lastOver = over; }
        }, { passive: false });

        container.addEventListener('touchend', e => {
            clearTimeout(pressTimer);
            if (!isDragging || !dragEl) {
                dragEl = null; isDragging = false;
                return;
            }
            ghost?.remove(); ghost = null;
            dragEl.style.opacity = '1';
            if (lastOver && lastOver !== dragEl) lastOver.style.outline = '';

            const t = e.changedTouches[0];
            const over = document.elementFromPoint(t.clientX, t.clientY)?.closest('[data-ppc-drag]');
            if (over && over !== dragEl) {
                const fromId = dragEl.dataset.ppcDrag, toId = over.dataset.ppcDrag;
                const order = sortedReg.map(r => r.id);
                const fi = order.indexOf(fromId), ti = order.indexOf(toId);
                if (fi >= 0 && ti >= 0) { order.splice(ti, 0, order.splice(fi, 1)[0]); _setOrder(order); _rebuild(); }
            }
            dragEl = null; lastOver = null; isDragging = false;
        }, { passive: true });
    }

    // Collapse button
    const colBtn = mk('button'); colBtn.type = 'button';
    colBtn.textContent = '▼';
    colBtn.style.cssText = [
        `font-size:9px;color:${FG};background:none;border:none;cursor:pointer`,
        `padding:2px 4px;font-family:inherit;flex-shrink:0`,
        vert ? `width:${SZ}px;text-align:center` : `min-width:20px;align-self:center`
    ].join(';');
    colBtn.title = _D('Küçült', 'Collapse', 'Recolher');
    colBtn.onclick = () => { _setCollapsed(true); _rebuild(); };

    // Render entries
    if (!vert) {
        const scrollWrap = mk('div');
        scrollWrap.style.cssText = 'display:flex;flex:1;min-width:0;overflow-x:auto;scrollbar-width:none;-webkit-overflow-scrolling:touch;align-items:stretch';
        const fixedEnd = mk('div');
        fixedEnd.style.cssText = 'display:flex;flex-shrink:0;align-items:stretch';

        let hasAny = false;
        sortedReg.forEach(entry => {
            if (!_isEnabled(entry.id)) return;
            if (hasAny) scrollWrap.appendChild(mkSep());
            entry.buttons.forEach((btn, i) => {
                const b = mkBtn(btn.icon, btn.label, btn.onClick, i === 0);
                if (i === 0) { b.dataset.ppcDrag = entry.id; _attachDrag(b, entry.id); }
                scrollWrap.appendChild(b);
            });
            hasAny = true;
        });

        if (hasAny) fixedEnd.appendChild(mkSep());
        const sBtn = mkBtn('⚙️', 'PopControl', _openSettings, false);
        fixedEnd.appendChild(sBtn);
        fixedEnd.appendChild(colBtn);

        bar.appendChild(scrollWrap);
        bar.appendChild(fixedEnd);
        _attachTouchDrag(scrollWrap);
    } else {
        let hasAny = false;
        sortedReg.forEach(entry => {
            if (!_isEnabled(entry.id)) return;
            if (hasAny) bar.appendChild(mkSep());
            entry.buttons.forEach((btn, i) => {
                const b = mkBtn(btn.icon, btn.label, btn.onClick, i === 0);
                if (i === 0) { b.dataset.ppcDrag = entry.id; _attachDrag(b, entry.id); }
                bar.appendChild(b);
            });
            hasAny = true;
        });
        if (hasAny) bar.appendChild(mkSep());
        const sBtn = mkBtn('⚙️', 'PopControl', _openSettings, false);
        sBtn.style.marginTop = 'auto';
        bar.appendChild(sBtn); bar.appendChild(mkSep()); bar.appendChild(colBtn);
        _attachTouchDrag(bar);
    }

    document.body.appendChild(bar);

    // Auto-shrink labels
    requestAnimationFrame(() => {
        bar.querySelectorAll('[data-ppc-lbl]').forEach(lbl => {
            const btn = lbl.closest('button');
            if (btn && lbl.scrollWidth > btn.clientWidth + 2) lbl.style.fontSize = '8px';
        });
    });

    // Push layout for top
    if (pos === 'top') _applyPush(bar.offsetHeight || 34);

    // Apply collapsed state
    if (_collapsed) {
        bar.style.display = 'none';
        fab.style.display = 'flex';
        _positionFab(fab);
    }
}

// ─── SETTINGS PANEL ──────────────────────────────────────────────────────────
function _openSettings() {
    document.getElementById('ppc-ov')?.remove();
    const pos = _getPos();

    const ov = mk('div'); ov.id = 'ppc-ov';
    ov.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.55);z-index:99998;display:flex;align-items:flex-end;justify-content:center';

    const box = mk('div');
    box.style.cssText = 'background:#fff;border-radius:16px 16px 0 0;padding:20px;width:100%;max-width:520px;max-height:80vh;overflow-y:auto;box-sizing:border-box';

    const mkH = t => { const d = mk('div'); d.textContent = t; d.style.cssText = 'font-size:10px;font-weight:700;color:#888;text-transform:uppercase;letter-spacing:.5px;margin:14px 0 6px'; return d; };
    const mkHr = () => { const hr = mk('hr'); hr.style.cssText = 'border:none;border-top:1px solid #eee;margin:10px 0'; return hr; };
    const mkPillRow = (items) => {
        const row = mk('div'); row.style.cssText = 'display:flex;gap:6px;flex-wrap:wrap';
        items.forEach(([val, lbl, active, fn]) => {
            const b = mkB(lbl, '', fn);
            b.style.cssText = `flex:1;min-width:70px;padding:7px 4px;border-radius:6px;border:1px solid ${active?'#6f42c1':'#ddd'};background:${active?'#6f42c1':'#f8f9fa'};color:${active?'#fff':'#333'};font-size:11px;cursor:pointer;font-family:inherit`;
            row.appendChild(b);
        });
        return row;
    };

    // Title
    const titleRow = mk('div'); titleRow.style.cssText = 'display:flex;justify-content:space-between;align-items:center;margin-bottom:16px';
    titleRow.appendChild(Object.assign(mk('span'), { textContent: ' PopControl v' + GM_info.script.version, style: { fontWeight: 'bold', fontSize: '16px' } }));
    const closeBtn = mkB('✕', '', () => ov.remove()); closeBtn.style.cssText = 'background:none;border:none;font-size:20px;cursor:pointer;color:#aaa;padding:0';
    titleRow.appendChild(closeBtn); box.appendChild(titleRow);

    // Position
    box.appendChild(mkH(STR.posLabel));
    box.appendChild(mkPillRow([
        ['bottom', STR.posBottom, pos==='bottom', () => { _setPos('bottom'); ov.remove(); location.reload(); }],
        ['top',    STR.posTop,    pos==='top',    () => { _setPos('top');    ov.remove(); location.reload(); }],
        ['left',   STR.posLeft,   pos==='left',   () => { _setPos('left');   ov.remove(); location.reload(); }],
        ['right',  STR.posRight,  pos==='right',  () => { _setPos('right');  ov.remove(); location.reload(); }],
    ]));
    box.appendChild(mkHr());

    // Ecosystem links
    const ecosystemRow = mk('div');
    ecosystemRow.style.cssText = 'background:#f0f8ff;border-radius:8px;padding:16px;margin-bottom:12px';
    ecosystemRow.innerHTML = `
        <div style="display:flex;gap:20px;justify-content:center;align-items:center">
            <div style="display:flex;align-items:center;gap:10px">
                <span style="font-size:16px">🇹🇷</span>
                <a href="https://rentry.org/PopControlEkosistemi" target="_blank" style="color:#1a5276;font-weight:500;text-decoration:none;font-size:13px">Beni Oku</a>
            </div>
            <div style="display:flex;align-items:center;gap:10px">
                <span style="font-size:16px">🇬🇧</span>
                <a href="https://rentry.org/PopControlEcosystem" target="_blank" style="color:#1a5276;font-weight:500;text-decoration:none;font-size:13px">Read Me</a>
            </div>
            <div style="display:flex;align-items:center;gap:10px">
                <span style="font-size:16px">🇧🇷</span>
                <a href="https://rentry.org/EcossistemaPopControl" target="_blank" style="color:#1a5276;font-weight:500;text-decoration:none;font-size:13px">Leia-me</a>
            </div>
        </div>
    `;
    box.appendChild(ecosystemRow);

    // Language
    box.appendChild(mkH(STR.langLabel));
        
    const _hasCustom = ['ppc_lc_helper','ppc_lc_social','ppc_lc_social_mobile','ppc_lc_depot','ppc_lc_guide','ppc_lc_route49'].some(k => localStorage.getItem(k));
    box.appendChild(mkPillRow([
        ['TR','🇹🇷 Türkçe', LANG==='TR', () => { CK.set('ppm_lang','TR'); ov.remove(); location.reload(); }],
        ['EN','🇬🇧 English', LANG==='EN', () => { CK.set('ppm_lang','EN'); ov.remove(); location.reload(); }],
        ['PT','🇧🇷 Português', LANG==='PT', () => { CK.set('ppm_lang','PT'); ov.remove(); location.reload(); }],
        ['CU','🌍 Customize', _hasCustom, () => _openCustomize(ov)],
    ]));
    box.appendChild(mkHr());

    // Colors
    box.appendChild(mkH('Renk Ayarları'));
    const colorRow = mk('div'); colorRow.style.cssText = 'display:flex;gap:12px;align-items:center;margin-bottom:12px';
    
    const bgInput = mk('input'); bgInput.type = 'color'; bgInput.value = _getColBg();
    bgInput.style.cssText = 'width:40px;height:40px;border:1px solid #ddd;border-radius:6px;cursor:pointer;box-shadow:0 2px 4px rgba(0,0,0,0.1)';
    bgInput.oninput = () => { _setColBg(bgInput.value); _queueRebuild(); };
    
    const fgInput = mk('input'); fgInput.type = 'color'; fgInput.value = _getColFg();
    fgInput.style.cssText = 'width:40px;height:40px;border:1px solid #ddd;border-radius:6px;cursor:pointer;box-shadow:0 2px 4px rgba(0,0,0,0.1)';
    fgInput.oninput = () => { _setColFg(fgInput.value); _queueRebuild(); };
    
    const bgLabel = mk('span'); bgLabel.textContent = STR.colorBar; bgLabel.style.cssText = 'font-size:13px;font-weight:500;color:#333';
    const fgLabel = mk('span'); fgLabel.textContent = STR.colorText; fgLabel.style.cssText = 'font-size:13px;font-weight:500;color:#333';
    
    colorRow.appendChild(bgLabel); colorRow.appendChild(bgInput);
    colorRow.appendChild(fgLabel); colorRow.appendChild(fgInput);
    box.appendChild(colorRow);
    
    // Keyboard shortcuts info
    const shortcutsRow = mk('div');
    shortcutsRow.style.cssText = 'background:#f8f9fa;border-radius:8px;padding:16px;margin-bottom:10px';
    shortcutsRow.innerHTML = `
        <div style="display:flex;align-items:center;gap:8px;margin-bottom:8px">
            <span style="font-size:16px">⌨️</span>
            <span style="font-size:13px;font-weight:500;color:#333">${STR.shortcut}</span>
        </div>
        <div style="display:flex;align-items:center;gap:8px">
            <span style="font-size:16px">📱</span>
            <span style="font-size:13px;font-weight:500;color:#333">${STR.orderHint}</span>
        </div>
    `;
    box.appendChild(shortcutsRow);
    box.appendChild(mkHr());

    // Menu Settings
    if (location.href.includes('/World/Popmundo.aspx/Character')) {
        box.appendChild(mkH(_D('Karakter Menüsü', 'Character Menu', 'Menu do Personagem')));
        const menuRow = mk('div'); 
        menuRow.style.cssText = 'display:flex;align-items:center;justify-content:space-between;padding:12px;background:#f8f9fa;border-radius:8px;margin-bottom:12px';
        
        const menuInfo = mk('span');
        menuInfo.innerHTML = `<span style="font-size:16px;margin-right:8px">🗂️</span><span style="font-size:13px;font-weight:500;color:#333">${_D('Gizle, favorilere al, sırala', 'Hide, favorite & reorder items', 'Ocultar, favoritar e reordenar')}</span>`;
        
        const _hiddenCount = JSON.parse(localStorage.getItem('hidden-native-menu-items') || '[]').length;
        const _badgeTxt = _hiddenCount ? ` <span style="background:#dc3545;color:#fff;border-radius:10px;padding:1px 7px;font-size:11px;font-weight:700;margin-left:4px;">${_hiddenCount}</span>` : '';
        const menuBtn = mk('button');
        menuBtn.type = 'button';
        menuBtn.innerHTML = _D('Yönet', 'Manage', 'Gerenciar') + _badgeTxt;
        menuBtn.style.cssText = 'padding:8px 16px;background:#667eea;color:white;border:none;border-radius:6px;cursor:pointer;font-size:12px;font-weight:600;transition:all 0.2s;display:flex;align-items:center;gap:4px;';
        menuBtn.onclick = () => { API.MenuManager.showMenuSettings(); ov.remove(); };
        menuBtn.onmouseover = () => menuBtn.style.background = '#5a6fd8';
        menuBtn.onmouseout = () => menuBtn.style.background = '#667eea';
        
        menuRow.appendChild(menuInfo);
        menuRow.appendChild(menuBtn);
        box.appendChild(menuRow);
        box.appendChild(mkHr());
    }

    // Script toggles
    if (_registry.length) {
        box.appendChild(mkH(STR.scripts));
        _sortedRegistry().forEach(entry => {
            const row = mk('div'); row.style.cssText = 'display:flex;align-items:center;justify-content:space-between;padding:10px 0;border-bottom:1px solid #f0f0f0';
            const name = mk('span'); name.textContent = entry.icon + ' ' + entry.label; name.style.cssText = 'font-size:13px;font-weight:500';
            const swLbl = mk('label'); swLbl.style.cssText = 'position:relative;display:inline-block;width:46px;height:26px;cursor:pointer;flex-shrink:0';
            const inp = mk('input'); inp.type = 'checkbox'; inp.checked = _isEnabled(entry.id); inp.style.cssText = 'opacity:0;width:0;height:0;position:absolute';
            const trk = mk('span'); trk.style.cssText = `position:absolute;inset:0;border-radius:26px;background:${inp.checked?'#6f42c1':'#ccc'};transition:.25s`;
            const knob = mk('span'); knob.style.cssText = `position:absolute;height:20px;width:20px;left:${inp.checked?'23px':'3px'};bottom:3px;background:#fff;border-radius:50%;transition:.25s;box-shadow:0 1px 3px rgba(0,0,0,.3)`;
            trk.appendChild(knob);
            inp.onchange = () => {
                const v = inp.checked;
                trk.style.background = v ? '#6f42c1' : '#ccc';
                knob.style.left = v ? '23px' : '3px';
                _setEnabled(entry.id, v);
                if (!v) entry.onUndo?.();
                _rebuild();
            };
            swLbl.append(inp, trk); row.append(name, swLbl); box.appendChild(row);
        });
        box.appendChild(mkHr());
    }

    ov.onclick = e => { if (e.target === ov) ov.remove(); };
    ov.appendChild(box); document.body.appendChild(ov);
}

// ─── CUSTOMIZE (LANGUAGE IMPORT/EXPORT) ──────────────────────────────────────
function _openCustomize(parentOv) {
    const LC_KEYS = {
        helper: 'ppc_lc_helper',
        social: 'ppc_lc_social',
        social_mobile: 'ppc_lc_social_mobile',
        depot: 'ppc_lc_depot',
        guide: 'ppc_lc_guide',
        route49: 'ppc_lc_route49',
    };
    const hasCustom = Object.values(LC_KEYS).some(k => localStorage.getItem(k));

    const ov = mk('div');
    ov.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.75);z-index:100001;display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box';
    const box = mk('div');
    box.style.cssText = 'background:#fff;border-radius:14px;padding:20px;width:100%;max-width:480px;max-height:90vh;overflow-y:auto;box-sizing:border-box;position:relative;font-family:inherit';

    // Header
    const hdr = mk('div');
    hdr.style.cssText = 'display:flex;justify-content:space-between;align-items:center;margin-bottom:16px';
    const title = mk('span');
    title.textContent = '🌍 Custom Language (Customize)';
    title.style.cssText = 'font-weight:700;font-size:16px';
    const xBtn = mk('button');
    xBtn.textContent = '✕'; xBtn.type = 'button';
    xBtn.style.cssText = 'background:none;border:none;font-size:20px;cursor:pointer;color:#aaa;padding:0';
    xBtn.onclick = () => ov.remove();
    hdr.append(title, xBtn);
    box.appendChild(hdr);

    // Info section
    const infoRow = mk('div');
    infoRow.style.cssText = 'background:#e8f4fd;border-radius:8px;padding:12px;margin-bottom:16px;font-size:12px;line-height:1.6;color:#1a5276';
    infoRow.innerHTML = `
        <div style="font-weight:600;margin-bottom:8px">With PopControl's <strong>Customize</strong> feature, you can translate all scripts' interfaces into any language:</div>
        <div style="margin-left:12px;margin-bottom:4px">1. <strong>📋 Copy Export JSON + Prompt</strong> — copy content</div>
        <div style="margin-left:12px;margin-bottom:4px">2. Paste into <a href="https://gemini.google.com" target="_blank" style="color:#1a5276;font-weight:600">Google Gemini</a>, specify the target language</div>
        <div style="margin-left:12px;margin-bottom:4px">3. Load the returned JSON via <strong>Import</strong></div>
        <div style="margin-left:12px">4. All scripts instantly switch to the new language</div>
    `;
    box.appendChild(infoRow);

    const mkHr = () => { const hr = mk('hr'); hr.style.cssText = 'border:none;border-top:1px solid #eee;margin:14px 0'; return hr; };

    // Export
    box.appendChild(Object.assign(mk('div'), {
        textContent: '📤 Export',
        style: 'font-weight:700;font-size:13px;margin-bottom:6px'
    }));
    
    const expBtn = mk('button');
    expBtn.textContent = '📋 Copy Export JSON';
    expBtn.type = 'button';
    expBtn.style.cssText = 'width:100%;padding:10px;background:#0d6efd;color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:13px;font-weight:600;font-family:inherit';
    expBtn.onclick = () => {
        const collected = {};
        _registry.forEach(entry => {
            if (entry.strings && Object.keys(entry.strings).length) {
                collected[entry.id] = entry.strings;
            }
        });
        if (!Object.keys(collected).length) {
            expBtn.textContent = '⚠️ No scripts registered yet';
            setTimeout(() => expBtn.textContent = '📋 Copy Export JSON', 2500);
            return;
        }
        const promptText = 'Translate JSON values below to the target language.\nRules: keep all emojis, {n}, %s and \\n exactly as-is. Return ONLY valid JSON, no markdown, no explanation.\n\nTarget language: [ENTER TARGET LANGUAGE HERE]\n\n' + JSON.stringify(collected, null, 2);
        navigator.clipboard.writeText(promptText);
        expBtn.textContent = '✅ Copied!';
        setTimeout(() => expBtn.textContent = '📋 Copy Export JSON', 2500);
    };
    box.appendChild(expBtn);
    box.appendChild(mkHr());

    // Import
    box.appendChild(Object.assign(mk('div'), {
        textContent: '📥 Import',
        style: 'font-weight:700;font-size:13px;margin-bottom:6px'
    }));
    
    const impTa = mk('textarea');
    impTa.placeholder = '{ "helper": { "save": "Speichern", ... }, "social": { ... }, ... }';
    impTa.style.cssText = 'width:100%;height:160px;font-size:11px;font-family:monospace;padding:8px;border:1px solid #ddd;border-radius:6px;box-sizing:border-box;resize:vertical;margin-bottom:8px';
    box.appendChild(impTa);

    const errDiv = mk('div');
    errDiv.style.cssText = 'font-size:12px;min-height:18px;margin-bottom:8px';
    box.appendChild(errDiv);

    const applyBtn = mk('button');
    applyBtn.textContent = '✅ Apply & Reload';
    applyBtn.type = 'button';
    applyBtn.style.cssText = 'width:100%;padding:10px;background:#198754;color:#fff;border:none;border-radius:8px;cursor:pointer;font-size:13px;font-weight:600;font-family:inherit';
    applyBtn.onclick = () => {
        try {
            const raw = impTa.value.trim();
            if (!raw) { errDiv.style.color='#dc3545'; errDiv.textContent='Paste translated JSON first.'; return; }
            const data = JSON.parse(raw);
            let applied = 0;
            Object.entries(LC_KEYS).forEach(([id, lsKey]) => {
                if (data[id] && typeof data[id] === 'object') {
                    localStorage.setItem(lsKey, JSON.stringify(data[id]));
                    applied++;
                }
            });
            if (!applied) { errDiv.style.color='#dc3545'; errDiv.textContent='No matching script keys found.'; return; }
            errDiv.style.color = '#198754';
            errDiv.textContent = '✅ Applied to ' + applied + ' script(s) — reloading...';
            setTimeout(() => { ov.remove(); if (parentOv) parentOv.remove(); location.reload(); }, 1200);
        } catch (err) {
            errDiv.style.color = '#dc3545';
            errDiv.textContent = '❌ Invalid JSON: ' + err.message;
        }
    };
    box.appendChild(applyBtn);

    box.appendChild(mkHr());

    // Reset
    const resetBtn = mk('button');
    resetBtn.textContent = '🗑️ Reset to Default Language';
    resetBtn.type = 'button';
    resetBtn.style.cssText = 'width:100%;padding:8px;background:none;color:#dc3545;border:1px solid #dc3545;border-radius:8px;cursor:pointer;font-size:12px;font-family:inherit';
    resetBtn.onclick = () => {
        if (!confirm('Remove all custom language data and restore defaults?')) return;
        Object.values(LC_KEYS).forEach(k => localStorage.removeItem(k));
        ov.remove(); if (parentOv) parentOv.remove(); location.reload();
    };
    if (hasCustom) box.appendChild(resetBtn);

    ov.onclick = e => { if (e.target === ov) ov.remove(); };
    ov.appendChild(box);
    document.body.appendChild(ov);
}
        // ─── API & INTEGRATION ────────────────────────────────────────────────────────
const _processed = new Set();
const _queue = window.PopControl && window.PopControl._q ? window.PopControl._q : [];

const API = {
    register({ id, icon, label, buttons, strings, onUndo }) {
        if (_registry.some(r => r.id === id)) return;
        _registry.push({ id, icon: icon || '🔌', label: label || id, buttons: buttons || [], strings: strings || {}, onUndo });
        log(`Registered: ${id}`);
        _queueRebuild();
    },
    unregister(id) {
        const i = _registry.findIndex(r => r.id === id);
        if (i < 0) return;
        const [entry] = _registry.splice(i, 1);
        if (entry._cleanup) entry._cleanup();
        entry.onUndo?.();
        log(`Unregistered: ${id}`);
        _queueRebuild();
    },
    isEnabled: _isEnabled,
    getLang: () => LANG,
    getConnectionStatus: () => ({
        registryCount: _registry.length,
        queueLength: _queue.length,
        scripts: _registry.map(r => ({ id: r.id, label: r.label }))
    }),

    // ─── MENU MANAGER ─────────────────────────────────────────────────────────────
    MenuManager: {
        menuConfigs: new Map(),
        builtMenus: new Set(),
        _favDragActive:  false,   // Favoriler sıralama modu
        _tvipDragActive: false,   // TOP VIP sıralama modu

        registerMenu(config) {
            const { id, title, position, items = [], draggable = false, collapsible = true } = config;
            
            if (this.menuConfigs.has(id)) {
                // Merge — id'ye göre dedup, aynı item iki kez eklenmesin
                const existing = this.menuConfigs.get(id);
                const newItems = items.filter(item => !existing.items.some(e => e.id === item.id));
                if (newItems.length) {
                    existing.items.push(...newItems);
                    log(`Updated menu: ${id} +${newItems.length} item(s)`);
                } else {
                    log(`Menu ${id}: tüm item'lar zaten mevcut, atlandı`);
                }
            } else {
                this.menuConfigs.set(id, { id, title, position, items: [...items], draggable, collapsible });
                log(`Registered menu: ${id}`);
            }
            
            this.rebuildMenus();
        },
        
        rebuildMenus() {
            // Only rebuild on character page
            if (!location.href.includes('/World/Popmundo.aspx/Character')) return;
            
            // Remove existing built menus
            this.builtMenus.forEach(menuId => {
                const existing = document.getElementById(menuId);
                if (existing) existing.remove();
            });
            this.builtMenus.clear();
            
            // Build each menu
            this.menuConfigs.forEach(config => {
                this.buildMenu(config);
            });

            // Favoriler + gizleme her zaman son olarak uygulanır
            this.rebuildFavoritesMenu();
            this.applyNativeItemVisibility();
        },
        
        buildMenu(config) {
            const { id, title, position, items, collapsible } = config;
            const isTopVip = id === 'top-vip';

            // Hedef menüyü bul (dil-agnostik)
            let targetMenu;
            if (position === 'above-career') {
                targetMenu = [...document.querySelectorAll('.menu h3')]
                    .find(h => /Kariyer|Career|Carreira/.test(h.textContent.trim()))?.closest('.menu');
            }
            if (!targetMenu) { log(`Target menu not found for position: ${position}`); return; }

            // TOP VIP için kayıtlı sırayı uygula
            let orderedItems = [...items];
            if (isTopVip) {
                const order = this._getTopVipOrder();
                if (order.length) {
                    orderedItems.sort((a, b) => {
                        const ai = order.indexOf(a.id), bi = order.indexOf(b.id);
                        if (ai < 0) return 1; if (bi < 0) return -1; return ai - bi;
                    });
                }
            }

            const menuElement = document.createElement('div');
            menuElement.id = id + '-menu'; menuElement.className = 'menu';

            // Başlık + badge
            const header = document.createElement('h3');
            header.style.cssText = 'background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:white;text-align:center;padding:8px;margin:0;border-radius:6px 6px 0 0;box-shadow:0 2px 8px rgba(102,126,234,0.3);cursor:pointer;user-select:none;';
            header.textContent = title + (orderedItems.length ? ` (${orderedItems.length})` : '');

            const content = document.createElement('div');
            content.style.cssText = 'padding:0;background:#f8f9fa;border:1px solid #e9ecef;border-top:none;border-radius:0 0 6px 6px;box-shadow:0 2px 4px rgba(0,0,0,0.1);overflow:hidden;';

            const ul = document.createElement('ul');
            ul.style.cssText = 'margin:0;padding:8px 0 4px;list-style:none;';

            if (!orderedItems.length) {
                // Boş durum placeholder
                const empty = document.createElement('li');
                empty.style.cssText = 'padding:6px 12px;font-size:11px;color:#aaa;font-style:italic;';
                empty.textContent = _D('Henüz buton eklenmedi', 'No buttons added yet', 'Nenhum botão adicionado');
                ul.appendChild(empty);
            } else {
                const MM = this;
                orderedItems.forEach(item => {
                    const li = document.createElement('li');
                    li.id = item.id;
                    li.dataset.tvipKey = item.id;
                    li.draggable = MM._tvipDragActive;
                    li.style.cssText = 'margin:2px 0;display:flex;align-items:center;';

                    // Grip — sadece sıralama modunda görünür
                    const grip = document.createElement('span');
                    grip.textContent = '⠿';
                    grip.style.cssText = `color:#bbb;cursor:grab;padding:4px 2px 4px 8px;flex-shrink:0;font-size:14px;line-height:1;display:${MM._tvipDragActive ? 'inline' : 'none'};`;

                    const a = document.createElement('a');
                    a.href = '#';
                    a.textContent = item.label;
                    a.style.cssText = 'color:#667eea;font-weight:600;text-decoration:none;display:block;padding:4px 12px;border-radius:4px;transition:all 0.2s;flex:1;';
                    a.addEventListener('mouseover', () => { a.style.background = '#667eea'; a.style.color = 'white'; });
                    a.addEventListener('mouseout',  () => { a.style.background = '';        a.style.color = '#667eea'; });
                    a.addEventListener('click', e => { e.preventDefault(); item.fn?.(); });

                    li.append(grip, a);
                    ul.appendChild(li);
                });
                if (isTopVip && this._tvipDragActive) this._attachTopVipDrag(ul);
            }

            content.appendChild(ul);
            menuElement.append(header, content);

            // Sıralama kulakçığı — menünün ALTINDA, içeriğin dışında (2+ item ve TOP VIP)
            const spacer = document.createElement('div');
            spacer.id = id + '-spacer'; spacer.style.cssText = 'height:6px;';

            targetMenu.before(menuElement);
            menuElement.after(spacer);

            this.builtMenus.add(id + '-menu');
            this.builtMenus.add(id + '-spacer');

            if (isTopVip && orderedItems.length > 1) {
                const MM = this;
                const tab = document.createElement('div');
                tab.id = id + '-drag-tab';
                tab.title = _D('Sıralama modunu aç/kapat', 'Toggle reorder mode', 'Alternar modo de reordenação');
                tab.textContent = '⇅ ' + (this._tvipDragActive
                    ? _D('Bitti', 'Done', 'Concluído')
                    : _D('Sırala', 'Reorder', 'Reordenar'));
                tab.style.cssText = [
                    'display:block;margin:0 auto;width:fit-content;padding:3px 14px',
                    `background:${this._tvipDragActive ? '#667eea' : '#f0f0f0'}`,
                    `color:${this._tvipDragActive ? '#fff' : '#999'}`,
                    `border:1px solid ${this._tvipDragActive ? '#667eea' : '#ddd'}`,
                    'border-top:none;border-radius:0 0 10px 10px',
                    'font-size:11px;cursor:pointer;transition:all .2s;user-select:none;'
                ].join(';');
                tab.onmouseover = () => { if (!this._tvipDragActive) { tab.style.background = '#e8e8e8'; tab.style.color = '#666'; } };
                tab.onmouseout  = () => { if (!this._tvipDragActive) { tab.style.background = '#f0f0f0'; tab.style.color = '#999'; } };
                tab.onclick = () => { MM._tvipDragActive = !MM._tvipDragActive; MM.rebuildMenus(); };
                menuElement.after(tab);
                tab.after(spacer);
                this.builtMenus.add(id + '-drag-tab');
            }

            if (collapsible) this.makeCollapsible(menuElement);
            this.applyNativeItemVisibility();
        },
        
        makeCollapsible(menuElement) {
            const header  = menuElement.querySelector('h3');
            const content = menuElement.querySelector(':scope > div'); // <ul> wrapper'ı — kesin seçim
            const storageKey = menuElement.id === 'top-vip-menu' ? 'top-vip-collapsed' : `menu-${menuElement.id}-collapsed`;
            
            let isCollapsed = localStorage.getItem(storageKey) === 'true';
            if (isCollapsed && content) content.style.display = 'none';
            
            if (!header) return;
            header.addEventListener('click', () => {
                isCollapsed = !isCollapsed;
                localStorage.setItem(storageKey, isCollapsed);
                if (content) content.style.display = isCollapsed ? 'none' : '';
            });
        },
        
        // ── FAVORITES STORAGE ─────────────────────────────────────────────────────
        _getFavorites() { return JSON.parse(localStorage.getItem('ppc-favorites') || '[]'); },
        _saveFavorites(arr) { localStorage.setItem('ppc-favorites', JSON.stringify(arr)); },

        // Sondaki karakter ID'sini sil: /OfferItem/3117642 → /OfferItem/
        _normalizePath(p) { return p.replace(/\/\d+\/?$/, '/'); },
        _getTopVipOrder() { return JSON.parse(localStorage.getItem('ppc-tvip-order') || '[]'); },
        _saveTopVipOrder(arr) { localStorage.setItem('ppc-tvip-order', JSON.stringify(arr)); },

        toggleFavorite(key, text, href) {
            const favs = this._getFavorites();
            const idx  = favs.findIndex(f => f.key === key);
            if (idx > -1) favs.splice(idx, 1);
            else favs.push({ key, text, href: href || '#' });
            this._saveFavorites(favs);
            this.rebuildFavoritesMenu();
        },

        reorderFavorites(fromKey, toKey) {
            const favs = this._getFavorites();
            const fi = favs.findIndex(f => f.key === fromKey);
            const ti = favs.findIndex(f => f.key === toKey);
            if (fi < 0 || ti < 0 || fi === ti) return;
            favs.splice(ti, 0, favs.splice(fi, 1)[0]);
            this._saveFavorites(favs);
            this.rebuildFavoritesMenu();
        },

        // ── FAVORITES MENU DOM ─────────────────────────────────────────────────────
        rebuildFavoritesMenu() {
            if (!location.href.includes('/World/Popmundo.aspx/Character')) return;
            document.getElementById('ppc-fav-menu')?.remove();
            document.getElementById('ppc-fav-spacer')?.remove();
            document.getElementById('ppc-fav-drag-tab')?.remove();

            const favs = this._getFavorites();
            if (!favs.length) return;

            const anchor = document.getElementById('top-vip-menu') ||
                [...document.querySelectorAll('.menu h3')]
                    .find(h => /Kariyer|Career|Carreira/.test(h.textContent))?.closest('.menu');
            if (!anchor) return;

            const isCol = localStorage.getItem('ppc-fav-collapsed') === 'true';
            const _Df = (tr, en, pt) => ({ TR: tr, EN: en, PT: pt }[LANG] || tr);
            const MM = this;

            const menu = document.createElement('div');
            menu.id = 'ppc-fav-menu'; menu.className = 'menu';

            // Başlık + badge
            const h3 = document.createElement('h3');
            h3.textContent = '⭐ ' + _Df('Sık Kullanılanlar', 'Favorites', 'Favoritos') + ` (${favs.length})`;
            h3.style.cssText = 'background:linear-gradient(135deg,#f093fb,#f5576c);color:#fff;text-align:center;padding:8px;margin:0;border-radius:6px 6px 0 0;cursor:pointer;box-shadow:0 2px 8px rgba(245,87,108,.25);user-select:none;font-size:inherit;font-weight:bold;';

            const content = document.createElement('div');
            content.style.cssText = `background:#fff9fe;border:1px solid #f0c0e8;border-top:none;border-radius:0 0 6px 6px;overflow:hidden;${isCol ? 'display:none;' : ''}`;

            const ul = document.createElement('ul');
            ul.id = 'ppc-fav-list';
            ul.style.cssText = 'margin:0;padding:6px 0 4px;list-style:none;';

            favs.forEach(fav => {
                const li = this._buildFavItem(fav, this._favDragActive);
                if (li) ul.appendChild(li);
            });
            if (this._favDragActive) this._attachFavDrag(ul);

            h3.onclick = () => {
                const open = content.style.display === 'none';
                content.style.display = open ? '' : 'none';
                localStorage.setItem('ppc-fav-collapsed', !open);
            };

            content.appendChild(ul);

            menu.append(h3, content);

            const spacer = document.createElement('div');
            spacer.id = 'ppc-fav-spacer'; spacer.style.cssText = 'height:6px;';

            anchor.before(menu);
            menu.after(spacer);

            // Sıralama kulakçığı — menünün ALTINDA (2+ favori varsa)
            if (favs.length > 1) {
                const tab = document.createElement('div');
                tab.id = 'ppc-fav-drag-tab';
                tab.title = _Df('Sıralama modunu aç/kapat', 'Toggle reorder mode', 'Alternar modo de reordenação');
                tab.textContent = '⇅ ' + (this._favDragActive
                    ? _Df('Bitti', 'Done', 'Concluído')
                    : _Df('Sırala', 'Reorder', 'Reordenar'));
                tab.style.cssText = [
                    'display:block;margin:0 auto;width:fit-content;padding:3px 14px',
                    `background:${this._favDragActive ? '#f5576c' : '#f0f0f0'}`,
                    `color:${this._favDragActive ? '#fff' : '#999'}`,
                    `border:1px solid ${this._favDragActive ? '#f5576c' : '#ddd'}`,
                    'border-top:none;border-radius:0 0 10px 10px',
                    'font-size:11px;cursor:pointer;transition:all .2s;user-select:none;'
                ].join(';');
                tab.onmouseover = () => { if (!this._favDragActive) { tab.style.background = '#e8e8e8'; tab.style.color = '#666'; } };
                tab.onmouseout  = () => { if (!this._favDragActive) { tab.style.background = '#f0f0f0'; tab.style.color = '#999'; } };
                tab.onclick = () => { MM._favDragActive = !MM._favDragActive; MM.rebuildFavoritesMenu(); };
                menu.after(tab);
                tab.after(spacer);
            }
        },

        _buildFavItem(fav, dragActive) {
            const MM = this;
            // Canlı href: DOM'dan normalize edilmiş key ile eşleştir
            let liveHref = fav.href || '#';
            if (fav.key.startsWith('#')) {
                const el = document.getElementById(fav.key.slice(1));
                const a  = el?.querySelector('a[href]') || (el?.tagName === 'A' ? el : null);
                if (a) liveHref = a.href;
            } else {
                // Normalize path → canlı DOM'dan bul (karakter ID değişse de çalışır)
                const match = [...document.querySelectorAll('.menu a[href]')]
                    .find(a => { try { return MM._normalizePath(new URL(a.href).pathname) === fav.key; } catch { return false; } });
                if (match) liveHref = match.href;
            }

            const li = document.createElement('li');
            li.dataset.favKey = fav.key;
            li.draggable = !!dragActive;
            li.style.cssText = 'margin:2px 0;display:flex;align-items:center;cursor:default;';

            // Grip — sadece sıralama modunda görünür
            const grip = document.createElement('span');
            grip.textContent = '⠿';
            grip.title = _D('Sıralamak için sürükle', 'Drag to reorder', 'Arraste p/ reordenar');
            grip.style.cssText = `color:#ccc;cursor:grab;padding:4px 2px 4px 8px;flex-shrink:0;font-size:14px;line-height:1;display:${dragActive ? 'inline' : 'none'};`;

            const a = document.createElement('a');
            a.href = liveHref;
            a.textContent = fav.text;
            a.style.cssText = 'color:#c0392b;font-weight:600;text-decoration:none;display:block;padding:4px 4px 4px 2px;border-radius:4px;transition:all .2s;flex:1;font-size:inherit;';
            a.onmouseover = () => { a.style.background = '#f5576c'; a.style.color = '#fff'; };
            a.onmouseout  = () => { a.style.background = '';        a.style.color = '#c0392b'; };

            li.append(grip, a);
            return li;
        },

        _attachFavDrag(ul) {
            let _fdk = null, _fdEl = null, _fdOver = null;
            const MM = this;
            ul.addEventListener('dragstart', e => {
                _fdEl = e.target.closest('li[data-fav-key]');
                if (!_fdEl) return;
                _fdk = _fdEl.dataset.favKey;
                e.dataTransfer.effectAllowed = 'move';
                setTimeout(() => { if (_fdEl) _fdEl.style.opacity = '.4'; }, 0);
            });
            ul.addEventListener('dragend', () => {
                if (_fdEl) _fdEl.style.opacity = '1';
                if (_fdOver) _fdOver.style.outline = '';
                _fdEl = null; _fdk = null; _fdOver = null;
            });
            ul.addEventListener('dragover', e => {
                e.preventDefault();
                const over = e.target.closest('li[data-fav-key]');
                if (_fdOver && _fdOver !== over) _fdOver.style.outline = '';
                if (over && over !== _fdEl) { over.style.outline = '2px dashed #f5576c'; _fdOver = over; }
            });
            ul.addEventListener('dragleave', e => {
                const over = e.target.closest('li[data-fav-key]');
                if (over) over.style.outline = '';
            });
            ul.addEventListener('drop', e => {
                e.preventDefault();
                const over = e.target.closest('li[data-fav-key]');
                if (over) over.style.outline = '';
                if (!_fdk || !over || over.dataset.favKey === _fdk) return;
                MM.reorderFavorites(_fdk, over.dataset.favKey);
            });
        },

        _attachTopVipDrag(ul) {
            let _dk = null, _dEl = null, _dOver = null;
            const MM = this;
            ul.addEventListener('dragstart', e => {
                _dEl = e.target.closest('li[data-tvip-key]');
                if (!_dEl) return;
                _dk = _dEl.dataset.tvipKey;
                e.dataTransfer.effectAllowed = 'move';
                setTimeout(() => { if (_dEl) _dEl.style.opacity = '.4'; }, 0);
            });
            ul.addEventListener('dragend', () => {
                if (_dEl) _dEl.style.opacity = '1';
                if (_dOver) _dOver.style.outline = '';
                _dEl = null; _dk = null; _dOver = null;
            });
            ul.addEventListener('dragover', e => {
                e.preventDefault();
                const over = e.target.closest('li[data-tvip-key]');
                if (_dOver && _dOver !== over) _dOver.style.outline = '';
                if (over && over !== _dEl) { over.style.outline = '2px dashed #667eea'; _dOver = over; }
            });
            ul.addEventListener('dragleave', e => {
                const over = e.target.closest('li[data-tvip-key]');
                if (over) over.style.outline = '';
            });
            ul.addEventListener('drop', e => {
                e.preventDefault();
                const over = e.target.closest('li[data-tvip-key]');
                if (over) over.style.outline = '';
                if (!_dk || !over || over.dataset.tvipKey === _dk) return;
                const cfg = MM.menuConfigs.get('top-vip');
                if (!cfg) return;
                const order = cfg.items.map(i => i.id);
                const fi = order.indexOf(_dk), ti = order.indexOf(over.dataset.tvipKey);
                if (fi < 0 || ti < 0) return;
                order.splice(ti, 0, order.splice(fi, 1)[0]);
                MM._saveTopVipOrder(order);
                MM.rebuildMenus();
            });
        },

        // ── NATIVE SECTIONS (grouped, for settings UI) ─────────────────────────────
        getNativeMenuSections() {
            const _Ds = (tr, en, pt) => ({ TR: tr, EN: en, PT: pt }[LANG] || tr);
            const sections = [];
            document.querySelectorAll('.box > .menu, .box > div > .menu').forEach(menuDiv => {
                if (['top-vip-menu','ppc-fav-menu'].includes(menuDiv.id)) return;
                const h3 = menuDiv.querySelector(':scope > h3');
                const title = h3 ? h3.textContent.trim() : _Ds('Karakter', 'Character', 'Personagem');
                const items = [];
                menuDiv.querySelectorAll('li').forEach(li => {
                    const a    = li.querySelector('a[href]');
                    const elId = li.id || li.querySelector('[id]')?.id;
                    const text = (a || li.querySelector('a') || li).textContent.trim();
                    if (!text) return;
                    let key = null, href = '#';
                    if (elId) {
                        key = '#' + elId;
                        href = a?.href || '#';
                    } else if (a) {
                        try { const p = new URL(a.href).pathname; key = this._normalizePath(p); href = a.href; } catch { key = a.getAttribute('href'); href = key; }
                    }
                    if (key && !items.some(i => i.key === key)) items.push({ key, text, href });
                });
                if (items.length) sections.push({ title, items });
            });
            return sections;
        },

        showMenuSettings() {
            this.openMenuCustomizationUI();
        },

        openMenuCustomizationUI() {
            if (document.getElementById('ppc-menu-settings')) return;

            const _Dm = (tr, en, pt) => ({ TR: tr, EN: en, PT: pt }[LANG] || tr);
            const MM = this;

            // ── CSS sabitleri ─────────────────────────────────────────────────────
            const CSS_OV  = 'position:fixed;inset:0;background:rgba(0,0,0,.75);z-index:100002;display:flex;align-items:center;justify-content:center;padding:16px;box-sizing:border-box';
            const CSS_BOX = 'background:#fff;border-radius:14px;padding:0;width:100%;max-width:540px;max-height:88vh;display:flex;flex-direction:column;box-sizing:border-box;font-family:inherit;box-shadow:0 10px 40px rgba(0,0,0,.3);overflow:hidden;';
            const CSS_HDR = 'display:flex;justify-content:space-between;align-items:center;padding:18px 20px 14px;border-bottom:2px solid #e9ecef;flex-shrink:0;';
            const CSS_SEC_WRAP  = 'margin-bottom:14px;';
            const CSS_SEC_HDR   = 'font-size:12px;font-weight:700;color:#fff;border-radius:6px;padding:5px 10px;margin-bottom:4px;cursor:pointer;user-select:none;display:flex;justify-content:space-between;align-items:center;';
            const CSS_SEC_LIST  = 'border-radius:0 0 6px 6px;border:1px solid #e9ecef;border-top:none;overflow:hidden;';
            const CSS_ROW_EVEN  = 'display:flex;align-items:center;gap:8px;padding:5px 10px;font-size:12px;background:#fff;transition:opacity .2s;';
            const CSS_ROW_ODD   = 'display:flex;align-items:center;gap:8px;padding:5px 10px;font-size:12px;background:#f8f9fa;transition:opacity .2s;';
            const CSS_ACT_BTN   = 'background:none;border-radius:4px;cursor:pointer;padding:2px 5px;flex-shrink:0;transition:all .2s;';
            const CSS_X_BTN     = 'background:none;border:none;font-size:22px;cursor:pointer;color:#aaa;padding:0;width:32px;height:32px;display:flex;align-items:center;justify-content:center;border-radius:6px;';

            // ── Bölüm başlığı oluşturucu (collapsed state kalıcı) ─────────────────
            const mkSecHdr = (label, gradient) => {
                const sKey = 'ppc-sec-' + label.replace(/\W+/g, '_');
                let open = localStorage.getItem(sKey) === 'true';
                const wrap = mk('div'); wrap.style.cssText = CSS_SEC_WRAP;
                const hdr  = mk('div');
                hdr.style.cssText = CSS_SEC_HDR + `background:${gradient || 'linear-gradient(135deg,#667eea,#764ba2)'};`;
                const ttl = mk('span'); ttl.textContent = label;
                const arr = mk('span'); arr.textContent = '▼';
                arr.style.cssText = 'font-size:9px;opacity:.7;transition:transform .2s;';
                if (!open) arr.style.transform = 'rotate(-90deg)';
                hdr.append(ttl, arr);
                const list = mk('div');
                list.style.cssText = CSS_SEC_LIST + `background:${gradient ? '#fffdf8' : '#f8f9fa'};` + (open ? '' : 'display:none;');
                hdr.onclick = () => {
                    open = !open;
                    localStorage.setItem(sKey, open);
                    list.style.display = open ? '' : 'none';
                    arr.style.transform = open ? '' : 'rotate(-90deg)';
                };
                wrap.append(hdr, list);
                return { wrap, list };
            };

            // ── Satır oluşturucu ──────────────────────────────────────────────────
            const mkItemRow = (item, idx, isFav, isHidden, onFav, onVis) => {
                const row = mk('div');
                row.style.cssText = (idx % 2 === 0 ? CSS_ROW_EVEN : CSS_ROW_ODD) + (isHidden ? 'opacity:.4;' : '');
                const itemText = mk('span'); itemText.textContent = item.text; itemText.style.cssText = 'flex:1;color:#2c3e50;';
                if (onFav !== null) {
                    const favBtn = mk('button'); favBtn.type = 'button';
                    favBtn.textContent = isFav ? '⭐' : '☆';
                    favBtn.title = isFav ? _Dm('Favorilerden çıkar','Remove','Remover') : _Dm('Favorilere ekle','Add to favorites','Adicionar');
                    favBtn.style.cssText = CSS_ACT_BTN + `border:1px solid ${isFav ? '#f5576c' : '#ddd'};font-size:13px;`;
                    favBtn.onmouseover = () => { favBtn.style.background = isFav ? '#fff0f0' : '#fffbe0'; };
                    favBtn.onmouseout  = () => { favBtn.style.background = 'none'; };
                    favBtn.onclick = onFav;
                    row.appendChild(favBtn);
                }
                const visBtn = mk('button'); visBtn.type = 'button';
                visBtn.textContent = isHidden ? '🚫' : '👁';
                visBtn.title = isHidden ? _Dm('Göster','Show','Mostrar') : _Dm('Gizle','Hide','Ocultar');
                visBtn.style.cssText = CSS_ACT_BTN + `border:1px solid ${isHidden ? '#dc3545' : '#ddd'};font-size:12px;`;
                visBtn.onmouseover = () => { visBtn.style.background = '#f8f9fa'; };
                visBtn.onmouseout  = () => { visBtn.style.background = 'none'; };
                visBtn.onclick = onVis;
                row.append(itemText, visBtn);
                return row;
            };

            // ── Overlay & kutu ────────────────────────────────────────────────────
            const ov = mk('div');
            ov.id = 'ppc-menu-settings';
            ov.style.cssText = CSS_OV;
            const box = mk('div');
            box.style.cssText = CSS_BOX;

            // ── Başlık ────────────────────────────────────────────────────────────
            const hdr = mk('div');
            hdr.style.cssText = CSS_HDR;
            const title = mk('span');
            title.textContent = '🗂️ ' + _Dm('Menü Yönetimi', 'Menu Manager', 'Gerenciar Menu');
            title.style.cssText = 'font-weight:700;font-size:17px;color:#2c3e50;';
            const xBtn = mk('button');
            xBtn.textContent = '✕'; xBtn.type = 'button';
            xBtn.style.cssText = CSS_X_BTN;
            xBtn.onmouseover = () => xBtn.style.background = '#f8f9fa';
            xBtn.onmouseout  = () => xBtn.style.background = 'none';
            xBtn.onclick = () => ov.remove();
            hdr.append(title, xBtn);
            box.appendChild(hdr);

            // ── İpucu bandı ───────────────────────────────────────────────────────
            const tip = mk('div');
            tip.style.cssText = 'background:#e8f4fd;padding:8px 20px;font-size:11px;color:#1a5276;display:flex;gap:20px;flex-shrink:0;border-bottom:1px solid #d6eaf8;flex-wrap:wrap;';
            tip.innerHTML = `
                <span>⭐ ${_Dm('Favori ekle', 'Add to favorites', 'Adicionar favorito')}</span>
                <span>👁 ${_Dm('Göster/Gizle', 'Show/Hide', 'Mostrar/Ocultar')}</span>
                <span>⇅ ${_Dm('Menü altındaki kulakçık ile sırala', 'Use the tab below each menu to reorder', 'Use a aba abaixo do menu p/ reordenar')}</span>
            `;
            box.appendChild(tip);

            // ── Scrollable içerik ─────────────────────────────────────────────────
            const body = mk('div');
            body.style.cssText = 'overflow-y:auto;flex:1;padding:12px 16px 16px;';
            box.appendChild(body);

            const hidden = JSON.parse(localStorage.getItem('hidden-native-menu-items') || '[]');
            const favs   = this._getFavorites();

            // ── TOP VIP bölümü ────────────────────────────────────────────────────
            const tvipCfg = this.menuConfigs.get('top-vip');
            if (tvipCfg && tvipCfg.items.length) {
                const { wrap: tvWrap, list: tvList } = mkSecHdr(
                    '⭐ TOP VIP (' + tvipCfg.items.length + ')',
                    'linear-gradient(135deg,#667eea 0%,#764ba2 100%)'
                );
                tvipCfg.items.forEach((item, idx) => {
                    const key = '#' + item.id;
                    const isHidden = hidden.includes(key);
                    const row = mkItemRow(
                        { text: item.label, key },
                        idx, false, isHidden,
                        null,
                        () => { MM.toggleNativeItemVisibility(key, isHidden); ov.remove(); MM.openMenuCustomizationUI(); }
                    );
                    row.querySelector('span').style.cssText = 'flex:1;color:#667eea;font-weight:600;';
                    tvList.appendChild(row);
                });
                body.appendChild(tvWrap);
            }

            // ── Favoriler özeti (tag cloud) ───────────────────────────────────────
            if (favs.length) {
                const favHdr = mk('div');
                favHdr.style.cssText = 'font-weight:600;font-size:13px;color:#c0392b;margin:4px 0 8px;display:flex;align-items:center;gap:6px;';
                favHdr.innerHTML = `⭐ ${_Dm('Sık Kullanılanlar', 'Favorites', 'Favoritos')} <span style="font-weight:400;font-size:11px;color:#888;">(${_Dm('menü altındaki ⇅ ile sırala', 'use ⇅ tab below menu to reorder', 'use aba ⇅ abaixo p/ reordenar')})</span>`;
                body.appendChild(favHdr);
                const favList = mk('div');
                favList.style.cssText = 'background:#fff0fb;border:1px solid #f0c0e8;border-radius:8px;padding:6px 10px;margin-bottom:14px;display:flex;flex-wrap:wrap;gap:4px;';
                favs.forEach(fav => {
                    const tag = mk('span');
                    tag.style.cssText = 'background:#f5576c;color:#fff;border-radius:20px;padding:2px 10px 2px 8px;font-size:11px;display:inline-flex;align-items:center;gap:4px;';
                    tag.innerHTML = `${fav.text} <button type="button" style="background:none;border:none;color:#fff;cursor:pointer;font-size:13px;padding:0;line-height:1;opacity:.8;" title="${_Dm('Favorilerden çıkar','Remove','Remover')}">✕</button>`;
                    tag.querySelector('button').onclick = () => { MM.toggleFavorite(fav.key,fav.text,fav.href); ov.remove(); MM.openMenuCustomizationUI(); };
                    favList.appendChild(tag);
                });
                body.appendChild(favList);
            }

            // ── Bölüm bazlı native menü linkleri ─────────────────────────────────
            const sections = this.getNativeMenuSections();
            sections.forEach(sec => {
                const { wrap: secWrap, list: secList } = mkSecHdr(sec.title);
                sec.items.forEach((item, idx) => {
                    const isFav    = favs.some(f => f.key === item.key);
                    const isHidden = hidden.includes(item.key);
                    const row = mkItemRow(
                        item, idx, isFav, isHidden,
                        () => { MM.toggleFavorite(item.key, item.text, item.href); ov.remove(); MM.openMenuCustomizationUI(); },
                        () => { MM.toggleNativeItemVisibility(item.key, isHidden); ov.remove(); MM.openMenuCustomizationUI(); }
                    );
                    secList.appendChild(row);
                });
                body.appendChild(secWrap);
            });

            if (!sections.length) {
                const empty = mk('div');
                empty.style.cssText = 'text-align:center;color:#aaa;padding:32px;font-size:13px;';
                empty.textContent = _Dm('Karakter sayfasında açın.', 'Open on the character page.', 'Abra na página do personagem.');
                body.appendChild(empty);
            }

            // ── Alt buton ─────────────────────────────────────────────────────────
            const footer = mk('div');
            footer.style.cssText = 'padding:12px 20px;border-top:1px solid #e9ecef;display:flex;gap:8px;flex-shrink:0;background:#fafafa;border-radius:0 0 14px 14px;';

            const resetAllBtn = mk('button');
            resetAllBtn.type = 'button';
            resetAllBtn.textContent = '🔄 ' + _Dm('Tümünü Sıfırla', 'Reset All', 'Redefinir Tudo');
            resetAllBtn.style.cssText = 'padding:8px 14px;background:#6c757d;color:#fff;border:none;border-radius:6px;cursor:pointer;font-size:12px;font-weight:600;transition:all .2s;';
            resetAllBtn.onmouseover = () => resetAllBtn.style.background = '#5a6268';
            resetAllBtn.onmouseout  = () => resetAllBtn.style.background = '#6c757d';
            resetAllBtn.onclick = () => {
                if (!confirm(_Dm('Tüm gizleme ve favori ayarları sıfırlansın mı?', 'Reset all hide/favorite settings?', 'Redefinir todas as configurações?'))) return;
                localStorage.removeItem('hidden-native-menu-items');
                localStorage.removeItem('ppc-favorites');
                localStorage.removeItem('top-vip-collapsed');
                localStorage.removeItem('ppc-fav-collapsed');
                localStorage.removeItem('ppc-tvip-order');
                MM._favDragActive  = false;
                MM._tvipDragActive = false;
                MM.rebuildMenus();
                ov.remove();
            };

            const closeBtn = mk('button');
            closeBtn.type = 'button';
            closeBtn.textContent = _Dm('Kapat', 'Close', 'Fechar');
            closeBtn.style.cssText = 'flex:1;padding:8px;background:#3498db;color:#fff;border:none;border-radius:6px;cursor:pointer;font-size:13px;font-weight:600;transition:all .2s;';
            closeBtn.onmouseover = () => closeBtn.style.background = '#2980b9';
            closeBtn.onmouseout  = () => closeBtn.style.background = '#3498db';
            closeBtn.onclick = () => ov.remove();

            footer.append(resetAllBtn, closeBtn);
            box.appendChild(footer);

            ov.onclick = e => { if (e.target === ov) ov.remove(); };
            ov.appendChild(box);
            document.body.appendChild(ov);
        },

        getNativeMenuItems() {
            return this.getNativeMenuSections().flatMap(s => s.items);
        },

        toggleNativeItemVisibility(key, show) {
            const hidden = JSON.parse(localStorage.getItem('hidden-native-menu-items') || '[]');
            const idx = hidden.indexOf(key);
            if (show  && idx > -1) hidden.splice(idx, 1);
            if (!show && idx < 0)  hidden.push(key);
            localStorage.setItem('hidden-native-menu-items', JSON.stringify(hidden));
            this.applyNativeItemVisibility();
        },

        applyNativeItemVisibility() {
            const hidden = JSON.parse(localStorage.getItem('hidden-native-menu-items') || '[]');
            document.querySelectorAll('.menu li').forEach(li => {
                if (li.closest('#ppc-fav-menu')) return;
                const a    = li.querySelector('a[href]');
                const elId = li.id || li.querySelector('[id]')?.id;
                let key = null;
                if (elId) {
                    key = '#' + elId;
                } else if (a) {
                    try { key = this._normalizePath(new URL(a.href).pathname); } catch { key = a.getAttribute('href'); }
                }
                if (!key) return;
                li.style.display = hidden.includes(key) ? 'none' : '';
            });
        }
    }
};

// Global API
const _finalAPI = {
    ...API,
    register: (cfg) => {
        if (!_processed.has(cfg.id)) {
            API.register(cfg);
            _processed.add(cfg.id);
        } else {
            log(`Already registered: ${cfg.id}, skipping`);
        }
    },
    isReady: false
};

window.PopControl = _finalAPI;
if (typeof unsafeWindow !== 'undefined') {
    unsafeWindow.PopControl = _finalAPI;
}

// Process queue
_queue.forEach(cfg => {
    if (!_processed.has(cfg.id)) {
        API.register(cfg);
        _processed.add(cfg.id);
    }
});
log(`Processed ${_queue.length} queued items, ${_processed.size} total registered`);

// Ready signal
let _readyFired = false;
const _fireReady = () => {
    if (_readyFired) return;
    _readyFired = true;
    _finalAPI.isReady = true;
    document.dispatchEvent(new CustomEvent('PopControlReady'));
    console.log('[PopControl] Ready signal sent, API is now available');
};

setTimeout(_fireReady, 20);

// ─── KEYBOARD SHORTCUT ─────────────────────────────────────────────────────────
document.addEventListener('keydown', function(e) {
    if (e.altKey && (e.key === 'p' || e.key === 'P')) {
        e.preventDefault();
        const bar = document.getElementById('ppc-bar');
        const fab = document.getElementById('ppc-fab');
        if (!bar) { _setCollapsed(!_collapsed); return; }
        _setCollapsed(!_collapsed);
        bar.style.display = _collapsed ? 'none' : '';
        if (fab) {
            fab.style.display = _collapsed ? 'flex' : 'none';
            if (_collapsed) _positionFab(fab);
        }
    }
});

// ─── INITIALIZATION ───────────────────────────────────────────────────────────
(function _init() {
    const go = () => {
        _rebuild();
        // MenuManager sadece karakter sayfasında, tek seferlik
        if (location.href.includes('/World/Popmundo.aspx/Character')) {
            // PopControl'ün kendi TOP VIP butonu
            const _ppcBtn = { id: 'mnu-ppc-settings', label: _D('🛠️ PopControl Ayarlar', '🛠️ PopControl Settings', '🛠️ Config PopControl'), fn: _openSettings };
            API.MenuManager.registerMenu({ id: 'top-vip', title: '⭐ TOP VIP ⭐', position: 'above-career', items: [_ppcBtn], collapsible: true });
            setTimeout(() => API.MenuManager.rebuildMenus(), 200);
        }
    };
    
    if (document.getElementById('ppm-main') || document.getElementById('ppm-footer')) { go(); return; }
    
    const obs = new MutationObserver(() => {
        if (document.getElementById('ppm-main') || document.getElementById('ppm-footer')) { 
            obs.disconnect(); 
            go(); 
        }
    });
    obs.observe(document.body, { childList: true, subtree: true });
    setTimeout(() => { obs.disconnect(); go(); }, 4000);
    
    // SPA navigasyon — throttle + subtree:false (performans)
    let _lastUrl = location.href;
    let _spaTimer = null;
    new MutationObserver(() => {
        if (location.href === _lastUrl) return;
        _lastUrl = location.href;
        clearTimeout(_spaTimer);
        _spaTimer = setTimeout(() => {
            if (location.href.includes('/World/Popmundo.aspx/Character')) {
                API.MenuManager.rebuildMenus();
            }
        }, 300);
    }).observe(document.body, { childList: true, subtree: false });
})();

})();