📦 Depot

Popmundo envanter paneli — çok dilli arayüz, otomatik tarama, arama, fiyat takibi ve CSV

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// ==UserScript==
// @name         📦 Depot
// @name:en      📦 Depot
// @name:pt-BR   📦 Depot
// @namespace    popmundo.inventory
// @version      2.1
// @description  Popmundo envanter paneli — çok dilli arayüz, otomatik tarama, arama, fiyat takibi ve CSV
// @description:en  Popmundo inventory panel — multilingual UI, auto-scan, search, price tracking & CSV export
// @description:pt-BR Painel de inventário Popmundo — multilíngue, varredura automática, busca, preços e CSV
// @author       luke-james-gibson
// @license      MIT
// @id           dpv9q3
// @supportURL   https://greasyfork.org/tr/scripts/568770-popmundo-envanter
// @match        https://*.popmundo.com/*
// @grant        GM_getValue
// @grant        GM_setValue
// @grant        GM_deleteValue
// @grant        unsafeWindow
// ==/UserScript==

(function () {
    'use strict';

    // ─── POPCONTROL DISABLE CHECK ────────────────────────────────────────────────
    try { const _ppc = JSON.parse(localStorage.getItem('ppc_enabled')||'{}'); if (_ppc['depot'] === false) return; } catch {}

    // Language
    const LANG = (() => { try { const c = document.cookie.match(/ppm_lang=([^;]+)/); return c ? c[1] : 'TR'; } catch { return 'TR'; } })();
    const _D = (tr, en, pt) => ({ TR: tr, EN: en, 'PT-BR': pt }[LANG] || tr);
    const S = {
        // Scan modal
        scanTitle:       _D('🔄 Otomatik Tarama',              '🔄 Auto Scan',                          '🔄 Varredura Automática'),
        scanPersonal:    _D('👤 Kişisel Eşyalar',              '👤 Personal Items',                     '👤 Itens Pessoais'),
        scanVehicles:    _D('🚗 Kişisel Araçlar',              '🚗 Personal Vehicles',                  '🚗 Veículos Pessoais'),
        scanHousing:     _D('🏠 Evler',                        '🏠 Housing',                            '🏠 Moradias'),
        scanArtist:      _D('🎵 Sanatçı / Turne Aracı',       '🎵 Artist / Tour Vehicle',              '🎵 Artista / Veículo de Turnê'),
        scanWarn:        _D('⚠️ Tarama sırasında sekmeler otomatik değişir.', '⚠️ Tabs will change automatically during scan.', '⚠️ As abas mudarão automaticamente durante a varredura.'),
        scanCancel:      _D('İptal',                           'Cancel',                                'Cancelar'),
        scanStart:       _D('▶ Taramayı Başlat',               '▶ Start Scan',                          '▶ Iniciar Varredura'),
        scanSelectOne:   _D('En az bir kategori seçin.',       'Select at least one category.',         'Selecione pelo menos uma categoria.'),
        // Scan report
        scanDone:        _D('✅ Tarama Tamamlandı',             '✅ Scan Complete',                      '✅ Varredura Concluída'),
        scanLocCount:    _D('Taranan Lokasyon:',               'Scanned Locations:',                    'Locais Varridos:'),
        scanItemCount:   _D('Toplam Eşya:',                    'Total Items:',                          'Total de Itens:'),
        scanClose:       _D('Kapat',                           'Close',                                 'Fechar'),
        // Scan prompts / logs
        scanAskId:       _D('Karakter ID girin:',              'Enter Character ID:',                   'Digite o ID do Personagem:'),
        scanBadId:       _D('Geçerli ID girilmedi.',           'No valid ID entered.',                  'Nenhum ID válido inserido.'),
        scanVehList:     _D('🔍 Araç listesi:',                '🔍 Vehicle list:',                      '🔍 Lista de veículos:'),
        scanVehUnit:     _D('araç.',                           'vehicles.',                             'veículos.'),
        scanHouseList:   _D('🔍 Ev listesi:',                  '🔍 Housing list:',                      '🔍 Lista de moradias:'),
        scanHouseUnit:   _D('ev.',                             'properties.',                           'imóveis.'),
        scanLogOk:       _D('çeşit.',                          'types.',                                'tipos.'),
        scanLogEmpty:    _D('eşya yok.',                       'no items.',                             'sem itens.'),
        scanStop:        _D('🛑 DURDUR',                       '🛑 STOP',                               '🛑 PARAR'),
        // Panel
        panelTitle:      '📦 Depot ' + GM_info.script.version,
        dragHint:        _D('⠿ Sürükle',                      '⠿ Drag',                                '⠿ Arrastar'),
        btnSettings:     _D('Panel Ayarları',                 'Panel Settings',                        'Configurações do Painel'),
        btnBackup:       _D('📤 Scripti Yedekle',              '📤 Backup Script',                      '📤 Fazer Backup'),
        btnRestore:      _D('📥 Yedeği Yükle',                 '📥 Load Backup',                        '📥 Carregar Backup'),
        catLabel:        _D('Kategori CSV (Kategori,Eşya):',   'Category CSV (Category,Item):',         'CSV de Categorias (Categoria,Item):'),
        catPlaceholder:  _D('Kategori,Eşya Adı',               'Category,Item Name',                    'Categoria,Nome do Item'),
        btnCatSave:      _D('💾 Kategorileri Güncelle',        '💾 Update Categories',                  '💾 Atualizar Categorias'),
        btnClearAll:     _D('⚠️ Tüm Veriyi Sıfırla',          '⚠️ Reset All Data',                     '⚠️ Redefinir Todos os Dados'),
        btnSavePage:     _D('📍 Sayfayı Kaydet',               '📍 Save Page',                          '📍 Salvar Página'),
        btnDelRecord:    _D('🗑️ Kaydı Sil',                   '🗑️ Delete Record',                     '🗑️ Excluir Registro'),
        btnInventory:    _D('Envanter İşlemleri',             'Inventory Actions',                     'Ações de Inventário'),
        btnAutoScan:     _D('🔄 OTOMATİK TARA',                '🔄 AUTO SCAN',                          '🔄 VARREDURA AUTOMÁTICA'),
        btnListManage:   _D('📋 ENVANTERLERİ LİSTELE / YÖNET','📋 LIST / MANAGE INVENTORIES',          '📋 LISTAR / GERENCIAR INVENTÁRIOS'),
        btnDetailed:     _D('📄 Detaylı CSV',                  '📄 Detailed CSV',                       '📄 CSV Detalhado'),
        btnStockCSV:     _D('📊 Stok & Fiyatlı CSV',           '📊 Stock & Priced CSV',                 '📊 CSV de Estoque & Preços'),
        btnImportCSV:    _D('📥 CSV Yükle',                    '📥 Import CSV',                         '📥 Importar CSV'),
        searchPH:        _D('Envanterde ara (Örn: Haiku)...',  'Search inventory (e.g. Haiku)...',      'Buscar no inventário (ex: Haiku)...'),
        // Alerts
        alertNoItems:    _D('Bu sayfada eşya bulunamadı.',     'No items found on this page.',          'Nenhum item encontrado nesta página.'),
        alertDeleted:    _D('Silindi.',                        'Deleted.',                              'Excluído.'),
        alertNotFound:   _D('Kayıt bulunamadı.',               'Record not found.',                     'Registro não encontrado.'),
        alertEnterData:  _D('Veri girin.',                     'Enter data.',                           'Insira os dados.'),
        alertCatFmt:     _D("Format hatalı! 'Kategori,Eşya'", "Invalid format! 'Category,Item'",       "Formato inválido! 'Categoria,Item'"),
        alertClearConf:  _D('Tüm DB sıfırlanacak!',           'All data will be reset!',               'Todos os dados serão redefinidos!'),
        alertRestored:   _D('Geri yüklendi.',                  'Restored.',                             'Restaurado.'),
        alertInvalidFile:_D('Geçersiz dosya.',                 'Invalid file.',                         'Arquivo inválido.'),
        // List
        listEmpty:       _D('Veritabanı boş.',                 'Database empty.',                       'Banco de dados vazio.'),
        btnDelAll:       _D('Tümünü Sil',                      'Delete All',                            'Excluir Tudo'),
        btnDel:          _D('SİL',                             'DEL',                                   'EXC'),
        confirmDel:      _D('Bu kayıt silinsin mi?',           'Delete this record?',                   'Excluir este registro?'),
        // Search
        noResults:       _D('Sonuç bulunamadı.',               'No results found.',                     'Nenhum resultado encontrado.'),
        totalLabel:      _D('Toplam',                          'Total',                                 'Total'),
        lastScanLabel:   _D('Son tarama:',                     'Last scan:',                            'Última varredura:'),
        btnCopy:         _D('📋 Bu sonuçları kopyala',         '📋 Copy these results',                 '📋 Copiar estes resultados'),
        btnCopied:       _D('✅ Kopyalandı',                   '✅ Copied',                             '✅ Copiado'),
        noPriceLabel:    _D('Teklif ediniz',                   'Make an offer',                         'Consultar preço'),
        // clsLbl
        clsPersonal:     _D('Eşyalar',                         'Items',                                 'Itens'),
        clsVehicle:      _D('Kişisel Araç',                    'Personal Vehicle',                      'Veículo Pessoal'),
        clsHousing:      _D('Ev',                              'Housing',                               'Moradia'),
        clsArtist:       _D('Sanatçı Aracı',                   'Artist Vehicle',                        'Veículo do Artista'),
        minTooltip:      _D('Paneli aç',                       'Open panel',                            'Abrir painel'),
        btnMinimize:     _D('Küçült',                          'Minimize',                              'Minimizar'),
        btnClose:        _D('Kapat',                           'Close',                                 'Fechar'),
        // Loc name fallbacks
        locVehicleFb:    _D('Kişisel Araç',                    'Personal Vehicle',                      'Veículo Pessoal'),
        locLocaleFb:     _D('Mekan',                           'Locale',                                'Local'),
        locCharFb:       _D('Karakter',                        'Character',                             'Personagem'),
        locInvSuffix:    _D('Envanteri',                       'Inventory',                             'Inventário'),
        locArtistFb:     _D('Grup Aracı',                      'Artist Vehicle',                        'Veículo do Artista'),
        locUnknown:      _D('Bilinmeyen',                      'Unknown',                               'Desconhecido'),
        variantDefault:  _D('Standart',                        'Standard',                              'Padrão'),
    };
    const _clDepot = (() => { try { const v = localStorage.getItem('ppc_lc_depot'); return v ? JSON.parse(v) : null; } catch { return null; } })();
    const s = k => (_clDepot && _clDepot[k]) ? _clDepot[k] : (S[k] || k);

    // GM Storage helpers
    const gmGet  = (k,def) => { try { const v=GM_getValue(k,null); return v?JSON.parse(v):def; } catch { return def; } };
    const gmSet  = (k,v)   => GM_setValue(k, JSON.stringify(v));
    const gmDel  = (k)     => GM_deleteValue(k);

    // localStorage helpers (scan state only)
    const lsGet  = (k,def) => { try { const v=localStorage.getItem(k); return v?JSON.parse(v):def; } catch { return def; } };
    const lsSet  = (k,v)   => localStorage.setItem(k, JSON.stringify(v));
    const lsDel  = (k)     => localStorage.removeItem(k);

    // Storage keys
    const K = { db:'pop_inv_data', cat:'pop_cat_data', price:'pop_price_data', veh:'pop_vehicle_names', char:'pop_char_id', owner:'pop_owner_name', theme:'pop_theme', min:'pop_min', pw:'pop_panel_w', pos:'pop_panel_pos', posMin:'pop_panel_pos_min', scan:'pop_scan_state' };

    // DB cache
    let _db=null, _prices=null;
    const getDB      = ()  => _db     || (_db=gmGet(K.db,{}));
    const saveDB     = (v) => { _db=v;     gmSet(K.db,v); };
    const getPrices  = ()  => _prices || (_prices=gmGet(K.price,{}));
    const savePrices = (v) => { _prices=v; gmSet(K.price,v); };

    // Utilities
    const today     = ()    => { const d=new Date(); return `${String(d.getDate()).padStart(2,'0')}.${String(d.getMonth()+1).padStart(2,'0')}.${d.getFullYear()}`; };
    const getCats   = ()    => gmGet(K.cat,{Manuscripts:['Fıkra','Haiku'],Drugs:['Ağrı Kesici','Afrodizyak İksiri']});
    const saveCats  = (v)   => gmSet(K.cat,v);
    const getCat    = (n)   => { for (const [c,items] of Object.entries(getCats())) if (items.includes(n)) return c; return 'Diğer'; };
    const theme     = ()    => GM_getValue(K.theme,'')||'dark';
    const priceKey  = (n,v) => `${n}|||${v}`;
    const esc       = (v)   => String(v).replace(/&/g,'&').replace(/"/g,'"');
    const normV     = (v)   => v.replace(/\.\s*$/,'').trim();
    const dlCSV     = (content,name) => { const a=document.createElement('a'); a.href=URL.createObjectURL(new Blob([content],{type:'text/csv;charset=utf-8;'})); a.download=name; a.click(); };
    const randDelay = ()    => 2000 + Math.floor(Math.random()*1500);
    const getTitle  = ()    => document.title.replace(/^.*?Popmundo\s*[-–]\s*/i,'').trim();

    // Scan state
    const getScan  = ()    => lsGet(K.scan, {active:false,queue:[],index:0,logs:[]});
    const saveScan = (st)  => lsSet(K.scan, st);

    // Scan: sayfa ayrıştırma
    const getLocInfo = (u) => {
        if (u.includes('/Character/Vehicle/')) {
            const veh=gmGet(K.veh,{}), rel=u.replace(/^https?:\/\/[^/]+/,'');
            return { name:veh[u]||veh[rel]||getTitle()||s('locVehicleFb'), type:'Araç' };
        }
        if (u.includes('/Locale/ItemsEquipment/')) {
            const h2=document.querySelector('.localebox h2')?.innerText.trim();
            const city=document.querySelector('.localebox .right a')?.innerText.trim();
            return { name:h2?(city?`${h2} (${city})`:h2):(getTitle()||s('locLocaleFb')), type:'Mekan' };
        }
        if (u.includes('/Character/Items/')) {
            const n=document.querySelector('.charPresBox h2')?.innerText.trim()||getTitle();
            return { name:`${n||s('locCharFb')} ${s('locInvSuffix')}`, type:'Kişisel' };
        }
        if (u.includes('/Artist/VehicleItems/')) return { name:getTitle()||s('locArtistFb'), type:'Grup Aracı' };
        return { name:s('locUnknown'), type:'Genel' };
    };

    const getOwner = () => {
        const el=document.querySelector('.charPresBox h2');
        if (el) { const n=el.innerText.trim(); GM_setValue(K.owner,n); return n; }
        return GM_getValue(K.owner,'')||s('locCharFb');
    };

    const extractVariant = (anchor) => {
        const td=anchor.closest('td')||anchor.parentElement, clone=td.cloneNode(true);
        clone.querySelector('[id*="lnkItem"]')?.remove();
        clone.querySelectorAll('.tvip-item-id, .tvis-ia-wrap').forEach(el => el.remove());
        const cEm=Array.from(clone.querySelectorAll('em')).find(e=>/^x\d+/i.test(e.textContent.trim()));
        if (cEm) cEm.remove();
        return clone.textContent.replace(/\s+/g,' ').trim()||s('variantDefault');
    };

    const updatePage = () => {
        const u=window.location.href, info=getLocInfo(u), owner=getOwner(), db=getDB(), map={};
        document.querySelectorAll('tr.hoverable').forEach(row => {
            const a=row.querySelector('a[id*="lnkItem"]'); if (!a) return;
            const name=a.innerText.trim(), em=row.querySelector('em');
            const count=em&&/^x\d+/i.test(em.textContent.trim())?(parseInt(em.textContent.replace(/[^\d]/g,''))||1):1;
            const variant=extractVariant(a);
            if (!map[name]) map[name]={variants:{}};
            map[name].variants[variant]=(map[name].variants[variant]||0)+count;
        });
        const cnt=Object.keys(map).length;
        if (cnt>0) {
            if (!db[owner]) db[owner]={};
            db[owner][u]={locType:info.name,locClass:info.type,url:u,lastUpdate:today(),
                items:Object.entries(map).map(([n,d])=>({name:n,variants:d.variants}))};
            _db=db; saveDB(db);
        }
        return cnt;
    };

    // Scan: modal & rapor
    const ovStyle   = 'position:fixed;inset:0;background:rgba(0,0,0,.8);z-index:9999999;display:flex;align-items:center;justify-content:center;';
    const modalWrap = (inner) => '<div style="background:#1a1a1a;border-radius:10px;padding:24px;max-width:420px;width:92%;color:#e0e0e0;font-family:Arial,sans-serif;">'+inner+'</div>';

    const showScanModal = (onConfirm) => {
        const ov=document.createElement('div'); ov.style.cssText=ovStyle;
        ov.innerHTML=modalWrap(
            '<div style="font-size:15px;font-weight:bold;color:#3498db;margin-bottom:12px;">'+s('scanTitle')+'</div>'
            +'<div style="display:flex;flex-direction:column;gap:10px;margin-bottom:14px;">'
            +'<label style="display:flex;align-items:center;gap:8px;font-size:12px;cursor:pointer;"><input type="checkbox" id="sc-p" checked> '+s('scanPersonal')+'</label>'
            +'<label style="display:flex;align-items:center;gap:8px;font-size:12px;cursor:pointer;"><input type="checkbox" id="sc-v" checked> '+s('scanVehicles')+'</label>'
            +'<label style="display:flex;align-items:center;gap:8px;font-size:12px;cursor:pointer;"><input type="checkbox" id="sc-h" checked> '+s('scanHousing')+'</label>'
            +'<label style="display:flex;align-items:center;gap:8px;font-size:12px;cursor:pointer;"><input type="checkbox" id="sc-a" checked> '+s('scanArtist')+'</label>'
            +'</div>'
            +'<div style="font-size:10px;color:#aaa;background:#222;border-radius:4px;padding:8px;margin-bottom:14px;">'+s('scanWarn')+'</div>'
            +'<div style="display:flex;gap:8px;">'
            +'<button id="sc-cancel" style="flex:1;padding:10px;background:none;color:#dc3545;border:1px solid #dc3545;border-radius:5px;cursor:pointer;font-weight:bold;">'+s('scanCancel')+'</button>'
            +'<button id="sc-start" style="flex:2;padding:10px;background:#0056b3;color:white;border:none;border-radius:5px;cursor:pointer;font-weight:bold;">'+s('scanStart')+'</button>'
            +'</div>'
        );
        document.body.appendChild(ov);
        document.getElementById('sc-cancel').onclick=()=>ov.remove();
        document.getElementById('sc-start').onclick=()=>{
            const opts={personal:document.getElementById('sc-p').checked,vehicles:document.getElementById('sc-v').checked,housing:document.getElementById('sc-h').checked,artist:document.getElementById('sc-a').checked};
            if (!Object.values(opts).some(Boolean)){alert(s('scanSelectOne'));return;}
            ov.remove(); onConfirm(opts);
        };
    };

    const showScanReport = (state) => {
        const db=getDB(); let totI=0,totL=0;
        Object.values(db).forEach(od=>{totL+=Object.keys(od).length;Object.values(od).forEach(e=>e.items.forEach(it=>Object.values(it.variants).forEach(c=>{totI+=Number(c)||0;})));});
        const ov=document.createElement('div'); ov.style.cssText=ovStyle.replace('9999999','9999998');
        ov.innerHTML=modalWrap(
            '<div style="font-size:16px;font-weight:bold;color:#2ecc71;margin-bottom:12px;">'+s('scanDone')+'</div>'
            +'<div style="background:#222;border-radius:5px;padding:10px;margin-bottom:10px;font-size:13px;">'
            +'<div>'+s('scanLocCount')+' <b style="color:#2ecc71">'+totL+'</b></div>'
            +'<div>'+s('scanItemCount')+' <b style="color:#2ecc71">'+totI+'</b></div></div>'
            +'<div style="background:#222;border-radius:5px;padding:8px;max-height:180px;overflow-y:auto;font-size:11px;font-family:monospace;line-height:1.6;">'
            +state.logs.map(l=>'<div style="color:'+(l.startsWith('✅')?'#2ecc71':l.startsWith('⚠️')?'#f39c12':'#e74c3c')+'">'+l+'</div>').join('')
            +'</div><button id="sc-done" style="width:100%;margin-top:14px;padding:10px;background:#2ecc71;color:#111;border:none;border-radius:5px;cursor:pointer;font-weight:bold;">'+s('scanClose')+'</button>'
        );
        document.body.appendChild(ov);
        document.getElementById('sc-done').onclick=()=>{ov.remove();location.href=`${location.origin}/World/Popmundo.aspx/Character/${state.charId}`;};
    };

    // Scan: keşif & adım
    const discover = () => {
        const url=window.location.href, base=`${location.origin}/World/Popmundo.aspx`;
        let id=(url.match(/\/Character\/(?:Details|Items|Vehicles|Housing)\/(\d+)/)||[])[1]
            ||document.querySelector('a[href*="/Character/Details/"]')?.href.match(/\/(\d+)$/)?.[1]
            ||document.querySelector('a[href*="/Character/Items/"]')?.href.match(/\/(\d+)$/)?.[1]
            ||GM_getValue(K.char,'');
        if (!id){const inp=prompt(s('scanAskId'));if(inp&&/^\d+$/.test(inp.trim()))id=inp.trim();else{alert(s('scanBadId'));return;}}
        GM_setValue(K.char,id);
        showScanModal(opts=>{
            const q=[];
            if(opts.personal)q.push(`${base}/Character/Items/${id}`);
            if(opts.vehicles)q.push(`${base}/Character/Vehicles/${id}`);
            if(opts.housing) q.push(`${base}/Character/Housing/${id}`);
            if(opts.artist)  q.push(`${base}/Artist/VehicleItems/`);
            saveScan({active:true,queue:q,index:0,logs:[],charId:id});
            location.href=q[0];
        });
    };

    const runStep = () => {
        if (!window.location.href.includes('/World/Popmundo.aspx/')) return;
        let st=getScan(); if (!st.active) return;
        setTimeout(()=>{
            const u=window.location.href; let found=[];
            if (u.includes('Character/Vehicles/')) {
                const anchors=document.querySelectorAll('#tablevehicles a[href*="/Character/Vehicle/"]');
                const veh=gmGet(K.veh,{});
                anchors.forEach(a=>{if(a.href&&a.innerText.trim())veh[a.href]=a.innerText.trim();});
                gmSet(K.veh,veh); found=Array.from(anchors).map(a=>a.href);
                st.logs.push(`${s('scanVehList')} ${found.length} ${s('scanVehUnit')}`);
            } else if (u.includes('Character/Housing/')) {
                found=Array.from(document.querySelectorAll('#tablelocales a[href*="/Locale/"]'))
                    .filter(a=>/\/Locale\/\d+$/.test(a.getAttribute('href')))
                    .map(a=>{const id=a.getAttribute('href').match(/\/Locale\/(\d+)$/)?.[1];return id?`${location.origin}/World/Popmundo.aspx/Locale/ItemsEquipment/${id}`:null;})
                    .filter(Boolean);
                st.logs.push(`${s('scanHouseList')} ${found.length} ${s('scanHouseUnit')}`);
            } else {
                const cnt=updatePage(), info=getLocInfo(u);
                st.logs.push(cnt>0?`✅ ${info.name} (${info.type}): ${cnt} ${s('scanLogOk')}`:`⚠️ ${info.name}: ${s('scanLogEmpty')}`);
            }
            if (found.length) st.queue.splice(st.index+1,0,...found);
            st.index++;
            if (st.index<st.queue.length){saveScan(st);location.href=st.queue[st.index];}
            else{const fs={...st};lsDel(K.scan);GM_setValue('pop_last_scan',today());showScanReport(fs);}
        },randDelay());
    };

    // Panel: temalar
    const CD = { bg:'#111',text:'#e0e0e0',border:'#444',hBg:'#1a1a1a',hBorder:'#444',subBg:'#1a1a1a',inBg:'#222',inText:'#eee',inBorder:'#555',detBg:'#1a1a1a',detBorder:'#444',owBg:'#2a2a2a',owText:'#f0ad4e',loc:'#5bc0de',lbl:'#aaa',muted:'#777',togBg:'#222',togText:'#ccc',togBorder:'#555',taBg:'#222',resBorder:'#2a2a2a',gtBg:'#1e3a1e',gtBorder:'#2ecc71',gtText:'#2ecc71',vtBg:'#1a2535',vtBorder:'#3498db',vtText:'#aad4f5',rowText:'#e0e0e0',countText:'#2ecc71',owText2:'#f0ad4e',link:'#5bc0de',sep:'#555',sec:'#95a5a6',dragHint:'#666',priceBg:'#1a1a1a',priceBorder:'#444',priceText:'#ccc' };
    const CL = { bg:'#f5f5f5',text:'#222',border:'#bbb',hBg:'#e0e0e0',hBorder:'#ccc',subBg:'#e8e8e8',inBg:'#fff',inText:'#222',inBorder:'#aaa',detBg:'#ececec',detBorder:'#ccc',owBg:'#ddd',owText:'#555',loc:'#1a6896',lbl:'#555',muted:'#888',togBg:'#ddd',togText:'#333',togBorder:'#bbb',taBg:'#fff',resBorder:'#ddd',gtBg:'#d4edda',gtBorder:'#28a745',gtText:'#155724',vtBg:'#cce5ff',vtBorder:'#004085',vtText:'#004085',rowText:'#333',countText:'#155724',owText2:'#7d4f00',link:'#1a6896',sep:'#aaa',sec:'#555',dragHint:'#999',priceBg:'#fff',priceBorder:'#aaa',priceText:'#222' };
    const C = () => theme()==='light' ? CL : CD;

    // Panel: CSV export / import
    const exportDetailed = () => {
        const db=getDB(), ds=today();
        let csv='\uFEFFCategory;Item Name;Variant;Qty;Owner;Class;Inventory Name;Date;URL\n';
        Object.keys(db).forEach(owner=>Object.keys(db[owner]).forEach(url=>{
            const e=db[owner][url], rel=url.replace(/^https?:\/\/[^/]+/,'');
            e.items.forEach(item=>Object.entries(item.variants).forEach(([v,c])=>
                csv+=`"${getCat(item.name)}";"${item.name}";"${v}";${c};"${owner}";"${e.locClass||'Genel'}";"${e.locType}";"${e.lastUpdate||ds}";"${rel}"\n`
            ));
        }));
        dlCSV(csv,`Detaylı_Envanter_CSV_${ds}.csv`);
    };

    const exportSummary = () => {
        const db=getDB(), ds=today(), prices=getPrices(), sum={};
        Object.values(db).forEach(od=>Object.values(od).forEach(e=>e.items.forEach(item=>
            Object.entries(item.variants).forEach(([v,c])=>{
                const k=priceKey(item.name,v);
                if (!sum[k]) sum[k]={name:item.name,variant:v,count:0,cat:getCat(item.name)};
                sum[k].count+=c;
            })
        )));
        let csv='\uFEFFCategory;Item Name;Variant;Total Qty;Unit Price;Total Value\n',gt=0,gv=0;
        Object.values(sum).forEach(x=>{
            const rawP=prices[priceKey(x.name,x.variant)]||'0',up=parsePrice(rawP),tv=x.count*up;
            gt+=x.count; gv+=tv; csv+=`"${x.cat}";"${x.name}";"${x.variant}";${x.count};${rawP};${tv}\n`;
        });
        csv+=`;;;"${gt}";;${gv}\n`;
        dlCSV(csv,`Toplu_Stok_Fiyatli_CSV_${ds}.csv`);
    };

    const importCSV = (txt) => {
        try {
            const lines=txt.split(/\r?\n/),delim=txt.includes(';')?';':',',newDB={};
            const h=lines[0].split(delim).map(x=>x.replace(/^"|"$/g,'').trim());
            const [iN,iV,iO,iT,iU]=['Item Name','Variant','Owner','Inventory Name','URL'].map(x=>h.indexOf(x));
            const iC=h.indexOf(h.find(x=>x.includes('Qty')));
            for (let i=1;i<lines.length;i++) {
                if (!lines[i].trim()) continue;
                const c=lines[i].split(delim).map(x=>x.replace(/^"|"$/g,'').trim());
                const owner=c[iO]||s('locUnknown'),url=c[iU]||'';
                if (!newDB[owner]) newDB[owner]={};
                if (!newDB[owner][url]) newDB[owner][url]={locType:c[iT],url,items:[]};
                let ex=newDB[owner][url].items.find(it=>it.name===c[iN]);
                if (!ex){ex={name:c[iN],variants:{}};newDB[owner][url].items.push(ex);}
                ex.variants[c[iV]]=(ex.variants[c[iV]]||0)+(parseInt(c[iC])||0);
            }
            saveDB(newDB); location.reload();
        } catch(e){alert(_D('Hata: ','Error: ','Erro: ')+e.message);}
    };

    // Panel: ayar yedek
    const exportSettings = () => {
        const out={}, gmKeys=[K.db,K.cat,K.price,K.veh,K.char,K.owner,K.theme];
        gmKeys.forEach(k=>{const v=GM_getValue(k,null);if(v)out['gm_'+k]=v;});
        const a=document.createElement('a'); a.href=URL.createObjectURL(new Blob([JSON.stringify(out,null,2)],{type:'application/json'})); a.download=`popmundo_yedek_${today()}.json`; a.click();
    };

    const importSettings = (txt) => {
        try {
            const d=JSON.parse(txt); if (typeof d!=='object') throw new Error();
            Object.entries(d).forEach(([k,v])=>{ if (k.startsWith('gm_')) GM_setValue(k.slice(3),v); });
            alert(s('alertRestored')); location.reload();
        } catch { alert(s('alertInvalidFile')); }
    };

    // Panel: fiyat
    const parsePrice = (str) => {
        if (!str) return 0;
        const v=String(str).trim().toLowerCase().replace(',','.');
        const n=parseFloat(v); if (isNaN(n)) return 0;
        if (v.endsWith('m')) return n*1000000;
        if (v.endsWith('k')) return n*1000;
        return n;
    };

    const doSavePrice = (inp) => {
        const name=inp.dataset.name,variant=inp.dataset.variant; if (!name||!variant) return;
        const raw=inp.value.trim(),p=getPrices(),k=priceKey(name,variant);
        if (raw) p[k]=raw; else delete p[k]; savePrices(p);
        const numVal=parsePrice(raw),count=parseInt(inp.dataset.count)||0;
        const valEl=inp.closest('.pi-vt-row')&&inp.closest('.pi-vt-row').querySelector('.pi-val-span');
        if (valEl) valEl.textContent=numVal>0?'= '+(numVal*count).toLocaleString('tr-TR'):'';
        inp.style.borderColor='#2ecc71'; setTimeout(()=>{inp.style.borderColor='';},1000);
    };

    // Panel: liste & arama
    let invListOpen=false;
    const clsLbl=(c)=>({Kişisel:s('clsPersonal'),Araç:s('clsVehicle'),Mekan:s('clsHousing'),'Grup Aracı':s('clsArtist')}[c]||c||s('clsPersonal'));

    const bindResults = (ld) => {
        ld.addEventListener('click',(e)=>{
            const btn=e.target.closest('[data-del-owner]');
            const btnAll=e.target.closest('[data-del-all-owner]');
            if (btnAll&&confirm(_D(btnAll.dataset.delAllOwner+' tüm verisi silinsin mi?','Delete all data for '+btnAll.dataset.delAllOwner+'?','Excluir todos os dados de '+btnAll.dataset.delAllOwner+'?'))) {
                const db=getDB(); delete db[btnAll.dataset.delAllOwner]; saveDB(db); _db=null; showList(); return;
            }
            if (btn&&confirm(s('confirmDel'))){
                const owner=btn.dataset.delOwner,url=btn.dataset.delUrl,db=getDB();
                delete db[owner][url];
                if (!Object.keys(db[owner]).length) delete db[owner];
                saveDB(db); _db=null; showList();
            }
        });
        ld.addEventListener('keydown',(e)=>{
            if (e.key==='Enter'&&e.target.classList.contains('pi-price-inp')){e.preventDefault();doSavePrice(e.target);}
        });
    };

    const showList = () => {
        const ld=document.getElementById('pi-results'); if (!ld) return;
        const db=getDB(),c=C(),owners=Object.keys(db).sort();
        if (!owners.length){ld.innerHTML='<p style="color:#e74c3c;text-align:center;font-size:11px;">'+s('listEmpty')+'</p>';return;}
        let html='';
        owners.forEach(owner=>{
            const totalCnt=Object.values(db[owner]).reduce((a,e)=>a+e.items.reduce((b,it)=>b+Object.values(it.variants).reduce((x,y)=>x+y,0),0),0);
            html+='<div style="margin-bottom:6px;border:1px solid '+c.border+';background:'+c.subBg+';border-radius:4px;">'
                +'<div style="background:'+c.owBg+';padding:4px 8px;color:'+c.owText+';font-size:11px;font-weight:bold;display:flex;justify-content:space-between;align-items:center;">'
                +'<span>👤 '+esc(owner)+' <span style="font-weight:normal;opacity:.7;">['+totalCnt+']</span></span>'
                +'<button data-del-all-owner="'+esc(owner)+'" style="background:none;color:#e74c3c;border:1px solid #e74c3c;padding:1px 6px;font-size:9px;cursor:pointer;border-radius:2px;">'+s('btnDelAll')+'</button></div>';
            Object.keys(db[owner]).sort().forEach(url=>{
                const e=db[owner][url],cnt=e.items.reduce((a,it)=>a+Object.values(it.variants).reduce((x,y)=>x+y,0),0);
                html+='<div style="padding:4px 8px;border-bottom:1px solid '+c.resBorder+';display:flex;justify-content:space-between;align-items:center;">'
                    +'<a href="'+esc(url)+'" target="_blank" style="font-size:10px;color:'+c.loc+';text-decoration:none;">📍 '+esc(e.locType)+' <span style="color:'+c.muted+'">['+cnt+']</span></a>'
                    +'<button data-del-owner="'+esc(owner)+'" data-del-url="'+esc(url)+'" style="background:#a94442;color:white;border:none;padding:1px 5px;font-size:9px;cursor:pointer;border-radius:2px;">'+s('btnDel')+'</button></div>';
            });
            html+='</div>';
        });
        ld.innerHTML=html; bindResults(ld);
    };

    const renderSearch = (query) => {
        const ld=document.getElementById('pi-results'); if (!ld) return;
        if (!query){invListOpen?showList():(ld.innerHTML='');return;}
        const db=getDB(),c=C(),prices=getPrices(),rows=[],vt={};
        let grand=0;
        Object.keys(db).forEach(owner=>Object.keys(db[owner]).forEach(url=>{
            const e=db[owner][url],displayOwner=e.locClass==='Araç'?e.locType:owner;
            e.items.forEach(item=>{
                if (!item.name.toLowerCase().includes(query.toLowerCase())) return;
                Object.entries(item.variants).forEach(([v,cnt])=>{
                    const nv=normV(v), k=priceKey(item.name,nv);
                    if (!vt[k]) vt[k]={name:item.name,variant:nv,count:0};
                    vt[k].count+=cnt; grand+=cnt;
                    rows.push({name:item.name,variant:nv,count:cnt,displayOwner,locClass:e.locClass,locType:e.locType,url});
                });
            });
        }));
        if (!rows.length){ld.innerHTML='<p style="font-size:10px;color:'+c.muted+';padding:4px;">'+s('noResults')+'</p>';return;}

        const lastScan=GM_getValue('pop_last_scan','')||'—';
        let html='<div style="background:'+c.gtBg+';border:1px solid '+c.gtBorder+';border-radius:4px;padding:6px 10px;margin-bottom:6px;font-size:12px;color:'+c.gtText+';display:flex;justify-content:space-between;align-items:center;">'
            +'<b>'+s('totalLabel')+' "'+esc(query)+'": '+grand+'</b>'
            +'<span style="font-size:10px;font-weight:normal;opacity:.7;">'+s('lastScanLabel')+' '+lastScan+'</span></div>';

        html+='<div style="background:'+c.vtBg+';border:1px solid '+c.vtBorder+';border-radius:4px;padding:6px 10px;margin-bottom:8px;font-size:11px;">';
        const vtList=Object.values(vt);
        vtList.forEach(x=>{
            const pk=priceKey(x.name,x.variant),raw=prices[pk]||'';
            const numVal=parsePrice(raw),valTxt=numVal>0?'= '+(numVal*x.count).toLocaleString('tr-TR'):'';
            html+='<div class="pi-vt-row" style="display:flex;align-items:center;gap:6px;padding:3px 0;border-bottom:1px solid '+c.vtBorder+'44;color:'+c.vtText+';">'
                +'<span style="flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;"><b>'+esc(x.name)+'</b> <span style="opacity:.7;font-size:10px;">'+esc(x.variant)+'</span> <span style="color:'+c.gtText+';font-weight:bold;">x'+x.count+'</span></span>'
                +'<input type="text" placeholder="30k / 2m" value="'+esc(raw)+'" data-count="'+x.count+'" data-name="'+esc(x.name)+'" data-variant="'+esc(x.variant)+'" class="pi-price-inp"'
                +' style="width:80px;font-size:10px;padding:2px 4px;background:'+c.priceBg+';color:'+c.priceText+';border:1px solid '+c.priceBorder+';border-radius:3px;flex-shrink:0;">'
                +'<span class="pi-val-span" style="font-size:10px;color:'+c.countText+';min-width:70px;flex-shrink:0;">'+valTxt+'</span></div>';
        });
        html+='<button id="pi-copy-btn" style="width:100%;margin-top:6px;padding:5px;background:#444;color:#ccc;border:1px solid #666;border-radius:3px;cursor:pointer;font-size:10px;">'+s('btnCopy')+'</button>';
        html+='</div><div style="font-size:10px;">';
        rows.forEach(r=>{
            const charIdM = r.url.match(/\/Character\/(?:Items|ItemsEquipment)\/(\d+)/);
            const charUrl = charIdM ? r.url.replace(/\/Character\/(?:Items|ItemsEquipment)\/\d+/, '/Character/Details/'+charIdM[1]) : null;
            const ownerHtml = charUrl
                ? '<a href="'+esc(charUrl)+'" target="_blank" style="color:'+c.owText2+';text-decoration:none;font-weight:600;">'+esc(r.displayOwner)+'</a>'
                : '<span style="color:'+c.owText2+';font-weight:600;">'+esc(r.displayOwner)+'</span>';
            html+='<div style="padding:5px 4px;border-bottom:1px solid '+c.resBorder+';display:flex;flex-direction:column;gap:2px;">'
                +'<div style="display:flex;align-items:baseline;gap:4px;flex-wrap:wrap;">'
                +'<span style="color:'+c.rowText+';font-size:10px;font-weight:600;word-break:break-word;">'+esc(r.name)+'</span>'
                +'<span style="color:'+c.muted+';font-size:9px;">'+esc(r.variant)+'</span>'
                +'<span style="color:'+c.countText+';font-weight:bold;font-size:10px;margin-left:auto;">x'+r.count+'</span>'
                +'</div>'
                +'<div style="display:flex;align-items:center;gap:4px;flex-wrap:wrap;font-size:9px;">'
                +ownerHtml
                +'<span style="color:'+c.sep+';">→</span>'
                +'<a href="'+esc(r.url)+'" target="_blank" style="color:'+c.link+';text-decoration:none;">'+esc(r.locType)+'</a>'
                +'</div>'
                +'</div>';
        });
        ld.innerHTML=html+'</div>';
        bindResults(ld);
        document.getElementById('pi-copy-btn')?.addEventListener('click',()=>{
            const txt=vtList.map(x=>{const raw=prices[priceKey(x.name,x.variant)]||'';return x.name+' '+x.variant+': x'+x.count+(raw?' - '+raw:' - '+s('noPriceLabel'));}).join('\n');
            navigator.clipboard.writeText(txt).then(()=>{const b=document.getElementById('pi-copy-btn');if(b){b.textContent=s('btnCopied');setTimeout(()=>{b.textContent=s('btnCopy');},1500);}});
        });
    };

    // Panel: UI
    function _createDepotFAB() {
        if (document.getElementById('pi-fab')) return;
        if (GM_getValue('dp_pc_connected', false)) return; // PC bağlıysa FAB gösterme
        // Position right of MissionAid float if present
        const maFloat = document.getElementById('qrFloat');
        const rightOffset = maFloat ? (window.innerWidth - maFloat.getBoundingClientRect().left + 8) : 14;
        const fab = document.createElement('button');
        fab.id = 'pi-fab'; fab.type = 'button';
        fab.style.cssText = 'position:fixed;bottom:18px;right:'+rightOffset+'px;z-index:999990;width:40px;height:40px;border-radius:50%;background:#6f42c1;color:#fff;font-size:20px;border:2px solid #fff;cursor:pointer;box-shadow:0 2px 8px rgba(0,0,0,.35);display:flex;align-items:center;justify-content:center;font-family:inherit;line-height:1';
        fab.title = _D('Envanter','Inventory','Inventário');
        fab.innerHTML = '<span style="pointer-events:none">📦</span>';
        fab.onclick = () => { fab.remove(); createUI(); };
        document.body.appendChild(fab);
    }

    const createUI = () => {
        if (document.getElementById('pi-panel')) return;
        const c=C(),w=Math.min(gmGet(K.pw,340),window.innerWidth-8);
        const panel=document.createElement('div'); panel.id='pi-panel';

        const defaultRight = () => ({ right: 10, top: Math.round(window.innerHeight / 2) - 20 });



        const pos = gmGet(K.pos, null);
        const posStyle = pos
            ? 'left:'+pos.left+'px;top:'+pos.top+'px;'
            : 'right:10px;top:'+Math.round(window.innerHeight/2-200)+'px;';

        const th=theme(), ts='background:'+c.togBg+';color:'+c.togText+';border:1px solid '+c.togBorder;
        const thD=th==='dark'?'background:#333;color:#fff;border:2px solid #f0ad4e':ts;
        const thL=th==='light'?'background:#fff;color:#222;border:2px solid #f0ad4e':ts;

        const mkLangBtn=(lang,label)=>{
            const active=LANG===lang;
            return '<button data-lang="'+lang+'" style="flex:1;padding:6px 4px;font-size:11px;border-radius:4px;cursor:pointer;font-weight:'+(active?'bold':'normal')+';background:'+(active?'#f0ad4e':c.togBg)+';color:'+(active?'#111':c.togText)+';border:2px solid '+(active?'#f0ad4e':c.togBorder)+';transition:all .15s;">'+label+'</button>';
        };

        panel.style.cssText='position:fixed;'+posStyle+'width:'+w+'px;min-width:220px;max-width:calc(100vw - 8px);z-index:999999;background:'+c.bg+';color:'+c.text+';border:2px solid '+c.border+';border-radius:10px;padding:0;font-family:Arial,sans-serif;box-shadow:0 12px 40px rgba(0,0,0,.5);max-height:88vh;overflow-y:auto;overflow-x:hidden;word-break:break-word;';

        panel.innerHTML=
            // HEADER — title + drag hint + minimize
            '<div id="pi-drag" style="background:'+c.hBg+';border-radius:8px 8px 0 0;padding:10px 14px;border-bottom:2px solid '+c.hBorder+';display:flex;justify-content:space-between;align-items:center;cursor:grab;user-select:none;">'
            +'<span style="font-size:14px;font-weight:bold;color:#f0ad4e;">'+s('panelTitle')+'</span>'
            +'<div style="display:flex;gap:6px;align-items:center;">'
            +('ontouchstart' in window ? '' : '<span style="font-size:10px;color:'+c.dragHint+';border:1px dashed '+c.dragHint+';padding:2px 5px;border-radius:3px;">'+s('dragHint')+'</span>')
            +'<button id="pi-min" style="'+ts+';border-radius:6px;padding:3px 8px;cursor:pointer;font-size:11px;display:flex;align-items:center;gap:4px;white-space:nowrap;flex-shrink:0;">'
            +(GM_getValue('dp_pc_connected',false)?'✕ '+s('btnClose'):'📦 '+s('btnMinimize'))
            +'</button>'
            +'</div></div>'
            +'<div style="padding:8px 12px 0;">'
            // ACCORDION ROW — two buttons side by side
            +'<div style="display:flex;gap:6px;margin-bottom:6px;">'
            +'<button id="pi-tog-cfg" style="flex:1;padding:8px 6px;'+ts+';border-radius:5px;cursor:pointer;font-weight:bold;font-size:11px;text-align:center;">⚙️ '+s('btnSettings')+' ▾</button>'
            +'<button id="pi-tog-det" style="flex:1;padding:8px 6px;'+ts+';border-radius:5px;cursor:pointer;font-weight:bold;font-size:11px;text-align:center;">📋 '+s('btnInventory')+' ▾</button>'
            +'</div>'
            // SETTINGS PANEL
            +'<div id="pi-cfg" style="display:none;background:'+c.detBg+';padding:10px;border-radius:5px;border:1px solid '+c.detBorder+';margin-bottom:8px;">'
            // Lang buttons — first row inside settings
            +'<div id="pi-lang-btns" style="display:flex;gap:5px;margin-bottom:10px;">'
            +mkLangBtn('TR','🇹🇷 Türkçe')+mkLangBtn('EN','🇬🇧 English')+mkLangBtn('PT-BR','🇧🇷 Português')
            +'</div>'
            +'<div style="display:flex;gap:6px;margin-bottom:10px;">'
            +'<button id="pi-th-dark"  style="flex:1;padding:7px;border-radius:4px;cursor:pointer;font-size:11px;font-weight:bold;'+thD+'">🌙 Dark</button>'
            +'<button id="pi-th-light" style="flex:1;padding:7px;border-radius:4px;cursor:pointer;font-size:11px;font-weight:bold;'+thL+'">☀️ Light</button></div>'
            +'<div style="display:flex;gap:5px;margin-bottom:6px;">'
            +'<button id="pi-exp-set" style="flex:1;padding:8px;background:#17a2b8;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnBackup')+'</button>'
            +'<button id="pi-imp-set" style="flex:1;padding:8px;background:#6c757d;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnRestore')+'</button></div>'
            +'<label style="color:'+c.lbl+';font-size:10px;">'+s('catLabel')+'</label>'
            +'<textarea id="pi-cat-txt" placeholder="'+s('catPlaceholder')+'" style="width:100%;height:50px;font-size:10px;background:'+c.taBg+';color:'+c.text+';border:1px solid '+c.inBorder+';border-radius:3px;resize:vertical;margin-top:4px;box-sizing:border-box;"></textarea>'
            +'<button id="pi-cat-save" style="width:100%;margin-top:5px;background:#444;color:white;border:none;padding:6px;font-size:10px;border-radius:3px;cursor:pointer;">'+s('btnCatSave')+'</button>'
            +'<button id="pi-clear" style="width:100%;margin-top:8px;padding:7px;background:none;color:#dc3545;border:1px solid #dc3545;border-radius:4px;cursor:pointer;font-size:10px;">'+s('btnClearAll')+'</button>'
            +'</div>'
            // INVENTORY PANEL
            +'<div id="pi-det" style="display:none;background:'+c.detBg+';padding:10px;border-radius:5px;border:1px solid '+c.detBorder+';margin-bottom:8px;">'
            +'<button id="pi-scan" style="width:100%;padding:10px;background:#0056b3;color:white;border:none;border-radius:5px;cursor:pointer;font-weight:bold;margin-bottom:8px;">'+s('btnAutoScan')+'</button>'
            +'<button id="pi-list" style="width:100%;background:#17a2b8;color:white;border:none;padding:8px;font-weight:bold;border-radius:5px;cursor:pointer;margin-bottom:8px;">'+s('btnListManage')+'</button>'
            +'<div style="display:flex;gap:5px;">'
            +'<button id="pi-exp-det" style="flex:1;padding:8px;background:#6c757d;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnDetailed')+'</button>'
            +'<button id="pi-exp-sum" style="flex:1;padding:8px;background:#6c757d;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnStockCSV')+'</button>'
            +'<button id="pi-imp-csv" style="flex:1;padding:8px;background:#6c757d;color:white;border:none;border-radius:3px;cursor:pointer;font-size:11px;">'+s('btnImportCSV')+'</button>'
            +'</div></div>'
            // SAVE / DELETE ROW
            +'<div style="display:flex;gap:6px;margin-bottom:8px;">'
            +'<button id="pi-save" style="flex:3;background:#218838;color:white;border:none;padding:10px;font-weight:bold;border-radius:5px;cursor:pointer;">'+s('btnSavePage')+'</button>'
            +'<button id="pi-del"  style="flex:1;background:none;color:#f39c12;border:1px solid #f39c12;border-radius:4px;cursor:pointer;font-size:10px;">'+s('btnDelRecord')+'</button>'
            +'</div>'
            // SEARCH
            +'<input type="text" id="pi-search" placeholder="'+s('searchPH')+'" style="width:100%;padding:10px;background:'+c.inBg+';color:'+c.inText+';border:2px solid #3498db;border-radius:5px;box-sizing:border-box;outline:none;">'
            +'<div id="pi-results" style="margin-top:10px;"></div>'
            +'</div>';

        document.body.appendChild(panel);

        // Dil butonları — document delegation, pi-cfg içinde display:none sorununu aşar
        document.addEventListener('click',(e)=>{
            const btn=e.target.closest('#pi-lang-btns [data-lang]'); if(!btn)return;
            document.cookie='ppm_lang='+btn.dataset.lang+';path=/;domain=.popmundo.com;max-age=31536000';
            location.reload();
        });

        // Accordion: birine tıklayınca diğeri kapanır
        const togMutual=(bA,dA,bB,dB)=>{
            const btnA=document.getElementById(bA),divA=document.getElementById(dA);
            const btnB=document.getElementById(bB),divB=document.getElementById(dB);
            if(!btnA||!btnB) return;
            const setArrow=(btn,open)=>{btn.textContent=btn.textContent.replace(open?'▴':'▾',open?'▾':'▴');};
            btnA.addEventListener('click',()=>{
                const openA=divA.style.display!=='none';
                divA.style.display=openA?'none':'block'; setArrow(btnA,openA);
                if(!openA){divB.style.display='none'; if(btnB.textContent.includes('▴'))setArrow(btnB,true);}
            });
            btnB.addEventListener('click',()=>{
                const openB=divB.style.display!=='none';
                divB.style.display=openB?'none':'block'; setArrow(btnB,openB);
                if(!openB){divA.style.display='none'; if(btnA.textContent.includes('▴'))setArrow(btnA,true);}
            });
        };
        togMutual('pi-tog-cfg','pi-cfg','pi-tog-det','pi-det');

        // Sol kenardan resize
        const rh=document.createElement('div');
        rh.style.cssText='position:absolute;top:0;left:0;width:8px;height:100%;cursor:ew-resize;z-index:2;';
        panel.appendChild(rh);
        let resizing=false,startX=0,startW=0;
        rh.addEventListener('mousedown',(e)=>{resizing=true;startX=e.clientX;startW=panel.offsetWidth;e.preventDefault();});
        document.addEventListener('mousemove',(e)=>{if(!resizing)return;const nw=Math.max(220,Math.min(window.innerWidth-8,startW-(e.clientX-startX)));panel.style.width=nw+'px';});
        document.addEventListener('mouseup',()=>{if(!resizing)return;resizing=false;gmSet(K.pw,panel.offsetWidth);});

        // Sürükleme
        let drag=false,ox=0,oy=0;
        document.getElementById('pi-drag').addEventListener('mousedown',(e)=>{
            if(e.target.closest('button'))return;
            drag=true; panel.style.cursor='grabbing';
            const rect=panel.getBoundingClientRect();
            ox=rect.left-e.clientX; oy=rect.top-e.clientY;
        });
        document.addEventListener('mousemove',(e)=>{
            if(!drag)return;
            panel.style.left=Math.max(0,e.clientX+ox)+'px';
            panel.style.top=Math.max(0,e.clientY+oy)+'px';
            panel.style.right='auto'; panel.style.bottom='auto';
        });
        document.addEventListener('mouseup',()=>{
            if(!drag)return; drag=false; panel.style.cursor='';
            gmSet(K.pos,{left:panel.offsetLeft,top:panel.offsetTop});
        });

        const fileInput=(accept,cb)=>{const i=document.createElement('input');i.type='file';i.accept=accept;i.onchange=e=>{const r=new FileReader();r.onload=ev=>cb(ev.target.result);r.readAsText(e.target.files[0]);};i.click();};
        const on=(id,fn)=>document.getElementById(id)&&document.getElementById(id).addEventListener('click',fn);

        on('pi-min',()=>{
            panel.remove();
            if (!GM_getValue('dp_pc_connected', false)) _createDepotFAB();
            // If connected: PopControl button brings it back — no FAB needed
        });
        on('pi-save',()=>{const cnt=updatePage();if(cnt>0){alert(_D(cnt+' çeşit eşya kaydedildi.',cnt+' item type(s) saved.',cnt+' tipo(s) de item salvos.'));location.reload();}else alert(s('alertNoItems'));});
        on('pi-del',()=>{const u=location.href,db=getDB();let f=false;Object.keys(db).forEach(o=>{if(db[o]&&db[o][u]){delete db[o][u];f=true;}});if(f){saveDB(db);alert(s('alertDeleted'));location.reload();}else alert(s('alertNotFound'));});
        on('pi-scan',()=>discover());
        on('pi-list',()=>{invListOpen?((document.getElementById('pi-results').innerHTML=''),invListOpen=false):(showList(),invListOpen=true);});
        on('pi-exp-det',exportDetailed);
        on('pi-exp-sum',exportSummary);
        on('pi-imp-csv',()=>fileInput('.csv',importCSV));
        on('pi-exp-set',exportSettings);
        on('pi-imp-set',()=>fileInput('.json',importSettings));
        on('pi-th-dark',()=>{GM_setValue(K.theme,'dark');panel.remove();createUI();});
        on('pi-th-light',()=>{GM_setValue(K.theme,'light');panel.remove();createUI();});
        document.getElementById('pi-search').addEventListener('input',(e)=>renderSearch(e.target.value.trim()));
        on('pi-cat-save',()=>{
            const raw=document.getElementById('pi-cat-txt').value; if(!raw.trim())return alert(s('alertEnterData'));
            const nc={};raw.split('\n').forEach(line=>{const p=line.includes('\t')?line.split('\t'):line.split(',');if(p.length>=2){const cat=p[0].trim(),it=p[1].trim();if(!nc[cat])nc[cat]=[];nc[cat].push(it);}});
            if(Object.keys(nc).length){saveCats(nc);alert(_D(Object.keys(nc).length+' kategori güncellendi!',Object.keys(nc).length+' category/categories updated!',Object.keys(nc).length+' categoria(s) atualizada(s)!'));}else alert(s('alertCatFmt'));
        });
        on('pi-clear',()=>{if(confirm(s('alertClearConf'))){gmDel(K.db);location.reload();}});
    };

    // Scan: oturum başlat
    const sc=getScan();
    if (sc.active && window.location.href.includes('/World/Popmundo.aspx/')) {
        const btn=document.createElement('button');
        const curName=sc.queue[sc.index]?sc.queue[sc.index].split('/').pop():'';
        btn.textContent=`${s('scanStop')} (${sc.index}/${sc.queue.length}) — ${curName}`;
        btn.style.cssText='position:fixed;top:10px;left:50%;transform:translateX(-50%);z-index:999998;padding:10px 20px;background:#dc3545;color:white;border:none;border-radius:6px;cursor:pointer;font-weight:bold;font-size:13px;';
        btn.onclick=()=>{lsDel(K.scan);location.reload();};
        document.body.appendChild(btn);
        if (document.readyState==='complete') runStep();
        else window.addEventListener('load',runStep);
    }

    // EN strings for PopControl export
    window.__ppcStrDepot = {"scanTitle": "🔄 Auto Scan", "scanPersonal": "👤 Personal Items", "scanVehicles": "🚗 Personal Vehicles", "scanHousing": "🏠 Housing", "scanArtist": "🎵 Artist / Tour Vehicle", "scanWarn": "⚠️ Tabs will change automatically during scan.", "scanCancel": "Cancel", "scanStart": "▶ Start Scan", "scanSelectOne": "Select at least one category.", "scanDone": "✅ Scan Complete", "scanLocCount": "Scanned Locations:", "scanItemCount": "Total Items:", "scanClose": "Close", "scanAskId": "Enter Character ID:", "scanBadId": "No valid ID entered.", "scanVehList": "🔍 Vehicle list:", "scanVehUnit": "vehicles.", "scanHouseList": "🔍 Housing list:", "scanHouseUnit": "properties.", "scanLogOk": "types.", "scanLogEmpty": "no items.", "scanStop": "🛑 STOP", "panelTitle": "📦 Depot", "dragHint": "⠿ Drag", "btnSettings": "Panel Settings", "btnBackup": "📤 Backup Script", "btnRestore": "📥 Load Backup", "catLabel": "Category CSV (Category,Item):", "catPlaceholder": "Category,Item Name", "btnCatSave": "💾 Update Categories", "btnClearAll": "⚠️ Reset All Data", "btnSavePage": "📍 Save Page", "btnDelRecord": "🗑️ Delete Record", "btnInventory": "Inventory Actions", "btnAutoScan": "🔄 AUTO SCAN", "btnListManage": "📋 LIST / MANAGE INVENTORIES", "btnDetailed": "📄 Detailed CSV", "btnStockCSV": "📊 Stock & Priced CSV", "btnImportCSV": "📥 Import CSV", "searchPH": "Search inventory (e.g. Haiku)...", "alertNoItems": "No items found on this page.", "alertDeleted": "Deleted.", "alertNotFound": "Record not found.", "alertEnterData": "Enter data.", "alertClearConf": "All data will be reset!", "alertRestored": "Restored.", "alertInvalidFile": "Invalid file.", "listEmpty": "Database empty.", "btnDelAll": "Delete All", "btnDel": "DEL", "confirmDel": "Delete this record?", "noResults": "No results found.", "totalLabel": "Total", "lastScanLabel": "Last scan:", "btnCopy": "📋 Copy these results", "btnCopied": "✅ Copied", "noPriceLabel": "Make an offer", "clsPersonal": "Items", "clsVehicle": "Personal Vehicle", "clsHousing": "Housing", "clsArtist": "Artist Vehicle", "minTooltip": "Open panel", "btnMinimize": "Minimize", "btnClose": "Close", "locVehicleFb": "Personal Vehicle", "locLocaleFb": "Locale", "locCharFb": "Character", "locInvSuffix": "Inventory", "locArtistFb": "Artist Vehicle", "locUnknown": "Unknown", "variantDefault": "Standard"};
    window.__ppcStrDepot.panelTitle = '📦 Depot ' + GM_info.script.version;

    // PopControl hazır olana kadar bekler
    function _waitPC(cb,n){n=n||0;if(unsafeWindow.PopControl){cb();return;}if(n<20)setTimeout(function(){_waitPC(cb,n+1);},300);}

    // Auto-connect to PopControl if available
    _waitPC(function() {
        unsafeWindow.PopControl.register({
            id:'depot', icon:'📦', label:_D('Envanter','Inventory','Inventário'),
            strings: window.__ppcStrDepot || {},
            buttons:[{icon:'📦', label:_D('Depot','Depot','Depot'), onClick:function(){
                var p=document.getElementById('pi-panel');
                if (p) { p.style.display = p.style.display===''?'none':''; }
                else { createUI(); }
            }}],
            onUndo:function(){
                GM_setValue('dp_pc_connected', false);
                document.getElementById('pi-panel')?.remove();
                _createDepotFAB();
            },
        });
        document.getElementById('pi-fab')?.remove();
        GM_setValue('dp_pc_connected', true);
    });

    _createDepotFAB();

})();