Web3 OKX Demo Trade Addon

Add Demo Trading tab and functional demo trade panel

Vous devrez installer une extension telle que Tampermonkey, Greasemonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Violentmonkey pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey ou Userscripts pour installer ce script.

Vous devrez installer une extension telle que Tampermonkey pour installer ce script.

Vous devrez installer une extension de gestionnaire de script utilisateur pour installer ce script.

(J'ai déjà un gestionnaire de scripts utilisateur, laissez-moi l'installer !)

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension telle que Stylus pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

Vous devrez installer une extension du gestionnaire de style pour utilisateur pour installer ce style.

(J'ai déjà un gestionnaire de style utilisateur, laissez-moi l'installer!)

// ==UserScript==
// @name         Web3 OKX Demo Trade Addon
// @namespace    http://tampermonkey.net/
// @version      2.4
// @description  Add Demo Trading tab and functional demo trade panel
// @author       mamiis
// @match        https://web3.okx.com/*
// @grant        none
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    let demoMode = false;
    let demoPanelVisible = false;
    let currentTokenPrice = 0;
    let currentSolPrice = 0;
    let currentTokenSymbol = 'TOKEN';
    let currentTokenName = '';
    let currentTokenImage = '';
    let totalPnL = 0;
    let totalPnLPercent = 0;
    let tokenPnL = 0;
    let tokenPnLPercent = 0;
    let activeTokenRealizedPnL = 0;
    let showFiat = true;
    let pnlSectionVisible = true; // PnL section
    const DEBUG_RESET_WITH_USD_TARGET_ENABLED = true;
    const DEBUG_RESET_USD_TARGET_AMOUNT = 21.61;
    const DEBUG_RESET_SOL_FALLBACK_AMOUNT = 1;

    // LocalStorage'dan ayarları yükle
    let currentSettings = JSON.parse(localStorage.getItem('demoSettings')) || {
        buySlippage: '15%',
        sellSlippage: '20%',
        customBuySlippage: false,
        customSellSlippage: false,
        customBuyAmounts: false,
        customSellPercents: false,
        buyAmounts: ['0.3', '0.6', '0.8', '1'],
        sellPercents: ['25%', '50%', '75%', '100%'],
        serviceFee: '0.68%',
        buyFixedFeeSol: '0.00005',
        sellFixedFeeSol: '0.00005'
    };

    const defaultBuyAmounts = ['0.3', '0.6', '0.8', '1'];
    const defaultSellPercents = ['25%', '50%', '75%', '100%'];

    if (!Array.isArray(currentSettings.buyAmounts)) {
        currentSettings.buyAmounts = [...defaultBuyAmounts];
    }
    if (!Array.isArray(currentSettings.sellPercents)) {
        currentSettings.sellPercents = [...defaultSellPercents];
    }

    currentSettings.buyAmounts = currentSettings.buyAmounts
        .map(v => String(v || '').trim())
        .filter(Boolean)
        .slice(0, 4);
    while (currentSettings.buyAmounts.length < 4) {
        currentSettings.buyAmounts.push(defaultBuyAmounts[currentSettings.buyAmounts.length]);
    }

    currentSettings.sellPercents = currentSettings.sellPercents
        .map(v => String(v || '').trim())
        .filter(Boolean)
        .slice(0, 4);
    while (currentSettings.sellPercents.length < 4) {
        currentSettings.sellPercents.push(defaultSellPercents[currentSettings.sellPercents.length]);
    }

    currentSettings.customBuySlippage = Boolean(currentSettings.customBuySlippage);
    currentSettings.customSellSlippage = Boolean(currentSettings.customSellSlippage);
    currentSettings.customBuyAmounts = Boolean(currentSettings.customBuyAmounts);
    currentSettings.customSellPercents = Boolean(currentSettings.customSellPercents);
    currentSettings.buyFixedFeeSol = normalizeFixedFeeSolText(currentSettings.buyFixedFeeSol, '0.00005');
    currentSettings.sellFixedFeeSol = normalizeFixedFeeSolText(currentSettings.sellFixedFeeSol, '0.00005');

    // Customize amounts state
    let customizeMode = false;
    let hotkeysEnabled = false;
    let hotkeysSpacePressed = false;
    let hotkeysListenersBound = false;
    let tempBuyAmounts = [...currentSettings.buyAmounts];
    let tempSellPercents = [...currentSettings.sellPercents];
    let tempBuySlippage = currentSettings.buySlippage;
    let tempSellSlippage = currentSettings.sellSlippage;
    let tempBuyFixedFeeSol = currentSettings.buyFixedFeeSol;
    let tempSellFixedFeeSol = currentSettings.sellFixedFeeSol;
    let tempServiceFee = currentSettings.serviceFee;
    let customizeExitAnimationPending = false;

    // Sayfa değişikliklerini izlemek için observer
    let pageObserver = null;

    // Token bilgilerini takip etmek için yeni değişkenler
    let demoPortfolio = JSON.parse(localStorage.getItem('demoPortfolio')) || {
        'SOL': {
            amount: 1,
            avgPrice: 100,
            totalInvested: 0,
            totalSold: 0,
            totalInvestedSol: 0,
            totalSoldSol: 0,
            realizedPnL: 0
        }
    };

    let totalRealizedPnL = parseFloat(localStorage.getItem('totalRealizedPnL')) || 0;
    let totalTradeVolume = parseFloat(localStorage.getItem('totalTradeVolume')) || 0;
    let tradeHistory = JSON.parse(localStorage.getItem('tradeHistory')) || [];

    // PnL deÄŸerleri
    let boughtAmount = 0;
    let soldAmount = 0;
    let boughtAmountSol = 0;
    let soldAmountSol = 0;
    let balanceAmount = 0;
    let tpnlAmount = 0;
    let demoBalance = 0;

    // Duplicate önleme için kontrol değişkeni
    let isInitializing = false;
    let lastTokenCA = '';
    const DEBUG_LOGS = false;
    // Debug: reset sırasında SOL bakiyesini sabit SOL yerine hedef USD karşılığına çevir.

    const SOL_TOKEN_IMAGE = 'https://web3.okx.com/cdn/web3/currency/token/501-11111111111111111111111111111111-1.png/type=default_350_0?v=1734571825920';
    const SOL_WALLET_ICON = 'https://web3.okx.com/cdn/wallet/logo/SOL-20220525.png';
    const DEFAULT_TOKEN_IMAGE = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///ywAAAAAAQABAAACAUwAOw==';
    const PANEL_UPDATE_THROTTLE_MS = 100;
    const PNL_UPDATE_THROTTLE_MS = 100;
    const SOL_PRICE_UPDATE_INTERVAL_MS = 300;
    const SOL_API_FALLBACK_INTERVAL_MS = 300;
    const SETTINGS_SYNC_INTERVAL_MS = 1200;
    const TRADE_DELAY_MIN_SECONDS = 0.35;
    const TRADE_DELAY_MAX_SECONDS = 0.60;
    const DROPDOWN_VERTICAL_OFFSET_PX = -16;
    const TRADE_FEE_MIN_SOL = 0.000001;
    const TRADE_FEE_MAX_SOL = 0.01;
    // Hız/gecikme oranlaması yalnızca 0.000001 - 0.0001 fee aralığında yapılır.
    const TRADE_SPEED_FEE_MAX_SOL = 0.0001;
    const NUMERIC_ZERO_EPSILON = 0.0000001;
    const TOKEN_AMOUNT_ZERO_EPSILON = 0.00000001;
    const DEMO_BUTTON_BASE_CLASSNAME = 'dex-plain-button peM48g__dex MovYo___dex q7TVYE__dex demo-mode-toggle';

    let lastPanelUpdateAt = 0;
    let lastPnLDisplayUpdateAt = 0;
    let pendingDemoComponentsUpdate = null;
    let lastTpnlColorSign = null;
    let lastRpnlColorSign = null;
    let lastUpnlColorSign = null;
    let lastSolApiFetchAt = 0;
    let lastSettingsSyncAt = 0;
    let isPanelDragging = false;
    let pendingPanelRebuildAfterDrag = false;
    let pendingDropdownRefreshAfterDrag = false;
    let pendingPanelValueRefreshAfterDrag = false;
    let tokenChangeUiRefreshTimeout = null;

    function debugLog(...args) {
        if (DEBUG_LOGS) {
            console.log(...args);
        }
    }

    function normalizeNearZero(value, epsilon = NUMERIC_ZERO_EPSILON) {
        const numeric = Number(value);
        if (!Number.isFinite(numeric)) return 0;
        return Math.abs(numeric) < epsilon ? 0 : numeric;
    }

    function isEffectivelyZero(value, epsilon = NUMERIC_ZERO_EPSILON) {
        return normalizeNearZero(value, epsilon) === 0;
    }

    function getImageUrlFromElement(element) {
        if (!element) return null;

        const fromSource = element.closest('picture')?.querySelector('source')?.getAttribute('srcset');
        const fromCurrentSrc = element.currentSrc;
        const fromSrc = element.getAttribute('src') || element.src;
        const fromDataSrc = element.getAttribute('data-src') || element.getAttribute('data-lazy-src');

        const candidates = [fromSource, fromCurrentSrc, fromSrc, fromDataSrc].filter(Boolean);

        for (const raw of candidates) {
            let url = String(raw).trim();
            if (!url) continue;

            // srcset birden fazla URL içeriyorsa sadece ilk URL'yi al.
            // Query içindeki virgül karakterlerini bozmayacak şekilde split edilir.
            if (/\s*,\s*https?:\/\//i.test(url)) {
                url = url.split(/\s*,\s*(?=https?:\/\/)/i)[0].trim();
            }

            // "... 1x" / "... 2x" / "... 640w" descriptor'larını temizle
            url = url
                .replace(/\s+\d+(?:\.\d+)?x$/i, '')
                .replace(/\s+\d+w$/i, '')
                .trim();

            if (url.startsWith('//')) {
                url = `https:${url}`;
            } else if (url.startsWith('/')) {
                try {
                    url = new URL(url, window.location.origin).href;
                } catch (_) {}
            }

            url = url.replace(/&/gi, '&');

            const lower = url.toLowerCase();
            if (!/^https?:\/\//.test(lower)) continue;
            if (lower.includes('/network/') || lower.includes('network-logo')) continue;
            if (lower.includes('blank') || lower.includes('placeholder')) continue;

            return url;
        }

        return null;
    }

    function buildImageSrcset(url) {
        if (!url) return '';
        const normalized = normalizeImageUrl(url);
        if (!normalized) return '';
        if (!/^https?:\/\//i.test(normalized)) return '';

        // x-oss-process parametresini tekilleştir ve stabil bir srcset üret
        try {
            const parsed = new URL(normalized);
            parsed.searchParams.delete('x-oss-process');
            parsed.searchParams.append('x-oss-process', 'image/format,webp/ignore-error,1');
            return parsed.toString();
        } catch (_) {
            const withoutProcess = normalized
                .replace(/([?&])x-oss-process=[^&]*/gi, '$1')
                .replace(/[?&]$/, '');
            const separator = withoutProcess.includes('?') ? '&' : '?';
            return `${withoutProcess}${separator}x-oss-process=image/format,webp/ignore-error,1`;
        }
    }

    function normalizeImageUrl(url) {
        if (typeof url !== 'string') return '';

        let normalized = url.trim();
        if (!normalized) return '';

        // srcset birden fazla URL içeriyorsa sadece ilk URL'yi al.
        if (/\s*,\s*https?:\/\//i.test(normalized)) {
            normalized = normalized.split(/\s*,\s*(?=https?:\/\/)/i)[0].trim();
        }

        normalized = normalized
            .replace(/&/gi, '&')
            .replace(/\s+\d+(?:\.\d+)?x$/i, '')
            .replace(/\s+\d+w$/i, '')
            .replace(/\?&/g, '?')
            .replace(/&&+/g, '&')
            .trim();

        if (normalized.startsWith('//')) {
            normalized = `https:${normalized}`;
        } else if (normalized.startsWith('/')) {
            try {
                normalized = new URL(normalized, window.location.origin).href;
            } catch (_) {}
        }

        return normalized;
    }

    function isLikelyTokenImageUrl(url) {
        const normalized = normalizeImageUrl(url);
        if (!normalized) return false;

        const lower = normalized.toLowerCase();
        if (!/^https?:\/\//.test(lower)) return false;
        if (!lower.includes('/currency/token/')) return false;
        if (lower.includes('/network/') || lower.includes('network-logo')) return false;
        if (lower.includes('11111111111111111111111111111111')) return false;
        return true;
    }

    function resolveTokenImageUrl(...candidates) {
        // Önce gerçek token icon URL'lerini tercih et
        for (const candidate of candidates) {
            const normalized = normalizeImageUrl(candidate);
            if (!normalized) continue;
            if (isLikelyTokenImageUrl(normalized)) return normalized;
        }

        // Sonra herhangi bir geçerli string fallback'ini kullan
        for (const candidate of candidates) {
            const normalized = normalizeImageUrl(candidate);
            if (normalized) return normalized;
        }

        return normalizeImageUrl(DEFAULT_TOKEN_IMAGE) || DEFAULT_TOKEN_IMAGE;
    }

    function setTextIfChanged(element, nextText) {
        if (!element || typeof nextText !== 'string') return;
        if (element.textContent !== nextText) {
            element.textContent = nextText;
        }
    }

    function setClassIfChanged(element, nextClass) {
        if (!element || typeof nextClass !== 'string') return;
        if (element.className !== nextClass) {
            element.className = nextClass;
        }
    }

    function setStyleIfChanged(element, styleName, nextValue) {
        if (!element || !styleName) return;
        if (element.style[styleName] !== nextValue) {
            element.style[styleName] = nextValue;
        }
    }

    function getHotkeyBadgeHTML(key) {
        const safeKey = String(key || '').trim().slice(0, 1).toUpperCase();
        return `<span class="demo-hotkey-badge" style="display: inline-flex; align-items: center; justify-content: center; min-width: 32px; height: 28px; padding: 0 8px; margin-left: -2px; border: none; border-radius: 6px; clip-path: inset(0 0 0 2px); font-size: 16px; font-weight: 700; line-height: 1; color: #dedede; background: #383838; text-transform: uppercase; letter-spacing: 0.2px; box-sizing: border-box; flex-shrink: 0;">${safeKey}</span>`;
    }

    function isEditableTarget(target) {
        if (!target || !(target instanceof Element)) return false;
        if (target.isContentEditable) return true;

        const tagName = (target.tagName || '').toLowerCase();
        if (tagName === 'input' || tagName === 'textarea' || tagName === 'select') {
            return true;
        }

        return Boolean(target.closest('input, textarea, select, [contenteditable="true"]'));
    }

    function rebuildDemoPanelPreservingPosition() {
        if (!demoPanelVisible) return;
        if (isPanelDragging) {
            pendingPanelRebuildAfterDrag = true;
            return;
        }

        const currentPanel = document.querySelector('.demo-trade-panel');
        let panelStyle = {};
        if (currentPanel) {
            panelStyle = {
                left: currentPanel.style.left,
                top: currentPanel.style.top
            };
        }

        showDemoPanel(true);

        if (panelStyle.left && panelStyle.top) {
            const newPanel = document.querySelector('.demo-trade-panel');
            if (newPanel) {
                newPanel.style.left = panelStyle.left;
                newPanel.style.top = panelStyle.top;
            }
        }
    }

    function requestPanelRebuildPreservingPosition() {
        if (isPanelDragging) {
            pendingPanelRebuildAfterDrag = true;
            return;
        }
        rebuildDemoPanelPreservingPosition();
    }

    function queueDropdownRefreshAfterDrag() {
        pendingDropdownRefreshAfterDrag = true;
        pendingPanelValueRefreshAfterDrag = true;
    }

    function queuePanelValueRefreshAfterDrag() {
        pendingPanelValueRefreshAfterDrag = true;
    }

    function flushDeferredPanelActionsAfterDrag() {
        if (isPanelDragging || !demoPanelVisible) return;

        if (pendingPanelRebuildAfterDrag) {
            pendingPanelRebuildAfterDrag = false;
            pendingDropdownRefreshAfterDrag = false;
            pendingPanelValueRefreshAfterDrag = false;
            rebuildDemoPanelPreservingPosition();
            return;
        }

        if (pendingDropdownRefreshAfterDrag) {
            pendingDropdownRefreshAfterDrag = false;
            setupDropdowns();
            setupDropdownEvents();
        }

        if (pendingPanelValueRefreshAfterDrag) {
            pendingPanelValueRefreshAfterDrag = false;
            lastPanelUpdateAt = 0;
            lastPnLDisplayUpdateAt = 0;
            updateDemoPanelValues();
        }
    }

    function triggerHotkeyActionByKey(rawKey) {
        const key = String(rawKey || '').toLowerCase();

        const buyKeyMap = { q: 0, w: 1, e: 2, r: 3 };
        const sellKeyMap = { a: 0, s: 1, d: 2, f: 3 };

        if (Object.prototype.hasOwnProperty.call(buyKeyMap, key)) {
            const buyButtons = document.querySelectorAll('.demo-buy-quick');
            const buyButton = buyButtons[buyKeyMap[key]];
            if (buyButton) {
                buyButton.click();
            }
            return;
        }

        if (Object.prototype.hasOwnProperty.call(sellKeyMap, key)) {
            const sellButtons = document.querySelectorAll('.demo-sell-quick');
            const sellButton = sellButtons[sellKeyMap[key]];
            if (sellButton) {
                sellButton.click();
            }
        }
    }

    function setupKeyboardHotkeys() {
        if (hotkeysListenersBound) return;
        hotkeysListenersBound = true;

        document.addEventListener('keydown', function(e) {
            const isSpaceKey = e.code === 'Space' || e.key === ' ' || e.key === 'Spacebar';

            if (isSpaceKey) {
                if (!hotkeysEnabled || isEditableTarget(e.target)) return;

                if (!hotkeysSpacePressed) {
                    hotkeysSpacePressed = true;
                    if (demoPanelVisible && !customizeMode) {
                        requestPanelRebuildPreservingPosition();
                    }
                }

                e.preventDefault();
                return;
            }

            if (!hotkeysEnabled || !hotkeysSpacePressed || !demoPanelVisible || customizeMode) return;
            if (isEditableTarget(e.target)) return;

            const pressedKey = String(e.key || '').toLowerCase();
            if (!'qwerasdf'.includes(pressedKey)) return;
            if (e.repeat) {
                e.preventDefault();
                return;
            }

            e.preventDefault();
            e.stopPropagation();
            e.stopImmediatePropagation();
            triggerHotkeyActionByKey(pressedKey);
        }, true);

        document.addEventListener('keyup', function(e) {
            const isSpaceKey = e.code === 'Space' || e.key === ' ' || e.key === 'Spacebar';
            if (!isSpaceKey) return;

            if (hotkeysSpacePressed) {
                hotkeysSpacePressed = false;
                if (demoPanelVisible && !customizeMode) {
                    requestPanelRebuildPreservingPosition();
                }
            }
        }, true);

        window.addEventListener('blur', function() {
            if (!hotkeysSpacePressed) return;
            hotkeysSpacePressed = false;
            if (demoPanelVisible && !customizeMode) {
                requestPanelRebuildPreservingPosition();
            }
        });
    }

    function getCurrencyToggleIconHTML(isFiatMode) {
        if (isFiatMode) {
            return '<i class="icon iconfont dex-okx-defi-spot-DCA rrglRU__dex" role="img" aria-hidden="true" style="font-size: 12px;"></i>';
        }

        return `
            <div class="vHgkEt__dex jn7mYO__dex" style="width: 12px; height: 12px;">
                <picture class="dex dex-picture srK4SZ__dex dex-picture-font">
                    <source srcset="${buildImageSrcset(SOL_WALLET_ICON)}">
                    <img class="base-logo srK4SZ__dex" alt="" src="${SOL_WALLET_ICON}">
                </picture>
            </div>
        `;
    }

    function setImageIfChanged(imageElement, sourceElement, imageUrl) {
        const normalizedImageUrl = normalizeImageUrl(imageUrl);
        if (!imageElement || !normalizedImageUrl) return;

        const previousSrc = normalizeImageUrl(imageElement.getAttribute('src') || '');
        const previousSourceSrcset = sourceElement ? normalizeImageUrl(sourceElement.getAttribute('srcset') || '') : '';

        const nextSrcset = buildImageSrcset(normalizedImageUrl);
        const currentSrc = previousSrc;
        const currentSrcset = normalizeImageUrl(imageElement.getAttribute('srcset') || '');

        if (currentSrc !== normalizedImageUrl) {
            imageElement.setAttribute('src', normalizedImageUrl);
        }

        if (currentSrcset !== nextSrcset) {
            imageElement.setAttribute('srcset', nextSrcset);
        }

        if (sourceElement) {
            const sourceSrcset = normalizeImageUrl(sourceElement.getAttribute('srcset') || '');
            if (sourceSrcset !== nextSrcset) {
                sourceElement.setAttribute('srcset', nextSrcset);
            }
        }

        // Görsel yüklenmezse önce bir önceki geçerli adrese dön, en son default'a düş
        const fallbackUrl = resolveTokenImageUrl(previousSourceSrcset, previousSrc, currentTokenImage, DEFAULT_TOKEN_IMAGE);
        if (fallbackUrl) {
            imageElement.onerror = function() {
                this.onerror = null;
                this.setAttribute('src', fallbackUrl);
                this.setAttribute('srcset', buildImageSrcset(fallbackUrl));
                if (sourceElement) {
                    sourceElement.setAttribute('srcset', buildImageSrcset(fallbackUrl));
                }
            };
        }
    }

    function getLiveTokenImageFromDOM() {
        const strictTokenCA = getTokenCAFromURL({ allowLastKnown: false });
        const normalizedStrictTokenCA =
            strictTokenCA && strictTokenCA !== 'default_token' && strictTokenCA !== 'error_token'
                ? strictTokenCA
                : '';
        const currentTokenCA = String(normalizedStrictTokenCA || '').toLowerCase();
        const defaultImageLower = normalizeImageUrl(DEFAULT_TOKEN_IMAGE).toLowerCase();
        const candidates = [];

        const pushUrl = (rawUrl, baseScore = 0) => {
            const normalized = normalizeImageUrl(rawUrl);
            if (!normalized) return;

            const lower = normalized.toLowerCase();
            if (!/^https?:\/\//.test(lower)) return;
            if (!lower.includes('/currency/token/')) return;
            if (lower.includes('/network/') || lower.includes('network-logo')) return;
            if (lower.includes('11111111111111111111111111111111')) return; // SOL logo

            let score = baseScore;
            if (currentTokenCA && lower.includes(`-${currentTokenCA}-`)) {
                score += 220;
            } else if (currentTokenCA && lower.includes(currentTokenCA)) {
                score += 160;
            }
            if (lower.includes('/large/')) score += 20;
            if (lower.includes('type=default_90_0')) score += 12;
            if (lower.includes('type=default_350_0')) score += 8;
            if (lower === defaultImageLower) score -= 60;

            candidates.push({ url: normalized, score });
        };

        const pushCandidate = (imageElement, baseScore = 0) => {
            if (!imageElement) return;
            if (imageElement.closest('.demo-trade-panel')) return;
            if (imageElement.closest('.demo-notification-container')) return;

            const candidateUrl = getImageUrlFromElement(imageElement);
            if (candidateUrl) {
                pushUrl(candidateUrl, baseScore);
            }
        };

        const symbolElement = document.querySelector('.B73M_W__dex');
        if (symbolElement) {
            const scopes = [
                symbolElement.closest('[class*="token"]'),
                symbolElement.closest('[class*="pair"]'),
                symbolElement.closest('section'),
                symbolElement.closest('div')
            ].filter(Boolean);

            for (const scope of scopes) {
                scope.querySelectorAll('picture source').forEach(source => {
                    if (source.closest('.demo-trade-panel')) return;
                    pushUrl(source.getAttribute('srcset') || '', 80);
                });
                scope.querySelectorAll('img').forEach(img => pushCandidate(img, 80));
            }
        }

        if (currentTokenCA) {
            const urlNodes = document.querySelectorAll('img[src], img[srcset], picture source[srcset]');
            urlNodes.forEach(node => {
                if (node.closest('.demo-trade-panel')) return;

                const raw =
                    (node.tagName && node.tagName.toLowerCase() === 'source')
                        ? (node.getAttribute('srcset') || '')
                        : (node.getAttribute('srcset') || node.getAttribute('src') || '');

                if (raw && String(raw).toLowerCase().includes(currentTokenCA)) {
                    pushUrl(raw, 130);
                }
            });
        }

        const sourceNodes = document.querySelectorAll('picture source[srcset*="/currency/token/"]');
        sourceNodes.forEach(source => {
            if (source.closest('.demo-trade-panel')) return;
            pushUrl(source.getAttribute('srcset') || '', 40);
        });

        const selectors = [
            '.lj9oR7__dex img',
            '.hiAF42__dex img',
            '.UvAw5q__dex img',
            '.vP8ohB__dex img',
            '[class*="token-avatar"] img',
            '[class*="TokenAvatar"] img',
            '.IMDFTB__dex img',
            '.BaV8Ko__dex img',
            'img[src*="/currency/token/"]',
            'img[srcset*="/currency/token/"]',
            'picture.dex-picture img'
        ];

        for (const selector of selectors) {
            const images = document.querySelectorAll(selector);
            for (const image of images) {
                pushCandidate(image, 30);
            }
        }

        if (!candidates.length) {
            const rememberedImage = currentTokenCA && demoPortfolio[currentTokenCA]
                ? demoPortfolio[currentTokenCA].image
                : '';
            return isLikelyTokenImageUrl(rememberedImage) ? normalizeImageUrl(rememberedImage) : null;
        }

        const uniqueCandidates = new Map();
        for (const item of candidates) {
            const existing = uniqueCandidates.get(item.url);
            if (!existing || item.score > existing.score) {
                uniqueCandidates.set(item.url, item);
            }
        }

        const best = Array.from(uniqueCandidates.values()).sort((a, b) => b.score - a.score)[0];
        return best ? best.url : null;
    }

    function getLiveTokenMetaFromDOM() {
        const sanitize = (value) => String(value || '').replace(/\s+/g, ' ').trim();
        const normalizeSymbol = (value) => sanitize(value).toUpperCase();
        const isBlockedSymbol = (value) => ['SOL', 'USDC', 'USDT', 'TOKEN'].includes(value);

        let symbol = '';
        let name = '';

        const tokenHeader = document.querySelector('.E36_sj__dex, [class*="E36_sj"]');
        if (tokenHeader) {
            const explicitNameEl = tokenHeader.querySelector('.AgB6GU__dex .ellipsis, [class*="AgB6GU"] .ellipsis');
            const explicitSymbolEl = tokenHeader.querySelector('.iI1U_c__dex.cQ_2nK__dex .ellipsis, .hXByxe__dex .ellipsis, [class*="hXByxe"] .ellipsis');

            name = sanitize(explicitNameEl ? explicitNameEl.textContent : '');
            symbol = normalizeSymbol(explicitSymbolEl ? explicitSymbolEl.textContent : '');

            const allLabels = Array.from(tokenHeader.querySelectorAll('.ellipsis'))
                .map(el => sanitize(el.textContent))
                .filter(Boolean);

            if (!name && allLabels.length > 0) {
                name = allLabels[0];
            }

            if (!symbol) {
                const upperCandidate = allLabels.find(label => /[A-Za-z]/.test(label) && label === label.toUpperCase());
                symbol = normalizeSymbol(upperCandidate || allLabels[1] || allLabels[0] || '');
            }
        }

        if (!symbol) {
            const fallbackSymbolEl = document.querySelector('.B73M_W__dex, [class*="B73M_W"]');
            symbol = normalizeSymbol(fallbackSymbolEl ? fallbackSymbolEl.textContent : '');
        }

        if (!name && symbol) {
            name = symbol;
        }

        if (isBlockedSymbol(symbol)) {
            symbol = '';
        }

        if (/^token$/i.test(name)) {
            name = '';
        }

        return { symbol, name };
    }

    function formatNumber(value, isFiat = true) {
        if (value === 0 || value === null || value === undefined) {
            return isFiat ? '$0.00' : '0.00';
        }

        if (isFiat) {
            if (Math.abs(value) >= 1000000) {
                return '$' + (value / 1000000).toFixed(2) + 'M';
            } else if (Math.abs(value) >= 1000) {
                return '$' + (value / 1000).toFixed(2) + 'K';
            } else {
                return '$' + value.toFixed(2);
            }
        } else {
            // Token miktarı için daha kompakt format
            const absValue = Math.abs(value);
            if (absValue >= 1000000) {
                return (value / 1000000).toFixed(2) + 'M';
            } else if (absValue >= 1000) {
                return (value / 1000).toFixed(2) + 'K';
            } else if (absValue >= 1) {
                return value.toFixed(2);
            } else if (absValue >= 0.01) {
                return value.toFixed(3);
            } else if (absValue >= 0.0001) {
                return value.toFixed(5);
            } else {
                return value.toFixed(7);
            }
        }
    }

    function formatBalanceDisplay(value) {
        if (value === null || value === undefined || !Number.isFinite(Number(value))) {
            return '0';
        }

        const numeric = Number(value);
        if (isEffectivelyZero(numeric)) {
            return '0';
        }

        const raw = formatNumber(numeric, false);
        return raw
            .replace(/(\.[0-9]*?[1-9])0+(?=[A-Za-z]*$)/, '$1')
            .replace(/\.0+(?=[A-Za-z]*$)/, '');
    }

    function formatPnLDisplay(value, isFiat = true) {
        if (value === null || value === undefined || !Number.isFinite(Number(value))) {
            return isFiat ? '$0.00' : '0';
        }

        const numeric = Number(value);
        if (isEffectivelyZero(numeric)) {
            return isFiat ? '$0.00' : '0';
        }

        const raw = formatNumber(numeric, isFiat);
        return raw
            .replace(/(\.[0-9]*?[1-9])0+(?=[A-Za-z]*$)/, '$1')
            .replace(/\.0+(?=[A-Za-z]*$)/, '');
    }

    function formatPnLSummaryAmountDisplay(value, isFiat = true) {
        if (!isFiat) {
            return formatPnLDisplay(value, false);
        }

        const numeric = Number(value);
        if (!Number.isFinite(numeric) || isEffectivelyZero(numeric)) {
            return '$0.0';
        }

        const abs = Math.abs(numeric);
        if (abs >= 1000000) {
            return `$${(numeric / 1000000).toFixed(1)}M`;
        }
        if (abs >= 1000) {
            return `$${(numeric / 1000).toFixed(1)}K`;
        }

        return `$${numeric.toFixed(1)}`;
    }

    function formatPnLIntegerDisplay(value, isFiat = true, nonFiatFractionDigits = 2) {
        const safeNonFiatDigits = Number.isInteger(nonFiatFractionDigits)
            ? Math.max(0, Math.min(8, nonFiatFractionDigits))
            : 2;

        if (value === null || value === undefined || !Number.isFinite(Number(value))) {
            return isFiat ? '$0.0' : (0).toFixed(safeNonFiatDigits);
        }

        const numeric = Number(value);
        const absoluteNumeric = Math.abs(numeric);
        if (isEffectivelyZero(absoluteNumeric)) {
            return isFiat ? '$0.0' : (0).toFixed(safeNonFiatDigits);
        }

        const fractionDigits = isFiat ? (absoluteNumeric > 99 ? 0 : 1) : safeNonFiatDigits;
        const multiplier = Math.pow(10, fractionDigits);
        let rounded = Math.round(numeric * multiplier) / multiplier;
        if (isEffectivelyZero(rounded)) {
            rounded = 0;
        }

        if (isFiat) {
            const absoluteText = Math.abs(rounded).toFixed(fractionDigits);
            if (rounded > 0) {
                return `+$${absoluteText}`;
            }
            if (rounded < 0) {
                return `-$${absoluteText}`;
            }
            return `$${absoluteText}`;
        }

        const absoluteText = Math.abs(rounded).toFixed(fractionDigits);
        if (rounded > 0) {
            return `+${absoluteText}`;
        }
        if (rounded < 0) {
            return `-${absoluteText}`;
        }
        return absoluteText;
    }

    function formatSignedUsdPnL(value, fractionDigits = 1) {
        const safeFractionDigits = Number.isInteger(fractionDigits)
            ? Math.max(0, Math.min(8, fractionDigits))
            : 1;

        if (value === null || value === undefined || !Number.isFinite(Number(value))) {
            return `$${(0).toFixed(safeFractionDigits)}`;
        }

        const numeric = Number(value);
        const multiplier = Math.pow(10, safeFractionDigits);
        let rounded = Math.round(numeric * multiplier) / multiplier;
        if (isEffectivelyZero(rounded)) {
            rounded = 0;
        }

        const absoluteText = Math.abs(rounded).toFixed(safeFractionDigits);
        if (rounded > 0) {
            return `+$${absoluteText}`;
        }
        if (rounded < 0) {
            return `-$${absoluteText}`;
        }
        return `$${absoluteText}`;
    }

    function copyTextToClipboard(text) {
        const safeText = typeof text === 'string' ? text : String(text || '');

        if (navigator.clipboard && typeof navigator.clipboard.writeText === 'function') {
            return navigator.clipboard.writeText(safeText);
        }

        return new Promise((resolve, reject) => {
            try {
                const textArea = document.createElement('textarea');
                textArea.value = safeText;
                textArea.setAttribute('readonly', 'readonly');
                textArea.style.position = 'fixed';
                textArea.style.left = '-9999px';
                document.body.appendChild(textArea);
                textArea.select();
                const copied = document.execCommand('copy');
                document.body.removeChild(textArea);

                if (copied) {
                    resolve();
                    return;
                }

                reject(new Error('Copy command failed'));
            } catch (error) {
                reject(error);
            }
        });
    }

    function formatTokenPriceDisplay(value) {
        if (value === null || value === undefined || !Number.isFinite(Number(value))) {
            return '$0';
        }

        const numeric = Number(value);
        const absValue = Math.abs(numeric);
        if (absValue === 0) {
            return '$0';
        }

        if (absValue < 0.000000000001) {
            return `$${numeric.toExponential(6)}`;
        }

        let decimals = 6;
        if (absValue < 1) decimals = 8;
        if (absValue < 0.01) decimals = 10;
        if (absValue < 0.0001) decimals = 12;

        const formatted = numeric
            .toFixed(decimals)
            .replace(/(\.[0-9]*?[1-9])0+$/, '$1')
            .replace(/\.0+$/, '');

        return `$${formatted}`;
    }

    function parseTokenPriceFromText(rawPriceText) {
        if (!rawPriceText || typeof rawPriceText !== 'string') return null;

        let cleanedPrice = rawPriceText
            .replace(/\s+/g, '')
            .replace('$', '')
            .replace(/,/g, '')
            .replace(/USDT|USD/gi, '');

        // OKX: 0.0₅123 => 0.00000123 (subscript, ondalık sonrası sıfır adedini temsil eder)
        const subscriptMap = {
            '\u2080': '0', '\u2081': '1', '\u2082': '2', '\u2083': '3', '\u2084': '4',
            '\u2085': '5', '\u2086': '6', '\u2087': '7', '\u2088': '8', '\u2089': '9'
        };

        const subscriptMatch = cleanedPrice.match(/^0\.0([\u2080-\u2089]+)(.*)$/);
        if (subscriptMatch) {
            const zeroCountText = Array.from(subscriptMatch[1])
                .map(char => subscriptMap[char] || '')
                .join('');
            const zeroCount = parseInt(zeroCountText, 10);
            const rest = (subscriptMatch[2] || '').replace(/[^\d]/g, '');

            if (!isNaN(zeroCount) && rest) {
                cleanedPrice = `0.${'0'.repeat(Math.min(zeroCount, 30))}${rest}`;
            }
        }

        cleanedPrice = cleanedPrice.replace(/[^\d.]/g, '');

        // Birden fazla nokta varsa tek ondalık formata indir
        if ((cleanedPrice.match(/\./g) || []).length > 1) {
            const parts = cleanedPrice.split('.');
            cleanedPrice = `${parts[0]}.${parts.slice(1).join('')}`;
        }

        const parsed = Number(cleanedPrice);
        return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
    }

    function extractPriceText(rawText, allowPlainNumber = false) {
        if (!rawText || typeof rawText !== 'string') return null;

        const normalized = rawText.replace(/\s+/g, ' ').trim();
        if (!normalized) return null;

        const dollarMatch = normalized.match(/\$\s*[0-9][0-9.,\u2080-\u2089]*/);
        if (dollarMatch && dollarMatch[0]) {
            return dollarMatch[0].replace(/\s+/g, '');
        }

        if (allowPlainNumber) {
            const compact = normalized.replace(/\s+/g, '').replace(/,/g, '');
            if (/^[0-9][0-9.\u2080-\u2089]*$/.test(compact)) {
                return compact;
            }

            const plainMatch = normalized.match(/([0-9][0-9.,\u2080-\u2089]*)/);
            if (plainMatch && plainMatch[1]) {
                return plainMatch[1].replace(/\s+/g, '');
            }
        }

        return null;
    }

    function getLiveSolPriceFromDOM() {
        const solImageHints = [
            '501-11111111111111111111111111111111-1',
            '11111111111111111111111111111111',
            '/501-',
            'solana'
        ];

        const isSolImage = (rawUrl) => {
            const url = normalizeImageUrl(rawUrl || '');
            if (!url) return false;
            const lower = url.toLowerCase();
            return solImageHints.some(hint => lower.includes(hint));
        };

        const parsePriceFromContainer = (container) => {
            if (!container) return null;

            const textCandidates = [
                ...Array.from(container.querySelectorAll('span')).map(el => el.textContent || ''),
                container.getAttribute ? container.getAttribute('aria-label') : null,
                container.textContent || ''
            ].filter(Boolean);

            for (const rawText of textCandidates) {
                const extracted = extractPriceText(rawText, true);
                const parsed = parseTokenPriceFromText(extracted || '');
                if (parsed && parsed > 0) {
                    return parsed;
                }
            }

            return null;
        };

        // 1) Kullanıcının paylaştığı üst bar yapısını önceliklendir: .PwSNTD__dex > .mB70vW__dex
        const scopedPopups = document.querySelectorAll('.PwSNTD__dex .mB70vW__dex');
        for (const popup of scopedPopups) {
            const image = popup.querySelector('img, .SN8BmF__dex');
            const imageUrl = getImageUrlFromElement(image) || (image ? image.getAttribute('src') : '');
            const popupText = popup.textContent || '';
            const isSolPopup = isSolImage(imageUrl) || /\bsol\b/i.test(popupText);
            if (!isSolPopup) continue;

            const parsedPrice = parsePriceFromContainer(popup);
            if (parsedPrice && parsedPrice > 0) {
                return parsedPrice;
            }
        }

        // 2) Genel fallback: tüm popup alanlarında SOL eşleşmesi ara
        const popupSelectors = [
            '.PwSNTD__dex .mB70vW__dex',
            '[data-testid="okd-popup"].mB70vW__dex',
            '.mB70vW__dex',
            '[data-testid="okd-popup"]'
        ];

        const popups = document.querySelectorAll(popupSelectors.join(','));
        for (const popup of popups) {
            const image = popup.querySelector('img');
            const imageUrl = getImageUrlFromElement(image) || (image ? image.getAttribute('src') : '');
            const popupText = popup.textContent || '';
            const isSolPopup = isSolImage(imageUrl) || /\bsol\b/i.test(popupText);
            if (!isSolPopup) continue;

            const parsedPrice = parsePriceFromContainer(popup);
            if (parsedPrice && parsedPrice > 0) {
                return parsedPrice;
            }
        }

        // 3) Son fallback: mB70vW satırındaki fiyat span'leri
        const directCandidates = document.querySelectorAll('.PwSNTD__dex .mB70vW__dex span, .mB70vW__dex span, .SN8BmF__dex + span');
        for (const element of directCandidates) {
            const extracted = extractPriceText(element.textContent || '', true);
            const parsed = parseTokenPriceFromText(extracted || '');
            if (parsed && parsed > 0) {
                return parsed;
            }
        }

        return null;
    }

    function getLiveTokenPriceFromDOM() {
        const labelSelectors = [
            '.Cg2_xV__dex',
            '.KMsU5K__dex',
            '[class*="Cg2_xV"]',
            '[class*="KMsU5K"]'
        ];

        const priceLabels = Array.from(document.querySelectorAll(labelSelectors.join(',')))
            .filter(el => (el.textContent || '').trim().toLowerCase() === 'price');

        for (const label of priceLabels) {
            const contextCandidates = [
                label.closest('.glKoFv__dex'),
                label.parentElement,
                label.closest('div'),
                label.parentElement ? label.parentElement.nextElementSibling : null,
                label.nextElementSibling
            ].filter(Boolean);

            for (const context of contextCandidates) {
                const valueCandidates = [
                    ...context.querySelectorAll('.BaV8Ko__dex, .IMDFTB__dex, [class*="BaV8Ko"], [class*="IMDFTB"]'),
                    context,
                    context.nextElementSibling
                ].filter(Boolean);

                for (const candidate of valueCandidates) {
                    const textCandidates = [
                        candidate.getAttribute ? candidate.getAttribute('data-clipboard-text') : null,
                        candidate.getAttribute ? candidate.getAttribute('data-copy') : null,
                        candidate.getAttribute ? candidate.getAttribute('title') : null,
                        candidate.getAttribute ? candidate.getAttribute('aria-label') : null,
                        candidate.textContent || ''
                    ].filter(Boolean);

                    for (const rawText of textCandidates) {
                        const text = extractPriceText(rawText, true);
                        const parsed = parseTokenPriceFromText(text || '');
                        if (parsed && parsed > 0) {
                            return parsed;
                        }
                    }
                }
            }
        }

        const directSelectors = [
            '.BaV8Ko__dex',
            '.IMDFTB__dex',
            '[class*="BaV8Ko"]',
            '[class*="IMDFTB"]',
            '[data-testid*="price"]',
            '[class*="price"]',
            '[class*="Price"]'
        ];

        for (const selector of directSelectors) {
            const elements = document.querySelectorAll(selector);
            for (const element of elements) {
                const textCandidates = [
                    element.getAttribute ? element.getAttribute('data-clipboard-text') : null,
                    element.getAttribute ? element.getAttribute('data-copy') : null,
                    element.getAttribute ? element.getAttribute('title') : null,
                    element.getAttribute ? element.getAttribute('aria-label') : null,
                    element.textContent || ''
                ].filter(Boolean);

                for (const rawText of textCandidates) {
                    const text = extractPriceText(rawText, selector.includes('BaV8Ko') || selector.includes('IMDFTB'));
                    const parsed = parseTokenPriceFromText(text || '');
                    if (parsed && parsed > 0) {
                        return parsed;
                    }
                }
            }
        }

        return null;
    }

    function saveSettingsToStorage() {
        localStorage.setItem('demoSettings', JSON.stringify(currentSettings));
    }

    function parseSlippagePercent(value, fallback = 0) {
        const numeric = parseFloat(String(value || '').replace('%', '').replace(',', '.').trim());
        if (!Number.isFinite(numeric)) {
            return fallback;
        }
        return Math.max(0, Math.min(100, numeric));
    }

    function normalizeSlippageText(value, fallback = '0%') {
        const numeric = parseSlippagePercent(value, parseSlippagePercent(fallback, 0));
        const fixed = Number(numeric.toFixed(4));
        return `${fixed}%`;
    }

    function parseFixedFeeSol(value, fallback = 0) {
        const normalizedText = String(value || '')
            .replace(',', '.')
            .replace(/[^0-9.]/g, '')
            .trim();

        const numeric = parseFloat(normalizedText);
        if (!Number.isFinite(numeric)) {
            return fallback;
        }

        return Math.max(0, numeric);
    }

    function normalizeFixedFeeSolText(value, fallback = '0.00005') {
        const fallbackNumeric = parseFixedFeeSol(fallback, 0.00005);
        const numeric = parseFixedFeeSol(value, fallbackNumeric);

        return numeric
            .toFixed(8)
            .replace(/0+$/, '')
            .replace(/\.$/, '') || '0';
    }

    function getTokenCAFromCurrentURLStrict() {
        try {
            const href = window.location.href;
            const parsedUrl = new URL(href);
            debugLog('🔍 Strict URL parsing for token:', href);

            // 1) Query param'ler
            const queryKeys = ['token', 'mint', 'address', 'ca', 'contractAddress', 'contract', 'tokenAddress', 'pairAddress'];
            for (const key of queryKeys) {
                const rawValue = parsedUrl.searchParams.get(key);
                const normalized = rawValue ? decodeURIComponent(rawValue).trim() : '';
                if (normalized && normalized.length > 10) {
                    return normalized;
                }
            }

            // 2) Path formatı: /token/{chain}/{contractAddress}
            const pathMatch = href.match(/\/token\/[^/]+\/([^/?#]+)/i);
            if (pathMatch && pathMatch[1] && pathMatch[1].length > 10) {
                return decodeURIComponent(pathMatch[1]);
            }

            // 3) Path segmentlerinden adres yakalama (Solana/EVM)
            const pathSegments = parsedUrl.pathname
                .split('/')
                .map(segment => decodeURIComponent(segment || '').trim())
                .filter(Boolean);

            for (let i = pathSegments.length - 1; i >= 0; i--) {
                const segment = pathSegments[i].replace(/[?#].*$/, '').trim();
                if (!segment) continue;

                if (/^0x[a-fA-F0-9]{40}$/.test(segment)) {
                    return segment;
                }

                if (/^[1-9A-HJ-NP-Za-km-z]{32,44}$/.test(segment) && segment !== '11111111111111111111111111111111') {
                    return segment;
                }
            }

            // 4) Son fallback: URL genelinde eÅŸleÅŸme
            const evmMatch = href.match(/0x[a-fA-F0-9]{40}/);
            if (evmMatch && evmMatch[0]) {
                return evmMatch[0];
            }

            const solMatches = href.match(/[1-9A-HJ-NP-Za-km-z]{32,44}/g) || [];
            const solCandidate = solMatches.find(value => value !== '11111111111111111111111111111111');
            if (solCandidate) {
                return solCandidate;
            }

            return '';
        } catch (error) {
            console.error('Error parsing token CA (strict):', error);
            return '';
        }
    }

    function getTokenCAFromURL(options = {}) {
        const allowLastKnown = options.allowLastKnown !== false;

        try {
            const strictTokenCA = getTokenCAFromCurrentURLStrict();
            if (strictTokenCA) {
                debugLog('✅ Token CA from current URL:', strictTokenCA);
                return strictTokenCA;
            }

            // Son başarılı CA yalnızca açıkça izin verildiğinde fallback olarak kullanılır.
            if (allowLastKnown && lastTokenCA) {
                debugLog('ℹ️ Using last known token CA:', lastTokenCA);
                return lastTokenCA;
            }

            debugLog('❌ No token identifier found');
            return 'default_token';
        } catch (error) {
            console.error('Error parsing token CA:', error);
            return 'error_token';
        }
    }

    function calculatePortfolioRealizedPnLSum() {
        let realizedSum = 0;

        Object.keys(demoPortfolio || {}).forEach(key => {
            const token = demoPortfolio[key];
            if (!token || typeof token !== 'object') return;

            const tokenRealized = Number(token.realizedPnL);
            if (Number.isFinite(tokenRealized)) {
                realizedSum += tokenRealized;
            }
        });

        return realizedSum;
    }

    function migrateLegacyPortfolioRealizedPnL() {
        let hasNonZeroTokenRealizedPnL = false;

        Object.keys(demoPortfolio || {}).forEach(key => {
            const token = demoPortfolio[key];
            if (!token || typeof token !== 'object') return;

            const numericRealized = Number(token.realizedPnL);
            token.realizedPnL = Number.isFinite(numericRealized) ? numericRealized : 0;
            if (token.realizedPnL !== 0) {
                hasNonZeroTokenRealizedPnL = true;
            }
        });

        const legacyGlobalRealized = Number(totalRealizedPnL);
        if (!hasNonZeroTokenRealizedPnL && Number.isFinite(legacyGlobalRealized) && Math.abs(legacyGlobalRealized) > 0) {
            const strictTokenCA = getTokenCAFromCurrentURLStrict();
            const fallbackTokenCA = strictTokenCA || lastTokenCA || Object.keys(demoPortfolio).find(key => key !== 'SOL') || 'SOL';

            if (!demoPortfolio[fallbackTokenCA]) {
                demoPortfolio[fallbackTokenCA] = {
                    amount: 0,
                    avgPrice: 0,
                    symbol: fallbackTokenCA === 'SOL' ? 'SOL' : (currentTokenSymbol || 'TOKEN'),
                    image: '',
                    totalInvested: 0,
                    totalSold: 0,
                    totalInvestedSol: 0,
                    totalSoldSol: 0,
                    realizedPnL: 0
                };
            }

            demoPortfolio[fallbackTokenCA].realizedPnL += legacyGlobalRealized;
        }

        totalRealizedPnL = calculatePortfolioRealizedPnLSum();
    }

    function getTokenSolTotalsFromTradeHistory(tokenCA) {
        const normalizedTokenCA = String(tokenCA || '').trim();
        if (!normalizedTokenCA || !Array.isArray(tradeHistory)) {
            return { totalInvestedSol: 0, totalSoldSol: 0 };
        }

        let totalInvestedSol = 0;
        let totalSoldSol = 0;

        tradeHistory.forEach(trade => {
            if (!trade || typeof trade !== 'object') return;
            if (String(trade.tokenCA || '').trim() !== normalizedTokenCA) return;

            const tradeType = String(trade.type || '').toUpperCase();
            const solAmount = Number(trade.solAmount);
            const totalFees = Number(trade.totalFees);

            if (tradeType === 'BUY') {
                const buySol = Number.isFinite(solAmount) ? solAmount : 0;
                const buyFeeSol = Number.isFinite(totalFees) ? totalFees : 0;
                totalInvestedSol += Math.max(0, buySol + buyFeeSol);
                return;
            }

            if (tradeType === 'SELL') {
                const netSoldSol = Number.isFinite(solAmount) ? solAmount : 0;
                totalSoldSol += Math.max(0, netSoldSol);
            }
        });

        return { totalInvestedSol, totalSoldSol };
    }

    function migrateLegacyPortfolioSolTotals() {
        Object.keys(demoPortfolio || {}).forEach(key => {
            const token = demoPortfolio[key];
            if (!token || typeof token !== 'object') return;

            const hasTotalInvestedSol = Number.isFinite(Number(token.totalInvestedSol)) && Number(token.totalInvestedSol) >= 0;
            const hasTotalSoldSol = Number.isFinite(Number(token.totalSoldSol)) && Number(token.totalSoldSol) >= 0;
            if (hasTotalInvestedSol && hasTotalSoldSol) return;

            const historyTotals = getTokenSolTotalsFromTradeHistory(key);
            if (!hasTotalInvestedSol) {
                token.totalInvestedSol = historyTotals.totalInvestedSol;
            }
            if (!hasTotalSoldSol) {
                token.totalSoldSol = historyTotals.totalSoldSol;
            }
        });
    }

    function getCurrentTokenPortfolio() {
        // Her seferinde URL'den CA al
        const tokenCA = getTokenCAFromURL();

        debugLog('🔄 Portfolio check - Current CA:', tokenCA, 'Symbol:', currentTokenSymbol);

        const normalizedCurrentImage = isLikelyTokenImageUrl(currentTokenImage)
            ? normalizeImageUrl(currentTokenImage)
            : '';

        // Mevcut token için portföy oluştur veya getir
        if (!demoPortfolio[tokenCA]) {
            demoPortfolio[tokenCA] = {
                amount: 0,
                avgPrice: 0,
                symbol: currentTokenSymbol,
                image: normalizedCurrentImage,
                totalInvested: 0,
                totalSold: 0,
                totalInvestedSol: 0,
                totalSoldSol: 0,
                realizedPnL: 0
            };
            debugLog('🆕 Created NEW portfolio for:', currentTokenSymbol, 'CA:', tokenCA);
        } else {
            // Mevcut portföy bilgilerini güncelle (sembol + geçerli ikon)
            demoPortfolio[tokenCA].symbol = currentTokenSymbol;
            if (normalizedCurrentImage) {
                demoPortfolio[tokenCA].image = normalizedCurrentImage;
            }
            debugLog('📁 Loaded EXISTING portfolio for:', currentTokenSymbol, 'Amount:', demoPortfolio[tokenCA].amount);
        }

        const activePortfolio = demoPortfolio[tokenCA];
        const legacySolTotals = getTokenSolTotalsFromTradeHistory(tokenCA);

        activePortfolio.amount = Number.isFinite(Number(activePortfolio.amount)) && Number(activePortfolio.amount) >= 0
            ? Number(activePortfolio.amount)
            : 0;
        activePortfolio.amount = Math.max(0, normalizeNearZero(activePortfolio.amount, TOKEN_AMOUNT_ZERO_EPSILON));

        activePortfolio.avgPrice = Number.isFinite(Number(activePortfolio.avgPrice)) && Number(activePortfolio.avgPrice) >= 0
            ? Number(activePortfolio.avgPrice)
            : 0;
        activePortfolio.avgPrice = normalizeNearZero(activePortfolio.avgPrice);

        if (isEffectivelyZero(activePortfolio.amount, TOKEN_AMOUNT_ZERO_EPSILON)) {
            activePortfolio.amount = 0;
            activePortfolio.avgPrice = 0;
        }

        activePortfolio.totalInvested = Number.isFinite(Number(activePortfolio.totalInvested)) && Number(activePortfolio.totalInvested) >= 0
            ? Number(activePortfolio.totalInvested)
            : 0;
        activePortfolio.totalSold = Number.isFinite(Number(activePortfolio.totalSold)) && Number(activePortfolio.totalSold) >= 0
            ? Number(activePortfolio.totalSold)
            : 0;
        activePortfolio.totalInvestedSol = Number.isFinite(Number(activePortfolio.totalInvestedSol)) && Number(activePortfolio.totalInvestedSol) >= 0
            ? Number(activePortfolio.totalInvestedSol)
            : legacySolTotals.totalInvestedSol;
        activePortfolio.totalSoldSol = Number.isFinite(Number(activePortfolio.totalSoldSol)) && Number(activePortfolio.totalSoldSol) >= 0
            ? Number(activePortfolio.totalSoldSol)
            : legacySolTotals.totalSoldSol;
        activePortfolio.realizedPnL = Number.isFinite(Number(activePortfolio.realizedPnL))
            ? Number(activePortfolio.realizedPnL)
            : 0;

        return activePortfolio;
    }

    function calculateTotalBalance() {
        let totalBalance = 0;

        // SOL bakiyesini ekle
        if (demoPortfolio.SOL && demoPortfolio.SOL.amount) {
            totalBalance += demoPortfolio.SOL.amount * currentSolPrice;
        }

        const strictActiveTokenCA = getTokenCAFromURL({ allowLastKnown: false });
        const activeTokenCA =
            strictActiveTokenCA && strictActiveTokenCA !== 'default_token' && strictActiveTokenCA !== 'error_token'
                ? strictActiveTokenCA
                : getTokenCAFromURL();

        // Diğer tokenların bakiyesini ekle
        Object.keys(demoPortfolio).forEach(key => {
            const token = demoPortfolio[key];
            const tokenAmount = token ? Math.max(0, normalizeNearZero(token.amount, TOKEN_AMOUNT_ZERO_EPSILON)) : 0;
            if (key !== 'SOL' && tokenAmount > 0) {
                // EÄŸer bu token ÅŸu anki token ise current price kullan, deÄŸilse avg price kullan
                const tokenPrice = (key === activeTokenCA) ? currentTokenPrice : (token.avgPrice || 0);
                totalBalance += tokenAmount * tokenPrice;
            }
        });

        return totalBalance;
    }

    function initDemoTrading() {
        if (isInitializing) {
            debugLog('🚫 Already initializing, skipping...');
            return;
        }

        isInitializing = true;
        debugLog('Initializing Demo Trading...');

        try {
            addDemoTab();
            addDemoButton();
            setupDemoMode();
            loadSettingsFromRealPanel();
            migrateLegacyPortfolioRealizedPnL();
            migrateLegacyPortfolioSolTotals();
            savePortfolioToStorage();
            startPriceUpdates();
            startSolPriceUpdates();
            setupKeyboardHotkeys();
            setupPageObserver();
        } catch (error) {
            console.error('Error in initDemoTrading:', error);
        } finally {
            setTimeout(() => {
                isInitializing = false;
            }, 1000);
        }
    }

    function setupPageObserver() {
        // Eğer observer zaten varsa, önce onu durdur
        if (pageObserver) {
            pageObserver.disconnect();
        }

        // Sayfa deÄŸiÅŸikliklerini izle
        pageObserver = new MutationObserver(function(mutations) {
            let shouldUpdate = false;

            mutations.forEach(function(mutation) {
                // Yeni node'lar eklendiÄŸinde kontrol et
                if (mutation.addedNodes && mutation.addedNodes.length > 0) {
                    for (let node of mutation.addedNodes) {
                        if (node.nodeType === 1) { // Element node
                            // Tab container deÄŸiÅŸti mi?
                            if (node.querySelector && (
                                node.querySelector('.dex-tabs-pane-list-container') ||
                                node.querySelector('.Q68nJL__dex') ||
                                node.querySelector('.vP8ohB__dex')
                            )) {
                                shouldUpdate = true;
                                break;
                            }
                        }
                    }
                }

                // Attribute deÄŸiÅŸiklikleri (active tab deÄŸiÅŸimi)
                if (mutation.type === 'attributes' &&
                    (mutation.attributeName === 'class' || mutation.attributeName === 'data-pane-id')) {
                    shouldUpdate = true;
                }
            });

            if (shouldUpdate && !isInitializing) {
                debugLog('Page changed, updating demo components...');

                if (pendingDemoComponentsUpdate) {
                    clearTimeout(pendingDemoComponentsUpdate);
                }

                pendingDemoComponentsUpdate = setTimeout(() => {
                    pendingDemoComponentsUpdate = null;
                    updateDemoComponents();
                }, 450);
            }
        });

        // Tüm sayfayı izle
        pageObserver.observe(document.body, {
            childList: true,
            subtree: true,
            attributes: true,
            attributeFilter: ['class', 'data-pane-id']
        });
    }

    function updateDemoComponents() {
        const strictTokenCA = getTokenCAFromCurrentURLStrict();
        if (!strictTokenCA && demoPanelVisible) {
            hideDemoPanel();
        }

        // Demo tab'ı kontrol et ve ekle
        if (!document.querySelector('[data-pane-id="demo_trading"]')) {
            addDemoTab();
        }

        // Demo butonunu kontrol et ve ekle
        if (!document.querySelector('.demo-trade-button')) {
            addDemoButton();
        }

        // Demo panel açıksa güncelle
        if (demoPanelVisible) {
            updateDemoPanelValues();
        }

        // Aktif tab'ı güncelle
        updateActiveTab();
    }

    function loadSettingsFromRealPanel() {
        const realPanel = document.querySelector('.cIknRK__dex:not(.demo-trade-panel)');
        if (realPanel) {
            const settingsSnapshotBefore = JSON.stringify(currentSettings);

            // Kullanıcı demo panelde slippage'i elle düzenlediyse, real panelden overwrite etme
            if (!currentSettings.customBuySlippage) {
                const buySlippage = realPanel.querySelector('.Nox6EF__dex .font-500');
                if (buySlippage) {
                    currentSettings.buySlippage = normalizeSlippageText(buySlippage.textContent || '15%', '15%');
                }
            } else {
                currentSettings.buySlippage = normalizeSlippageText(currentSettings.buySlippage, '15%');
            }

            if (!currentSettings.customSellSlippage) {
                const sellSlippageElements = realPanel.querySelectorAll('.Nox6EF__dex .font-500');
                if (sellSlippageElements.length > 1) {
                    currentSettings.sellSlippage = normalizeSlippageText(sellSlippageElements[1].textContent || '20%', '20%');
                }
            } else {
                currentSettings.sellSlippage = normalizeSlippageText(currentSettings.sellSlippage, '20%');
            }

            // Buy amounts
            if (!currentSettings.customBuyAmounts) {
                const buyAmounts = realPanel.querySelectorAll('.H5f_ax__dex.Cg7h1c__dex .l5GPKh__dex');
                if (buyAmounts.length > 0) {
                    currentSettings.buyAmounts = [
                        (buyAmounts[0] && buyAmounts[0].textContent ? buyAmounts[0].textContent.trim() : '') || currentSettings.buyAmounts[0] || defaultBuyAmounts[0],
                        (buyAmounts[1] && buyAmounts[1].textContent ? buyAmounts[1].textContent.trim() : '') || currentSettings.buyAmounts[1] || defaultBuyAmounts[1],
                        (buyAmounts[2] && buyAmounts[2].textContent ? buyAmounts[2].textContent.trim() : '') || currentSettings.buyAmounts[2] || defaultBuyAmounts[2],
                        (buyAmounts[3] && buyAmounts[3].textContent ? buyAmounts[3].textContent.trim() : '') || currentSettings.buyAmounts[3] || defaultBuyAmounts[3]
                    ];
                }
            }

            currentSettings.buyAmounts = currentSettings.buyAmounts
                .map(v => String(v || '').trim())
                .filter(Boolean)
                .slice(0, 4);
            while (currentSettings.buyAmounts.length < 4) {
                currentSettings.buyAmounts.push(defaultBuyAmounts[currentSettings.buyAmounts.length]);
            }

            // Sell percents
            if (!currentSettings.customSellPercents) {
                const sellPercents = realPanel.querySelectorAll('.H5f_ax__dex.ODJ17x__dex .l5GPKh__dex');
                if (sellPercents.length > 0) {
                    currentSettings.sellPercents = [
                        (sellPercents[0] && sellPercents[0].textContent ? sellPercents[0].textContent.trim() : '') || currentSettings.sellPercents[0] || defaultSellPercents[0],
                        (sellPercents[1] && sellPercents[1].textContent ? sellPercents[1].textContent.trim() : '') || currentSettings.sellPercents[1] || defaultSellPercents[1],
                        (sellPercents[2] && sellPercents[2].textContent ? sellPercents[2].textContent.trim() : '') || currentSettings.sellPercents[2] || defaultSellPercents[2],
                        (sellPercents[3] && sellPercents[3].textContent ? sellPercents[3].textContent.trim() : '') || currentSettings.sellPercents[3] || defaultSellPercents[3]
                    ];
                }
            }

            currentSettings.sellPercents = currentSettings.sellPercents
                .map(v => String(v || '').trim())
                .filter(Boolean)
                .slice(0, 4);
            while (currentSettings.sellPercents.length < 4) {
                currentSettings.sellPercents.push(defaultSellPercents[currentSettings.sellPercents.length]);
            }

            currentSettings.buySlippage = normalizeSlippageText(currentSettings.buySlippage, '15%');
            currentSettings.sellSlippage = normalizeSlippageText(currentSettings.sellSlippage, '20%');
            currentSettings.buyFixedFeeSol = normalizeFixedFeeSolText(currentSettings.buyFixedFeeSol, '0.00005');
            currentSettings.sellFixedFeeSol = normalizeFixedFeeSolText(currentSettings.sellFixedFeeSol, '0.00005');

            // Customize panel açıldığında eski değerlerin geri yazılmasını önlemek için temp değerleri de senkron tut
            tempBuyAmounts = [...currentSettings.buyAmounts];
            tempSellPercents = [...currentSettings.sellPercents];
            tempBuySlippage = currentSettings.buySlippage;
            tempSellSlippage = currentSettings.sellSlippage;
            tempBuyFixedFeeSol = currentSettings.buyFixedFeeSol;
            tempSellFixedFeeSol = currentSettings.sellFixedFeeSol;

            const buySlippageValueEl = document.querySelector('.demo-buy-slippage-value');
            if (buySlippageValueEl) {
                buySlippageValueEl.textContent = currentSettings.buySlippage;
            }

            const sellSlippageValueEl = document.querySelector('.demo-sell-slippage-value');
            if (sellSlippageValueEl) {
                sellSlippageValueEl.textContent = currentSettings.sellSlippage;
            }

            const buyFixedFeeValueEl = document.querySelector('.demo-buy-fixed-fee-value');
            if (buyFixedFeeValueEl) {
                buyFixedFeeValueEl.textContent = currentSettings.buyFixedFeeSol;
            }

            const sellFixedFeeValueEl = document.querySelector('.demo-sell-fixed-fee-value');
            if (sellFixedFeeValueEl) {
                sellFixedFeeValueEl.textContent = currentSettings.sellFixedFeeSol;
            }

            if (JSON.stringify(currentSettings) !== settingsSnapshotBefore) {
                saveSettingsToStorage();
            }
        }
    }

    function getCurrentPrices() {
        const previousTokenPrice = currentTokenPrice;

        try {
            const previousTokenCA = lastTokenCA;
            const previousTokenSymbol = currentTokenSymbol;

            debugLog('--- COIN PRICE SEARCH STARTED ---');

            // 1) Token sembolü ve resmi
            const liveTokenMeta = getLiveTokenMetaFromDOM();
            if (liveTokenMeta.symbol) {
                currentTokenSymbol = liveTokenMeta.symbol;
            }
            if (liveTokenMeta.name) {
                currentTokenName = liveTokenMeta.name;
            }

            const detectedTokenImage = getLiveTokenImageFromDOM();
            if (detectedTokenImage) {
                currentTokenImage = detectedTokenImage;
            } else if (!isLikelyTokenImageUrl(currentTokenImage)) {
                const tokenCA = getTokenCAFromURL();
                const rememberedImage = tokenCA && demoPortfolio[tokenCA] ? demoPortfolio[tokenCA].image : '';
                if (isLikelyTokenImageUrl(rememberedImage)) {
                    currentTokenImage = normalizeImageUrl(rememberedImage);
                }
            }

            debugLog('✅ Token symbol and image updated:', currentTokenSymbol, currentTokenName, currentTokenImage);

            // 2) SOL fiyatını canlı DOM'dan al (varsa)
            const liveSolPrice = getLiveSolPriceFromDOM();
            if (liveSolPrice && liveSolPrice > 0) {
                currentSolPrice = liveSolPrice;
                debugLog('✅ SOL PRICE FROM LIVE DOM:', currentSolPrice);
            } else if (!currentSolPrice || currentSolPrice <= 0 || Number.isNaN(currentSolPrice)) {
                // DOM'dan yakalanamadıysa async fallback'i tetikle; sabit sayıya düşme yapma
                fetchSolPrice();
            }

            // 3) Token fiyatını yeni + eski selector stratejileri ile bul
            const detectedPrice = getLiveTokenPriceFromDOM();
            if (detectedPrice && detectedPrice > 0) {
                currentTokenPrice = detectedPrice;
                debugLog('✅ PRICE SUCCESSFULLY PARSED:', currentTokenPrice);
            } else {
                // Hatalı parse durumunda son geçerli fiyatı koru
                currentTokenPrice = previousTokenPrice > 0 ? previousTokenPrice : 0;
                debugLog('❌ Price parsing failed, keeping previous price:', currentTokenPrice);
            }

            debugLog('✅ FINAL TOKEN PRICE:', currentTokenPrice);
            debugLog('--- COIN PRICE SEARCH ENDED ---');

            // 4) Token CA güncelle
            const strictCurrentTokenCA = getTokenCAFromURL({ allowLastKnown: false });
            const hasStrictCurrentTokenCA =
                strictCurrentTokenCA && strictCurrentTokenCA !== 'default_token' && strictCurrentTokenCA !== 'error_token';
            const currentTokenCA = hasStrictCurrentTokenCA ? strictCurrentTokenCA : getTokenCAFromURL();

            // lastTokenCA yalnızca strict URL çözümü başarılıysa güncellensin (stale fallback zincirini kırar)
            if (hasStrictCurrentTokenCA) {
                lastTokenCA = strictCurrentTokenCA;
            }

            // 5) Token değişim kontrolü
            const tokenChanged =
                (previousTokenCA !== currentTokenCA || previousTokenSymbol !== currentTokenSymbol) &&
                currentTokenCA !== 'default_token' &&
                currentTokenCA !== 'error_token' &&
                currentTokenSymbol !== 'TOKEN';

            if (tokenChanged) {
                debugLog('🔄 TOKEN CHANGED DETECTED!', {
                    from: `${previousTokenSymbol} (${previousTokenCA})`,
                    to: `${currentTokenSymbol} (${currentTokenCA})`
                });

                // Token deÄŸiÅŸiminde unrealized PnL realize edilmiyor.
                // Realized PnL yalnızca SELL işlemlerinde güncellenir.

                if (demoPanelVisible) {
                    debugLog('🔄 Rebuilding dropdowns for new token...');

                    if (tokenChangeUiRefreshTimeout) {
                        clearTimeout(tokenChangeUiRefreshTimeout);
                    }

                    tokenChangeUiRefreshTimeout = setTimeout(() => {
                        tokenChangeUiRefreshTimeout = null;

                        if (isPanelDragging) {
                            queueDropdownRefreshAfterDrag();
                            return;
                        }

                        calculatePnL();
                        lastPanelUpdateAt = 0;
                        lastPnLDisplayUpdateAt = 0;
                        setupDropdowns();
                        setupDropdownEvents();
                        updateDemoPanelValues(true);
                        updatePnLDisplay(true);
                    }, 100);
                }
            }

            calculatePnL();

        } catch (e) {
            console.error('❌ Price update error:', e);
            currentTokenPrice = previousTokenPrice > 0 ? previousTokenPrice : 0;
        }
    }

    // SOL fiyatını öncelikle canlı DOM'dan, yoksa API'den çek
    function fetchSolPrice() {
        const liveSolPrice = getLiveSolPriceFromDOM();
        if (liveSolPrice && liveSolPrice > 0) {
            currentSolPrice = liveSolPrice;
            debugLog('✅ SOL PRICE FROM LIVE DOM:', currentSolPrice);

            if (demoPanelVisible) {
                updateDemoPanelValues();
            }
            return;
        }

        const now = Date.now();
        if (now - lastSolApiFetchAt < SOL_API_FALLBACK_INTERVAL_MS) {
            return;
        }
        lastSolApiFetchAt = now;

        fetch('https://api.coingecko.com/api/v3/simple/price?ids=solana&vs_currencies=usd')
            .then(response => response.json())
            .then(data => {
                if (data.solana && data.solana.usd) {
                    currentSolPrice = data.solana.usd;
                    debugLog('✅ SOL PRICE FROM API:', currentSolPrice);

                    // Panel açıksa değerleri güncelle
                    if (demoPanelVisible) {
                        updateDemoPanelValues();
                    }
                }
            })
            .catch(() => {
                debugLog('❌ SOL price unavailable from DOM/API, keeping last known price:', currentSolPrice);
            });
    }

    // SOL fiyatını periyodik olarak güncelle
    function startSolPriceUpdates() {
        // İlk güncellemeyi hemen yap
        fetchSolPrice();

        // Sonra her 1 saniyede bir güncelle
        setInterval(fetchSolPrice, SOL_PRICE_UPDATE_INTERVAL_MS);
    }

    function calculatePnL() {
        const tokenPortfolio = getCurrentTokenPortfolio();
        const currentTokenCA = getTokenCAFromURL();

        debugLog('🔄 Calculating PnL for:', {
            symbol: currentTokenSymbol,
            CA: currentTokenCA,
            amount: tokenPortfolio.amount,
            avgPrice: tokenPortfolio.avgPrice,
            currentPrice: currentTokenPrice
        });

        // Reset values
        tokenPnL = 0;
        tokenPnLPercent = 0;
        totalPnL = 0;
        totalPnLPercent = 0;

        tokenPortfolio.amount = Math.max(0, normalizeNearZero(tokenPortfolio.amount, TOKEN_AMOUNT_ZERO_EPSILON));
        tokenPortfolio.avgPrice = Math.max(0, normalizeNearZero(tokenPortfolio.avgPrice));
        if (isEffectivelyZero(tokenPortfolio.amount, TOKEN_AMOUNT_ZERO_EPSILON)) {
            tokenPortfolio.amount = 0;
            tokenPortfolio.avgPrice = 0;
        }

        // Sadece mevcut token için unrealized PnL hesapla
        if (tokenPortfolio.amount > 0 && tokenPortfolio.avgPrice > 0) {
            const currentValue = tokenPortfolio.amount * currentTokenPrice;
            const costBasis = tokenPortfolio.amount * tokenPortfolio.avgPrice;
            tokenPnL = normalizeNearZero(currentValue - costBasis);
            tokenPnLPercent = costBasis > 0 ? (tokenPnL / costBasis) * 100 : 0;

            debugLog('📊 Current Token PnL:', {
                amount: tokenPortfolio.amount,
                avgPrice: tokenPortfolio.avgPrice,
                currentPrice: currentTokenPrice,
                costBasis: costBasis,
                currentValue: currentValue,
                pnl: tokenPnL,
                percent: tokenPnLPercent
            });
        }

        activeTokenRealizedPnL = Number.isFinite(Number(tokenPortfolio.realizedPnL))
            ? Number(tokenPortfolio.realizedPnL)
            : 0;

        // Global realized (hesap geneli) state'i de koru
        totalRealizedPnL = calculatePortfolioRealizedPnLSum();

        // Aktif coin TPnL = aktif realized + aktif unrealized
        totalPnL = normalizeNearZero(tokenPnL + activeTokenRealizedPnL);

        // Panelde aktif coin TPnL: realized + unrealized birlikte gösterilir.
        // Formül: sold + currentBalanceValue - totalInvested
        boughtAmount = Number.isFinite(Number(tokenPortfolio.totalInvested)) ? Number(tokenPortfolio.totalInvested) : 0;
        soldAmount = Number.isFinite(Number(tokenPortfolio.totalSold)) ? Number(tokenPortfolio.totalSold) : 0;
        boughtAmountSol = Number.isFinite(Number(tokenPortfolio.totalInvestedSol)) ? Number(tokenPortfolio.totalInvestedSol) : 0;
        soldAmountSol = Number.isFinite(Number(tokenPortfolio.totalSoldSol)) ? Number(tokenPortfolio.totalSoldSol) : 0;
        balanceAmount = normalizeNearZero(tokenPortfolio.amount * currentTokenPrice);

        const activeTokenTpnl = soldAmount + balanceAmount - boughtAmount;
        tpnlAmount = Number.isFinite(activeTokenTpnl) ? normalizeNearZero(activeTokenTpnl) : 0;

        const tpnlBase = boughtAmount > 0 ? boughtAmount : 0;
        totalPnLPercent = tpnlBase > 0 ? (tpnlAmount / tpnlBase) * 100 : 0;

        // NaN kontrolü
        if (isNaN(totalPnL)) totalPnL = 0;
        if (isNaN(totalPnLPercent)) totalPnLPercent = 0;
        if (isNaN(tokenPnL)) tokenPnL = 0;
        if (isNaN(tokenPnLPercent)) tokenPnLPercent = 0;
        if (isNaN(activeTokenRealizedPnL)) activeTokenRealizedPnL = 0;
        if (isNaN(totalRealizedPnL)) totalRealizedPnL = 0;

        debugLog('✅ Final PnL:', {
            tokenPnL: tokenPnL,
            tokenPnLPercent: tokenPnLPercent.toFixed(2) + '%',
            activeTokenRealizedPnL: activeTokenRealizedPnL,
            totalPnL: totalPnL,
            totalPnLPercent: totalPnLPercent.toFixed(2) + '%',
            totalRealizedPnL: totalRealizedPnL
        });
    }

    function savePortfolioToStorage() {
        totalRealizedPnL = calculatePortfolioRealizedPnLSum();
        localStorage.setItem('demoPortfolio', JSON.stringify(demoPortfolio));
        localStorage.setItem('totalRealizedPnL', totalRealizedPnL.toString());
        localStorage.setItem('totalTradeVolume', totalTradeVolume.toString());
        localStorage.setItem('tradeHistory', JSON.stringify(tradeHistory));
        debugLog('Portfolio saved to localStorage');
    }

    function startPriceUpdates() {
        // İlk fiyat güncellemesini hemen yap
        getCurrentPrices();
        fetchSolPrice();

        // Sonra periyodik olarak devam et
        setInterval(() => {
            if (demoMode) {
                getCurrentPrices();
                if (demoPanelVisible) {
                    updateDemoPanelValues();
                }
            }
        }, 1000); // 1 saniye (log/perf spam fix)
    }

    function addDemoTab() {
        const tabList = document.querySelector('.dex-tabs-pane-list-container');
        if (!tabList) {
            setTimeout(addDemoTab, 1000);
            return;
        }

        if (document.querySelector('[data-pane-id="demo_trading"]')) {
            return;
        }

        const demoTabHTML = `
            <div class="dex-tabs-pane dex-tabs-pane-lg dex-tabs-pane-blue dex-tabs-pane-underline AV2oC5__dex" data-pane-id="demo_trading" id=":r2if:-demo_trading" role="tab" aria-selected="false" tabindex="-1">
                <h2 class="font-inherit">Demo Trading</h2>
            </div>
        `;

        const lastTab = tabList.querySelector('.dex-tabs-pane:last-child');
        if (lastTab) {
            lastTab.insertAdjacentHTML('beforebegin', demoTabHTML);
            addTabClickHandler();
        }
    }

    function addDemoButton() {
        const buttonContainer = document.querySelector('.Q68nJL__dex');
        if (!buttonContainer) {
            setTimeout(addDemoButton, 1000);
            return;
        }

        if (document.querySelector('.demo-trade-button')) {
            return;
        }

        const demoButtonHTML = `
            <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-coach-popover dex-coachmark-var demo-trade-button">
                <button type="button" class="dex-plain-button peM48g__dex MovYo___dex q7TVYE__dex demo-mode-toggle">
                    <span class="zGJMLt__dex MovYo___dex">
                        <i class="icon iconfont dex-okx-defi-dex-quick-filled uZT0ej__dex" role="img" aria-hidden="true"></i>
                        <span>Demo trade</span>
                    </span>
                </button>
            </div>
        `;

        const instantTradeBtn = buttonContainer.querySelector('[data-testid="okd-popup"]:last-child');
        if (instantTradeBtn) {
            instantTradeBtn.insertAdjacentHTML('beforebegin', demoButtonHTML);
            addButtonClickHandler();
            updateDemoButton();
        }
    }

    function addTabClickHandler() {
        const demoTab = document.querySelector('[data-pane-id="demo_trading"]');
        if (demoTab) {
            demoTab.addEventListener('click', function() {
                switchToDemoMode();
                updateActiveTab();
                showDemoPanel();
            });
        }
    }

    function addButtonClickHandler() {
        const demoButton = document.querySelector('.demo-mode-toggle');
        if (demoButton) {
            setupDemoButtonHoverSync(demoButton);

            demoButton.addEventListener('click', function(e) {
                e.stopPropagation();
                demoMode = !demoMode;
                updateDemoButton();

                if (demoMode) {
                    showDemoPanel();
                } else {
                    hideDemoPanel();
                }
            });
        }
    }

    function switchToDemoMode() {
        demoMode = true;
        updateDemoButton();
        showDemoPanel();
    }

    function setupDemoButtonHoverSync(demoButton) {
        if (!demoButton || demoButton.dataset.hoverSyncBound === '1') return;

        demoButton.dataset.hoverSyncBound = '1';

        const applyClosedVisualSyncIfNeeded = () => {
            if (!demoMode) {
                syncDemoButtonClosedStyleFromInstantTrade(demoButton);
            }
        };

        demoButton.addEventListener('mouseenter', applyClosedVisualSyncIfNeeded);
        demoButton.addEventListener('mouseleave', applyClosedVisualSyncIfNeeded);
        demoButton.addEventListener('focus', applyClosedVisualSyncIfNeeded);
        demoButton.addEventListener('blur', applyClosedVisualSyncIfNeeded);
    }

    function getInstantTradeButtonFromContainer(demoButton) {
        if (!demoButton) return null;

        const buttonContainer = demoButton.closest('.Q68nJL__dex');
        if (!buttonContainer) return null;

        return buttonContainer.querySelector('[data-testid="okd-popup"]:last-child button');
    }

    function syncDemoButtonClosedStyleFromInstantTrade(demoButton) {
        if (!demoButton) return;

        demoButton.className = DEMO_BUTTON_BASE_CLASSNAME;

        const instantTradeButton = getInstantTradeButtonFromContainer(demoButton);
        if (!instantTradeButton || instantTradeButton === demoButton) return;

        const instantStyle = window.getComputedStyle(instantTradeButton);
        if (!instantStyle) return;

        demoButton.style.background = instantStyle.background;
        demoButton.style.backgroundColor = instantStyle.backgroundColor;
        demoButton.style.color = instantStyle.color;
        demoButton.style.borderColor = instantStyle.borderColor;
        demoButton.style.borderStyle = instantStyle.borderStyle;
        demoButton.style.borderWidth = instantStyle.borderWidth;
        demoButton.style.boxShadow = instantStyle.boxShadow;
        demoButton.style.borderRadius = instantStyle.borderRadius;
    }

    function updateDemoButton() {
        const demoButton = document.querySelector('.demo-mode-toggle');
        if (!demoButton) return;

        setupDemoButtonHoverSync(demoButton);

        const label = demoButton.querySelector('span span');
        if (label) {
            label.textContent = 'Demo trade';
        }

        const instantTradeButton = getInstantTradeButtonFromContainer(demoButton);
        const isInstantTradeVisible = instantTradeButton && window.getComputedStyle(instantTradeButton).display !== 'none';

        if (demoMode || isInstantTradeVisible) {
            demoButton.className = DEMO_BUTTON_BASE_CLASSNAME;
            demoButton.style.position = 'relative';
            demoButton.style.left = '';
            demoButton.style.top = '';
            demoButton.style.background = '';
            demoButton.style.backgroundColor = '';
            demoButton.style.color = '';
            demoButton.style.borderColor = '';
            demoButton.style.borderStyle = '';
            demoButton.style.borderWidth = '';
            demoButton.style.boxShadow = '';
            demoButton.style.borderRadius = '';
        } else {
            syncDemoButtonClosedStyleFromInstantTrade(demoButton);
            demoButton.style.position = 'fixed';
            demoButton.style.left = 'calc(50% - 50px)';
            demoButton.style.top = '100px';
        }
    }

    function updateActiveTab() {
        const tabs = document.querySelectorAll('.dex-tabs-pane');
        tabs.forEach(tab => {
            tab.classList.remove('dex-tabs-pane-underline-active', 'p0ZfTr__dex');
        });

        const activeTab = document.querySelector('[data-pane-id="demo_trading"]');
        if (activeTab) {
            activeTab.classList.add('dex-tabs-pane-underline-active', 'p0ZfTr__dex');
        }
    }

    function ensureDemoPanelStyles() {
        if (document.querySelector('#demo-panel-extra-styles')) return;

        const style = document.createElement('style');
        style.id = 'demo-panel-extra-styles';
        style.textContent = `
        @keyframes demoCustomizeInputIn {
            0% {
                opacity: 0;
                transform: translateY(8px) scale(0.985);
            }
            100% {
                opacity: 1;
                transform: translateY(0) scale(1);
            }
        }

        @keyframes demoCustomizeInputOut {
            0% {
                opacity: 0;
                transform: translateY(-8px) scale(0.985);
            }
            100% {
                opacity: 1;
                transform: translateY(0) scale(1);
            }
        }

        .demo-trade-panel .demo-buy-input,
        .demo-trade-panel .demo-sell-input,
        .demo-trade-panel .demo-buy-slippage-input,
        .demo-trade-panel .demo-sell-slippage-input,
        .demo-trade-panel .demo-buy-fixed-fee-input,
        .demo-trade-panel .demo-sell-fixed-fee-input,
        .demo-trade-panel .demo-sol-balance-input,
        .demo-trade-panel .demo-token-balance-input,
        .demo-trade-panel .demo-service-fee-input {
            animation: demoCustomizeInputIn 0.22s cubic-bezier(0.16, 1, 0.3, 1);
            will-change: transform, opacity;
        }

        .demo-trade-panel.demo-customize-exit .demo-buy-quick,
        .demo-trade-panel.demo-customize-exit .demo-sell-quick,
        .demo-trade-panel.demo-customize-exit .demo-buy-slippage-value,
        .demo-trade-panel.demo-customize-exit .demo-sell-slippage-value,
        .demo-trade-panel.demo-customize-exit .demo-buy-fixed-fee-value,
        .demo-trade-panel.demo-customize-exit .demo-sell-fixed-fee-value,
        .demo-trade-panel.demo-customize-exit .demo-service-fee-value,
        .demo-trade-panel.demo-customize-exit .VHD_xh__dex {
            animation: demoCustomizeInputOut 0.22s cubic-bezier(0.16, 1, 0.3, 1);
            will-change: transform, opacity;
        }

        .demo-trade-panel .demo-customize-btn {
            transition: background-color 0.16s ease, color 0.16s ease, box-shadow 0.16s ease;
        }

        .demo-trade-panel .demo-customize-btn i {
            transition: transform 0.14s ease;
        }

        .demo-trade-panel .demo-customize-btn-active i {
            transform: scale(1.05);
        }
        `;

        document.head.appendChild(style);
    }

    function showDemoPanel(forceRebuild = false) {
        if (isPanelDragging) {
            if (forceRebuild) {
                pendingPanelRebuildAfterDrag = true;
            } else {
                queuePanelValueRefreshAfterDrag();
            }
            return;
        }

        if (!getTokenCAFromCurrentURLStrict()) {
            hideDemoPanel();
            return;
        }

        if (demoPanelVisible && !forceRebuild) return;

        if (forceRebuild) {
            hideDemoPanel();
        }

        ensureDemoPanelStyles();
        loadSettingsFromRealPanel();
        getCurrentPrices();

        // Mevcut token portföyünü al
        const tokenPortfolio = getCurrentTokenPortfolio();

        // Panel açılırken de canlı DOM'dan icon al
        const liveTokenImage = getLiveTokenImageFromDOM();
        if (liveTokenImage) {
            currentTokenImage = liveTokenImage;
            tokenPortfolio.image = liveTokenImage;
        } else if (!isLikelyTokenImageUrl(currentTokenImage) && isLikelyTokenImageUrl(tokenPortfolio.image)) {
            currentTokenImage = normalizeImageUrl(tokenPortfolio.image);
        }

        const activeTokenImage = resolveTokenImageUrl(liveTokenImage, currentTokenImage, tokenPortfolio.image, DEFAULT_TOKEN_IMAGE);

        const demoPanelHTML = `
    <div class="cIknRK__dex gRJpse__dex demo-trade-panel${customizeExitAnimationPending ? ' demo-customize-exit' : ''}" role="button" tabindex="-1" style="left: 400px; top: 200px; opacity: 1; transition: all 0.2s; cursor: default; z-index: 1007;">
        <div class="vM9Rz8__dex F_UE_X__dex" role="button" tabindex="0" aria-disabled="false" aria-roledescription="draggable">
            <div class="bSH5VS__dex" aria-label="drag-to-move-dialog"><i class="icon iconfont cenOGi__dex dex-okx-defi-dex-drag" role="img" aria-hidden="true"></i></div>
            <div>
                <div class="NZD_dv__dex">
                    <div class="dex dex-select-var dex-select select-text Hp9ZjI__dex demo-default-select">
                        <div class="dex-select-value-box display-area pm_IiY__dex">
                            <div class="LFH5He__dex">
                                <div class="D3fk1I__dex">Default</div>
                                <i class="icon iconfont dex-okds-chevron-down icon-sign select-up dex-select-reference-icon dex-select-reference-icon-md" role="img" aria-label="" aria-hidden="true"></i>
                            </div>
                        </div>
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup select-popup-reference"></div>
                    </div>
                </div>
            </div>
            <div class="aynava__dex" style="display: flex; align-items: center; gap: 6px;">
                <!-- RESET BUTON -->
                <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral" style="margin: 0 0 0 4px;">
                    <button type="button" class="dex-plain-button hs2qqD__dex demo-reset-balance">
                        <i class="icon iconfont McyHpj__dex dex-okx-defi-dex-refresh" role="img" aria-label="Reset Demo"></i>
                    </button>
                </div>

                <!-- CUSTOMIZE BUTON -->
                <div data-testid="okd-popup" class="dex dex-popup-var dex-popup" style="margin: 0;">
                    <button type="button" class="dex-plain-button hs2qqD__dex demo-customize-btn ${customizeMode ? 'demo-customize-btn-active QzYi7N__dex' : ''}" aria-pressed="${customizeMode ? 'true' : 'false'}" style="${customizeMode ? 'background-color: rgba(188,255,47,0.16); color: #bcff2f; border-radius: 8px;' : ''}">
                        <i class="icon iconfont McyHpj__dex ${customizeMode ? 'dex-okx-defi-dex-check' : 'dex-okx-defi-marketplace-edit'}" role="img" aria-label="Customize amounts"></i>
                    </button>
                </div>

                <!-- HOTKEYS BUTON -->
                <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  " style="margin: 0;">
                    <button type="button" class="dex-plain-button hs2qqD__dex demo-hotkeys-btn ${hotkeysEnabled ? 'demo-hotkeys-btn-active' : ''}" aria-pressed="${hotkeysEnabled ? 'true' : 'false'}" style="${hotkeysEnabled ? 'background-color: rgba(188,255,47,0.16); color: #bcff2f; border-radius: 8px;' : ''}">
                        <i class="icon iconfont McyHpj__dex dex-okx-defi-dex-keyboard" role="img" aria-label="Click to activate hotkeys"></i>
                    </button>
                </div>

                <!-- PNL BUTON - GÜNCELLENDİ -->
                <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  " style="margin: 0;">
                    <button type="button" class="dex-plain-button hs2qqD__dex demo-pnl-btn ${pnlSectionVisible ? 'QzYi7N__dex' : ''}">
                        <i class="icon iconfont McyHpj__dex dex-okx-defi-web3-leaderboard ${pnlSectionVisible ? 'WAaPvo__dex' : ''}" role="img" aria-label="PnL"></i>
                    </button>
                </div>

                <i class="icon iconfont vuymPd__dex dex-okx-defi-marketplace-close dex-a11y-button demo-panel-close" role="button" aria-label="Close" tabindex="0" style="margin: 0;"></i>
            </div>
        </div>
        <div class="JlS9Ws__dex" style="padding-bottom: 0;">
            <div>
                <div class="flex justify-between items-center uyKNVr__dex">
                    <div class="dex dex-select-var dex-select select-text lnOLCt__dex instant-trade-token-selector-buy demo-buy-select">
                        <div class="dex-select-value-box display-area NC4WG2__dex">
                            <div class="e4mTHT__dex flex items-center font-12">
                                <span class="ioQevx__dex">Buy with</span>
                                <span class="font-500 UE7t1T__dex">SOL</span>
                                <i class="icon iconfont dex-okx-defi-dex-market-sort-down RQGYJ6__dex" role="img" aria-hidden="true"></i>
                            </div>
                        </div>
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup select-popup-reference"></div>
                    </div>
                    <div class="flex items-center">
                        ${customizeMode ? `
                            <div class="dex dex-input-var dex-input dex-input-sm" style="width: 80px; margin-right: 8px;">
                                <div class="dex-input-box auto-size" role="none">
                                    <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                    <input inputmode="decimal" enable_thousands="true" min="0" max="9007199254740991" autocomplete="off" step="1" id="demo-sol-balance-input" class="dex-input-input demo-sol-balance-input" autocapitalize="off" autocorrect="off" type="text" value="${demoPortfolio.SOL.amount.toFixed(4)}" name="demo_sol_balance_input">
                                    <div class="dex-input-suffix"></div>
                                </div>
                            </div>
                        ` : `
                            <span class="VHD_xh__dex">${formatBalanceDisplay(demoPortfolio.SOL.amount)}</span>
                        `}
                        <picture class="dex dex-picture dex-picture-font"><source srcset="${buildImageSrcset(SOL_TOKEN_IMAGE)}"><img width="16" height="16" class="Lrw8Qc__dex" alt="" src="${SOL_TOKEN_IMAGE}" style="width: 16px; height: 16px;"></picture>
                    </div>
                </div>
                <div class="flex justify-between lFouoK__dex">
                    <div class="k_jil0__dex xr2g7U__dex">
                        <div class="ThQSDh__dex options-wrapper">
                            ${customizeMode ? `
                                <!-- CUSTOMIZE MODE: INPUT ALANLARI -->
                                <div class="dex dex-input-var dex-input dex-input-md __XCfV__dex mW93WY__dex">
                                    <div class="dex-input-box auto-size E_NN8J__dex utlHnK__dex" role="none">
                                        <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                        <input inputmode="decimal" enable_thousands="true" min="0" max="9007199254740991" autocomplete="off" step="1" id="demo-buy-input-1" class="dex-input-input PfVQrS__dex demo-buy-input" autocapitalize="off" autocorrect="off" type="text" value="${tempBuyAmounts[0]}" name="demo_buy_input_1">
                                        <div class="dex-input-suffix"></div>
                                    </div>
                                </div>
                                <div class="dex dex-input-var dex-input dex-input-md __XCfV__dex mW93WY__dex">
                                    <div class="dex-input-box auto-size E_NN8J__dex utlHnK__dex" role="none">
                                        <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                        <input inputmode="decimal" enable_thousands="true" min="0" max="9007199254740991" autocomplete="off" step="1" id="demo-buy-input-2" class="dex-input-input PfVQrS__dex demo-buy-input" autocapitalize="off" autocorrect="off" type="text" value="${tempBuyAmounts[1]}" name="demo_buy_input_2">
                                        <div class="dex-input-suffix"></div>
                                    </div>
                                </div>
                                <div class="dex dex-input-var dex-input dex-input-md __XCfV__dex mW93WY__dex">
                                    <div class="dex-input-box auto-size E_NN8J__dex utlHnK__dex" role="none">
                                        <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                        <input inputmode="decimal" enable_thousands="true" min="0" max="9007199254740991" autocomplete="off" step="1" id="demo-buy-input-3" class="dex-input-input PfVQrS__dex demo-buy-input" autocapitalize="off" autocorrect="off" type="text" value="${tempBuyAmounts[2]}" name="demo_buy_input_3">
                                        <div class="dex-input-suffix"></div>
                                    </div>
                                </div>
                                <div class="dex dex-input-var dex-input dex-input-md __XCfV__dex mW93WY__dex">
                                    <div class="dex-input-box auto-size E_NN8J__dex utlHnK__dex" role="none">
                                        <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                        <input inputmode="decimal" enable_thousands="true" min="0" max="9007199254740991" autocomplete="off" step="1" id="demo-buy-input-4" class="dex-input-input PfVQrS__dex demo-buy-input" autocapitalize="off" autocorrect="off" type="text" value="${tempBuyAmounts[3]}" name="demo_buy_input_4">
                                        <div class="dex-input-suffix"></div>
                                    </div>
                                </div>
                            ` : `
                                <!-- NORMAL MODE: BUTONLAR -->
                                <div class="flex items-center kw6r9M__dex">
                                    <div class="H5f_ax__dex Cg7h1c__dex VmOKPA__dex demo-buy-quick" data-amount="${parseFloat(currentSettings.buyAmounts[0]) || 0.03}" style="cursor: pointer; background-color: rgba(18,18,18,0.72); color: #bcff2f; ${hotkeysEnabled && hotkeysSpacePressed ? 'border-radius: 8px 0 0 8px;' : ''}">
                                        <div class="l5GPKh__dex ellipsis" style="color: #bcff2f;">${currentSettings.buyAmounts[0] || '0.03'}</div>
                                    </div>
                                    ${hotkeysEnabled && hotkeysSpacePressed ? getHotkeyBadgeHTML('Q') : ''}
                                </div>
                                <div class="flex items-center kw6r9M__dex">
                                    <div class="H5f_ax__dex Cg7h1c__dex VmOKPA__dex demo-buy-quick" data-amount="${parseFloat(currentSettings.buyAmounts[1]) || 0.05}" style="cursor: pointer; background-color: rgba(18,18,18,0.72); color: #bcff2f; ${hotkeysEnabled && hotkeysSpacePressed ? 'border-radius: 8px 0 0 8px;' : ''}">
                                        <div class="l5GPKh__dex ellipsis" style="color: #bcff2f;">${currentSettings.buyAmounts[1] || '0.05'}</div>
                                    </div>
                                    ${hotkeysEnabled && hotkeysSpacePressed ? getHotkeyBadgeHTML('W') : ''}
                                </div>
                                <div class="flex items-center kw6r9M__dex">
                                    <div class="H5f_ax__dex Cg7h1c__dex VmOKPA__dex demo-buy-quick" data-amount="${parseFloat(currentSettings.buyAmounts[2]) || 0.07}" style="cursor: pointer; background-color: rgba(18,18,18,0.72); color: #bcff2f; ${hotkeysEnabled && hotkeysSpacePressed ? 'border-radius: 8px 0 0 8px;' : ''}">
                                        <div class="l5GPKh__dex ellipsis" style="color: #bcff2f;">${currentSettings.buyAmounts[2] || '0.07'}</div>
                                    </div>
                                    ${hotkeysEnabled && hotkeysSpacePressed ? getHotkeyBadgeHTML('E') : ''}
                                </div>
                                <div class="flex items-center kw6r9M__dex">
                                    <div class="H5f_ax__dex Cg7h1c__dex VmOKPA__dex demo-buy-quick" data-amount="${parseFloat(currentSettings.buyAmounts[3]) || 0.1}" style="cursor: pointer; background-color: rgba(18,18,18,0.72); color: #bcff2f; ${hotkeysEnabled && hotkeysSpacePressed ? 'border-radius: 8px 0 0 8px;' : ''}">
                                        <div class="l5GPKh__dex ellipsis" style="color: #bcff2f;">${currentSettings.buyAmounts[3] || '0.1'}</div>
                                    </div>
                                    ${hotkeysEnabled && hotkeysSpacePressed ? getHotkeyBadgeHTML('R') : ''}
                                </div>
                            `}
                        </div>
                    </div>
                </div>
                <div class="flex justify-start Nox6EF__dex">
                    <div class="flex items-center Fb9n18__dex" role="presentation">
                        <i class="icon iconfont dex-okx-defi-dex-slippage GuPJu7__dex" role="img" aria-hidden="true"></i>
                        ${customizeMode ? `
                            <div class="dex dex-input-var dex-input dex-input-sm" style="width: 70px; margin-left: 4px;">
                                <div class="dex-input-box auto-size" role="none">
                                    <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                    <input inputmode="decimal" autocomplete="off" step="0.1" id="demo-buy-slippage-input" class="dex-input-input demo-buy-slippage-input" autocapitalize="off" autocorrect="off" type="text" value="${tempBuySlippage}" name="demo_buy_slippage_input">
                                    <div class="dex-input-suffix"></div>
                                </div>
                            </div>
                        ` : `
                            <span class="font-12 ml-4 font-500 demo-buy-slippage-value">${currentSettings.buySlippage}</span>
                        `}
                        <span class="ROEGPH__dex"></span>
                        <i class="icon iconfont dex-okx-defi-dex-fee GuPJu7__dex" role="img" aria-hidden="true"></i>
                        ${customizeMode ? `
                            <div class="dex dex-input-var dex-input dex-input-sm" style="width: 90px; margin-left: 4px;">
                                <div class="dex-input-box auto-size" role="none">
                                    <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                    <input inputmode="decimal" autocomplete="off" step="0.000001" id="demo-buy-fixed-fee-input" class="dex-input-input demo-buy-fixed-fee-input" autocapitalize="off" autocorrect="off" type="text" value="${tempBuyFixedFeeSol}" name="demo_buy_fixed_fee_input">
                                    <div class="dex-input-suffix"></div>
                                </div>
                            </div>
                        ` : `
                            <span class="font-12 ml-4 font-500 demo-buy-fixed-fee-value">${currentSettings.buyFixedFeeSol}</span>
                        `}
                        <span class="ROEGPH__dex"></span>
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  "><div class="flex items-center"><i class="icon iconfont dex-okx-defi-web3-shield Xm6VIO__dex" role="img" aria-label="config-item"></i><span class="Or4Gzq__dex">Auto</span></div></div>
                        <i class="icon iconfont dex-okx-defi-marketplace-chevron-right C0NIv2__dex demo-buy-settings" role="img" aria-hidden="true" style="cursor: pointer;"></i>
                    </div>
                </div>
            </div>
            <div class="QwqNAT__dex">
                <div class="flex justify-between items-center uyKNVr__dex">
                    <div class="dex dex-select-var dex-select select-text lnOLCt__dex instant-trade-token-selector-sell demo-sell-select">
                        <div class="dex-select-value-box display-area NC4WG2__dex">
                            <div class="e4mTHT__dex flex items-center font-12">
                                <span class="ioQevx__dex demo-sell-for-label">Sell for <span class="font-500 UE7t1T__dex">SOL</span></span>
                                <i class="icon iconfont dex-okx-defi-dex-market-sort-down RQGYJ6__dex" role="img" aria-hidden="true" style="margin-left: -2px;"></i>
                            </div>
                        </div>
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup select-popup-reference"></div>
                    </div>
                    <div class="flex items-center">
                        ${customizeMode ? `
                            <div class="dex dex-input-var dex-input dex-input-sm" style="width: 80px; margin-right: 8px;">
                                <div class="dex-input-box auto-size" role="none">
                                    <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                    <input inputmode="decimal" enable_thousands="true" min="0" max="9007199254740991" autocomplete="off" step="1" id="demo-token-balance-input" class="dex-input-input demo-token-balance-input" autocapitalize="off" autocorrect="off" type="text" value="${tokenPortfolio.amount.toFixed(4)}" name="demo_token_balance_input">
                                    <div class="dex-input-suffix"></div>
                                </div>
                            </div>
                        ` : `
                            <span class="VHD_xh__dex">${formatBalanceDisplay(tokenPortfolio.amount)}</span>
                        `}
                        <picture class="dex dex-picture dex-picture-font"><source srcset="${buildImageSrcset(activeTokenImage)}"><img width="16" height="16" class="Lrw8Qc__dex" alt="" src="${activeTokenImage}" style="width: 16px; height: 16px;"></picture>
                    </div>
                </div>
                <div class="flex justify-between lFouoK__dex">
                    <div class="k_jil0__dex xr2g7U__dex">
                        <div class="ThQSDh__dex options-wrapper">
                            ${customizeMode ? `
                                <!-- CUSTOMIZE MODE: INPUT ALANLARI -->
                                <div class="dex dex-input-var dex-input dex-input-md __XCfV__dex mW93WY__dex">
                                    <div class="dex-input-box auto-size E_NN8J__dex utlHnK__dex" role="none">
                                        <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                        <input inputmode="decimal" enable_thousands="true" min="0" max="100" autocomplete="off" step="1" id="demo-sell-input-1" class="dex-input-input PfVQrS__dex demo-sell-input" autocapitalize="off" autocorrect="off" type="text" value="${tempSellPercents[0]}" name="demo_sell_input_1">
                                        <div class="dex-input-suffix"></div>
                                    </div>
                                </div>
                                <div class="dex dex-input-var dex-input dex-input-md __XCfV__dex mW93WY__dex">
                                    <div class="dex-input-box auto-size E_NN8J__dex utlHnK__dex" role="none">
                                        <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                        <input inputmode="decimal" enable_thousands="true" min="0" max="100" autocomplete="off" step="1" id="demo-sell-input-2" class="dex-input-input PfVQrS__dex demo-sell-input" autocapitalize="off" autocorrect="off" type="text" value="${tempSellPercents[1]}" name="demo_sell_input_2">
                                        <div class="dex-input-suffix"></div>
                                    </div>
                                </div>
                                <div class="dex dex-input-var dex-input dex-input-md __XCfV__dex mW93WY__dex">
                                    <div class="dex-input-box auto-size E_NN8J__dex utlHnK__dex" role="none">
                                        <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                        <input inputmode="decimal" enable_thousands="true" min="0" max="100" autocomplete="off" step="1" id="demo-sell-input-3" class="dex-input-input PfVQrS__dex demo-sell-input" autocapitalize="off" autocorrect="off" type="text" value="${tempSellPercents[2]}" name="demo_sell_input_3">
                                        <div class="dex-input-suffix"></div>
                                    </div>
                                </div>
                                <div class="dex dex-input-var dex-input dex-input-md __XCfV__dex mW93WY__dex">
                                    <div class="dex-input-box auto-size E_NN8J__dex utlHnK__dex" role="none">
                                        <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                        <input inputmode="decimal" enable_thousands="true" min="0" max="100" autocomplete="off" step="1" id="demo-sell-input-4" class="dex-input-input PfVQrS__dex demo-sell-input" autocapitalize="off" autocorrect="off" type="text" value="${tempSellPercents[3]}" name="demo_sell_input_4">
                                        <div class="dex-input-suffix"></div>
                                    </div>
                                </div>
                            ` : `
                                <!-- NORMAL MODE: BUTONLAR -->
                                <div class="flex items-center kw6r9M__dex">
                                    <div class="H5f_ax__dex ODJ17x__dex VmOKPA__dex demo-sell-quick" data-percent="${parseFloat((currentSettings.sellPercents[0] || '25%').replace('%', '')) || 25}" style="cursor: pointer; background-color: rgba(18,18,18,0.72); color: #fc46ab; ${hotkeysEnabled && hotkeysSpacePressed ? 'border-radius: 8px 0 0 8px;' : ''}">
                                        <div class="l5GPKh__dex ellipsis" style="color: #fc46ab;">${currentSettings.sellPercents[0] || '25%'}</div>
                                    </div>
                                    ${hotkeysEnabled && hotkeysSpacePressed ? getHotkeyBadgeHTML('A') : ''}
                                </div>
                                <div class="flex items-center kw6r9M__dex">
                                    <div class="H5f_ax__dex ODJ17x__dex VmOKPA__dex demo-sell-quick" data-percent="${parseFloat((currentSettings.sellPercents[1] || '50%').replace('%', '')) || 50}" style="cursor: pointer; background-color: rgba(18,18,18,0.72); color: #fc46ab; ${hotkeysEnabled && hotkeysSpacePressed ? 'border-radius: 8px 0 0 8px;' : ''}">
                                        <div class="l5GPKh__dex ellipsis" style="color: #fc46ab;">${currentSettings.sellPercents[1] || '50%'}</div>
                                    </div>
                                    ${hotkeysEnabled && hotkeysSpacePressed ? getHotkeyBadgeHTML('S') : ''}
                                </div>
                                <div class="flex items-center kw6r9M__dex">
                                    <div class="H5f_ax__dex ODJ17x__dex VmOKPA__dex demo-sell-quick" data-percent="${parseFloat((currentSettings.sellPercents[2] || '75%').replace('%', '')) || 75}" style="cursor: pointer; background-color: rgba(18,18,18,0.72); color: #fc46ab; ${hotkeysEnabled && hotkeysSpacePressed ? 'border-radius: 8px 0 0 8px;' : ''}">
                                        <div class="l5GPKh__dex ellipsis" style="color: #fc46ab;">${currentSettings.sellPercents[2] || '75%'}</div>
                                    </div>
                                    ${hotkeysEnabled && hotkeysSpacePressed ? getHotkeyBadgeHTML('D') : ''}
                                </div>
                                <div class="flex items-center kw6r9M__dex">
                                    <div class="H5f_ax__dex ODJ17x__dex VmOKPA__dex demo-sell-quick" data-percent="${parseFloat((currentSettings.sellPercents[3] || '100%').replace('%', '')) || 100}" style="cursor: pointer; background-color: rgba(18,18,18,0.72); color: #fc46ab; ${hotkeysEnabled && hotkeysSpacePressed ? 'border-radius: 8px 0 0 8px;' : ''}">
                                        <div class="l5GPKh__dex ellipsis" style="color: #fc46ab;">${currentSettings.sellPercents[3] || '100%'}</div>
                                    </div>
                                    ${hotkeysEnabled && hotkeysSpacePressed ? getHotkeyBadgeHTML('F') : ''}
                                </div>
                            `}
                        </div>
                    </div>
                </div>
                <div class="flex justify-start Nox6EF__dex">
                    <div class="flex items-center Fb9n18__dex" role="presentation">
                        <i class="icon iconfont dex-okx-defi-dex-slippage GuPJu7__dex" role="img" aria-hidden="true"></i>
                        ${customizeMode ? `
                            <div class="dex dex-input-var dex-input dex-input-sm" style="width: 70px; margin-left: 4px;">
                                <div class="dex-input-box auto-size" role="none">
                                    <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                    <input inputmode="decimal" autocomplete="off" step="0.1" id="demo-sell-slippage-input" class="dex-input-input demo-sell-slippage-input" autocapitalize="off" autocorrect="off" type="text" value="${tempSellSlippage}" name="demo_sell_slippage_input">
                                    <div class="dex-input-suffix"></div>
                                </div>
                            </div>
                        ` : `
                            <span class="font-12 ml-4 font-500 demo-sell-slippage-value">${currentSettings.sellSlippage}</span>
                        `}
                        <span class="ROEGPH__dex"></span>
                        <i class="icon iconfont dex-okx-defi-dex-fee GuPJu7__dex" role="img" aria-hidden="true"></i>
                        ${customizeMode ? `
                            <div class="dex dex-input-var dex-input dex-input-sm" style="width: 90px; margin-left: 4px;">
                                <div class="dex-input-box auto-size" role="none">
                                    <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                                    <input inputmode="decimal" autocomplete="off" step="0.000001" id="demo-sell-fixed-fee-input" class="dex-input-input demo-sell-fixed-fee-input" autocapitalize="off" autocorrect="off" type="text" value="${tempSellFixedFeeSol}" name="demo_sell_fixed_fee_input">
                                    <div class="dex-input-suffix"></div>
                                </div>
                            </div>
                        ` : `
                            <span class="font-12 ml-4 font-500 demo-sell-fixed-fee-value">${currentSettings.sellFixedFeeSol}</span>
                        `}
                        <span class="ROEGPH__dex"></span>
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  "><div class="flex items-center"><i class="icon iconfont dex-okx-defi-web3-shield Xm6VIO__dex" role="img" aria-label="config-item"></i><span class="Or4Gzq__dex">Auto</span></div></div>
                        <i class="icon iconfont dex-okx-defi-marketplace-chevron-right C0NIv2__dex demo-sell-settings" role="img" aria-hidden="true" style="cursor: pointer;"></i>
                    </div>
                </div>
            </div>
            <!-- SERVICE FEE KISMI - BOÅžLUK SADECE SERVICE FEE ALTINDA -->
            <div class="MEKLl5__dex LAaFhW__dex" style="justify-content: center; margin: 0px 0 24px;">
                <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral cursor-pointer  flex items-center underline-dash vgre7c__dex"><span class="Nx6sMk__dex">Service fee</span></div>
                ${customizeMode ? `
                    <div class="dex dex-input-var dex-input dex-input-sm" style="width: 80px; display: inline-block;">
                        <div class="dex-input-box auto-size" role="none">
                            <input autocomplete="off" readonly="" type="hidden" style="display: none;">
                            <input inputmode="decimal" enable_thousands="true" min="0" max="100" autocomplete="off" step="0.01" id="demo-service-fee-input" class="dex-input-input demo-service-fee-input" autocapitalize="off" autocorrect="off" type="text" value="${tempServiceFee}" name="demo_service_fee_input">
                            <div class="dex-input-suffix"></div>
                        </div>
                    </div>
                ` : `<span class="demo-service-fee-value">${currentSettings.serviceFee}</span>`}
            </div>

            <!-- PNL BÖLÜMÜ - YENİ TASARIM -->
            ${pnlSectionVisible ? `
                <!-- ÇİZGİ: EXTRA ALT BOŞLUK KALDIRILDI -->
                <div class="zt1bsn__dex" style="margin: 0 -12px !important; width: calc(100% + 24px);"></div>
                <div class="flex gap-2 font-12 items-center">
                    <div class="K_Nnu2__dex">
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  ">
                            <div class="sU7u0q__dex underline-dash">Bought</div>
                        </div>
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  ">
                            <div class="bXHX98__dex HV7ko9__dex demo-pnl-bought">${formatPnLSummaryAmountDisplay(boughtAmount, showFiat)}</div>
                        </div>
                    </div>
                    <div class="K_Nnu2__dex">
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  ">
                            <div class="sU7u0q__dex underline-dash">Sold</div>
                        </div>
                        <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  ">
                            <div class="bXHX98__dex HV7ko9__dex demo-pnl-sold">${formatPnLSummaryAmountDisplay(soldAmount, showFiat)}</div>
                        </div>
                    </div>
                    <div class="K_Nnu2__dex">
                        <div class="sU7u0q__dex">Balance</div>
                        <div class="bXHX98__dex HV7ko9__dex demo-pnl-balance">${formatPnLSummaryAmountDisplay(balanceAmount, showFiat)}</div>
                    </div>
                    <div class="lWdbPD__dex">
                        <div class="flex flex-row items-center justify-center">
                            <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  ">
                                <div class="sU7u0q__dex underline-dash">T/R/UPnl</div>
                            </div>
                            <div data-testid="okd-popup" class="dex dex-popup-var dex-popup dex-tooltip dex-tooltip-var dex-tooltip-neutral  ">
                                <div role="button" tabindex="0" class="l6WLJO__dex border-1 rounded-full w-16 h-16 ml-2 demo-currency-toggle" data-icon-mode="${showFiat ? 'fiat' : 'token'}">
                                    ${getCurrencyToggleIconHTML(showFiat)}
                                </div>
                            </div>
                        </div>
                        <div class="VlintX__dex">
                            <div class="ibsEqm__dex HV7ko9__dex VlintX__dex demo-pnl-inline-values" style="display: flex; align-items: center; gap: 0; white-space: nowrap;">
                                <span class="demo-pnl-tpnl">${formatPnLIntegerDisplay(totalPnL, showFiat)}</span><span class="demo-pnl-space" style="display: inline-block; width: 0.35em; min-width: 0.35em;"></span><span class="demo-pnl-rpnl">${formatPnLIntegerDisplay(activeTokenRealizedPnL, showFiat)}</span><span class="demo-pnl-space" style="display: inline-block; width: 0.35em; min-width: 0.35em;"></span><span class="demo-pnl-upnl">${formatPnLIntegerDisplay(tokenPnL, showFiat)}</span>
                            </div>
                        </div>
                    </div>
                </div>
            ` : ''}
        </div>
    </div>
    `;

        hideDemoPanel();
        document.body.insertAdjacentHTML('beforeend', demoPanelHTML);

        setTimeout(() => {
            try {
                setupDemoPanelEvents();
                setupAdvancedDragAndDrop();
                setupDropdowns();
                setupDropdownEvents();
                updateDemoPanelValues();
            } catch (error) {
                console.error('Error setting up demo panel:', error);
            }
        }, 200);

        demoPanelVisible = true;
        customizeExitAnimationPending = false;
    }

    function hideDemoPanel() {
        const demoPanel = document.querySelector('.demo-trade-panel');
        if (demoPanel) {
            demoPanel.remove();
        }
        if (tokenChangeUiRefreshTimeout) {
            clearTimeout(tokenChangeUiRefreshTimeout);
            tokenChangeUiRefreshTimeout = null;
        }
        isPanelDragging = false;
        pendingPanelRebuildAfterDrag = false;
        pendingDropdownRefreshAfterDrag = false;
        pendingPanelValueRefreshAfterDrag = false;
        demoPanelVisible = false;
    }

    function setupAdvancedDragAndDrop() {
        const demoPanel = document.querySelector('.demo-trade-panel');
        if (!demoPanel) return;

        let isDragging = false;
        let startX, startY, initialX, initialY;

        const dragHandle = demoPanel.querySelector('.vM9Rz8__dex');

        const dragStart = (e) => {
            if (e.target.closest('.vM9Rz8__dex')) {
                isDragging = true;
                isPanelDragging = true;
                startX = e.clientX || e.touches[0].clientX;
                startY = e.clientY || e.touches[0].clientY;

                const rect = demoPanel.getBoundingClientRect();
                initialX = rect.left;
                initialY = rect.top;

                demoPanel.style.cursor = 'grabbing';
                demoPanel.style.transition = 'none';
                demoPanel.style.opacity = '0.85';

                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();
            }
        };

        const drag = (e) => {
            if (!isDragging) return;

            const currentX = e.clientX || e.touches[0].clientX;
            const currentY = e.clientY || e.touches[0].clientY;

            const deltaX = currentX - startX;
            const deltaY = currentY - startY;

            demoPanel.style.left = (initialX + deltaX) + 'px';
            demoPanel.style.top = (initialY + deltaY) + 'px';

            e.preventDefault();
            e.stopPropagation();
        };

        const dragEnd = () => {
            if (!isDragging) return;

            isDragging = false;
            isPanelDragging = false;
            demoPanel.style.cursor = 'default';
            demoPanel.style.transition = 'all 0.2s';
            demoPanel.style.opacity = '1';

            const hadPendingRebuild = pendingPanelRebuildAfterDrag;
            flushDeferredPanelActionsAfterDrag();

            if (!hadPendingRebuild) {
                lastPanelUpdateAt = 0;
                lastPnLDisplayUpdateAt = 0;
                updateDemoPanelValues();
            }
        };

        dragHandle.addEventListener('mousedown', dragStart, true);
        dragHandle.addEventListener('touchstart', dragStart, { passive: false });

        document.addEventListener('mousemove', drag, true);
        document.addEventListener('touchmove', drag, { passive: false });

        document.addEventListener('mouseup', dragEnd, true);
        document.addEventListener('touchend', dragEnd, true);
        document.addEventListener('mouseleave', dragEnd, true);
    }

    function setupDropdowns() {
        if (isPanelDragging) {
            queueDropdownRefreshAfterDrag();
            return;
        }

        debugLog('🔄 Setting up dropdowns with current token:', currentTokenSymbol, currentTokenImage);

        // Default select dropdown
        const defaultSelect = document.querySelector('.demo-default-select');
        if (defaultSelect) {
            const popupReference = defaultSelect.querySelector('.select-popup-reference');
            if (popupReference) {
                popupReference.innerHTML = `
                    <div class="dex dex-popup-var dex-popup-layer dex-popup-layer-visible" style="z-index: 10000; visibility: hidden; position: absolute; left: 0px; top: 0px; margin: 0px; transform: translate(0px, 34px);" data-popper-placement="bottom-start">
                        <div class="dex-popup-layer-content" style="width: 140px;">
                            <div class="dex-select-var dex-select-option dex-select-option-pc yip61W__dex align-left drop-mode option-md">
                                <div class="dex-select-option-box">
                                    <div class="pc-option-scroll" style="max-height: 200px;">
                                        <div class="dex-select-item-container dex-select-item-container-real">
                                            <div class="dex-select-item dex-select-item-active dex-dropdown-option demo-default-option" role="option" aria-selected="true" data-value="Default">
                                                <div class="flex justify-between items-center Be9HsZ__dex">
                                                    <div class="vZhXdm__dex">Default</div>
<i class="icon iconfont dex-okx-defi-dex-check DaCpQM__dex qriW7s__dex" role="img" aria-hidden="true"></i>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;
            }
        }

        // Buy token select dropdown
        const buySelect = document.querySelector('.demo-buy-select');
        if (buySelect) {
            const popupReference = buySelect.querySelector('.select-popup-reference');
            if (popupReference) {
                const solBalance = demoPortfolio.SOL.amount.toFixed(4);
                const solValue = (demoPortfolio.SOL.amount * currentSolPrice).toFixed(2);

                popupReference.innerHTML = `
                    <div class="dex dex-popup-var dex-popup-layer dex-popup-layer-visible" style="z-index: 10001; visibility: hidden; position: absolute; left: 0px; top: 0px; margin: 0px; transform: translate(0px, 40px);" data-popper-placement="bottom-start">
                        <div class="dex-popup-layer-content" style="width: 308px;">
                            <div class="dex-select-var dex-select-option dex-select-option-pc WFwMwa__dex instant-trade-token-selector-option-cont-buy align-left drop-mode option-md">
                                <div class="dex-select-option-box">
                                    <div class="pc-option-scroll" style="max-height: 208px;">
                                        <div class="dex-select-item-container dex-select-item-container-real">
                                            <div class="dex-select-item dex-select-item-active dex-dropdown-option demo-buy-option" role="option" aria-selected="true" data-value="SOL">
                                                <div class="flex justify-between items-center G9BMtd__dex">
                                                    <div class="flex items-center">
                                                        <picture class="dex dex-picture dex-picture-font">
                                                            <source srcset="${buildImageSrcset(SOL_TOKEN_IMAGE)}">
                                                                <img width="28" height="28" class="jxzKU9__dex" alt="" src="${SOL_TOKEN_IMAGE}" style="width: 28px; height: 28px;">
                                                                    </picture>
<div class="flex flex-col">
    <span class="tiQWEG__dex">SOL</span>
<span class="inAvcR__dex">Solana</span>
</div>
</div>
<div class="flex flex-col tsKlgJ__dex">
    <span class="tiQWEG__dex">${solBalance}</span>
<span class="inAvcR__dex">$${solValue}</span>
</div>
</div>
</div>
<div class="dex-select-item dex-dropdown-option demo-buy-option" role="option" aria-selected="false" data-value="USDC">
    <div class="flex justify-between items-center G9BMtd__dex">
        <div class="flex items-center">
            <picture class="dex dex-picture dex-picture-font">
                <source srcset="https://web3.okx.com/cdn/web3/currency/token/large/637-0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b-107/type=default_90_0?v=1756203256814&amp;x-oss-process=image/format,webp/ignore-error,1">
                    <img width="28" height="28" class="jxzKU9__dex" alt="" src="https://web3.okx.com/cdn/web3/currency/token/large/637-0xbae207659db88bea0cbead6da0ed00aac12edcdda169e591cd41c94180b46f3b-107/type=default_90_0?v=1756203256814" style="width: 28px; height: 28px;">
                        </picture>
<div class="flex flex-col">
    <span class="tiQWEG__dex">USDC</span>
<span class="inAvcR__dex">USD Coin</span>
</div>
</div>
<div class="flex flex-col tsKlgJ__dex">
    <span class="tiQWEG__dex">0</span>
<span class="inAvcR__dex">$0.00</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;

                // Sadece SOL seçeneğini bırak
                popupReference
                    .querySelectorAll('.demo-buy-option:not([data-value="SOL"])')
                    .forEach(el => el.remove());
            }
        }

        // Sell token select dropdown
        const sellSelect = document.querySelector('.demo-sell-select');
        if (sellSelect) {
            const popupReference = sellSelect.querySelector('.select-popup-reference');
            if (popupReference) {
                const tokenPortfolio = getCurrentTokenPortfolio();
                const tokenBalance = tokenPortfolio.amount.toFixed(4);
                const tokenValueUsdNumeric = tokenPortfolio.amount * currentTokenPrice;
                const tokenValueInUsd = tokenValueUsdNumeric.toFixed(2);
                const tokenValueInSol = currentSolPrice > 0
                    ? (tokenValueUsdNumeric / currentSolPrice).toFixed(4)
                    : '0.0000';

                const liveTokenImage = getLiveTokenImageFromDOM();
                if (liveTokenImage) {
                    currentTokenImage = liveTokenImage;
                    tokenPortfolio.image = liveTokenImage;
                }
                const resolvedTokenImage = resolveTokenImageUrl(liveTokenImage, currentTokenImage, tokenPortfolio.image, DEFAULT_TOKEN_IMAGE);

                popupReference.innerHTML = `
                    <div class="dex dex-popup-var dex-popup-layer dex-popup-layer-visible" style="z-index: 10002; visibility: hidden; position: absolute; left: 0px; top: 0px; margin: 0px; transform: translate(0px, 40px);" data-popper-placement="bottom-start">
                        <div class="dex-popup-layer-content" style="width: 308px;">
                            <div class="dex-select-var dex-select-option dex-select-option-pc WFwMwa__dex instant-trade-token-selector-option-cont-sell align-left drop-mode option-md">
                                <div class="dex-select-option-box">
                                    <div class="pc-option-scroll" style="max-height: 208px;">
                                        <div class="dex-select-item-container dex-select-item-container-real">
                                            <div class="dex-select-item dex-select-item-active dex-dropdown-option demo-sell-option" role="option" aria-selected="true" data-value="${currentTokenSymbol}">
                                                <div class="flex justify-between items-center G9BMtd__dex">
                                                    <div class="flex items-center">
                                                        <picture class="dex dex-picture dex-picture-font">
                                                            <source srcset="${buildImageSrcset(SOL_TOKEN_IMAGE)}">
                                                                <img width="28" height="28" class="jxzKU9__dex" alt="" src="${SOL_TOKEN_IMAGE}" style="width: 28px; height: 28px;">
                                                                    </picture>
<div class="flex flex-col">
    <span class="tiQWEG__dex">${currentTokenSymbol}</span>
<span class="inAvcR__dex">${currentTokenName || 'Current Token'}</span>
</div>
</div>
<div class="flex flex-col tsKlgJ__dex">
    <span class="tiQWEG__dex">${tokenBalance}</span>
<span class="inAvcR__dex">$${tokenValueInUsd}</span>
</div>
</div>
</div>
<div class="dex-select-item dex-dropdown-option demo-sell-option" role="option" aria-selected="false" data-value="SOL">
    <div class="flex justify-between items-center G9BMtd__dex">
        <div class="flex items-center">
            <picture class="dex dex-picture dex-picture-font">
                <source srcset="${buildImageSrcset(SOL_TOKEN_IMAGE)}">
                    <img width="28" height="28" class="jxzKU9__dex" alt="" src="${SOL_TOKEN_IMAGE}" style="width: 28px; height: 28px;">
                        </picture>
<div class="flex flex-col">
    <span class="tiQWEG__dex">SOL</span>
<span class="inAvcR__dex">Solana</span>
</div>
</div>
<div class="flex flex-col tsKlgJ__dex">
    <span class="tiQWEG__dex">${tokenValueInSol}</span>
<span class="inAvcR__dex">$${tokenValueInUsd}</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
`;

                popupReference
                    .querySelectorAll('.demo-sell-option:not([data-value="SOL"])')
                    .forEach(el => el.remove());

                const sellOnlyOption = popupReference.querySelector('.demo-sell-option[data-value="SOL"]');
                if (sellOnlyOption) {
                    sellOnlyOption.classList.add('dex-select-item-active');
                    sellOnlyOption.setAttribute('aria-selected', 'true');
                }

                const sellDisplayLabel = document.querySelector('.demo-sell-select .demo-sell-for-label');
                if (sellDisplayLabel) {
                    sellDisplayLabel.innerHTML = 'Sell for <span class="font-500 UE7t1T__dex">SOL</span>';
                }

                debugLog('✅ Sell dropdown updated with SOL-only option');
            }
        }
    }

    function toggleDropdownPopupVisibility(selectValueBox, popupLayer, zIndex = '10009') {
        if (!selectValueBox || !popupLayer) return;

        const isVisible = popupLayer.style.visibility === 'visible';

        document.querySelectorAll('.dex-popup-layer').forEach(layer => {
            layer.style.visibility = 'hidden';
            layer.style.zIndex = '-1';
        });

        if (isVisible) return;

        const selectWrapper = selectValueBox.closest('.dex-select') || selectValueBox;
        const wrapperRect = selectWrapper.getBoundingClientRect();
        const popupOffsetY = Math.round((wrapperRect.height || selectValueBox.getBoundingClientRect().height || 34) + DROPDOWN_VERTICAL_OFFSET_PX);

        popupLayer.style.position = 'absolute';
        popupLayer.style.left = '0px';
        popupLayer.style.top = '0px';
        popupLayer.style.margin = '0';
        popupLayer.style.transform = `translate(0px, ${popupOffsetY}px)`;
        popupLayer.style.visibility = 'visible';
        popupLayer.style.zIndex = zIndex;
    }

    function setupDropdownEvents() {
        if (isPanelDragging) {
            queueDropdownRefreshAfterDrag();
            return;
        }

        debugLog('Setting up dropdown events...');

        // Default select
        const defaultSelect = document.querySelector('.demo-default-select .dex-select-value-box');
        if (defaultSelect) {
            defaultSelect.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                const popup = this.closest('.dex-select').querySelector('.dex-popup-layer');
                toggleDropdownPopupVisibility(this, popup, '10008');
                return false;
            }, true);
        }

        // Buy select
        const buySelect = document.querySelector('.demo-buy-select .dex-select-value-box');
        if (buySelect) {
            buySelect.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                const popup = this.closest('.dex-select').querySelector('.dex-popup-layer');
                toggleDropdownPopupVisibility(this, popup, '10009');
                return false;
            }, true);
        }

        // Sell select
        const sellSelect = document.querySelector('.demo-sell-select .dex-select-value-box');
        if (sellSelect) {
            sellSelect.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                const popup = this.closest('.dex-select').querySelector('.dex-popup-layer');
                toggleDropdownPopupVisibility(this, popup, '10009');
                return false;
            }, true);
        }

        // Dropdown options
        setTimeout(() => {
            document.querySelectorAll('.demo-default-option').forEach(option => {
                option.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    e.stopImmediatePropagation();

                    const value = this.getAttribute('data-value');
                    const display = document.querySelector('.demo-default-select .D3fk1I__dex');
                    if (display) display.textContent = value;

                    document.querySelectorAll('.dex-popup-layer').forEach(p => {
                        p.style.visibility = 'hidden';
                        p.style.zIndex = '-1';
                    });

                    showDemoNotification(`Mode changed to: ${value}`, 'info');
                    return false;
                }, true);
            });

            document.querySelectorAll('.demo-buy-option').forEach(option => {
                option.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    e.stopImmediatePropagation();

                    const value = this.getAttribute('data-value');
                    const display = document.querySelector('.demo-buy-select .UE7t1T__dex');
                    if (display) display.textContent = value;

                    document.querySelectorAll('.dex-popup-layer').forEach(p => {
                        p.style.visibility = 'hidden';
                        p.style.zIndex = '-1';
                    });

                    showDemoNotification(`Buy with: ${value}`, 'info');
                    return false;
                }, true);
            });

            document.querySelectorAll('.demo-sell-option').forEach(option => {
                option.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    e.stopImmediatePropagation();

                    const value = this.getAttribute('data-value');
                    const display = document.querySelector('.demo-sell-select .demo-sell-for-label');
                    if (display) display.innerHTML = 'Sell for <span class="font-500 UE7t1T__dex">SOL</span>';

                    document.querySelectorAll('.dex-popup-layer').forEach(p => {
                        p.style.visibility = 'hidden';
                        p.style.zIndex = '-1';
                    });

                    showDemoNotification(`Sell for: ${value}`, 'info');
                    return false;
                }, true);
            });
        }, 100);

        // Document click to close dropdowns
        document.addEventListener('click', function(e) {
            // Sadece demo dropdown'ları değilse kapat
            if (!e.target.closest('.demo-default-select') &&
                !e.target.closest('.demo-buy-select') &&
                !e.target.closest('.demo-sell-select') &&
                !e.target.closest('.dex-popup-layer')) {
                document.querySelectorAll('.dex-popup-layer').forEach(popup => {
                    popup.style.visibility = 'hidden';
                    popup.style.zIndex = '-1';
                });
            }
        }, true);
    }

    function setupDemoPanelEvents() {
        debugLog('Setting up demo panel events...');

        // Kapat butonu
        const closeBtn = document.querySelector('.demo-panel-close');
        if (closeBtn) {
            closeBtn.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                hideDemoPanel();
                return false;
            }, true);
        }

        // Reset butonu
        const resetBtn = document.querySelector('.demo-reset-balance');
        if (resetBtn) {
            resetBtn.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                resetDemoAccount();
                return false;
            }, true);
        }

        // Customize butonu
        const customizeBtn = document.querySelector('.demo-customize-btn');
        if (customizeBtn) {
            debugLog('Customize button found, setting up click event...');

            const newCustomizeBtn = customizeBtn.cloneNode(true);
            customizeBtn.parentNode.replaceChild(newCustomizeBtn, customizeBtn);

            newCustomizeBtn.addEventListener('click', function(e) {
                debugLog('✅ CUSTOMIZE BUTTON CLICKED! Mode:', customizeMode);
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                toggleCustomizeMode();
                return false;
            }, true);
        }

        // Hotkeys butonu
        const hotkeysBtn = document.querySelector('.demo-hotkeys-btn');
        if (hotkeysBtn) {
            const newHotkeysBtn = hotkeysBtn.cloneNode(true);
            hotkeysBtn.parentNode.replaceChild(newHotkeysBtn, hotkeysBtn);

            newHotkeysBtn.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                hotkeysEnabled = !hotkeysEnabled;
                hotkeysSpacePressed = false;

                if (hotkeysEnabled) {
                    showDemoNotification('Hotkeys enabled. Hold SPACE to show keycaps, then use QWER / ASDF.', 'info');
                } else {
                    showDemoNotification('Hotkeys disabled.', 'info');
                }

                requestPanelRebuildPreservingPosition();

                return false;
            }, true);
        }

        // PnL butonu - YENİ EKLENDİ
        const pnlBtn = document.querySelector('.demo-pnl-btn');
        if (pnlBtn) {
            pnlBtn.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                debugLog('✅ PNL BUTTON CLICKED! Current state:', pnlSectionVisible);
                pnlSectionVisible = !pnlSectionVisible;

                // Panel'i yeniden oluÅŸtur
                if (demoPanelVisible) {
                    requestPanelRebuildPreservingPosition();
                }

                return false;
            }, true);
        }

        // Currency toggle butonu - GÜNCELLENDİ
        const currencyToggle = document.querySelector('.demo-currency-toggle');
        if (currencyToggle) {
            // Mevcut event listener'ları temizle
            const newCurrencyToggle = currencyToggle.cloneNode(true);
            currencyToggle.parentNode.replaceChild(newCurrencyToggle, currencyToggle);

            newCurrencyToggle.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                e.stopImmediatePropagation();

                debugLog('💰 Currency toggle clicked. Current mode:', showFiat);
                showFiat = !showFiat;

                // Butonun görünürlüğünü koru ve güncelle
                this.style.display = 'flex';
                this.style.alignItems = 'center';
                this.style.justifyContent = 'center';

                updatePnLDisplay(true);
                return false;
            }, true);
        }

        // Buy settings butonu (prompt kaldırıldı, slippage sadece customize mode'dan düzenlenir)
        const buySettings = document.querySelector('.demo-buy-settings');
        if (buySettings) {
            buySettings.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                return false;
            }, true);
        }

        // Sell settings butonu (prompt kaldırıldı, slippage sadece customize mode'dan düzenlenir)
        const sellSettings = document.querySelector('.demo-sell-settings');
        if (sellSettings) {
            sellSettings.addEventListener('click', function(e) {
                e.preventDefault();
                e.stopPropagation();
                return false;
            }, true);
        }

        // Hızlı alım butonları (sadece customize mode kapalıyken)
        if (!customizeMode) {
            const buyButtons = document.querySelectorAll('.demo-buy-quick');
            buyButtons.forEach(btn => {
                btn.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    const amount = parseFloat(this.getAttribute('data-amount')) || 0.03;
                    executeDemoBuy(amount);
                    return false;
                }, true);
            });
        }

        // Hızlı satış butonları (sadece customize mode kapalıyken)
        if (!customizeMode) {
            const sellButtons = document.querySelectorAll('.demo-sell-quick');
            sellButtons.forEach(btn => {
                btn.addEventListener('click', function(e) {
                    e.preventDefault();
                    e.stopPropagation();
                    const percent = parseInt(this.getAttribute('data-percent')) || 50;
                    executeDemoSell(percent);
                    return false;
                }, true);
            });
        }

        // Input event'leri (sadece customize mode açıkken)
        if (customizeMode) {
            // Buy amount input'ları
            const buyInputs = document.querySelectorAll('.demo-buy-input');
            buyInputs.forEach((input, index) => {
                input.addEventListener('input', function() {
                    tempBuyAmounts[index] = this.value;
                    debugLog(`Buy amount ${index + 1} updated: ${this.value}`);
                });

                input.addEventListener('blur', function() {
                    tempBuyAmounts[index] = this.value;
                    debugLog(`Buy amount ${index + 1} saved: ${this.value}`);
                });
            });

            // Sell percent input'ları
            const sellInputs = document.querySelectorAll('.demo-sell-input');
            sellInputs.forEach((input, index) => {
                input.addEventListener('input', function() {
                    tempSellPercents[index] = this.value;
                    debugLog(`Sell percent ${index + 1} updated: ${this.value}`);
                });

                input.addEventListener('blur', function() {
                    tempSellPercents[index] = this.value;
                    debugLog(`Sell percent ${index + 1} saved: ${this.value}`);
                });
            });

            // Buy slippage input event'i
            const buySlippageInput = document.querySelector('.demo-buy-slippage-input');
            if (buySlippageInput) {
                buySlippageInput.addEventListener('input', function() {
                    tempBuySlippage = this.value;
                    debugLog(`Buy slippage updated: ${this.value}`);
                });

                buySlippageInput.addEventListener('blur', function() {
                    tempBuySlippage = normalizeSlippageText(this.value, currentSettings.buySlippage || '15%');
                    this.value = tempBuySlippage;
                    debugLog(`Buy slippage saved: ${this.value}`);
                });
            }

            // Sell slippage input event'i
            const sellSlippageInput = document.querySelector('.demo-sell-slippage-input');
            if (sellSlippageInput) {
                sellSlippageInput.addEventListener('input', function() {
                    tempSellSlippage = this.value;
                    debugLog(`Sell slippage updated: ${this.value}`);
                });

                sellSlippageInput.addEventListener('blur', function() {
                    tempSellSlippage = normalizeSlippageText(this.value, currentSettings.sellSlippage || '20%');
                    this.value = tempSellSlippage;
                    debugLog(`Sell slippage saved: ${this.value}`);
                });
            }

            // Buy fixed fee input event'i
            const buyFixedFeeInput = document.querySelector('.demo-buy-fixed-fee-input');
            if (buyFixedFeeInput) {
                buyFixedFeeInput.addEventListener('input', function() {
                    tempBuyFixedFeeSol = this.value;
                    debugLog(`Buy fixed fee updated: ${this.value}`);
                });

                buyFixedFeeInput.addEventListener('blur', function() {
                    tempBuyFixedFeeSol = normalizeFixedFeeSolText(this.value, currentSettings.buyFixedFeeSol || '0.00005');
                    this.value = tempBuyFixedFeeSol;
                    debugLog(`Buy fixed fee saved: ${this.value}`);
                });
            }

            // Sell fixed fee input event'i
            const sellFixedFeeInput = document.querySelector('.demo-sell-fixed-fee-input');
            if (sellFixedFeeInput) {
                sellFixedFeeInput.addEventListener('input', function() {
                    tempSellFixedFeeSol = this.value;
                    debugLog(`Sell fixed fee updated: ${this.value}`);
                });

                sellFixedFeeInput.addEventListener('blur', function() {
                    tempSellFixedFeeSol = normalizeFixedFeeSolText(this.value, currentSettings.sellFixedFeeSol || '0.00005');
                    this.value = tempSellFixedFeeSol;
                    debugLog(`Sell fixed fee saved: ${this.value}`);
                });
            }

            // Service fee input event'i
            const serviceFeeInput = document.querySelector('.demo-service-fee-input');
            if (serviceFeeInput) {
                serviceFeeInput.addEventListener('input', function() {
                    tempServiceFee = this.value;
                    debugLog(`Service fee updated: ${this.value}`);
                });

                serviceFeeInput.addEventListener('blur', function() {
                    tempServiceFee = this.value;
                    debugLog(`Service fee saved: ${this.value}`);
                });
            }

            // SOL balance input event'i
            const solBalanceInput = document.querySelector('.demo-sol-balance-input');
            if (solBalanceInput) {
                solBalanceInput.addEventListener('input', function() {
                    const newValue = parseFloat(this.value);
                    if (!isNaN(newValue) && newValue >= 0) {
                        demoPortfolio.SOL.amount = newValue;
                        debugLog(`SOL balance updated: ${this.value}`);
                    }
                });

                solBalanceInput.addEventListener('blur', function() {
                    const newValue = parseFloat(this.value);
                    if (!isNaN(newValue) && newValue >= 0) {
                        demoPortfolio.SOL.amount = newValue;
                        savePortfolioToStorage();
                        debugLog(`SOL balance saved: ${this.value}`);
                    }
                });
            }

            // Token balance input event'i
            const tokenBalanceInput = document.querySelector('.demo-token-balance-input');
            if (tokenBalanceInput) {
                tokenBalanceInput.addEventListener('input', function() {
                    const newValue = parseFloat(this.value);
                    if (!isNaN(newValue) && newValue >= 0) {
                        const tokenPortfolio = getCurrentTokenPortfolio();
                        tokenPortfolio.amount = newValue;
                        debugLog(`Token balance updated: ${this.value}`);
                    }
                });

                tokenBalanceInput.addEventListener('blur', function() {
                    const newValue = parseFloat(this.value);
                    if (!isNaN(newValue) && newValue >= 0) {
                        const tokenPortfolio = getCurrentTokenPortfolio();
                        tokenPortfolio.amount = newValue;
                        savePortfolioToStorage();
                        debugLog(`Token balance saved: ${this.value}`);
                    }
                });
            }
        }
    }

    function toggleCustomizeMode() {
        debugLog('Toggling customize mode. Current mode:', customizeMode);
        const wasCustomizeMode = customizeMode;
        customizeMode = !customizeMode;
        customizeExitAnimationPending = wasCustomizeMode && !customizeMode;

        if (customizeMode) {
            // Geçici değerleri mevcut ayarlarla doldur
            tempBuyAmounts = [...currentSettings.buyAmounts];
            tempSellPercents = [...currentSettings.sellPercents];
            tempBuySlippage = currentSettings.buySlippage;
            tempSellSlippage = currentSettings.sellSlippage;
            tempBuyFixedFeeSol = currentSettings.buyFixedFeeSol;
            tempSellFixedFeeSol = currentSettings.sellFixedFeeSol;
            tempServiceFee = currentSettings.serviceFee;
            showDemoNotification('Customize mode activated - Edit buy/sell amounts, slippage, fixed fees and service fee', 'info');
        } else {
            // DeÄŸiÅŸiklikleri kaydet
            currentSettings.buyAmounts = [...tempBuyAmounts];
            currentSettings.sellPercents = [...tempSellPercents];
            currentSettings.buySlippage = normalizeSlippageText(tempBuySlippage, currentSettings.buySlippage || '15%');
            currentSettings.sellSlippage = normalizeSlippageText(tempSellSlippage, currentSettings.sellSlippage || '20%');
            currentSettings.customBuySlippage = true;
            currentSettings.customSellSlippage = true;
            currentSettings.customBuyAmounts = true;
            currentSettings.customSellPercents = true;
            currentSettings.buyFixedFeeSol = normalizeFixedFeeSolText(tempBuyFixedFeeSol, currentSettings.buyFixedFeeSol || '0.00005');
            currentSettings.sellFixedFeeSol = normalizeFixedFeeSolText(tempSellFixedFeeSol, currentSettings.sellFixedFeeSol || '0.00005');
            currentSettings.serviceFee = tempServiceFee;

            // Ayarları localStorage'a kaydet
            saveSettingsToStorage();
            savePortfolioToStorage();

            showDemoNotification('Custom amounts, slippage, fixed fees and service fee saved successfully!', 'success');
        }

        // PANELİ YENİDEN OLUŞTUR
        if (demoPanelVisible) {
            requestPanelRebuildPreservingPosition();
            debugLog('Panel rebuilt with customize mode:', customizeMode);
        }
    }

    function resetDemoAccount() {
        if (confirm('Are you sure you want to reset your demo account? All portfolio data will be lost.')) {
            let resetSolAmount = DEBUG_RESET_SOL_FALLBACK_AMOUNT;
            if (DEBUG_RESET_WITH_USD_TARGET_ENABLED) {
                const liveSolPrice = getLiveSolPriceFromDOM();
                if (liveSolPrice && liveSolPrice > 0) {
                    currentSolPrice = liveSolPrice;
                }

                const usdTargetAmount = Number(DEBUG_RESET_USD_TARGET_AMOUNT);
                const solPriceForReset = Number(currentSolPrice);
                if (Number.isFinite(usdTargetAmount) && usdTargetAmount > 0 && Number.isFinite(solPriceForReset) && solPriceForReset > 0) {
                    resetSolAmount = usdTargetAmount / solPriceForReset;
                } else {
                    debugLog('⚠️ Reset USD target aktif ama SOL fiyatı geçersiz, fallback SOL amount kullanılacak.', {
                        usdTargetAmount,
                        solPriceForReset,
                        fallback: DEBUG_RESET_SOL_FALLBACK_AMOUNT
                    });
                }
            }

            if (!Number.isFinite(resetSolAmount) || resetSolAmount <= 0) {
                resetSolAmount = DEBUG_RESET_SOL_FALLBACK_AMOUNT;
            }

            demoBalance = Number.isFinite(currentSolPrice) && currentSolPrice > 0
                ? resetSolAmount * currentSolPrice
                : 1000;

            // Sadece SOL'u koru, diğer tüm tokenları temizle
            demoPortfolio = {
                'SOL': {
                    amount: resetSolAmount,
                    avgPrice: Number.isFinite(currentSolPrice) && currentSolPrice > 0 ? currentSolPrice : 100,
                    symbol: 'SOL',
                    image: 'https://web3.okx.com/cdn/web3/currency/token/501-11111111111111111111111111111111-1.png/type=default_350_0?v=1734571825920',
                    totalInvested: 0,
                    totalSold: 0,
                    totalInvestedSol: 0,
                    totalSoldSol: 0,
                    realizedPnL: 0
                }
            };
            totalPnL = 0;
            totalPnLPercent = 0;
            tokenPnL = 0;
            tokenPnLPercent = 0;
            activeTokenRealizedPnL = 0;
            totalRealizedPnL = 0;
            totalTradeVolume = 0;
            tradeHistory = [];
            boughtAmount = 0;
            soldAmount = 0;
            boughtAmountSol = 0;
            soldAmountSol = 0;
            balanceAmount = 0;
            tpnlAmount = 0;

            // Ayarlar/buton/fee değerlerine dokunma: sadece portföy + PnL reset
            lastSettingsSyncAt = 0;

            // localStorage'ı da temizle
            savePortfolioToStorage();

            // PnL state'ini reset sonrasında zorunlu olarak yeniden hesapla
            calculatePnL();

            if (demoPanelVisible) {
                requestPanelRebuildPreservingPosition();
            }
            updateDemoPanelValues(true);
            updatePnLDisplay(true);
            const resetNotificationText = DEBUG_RESET_WITH_USD_TARGET_ENABLED
                ? `Demo account reset! SOL: ${resetSolAmount.toFixed(6)} (~$${Number(DEBUG_RESET_USD_TARGET_AMOUNT).toFixed(2)})`
                : `Demo account reset! SOL: ${resetSolAmount.toFixed(6)}`;
            showDemoNotification(resetNotificationText, 'success');
        }
    }

    // Rastgele SOL fee hesaplama fonksiyonu
    function calculateRandomSolFee() {
        const min = 0.0004;
        const max = 0.0009;
        return (Math.random() * (max - min) + min).toFixed(6);
    }

    // Service fee hesaplama fonksiyonu
    function calculateServiceFee(amount, feePercentage) {
        const percentage = parseFloat(feePercentage.replace('%', '')) / 100;
        return amount * percentage;
    }

    function clampNumber(value, min, max) {
        return Math.min(max, Math.max(min, value));
    }

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

    function resolveDelayFeeSol(rawFixedFeeSol) {
        const numericFee = Number(rawFixedFeeSol);
        if (!Number.isFinite(numericFee)) {
            return TRADE_FEE_MIN_SOL;
        }
        return clampNumber(numericFee, TRADE_FEE_MIN_SOL, TRADE_SPEED_FEE_MAX_SOL);
    }

    function calculateTradeDelaySecondsFromFee(paidFeeSol) {
        const delayFeeSol = resolveDelayFeeSol(paidFeeSol);
        const feeRange = Math.max(TRADE_SPEED_FEE_MAX_SOL - TRADE_FEE_MIN_SOL, Number.EPSILON);
        const normalizedFee = (delayFeeSol - TRADE_FEE_MIN_SOL) / feeRange;
        const clampedNormalizedFee = clampNumber(normalizedFee, 0, 1);

        // 0.000001 fee => 0.600s, 0.0001 fee => 0.350s (tam lineer oran)
        const delaySeconds = TRADE_DELAY_MAX_SECONDS - (clampedNormalizedFee * (TRADE_DELAY_MAX_SECONDS - TRADE_DELAY_MIN_SECONDS));

        return clampNumber(delaySeconds, TRADE_DELAY_MIN_SECONDS, TRADE_DELAY_MAX_SECONDS);
    }

    async function executeDemoBuy(amount) {
        const tokenPortfolio = getCurrentTokenPortfolio();

        // SOL fiyatını işlem anında canlı DOM'dan tazele
        const liveSolPrice = getLiveSolPriceFromDOM();
        if (liveSolPrice && liveSolPrice > 0) {
            currentSolPrice = liveSolPrice;
        }

        if (!currentSolPrice || currentSolPrice <= 0 || isNaN(currentSolPrice)) {
            showDemoNotification('Cannot execute buy - SOL price not available yet!', 'error');
            return;
        }

        // Fiyat kontrolü (işlem öncesi bir kez daha tazele)
        if (!currentTokenPrice || currentTokenPrice <= 0 || isNaN(currentTokenPrice)) {
            getCurrentPrices();
        }

        if (!currentTokenPrice || currentTokenPrice <= 0 || isNaN(currentTokenPrice)) {
            const emergencyPrice = getLiveTokenPriceFromDOM();
            if (emergencyPrice && emergencyPrice > 0) {
                currentTokenPrice = emergencyPrice;
            }
        }

        if (!currentTokenPrice || currentTokenPrice <= 0 || isNaN(currentTokenPrice)) {
            showDemoNotification('Cannot execute buy - token price not available!', 'error');
            return;
        }

        if (!demoMode) {
            showDemoNotification('Please activate demo mode first!', 'error');
            return;
        }

        const slippagePercent = parseSlippagePercent(currentSettings.buySlippage, 0);
        // Demo modda slippage bir tolerans değeridir; gerçekleşen fiyatı otomatik olarak kötüleştirmiyoruz.
        const executionTokenPrice = currentTokenPrice;

        const solCost = amount;

        if (solCost > demoPortfolio.SOL.amount) {
            showDemoNotification(`Insufficient SOL! Need ${solCost.toFixed(4)} SOL but only have ${demoPortfolio.SOL.amount.toFixed(4)} SOL`, 'error');
            return;
        }

        const orderTokenCA = getTokenCAFromURL();
        const orderTokenSymbol = currentTokenSymbol;

        debugLog('🛒 Executing BUY for:', orderTokenSymbol, 'CA:', orderTokenCA);

        // Fee hesaplamaları
        const serviceFeeAmount = calculateServiceFee(solCost, currentSettings.serviceFee);
        const fixedFeeSol = parseFixedFeeSol(currentSettings.buyFixedFeeSol, 0.00005);
        const totalFees = serviceFeeAmount + fixedFeeSol;
        const totalSolCost = solCost + totalFees;

        if (totalSolCost > demoPortfolio.SOL.amount) {
            showDemoNotification(`Insufficient SOL for fees! Need ${totalSolCost.toFixed(6)} SOL`, 'error');
            return;
        }

        // Gecikme hesabında service fee dahil edilmez; yalnızca buy fixed fee kullanılır.
        const delayFeeSol = resolveDelayFeeSol(fixedFeeSol);
        const delaySeconds = calculateTradeDelaySecondsFromFee(delayFeeSol);
        const delayMs = delaySeconds * 1000;

        showDemoNotification(`Buy processing... ${delaySeconds.toFixed(4)}s (${delayMs.toFixed(1)}ms) | fee: ${delayFeeSol.toFixed(6)} SOL`, 'info');
        await wait(delayMs);

        if (totalSolCost > demoPortfolio.SOL.amount) {
            showDemoNotification('Buy aborted: SOL balance changed during delay.', 'error');
            return;
        }

        // Token miktarı hesaplama (gerçekleşen fiyat)
        const tokenAmount = (solCost * currentSolPrice) / executionTokenPrice;
        const usdValue = solCost * currentSolPrice;
        const totalFeesUsd = totalFees * currentSolPrice;

        debugLog('💰 Buy calculation:', {
            tokenAmount: tokenAmount,
            tokenPrice: currentTokenPrice,
            executionTokenPrice,
            slippagePercent,
            solCost: solCost,
            usdValue: usdValue,
            serviceFeeAmount,
            fixedFeeSol,
            totalFees,
            totalFeesUsd
        });

        // Weighted average price hesaplama (alış fee'si maliyete dahil)
        const previousAmount = tokenPortfolio.amount;
        const previousAvgPrice = tokenPortfolio.avgPrice;
        const previousTotalValue = previousAmount * previousAvgPrice;
        const newTotalValue = previousTotalValue + (tokenAmount * executionTokenPrice) + totalFeesUsd;
        const totalTokenAmount = previousAmount + tokenAmount;

        // Yeni ortalama fiyat
        tokenPortfolio.avgPrice = totalTokenAmount > 0 ? newTotalValue / totalTokenAmount : executionTokenPrice;
        tokenPortfolio.amount = totalTokenAmount;
        tokenPortfolio.totalInvested += (usdValue + totalFeesUsd);
        tokenPortfolio.totalInvestedSol += totalSolCost;

        // SOL bakiyesini güncelle
        demoPortfolio.SOL.amount -= totalSolCost;

        // Trade history
        tradeHistory.push({
            type: 'BUY',
            tokenSymbol: orderTokenSymbol,
            tokenCA: orderTokenCA,
            tokenAmount: tokenAmount,
            tokenPrice: executionTokenPrice,
            solAmount: solCost,
            usdValue: usdValue,
            slippagePercent,
            serviceFeeAmount,
            fixedFeeSol,
            totalFees,
            executionDelaySec: delaySeconds,
            timestamp: new Date()
        });

        totalTradeVolume += usdValue;

        // Local storage'a kaydet
        savePortfolioToStorage();

        calculatePnL();
        updateDemoPanelValues(true);
        updatePnLDisplay(true);

        showDemoNotification(`Bought ${tokenAmount.toFixed(2)} ${orderTokenSymbol} for ${solCost.toFixed(4)} SOL | Delay: ${delaySeconds.toFixed(4)}s | Slippage Tol: ${slippagePercent.toFixed(2)}% | Fees: ${totalFees.toFixed(6)} SOL | Avg Price: ${formatTokenPriceDisplay(tokenPortfolio.avgPrice)}`, 'success');
    }

    async function executeDemoSell(percent) {
        const tokenPortfolio = getCurrentTokenPortfolio();

        // SOL fiyatını işlem anında canlı DOM'dan tazele
        const liveSolPrice = getLiveSolPriceFromDOM();
        if (liveSolPrice && liveSolPrice > 0) {
            currentSolPrice = liveSolPrice;
        }

        if (!currentSolPrice || currentSolPrice <= 0 || isNaN(currentSolPrice)) {
            showDemoNotification('Cannot execute sell - SOL price not available yet!', 'error');
            return;
        }

        if (!demoMode) {
            showDemoNotification('Please activate demo mode first!', 'error');
            return;
        }

        tokenPortfolio.amount = Math.max(0, normalizeNearZero(tokenPortfolio.amount, TOKEN_AMOUNT_ZERO_EPSILON));
        if (tokenPortfolio.amount <= 0) {
            tokenPortfolio.amount = 0;
            tokenPortfolio.avgPrice = 0;
            showDemoNotification(`No ${currentTokenSymbol} to sell!`, 'error');
            return;
        }

        const orderTokenCA = getTokenCAFromURL();
        const orderTokenSymbol = currentTokenSymbol;

        const slippagePercent = parseSlippagePercent(currentSettings.sellSlippage, 0);
        // Demo modda slippage bir tolerans değeridir; gerçekleşen fiyatı otomatik olarak düşürmüyoruz.
        const executionTokenPrice = currentTokenPrice;

        const tokenAmount = tokenPortfolio.amount * (percent / 100);

        // Gelir hesaplama (slippage sonrası efektif fiyat)
        const solRevenue = (tokenAmount * executionTokenPrice) / currentSolPrice;
        const usdValue = tokenAmount * executionTokenPrice;

        // Fee hesaplamaları
        const serviceFeeAmount = calculateServiceFee(solRevenue, currentSettings.serviceFee);
        const fixedFeeSol = parseFixedFeeSol(currentSettings.sellFixedFeeSol, 0.00005);
        const totalFees = serviceFeeAmount + fixedFeeSol;
        const totalFeesUsd = totalFees * currentSolPrice;
        const netSolRevenue = solRevenue - totalFees;

        if (netSolRevenue < 0) {
            showDemoNotification(`Fees exceed revenue! Cannot sell.`, 'error');
            return;
        }

        // Gecikme hesabında service fee dahil edilmez; yalnızca sell fixed fee kullanılır.
        const delayFeeSol = resolveDelayFeeSol(fixedFeeSol);
        const delaySeconds = calculateTradeDelaySecondsFromFee(delayFeeSol);
        const delayMs = delaySeconds * 1000;

        showDemoNotification(`Sell processing... ${delaySeconds.toFixed(4)}s (${delayMs.toFixed(1)}ms) | fee: ${delayFeeSol.toFixed(6)} SOL`, 'info');
        await wait(delayMs);

        if (tokenAmount > tokenPortfolio.amount) {
            showDemoNotification('Sell aborted: token balance changed during delay.', 'error');
            return;
        }

        // PnL hesaplama (satış fee'si realize PnL'e dahil)
        const costBasis = tokenAmount * tokenPortfolio.avgPrice;
        const realizedPnL = (usdValue - totalFeesUsd) - costBasis;

        debugLog('💰 Sell calculation:', {
            tokenAmount: tokenAmount,
            avgPrice: tokenPortfolio.avgPrice,
            currentPrice: currentTokenPrice,
            executionTokenPrice,
            slippagePercent,
            costBasis: costBasis,
            revenue: usdValue,
            realizedPnL: realizedPnL,
            serviceFeeAmount,
            fixedFeeSol,
            totalFees,
            totalFeesUsd
        });

        // Portföyü güncelle
        tokenPortfolio.amount = Math.max(0, normalizeNearZero(tokenPortfolio.amount - tokenAmount, TOKEN_AMOUNT_ZERO_EPSILON));
        tokenPortfolio.totalSold += (usdValue - totalFeesUsd);
        tokenPortfolio.totalSoldSol += netSolRevenue;

        // Eğer tüm tokenlar satıldıysa average price'ı sıfırla
        if (isEffectivelyZero(tokenPortfolio.amount, TOKEN_AMOUNT_ZERO_EPSILON)) {
            tokenPortfolio.amount = 0;
            tokenPortfolio.avgPrice = 0;
        }

        // SOL bakiyesine net geliri ekle
        demoPortfolio.SOL.amount += netSolRevenue;

        // Realize edilen PnL'yi coin bazında güncelle
        tokenPortfolio.realizedPnL = Number(tokenPortfolio.realizedPnL || 0) + realizedPnL;
        totalRealizedPnL = calculatePortfolioRealizedPnLSum();

        // Trade history
        tradeHistory.push({
            type: 'SELL',
            tokenSymbol: orderTokenSymbol,
            tokenCA: orderTokenCA,
            tokenAmount: tokenAmount,
            tokenPrice: executionTokenPrice,
            solAmount: netSolRevenue,
            usdValue: usdValue,
            slippagePercent,
            serviceFeeAmount,
            fixedFeeSol,
            totalFees,
            realizedPnL: realizedPnL,
            executionDelaySec: delaySeconds,
            timestamp: new Date()
        });

        totalTradeVolume += usdValue;

        // Local storage'a kaydet
        savePortfolioToStorage();

        calculatePnL();
        updateDemoPanelValues(true);
        updatePnLDisplay(true);

        const pnlPercent = costBasis > 0 ? (realizedPnL / costBasis) * 100 : 0;
        const pnlText = realizedPnL >= 0 ?
              `Profit: +$${realizedPnL.toFixed(2)} (${pnlPercent.toFixed(2)}%)` :
        `Loss: -$${Math.abs(realizedPnL).toFixed(2)} (${Math.abs(pnlPercent).toFixed(2)}%)`;

        showDemoNotification(`Sold ${tokenAmount.toFixed(2)} ${orderTokenSymbol} for ${netSolRevenue.toFixed(4)} SOL | Delay: ${delaySeconds.toFixed(4)}s | Slippage Tol: ${slippagePercent.toFixed(2)}% | Fees: ${totalFees.toFixed(6)} SOL | ${pnlText}`, 'success');
    }

    function updateDemoPanelValues(forceUpdate = false) {
        const demoPanel = document.querySelector('.demo-trade-panel');
        if (!demoPanel) return;
        if (isPanelDragging) {
            queuePanelValueRefreshAfterDrag();
            return;
        }

        const now = Date.now();
        if (!forceUpdate && now - lastPanelUpdateAt < PANEL_UPDATE_THROTTLE_MS) return;
        lastPanelUpdateAt = now;

        // Panel açıkken real panel ayarları belirli aralıklarla çekilsin ki interval/slippage değişimleri canlı yansısın.
        if (!customizeMode && (forceUpdate || now - lastSettingsSyncAt >= SETTINGS_SYNC_INTERVAL_MS)) {
            lastSettingsSyncAt = now;
            loadSettingsFromRealPanel();
        }

        const tokenPortfolio = getCurrentTokenPortfolio();

        const detectedTokenImage = getLiveTokenImageFromDOM();
        if (detectedTokenImage) {
            if (detectedTokenImage !== currentTokenImage) {
                currentTokenImage = detectedTokenImage;
            }
            if (tokenPortfolio && tokenPortfolio.image !== detectedTokenImage) {
                tokenPortfolio.image = detectedTokenImage;
            }
        } else if (!isLikelyTokenImageUrl(currentTokenImage) && isLikelyTokenImageUrl(tokenPortfolio.image)) {
            currentTokenImage = normalizeImageUrl(tokenPortfolio.image);
        }

        // Balance hesapla - tüm tokenları dahil et
        const strictActiveTokenCA = getTokenCAFromURL({ allowLastKnown: false });
        const activeTokenCA =
            strictActiveTokenCA && strictActiveTokenCA !== 'default_token' && strictActiveTokenCA !== 'error_token'
                ? strictActiveTokenCA
                : getTokenCAFromURL();

        let totalBalance = demoPortfolio.SOL.amount * currentSolPrice;
        Object.keys(demoPortfolio).forEach(key => {
            if (key !== 'SOL') {
                const token = demoPortfolio[key];
                // Geçerli token fiyatını kullan (sadece aktif token için currentTokenPrice var)
                const tokenPrice = (key === activeTokenCA) ? currentTokenPrice : (token.avgPrice || 0);
                totalBalance += token.amount * tokenPrice;
            }
        });

        demoBalance = totalBalance;

        // Token görüntülerini güncelle
        const buyTokenDisplay = demoPanel.querySelector('.instant-trade-token-selector-buy + .flex.items-center .VHD_xh__dex');
        const sellTokenDisplay = demoPanel.querySelector('.instant-trade-token-selector-sell + .flex.items-center .VHD_xh__dex');
        const sellForLabel = demoPanel.querySelector('.instant-trade-token-selector-sell .demo-sell-for-label');
        const sellPicture = demoPanel.querySelector('.instant-trade-token-selector-sell + .flex.items-center picture.dex-picture');
        const sellTokenImage = sellPicture ? sellPicture.querySelector('img') : null;
        const sellTokenSource = sellPicture ? sellPicture.querySelector('source') : null;
        const resolvedTokenImage = resolveTokenImageUrl(detectedTokenImage, currentTokenImage, tokenPortfolio.image, DEFAULT_TOKEN_IMAGE);

        const sellDropdownTokenOption = demoPanel.querySelector('.demo-sell-select .demo-sell-option:not([data-value="SOL"])');
        if (sellDropdownTokenOption && currentTokenSymbol) {
            if (sellDropdownTokenOption.getAttribute('data-value') !== currentTokenSymbol) {
                sellDropdownTokenOption.setAttribute('data-value', currentTokenSymbol);
            }

            const optionPrimaryText = sellDropdownTokenOption.querySelectorAll('.tiQWEG__dex');
            const optionSecondaryText = sellDropdownTokenOption.querySelectorAll('.inAvcR__dex');
            const optionPicture = sellDropdownTokenOption.querySelector('picture');
            const optionImage = optionPicture ? optionPicture.querySelector('img') : null;
            const optionSource = optionPicture ? optionPicture.querySelector('source') : null;

            setTextIfChanged(optionPrimaryText[0], currentTokenSymbol);
            setTextIfChanged(optionSecondaryText[0], currentTokenName || 'Current Token');
            setTextIfChanged(optionPrimaryText[1], tokenPortfolio.amount.toFixed(4));
            setTextIfChanged(optionSecondaryText[1], `$${(tokenPortfolio.amount * currentTokenPrice).toFixed(2)}`);
            setImageIfChanged(optionImage, optionSource, resolvedTokenImage);
        }

        setTextIfChanged(buyTokenDisplay, formatBalanceDisplay(demoPortfolio.SOL.amount));
        setTextIfChanged(sellTokenDisplay, formatBalanceDisplay(tokenPortfolio.amount));
        if (sellForLabel && sellForLabel.innerHTML !== 'Sell for <span class="font-500 UE7t1T__dex">SOL</span>') {
            sellForLabel.innerHTML = 'Sell for <span class="font-500 UE7t1T__dex">SOL</span>';
        }
        setImageIfChanged(sellTokenImage, sellTokenSource, resolvedTokenImage);

        // Quick buy/sell buton metinlerini ve data attribute'larını canlı güncelle
        const buyQuickButtons = demoPanel.querySelectorAll('.demo-buy-quick');
        buyQuickButtons.forEach((button, index) => {
            const nextText = String(currentSettings.buyAmounts[index] || defaultBuyAmounts[index] || '').trim();
            const textEl = button.querySelector('.l5GPKh__dex');
            setTextIfChanged(textEl, nextText);

            const parsedAmount = parseFloat(nextText);
            const fallbackAmount = parseFloat(defaultBuyAmounts[index]) || 0;
            const nextAmount = Number.isFinite(parsedAmount) ? parsedAmount : fallbackAmount;
            const nextAmountAttr = String(nextAmount);
            if (button.getAttribute('data-amount') !== nextAmountAttr) {
                button.setAttribute('data-amount', nextAmountAttr);
            }
        });

        const sellQuickButtons = demoPanel.querySelectorAll('.demo-sell-quick');
        sellQuickButtons.forEach((button, index) => {
            const nextText = String(currentSettings.sellPercents[index] || defaultSellPercents[index] || '').trim();
            const textEl = button.querySelector('.l5GPKh__dex');
            setTextIfChanged(textEl, nextText);

            const parsedPercent = parseFloat(nextText.replace('%', ''));
            const fallbackPercent = parseFloat(defaultSellPercents[index].replace('%', '')) || 0;
            const nextPercent = Number.isFinite(parsedPercent) ? parsedPercent : fallbackPercent;
            const nextPercentAttr = String(nextPercent);
            if (button.getAttribute('data-percent') !== nextPercentAttr) {
                button.setAttribute('data-percent', nextPercentAttr);
            }
        });

        setTextIfChanged(demoPanel.querySelector('.demo-buy-slippage-value'), currentSettings.buySlippage);
        setTextIfChanged(demoPanel.querySelector('.demo-sell-slippage-value'), currentSettings.sellSlippage);
        setTextIfChanged(demoPanel.querySelector('.demo-buy-fixed-fee-value'), currentSettings.buyFixedFeeSol);
        setTextIfChanged(demoPanel.querySelector('.demo-sell-fixed-fee-value'), currentSettings.sellFixedFeeSol);
        setTextIfChanged(demoPanel.querySelector('.demo-service-fee-value'), currentSettings.serviceFee);

        // Dropdown menülerindeki SOL bakiyesini de canlı güncelle
        const buyDropdownSolOption = demoPanel.querySelector('.demo-buy-select .demo-buy-option[data-value="SOL"]');
        if (buyDropdownSolOption) {
            const buyOptionPrimaryText = buyDropdownSolOption.querySelectorAll('.tiQWEG__dex');
            const buyOptionSecondaryText = buyDropdownSolOption.querySelectorAll('.inAvcR__dex');
            setTextIfChanged(buyOptionPrimaryText[1], demoPortfolio.SOL.amount.toFixed(4));
            setTextIfChanged(buyOptionSecondaryText[1], `$${(demoPortfolio.SOL.amount * currentSolPrice).toFixed(2)}`);
        }

        const sellDropdownSolOption = demoPanel.querySelector('.demo-sell-select .demo-sell-option[data-value="SOL"]');
        if (sellDropdownSolOption) {
            const sellOptionPrimaryText = sellDropdownSolOption.querySelectorAll('.tiQWEG__dex');
            const sellOptionSecondaryText = sellDropdownSolOption.querySelectorAll('.inAvcR__dex');
            const tokenValueUsdNumeric = tokenPortfolio.amount * currentTokenPrice;
            const tokenValueInSol = currentSolPrice > 0
                ? (tokenValueUsdNumeric / currentSolPrice).toFixed(4)
                : '0.0000';
            setTextIfChanged(sellOptionPrimaryText[1], tokenValueInSol);
            setTextIfChanged(sellOptionSecondaryText[1], `$${tokenValueUsdNumeric.toFixed(2)}`);
        }

        // PnL değerlerini güncelle
        updatePnLDisplay();

        // Dropdown içeriklerini her tick yeniden kurmuyoruz (perf + log spam fix)
    }

    function updatePnLDisplay(forceUpdate = false) {
        const demoPanel = document.querySelector('.demo-trade-panel');
        if (!demoPanel) return;
        if (isPanelDragging) {
            queuePanelValueRefreshAfterDrag();
            return;
        }

        const now = Date.now();
        if (!forceUpdate && now - lastPnLDisplayUpdateAt < PNL_UPDATE_THROTTLE_MS) return;
        lastPnLDisplayUpdateAt = now;

        const boughtFiat = boughtAmount;
        const soldFiat = soldAmount;
        const balanceFiat = balanceAmount;

        const boughtSol = boughtAmountSol;
        const soldSol = soldAmountSol;
        const balanceSol = currentSolPrice > 0 ? balanceAmount / currentSolPrice : 0;

        const totalPnlFiat = totalPnL;
        const realizedPnlFiat = activeTokenRealizedPnL;
        const unrealizedPnlFiat = tokenPnL;
        const totalPnlSol = currentSolPrice > 0 ? totalPnlFiat / currentSolPrice : 0;
        const realizedPnlSol = currentSolPrice > 0 ? realizedPnlFiat / currentSolPrice : 0;
        const unrealizedPnlSol = currentSolPrice > 0 ? unrealizedPnlFiat / currentSolPrice : 0;

        const boughtElement = demoPanel.querySelector('.demo-pnl-bought');
        const soldElement = demoPanel.querySelector('.demo-pnl-sold');
        const balanceElement = demoPanel.querySelector('.demo-pnl-balance');
        const tpnlElement = demoPanel.querySelector('.demo-pnl-tpnl');
        const rpnlElement = demoPanel.querySelector('.demo-pnl-rpnl');
        const upnlElement = demoPanel.querySelector('.demo-pnl-upnl');
        const currencyToggleButton = demoPanel.querySelector('.demo-currency-toggle');

        const boughtText = showFiat
            ? formatPnLSummaryAmountDisplay(boughtFiat, true)
            : formatPnLSummaryAmountDisplay(boughtSol, false);
        const soldText = showFiat
            ? formatPnLSummaryAmountDisplay(soldFiat, true)
            : formatPnLSummaryAmountDisplay(soldSol, false);
        const balanceText = showFiat
            ? formatPnLSummaryAmountDisplay(balanceFiat, true)
            : formatPnLSummaryAmountDisplay(balanceSol, false);

        const isNearZero = (value) => isEffectivelyZero(value);

        const largeSolPnLCount = [totalPnlSol, realizedPnlSol, unrealizedPnlSol]
            .filter(value => Number.isFinite(Number(value)) && Math.abs(Number(value)) > 999)
            .length;
        const hasZeroSolPnL = [totalPnlSol, realizedPnlSol, unrealizedPnlSol].some(isNearZero);
        const hideAllSolPnLFractions = largeSolPnLCount >= 2 && hasZeroSolPnL;

        const baseTpnlSolFractionDigits = Math.abs(totalPnlSol) > 99 ? 1 : (Math.abs(totalPnlSol) > 9 ? 2 : 3);
        const baseRpnlSolFractionDigits = Math.abs(realizedPnlSol) > 99 ? 1 : 2;
        const baseUpnlSolFractionDigits = Math.abs(unrealizedPnlSol) > 99 ? 1 : 2;

        const tpnlSolFractionDigits = hideAllSolPnLFractions ? 0 : baseTpnlSolFractionDigits;
        const rpnlSolFractionDigits = hideAllSolPnLFractions ? 0 : baseRpnlSolFractionDigits;
        const upnlSolFractionDigits = hideAllSolPnLFractions ? 0 : baseUpnlSolFractionDigits;

        const largeFiatPnLCount = [totalPnlFiat, realizedPnlFiat, unrealizedPnlFiat]
            .filter(value => Number.isFinite(Number(value)) && Math.abs(Number(value)) > 999)
            .length;
        const hasZeroFiatPnL = [totalPnlFiat, realizedPnlFiat, unrealizedPnlFiat].some(isNearZero);
        const hideAllFiatPnLFractions = largeFiatPnLCount >= 2 && hasZeroFiatPnL;

        const tpnlFiatFractionDigits = hideAllFiatPnLFractions ? 0 : (Math.abs(totalPnlFiat) > 99 ? 0 : 1);
        const rpnlFiatFractionDigits = hideAllFiatPnLFractions ? 0 : (Math.abs(realizedPnlFiat) > 99 ? 0 : 1);
        const upnlFiatFractionDigits = hideAllFiatPnLFractions ? 0 : (Math.abs(unrealizedPnlFiat) < 100 ? 1 : 0);

        const tpnlText = showFiat
            ? formatSignedUsdPnL(totalPnlFiat, tpnlFiatFractionDigits)
            : formatPnLIntegerDisplay(totalPnlSol, false, tpnlSolFractionDigits);
        const rpnlText = showFiat
            ? formatSignedUsdPnL(realizedPnlFiat, rpnlFiatFractionDigits)
            : formatPnLIntegerDisplay(realizedPnlSol, false, rpnlSolFractionDigits);
        const upnlText = showFiat
            ? formatSignedUsdPnL(unrealizedPnlFiat, upnlFiatFractionDigits)
            : formatPnLIntegerDisplay(unrealizedPnlSol, false, upnlSolFractionDigits);

        setTextIfChanged(boughtElement, boughtText);
        setTextIfChanged(soldElement, soldText);
        setTextIfChanged(balanceElement, balanceText);
        setTextIfChanged(tpnlElement, tpnlText);
        setTextIfChanged(rpnlElement, rpnlText);
        setTextIfChanged(upnlElement, upnlText);

        const tpnlSign = totalPnlFiat >= 0 ? 1 : -1;
        const rpnlSign = realizedPnlFiat >= 0 ? 1 : -1;
        const upnlSign = unrealizedPnlFiat >= 0 ? 1 : -1;

        if (lastTpnlColorSign !== tpnlSign) {
            setStyleIfChanged(tpnlElement, 'color', tpnlSign > 0 ? '#bcff2f' : '#fc46ab');
            lastTpnlColorSign = tpnlSign;
        }
        if (lastRpnlColorSign !== rpnlSign) {
            setStyleIfChanged(rpnlElement, 'color', rpnlSign > 0 ? '#bcff2f' : '#fc46ab');
            lastRpnlColorSign = rpnlSign;
        }
        if (lastUpnlColorSign !== upnlSign) {
            setStyleIfChanged(upnlElement, 'color', upnlSign > 0 ? '#bcff2f' : '#fc46ab');
            lastUpnlColorSign = upnlSign;
        }

        if (currencyToggleButton) {
            const nextIconMode = showFiat ? 'fiat' : 'token';
            if (currencyToggleButton.getAttribute('data-icon-mode') !== nextIconMode) {
                currencyToggleButton.innerHTML = getCurrencyToggleIconHTML(showFiat);
                currencyToggleButton.setAttribute('data-icon-mode', nextIconMode);
            }
        }

    }

    function showDemoNotification(message, type = 'info') {
        let notificationContainer = document.querySelector('.demo-notification-container');
        if (!notificationContainer) {
            notificationContainer = document.createElement('div');
            notificationContainer.className = 'demo-notification-container dex-message-container dex-notice-stack-closed';
            notificationContainer.style.cssText = `
            position: fixed;
            top: 72px;
            left: 50%;
            transform: translateX(-50%);
            z-index: 10000;
            display: flex;
            flex-direction: column;
            align-items: center;
            gap: 10px;
            max-width: 420px;
            width: calc(100vw - 24px);
            pointer-events: none;
            `;
            document.body.appendChild(notificationContainer);
            addNotificationStyles();
        }

        const currentMessages = notificationContainer.querySelectorAll('.dex-message-box');
        if (currentMessages.length >= 2) {
            const messagesToRemove = Array.from(currentMessages).slice(0, currentMessages.length - 1);
            messagesToRemove.forEach((messageEl, index) => {
                setTimeout(() => {
                    messageEl.style.animation = 'demoMessageQuickOut 0.25s ease-out forwards';
                    setTimeout(() => {
                        if (messageEl.parentNode) {
                            messageEl.parentNode.removeChild(messageEl);
                        }
                    }, 250);
                }, index * 70);
            });
        }

        const notificationId = 'demo-notification-' + Date.now();

        let iconClass = 'dex-okds-info-circle-fill';
        let boxClass = 'info';
        let iconLabel = 'Info';

        if (type === 'error') {
            iconClass = 'dex-okds-fail-circle-fill';
            boxClass = 'error';
            iconLabel = 'Error';
        } else if (type === 'success') {
            iconClass = 'dex-okds-success-circle-fill';
            boxClass = 'success';
            iconLabel = 'Success';
        } else if (type === 'warning') {
            iconClass = 'dex-okds-warning-circle-fill';
            boxClass = 'warning';
            iconLabel = 'Warning';
        }

        const notificationHTML = `
        <div class="dex-message-var dex-message-box ${boxClass} auto-width"
             id="${notificationId}"
             role="alert"
             aria-live="polite"
             style="animation: demoMessageIn 0.35s ease-out;">
             <span class="dex-message-icon-circle-container">
                 <i class="icon iconfont dex-message-icon-new ${iconClass}"
                    role="img"
                    aria-label="${iconLabel}"></i>
             </span>
             <div class="dex-message-content">
                 <div class="dex-message-title-box">
                     <span class="dex-message-title">${message}</span>
                 </div>
             </div>
        </div>
        `;

        notificationContainer.insertAdjacentHTML('beforeend', notificationHTML);

        setTimeout(() => {
            const notification = document.getElementById(notificationId);
            if (notification) {
                notification.style.animation = 'demoMessageOut 0.3s ease-in forwards';
                setTimeout(() => {
                    if (notification.parentNode) {
                        notification.parentNode.removeChild(notification);
                    }
                }, 300);
            }
        }, 3800);
    }

    // CSS animasyonlarını ekleyen fonksiyon
    function addNotificationStyles() {
        if (document.querySelector('#demo-notification-styles')) return;

        const style = document.createElement('style');
        style.id = 'demo-notification-styles';
        style.textContent = `
        @keyframes demoMessageIn {
            0% {
                transform: translateY(-12px);
                opacity: 0;
            }
            100% {
                transform: translateY(0);
                opacity: 1;
            }
        }

        @keyframes demoMessageOut {
            0% {
                transform: translateY(0);
                opacity: 1;
            }
            100% {
                transform: translateY(-10px);
                opacity: 0;
            }
        }

        @keyframes demoMessageQuickOut {
            0% {
                opacity: 1;
                transform: translateY(0);
            }
            100% {
                opacity: 0;
                transform: translateY(-8px);
            }
        }

        .demo-notification-container {
            transition: all 0.2s ease;
        }

        .demo-notification-container .dex-message-box {
            pointer-events: auto;
            width: auto;
            max-width: 100%;
            box-sizing: border-box;
            border-radius: 8px;
            border: 1px solid rgba(196, 196, 196, 0.28);
            background: #383838;
            color: #eef1f5;
            padding: 10px 12px;
            display: flex;
            align-items: center;
            gap: 9px;
            box-shadow: 0 10px 26px rgba(0, 0, 0, 0.35);
        }

        .demo-notification-container .dex-message-icon-circle-container {
            display: inline-flex;
            align-items: center;
            justify-content: center;
            align-self: center;
            flex-shrink: 0;
            width: 19px;
            min-width: 19px;
            height: 19px;
            margin-top: 0;
        }

        .demo-notification-container .dex-message-icon-new {
            font-size: 19px;
            line-height: 1;
        }

        .demo-notification-container .dex-message-box.success .dex-message-icon-new {
            color: #bcff2f;
        }

        .demo-notification-container .dex-message-box.error .dex-message-icon-new {
            color: #fc46ab;
        }

        .demo-notification-container .dex-message-box.warning .dex-message-icon-new {
            color: #f6b73c;
        }

        .demo-notification-container .dex-message-box.info .dex-message-icon-new {
            color: #4f9bff;
        }

        .demo-notification-container .dex-message-content {
            min-width: 0;
            flex: 1;
        }

        .demo-notification-container .dex-message-title-box {
            display: block;
            width: 100%;
        }

        .demo-notification-container .dex-message-title {
            display: block;
            font-size: 13px;
            line-height: 1.45;
            font-weight: 500;
            color: #eef1f5;
            word-break: break-word;
        }

        .demo-notification-container .dex-message-box.success,
        .demo-notification-container .dex-message-box.error,
        .demo-notification-container .dex-message-box.warning,
        .demo-notification-container .dex-message-box.info {
            border-color: rgba(196, 196, 196, 0.28);
            background: #383838;
        }
        `;
        document.head.appendChild(style);
    }

    function setupDemoMode() {
        debugLog('Demo trading mode initialized');
    }

    // Sayfa yüklendiğinde başlat
    if (document.readyState === 'loading') {
        document.addEventListener('DOMContentLoaded', initDemoTrading);
    } else {
        initDemoTrading();
    }

    // URL değişikliklerini dinle (SPA'lar için)
    let lastUrl = location.href;
    new MutationObserver(() => {
        const url = location.href;
        if (url !== lastUrl) {
            lastUrl = url;

            if (!getTokenCAFromCurrentURLStrict() && demoPanelVisible) {
                hideDemoPanel();
            }

            debugLog('URL changed, reinitializing demo trading...');
            setTimeout(initDemoTrading, 1000);
        }
    }).observe(document, { subtree: true, childList: true });

})();