RR Tracker v18.3

RR tracker with cool features, now with an integrated stats panel and profit graph, Martingale bet auto-start, a powerful dynamic bet calculator, and a fully scalable UI.

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Greasemonkey 油猴子Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Violentmonkey 暴力猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴Userscripts ,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey 篡改猴,才能安装此脚本。

您需要先安装一款用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         RR Tracker v18.3
// @namespace    https://greasyfork.org/users/1493252
// @version      18.3
// @description RR tracker with cool features, now with an integrated stats panel and profit graph, Martingale bet auto-start, a powerful dynamic bet calculator, and a fully scalable UI.
//###Your Torn RR Tracker: Quick Guide
//###Auto-Tracking
//###Just open Russian Roulette, and your tracker starts automatically. It records every win and loss, showing your profit, win rate, and streaks.
//###Panel Controls
//###* Drag: Click and drag the ☰ icon to move the panel anywhere you like.
//###* Shift + Drag: Hold Shift and drag with your mouse from anywhere on the panel to move it.
//###* Collapse/Expand: Click the ► (or ▪) icon to shrink or expand the panel.
//###* Hide/Show: If Auto-Hide is on in settings, the tracker hides when you leave RR and reappears when you return.
//###Settings (⚙️ icon)
//###* Panel Size: Use the slider to zoom the entire panel in or out for a perfect fit.
//###* Panel Opacity: Adjust how see-through the panel is.
//###* Profit/Loss Alerts: Set targets to be notified when you hit a certain profit or loss.
//###* Mini-Bar Count: Choose how many recent games show in the collapsed view.
//###* Mini-Button Size: Adjust the size of the bet buttons in the collapsed view.
//###* Bet Button Count: Use a slider to choose how many bet buttons to display (4-16).
//###* Reset Data: Clear all your tracked stats and profit.
//###* Edit Bets: Customize your bet amounts in a dedicated panel.
//###* Charging Shoots: Toggle the auto-shoot helper panel on or off.
//###Bets (💰 icon)
//###* Smart Bets: The panel now shows your recent match history and allows you to auto-start bets.
//###Stats (📊 icon) (NEW!)
//###* Open a new panel with a cumulative profit graph.
//###* Select timeframes: 7 Days, 1 Month, 3 Months, 6 Months, or 1 Year.
//###* See key stats for the selected period like Total Profit, Win/Loss, and Games Played.
//###* A new icon (➕/🔗) next to the result circle shows if you 'created' or 'joined' the game.
//###Edit Bets (✏️ NEW LOGIC!)
//###* Enable "Dynamic Bets" to use the new calculator.
//###* Set your strategy (Capital, Streak, Multiplier).
//###* Use the lock icons (🔒/🔓) to choose your calculation method.
//###* Lock 'Gambling Capital' to calculate the 'Starting Bet'.
//###* Lock 'Starting Bet' to calculate the required 'Gambling Capital'.
//###* The script populates your bet buttons automatically.
//###* Disable "Dynamic Bets" to return to setting bets manually.
// @match        https://www.torn.com/page.php?sid=russianRoulette*
// @grant        GM.xmlHttpRequest
// @connect      api.torn.com
// @run-at       document-idle
// @license      MIT
// ==/UserScript==






(function waitUntilReady() {



    'use strict';

    try {

        // --- ADD THIS NEW STYLE BLOCK ---
        const styleSheet = document.createElement("style");

        styleSheet.type = "text/css";
        styleSheet.innerText = `
        .next-bet-highlight {
            background: rgba(255, 165, 0, 0.35) !important; /* A distinct orange glow */
            border: 1px solid rgba(255, 165, 0, 0.9) !important;
            box-shadow: 0 0 8px rgba(255, 165, 0, 0.7);
        }
    `;
        document.head.appendChild(styleSheet);
        // --- END OF NEW STYLE BLOCK ---


        // --- Constants ---
        const PANEL_EDGE_MARGIN = 150; // The minimum number of pixels to keep visible
        const MINIMIZE_KEY = 'rr_panelMinimized';
        const BET_MODE_KEY = 'rr_bettingMode'; // 'manual', 'dynamic', 'simple'
        const SIMPLE_STEP_KEY = 'rr_simpleModeStep';
        const AUTO_NEXT_KEY = 'rr_autoNextLoss';
        const AUTO_RESET_KEY = 'rr_autoResetWin';
        const PANEL_ID = 'rr-tracker-panel';
        const API_SYNC_INTERVAL_MS = 10 * 1000; // 15 seconds. This now controls everything.
        const BOOSTED_BETS_ENABLED_KEY = 'rr_boostedBetsEnabled';
        const STORAGE = 'torn_rr_tracker_results';
        const PROFIT_STORAGE = 'torn_rr_total_profit';
        const API_KEY_STORAGE = 'rr_tracker_api_key';
        const LAST_SYNC_KEY = 'rr_tracker_last_sync';
        const POS_KEY = 'rr_panelPos';
        const COLLAPSE_KEY = 'rr_panelCollapsed';
        const AUTOHIDE_KEY = 'rr_autoHide';
        const MAX_DISPLAY_KEY = 'rr_maxDisplayMatches';
        const OPACITY_KEY = 'rr_panelOpacity';
        const PROFIT_TARGET_KEY = 'rr_profitTarget';
        const LOSS_LIMIT_KEY = 'rr_lossLimit';
        const ALERT_SHOWN_PROFIT_KEY = 'rr_alertShownProfit';
        const ALERT_SHOWN_LOSS_KEY = 'rr_alertShownLoss';
        const MINI_BAR_COUNT_KEY = 'rr_miniBarCount';
        const MINI_BUTTON_SIZE_KEY = 'rr_miniButtonSize';
        const MANUAL_BETS_STORAGE_KEY = 'RRManualBets_v3';
        const DEFAULT_MANUAL_BETS = [100000, 200000, 400000, 800000, 1600000, 3200000, 6400000, 12800000, 25600000, 51200000, 102400000];
        const DYNAMIC_BETS_ENABLED_KEY = 'rr_dynamicBetsEnabled';
        const DYNAMIC_BETS_SETTINGS_KEY = 'rr_dynamicBetsSettings_v2';
        const UI_BUTTON_COUNT_KEY = 'rr_16';
        const MAX_L_STREAK_CAP = 15;
        const PANEL_SCALE_KEY = 'rr_panelScale';
        const MANUAL_SYNC_COOLDOWN_KEY = 'rr_tracker_last_manual_sync';
        const STOP_LOSS_ENABLED_KEY = 'rr_stopLossEnabled';
        const HIDE_ALERTS_KEY = 'rr_hideAlerts';
        const STREAK_VIEW_KEY = 'rr_streakView'; // <<< ADD THIS LINE
        const SIM_CAPITAL_KEY = 'rr_simCapital';
        const SIM_STREAK_KEY = 'rr_simStreak';
        const SIM_MATCHES_KEY = 'rr_simMatches';
        const SIM_SESSIONS_KEY = 'rr_simSessions';
        const SIM_MANUAL_BETS_KEY = 'rr_simManualBets';

        const SIM_USE_DYNAMIC_KEY = 'rr_simUseDynamic'; // <<< ADD THIS LINE

        const ENABLE_SHOOT_2_KEY = 'rr_enableShoot2';
        const ENABLE_SHOOT_3_KEY = 'rr_enableShoot3';
        let enableShoot2 = true;
        let enableShoot3 = true;




        const DEFAULT_DYNAMIC_SETTINGS = {
            testBet: 10000,
            capital: 100000000,
            maxLStreak: 10,
            martingaleValue: 2,
            reinforce: false,
            reinforceInterval: 2, // New default
            boostedBets: false,
            boostInterval: 5,     // New default
            lockedField: 'capital',
            startingBet: 0,
            // Drain Settings (Preserved)
            drainEnabled: false,
            drainStart: 3,
            drainRepeats: 4
        };

      



        // --- State Variables ---
        let apiKey = '';
        let lastSyncTime = 0;
        let manualBets, currentBets, showBetsPanel, showEditBetsPanel, showStatsPanel, isDragging, dragMouseX, dragMouseY, isTwoFingerDragging, initialTouchMidX, initialTouchMidY, initialPanelX, initialPanelY;
        let results, totalProfit, collapsed, autoHide, showSettings, maxDisplayMatches, currentOpacity, profitTarget, lossLimit, miniBarCount, miniButtonSize;
        let simulatorManualBetsString = ''; // Will remember the manual bets in the simulator
        let hideAlerts;
        let streakBreakdownView; // <<< ADD THIS LINE
        let bettingMode = 'manual'; // Default
        let simpleModeStep = 0;
        let autoNextEnabled = false;
        let autoResetEnabled = false;

        let simUseDynamic; // <<< ADD THIS LINE
        let showSimulatorConfig = false; // <<< ADD THIS LINE
        let showSimulatorPanel = false;


        let isShootDelayed = false;
        let isMinimized = false;
        let isStopLossActive = false;
        let stopLossEnabled = false;
		  let flashEnabled = false;
		e;

        let manualEditInputs = [];
        let panelScale;
        let rrChart = null;
        let isSyncing = false; // This is our new sync lock
        let wasInMatch = false;
        // --- NEW SESSION VARIABLES ---
        let isSessionActive = false;
        let sessionProfit = 0;
        let sessionStartDate = 0;
        const SESSION_ACTIVE_KEY = 'rr_sessionActive';
        const SESSION_PROFIT_KEY = 'rr_sessionProfit';
        const SESSION_START_KEY = 'rr_sessionStartDate';
        let simCapital, simMaxLStreak, simMatches, simSessions;

        // --- Dynamic Bets State ---
        let dynamicBetsEnabled, dynamicBetsSettings;
        let capitalInput, startingBetInput, testBetInput, capitalLock, startingBetLock;

        // --- Stats Panel State ---
        let currentStatsTimeframe = 1; // Default to 1 Day
        let chartPageOffset = 0; // 0 = Current, -1 = Previous, 1 = Next
        // ...

        const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;

        // --- Initial Checks ---
        if (document.getElementById(PANEL_ID)) return;

        // --- Load Data and Initialize Variables ---
        function initializeState() {

            isMinimized = JSON.parse(localStorage.getItem(MINIMIZE_KEY) || 'false');

            apiKey = localStorage.getItem(API_KEY_STORAGE) || '';lastSyncTime = parseInt(localStorage.getItem(LAST_SYNC_KEY) || '0', 10);
            manualBets = []; currentBets = []; showBetsPanel = false; showEditBetsPanel = false; showStatsPanel = false; isDragging = false; dragMouseX = 0; dragMouseY = 0; isTwoFingerDragging = false; initialTouchMidX = 0; initialTouchMidY = 0; initialPanelX = 0; initialPanelY = 0;
            // --- LOAD NEW MODES ---
            bettingMode = localStorage.getItem(BET_MODE_KEY) || 'manual';
            // Backwards compatibility: if dynamicBetsEnabled was true, force dynamic mode
            if (JSON.parse(localStorage.getItem(DYNAMIC_BETS_ENABLED_KEY) || 'false') && bettingMode === 'manual') {
                bettingMode = 'dynamic';
            }

            simpleModeStep = parseInt(localStorage.getItem(SIMPLE_STEP_KEY) || '0', 10);
            autoNextEnabled = JSON.parse(localStorage.getItem(AUTO_NEXT_KEY) || 'false');
            autoResetEnabled = JSON.parse(localStorage.getItem(AUTO_RESET_KEY) || 'false');

            // Sync the old boolean for compatibility with other parts of your script
            dynamicBetsEnabled = (bettingMode !== 'manual');
            results = JSON.parse(localStorage.getItem(STORAGE) || '[]');
            totalProfit = parseFloat(localStorage.getItem(PROFIT_STORAGE) || '0');
            collapsed = JSON.parse(localStorage.getItem(COLLAPSE_KEY) || 'false');
            autoHide = JSON.parse(localStorage.getItem(AUTOHIDE_KEY) || 'false');
            showSettings = false;
            maxDisplayMatches = parseInt(localStorage.getItem(MAX_DISPLAY_KEY) || '100', 10);
            if (isNaN(maxDisplayMatches) || maxDisplayMatches < 1) { maxDisplayMatches = 100; localStorage.setItem(MAX_DISPLAY_KEY, maxDisplayMatches.toString()); }
            currentOpacity = parseFloat(localStorage.getItem(OPACITY_KEY) || '0.6');
            if (isNaN(currentOpacity) || currentOpacity < 0.1 || currentOpacity > 1.0) { currentOpacity = 0.6; localStorage.setItem(OPACITY_KEY, currentOpacity.toString()); }
            profitTarget = parseFloat(localStorage.getItem(PROFIT_TARGET_KEY) || '0');
            lossLimit = parseFloat(localStorage.getItem(LOSS_LIMIT_KEY) || '0');
            hideAlerts = JSON.parse(localStorage.getItem(HIDE_ALERTS_KEY) || 'false');
            streakBreakdownView = localStorage.getItem(STREAK_VIEW_KEY) || 'win'; // <<< ADD THIS LINE
            showSimulatorPanel = false;

            enableShoot2 = JSON.parse(localStorage.getItem(ENABLE_SHOOT_2_KEY) || 'false');
            enableShoot3 = JSON.parse(localStorage.getItem(ENABLE_SHOOT_3_KEY) || 'false');

            miniBarCount = parseInt(localStorage.getItem(MINI_BAR_COUNT_KEY) || '10', 10);
            if (isNaN(miniBarCount) || miniBarCount < 1 || miniBarCount > 50) { miniBarCount = 10; localStorage.setItem(MINI_BAR_COUNT_KEY, miniBarCount.toString()); }
            miniButtonSize = parseInt(localStorage.getItem(MINI_BUTTON_SIZE_KEY) || '9', 10);
            if (isNaN(miniButtonSize) || miniButtonSize < 7 || miniButtonSize > 14) { miniButtonSize = 9; localStorage.setItem(MINI_BUTTON_SIZE_KEY, miniButtonSize.toString()); }
            panelScale = parseFloat(localStorage.getItem(PANEL_SCALE_KEY) || '1.0');
            if (isNaN(panelScale) || panelScale < 0.5 || panelScale > 1.5) { panelScale = 1.0; localStorage.setItem(PANEL_SCALE_KEY, panelScale.toString()); }
            dynamicBetsEnabled = JSON.parse(localStorage.getItem(DYNAMIC_BETS_ENABLED_KEY) || 'false');
            try {
                const storedDynamicSettings = JSON.parse(localStorage.getItem(DYNAMIC_BETS_SETTINGS_KEY));
                dynamicBetsSettings = { ...DEFAULT_DYNAMIC_SETTINGS, ...storedDynamicSettings };
            } catch {
                dynamicBetsSettings = { ...DEFAULT_DYNAMIC_SETTINGS };
            }
            isSessionActive = JSON.parse(localStorage.getItem(SESSION_ACTIVE_KEY) || 'false');
            sessionProfit = parseFloat(localStorage.getItem(SESSION_PROFIT_KEY) || '0');

            sessionStartDate = parseInt(localStorage.getItem(SESSION_START_KEY) || '0' , 10);

            flashEnabled = JSON.parse(localStorage.getItem('rr_flashEnabled') || 'false');

            stopLossEnabled = JSON.parse(localStorage.getItem(STOP_LOSS_ENABLED_KEY) || 'true');

            let initialBets = loadManualBets();
            manualBets = adjustManualBetsArray(initialBets);
            // Load simulator settings
            simCapital = localStorage.getItem(SIM_CAPITAL_KEY) || '500m';
            simMaxLStreak = localStorage.getItem(SIM_STREAK_KEY) || '12';
            simMatches = localStorage.getItem(SIM_MATCHES_KEY) || '10000';
            simSessions = localStorage.getItem(SIM_SESSIONS_KEY) || '1000';
            simulatorManualBetsString = localStorage.getItem(SIM_MANUAL_BETS_KEY) || '';
            simUseDynamic = JSON.parse(localStorage.getItem(SIM_USE_DYNAMIC_KEY) || 'true'); // <<< ADD THIS LINE



        }
        initializeState();

        // --- UI Creation ---
        const panel = document.createElement('div');
        panel.id = PANEL_ID;
        Object.assign(panel.style, {
            position: 'fixed', top: '12px', left: '12px', background: `rgba(0,0,0,${currentOpacity})`, color: '#fff',
            fontFamily: 'monospace', fontSize: '14px', padding: '36px 12px 12px', borderRadius: '10px',
            boxShadow: '0 0 12px rgba(255,0,0,0.3)', zIndex: '9999999', userSelect: 'none', display: 'flex',
            flexDirection: 'column', gap: '8px',
            width: '400px',
            flexShrink: '0', // Add this line
            boxSizing: 'border-box', // And add this line
            transformOrigin: 'top left', transform: `scale(${panelScale})`
        });

        document.body.appendChild(panel);
        try { const pos = JSON.parse(localStorage.getItem(POS_KEY) || '{}'); if (pos.top && pos.left) { panel.style.top = pos.top; panel.style.left = pos.left; } } catch {}

        // --- Reposition Panel if Off-Screen on Load ---
        setTimeout(() => {
            let currentLeft = panel.offsetLeft;
            let currentTop = panel.offsetTop;

            // Define the screen boundaries using our new constant
            // REPLACE WITH THESE
            const panelRenderedWidth = panel.offsetWidth * panelScale;
            const minX = -(panelRenderedWidth - PANEL_EDGE_MARGIN);
            const maxX = window.innerWidth - PANEL_EDGE_MARGIN;
            const minY = 0;
            const maxY = window.innerHeight - PANEL_EDGE_MARGIN;

            // Clamp the current position to the valid range
            const clampedX = Math.max(minX, Math.min(currentLeft, maxX));
            const clampedY = Math.max(minY, Math.min(currentTop, maxY));

            // If the position was out of bounds, apply the fix
            if (clampedX !== currentLeft || clampedY !== currentTop) {
                console.log('RR Tracker: Panel was off-screen, repositioning.');
                panel.style.left = clampedX + 'px';
                panel.style.top = clampedY + 'px';
                savePos(); // Save the corrected position for the next reload
            }
        }, 100); // A tiny delay to ensure the panel has rendered
        // --- End of Reposition Logic ---

        const alertMessageDiv = document.createElement('div');
        alertMessageDiv.id = 'rr-alert-message';
        Object.assign(alertMessageDiv.style, { display: 'none', padding: '8px', marginBottom: '8px', borderRadius: '6px', textAlign: 'center', fontWeight: 'bold', fontSize: '16px', color: 'white', cursor: 'pointer', border: '1px solid transparent', transition: 'background-color 0.3s, border-color 0.3s' });
        panel.appendChild(alertMessageDiv);

        const miniBar = document.createElement('div');
        const miniBetGridContainer = document.createElement('div');
        miniBetGridContainer.id = 'rr-mini-bet-grid';
        Object.assign(miniBetGridContainer.style, {
            display: 'grid',
            gridTemplateColumns: 'repeat(4, 1fr)', // Creates 4 equal columns
            gap: '3px',
            marginTop: '5px'
        });



        Object.assign(miniBar.style, { display: 'none', flexDirection: 'column', gap: '2px', padding: '4px 0' });
        panel.appendChild(miniBar);

        const profitMini = document.createElement('div');
        Object.assign(profitMini.style, { display: 'none', fontSize: '14px', fontFamily: 'monospace', margin: '2px 0' });
        panel.appendChild(profitMini);

        const statusDiv = document.createElement('div'); statusDiv.title = "Collapse/Expand the tracker panel.";
        Object.assign(statusDiv.style, { position: 'absolute', top: '8px', left: '30px', width: '20px', height: '20px', fontSize: '18px', cursor: 'pointer', color: 'rgba(255,255,255,0.7)' });
        panel.appendChild(statusDiv);

        const minimizeButton = document.createElement('div'); minimizeButton.title = "Minimize/Restore the tracker panel.";
        Object.assign(minimizeButton.style, { position: 'absolute', top: '8px', left: '8px', width: '20px', height: '20px', fontSize: '18px', cursor: 'pointer', color: 'rgba(255,255,255,0.7)' });

        minimizeButton.onclick = () => {
            isMinimized = !isMinimized; // Just toggle the minimized state
            saveMinimized();
            refreshAll();
        };

        panel.appendChild(minimizeButton);

        const dragHandle = document.createElement('div'); dragHandle.textContent = '☰'; dragHandle.title = "Click and drag to move the panel.";
        Object.assign(dragHandle.style, { position: 'absolute', top: '8px', right: '8px', width: '20px', height: '20px', fontSize: '18px', cursor: 'move', color: 'rgba(255,255,255,0.7)', touchAction: 'none' });
        panel.appendChild(dragHandle);

        const statsGroup = document.createElement('div');
        Object.assign(statsGroup.style, { display: 'flex', flexDirection: 'column', gap: '4px' });

        panel.appendChild(statsGroup);

        // --- ADD THIS NEW CODE BLOCK ---
        const mainBetGridContainer = document.createElement('div');
        mainBetGridContainer.id = 'rr-main-bet-grid';
        Object.assign(mainBetGridContainer.style, {
            display: 'grid',
            gridTemplateColumns: 'repeat(4, 1fr)', // Creates 4 equal columns
            gap: '4px', // Space between buttons
            marginTop: '10px',
            paddingTop: '6px',
            borderTop: '1px solid #333' // A separator line
        });
        panel.appendChild(mainBetGridContainer);
        // --- END OF NEW CODE BLOCK ---


        const profitDiv = document.createElement('div');
        profitDiv.id = 'rr-lifetime-profit'; // <-- ADD ID
        profitDiv.title = "Total profit or loss tracked since the last reset.";

        const dailyProfitDiv = document.createElement('div');
        dailyProfitDiv.id = 'rr-daily-profit'; // <-- ADD ID
        dailyProfitDiv.title = "Profit or loss for today (since midnight local time).";

        const winrateDiv = document.createElement('div');
        winrateDiv.id = 'rr-winrate'; // <-- ADD ID

        const streakDiv = document.createElement('div');
        streakDiv.id = 'rr-streak'; // <-- ADD ID

        const sessionDiv = document.createElement('div');
        sessionDiv.id = 'rr-session-div';
        sessionDiv.title = "Profit/loss for the current session.";
        const syncTimerDisplay = document.createElement('div');
        syncTimerDisplay.id = 'rr-sync-timer';
        Object.assign(syncTimerDisplay.style, {
            fontSize: '11px',
            fontFamily: 'monospace',
            color: '#999',
            textAlign: 'center',
            marginTop: '6px', // Add some space above
            marginBottom: '2px' // Add some space below
        });
        statsGroup.append(profitDiv, winrateDiv, streakDiv, syncTimerDisplay, dailyProfitDiv, sessionDiv);

        // VVV ADD THIS NEW BLOCK VVV
        const riskAnalysisContainer = document.createElement('div');
        riskAnalysisContainer.id = 'rr-risk-analysis';
        Object.assign(riskAnalysisContainer.style, {
            display: 'none', // Hidden by default
            flexDirection: 'column',
            gap: '4px',
            padding: '8px',
            marginTop: '6px',
            border: '1px solid #444',
            borderRadius: '6px',
            fontSize: '12px'
        });
        statsGroup.appendChild(riskAnalysisContainer);
        // ^^^ END OF NEW BLOCK ^^^


        const resultsContainer = document.createElement('div');
        Object.assign(resultsContainer.style, { maxHeight: '140px', overflowY: 'auto', marginTop: '4px' });
        statsGroup.appendChild(resultsContainer);

        const settingsPanel = document.createElement('div');
        Object.assign(settingsPanel.style, { display: 'none', flexDirection: 'column', gap: '8px', padding: '12px 0' });
        panel.appendChild(settingsPanel);

        const settingsTitle = document.createElement('div'); settingsTitle.textContent = 'Settings';
        Object.assign(settingsTitle.style, { fontSize: '16px', fontWeight: 'bold', marginBottom: '4px' });
        settingsPanel.appendChild(settingsTitle);

        const backButtonSettings = document.createElement('button'); backButtonSettings.textContent = '← Back';
        Object.assign(backButtonSettings.style, { alignSelf: 'flex-start', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer', marginBottom: '8px' });
        backButtonSettings.onmouseenter = () => backButtonSettings.style.background = 'rgba(255,255,255,0.2)'; backButtonSettings.onmouseleave = () => backButtonSettings.style.background = 'rgba(255,255,255,0.1)';
        backButtonSettings.onclick = () => { showSettings = false; showBetsPanel = false; showEditBetsPanel = false; refreshAll(); };
        settingsPanel.appendChild(backButtonSettings);

        const settingsScrollContainer = document.createElement('div');
        Object.assign(settingsScrollContainer.style, {
            display: 'flex', flexDirection: 'column', gap: '8px',
            maxHeight: '300px', overflowY: 'auto', paddingRight: '5px'
        });
        settingsPanel.appendChild(settingsScrollContainer);

        const apiSettingDiv = document.createElement('div');
        Object.assign(apiSettingDiv.style, { display: 'flex', flexDirection: 'column', gap: '6px', padding: '8px', border: '1px solid #444', borderRadius: '6px' });
        const apiKeyLabel = document.createElement('label');
        apiKeyLabel.textContent = 'Torn API Key (Auto-Syncs):';
        apiKeyLabel.htmlFor = 'api-key-input';
        const apiKeyInput = document.createElement('input');
        apiKeyInput.type = 'password';
        apiKeyInput.id = 'api-key-input';
        apiKeyInput.value = apiKey;
        apiKeyInput.placeholder = 'Enter API Key Here';
        apiKeyInput.title = 'Enter your Torn API key here. A limited-access key is recommended.';
        Object.assign(apiKeyInput.style, { width: '95%', padding: '4px', border: '1px solid #555', borderRadius: '4px', background: 'rgba(255,255,255,0.1)', color: '#fff' });
        apiKeyInput.onchange = () => {
            apiKey = apiKeyInput.value.trim();
            localStorage.setItem(API_KEY_STORAGE, apiKey);
            initiateSyncing();
        };

        const apiButtonsGroup = document.createElement('div');
        Object.assign(apiButtonsGroup.style, { display: 'flex', gap: '8px', marginTop: '8px' });

        const generateKeyLink = document.createElement('a');
        generateKeyLink.href = 'https://www.torn.com/preferences.php#tab=api?step=addNewKey&title=The%20Ultimate%20RR%20Toolkit&user=log';
        generateKeyLink.textContent = 'Generate Key';
        generateKeyLink.target = '_blank';
        generateKeyLink.rel = 'noopener noreferrer';
        generateKeyLink.title = 'Opens a new tab to the Torn API page with pre-filled settings for this script.';
        Object.assign(generateKeyLink.style, {
            background: 'rgba(100, 180, 255, 0.2)', color: '#fff', border: '1px solid #64B4FF', borderRadius: '6px',
            padding: '4px 8px', cursor: 'pointer', textDecoration: 'none', fontSize: '12px'
        });
        generateKeyLink.onmouseenter = () => generateKeyLink.style.background = 'rgba(100, 180, 255, 0.3)';
        generateKeyLink.onmouseleave = () => generateKeyLink.style.background = 'rgba(100, 180, 255, 0.2)';

        const pasteApiKeyButton = document.createElement('button');
        // --- START: New Force Sync Button ---
        const forceSyncButton = document.createElement('button');
        forceSyncButton.textContent = '🔄 Sync Now';
        forceSyncButton.title = 'Manually syncs your RR history from the Torn API. Useful after generating a new key or to check for recent games.';
        Object.assign(forceSyncButton.style, {
            background: 'rgba(128, 90, 213, 0.2)', // A distinct purple color
            color: '#fff',
            border: '1px solid #805AD5',
            borderRadius: '6px',
            padding: '4px 8px',
            cursor: 'pointer',
            fontSize: '12px'
        });
        forceSyncButton.onmouseenter = () => forceSyncButton.style.background = 'rgba(128, 90, 213, 0.3)';
        forceSyncButton.onmouseleave = () => forceSyncButton.style.background = 'rgba(128, 90, 213, 0.2)';

        // We give the button an ID to make it easier to find in our new function
        forceSyncButton.id = 'rr-force-sync-btn';

        forceSyncButton.onclick = forceFullResync; // The button now calls our new function.

        // --- END: New Force Sync Button ---

        pasteApiKeyButton.textContent = 'Paste Key';
        pasteApiKeyButton.title = 'Paste API Key from your clipboard';
        Object.assign(pasteApiKeyButton.style, {
            background: 'rgba(76, 175, 80, 0.2)', color: '#fff', border: '1px solid #4CAF50', borderRadius: '6px',
            padding: '4px 8px', cursor: 'pointer', fontSize: '12px'
        });
        pasteApiKeyButton.onmouseenter = () => pasteApiKeyButton.style.background = 'rgba(76, 175, 80, 0.3)';
        pasteApiKeyButton.onmouseleave = () => pasteApiKeyButton.style.background = 'rgba(76, 175, 80, 0.2)';

        pasteApiKeyButton.addEventListener('click', async () => {
            try {
                if (!navigator.clipboard?.readText) {
                    alert('Clipboard API is not supported by your browser.');
                    return;
                }
                const text = await navigator.clipboard.readText();
                if (text) {
                    apiKeyInput.value = text.trim();
                    apiKeyInput.dispatchEvent(new Event('change', { bubbles: true }));
                }
            } catch (err) {
                console.error('Failed to read clipboard contents:', err);
                alert('Could not paste from clipboard. Please ensure you have granted the website permission to read clipboard data.');
            }
        });

        apiButtonsGroup.append(generateKeyLink, pasteApiKeyButton, forceSyncButton);
        apiSettingDiv.append(apiKeyLabel, apiKeyInput, apiButtonsGroup);
        settingsScrollContainer.appendChild(apiSettingDiv);

        const panelScaleSettingDiv = document.createElement('div');
        Object.assign(panelScaleSettingDiv.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const panelScaleLabel = document.createElement('label');
        panelScaleLabel.textContent = `Panel Size (${Math.round(panelScale * 100)}%):`;
        panelScaleLabel.htmlFor = 'panel-scale-slider';
        Object.assign(panelScaleLabel.style, { flexShrink: '0' });
        const panelScaleSlider = document.createElement('input');
        panelScaleSlider.type = 'range'; panelScaleSlider.id = 'panel-scale-slider';
        panelScaleSlider.min = '0.5'; panelScaleSlider.max = '1.5'; panelScaleSlider.step = '0.05';
        panelScaleSlider.value = panelScale; panelScaleSlider.title = "Adjust the overall size (zoom) of the tracker panel.";
        Object.assign(panelScaleSlider.style, { width: '100px', cursor: 'pointer' });
        panelScaleSlider.oninput = () => {
            panelScaleLabel.textContent = `Panel Size (${Math.round(parseFloat(panelScaleSlider.value) * 100)}%):`;
        };
        panelScaleSlider.onchange = () => {
            panelScale = parseFloat(panelScaleSlider.value);
            panel.style.transform = `scale(${panelScale})`;
            localStorage.setItem(PANEL_SCALE_KEY, panelScale.toString());
        };
        panelScaleSettingDiv.append(panelScaleLabel, panelScaleSlider);
        settingsScrollContainer.appendChild(panelScaleSettingDiv);

        const maxMatchesSettingDiv = document.createElement('div'); Object.assign(maxMatchesSettingDiv.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const maxMatchesLabel = document.createElement('label'); maxMatchesLabel.textContent = 'Max Matches Displayed:'; maxMatchesLabel.htmlFor = 'max-matches-input'; Object.assign(maxMatchesLabel.style, { flexShrink: '0' });
        const maxMatchesInput = document.createElement('input'); maxMatchesInput.type = 'number'; maxMatchesInput.id = 'max-matches-input'; maxMatchesInput.min = '1'; maxMatchesInput.max = '100000'; maxMatchesInput.value = maxDisplayMatches; maxMatchesInput.title = "Set the maximum number of recent matches to show in the main panel."; Object.assign(maxMatchesInput.style, { width: '60px', padding: '4px', border: '1px solid #555', borderRadius: '4px', background: 'rgba(255,255,255,0.1)', color: '#fff' });
        maxMatchesInput.onchange = () => { let newValue = parseInt(maxMatchesInput.value, 10); if (isNaN(newValue) || newValue < 1) { newValue = 1; } if (newValue > 100000) newValue = 100000; maxDisplayMatches = newValue; maxMatchesInput.value = maxDisplayMatches; localStorage.setItem(MAX_DISPLAY_KEY, maxDisplayMatches.toString()); refreshAll(); };
        maxMatchesSettingDiv.append(maxMatchesLabel, maxMatchesInput);
        settingsScrollContainer.appendChild(maxMatchesSettingDiv);

        const transparencySettingDiv = document.createElement('div'); Object.assign(transparencySettingDiv.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const transparencyLabel = document.createElement('label'); transparencyLabel.textContent = 'Panel Opacity:'; transparencyLabel.htmlFor = 'transparency-slider'; Object.assign(transparencyLabel.style, { flexShrink: '0' });
        const transparencySlider = document.createElement('input'); transparencySlider.type = 'range'; transparencySlider.id = 'transparency-slider'; transparencySlider.min = '0.1'; transparencySlider.max = '1.0'; transparencySlider.step = '0.05'; transparencySlider.value = currentOpacity; transparencySlider.title = "Adjust the transparency of the tracker panel."; Object.assign(transparencySlider.style, { width: '100px', padding: '4px', border: 'none', background: 'transparent', cursor: 'pointer' });
        transparencySlider.oninput = () => { currentOpacity = parseFloat(transparencySlider.value); panel.style.background = `rgba(0,0,0,${currentOpacity})`; localStorage.setItem(OPACITY_KEY, currentOpacity.toString()); refreshAll(); };
        transparencySettingDiv.append(transparencyLabel, transparencySlider);
        settingsScrollContainer.appendChild(transparencySettingDiv);

        const profitTargetSettingDiv = document.createElement('div'); Object.assign(profitTargetSettingDiv.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const profitTargetLabel = document.createElement('label'); profitTargetLabel.textContent = 'Profit Target ($):'; profitTargetLabel.htmlFor = 'profit-target-input'; Object.assign(profitTargetLabel.style, { flexShrink: '0' });
        const profitTargetInput = document.createElement('input'); profitTargetInput.type = 'text'; profitTargetInput.id = 'profit-target-input'; profitTargetInput.value = profitTarget; profitTargetInput.title = "Set a profit target. You'll get a persistent alert when this target is reached."; Object.assign(profitTargetInput.style, { width: '80px', padding: '4px', border: '1px solid #555', borderRadius: '4px', background: 'rgba(255,255,255,0.1)', color: '#fff' });
        profitTargetInput.onchange = () => { let newValue = parseBetInput(profitTargetInput.value); if (newValue === null || newValue < 0) newValue = 0; profitTarget = newValue; profitTargetInput.value = formatNumberToKMB(profitTarget); localStorage.setItem(PROFIT_TARGET_KEY, profitTarget.toString()); alertShownProfit = false; localStorage.setItem(ALERT_SHOWN_PROFIT_KEY, 'false'); refreshAll(); };
        profitTargetSettingDiv.append(profitTargetLabel, profitTargetInput);
        settingsScrollContainer.appendChild(profitTargetSettingDiv);

        const lossLimitSettingDiv = document.createElement('div'); Object.assign(lossLimitSettingDiv.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const lossLimitLabel = document.createElement('label'); lossLimitLabel.textContent = 'Loss Limit ($):'; lossLimitLabel.htmlFor = 'loss-limit-input'; Object.assign(lossLimitLabel.style, { flexShrink: '0' });
        const lossLimitInput = document.createElement('input'); lossLimitInput.type = 'text'; lossLimitInput.id = 'loss-limit-input'; lossLimitInput.value = lossLimit; lossLimitInput.title = "Set a loss limit. You'll get a persistent alert if your losses reach this amount."; Object.assign(lossLimitInput.style, { width: '80px', padding: '4px', border: '1px solid #555', borderRadius: '4px', background: 'rgba(255,255,255,0.1)', color: '#fff' });
        lossLimitInput.onchange = () => { let newValue = parseBetInput(lossLimitInput.value); if (newValue === null || newValue < 0) newValue = 0; lossLimit = newValue; lossLimitInput.value = formatNumberToKMB(lossLimit); localStorage.setItem(LOSS_LIMIT_KEY, lossLimit.toString()); alertShownLoss = false; localStorage.setItem(ALERT_SHOWN_LOSS_KEY, 'false'); refreshAll(); };
        lossLimitSettingDiv.append(lossLimitLabel, lossLimitInput);
        settingsScrollContainer.appendChild(lossLimitSettingDiv);

        const hideAlertsToggleContainer = document.createElement('div');
        Object.assign(hideAlertsToggleContainer.style, { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '8px' });

        const hideAlertsToggle = document.createElement('input');
        hideAlertsToggle.type = 'checkbox';
        hideAlertsToggle.id = 'hide-alerts-toggle';
        hideAlertsToggle.checked = hideAlerts;
        hideAlertsToggle.title = 'If checked, all profit/loss alerts will be hidden from the panel.';

        const hideAlertsLabel = document.createElement('label');
        hideAlertsLabel.textContent = 'Hide Profit/Loss Alerts';
        hideAlertsLabel.htmlFor = 'hide-alerts-toggle';
        hideAlertsLabel.style.cursor = 'pointer';

        hideAlertsToggle.onchange = () => {
            hideAlerts = hideAlertsToggle.checked;
            localStorage.setItem(HIDE_ALERTS_KEY, JSON.stringify(hideAlerts));
            refreshAll();
        };

        hideAlertsToggleContainer.append(hideAlertsToggle, hideAlertsLabel);
        settingsScrollContainer.appendChild(hideAlertsToggleContainer);


        // --- NEW FLASH TOGGLE ---
        const flashToggleContainer = document.createElement('div');
        Object.assign(flashToggleContainer.style, { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '8px' });

        const flashToggle = document.createElement('input');
        flashToggle.type = 'checkbox';
        flashToggle.id = 'flash-toggle';
        flashToggle.checked = flashEnabled;
        flashToggle.title = 'If checked, the screen will flash Green on wins and Red on losses.';

        const flashLabel = document.createElement('label');
        flashLabel.textContent = 'Enable Win/Loss Screen Flash';
        flashLabel.htmlFor = 'flash-toggle';
        flashLabel.style.cursor = 'pointer';

        flashToggle.onchange = () => {
            flashEnabled = flashToggle.checked;
            localStorage.setItem('rr_flashEnabled', JSON.stringify(flashEnabled));
        };

        flashToggleContainer.append(flashToggle, flashLabel);
        settingsScrollContainer.appendChild(flashToggleContainer);
        // --- END FLASH TOGGLE ---

                // ... after stopLossToggleContainer ...

        // --- NEW SHOOT BUTTON SETTINGS ---
        const shootSettingsDiv = document.createElement('div');
        Object.assign(shootSettingsDiv.style, { marginTop: '10px', borderTop: '1px solid #444', paddingTop: '5px' });
        
        const shootTitle = document.createElement('div');
        shootTitle.textContent = "Extra Shoot Buttons:";
        shootTitle.style.fontSize = '12px';
        shootTitle.style.marginBottom = '4px';
        shootTitle.style.color = '#aaa';
        shootSettingsDiv.appendChild(shootTitle);

        // x2 Toggle
        const x2Div = document.createElement('div');
        Object.assign(x2Div.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const x2Check = document.createElement('input'); x2Check.type = 'checkbox'; x2Check.id = 'toggle-x2'; x2Check.checked = enableShoot2;
        const x2Label = document.createElement('label'); x2Label.textContent = 'Enable "x2 Shoot" Button'; x2Label.htmlFor = 'toggle-x2';
        x2Check.onchange = () => { enableShoot2 = x2Check.checked; localStorage.setItem(ENABLE_SHOOT_2_KEY, JSON.stringify(enableShoot2)); refreshAll(); };
        x2Div.append(x2Check, x2Label);

        // x3 Toggle
        const x3Div = document.createElement('div');
        Object.assign(x3Div.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const x3Check = document.createElement('input'); x3Check.type = 'checkbox'; x3Check.id = 'toggle-x3'; x3Check.checked = enableShoot3;
        const x3Label = document.createElement('label'); x3Label.textContent = 'Enable "x3 Shoot" Button'; x3Label.htmlFor = 'toggle-x3';
        x3Check.onchange = () => { enableShoot3 = x3Check.checked; localStorage.setItem(ENABLE_SHOOT_3_KEY, JSON.stringify(enableShoot3)); refreshAll(); };
        x3Div.append(x3Check, x3Label);

        shootSettingsDiv.append(x2Div, x3Div);
        settingsScrollContainer.appendChild(shootSettingsDiv);
        // ...


// --- ADD THIS NEW TOGGLE ---
        const stopLossToggleContainer = document.createElement('div');
        Object.assign(stopLossToggleContainer.style, { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '8px' });

        const stopLossToggle = document.createElement('input');
        stopLossToggle.type = 'checkbox';
        stopLossToggle.id = 'stop-loss-toggle';
        stopLossToggle.checked = stopLossEnabled;
        stopLossToggle.title = 'If enabled, bet buttons will be automatically disabled when the daily loss limit is reached.';

        const stopLossLabel = document.createElement('label');
        stopLossLabel.textContent = 'Enable Auto Stop-Loss';
        stopLossLabel.htmlFor = 'stop-loss-toggle';
        stopLossLabel.style.cursor = 'pointer';

        stopLossToggle.onchange = () => {
            stopLossEnabled = stopLossToggle.checked;
            localStorage.setItem(STOP_LOSS_ENABLED_KEY, JSON.stringify(stopLossEnabled));
            // If the user disables it while it's active, reset the lock
            if (!stopLossEnabled && isStopLossActive) {
                isStopLossActive = false;
                refreshAll();
            }
        };

        stopLossToggleContainer.append(stopLossToggle, stopLossLabel);
        settingsScrollContainer.appendChild(stopLossToggleContainer);
        // --- END OF NEW TOGGLE ---

        //. Instant Leave Toggle ---
        const instantLeaveContainer = document.createElement('div');
        Object.assign(instantLeaveContainer.style, { display: 'flex', alignItems: 'center', gap: '8px', marginTop: '8px' });

        const INSTANT_LEAVE_KEY = 'rr_instantLeave';
        // Define variable here so it is available globally in this scope
        let instantLeaveEnabled = JSON.parse(localStorage.getItem(INSTANT_LEAVE_KEY) || 'false');

        const instantLeaveToggle = document.createElement('input');
        instantLeaveToggle.type = 'checkbox';
        instantLeaveToggle.id = 'instant-leave-toggle';
        instantLeaveToggle.checked = instantLeaveEnabled;
        instantLeaveToggle.title = 'If checked, the script will instantly redirect you to the RR lobby after a Bang (Win or Loss).';

        const instantLeaveLabel = document.createElement('label');
        instantLeaveLabel.textContent = 'Instant Leave on Bang';
        instantLeaveLabel.htmlFor = 'instant-leave-toggle';
        instantLeaveLabel.style.cursor = 'pointer';

        instantLeaveToggle.onchange = () => {
            instantLeaveEnabled = instantLeaveToggle.checked;
            localStorage.setItem(INSTANT_LEAVE_KEY, JSON.stringify(instantLeaveEnabled));
        };

        instantLeaveContainer.append(instantLeaveToggle, instantLeaveLabel);
        settingsScrollContainer.appendChild(instantLeaveContainer);
        // --- END NEW LOCATION ---


        const miniBarCountSettingDiv = document.createElement('div'); Object.assign(miniBarCountSettingDiv.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const miniBarCountLabel = document.createElement('label'); miniBarCountLabel.textContent = 'Mini-Bar Count:'; miniBarCountLabel.htmlFor = 'mini-bar-count-input'; Object.assign(miniBarCountLabel.style, { flexShrink: '0' });
        const miniBarCountInput = document.createElement('input'); miniBarCountInput.type = 'number'; miniBarCountInput.id = 'mini-bar-count-input'; miniBarCountInput.min = '1'; miniBarCountInput.max = '50'; miniBarCountInput.value = miniBarCount; miniBarCountInput.title = "Set how many recent match indicators (W/L circles) are shown in the collapsed view."; Object.assign(miniBarCountInput.style, { width: '60px', padding: '4px', border: '1px solid #555', borderRadius: '4px', background: 'rgba(255,255,255,0.1)', color: '#fff' });
        miniBarCountInput.onchange = () => { let newValue = parseInt(miniBarCountInput.value, 10); if (isNaN(newValue) || newValue < 1) newValue = 1; if (newValue > 50) newValue = 50; miniBarCount = newValue; miniBarCountInput.value = miniBarCount; localStorage.setItem(MINI_BAR_COUNT_KEY, miniBarCount.toString()); refreshAll(); };
        miniBarCountSettingDiv.append(miniBarCountLabel, miniBarCountInput);
        settingsScrollContainer.appendChild(miniBarCountSettingDiv);

        const miniButtonSizeSettingDiv = document.createElement('div'); Object.assign(miniButtonSizeSettingDiv.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const miniButtonSizeLabel = document.createElement('label'); miniButtonSizeLabel.textContent = 'Mini-Button Size:'; miniButtonSizeLabel.htmlFor = 'mini-button-size-slider'; Object.assign(miniButtonSizeLabel.style, { flexShrink: '0' });
        const miniButtonSizeSlider = document.createElement('input'); miniButtonSizeSlider.type = 'range'; miniButtonSizeSlider.id = 'mini-button-size-slider'; miniButtonSizeSlider.min = '7'; miniButtonSizeSlider.max = '14'; miniButtonSizeSlider.step = '1'; miniButtonSizeSlider.value = miniButtonSize; miniButtonSizeSlider.title = "Adjust the font size of the bet buttons in the collapsed view."; Object.assign(miniButtonSizeSlider.style, { width: '100px', padding: '4px', border: 'none', background: 'transparent', cursor: 'pointer' });
        miniButtonSizeSlider.oninput = () => { miniButtonSize = parseInt(miniButtonSizeSlider.value, 10); localStorage.setItem(MINI_BUTTON_SIZE_KEY, miniButtonSize.toString()); refreshAll(); };
        miniButtonSizeSettingDiv.append(miniButtonSizeLabel, miniButtonSizeSlider);
        settingsScrollContainer.appendChild(miniButtonSizeSettingDiv);


        const editBetsButton = document.createElement('button'); editBetsButton.textContent = '✏️ Edit Bets'; editBetsButton.title = "Open the panel to configure your manual or dynamic betting strategy.";
        Object.assign(editBetsButton.style, { alignSelf: 'flex-start', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer' });
        editBetsButton.onmouseenter = () => editBetsButton.style.background = 'rgba(255,255,255,0.2)'; editBetsButton.onmouseleave = () => editBetsButton.style.background = 'rgba(255,255,255,0.1)';
        editBetsButton.onclick = () => { showSettings = false; showBetsPanel = false; showEditBetsPanel = true; refreshAll(); };
        settingsScrollContainer.appendChild(editBetsButton);


        const resetBtn = document.createElement('button'); 
        resetBtn.textContent = '🔄 Reset Data'; 
        resetBtn.title = "WARNING: This will clear all tracked stats, profit, reset all bet configurations (including Boost Wins settings), and your API key.";
        Object.assign(resetBtn.style, { alignSelf: 'flex-start', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer' });
        
        resetBtn.onmouseenter = () => resetBtn.style.background = 'rgba(255,255,255,0.2)'; 
        resetBtn.onmouseleave = () => resetBtn.style.background = 'rgba(255,255,255,0.1)';
        
        resetBtn.onclick = () => {
            if (confirm('Clear ALL results, reset profit, and wipe all strategy settings?')) {
                // 1. Clear Standard Data
                localStorage.removeItem(STORAGE);
                localStorage.removeItem(PROFIT_STORAGE);
                localStorage.removeItem(ALERT_SHOWN_PROFIT_KEY);
                localStorage.removeItem(ALERT_SHOWN_LOSS_KEY);
                localStorage.removeItem(MANUAL_BETS_STORAGE_KEY);
                localStorage.removeItem(DYNAMIC_BETS_ENABLED_KEY);
                localStorage.removeItem(DYNAMIC_BETS_SETTINGS_KEY);
                localStorage.removeItem(UI_BUTTON_COUNT_KEY);
                localStorage.removeItem(PANEL_SCALE_KEY);
                localStorage.removeItem(API_KEY_STORAGE);
                localStorage.removeItem(LAST_SYNC_KEY);
                
                // 2. Clear Session Data
                localStorage.removeItem(SESSION_ACTIVE_KEY);
                localStorage.removeItem(SESSION_PROFIT_KEY);
                localStorage.removeItem(SESSION_START_KEY);

                // 3. Clear Auto/Simple Mode Data
                localStorage.removeItem(SIMPLE_STEP_KEY);
                localStorage.removeItem(AUTO_NEXT_KEY);
                localStorage.removeItem(AUTO_RESET_KEY);

                // 4. Clear New "Boost Wins" Strategy Data
                localStorage.removeItem('rr_boostWins');
                localStorage.removeItem('rr_streakCap');
                localStorage.removeItem('rr_martingaleStart');
                localStorage.removeItem('rr_martingaleActive');

                // 5. Re-Initialize and Refresh
                initializeState();
                apiKeyInput.value = '';
                // Reset inputs in the UI to defaults
                if(document.querySelector('#mode-manual')) document.querySelector('#mode-manual').click();
                
                refreshAll();
                alert("All data and settings have been reset.");
            }
        };

        settingsScrollContainer.appendChild(resetBtn);



        const buttonContainer = document.createElement('div');
        Object.assign(buttonContainer.style, { display: 'flex', gap: '4px', marginTop: '4px' });
        panel.appendChild(buttonContainer);

        const settingsButton = document.createElement('button'); settingsButton.textContent = '⚙️ Settings'; settingsButton.title = "Open the settings panel.";
        Object.assign(settingsButton.style, { flex: '1', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer' });
        settingsButton.onmouseenter = () => settingsButton.style.background = 'rgba(255,255,255,0.2)';
        settingsButton.onmouseleave = () => settingsButton.style.background = 'rgba(255,255,255,0.1)';
        settingsButton.onclick = () => { showSettings = !showSettings; showBetsPanel = false; showEditBetsPanel = false; showStatsPanel = false; refreshAll(); };
        buttonContainer.appendChild(settingsButton);

        const editBetsPanel = document.createElement('div');
        Object.assign(editBetsPanel.style, { display: 'none', flexDirection: 'column', gap: '8px', padding: '12px 0' });
        panel.appendChild(editBetsPanel);
        const editBetsTitle = document.createElement('div'); editBetsTitle.textContent = 'Edit Bets';
        Object.assign(editBetsTitle.style, { fontSize: '16px', fontWeight: 'bold', marginBottom: '4px' });
        editBetsPanel.appendChild(editBetsTitle);

        const createDynamicInput = (label, id, value, title, type = 'text') => {
            const lbl = document.createElement('label'); lbl.textContent = label; lbl.htmlFor = id;
            const input = document.createElement('input'); input.type = type; input.id = id; input.value = value; input.title = title;
            Object.assign(input.style, { width: '100%', padding: '4px', border: '1px solid #555', borderRadius: '4px', background: 'rgba(255,255,255,0.1)', color: '#fff' });
            const lock = document.createElement('button'); lock.style.cursor = 'pointer'; lock.style.background = 'none'; lock.style.border = 'none'; lock.style.color = '#fff'; lock.style.fontSize = '16px'; lock.style.padding = '0 5px';
            return [lbl, input, lock];
        };

        const backButtonEditBets = document.createElement('button'); backButtonEditBets.textContent = '← Back to Settings';
        Object.assign(backButtonEditBets.style, { alignSelf: 'flex-start', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer', marginBottom: '8px' });
        backButtonEditBets.onmouseenter = () => backButtonEditBets.style.background = 'rgba(255,255,255,0.2)'; backButtonEditBets.onmouseleave = () => backButtonEditBets.style.background = 'rgba(255,255,255,0.1)';
        backButtonEditBets.onclick = () => { showEditBetsPanel = false; showSettings = true; refreshAll(); };
        editBetsPanel.appendChild(backButtonEditBets);

        // --- NEW BETTING MODE SELECTOR ---
        const modeContainer = document.createElement('div');
        Object.assign(modeContainer.style, { display: 'flex', flexDirection: 'column', gap: '8px', padding: '10px', background: 'rgba(255,255,255,0.05)', borderRadius: '6px', marginBottom: '10px' });

        const modeTitle = document.createElement('div');
        modeTitle.textContent = "Select Betting Mode:";
        modeTitle.style.fontWeight = "bold";
        modeContainer.appendChild(modeTitle);

        const modes = [
            { value: 'manual', label: 'Manual Grid (Static)' },
            { value: 'dynamic', label: 'Dynamic Grid (Calculated)' },
            { value: 'simple', label: 'Simple Multiplier (4-Button)' }
        ];

        modes.forEach(m => {
            const row = document.createElement('div');
            Object.assign(row.style, { display: 'flex', alignItems: 'center', gap: '8px' });

            const radio = document.createElement('input');
            radio.type = 'radio';
            radio.name = 'rr_bet_mode';
            radio.id = `mode-${m.value}`;
            radio.value = m.value;
            radio.checked = (bettingMode === m.value); // Uses var from Phase 1

            const label = document.createElement('label');
            label.textContent = m.label;
            label.htmlFor = `mode-${m.value}`;
            label.style.cursor = "pointer";

            radio.onchange = () => {
                bettingMode = m.value;
                localStorage.setItem(BET_MODE_KEY, bettingMode);

                // Maintain compatibility with old logic
                dynamicBetsEnabled = (bettingMode !== 'manual');
                localStorage.setItem(DYNAMIC_BETS_ENABLED_KEY, JSON.stringify(dynamicBetsEnabled));

                updateSettingsVisibility();
                calculateBetsAndRefresh();
            };

            row.append(radio, label);
            modeContainer.appendChild(row);
        });

        editBetsPanel.appendChild(modeContainer);

        // --- AUTO FEATURES (Simple Mode Only) ---
        // --- AUTO FEATURES (Simple Mode Only) ---
        const autoFeaturesContainer = document.createElement('div');
        Object.assign(autoFeaturesContainer.style, { display: 'none', flexDirection: 'column', gap: '8px', padding: '0 10px 10px 10px', marginLeft: '10px', borderLeft: '2px solid #555' });

        // 1. Existing Simple Toggles
        const createSimpleToggle = (labelText, checked, key, callback) => {
            const div = document.createElement('div');
            Object.assign(div.style, { display: 'flex', alignItems: 'center', gap: '8px' });
            const box = document.createElement('input'); box.type = 'checkbox'; box.checked = checked;
            const lbl = document.createElement('label'); lbl.textContent = labelText;
            box.onchange = () => {
                localStorage.setItem(key, JSON.stringify(box.checked));
                callback(box.checked);
            };
            div.append(box, lbl);
            return div;
        };

                // [Inside the block where you add Auto-Next/Auto-Reset toggles]
        
autoFeaturesContainer.appendChild(createSimpleToggle("Auto-Next after Loss", autoNextEnabled, AUTO_NEXT_KEY, (val) => autoNextEnabled = val));
        autoFeaturesContainer.appendChild(createSimpleToggle("Auto-Reset after Win", autoResetEnabled, AUTO_RESET_KEY, (val) => autoResetEnabled = val));

        // 2. NEW: Boost Wins Section
        const boostContainer = document.createElement('div');
        Object.assign(boostContainer.style, { display: 'flex', flexDirection: 'column', gap: '5px', marginTop: '5px', paddingTop: '5px', borderTop: '1px solid #444' });
        
        // Boost Toggle
        const boostCheckDiv = document.createElement('div');
        Object.assign(boostCheckDiv.style, { display: 'flex', alignItems: 'center', gap: '8px' });
        const boostCheck = document.createElement('input'); 
        boostCheck.type = 'checkbox';
        boostCheck.checked = JSON.parse(localStorage.getItem('rr_boostWins') || 'false');
        const boostLabel = document.createElement('label'); 
        boostLabel.textContent = 'Enable "Boost Wins" Strategy';
        
        boostCheck.onchange = () => {
            localStorage.setItem('rr_boostWins', JSON.stringify(boostCheck.checked));
            // Reset the "Active Martingale" state if user toggles this, to prevent getting stuck
            localStorage.setItem('rr_martingaleActive', 'false'); 
        };
        boostCheckDiv.append(boostCheck, boostLabel);
        boostContainer.appendChild(boostCheckDiv);

        // Inputs Container
        const boostInputsDiv = document.createElement('div');
        Object.assign(boostInputsDiv.style, { display: 'flex', gap: '10px', fontSize: '12px' });

        // Cap Input
        const capDiv = document.createElement('div');
        capDiv.innerHTML = 'Streak Cap:<br>';
        const capInput = document.createElement('input');
        capInput.type = 'number';
        capInput.value = localStorage.getItem('rr_streakCap') || '4';
        capInput.style.width = '40px';
        capInput.onchange = () => localStorage.setItem('rr_streakCap', capInput.value);
        capDiv.appendChild(capInput);

        // Start Input
        const startDiv = document.createElement('div');
        startDiv.innerHTML = 'Martingale Start:<br>';
        const startInput = document.createElement('input');
        startInput.type = 'number';
        startInput.value = localStorage.getItem('rr_martingaleStart') || '2';
        startInput.style.width = '40px';
        startInput.onchange = () => localStorage.setItem('rr_martingaleStart', startInput.value);
        startDiv.appendChild(startInput);

        boostInputsDiv.append(capDiv, startDiv);
        boostContainer.appendChild(boostInputsDiv);
        
        autoFeaturesContainer.appendChild(boostContainer);

        modeContainer.appendChild(autoFeaturesContainer);


        // and replace it with this visibility helper:

        const dynamicBetsContainer = document.createElement('div');
        Object.assign(dynamicBetsContainer.style, { display: dynamicBetsEnabled ? 'grid' : 'none', gridTemplateColumns: 'auto 1fr auto', gap: '8px 10px', marginTop: '10px' });
        editBetsPanel.appendChild(dynamicBetsContainer);

        const manualBetsContainer = document.createElement('div');
        Object.assign(manualBetsContainer.style, { display: dynamicBetsEnabled ? 'none' : 'block', marginTop: '10px' });
        editBetsPanel.appendChild(manualBetsContainer);
        const manualBetsTitle = document.createElement('div'); manualBetsTitle.textContent = 'Manual Bet Configuration';
        Object.assign(manualBetsTitle.style, { fontSize: '13px', color: 'rgba(255,255,255,0.7)', marginBottom: '8px' });
        manualBetsContainer.appendChild(manualBetsTitle);
        const manualEditGrid = document.createElement('div');
        Object.assign(manualEditGrid.style, { display: 'grid', gridTemplateColumns: 'auto 1fr', gap: '6px 10px', overflowY: 'auto', maxHeight: '200px' });
        manualBetsContainer.appendChild(manualEditGrid);



        const [capitalLabel, localCapitalInput, localCapitalLock] = createDynamicInput('Gambling Capital:', 'dyn-capital', dynamicBetsSettings.capital, "Define your total risk. Lock this (🔒) to have the script calculate the 'Starting Bet' for you. Accepts k/m/b suffixes.", 'text');
        capitalInput = localCapitalInput; capitalLock = localCapitalLock;
        capitalInput.onchange = () => {
            if (dynamicBetsSettings.lockedField === 'capital') {
                const parsed = parseBetInput(capitalInput.value);
                if (parsed !== null) {
                    dynamicBetsSettings.capital = Math.max(0, parsed);
                    saveDynamicBetsSettings();
                    calculateBetsAndRefresh();
                } else {
                    capitalInput.value = formatNumberToKMB(dynamicBetsSettings.capital);
                }
            }
        };
        capitalLock.onclick = () => { dynamicBetsSettings.lockedField = 'capital'; saveDynamicBetsSettings(); calculateBetsAndRefresh(); };
        dynamicBetsContainer.append(capitalLabel, capitalInput, capitalLock);

        const [startingBetLabel, localStartingBetInput, localStartingBetLock] = createDynamicInput('Starting Bet (x):', 'dyn-starting-bet', dynamicBetsSettings.startingBet, "Define your ideal first bet. Lock this (🔒) to have the script calculate the total 'Gambling Capital' required. Accepts k/m/b suffixes.", 'text');
        startingBetInput = localStartingBetInput; startingBetLock = localStartingBetLock;
        startingBetInput.onchange = () => {
            if (dynamicBetsSettings.lockedField === 'startingBet') {
                const parsed = parseBetInput(startingBetInput.value);
                if (parsed !== null) {
                    dynamicBetsSettings.startingBet = Math.max(0, parsed);
                    saveDynamicBetsSettings();
                    calculateBetsAndRefresh();
                } else {
                    startingBetInput.value = formatNumberToKMB(dynamicBetsSettings.startingBet);
                }
            }
        };
        startingBetLock.onclick = () => { dynamicBetsSettings.lockedField = 'startingBet'; saveDynamicBetsSettings(); calculateBetsAndRefresh(); };
        dynamicBetsContainer.append(startingBetLabel, startingBetInput, startingBetLock);

        const [maxLLabel, maxLInput] = createDynamicInput('Max L Streak:', 'dyn-max-l', dynamicBetsSettings.maxLStreak, `The maximum number of consecutive losses your strategy should be able to withstand. Max: ${MAX_L_STREAK_CAP}.`, 'number');
        maxLInput.max = MAX_L_STREAK_CAP;
        maxLInput.onchange = () => {
            let val = Math.max(1, parseInt(maxLInput.value, 10) || 1);
            val = Math.min(val, MAX_L_STREAK_CAP);
            dynamicBetsSettings.maxLStreak = val;
            maxLInput.value = val;
            saveDynamicBetsSettings();
            calculateBetsAndRefresh();
        };
        dynamicBetsContainer.append(maxLLabel, maxLInput, document.createElement('div'));

        const [martingaleLabel, martingaleInput] = createDynamicInput('Martingale Value:', 'dyn-martingale', dynamicBetsSettings.martingaleValue, "The multiplier for your bets (e.g., 2 for doubling, 3 for tripling).", 'number');
        martingaleInput.step = '0.1';
        martingaleInput.onchange = () => {
            let val = Math.max(1.1, parseFloat(martingaleInput.value) || 1.1);
            dynamicBetsSettings.martingaleValue = val;
            martingaleInput.value = val;
            saveDynamicBetsSettings();
            calculateBetsAndRefresh();
        };
        dynamicBetsContainer.append(martingaleLabel, martingaleInput, document.createElement('div'));

        // --- START NEW DRAIN L STREAK UI ---
        const drainContainer = document.createElement('div');
        Object.assign(drainContainer.style, { gridColumn: '1 / -1', display: 'flex', alignItems: 'center', gap: '8px', borderTop: '1px solid #444', paddingTop: '8px', marginTop: '4px' });

        const drainCheck = document.createElement('input'); 
        drainCheck.type = 'checkbox'; 
        drainCheck.id = 'dyn-drain'; 
        drainCheck.checked = dynamicBetsSettings.drainEnabled;
        
        const drainLabel = document.createElement('label'); 
        drainLabel.textContent = 'Drain L Streak'; 
        drainLabel.htmlFor = 'dyn-drain';

        const drainStartInput = document.createElement('input');
        drainStartInput.type = 'number'; 
        drainStartInput.value = dynamicBetsSettings.drainStart; 
        drainStartInput.style.width = '40px'; 
        drainStartInput.title = "Start Step (e.g. 3 starts flattening at 3rd bet)";
        
        const drainRepeatsInput = document.createElement('input');
        drainRepeatsInput.type = 'number'; 
        drainRepeatsInput.value = dynamicBetsSettings.drainRepeats; 
        drainRepeatsInput.style.width = '40px'; 
        drainRepeatsInput.title = "Repeats (how many times to bet the same amount)";

        const drainUpdate = () => {
            dynamicBetsSettings.drainEnabled = drainCheck.checked;
            dynamicBetsSettings.drainStart = parseInt(drainStartInput.value) || 3;
            dynamicBetsSettings.drainRepeats = parseInt(drainRepeatsInput.value) || 4;
            saveDynamicBetsSettings();
            calculateBetsAndRefresh();
        };

        drainCheck.onchange = drainUpdate;
        drainStartInput.onchange = drainUpdate;
        drainRepeatsInput.onchange = drainUpdate;

        drainContainer.append(drainCheck, drainLabel, document.createTextNode(' Start:'), drainStartInput, document.createTextNode(' Reps:'), drainRepeatsInput);
        dynamicBetsContainer.appendChild(drainContainer);
        // --- END NEW DRAIN L STREAK UI ---




        // --- UPDATED REINFORCE UI WITH INTERVAL INPUT ---
        const reinforceContainer = document.createElement('div');
        Object.assign(reinforceContainer.style, { gridColumn: '1 / -1', display: 'flex', alignItems: 'center', gap: '8px' });
        
        const reinforceCheck = document.createElement('input'); 
        reinforceCheck.type = 'checkbox'; 
        reinforceCheck.id = 'dyn-reinforce'; 
        reinforceCheck.checked = dynamicBetsSettings.reinforce;
        
        const reinforceLabel = document.createElement('label'); 
        reinforceLabel.textContent = 'Reinforce every:'; 
        reinforceLabel.htmlFor = 'dyn-reinforce';
        
        const reinforceInput = document.createElement('input');
        reinforceInput.type = 'number';
        reinforceInput.value = dynamicBetsSettings.reinforceInterval || 2;
        reinforceInput.style.width = '35px';
        reinforceInput.style.textAlign = 'center';
        reinforceInput.title = "Apply reinforcement every X steps (Default: 2 = odd steps like 3, 5, 7)";
        
        const reinforceSuffix = document.createElement('span');
        reinforceSuffix.textContent = 'steps';
        
        const updateReinforce = () => {
            dynamicBetsSettings.reinforce = reinforceCheck.checked;
            let interval = parseInt(reinforceInput.value);
            if(isNaN(interval) || interval < 1) interval = 2;
            dynamicBetsSettings.reinforceInterval = interval;
            saveDynamicBetsSettings(); 
            calculateBetsAndRefresh(); 
        };
        reinforceCheck.onchange = updateReinforce;
        reinforceInput.onchange = updateReinforce;
        
        reinforceContainer.append(reinforceCheck, reinforceLabel, reinforceInput, reinforceSuffix);
        dynamicBetsContainer.appendChild(reinforceContainer);

        // --- UPDATED BOOSTED BETS UI WITH INTERVAL INPUT ---
        const boostedBetsContainer = document.createElement('div');
        Object.assign(boostedBetsContainer.style, { gridColumn: '1 / -1', display: 'flex', alignItems: 'center', gap: '8px' });
        
        const boostedBetsCheck = document.createElement('input');
        boostedBetsCheck.type = 'checkbox';
        boostedBetsCheck.id = 'dyn-boosted';
        boostedBetsCheck.checked = dynamicBetsSettings.boostedBets;
        
        const boostedBetsLabel = document.createElement('label');
        boostedBetsLabel.textContent = 'Boost (x2) every:';
        boostedBetsLabel.htmlFor = 'dyn-boosted';
        
        const boostedInput = document.createElement('input');
        boostedInput.type = 'number';
        boostedInput.value = dynamicBetsSettings.boostInterval || 5;
        boostedInput.style.width = '35px';
        boostedInput.style.textAlign = 'center';
        boostedInput.title = "Double the bet every X steps (Default: 5 = 5th, 10th, 15th)";

        const boostedSuffix = document.createElement('span');
        boostedSuffix.textContent = 'L';

        const updateBoost = () => {
            dynamicBetsSettings.boostedBets = boostedBetsCheck.checked;
            let interval = parseInt(boostedInput.value);
            if(isNaN(interval) || interval < 1) interval = 5;
            dynamicBetsSettings.boostInterval = interval;
            saveDynamicBetsSettings();
            calculateBetsAndRefresh();
        };

        boostedBetsCheck.onchange = updateBoost;
        boostedInput.onchange = updateBoost;

        boostedBetsContainer.append(boostedBetsCheck, boostedBetsLabel, boostedInput, boostedSuffix);
        dynamicBetsContainer.appendChild(boostedBetsContainer);
 
        function performInstantLeave() {
            // This URL is the main lobby for Russian Roulette
            const lobbyUrl = "https://www.torn.com/page.php?sid=russianRoulette";
            
            console.log("RR Tracker: Instant Leave triggered. Redirecting...");
            
            // Force the browser to go there immediately
            window.location.href = lobbyUrl;
        }


        // --- TEXT-BASED DETECTION (Trigger Only) ---
        function enableTextBasedDetection() {
            let syncTriggered = false;
            let flashTriggered = false;

            const observer = new MutationObserver((mutations) => {
                const text = document.body.innerText || "";
                const hasBang = text.includes("BANG");

                // 1. RESET
                if (!hasBang) {
                    if (syncTriggered || flashTriggered) {
                        syncTriggered = false;
                        flashTriggered = false;
                    }
                    return;
                }

                // 2. SYNC TRIGGER (The "Bang")
                if (hasBang && !syncTriggered) {
                    console.log("RR Tracker: 'BANG' detected! Syncing...");
                    // This Sync will eventually call autoBet() when data arrives
                    importApiData(true); 
                    syncTriggered = true;
                }

                // [Inside enableTextBasedDetection, in the 'if (hasBang)' block]

                // 3. FLASH & ACTIONS
                if (hasBang && !flashTriggered) {
                    
                    // LOAD SETTING (Dynamic)
                    const instantLeave = JSON.parse(localStorage.getItem('rr_instantLeave') || 'false');

                    // --- SCENARIO: LOSS ---
                    if (text.includes("You fall down")) {
                        triggerFlash('loss');
                        flashTriggered = true;
                        // Wait 500ms for flash, then redirect
                        if (instantLeave) setTimeout(performInstantLeave, 500); 
                    } 
                    
                    // --- SCENARIO: WIN ---
                    else if (text.includes("You take your winnings")) {
                        triggerFlash('win');
                        flashTriggered = true;
                        // Wait 500ms for flash, then redirect
                        if (instantLeave) setTimeout(performInstantLeave, 500); 
                    }
                }

            });

            observer.observe(document.body, { childList: true, subtree: true, characterData: true });
            console.log("RR Tracker: Text-based detection enabled.");
        }



        function updateSettingsVisibility() {
            dynamicBetsContainer.style.display = (bettingMode === 'manual') ? 'none' : 'grid';
            manualBetsContainer.style.display = (bettingMode === 'manual') ? 'block' : 'none';
            autoFeaturesContainer.style.display = (bettingMode === 'simple') ? 'flex' : 'none';
        }
        // Run once to set initial state
        updateSettingsVisibility();


        const statsButton = document.createElement('button'); statsButton.textContent = '📊 Stats'; statsButton.title = "Open the Statistics and Graph panel.";
        Object.assign(statsButton.style, { flex: '1', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer' });
        statsButton.onmouseenter = () => statsButton.style.background = 'rgba(255,255,255,0.2)';
        statsButton.onmouseleave = () => statsButton.style.background = 'rgba(255,255,255,0.1)';
        statsButton.onclick = () => {
            showStatsPanel = !showStatsPanel;
            showSettings = false; showBetsPanel = false; showEditBetsPanel = false;
            refreshAll();
            if (showStatsPanel) {
                updateGraph();
            }
        };
        buttonContainer.appendChild(statsButton);


        // ... after the statsButton is added to buttonContainer ...

        // ... after the statsButton is added to buttonContainer ...

        const simulatorButton = document.createElement('button');
        simulatorButton.textContent = '🔬 Simulator';
        simulatorButton.title = "Open the Strategy Simulator to simulate outcomes.";
        Object.assign(simulatorButton.style, { flex: '1', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer' });
        simulatorButton.onmouseenter = () => simulatorButton.style.background = 'rgba(255,255,255,0.2)';
        simulatorButton.onmouseleave = () => simulatorButton.style.background = 'rgba(255,255,255,0.1)';
        simulatorButton.onclick = () => {
            showSimulatorPanel = !showSimulatorPanel;
            showSettings = false; showBetsPanel = false; showEditBetsPanel = false; showStatsPanel = false;

            // --- ADD THESE TWO LINES ---
            showSimulatorConfig = false; // Always start on the main results view
            if (showSimulatorPanel) refreshSimulatorView(); // Refresh the view if opening
            refreshAll();
        };
        buttonContainer.appendChild(simulatorButton);


        const sessionButton = document.createElement('button');
        sessionButton.id = 'rr-session-button';
        Object.assign(sessionButton.style, {
            flex: '1', background: 'rgba(255, 255, 255, 0.1)', color: '#fff',
            border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer'
        });
        sessionButton.onmouseenter = () => sessionButton.style.background = 'rgba(255,255,255,0.2)';
        sessionButton.onmouseleave = () => sessionButton.style.background = 'rgba(255,255,255,0.1)';
        buttonContainer.appendChild(sessionButton);

        // --- Mini Panel Structure ---
        const miniCirclesContainer = document.createElement('div');
        miniCirclesContainer.id = 'rr-mini-circles-container'; // <<< ADD THIS LINE
        Object.assign(miniCirclesContainer.style, { display: 'flex', flexWrap: 'wrap', gap: '3px', justifyContent: 'center', padding: '4px 0' });

        const miniStatsContainer = document.createElement('div');
        Object.assign(miniStatsContainer.style, { display: 'flex', flexDirection: 'column', gap: '4px', padding: '6px 0', borderTop: '1px solid #333', borderBottom: '1px solid #333' });

        // Add clones of the main stats divs to the mini container
        const miniStreakDiv = streakDiv.cloneNode(true);
        miniStreakDiv.id = ''; // <-- ADD THIS LINE to remove the cloned ID

        const miniDailyProfitDiv = dailyProfitDiv.cloneNode(true);
        miniDailyProfitDiv.id = ''; // <-- ADD THIS LINE to remove the cloned ID

        const miniSessionDiv = sessionDiv.cloneNode(true);
        miniSessionDiv.id = ''; // <-- ADD THIS LINE to remove the cloned ID

        miniStatsContainer.append(miniStreakDiv, miniDailyProfitDiv, miniSessionDiv);

        miniBar.append(miniCirclesContainer, miniStatsContainer, miniBetGridContainer);
        // --- End Mini Panel Structure ---


        const simulatorPanel = document.createElement('div');
        simulatorPanel.id = 'rr-simulator-panel';
        Object.assign(simulatorPanel.style, { display: 'none', flexDirection: 'column', gap: '8px', padding: '12px 0' });
        panel.appendChild(simulatorPanel);

        // (Inside the (function waitUntilReady() { ... block)

        simulatorPanel.innerHTML = `
        <div style="font-size: 16px; font-weight: bold;">Strategy Simulator</div>
        <button id="simulator-back-btn" style="align-self: flex-start; background: rgba(255,255,255,0.1); color: #fff; border: none; border-radius: 6px; padding: 4px 8px; cursor: pointer; margin-bottom: 8px;">← Back to Main Panel</button>

        <div id="simulator-main-view">
            <button id="simulator-configure-btn" style="width: 100%; background: rgba(100, 180, 255, 0.2); color: #fff; border: 1px solid #64B4FF; border-radius: 6px; padding: 6px; cursor: pointer; font-size: 14px; margin-bottom: 15px;">
                ⚙️ Simulator Configuration
            </button>

            <div style="display: flex; gap: 8px;">
                <button id="simulator-run-btn" style="flex: 1; background: #4CAF50; color: white; border: none; border-radius: 6px; padding: 8px; cursor: pointer; font-size: 14px; font-weight: bold;">Run Simulation(s)</button>
                <button id="simulator-deep-run-btn" title="Run a detailed analysis to find the optimal Max L Streak for profit and safety." style="flex: 1; background: #3F51B5; color: white; border: none; border-radius: 6px; padding: 8px; cursor: pointer; font-size: 14px; font-weight: bold;">🔬 Deep Simulation</button>
            </div>

            <canvas id="simulator-graph-canvas" width="350" height="200" style="background: rgba(0,0,0,0.2); border-radius: 6px; margin-top: 15px; display: none;"></canvas>

            <div id="simulator-results-container" style="margin-top: 10px; padding: 10px; background: rgba(0,0,0,0.2); border-radius: 6px; min-height: 100px; font-size: 13px; white-space: pre-wrap; max-height: 250px; overflow-y: auto;">
                Configure your strategy and run a simulation to see the potential outcome.
            </div>

            <div id="simulator-deep-results-container" style="display: none; margin-top: 10px; font-size: 13px;"></div>
        </div>

        <div id="simulator-config-view" style="display: none; flex-direction: column; gap: 8px;">
            <button id="simulator-config-back-btn" style="align-self: flex-start; background: rgba(255,255,255,0.1); color: #fff; border: none; border-radius: 6px; padding: 4px 8px; cursor: pointer;">← Back to Results</button>

            <div style="display: grid; grid-template-columns: auto 1fr; gap: 8px; align-items: center; margin-top: 10px; padding: 10px; border: 1px solid #444; border-radius: 6px;">
                <label for="simulator-capital">Starting Capital:</label>
                <input type="text" id="simulator-capital" style="padding: 4px; border: 1px solid #555; border-radius: 4px; background: rgba(255,255,255,0.1); color: #fff;">

                <label for="simulator-max-streak">Max L Streak:</label>
                <input type="number" id="simulator-max-streak" style="padding: 4px; border: 1px solid #555; border-radius: 4px; background: rgba(255,255,255,0.1); color: #fff;">

                <label for="simulator-matches">Matches per Session:</label>
                <input type="number" id="simulator-matches" style="padding: 4px; border: 1px solid #555; border-radius: 4px; background: rgba(255,255,255,0.1); color: #fff;">

                <label for="simulator-sessions">Number of Sessions:</label>
                <input type="number" id="simulator-sessions" style="padding: 4px; border: 1px solid #555; border-radius: 4px; background: rgba(255,255,255,0.1); color: #fff;">
            </div>

            <div style="display: flex; align-items: center; gap: 8px; padding: 8px; background: rgba(255,255,255,0.05); border-radius: 6px; margin-top: 10px;">
                <input type="checkbox" id="simulator-dynamic-toggle">
                <label for="simulator-dynamic-toggle" style="cursor: pointer;">Import Bets from Dynamic Calculator</label>
            </div>

            <div id="simulator-manual-bets-container" style="display: none; flex-direction: column; gap: 4px; margin-top: 10px;">
                <div style="display: flex; justify-content: space-between; align-items: center;">
                    <label for="simulator-manual-bets">Manual Bets (comma-separated):</label>
                    <button id="simulator-copy-dynamic-btn" title="Copy the current bets from the Dynamic Calculator into this text box." style="background: rgba(255,255,255,0.1); color: #fff; border: 1px solid #555; border-radius: 4px; padding: 2px 6px; cursor: pointer; font-size: 11px;">↙️ Copy from Dynamic</button>
                </div>
                <textarea id="simulator-manual-bets" rows="3" style="padding: 4px; border: 1px solid #555; border-radius: 4px; background: rgba(255,255,255,0.1); color: #fff; font-family: monospace; resize: vertical;"></textarea>
            </div>
        </div>
    `;



        const statsDisplayPanel = document.createElement('div');
        Object.assign(statsDisplayPanel.style, {
            display: 'none',
            flexDirection: 'column',
            gap: '8px',
            padding: '12px 10px 12px 0',
            width: '360px',
            maxHeight: '80vh',
            overflowY: 'auto'
        });
        panel.appendChild(statsDisplayPanel);

        const statsDisplayTitle = document.createElement('div');
        statsDisplayTitle.textContent = 'Statistics & Graph';
        Object.assign(statsDisplayTitle.style, { fontSize: '16px', fontWeight: 'bold' });

        const backButtonStats = document.createElement('button');
        backButtonStats.textContent = '← Back';
        Object.assign(backButtonStats.style, { alignSelf: 'flex-start', background: 'rgba(255,255,255,0.1)', color: '#fff', border: 'none', borderRadius: '6px', padding: '4px 8px', cursor: 'pointer', marginBottom: '8px' });
        backButtonStats.onmouseenter = () => backButtonStats.style.background = 'rgba(255,255,255,0.2)';
        backButtonStats.onmouseleave = () => backButtonStats.style.background = 'rgba(255,255,255,0.1)';
        backButtonStats.onclick = () => { showStatsPanel = false; refreshAll(); };

        // --- Create all stats elements first ---
        const statsSummaryDiv = document.createElement('div');
        Object.assign(statsSummaryDiv.style, { fontSize: '12px', display: 'flex', justifyContent: 'space-around', padding: '4px', background: 'rgba(255,255,255,0.05)', borderRadius: '4px' });

        const lifetimeStreaksDiv = document.createElement('div');
        lifetimeStreaksDiv.id = 'rr-lifetime-streaks-display';
        Object.assign(lifetimeStreaksDiv.style, {
            fontSize: '12px',
            display: 'flex',
            justifyContent: 'space-around',
            padding: '6px',
            marginTop: '8px',
            borderTop: '1px solid #444'
        });

        const timeframeContainer = document.createElement('div');
        Object.assign(timeframeContainer.style, { display: 'flex', justifyContent: 'center', gap: '5px', marginTop: '8px' });

        const graphCanvas = document.createElement('canvas');
        graphCanvas.id = 'rr-graph-canvas';
        graphCanvas.width = 350;
        graphCanvas.height = 200;
        Object.assign(graphCanvas.style, { background: 'rgba(0,0,0,0.2)', borderRadius: '6px', marginTop: '8px' });

        const breakdownParentContainer = document.createElement('div');
        Object.assign(breakdownParentContainer.style, {
            display: 'flex',
            gap: '10px',
            marginTop: '8px',
            alignItems: 'flex-start'
        });

        const profitBreakdownDiv = document.createElement('div');
        profitBreakdownDiv.id = 'rr-profit-breakdown';
        Object.assign(profitBreakdownDiv.style, {
            flex: '1', display: 'flex', flexDirection: 'column', gap: '4px', fontSize: '12px',
            padding: '8px', background: 'rgba(255,255,255,0.05)', borderRadius: '4px',
            maxHeight: '150px', overflowY: 'auto'
        });

        // --- Reworked Streak Breakdown Container ---
        const streakBreakdownDiv = document.createElement('div');
        streakBreakdownDiv.id = 'rr-streak-breakdown';
        Object.assign(streakBreakdownDiv.style, {
            flex: '1', display: 'flex', flexDirection: 'column', padding: '8px',
            background: 'rgba(255,255,255,0.05)', borderRadius: '4px'
        });

        const streakTitle = document.createElement('h4');
        streakTitle.textContent = 'Streaks';
        Object.assign(streakTitle.style, { margin: '0 0 8px 0', textAlign: 'center', color: '#ccc' });

        const streakToggleContainer = document.createElement('div');
        Object.assign(streakToggleContainer.style, { textAlign: 'center', marginBottom: '8px' });

        const winStreakToggle = document.createElement('span');
        winStreakToggle.id = 'win-streak-toggle';
        winStreakToggle.textContent = '🔥';
        winStreakToggle.title = 'Show Win Streaks';
        Object.assign(winStreakToggle.style, { cursor: 'pointer', fontSize: '20px', margin: '0 10px', transition: 'opacity 0.2s, transform 0.2s' });

        const lossStreakToggle = document.createElement('span');
        lossStreakToggle.id = 'loss-streak-toggle';
        lossStreakToggle.textContent = '💀';
        lossStreakToggle.title = 'Show Loss Streaks';
        Object.assign(lossStreakToggle.style, { cursor: 'pointer', fontSize: '20px', margin: '0 10px', transition: 'opacity 0.2s, transform 0.2s' });

        const streakSeparator = document.createElement('span');
        streakSeparator.textContent = '|';
        Object.assign(streakSeparator.style, { color: '#555', fontSize: '18px' });

        winStreakToggle.onclick = () => { streakBreakdownView = 'win'; localStorage.setItem(STREAK_VIEW_KEY, 'win'); updateGraph(); };
        lossStreakToggle.onclick = () => { streakBreakdownView = 'loss'; localStorage.setItem(STREAK_VIEW_KEY, 'loss'); updateGraph(); };

        const streakListContainer = document.createElement('div');
        streakListContainer.id = 'rr-streak-list';
        Object.assign(streakListContainer.style, { maxHeight: '105px', overflowY: 'auto' });

        const graphTooltipDisplay = document.createElement('div');
        graphTooltipDisplay.id = 'rr-graph-tooltip-display';
        Object.assign(graphTooltipDisplay.style, {
            display: 'none', padding: '8px', marginTop: '10px', background: 'rgba(0,0,0,0.3)',
            borderRadius: '6px', border: '1px solid #555', textAlign: 'center', fontSize: '12px',
            fontFamily: 'monospace', transition: 'opacity 0.2s', color: '#ddd'
        });

        // --- Assemble the stats panel in the correct, final order ---
        statsDisplayPanel.appendChild(statsDisplayTitle);
        statsDisplayPanel.appendChild(backButtonStats);
        statsDisplayPanel.appendChild(statsSummaryDiv); // Reverted to old layout
        statsDisplayPanel.appendChild(lifetimeStreaksDiv); // Reverted to old layout
        statsDisplayPanel.appendChild(timeframeContainer);
        statsDisplayPanel.appendChild(graphCanvas);

                // --- NEW: Container for Date Navigation (Under Graph) ---
        const graphNavigationDiv = document.createElement('div');
        graphNavigationDiv.id = 'rr-graph-navigation';
        Object.assign(graphNavigationDiv.style, { 
            display: 'flex', 
            alignItems: 'center', 
            justifyContent: 'center', 
            gap: '15px', 
            marginTop: '8px', 
            padding: '5px', 
            background: 'rgba(255,255,255,0.05)', 
            borderRadius: '4px' 
        });
        statsDisplayPanel.appendChild(graphNavigationDiv);
        // -------------------------------------------------------


streakToggleContainer.appendChild(winStreakToggle);
        streakToggleContainer.appendChild(streakSeparator);
        streakToggleContainer.appendChild(lossStreakToggle);
        streakBreakdownDiv.appendChild(streakTitle);
        streakBreakdownDiv.appendChild(streakToggleContainer);
        streakBreakdownDiv.appendChild(streakListContainer);
        breakdownParentContainer.appendChild(profitBreakdownDiv);
        breakdownParentContainer.appendChild(streakBreakdownDiv);
        statsDisplayPanel.appendChild(breakdownParentContainer);

        statsDisplayPanel.appendChild(graphTooltipDisplay);


        const timeframes = [
            { label: '1D', days: 1 }, { label: '7D', days: 7 }, { label: '1M', days: 30 },
            { label: '6M', days: 182 }, { label: '1Y', days: 365 }, { label: '5Y', days: 1825 }
        ];


        timeframes.forEach(tf => {
            const btn = document.createElement('button');
            btn.textContent = tf.label;
            btn.dataset.days = tf.days;
            btn.title = `Show stats for the last ${tf.label}`;
            Object.assign(btn.style, {
                background: 'rgba(255,255,255,0.1)', color: '#fff', border: '1px solid #555',
                borderRadius: '6px', padding: '3px 8px', cursor: 'pointer', fontSize: '11px'
            });
            btn.onmouseenter = () => btn.style.background = 'rgba(255,255,255,0.2)';
            btn.onmouseleave = () => { if(currentStatsTimeframe != tf.days) btn.style.background = 'rgba(255,255,255,0.1)'; };
            // ... inside timeframes.forEach loop ...
            btn.onclick = () => {
                currentStatsTimeframe = tf.days;
                chartPageOffset = 0; // <--- ADD THIS LINE (Reset to "Today/Current" when switching modes)
                updateGraph();
            };
            // ...

            timeframeContainer.appendChild(btn);
        });

        // --- Core Functions ---
        const saveMinimized = () => localStorage.setItem(MINIMIZE_KEY, JSON.stringify(isMinimized));
        const saveResults = () => localStorage.setItem(STORAGE, JSON.stringify(results));
        const saveTotalProfit = () => localStorage.setItem(PROFIT_STORAGE, totalProfit.toString());
        const saveCollapsed = () => localStorage.setItem(COLLAPSE_KEY, JSON.stringify(collapsed));
        const saveManualBets = () => localStorage.setItem(MANUAL_BETS_STORAGE_KEY, JSON.stringify(manualBets));
        const saveDynamicBetsSettings = () => localStorage.setItem(DYNAMIC_BETS_SETTINGS_KEY, JSON.stringify(dynamicBetsSettings));
        const saveSessionState = () => {
            localStorage.setItem(SESSION_ACTIVE_KEY, JSON.stringify(isSessionActive));
            localStorage.setItem(SESSION_PROFIT_KEY, sessionProfit.toString());
            localStorage.setItem(SESSION_START_KEY, sessionStartDate.toString());
        };

        // --- ADD THIS ENTIRE NEW FUNCTION ---
        function calculateLifetimeStreaks() {
            let maxWinStreak = 0;
            let maxLossStreak = 0;
            let currentWinStreak = 0;
            let currentLossStreak = 0;

            // Iterate backwards from the most recent game
            for (let i = results.length - 1; i >= 0; i--) {
                if (results[i].result === 'win') {
                    currentWinStreak++;
                    currentLossStreak = 0; // Reset loss streak
                } else {
                    currentLossStreak++;
                    currentWinStreak = 0; // Reset win streak
                }

                if (currentWinStreak > maxWinStreak) {
                    maxWinStreak = currentWinStreak;
                }
                if (currentLossStreak > maxLossStreak) {
                    maxLossStreak = currentLossStreak;
                }
            }
            return { maxWinStreak, maxLossStreak };
        }


        let syncCountdownInterval = null; // Variable to hold our new timer

        /**
 * Updates the sync countdown timer display in the UI.
 */
        function updateSyncTimer() {
            const timerDisplay = document.getElementById('rr-sync-timer');
            if (!timerDisplay) return;

            if (!apiKey || lastSyncTime === 0) {
                timerDisplay.textContent = 'Auto-sync inactive';
                return;
            }

            // It now also uses the central constant, ensuring the countdown is always accurate.
            const nextSyncTime = lastSyncTime + API_SYNC_INTERVAL_MS;
            const now = Date.now();
            const secondsLeft = Math.round((nextSyncTime - now) / 1000);

            if (secondsLeft > 0) {
                timerDisplay.textContent = `Next sync: ${secondsLeft}s`;
            } else {
                timerDisplay.textContent = 'Syncing now...';
            }
        }


        function toggleSession() {
            if (isSessionActive) {
                // Stopping the session
                isSessionActive = false;
                if (confirm('Do you want to stop the current session? Your session profit will be reset the next time you start.')) {
                    // User confirmed stop
                } else {
                    // User cancelled, so we revert the state
                    isSessionActive = true;
                    return; // Exit without changes
                }
            } else {
                // Starting a new session
                isSessionActive = true;
                sessionProfit = 0;
                sessionStartDate = Date.now();
            }
            saveSessionState();
            refreshAll(); // Update the UI immediately
        }

        // Attach the function to the button after the UI is created
        // Place this line right after you define the sessionButton
        sessionButton.onclick = toggleSession;

        /**
 * Call this function whenever a new game result is recorded.
 * @param {string} result - Should be 'win' or 'lose'.
 * @param {number} betAmount - The amount of money that was bet.
 * @param {object} additionalData - Any other data like timestamp, origin, etc.
 */

        function calculateProfitBreakdown(games, timeframeInDays, offset = 0) {
            const breakdown = [];
            const now = new Date();
            const currentYear = now.getUTCFullYear();
            const currentMonth = now.getUTCMonth();
            const currentDate = now.getUTCDate();
            
            // Define one day in milliseconds
            const ONE_DAY_MS = 24 * 60 * 60 * 1000;

            // 1. Determine Start and End Timestamps (UTC)
            let startTimestamp, endTimestamp;
            let periodType = '';

            if (timeframeInDays === 1) {
                // --- 1 DAY VIEW (4-Hour Blocks) ---
                periodType = '4-hour';
                // Start: 00:00 UTC of target day
                startTimestamp = Date.UTC(currentYear, currentMonth, currentDate + offset);
                // End: 00:00 UTC of next day
                endTimestamp = Date.UTC(currentYear, currentMonth, currentDate + offset + 1);

            } else if (timeframeInDays === 7) {
                // --- 7 DAY VIEW (Daily, Mon-Sun) ---
                periodType = 'day';
                let dayOfWeek = now.getUTCDay(); 
                if (dayOfWeek === 0) dayOfWeek = 7; // Fix Sunday
                const daysToMonday = dayOfWeek - 1;
                
                // Calculate Monday of the current week, then shift by offset
                const currentMonday = Date.UTC(currentYear, currentMonth, currentDate - daysToMonday);
                startTimestamp = currentMonday + (offset * 7 * ONE_DAY_MS);
                endTimestamp = startTimestamp + (7 * ONE_DAY_MS);

            } else if (timeframeInDays === 30) {
                // --- MONTH VIEW (Daily, 1st-End) ---
                periodType = 'day';
                // Start: 1st of Target Month
                startTimestamp = Date.UTC(currentYear, currentMonth + offset, 1);
                // End: 1st of Next Month
                endTimestamp = Date.UTC(currentYear, currentMonth + offset + 1, 1);

            } else if (timeframeInDays === 365) {
                // --- YEAR VIEW (Quarterly) ---
                periodType = 'quarter';
                // Start: Jan 1st of Target Year
                startTimestamp = Date.UTC(currentYear + offset, 0, 1);
                // End: Jan 1st of Next Year
                endTimestamp = Date.UTC(currentYear + offset + 1, 0, 1);
            } else {
                return [];
            }

            // 2. Generate Periods Loop (Safer Timestamp Math)
            if (periodType === 'quarter') {
                // Special handling for Quarters (3 months each)
                const startYear = new Date(startTimestamp).getUTCFullYear();
                for (let q = 0; q < 4; q++) {
                    const qStart = Date.UTC(startYear, q * 3, 1);
                    const qEnd = Date.UTC(startYear, (q + 1) * 3, 1); // 1st of next block
                    // End of quarter for display (last ms of previous block)
                    const displayEnd = new Date(qEnd - 1); 
                    const displayStart = new Date(qStart);

                    const label = `Q${q+1} (${displayStart.toLocaleString('en-GB', { month: 'short', timeZone: 'UTC' })} - ${displayEnd.toLocaleString('en-GB', { month: 'short', timeZone: 'UTC' })})`;
                    
                    breakdown.push({ label: label, start: qStart, end: qEnd });
                }
                // Reverse to show Q4 at top, Q1 at bottom
                breakdown.reverse();

            } else if (periodType === '4-hour') {
                // Loop 6 times (4 hours * 6 = 24 hours)
                for (let t = startTimestamp; t < endTimestamp; t += (4 * 60 * 60 * 1000)) {
                    const pStart = new Date(t);
                    const pEnd = new Date(t + (4 * 60 * 60 * 1000));
                    const label = `${pStart.getUTCHours().toString().padStart(2, '0')}:00 - ${pEnd.getUTCHours().toString().padStart(2, '0')}:00`;
                    
                    // We push to array, then reverse later so newest time is top
                    breakdown.push({ label: label, start: t, end: t + (4 * 60 * 60 * 1000) });
                }
                breakdown.reverse();

            } else {
                // --- DAILY LOOPS (For Week and Month views) ---
                // Loop day by day
                for (let t = startTimestamp; t < endTimestamp; t += ONE_DAY_MS) {
                    const dateObj = new Date(t);
                    let label = dateObj.toLocaleDateString('en-GB', { weekday: 'short', day: 'numeric', timeZone: 'UTC' });
                    
                    if (timeframeInDays === 30) {
                        label = dateObj.toLocaleDateString('en-GB', { month: 'short', day: 'numeric', timeZone: 'UTC' });
                    }

                    breakdown.push({ label: label, start: t, end: t + ONE_DAY_MS });
                }
                // Reverse so the last day of the month/week is at the top
                breakdown.reverse();
            }

            // 3. Calculate Profit
            // Pre-calculate game results once for performance
            const resultsWithProfit = breakdown.map(p => {
                let pProfit = 0;
                // Optimization: Only iterate relevant portion of games array? 
                // For now, simple filter is safe enough for <100k games.
                for (const g of games) {
                    const gTime = g.timestamp * 1000;
                    if (gTime >= p.start && gTime < p.end) {
                        pProfit += (g.result === 'win' ? g.bet : -g.bet);
                    }
                }
                return { label: p.label, profit: pProfit };
            });

            return resultsWithProfit;
        }



        function refreshSimulatorView() {
            const mainView = document.getElementById('simulator-main-view');
            const configView = document.getElementById('simulator-config-view');
            if (!mainView || !configView) return;

            if (showSimulatorConfig) {
                mainView.style.display = 'none';
                configView.style.display = 'flex';
            } else {
                mainView.style.display = 'block';
                configView.style.display = 'none';
            }
        }


        /**
 * Generates a random sequence of Win/Loss outcomes.
 * @param {number} count The number of matches in the sequence.
 * @returns {string[]} An array like ['W', 'L', 'L', 'W', ...]
 */
        function generateOutcomes(count) {
            const outcomes = [];
            for (let i = 0; i < count; i++) {
                outcomes.push(Math.random() < 0.5 ? 'W' : 'L');
            }
            return outcomes;
        }


        /**
 * Samples a large dataset to a more manageable size for graphing.
 * @param {number[]} data The full array of capital history.
 * @param {number} maxPoints The maximum number of points for the graph.
 * @returns {number[]} The smaller, sampled array.
 */
        function sampleData(data, maxPoints) {
            if (data.length <= maxPoints) {
                return data; // No sampling needed if data is already small
            }
            const sampled = [];
            const step = (data.length - 1) / (maxPoints - 1);
            for (let i = 0; i < maxPoints; i++) {
                sampled.push(data[Math.floor(i * step)]);
            }
            return sampled;
        }


        /**
 * "Replays" a pre-generated timeline of outcomes with a specific strategy.
 * @param {object} params Parameters including capital, bets, outcomes, and the specific maxLStreak to test.
 * @returns {object} The final result { finalCapital, bankrupt: boolean }.
 */
        function replaySessionWithLimit(params) {
            const { capital, bets, outcomes, maxLStreak } = params;
            let currentCapital = capital;
            let currentLStreak = 0;

            for (const outcome of outcomes) {
                const betIndex = currentLStreak;
                const currentBet = bets[betIndex];

                if (!currentBet || currentBet > currentCapital) {
                    // Bankruptcy occurred during this replay.
                    return { finalCapital: currentCapital, bankrupt: true };
                }

                if (outcome === 'W') {
                    currentCapital += currentBet;
                    currentLStreak = 0;
                } else { // Outcome is 'L'
                    currentCapital -= currentBet;
                    currentLStreak++;
                }

                if (currentLStreak >= maxLStreak) {
                    // A reset occurs according to the rule being tested.
                    currentLStreak = 0;
                }
            }
            // If the loop completes, the session was successful for this rule.
            return { finalCapital: currentCapital, bankrupt: false };
        }


        function runMatchByMatchSimulation(params) {
            const { capital, maxLStreak, bets, matches, initialStreak = 0 } = params;
            if (!capital || !maxLStreak || !bets || bets.length === 0 || !matches) {
                return { error: "Invalid simulation parameters. Check all inputs." };
            }
            let currentCapital = capital;
            let currentLStreak = initialStreak;
            let resetCount = 0;
            const streakCounts = {};
            const capitalHistory = [capital];
            for (let i = 0; i < matches; i++) {
                const betIndex = currentLStreak;
                const currentBet = bets[betIndex];
                if (!currentBet || currentBet > currentCapital) {
                    return {
                        finalCapital: currentCapital, streakCounts, resetCount, capitalHistory,
                        matchesCompleted: i,
                        stopReason: `Bankrupt at Match #${i + 1}.`,
                        unfinishedStreak: currentLStreak,
                        finalStreak: currentLStreak
                    };
                }
                const isWin = Math.random() < 0.5;
                if (isWin) {
                    currentCapital += currentBet;
                    if (currentLStreak > 0) {
                        streakCounts[currentLStreak] = (streakCounts[currentLStreak] || 0) + 1;
                    }
                    currentLStreak = 0;
                } else {
                    currentCapital -= currentBet;
                    currentLStreak++;
                }
                capitalHistory.push(currentCapital);
                if (currentLStreak >= maxLStreak) {
                    streakCounts[currentLStreak] = (streakCounts[currentLStreak] || 0) + 1;
                    resetCount++;
                    currentLStreak = 0;
                }
            }
            return {
                finalCapital: currentCapital, streakCounts, resetCount, capitalHistory,
                matchesCompleted: matches,
                stopReason: `Simulation completed successfully.`,
                unfinishedStreak: 0,
                finalStreak: currentLStreak
            };
        }


        function runMultipleSimulations(params) {
            const { capital, maxLStreak, bets, matches, sessions } = params;
            const allSessionResults = [];
            for (let i = 0; i < sessions; i++) {
                const result = runMatchByMatchSimulation({ capital, maxLStreak, bets, matches });
                allSessionResults.push(result);
            }
            const totalResets = allSessionResults.reduce((sum, r) => sum + r.resetCount, 0);
            const finalCapitals = allSessionResults.map(r => r.finalCapital);
            const totalProfit = finalCapitals.reduce((sum, cap) => sum + (cap - capital), 0);
            const bankruptcies = allSessionResults.filter(r => r.stopReason.startsWith('Bankrupt')).length;
            const profitableSessions = allSessionResults.filter(r => r.finalCapital > capital).length;
            const aggregateStreaks = {};
            const bankruptcyStreaks = {};
            allSessionResults.forEach(r => {
                for (const [streak, count] of Object.entries(r.streakCounts)) {
                    aggregateStreaks[streak] = (aggregateStreaks[streak] || 0) + count;
                }
                if (r.unfinishedStreak > 0) {
                    bankruptcyStreaks[r.unfinishedStreak] = (bankruptcyStreaks[r.unfinishedStreak] || 0) + 1;
                }
            });
            finalCapitals.sort((a, b) => a - b);
            const mid = Math.floor(sessions / 2);
            const medianCapital = sessions % 2 !== 0 ? finalCapitals[mid] : (finalCapitals[mid - 1] + finalCapitals[mid]) / 2;
            const mostCommonFailure = Object.entries(bankruptcyStreaks).sort((a, b) => b[1] - a[1])[0];
            return {
                sessions, totalResets,
                bankruptRate: (bankruptcies / sessions) * 100,
                profitableRate: (profitableSessions / sessions) * 100,
                averageProfit: totalProfit / sessions,
                medianProfit: medianCapital - capital,
                aggregateStreaks,
                mostCommonFailure: mostCommonFailure ? `L${mostCommonFailure[0]} (${mostCommonFailure[1]} times)` : 'N/A'
            };
        }



        // Add this new function right after runMultipleSimulations

        function runCumulativeSimulation(params) {
            const { capital, maxLStreak, bets, matches, sessions } = params;
            let currentCapital = capital;
            let currentLStreak = 0;
            let resetCount = 0;
            const streakCounts = {};
            const capitalHistory = [capital];
            const totalMatchesToRun = matches * sessions;
            for (let i = 0; i < totalMatchesToRun; i++) {
                const betIndex = currentLStreak;
                const currentBet = bets[betIndex];
                if (!currentBet || currentBet > currentCapital) {
                    return {
                        finalCapital: currentCapital, capitalHistory, resetCount, streakCounts,
                        stopReason: `Bankrupt at Match #${i + 1}.`,
                    };
                }
                const isWin = Math.random() < 0.5;
                if (isWin) {
                    currentCapital += currentBet;
                    if (currentLStreak > 0) {
                        streakCounts[currentLStreak] = (streakCounts[currentLStreak] || 0) + 1;
                    }
                    currentLStreak = 0;
                } else {
                    currentCapital -= currentBet;
                    currentLStreak++;
                }
                capitalHistory.push(currentCapital);
                if (currentLStreak >= maxLStreak) {
                    streakCounts[currentLStreak] = (streakCounts[currentLStreak] || 0) + 1;
                    resetCount++;
                    currentLStreak = 0;
                }
            }
            return {
                finalCapital: currentCapital, capitalHistory, resetCount, streakCounts,
                stopReason: `Simulation completed successfully.`,
            };
        }

        function runDeepMatchSimulation(params) {
            const { capital, bets, matches } = params;
            let currentCapital = capital;
            let currentLStreak = 0;
            const streakOutcomes = []; // This will log every streak { length, outcome: 'win' or 'bankrupt' }

            for (let i = 0; i < matches; i++) {
                const betIndex = currentLStreak;
                const currentBet = bets[betIndex];

                if (!currentBet || currentBet > currentCapital) {
                    // This is a bankruptcy. Log the streak that caused it.
                    if (currentLStreak > 0) {
                        streakOutcomes.push({ length: currentLStreak, outcome: 'bankrupt' });
                    }
                    return streakOutcomes; // End of this simulation run
                }

                const isWin = Math.random() < 0.5;

                if (isWin) {
                    currentCapital += currentBet;
                    if (currentLStreak > 0) {
                        // We won, so the streak ended successfully.
                        streakOutcomes.push({ length: currentLStreak, outcome: 'win' });
                    }
                    currentLStreak = 0;
                } else {
                    currentCapital -= currentBet;
                    currentLStreak++;
                }
            }
            return streakOutcomes; // Return all streaks from the completed session
        }


        function runDeepAnalysis(params) {
            const { capital, bets, matches, simulations } = params;

            // This object will store the summed results for each limit across all simulations.
            const resultsByLimit = {};
            const maxStreakToAnalyze = bets.length;

            // 1. Main Simulation Loop (e.g., 100 times)
            for (let i = 0; i < simulations; i++) {
                // Generate one master timeline of W/L outcomes
                const outcomes = generateOutcomes(matches);
                let maxStreakInThisTimeline = 0;

                // Find the longest streak in this specific timeline to cap the inner loop
                let currentLStreak = 0;
                for (const outcome of outcomes) {
                    if (outcome === 'L') {
                        currentLStreak++;
                    } else {
                        if (currentLStreak > maxStreakInThisTimeline) {
                            maxStreakInThisTimeline = currentLStreak;
                        }
                        currentLStreak = 0;
                    }
                }
                if (currentLStreak > maxStreakInThisTimeline) {
                    maxStreakInThisTimeline = currentLStreak;
                }


                // 2. Inner "What If" Loop
                // Replay the master timeline for each possible Max L Streak rule
                for (let limit = 4; limit <= maxStreakInThisTimeline + 1 && limit < maxStreakToAnalyze; limit++) {
                    if (!resultsByLimit[limit]) {
                        resultsByLimit[limit] = { totalProfit: 0, bankruptcies: 0 };
                    }

                    const result = replaySessionWithLimit({ capital, bets, outcomes, maxLStreak: limit });

                    // Add the results of this replay to the totals
                    resultsByLimit[limit].totalProfit += (result.finalCapital - capital);
                    if (result.bankrupt) {
                        resultsByLimit[limit].bankruptcies++;
                    }
                }
            }

            // 3. Final Aggregation
            const finalAnalysis = [];
            for (const limit in resultsByLimit) {
                const data = resultsByLimit[limit];
                finalAnalysis.push({
                    limit: parseInt(limit, 10),
                    avgProfit: data.totalProfit / simulations,
                    bankRate: (data.bankruptcies / simulations) * 100
                });
            }

            return finalAnalysis;
        }



        function calculateStreakBreakdown(allResults) {
            if (allResults.length === 0) {
                return { winStreaks: [], lossStreaks: [] };
            }

            const winStreakCounts = {};
            const lossStreakCounts = {};
            let currentStreakLength = 0;
            let currentStreakType = '';

            // Iterate through all results to count streaks
            allResults.slice().reverse().forEach(result => {
                if (result.result === currentStreakType) {
                    currentStreakLength++;
                } else {
                    // Streak is broken, record the previous one if it existed
                    if (currentStreakLength > 0) {
                        if (currentStreakType === 'win') {
                            winStreakCounts[currentStreakLength] = (winStreakCounts[currentStreakLength] || 0) + 1;
                        } else {
                            lossStreakCounts[currentStreakLength] = (lossStreakCounts[currentStreakLength] || 0) + 1;
                        }
                    }
                    // Start the new streak
                    currentStreakType = result.result;
                    currentStreakLength = 1;
                }
            });

            // Record the very last streak after the loop finishes
            if (currentStreakLength > 0) {
                if (currentStreakType === 'win') {
                    winStreakCounts[currentStreakLength] = (winStreakCounts[currentStreakLength] || 0) + 1;
                } else {
                    lossStreakCounts[currentStreakLength] = (lossStreakCounts[currentStreakLength] || 0) + 1;
                }
            }

            const totalWinStreaks = Object.values(winStreakCounts).reduce((a, b) => a + b, 0);
            const totalLossStreaks = Object.values(lossStreakCounts).reduce((a, b) => a + b, 0);

            const formatStreaks = (counts, total) => {
                return Object.entries(counts)
                    .map(([length, count]) => ({
                    length: parseInt(length, 10),
                    count,
                    percentage: total > 0 ? ((count / total) * 100).toFixed(1) : 0
                }))
                    .sort((a, b) => a.length - b.length);
            };

            return {
                winStreaks: formatStreaks(winStreakCounts, totalWinStreaks),
                lossStreaks: formatStreaks(lossStreakCounts, totalLossStreaks)
            };
        }


        function updateGraph() {
            // 1. Destroy old chart
            if (rrChart) {
                rrChart.destroy();
                rrChart = null;
            }

            // 2. Get Data
            const { dataPoints, summary } = processDataForGraph(currentStatsTimeframe);

            // 3. Prepare Colors
            const profitSign = summary.totalProfit >= 0 ? '+' : '-';
            const profitColor = summary.totalProfit >= 0 ? '#4CAF50' : '#E53935';
            
            // 4. Update Summary HTML (TOP - STATS ONLY)
            // This restores the "Old" look for the top section
            statsSummaryDiv.innerHTML = `
                <span title="Total profit/loss for this period" style="color:${profitColor}; font-weight: bold;">${profitSign}$${formatNumberToKMB(Math.abs(summary.totalProfit))}</span>
                <span title="Wins / Losses">W/L: ${summary.wins} / ${summary.losses}</span>
                <span title="Total games played">Games: ${summary.totalGames}</span>
            `;

            // 5. Update Navigation HTML (BOTTOM - BUTTONS ONLY)
            // We target the new container we created in Step 1
            const navContainer = document.getElementById('rr-graph-navigation');
            if (navContainer) {
                navContainer.innerHTML = `
                    <button id="chart-prev-btn" title="Previous Period" style="background: rgba(255,255,255,0.1); border: 1px solid #555; border-radius: 4px; color: #fff; cursor: pointer; font-size: 14px; padding: 2px 10px;">◀</button>
                    
                    <span style="font-weight: bold; color: #fff; font-size: 13px; min-width: 140px; text-align: center;">${summary.rangeLabel || 'Current Period'}</span>
                    
                    <button id="chart-next-btn" title="Next Period" style="background: rgba(255,255,255,0.1); border: 1px solid ${chartPageOffset === 0 ? '#333' : '#555'}; border-radius: 4px; color: ${chartPageOffset === 0 ? '#555' : '#fff'}; cursor: ${chartPageOffset === 0 ? 'default' : 'pointer'}; font-size: 14px; padding: 2px 10px;" ${chartPageOffset === 0 ? 'disabled' : ''}>▶</button>
                `;

                // Bind Button Events
                document.getElementById('chart-prev-btn').onclick = () => {
                    chartPageOffset--; 
                    updateGraph();
                };
                document.getElementById('chart-next-btn').onclick = () => {
                    if (chartPageOffset < 0) { 
                        chartPageOffset++; 
                        updateGraph();
                    }
                };
            }

            // 6. Handle Profit Breakdown 
            const profitBreakdownContainer = document.getElementById('rr-profit-breakdown');
            if(profitBreakdownContainer) {
                 // NOW: We pass the 'chartPageOffset' to the function!
                 const profitBreakdownData = calculateProfitBreakdown(results, currentStatsTimeframe, chartPageOffset);
                 
                 if (profitBreakdownData.length > 0) {
                    profitBreakdownContainer.style.display = 'flex';
                    profitBreakdownContainer.innerHTML = `<h4 style="margin: 0 0 5px 0; text-align: center; color: #ccc;">Profit Breakdown</h4>` +
                        profitBreakdownData.map(item => {
                        const itemProfitSign = item.profit >= 0 ? '+' : '-';
                        const itemProfitColor = item.profit >= 0 ? '#4CAF50' : '#E53935';
                        const formattedProfit = `$${formatNumberToKMB(Math.abs(item.profit))}`;
                        return `
                        <div style="display: flex; justify-content: space-between; padding: 2px 4px; border-bottom: 1px solid #333;">
                            <span>${item.label}:</span>
                            <span style="color: ${itemProfitColor}; font-weight: bold;">${itemProfitSign}${formattedProfit}</span>
                        </div>`;
                    }).join('');
                } else {
                    // Show N/A if no data, but the box is still active
                    profitBreakdownContainer.innerHTML = `<h4 style="margin: 0 0 5px 0; text-align: center; color: #ccc;">Profit Breakdown</h4><div style="text-align:center; color: #888;">No games in this period</div>`;
                }
            }


            // 7. Handle Streak Breakdown
            const streakData = calculateStreakBreakdown(results);
            const listContainer = document.getElementById('rr-streak-list');
            const buildStreakTable = (data) => {
                let tableHTML = `<div style="display: grid; grid-template-columns: 1fr 1fr 1fr; text-align: center; font-size: 10px; color: #888; margin-bottom: 4px;"><span>Streak</span><span>Count</span><span>Freq.</span></div>`;
                if (data.length > 0) {
                    tableHTML += data.map(s => `
                    <div style="display: grid; grid-template-columns: 1fr 1fr 1fr; text-align: center; padding: 1px 0;">
                        <span>${s.length}</span>
                        <span>${s.count}x</span>
                        <span>${s.percentage}%</span>
                    </div>`).join('');
                } else {
                    tableHTML += `<div style="text-align:center; color: #888; padding: 5px 0;">No streaks recorded.</div>`;
                }
                return tableHTML;
            };

            if (listContainer) {
                if (streakBreakdownView === 'win') listContainer.innerHTML = buildStreakTable(streakData.winStreaks);
                else listContainer.innerHTML = buildStreakTable(streakData.lossStreaks);
            }

            // 8. Handle Lifetime Streaks
            const { maxWinStreak, maxLossStreak } = calculateLifetimeStreaks();
            const lifetimeStreaksDisplay = document.getElementById('rr-lifetime-streaks-display');
            if (lifetimeStreaksDisplay) {
                lifetimeStreaksDisplay.innerHTML = `
                <span title="Longest lifetime winning streak">🔥 Max W-Streak: <b>${maxWinStreak}</b></span>
                <span title="Longest lifetime losing streak">💀 Max L-Streak: <b>${maxLossStreak}</b></span>
                `;
            }

            // 9. Draw Chart
            const graphTooltipDisplay = document.getElementById('rr-graph-tooltip-display');
            rrChart = new RrChart(graphCanvas, dataPoints, graphTooltipDisplay);

            // 10. Update Active Buttons Style
            const tfContainer = statsDisplayPanel.querySelector('div:nth-child(4)') || timeframeContainer; 
            if(tfContainer) {
                tfContainer.querySelectorAll('button').forEach(btn => {
                    if (parseInt(btn.dataset.days, 10) === currentStatsTimeframe) {
                        btn.style.background = 'rgba(100, 180, 255, 0.3)';
                        btn.style.borderColor = '#64B4FF';
                    } else {
                        btn.style.background = 'rgba(255,255,255,0.1)';
                        btn.style.borderColor = '#555';
                    }
                });
            }
        }


        function processDataForGraph(timeframeInDays) {
            // 1. Setup Torn Time (UTC) Anchor
            const now = new Date();
            // We align everything to UTC because Torn Time is UTC.
            const currentYear = now.getUTCFullYear();
            const currentMonth = now.getUTCMonth();
            const currentDate = now.getUTCDate();
            
            // This will determine our window start/end
            let startTime, endTime;
            let rangeLabel = "";

            // 2. Calculate Calendar Windows based on Offset
            if (timeframeInDays === 1) {
                // --- DAY VIEW (Daily) ---
                // Start: 00:00 UTC of the target day
                const targetDate = new Date(Date.UTC(currentYear, currentMonth, currentDate + chartPageOffset));
                startTime = targetDate.getTime();
                
                // End: 23:59:59 UTC of the target day (Start of next day)
                const nextDate = new Date(Date.UTC(currentYear, currentMonth, currentDate + chartPageOffset + 1));
                endTime = nextDate.getTime();

                // Label: "Jan 15"
                rangeLabel = targetDate.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', timeZone: 'UTC' });

            } else if (timeframeInDays === 7) {
                // --- WEEK VIEW (Mon-Sun) ---
                // Find current Monday UTC
                // getUTCDay(): 0 is Sunday, 1 is Monday.
                let dayOfWeek = now.getUTCDay(); 
                if (dayOfWeek === 0) dayOfWeek = 7; // Make Sunday 7 so we can subtract easily
                const daysToMonday = dayOfWeek - 1;

                const startOfCurrentWeek = new Date(Date.UTC(currentYear, currentMonth, currentDate - daysToMonday));
                
                // Shift by offset weeks (offset * 7 days)
                const startOfTargetWeek = new Date(startOfCurrentWeek.getTime() + (chartPageOffset * 7 * 24 * 60 * 60 * 1000));
                
                startTime = startOfTargetWeek.getTime();
                endTime = startTime + (7 * 24 * 60 * 60 * 1000); // +7 Days

                // Label: "Jan 1 - Jan 7"
                const endLabelDate = new Date(endTime - 1);
                rangeLabel = `${startOfTargetWeek.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', timeZone: 'UTC' })} - ${endLabelDate.toLocaleDateString('en-GB', { day: 'numeric', month: 'short', timeZone: 'UTC' })}`;

            } else if (timeframeInDays === 30) {
                // --- MONTH VIEW (1st - 31st) ---
                // Start: 1st of Target Month
                const targetMonthDate = new Date(Date.UTC(currentYear, currentMonth + chartPageOffset, 1));
                startTime = targetMonthDate.getTime();
                
                // End: 1st of Next Month
                const nextMonthDate = new Date(Date.UTC(currentYear, currentMonth + chartPageOffset + 1, 1));
                endTime = nextMonthDate.getTime();

                // Label: "January 2024"
                rangeLabel = targetMonthDate.toLocaleDateString('en-GB', { month: 'long', year: 'numeric', timeZone: 'UTC' });

            } else if (timeframeInDays === 365) {
                // --- YEAR VIEW (Jan 1 - Dec 31) ---
                const targetYearDate = new Date(Date.UTC(currentYear + chartPageOffset, 0, 1));
                startTime = targetYearDate.getTime();
                
                const nextYearDate = new Date(Date.UTC(currentYear + chartPageOffset + 1, 0, 1));
                endTime = nextYearDate.getTime();
                
                rangeLabel = targetYearDate.toLocaleDateString('en-GB', { year: 'numeric', timeZone: 'UTC' });

            } else {
                // --- FALLBACK (Rolling Window for weird custom days) ---
                // Just use the old logic if user sets custom day count not matching 1, 7, 30, 365
                endTime = Date.now() + (chartPageOffset * timeframeInDays * 24 * 3600 * 1000);
                startTime = endTime - (timeframeInDays * 24 * 3600 * 1000);
                rangeLabel = "Custom Range";
            }

            // 3. Filter Results (Convert timestamps to ms for comparison)
            const filteredResults = results.filter(r => {
                const rTime = r.timestamp * 1000;
                return rTime >= startTime && rTime < endTime;
            });

            // 4. Build Data Points
            // Note: We need to sort by timestamp
            filteredResults.sort((a, b) => a.timestamp - b.timestamp);

            // We must find the "Profit at Start of Period".
            // To do this, we sum up ALL profit from the beginning of time up until 'startTime'.
            let profitAtStart = 0;
            // Iterate all results, stop when we hit our window
            for (const r of results) {
                if ((r.timestamp * 1000) >= startTime) break;
                profitAtStart += (r.result === 'win' ? r.bet : -r.bet);
            }

            let cumulativeProfit = profitAtStart;
            let wins = 0;
            let losses = 0;

            const dataPoints = filteredResults.map(game => {
                const profit = game.result === 'win' ? game.bet : -game.bet;
                cumulativeProfit += profit;
                if (profit > 0) wins++;
                else losses++;
                // Convert back to seconds for the Chart class if it expects seconds, 
                // OR keep milliseconds. Your existing RrChart likely expects SECONDS based on previous code.
                return { timestamp: game.timestamp, cumulativeProfit: cumulativeProfit };
            });

            // Add an initial point at the exact start time to make the graph look correct
            // (Start of the day/week with the starting profit)
            if (dataPoints.length > 0 || profitAtStart !== 0) {
                 dataPoints.unshift({ timestamp: startTime / 1000, cumulativeProfit: profitAtStart });
            }
            
            // If the period is empty but we have history, we still want a flat line
            if (filteredResults.length === 0 && results.length > 0) {
                 // Add end point so line draws across
                 dataPoints.push({ timestamp: endTime / 1000, cumulativeProfit: profitAtStart });
            }

            const summary = {
                totalProfit: cumulativeProfit - profitAtStart, // Profit made strictly IN this period
                wins: wins,
                losses: losses,
                totalGames: wins + losses,
                rangeLabel: rangeLabel // Pass label back for the UI
            };

            return { dataPoints, summary };
        }



        // ===================================================================
        // ================== DEFINITIVE CHARTING LOGIC ======================
        // ===================================================================

        class RrChart {
            constructor(canvas, data, tooltipElement) {
                this.canvas = canvas;
                this.ctx = canvas.getContext('2d');
                this.data = data;
                this.tooltipElement = tooltipElement; // The HTML div for our text
                this.padding = { top: 20, right: 15, bottom: 30, left: 55 };
                this.hoveredPoint = null;

                this.handleMouseMove = this.handleMouseMove.bind(this);
                this.handleMouseOut = this.handleMouseOut.bind(this);
                this.canvas.addEventListener('mousemove', this.handleMouseMove);
                this.canvas.addEventListener('mouseout', this.handleMouseOut);

                this.calculateScales();
                this.draw();
            }

            draw() {
                const { ctx, canvas } = this;
                ctx.clearRect(0, 0, canvas.width, canvas.height);

                if (this.data.length < 2) {
                    this.drawEmptyMessage('Not enough data for this period.');
                    return;
                }

                this.drawGridAndAxes();
                this.drawAreaAndLine();

                if (this.hoveredPoint) {
                    this.drawHoverHighlight(this.hoveredPoint);
                }
            }

            calculateScales() {
                const { data, padding, canvas } = this;
                if (this.data.length === 0) return;

                // Use a loop to find min/max, which is safer for large arrays
                let minProfit = Infinity, maxProfit = -Infinity;
                let minTimestamp = Infinity, maxTimestamp = -Infinity;

                for (const point of data) {
                    if (point.cumulativeProfit < minProfit) minProfit = point.cumulativeProfit;
                    if (point.cumulativeProfit > maxProfit) maxProfit = point.cumulativeProfit;
                    if (point.timestamp < minTimestamp) minTimestamp = point.timestamp;
                    if (point.timestamp > maxTimestamp) maxTimestamp = point.timestamp;
                }

                const range = maxProfit - minProfit;
                if (range === 0) {
                    maxProfit += 1000;
                    minProfit -= 1000;
                }

                this.maxProfit = Math.max(maxProfit + (maxProfit - minProfit) * 0.1, 0);
                this.minProfit = Math.min(minProfit - (maxProfit - minProfit) * 0.1, 0);
                this.minTimestamp = minTimestamp;
                this.maxTimestamp = maxTimestamp;

                const timeRange = this.maxTimestamp - this.minTimestamp;
                const profitRange = this.maxProfit - this.minProfit;

                this.mapX = (ts) => padding.left + (timeRange > 0 ? ((ts - this.minTimestamp) / timeRange) * (canvas.width - padding.left - padding.right) : 0);
                this.mapY = (profit) => canvas.height - padding.bottom - (profitRange > 0 ? ((profit - this.minProfit) / profitRange) * (canvas.height - padding.top - padding.bottom) : 0);
            }


            drawEmptyMessage(message) {
                const { ctx, canvas } = this;
                ctx.save();
                ctx.fillStyle = '#888';
                ctx.font = '14px monospace';
                ctx.textAlign = 'center';
                ctx.fillText(message, canvas.width / 2, canvas.height / 2);
                ctx.restore();
            }

            drawGridAndAxes() {
                const { ctx, padding, canvas } = this;
                const { width, height } = canvas;
                ctx.save();
                ctx.strokeStyle = '#444';
                ctx.lineWidth = 1;
                ctx.font = '10px monospace';
                ctx.fillStyle = '#aaa';
                const yLabelCount = 5;
                ctx.textAlign = 'right';
                ctx.textBaseline = 'middle';
                for (let i = 0; i <= yLabelCount; i++) {
                    const profitValue = this.minProfit + (i / yLabelCount) * (this.maxProfit - this.minProfit);
                    const y = this.mapY(profitValue);
                    ctx.fillText('$' + formatNumberToKMB(profitValue, 1), padding.left - 8, y);
                    ctx.beginPath();
                    ctx.moveTo(padding.left - 4, y);
                    ctx.lineTo(width - padding.right, y);
                    ctx.stroke();
                }
                ctx.textAlign = 'center';
                ctx.textBaseline = 'top';
                const xLabelCount = 2;
                for (let i = 0; i <= xLabelCount; i++) {
                    const timestamp = this.minTimestamp + (i / xLabelCount) * (this.maxTimestamp - this.minTimestamp);
                    const x = this.mapX(timestamp);
                    // If the tooltipElement is null, we know it's the simulator chart
                    let labelText;
                    if (this.tooltipElement === null) {
                        labelText = `Match ${Math.round(timestamp).toLocaleString()}`;
                    } else {
                        const date = new Date(timestamp * 1000);
                        labelText = date.toLocaleDateString();
                    }
                    ctx.fillText(labelText, x, height - padding.bottom + 5);
                    // --- END OF CHANGE ---
                }

                const zeroY = this.mapY(0);
                if (zeroY > padding.top && zeroY < height - padding.bottom) {
                    ctx.setLineDash([3, 4]);
                    ctx.strokeStyle = '#888';
                    ctx.beginPath();
                    ctx.moveTo(padding.left, zeroY);
                    ctx.lineTo(width - padding.right, zeroY);
                    ctx.stroke();
                    ctx.setLineDash([]);
                }
                ctx.restore();
            }

            drawAreaAndLine() {
                const { ctx, data, canvas } = this;
                const zeroY = this.mapY(0);
                ctx.save();
                const positivePath = new Path2D();
                positivePath.moveTo(this.mapX(data[0].timestamp), zeroY);
                data.forEach(p => {
                    const yPos = Math.min(this.mapY(p.cumulativeProfit), zeroY);
                    positivePath.lineTo(this.mapX(p.timestamp), yPos);
                });
                positivePath.lineTo(this.mapX(data[data.length - 1].timestamp), zeroY);
                positivePath.closePath();
                ctx.clip(positivePath);
                ctx.fillStyle = 'rgba(76, 175, 80, 0.4)';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.restore();
                ctx.save();
                const negativePath = new Path2D();
                negativePath.moveTo(this.mapX(data[0].timestamp), zeroY);
                data.forEach(p => {
                    const yPos = Math.max(this.mapY(p.cumulativeProfit), zeroY);
                    negativePath.lineTo(this.mapX(p.timestamp), yPos);
                });
                negativePath.lineTo(this.mapX(data[data.length - 1].timestamp), zeroY);
                negativePath.closePath();
                ctx.clip(negativePath);
                ctx.fillStyle = 'rgba(229, 57, 53, 0.5)';
                ctx.fillRect(0, 0, canvas.width, canvas.height);
                ctx.restore();
                ctx.save();
                ctx.lineWidth = 2;
                for (let i = 1; i < data.length; i++) {
                    const p1 = data[i - 1], p2 = data[i];
                    const x1 = this.mapX(p1.timestamp), y1 = this.mapY(p1.cumulativeProfit);
                    const x2 = this.mapX(p2.timestamp), y2 = this.mapY(p2.cumulativeProfit);
                    if (p1.cumulativeProfit * p2.cumulativeProfit < 0) {
                        const intersect_ts = p1.timestamp + (p2.timestamp - p1.timestamp) * (0 - p1.cumulativeProfit) / (p2.cumulativeProfit - p1.cumulativeProfit);
                        const x_intersect = this.mapX(intersect_ts), y_intersect = this.mapY(0);
                        ctx.beginPath();
                        ctx.moveTo(x1, y1);
                        ctx.lineTo(x_intersect, y_intersect);
                        ctx.strokeStyle = p1.cumulativeProfit >= 0 ? '#4CAF50' : '#E53935';
                        ctx.stroke();
                        ctx.beginPath();
                        ctx.moveTo(x_intersect, y_intersect);
                        ctx.lineTo(x2, y2);
                        ctx.strokeStyle = p2.cumulativeProfit >= 0 ? '#4CAF50' : '#E53935';
                        ctx.stroke();
                    } else {
                        ctx.beginPath();
                        ctx.moveTo(x1, y1);
                        ctx.lineTo(x2, y2);
                        ctx.strokeStyle = p1.cumulativeProfit >= 0 ? '#4CAF50' : '#E53935';
                        ctx.stroke();
                    }
                }
                ctx.restore();
            }

            drawHoverHighlight(point) {
                const { ctx, canvas, padding } = this;
                const x = this.mapX(point.timestamp);
                const y = this.mapY(point.cumulativeProfit);
                ctx.save();
                ctx.strokeStyle = 'rgba(255, 255, 255, 0.7)';
                ctx.setLineDash([3, 3]);
                ctx.beginPath();
                ctx.moveTo(x, y);
                ctx.lineTo(x, canvas.height - padding.bottom);
                ctx.stroke();
                ctx.setLineDash([]);
                ctx.beginPath();
                ctx.arc(x, y, 5);
                ctx.fillStyle = point.cumulativeProfit >= 0 ? '#4CAF50' : '#E53935';
                ctx.fill();
                ctx.strokeStyle = '#fff';
                ctx.lineWidth = 1.5;
                ctx.stroke();
                ctx.restore();
            }

            handleMouseMove(e) {
                const rect = this.canvas.getBoundingClientRect();
                const mouseX = (e.clientX - rect.left) / panelScale;
                if (mouseX < this.padding.left || mouseX > this.canvas.width - this.padding.right) {
                    this.handleMouseOut();
                    return;
                }
                let closestPoint = null;
                let minDistance = Infinity;
                this.data.forEach(point => {
                    const x = this.mapX(point.timestamp);
                    const distance = Math.abs(x - mouseX);
                    if (distance < minDistance) {
                        minDistance = distance;
                        closestPoint = point;
                    }
                });
                if (closestPoint && closestPoint !== this.hoveredPoint) {
                    this.hoveredPoint = closestPoint;
                    this.draw();
                    const profitColor = closestPoint.cumulativeProfit >= 0 ? '#4CAF50' : '#E53935';
                    const dateString = new Date(closestPoint.timestamp * 1000).toLocaleString('en-GB', { dateStyle: 'medium', timeStyle: 'short'}); // Using a clearer format
                    this.tooltipElement.innerHTML = `
                    <div style="font-weight: bold; color: ${profitColor};">Profit: $${closestPoint.cumulativeProfit.toLocaleString()}</div>
                    <div style="font-size: 11px; color: #999; margin-top: 4px;">${dateString}</div>
                `;
                    this.tooltipElement.style.display = 'block';
                    this.tooltipElement.style.opacity = '1';
                }
            }

            handleMouseOut() {
                if (this.hoveredPoint) {
                    this.hoveredPoint = null;
                    this.draw();
                    this.tooltipElement.style.opacity = '0';
                    this.tooltipElement.style.display = 'none';
                }
            }

            destroy() {
                this.canvas.removeEventListener('mousemove', this.handleMouseMove);
                this.canvas.removeEventListener('mouseout', this.handleMouseOut);
            }
        }


        /**
 * Draws the dual-axis graph for the Deep Simulation results.
 * @param {HTMLCanvasElement} canvas The canvas to draw on.
 * @param {object[]} data The results array from runDeepAnalysis.
 */
        function drawDeepAnalysisGraph(canvas, data) {
            const ctx = canvas.getContext('2d');
            ctx.clearRect(0, 0, canvas.width, canvas.height);

            if (!data || data.length < 2) {
                ctx.fillStyle = '#888';
                ctx.font = '14px monospace';
                ctx.textAlign = 'center';
                ctx.fillText('Not enough data to draw graph.', canvas.width / 2, canvas.height / 2);
                return;
            }

            const padding = { top: 30, right: 50, bottom: 30, left: 55 };

            // --- Calculate Scales (Dual Y-Axis) ---
            const xMin = data[0].limit;
            const xMax = data[data.length - 1].limit;

            const profitMax = Math.max(0, ...data.map(d => d.avgProfit));
            const profitMin = Math.min(0, ...data.map(d => d.avgProfit));

            const mapX = (limit) => padding.left + ((limit - xMin) / (xMax - xMin)) * (canvas.width - padding.left - padding.right);
            const mapYProfit = (profit) => canvas.height - padding.bottom - ((profit - profitMin) / (profitMax - profitMin)) * (canvas.height - padding.top - padding.bottom);
            const mapYBankRate = (rate) => canvas.height - padding.bottom - (rate / 100) * (canvas.height - padding.top - padding.bottom);

            // --- Draw Grid and Axes ---
            ctx.strokeStyle = '#444';
            ctx.lineWidth = 1;
            ctx.font = '10px monospace';

            // Left Y-Axis (Profit)
            ctx.fillStyle = '#aaa';
            ctx.textAlign = 'right';
            for (let i = 0; i <= 5; i++) {
                const profit = profitMin + (i / 5) * (profitMax - profitMin);
                const y = mapYProfit(profit);
                ctx.fillText('$' + formatNumberToKMB(profit, 1), padding.left - 8, y);
                ctx.beginPath();
                ctx.moveTo(padding.left, y);
                ctx.lineTo(canvas.width - padding.right, y);
                ctx.stroke();
            }

            // Right Y-Axis (Bankruptcy %)
            ctx.fillStyle = '#FF9800';
            ctx.textAlign = 'left';
            for (let i = 0; i <= 5; i++) {
                const rate = (i / 5) * 100;
                const y = mapYBankRate(rate);
                ctx.fillText(`${rate.toFixed(0)}%`, canvas.width - padding.right + 8, y);
            }

            // X-Axis (Limit)
            ctx.fillStyle = '#aaa';
            ctx.textAlign = 'center';
            data.forEach(d => {
                if (d.limit % 2 === 0 || data.length < 8) { // Label more if few points
                    const x = mapX(d.limit);
                    ctx.fillText(`L${d.limit}`, x, canvas.height - padding.bottom + 15);
                }
            });

            // --- Draw Profit Area Chart ---
            const zeroY = mapYProfit(0);
            ctx.beginPath();
            ctx.moveTo(mapX(data[0].limit), zeroY);
            data.forEach(d => ctx.lineTo(mapX(d.limit), mapYProfit(d.avgProfit)));
            ctx.lineTo(mapX(data[data.length - 1].limit), zeroY);
            ctx.closePath();
            ctx.save();
            ctx.clip();
            const grad = ctx.createLinearGradient(0, mapYProfit(profitMax), 0, mapYProfit(profitMin));
            grad.addColorStop(mapYProfit(0) / canvas.height, 'rgba(76, 175, 80, 0.4)');
            grad.addColorStop(mapYProfit(0) / canvas.height, 'rgba(229, 57, 53, 0.5)');
            ctx.fillStyle = grad;
            ctx.fillRect(0, 0, canvas.width, canvas.height);
            ctx.restore();

            // --- Draw Bankruptcy Rate Line Chart ---
            ctx.strokeStyle = '#FF9800';
            ctx.fillStyle = '#FF9800';
            ctx.lineWidth = 2;
            ctx.beginPath();
            data.forEach((d, i) => {
                const x = mapX(d.limit);
                const y = mapYBankRate(d.bankRate);
                if (i === 0) ctx.moveTo(x, y);
                else ctx.lineTo(x, y);
            });
            ctx.stroke();
            // Draw points on the line
            data.forEach(d => {
                ctx.beginPath();
                ctx.arc(mapX(d.limit), mapYBankRate(d.bankRate), 3, 0, Math.PI * 2);
                ctx.fill();
            });

            // --- Draw Legend ---
            ctx.fillStyle = '#aaa';
            ctx.font = '11px monospace';
            ctx.textAlign = 'left';
            ctx.fillText('Avg. Profit', padding.left, 15);
            ctx.fillStyle = '#FF9800';
            ctx.textAlign = 'right';
            ctx.fillText('Bankrupt %', canvas.width - padding.right, 15);
        }


        async function fetchAllLogsPaginated(logType, onStatusUpdate) {
            const allLogs = [];
            let currentToTimestamp = null;
            const stopTimestamp = Math.floor(Date.now() / 1000) - (36500 * 24 * 3600); // 100 years ago
            let pageCount = 0;

            while (true) {
                try {
                    // Update the UI if a callback is provided
                    if (onStatusUpdate) {
                        onStatusUpdate(`Fetching Log ${logType} (Page ${pageCount + 1})...`);
                    }

                    const batch = await fetchLogs(logType, currentToTimestamp);
                    const logsInBatch = Object.values(batch.log || {});
                    pageCount++;

                    for (const log of logsInBatch) {
                        if (log.timestamp >= stopTimestamp) {
                            allLogs.push(log);
                        }
                    }

                    if (logsInBatch.length < 100) {
                        console.log(`RR Tracker: Finished fetching log type ${logType}.`);
                        break;
                    }

                    let oldestTimestampInBatch = Math.min(...logsInBatch.map(log => log.timestamp));

                    if (!isFinite(oldestTimestampInBatch)) {
                        break;
                    }

                    // Small delay to be kind to the API
                    await new Promise(resolve => setTimeout(resolve, 200)); 
                    currentToTimestamp = oldestTimestampInBatch;

                } catch (error) {
                    console.error(`RR Tracker: Error fetching log type ${logType}.`, error);
                    break;
                }
            }
            return allLogs;
        }




        // This new, more powerful function replaces the old fetchLogsSince
        async function fetchAllLogsSince(fromTimestamp, logType) {
            // This new version completely removes the while() loop.
            // It will only fetch the very first "page" of up to 100 logs.
            try {
                const fromSeconds = Math.floor(fromTimestamp / 1000);

                // We call fetchLogPage ONCE and only once.
                // The 'to' parameter is null, which means "give me the most recent ones".
                const logsInBatch = await fetchLogPage(fromSeconds, null, logType);

                // We immediately return what we got, without looping for more.
                return logsInBatch;

            } catch (error) {
                // If the single request fails, log the error and return an empty array.
                console.error(`RR Tracker: Error during single-page (non-paginated) fetch for log type ${logType}.`, error);
                return [];
            }
        }


        // This is a new helper function used by the one above
        function fetchLogPage(from, to, logType) {
            let url = `https://api.torn.com/user/?selections=log&log=${logType}&from=${from}&key=${apiKey}`;
            if (to) {
                url += `&to=${to}`;
            }
            return new Promise((resolve, reject) => {
                GM.xmlHttpRequest({
                    method: "GET",
                    url: url,
                    onload: (response) => {
                        try {
                            const data = JSON.parse(response.responseText);
                            if (data.error) { reject(new Error(data.error.error)); }
                            else { resolve(Object.values(data.log || {})); }
                        } catch (e) { reject(new Error("Failed to parse API response.")); }
                    },
                    onerror: (err) => reject(new Error("Network request failed.")),
                    ontimeout: () => reject(new Error("Request timed out.")),
                });
            });
        }

        let syncInterval = null;
        function initiateSyncing() {
            if (syncInterval) clearInterval(syncInterval);
            if (!apiKey || apiKey.length < 16) {
                console.log("/*  */RR Tracker: No API key set, auto-sync disabled.");
                return;
            }

            // It now correctly uses our new global constant
            if (Date.now() - lastSyncTime > API_SYNC_INTERVAL_MS) {
                console.log("RR Tracker: Stale data detected, performing initial sync.");
                importApiData(true);
            }

            // The interval is now set correctly to a safe 60 seconds using the constant
            syncInterval = setInterval(() => importApiData(true), API_SYNC_INTERVAL_MS);

            // The log message is now dynamic and always accurate
            console.log(`RR Tracker: Auto-sync initiated for every ${API_SYNC_INTERVAL_MS / 1000} seconds.`);
        }

        /**
 * Clears all local game results and repopulates them by forcing a full "deep scan" from the Torn API.
 * This is a data-only reset; settings are not affected.
 */

        // --- DEEP SYNC ENGINE (Combined Stream) ---
        const DEEP_SYNC_KEY = 'rr_deep_sync_progress';

        async function processDeepSyncStep() {
            // 1. Load State
            const state = JSON.parse(localStorage.getItem(DEEP_SYNC_KEY));
            if (!state) return; 

            const btn = document.getElementById('rr-force-sync-btn');
            
            // 2. Update Button UI
            if (btn) {
                if (state.finished) {
                     btn.textContent = 'Sync Complete ✅';
                     btn.disabled = false;
                     setTimeout(() => btn.textContent = '🔄 Sync Now', 3000);
                     return;
                }
                btn.textContent = `Synced ${state.totalSynced} Matches...`;
                btn.disabled = true;
            }

            try {
                // 3. FETCH COMBINED DATA
                // We ask for BOTH log types at once: "8395,8396"
                // The API will give us the mixed 100 most recent items.
                const batch = await fetchLogPage(0, state.cursorTimestamp, "8395,8396");
                const rawLogs = Object.values(batch || {});

                if (rawLogs.length > 0) {
                    // 4. PARSE (Mixed List)
                    const newGames = rawLogs.map(log => {
                        let result = (log.log === 8395) ? 'win' : (log.log === 8396 ? 'lose' : null);
                        if (!result || !log.data || !log.data.pot) return null;

                        return {
                            result: result,
                            bet: log.data.pot / 2,
                            timestamp: log.timestamp,
                            origin: 'joined'
                        };
                    }).filter(g => g !== null);

                    // 5. UPDATE UI
                    if (newGames.length > 0) {
                        const existingTimestamps = new Set(results.map(r => r.timestamp));
                        const uniqueNew = newGames.filter(g => !existingTimestamps.has(g.timestamp));
                        
                        if (uniqueNew.length > 0) {
                            results = [...results, ...uniqueNew];
                            results.sort((a, b) => b.timestamp - a.timestamp); 
                            
                            // Stats & Graph
                            totalProfit = results.reduce((acc, game) => acc + (game.result === 'win' ? game.bet : -game.bet), 0);
                            saveResults();
                            saveTotalProfit();
                            refreshAll(); 
									  autoBet();
                            if (showStatsPanel) updateGraph();

                            // Update Counter
                            state.totalSynced += uniqueNew.length;
                        }
                    }

                    // 6. UPDATE CURSOR
                    // We just take the oldest timestamp from the mixed batch.
                    // Next call will ask for data OLDER than this.
                    const oldestInBatch = Math.min(...rawLogs.map(l => l.timestamp));
                    state.cursorTimestamp = oldestInBatch;
                    
                    localStorage.setItem(DEEP_SYNC_KEY, JSON.stringify(state));
                    
                    // Loop: 2 seconds
                    setTimeout(processDeepSyncStep, 2000);

                } else {
                    // 7. FINISHED
                    // If the API returns nothing, we have reached the end of history.
                    console.log("RR Tracker: Deep Sync Finished.");
                    state.finished = true;
                    localStorage.removeItem(DEEP_SYNC_KEY); // Done!
                    
                    if (btn) {
                        btn.textContent = 'Sync Complete ✅';
                        btn.disabled = false;
                        setTimeout(() => btn.textContent = '🔄 Sync Now', 3000);
                    }
                    importApiData(true); // Final standard check
                }

            } catch (error) {
                console.error("RR Tracker: Deep Sync Error", error);
                if (btn) btn.textContent = "Retrying...";
                setTimeout(processDeepSyncStep, 5000);
            }
        }



        async function forceFullResync() {
            // 1. Reset Memory
            localStorage.removeItem(DEEP_SYNC_KEY);

            if (!confirm("Start Deep Sync? This Will Trigger 1 API Call Every 2 Secounds(30/min). Matches appear LIVE.")) {
                return;
            }

            console.log("RR Tracker: Starting Combined Deep Sync...");
            
            // 2. Clear current data
            results = []; 
            totalProfit = 0;
            saveResults();
            refreshAll(); 

            // 3. Initialize Simple State
            // We only need ONE cursor now because the API mixes the data for us.
            const initialState = {
                cursorTimestamp: null,  // Where we are in history
                totalSynced: 0,         // Counter
                finished: false
            };
            
            localStorage.setItem(DEEP_SYNC_KEY, JSON.stringify(initialState));

            // 4. Kickstart
            processDeepSyncStep();
        }




        // ADD THIS ENTIRE NEW HELPER FUNCTION
        async function processLogsInChunks(logs, onProgress) {
            return new Promise(resolve => {
                const chunkSize = 500; // Process 500 log entries at a time
                let index = 0;
                const newlyProcessedGames = [];

                function processChunk() {
                    const chunkEnd = Math.min(index + chunkSize, logs.length);
                    const chunk = logs.slice(index, chunkEnd);

                    // This is the processing logic moved from your original function
                    const startGameIndices = [];
                    chunk.forEach((log, i) => {
                        if (log.log === 8392 || log.log === 8391) startGameIndices.push(i);
                    });

                    for (let i = 0; i < startGameIndices.length; i++) {
                        const startIndex = startGameIndices[i];
                        // Note: End index calculation needs to look at the original `logs` array for context
                        const absoluteStartIndex = index + startIndex;
                        let absoluteEndIndex = logs.length;
                        for(let k = absoluteStartIndex + 1; k < logs.length; k++) {
                            if (logs[k].log === 8392 || logs[k].log === 8391) {
                                absoluteEndIndex = k;
                                break;
                            }
                        }

                        const gameSlice = logs.slice(absoluteStartIndex, absoluteEndIndex);

                        let origin, result, bet, gameTimestamp;
                        if (gameSlice.length > 0) {
                            const startLog = gameSlice[0];
                            origin = startLog.log === 8392 ? 'created' : 'joined';
                            for (let j = 1; j < gameSlice.length; j++) {
                                const event = gameSlice[j];
                                if (event.log === 8395) { result = 'win'; bet = event.data.pot / 2; gameTimestamp = event.timestamp; }
                                else if (event.log === 8396) { result = 'lose'; bet = event.data.pot / 2; gameTimestamp = event.timestamp; }
                            }
                        }
                        if (result && gameTimestamp) {
                            newlyProcessedGames.push({ result, bet, timestamp: gameTimestamp, origin });
                        }
                    }
                    // End of moved logic

                    index += chunk.length; // Use actual chunk length to advance

                    if (typeof onProgress === 'function') {
                        onProgress(Math.round((index / logs.length) * 100));
                    }

                    if (index < logs.length) {
                        setTimeout(processChunk, 0); // Yield to the main thread before the next chunk
                    } else {
                        resolve(newlyProcessedGames);
                    }
                }
                processChunk();
            });
        }

        // --- AUTO BET CONTROLLER ---
        function autoBet() {
            // Only run if we are in Simple Mode
            if (bettingMode !== 'simple') return;

            // Check if Auto-features are enabled
            const isAutoNext = JSON.parse(localStorage.getItem(AUTO_NEXT_KEY) || 'false');
            const isAutoReset = JSON.parse(localStorage.getItem(AUTO_RESET_KEY) || 'false');
            
            // If neither is on, do nothing
            if (!isAutoNext && !isAutoReset) return;

            // 1. RUN THE STRATEGY ENGINE
            // We pass the full history (including the game that just finished)
            // The engine returns the mathematically correct NEXT step.
            const state = calculateCurrentState(results);
            
            // 2. APPLY THE RESULT
            // The engine handles ALL rules (Boost, Drain, Martingale) internally.
            // We just trust its output.
            simpleModeStep = state.step;

            // 3. SAVE & UPDATE UI
            localStorage.setItem(SIMPLE_STEP_KEY, simpleModeStep.toString());
            calculateBetsAndRefresh();
            
            console.log(`RR Tracker: AutoBet set Step to ${simpleModeStep + 1}. (Drain Active: ${state.isDrain})`);
        }


        // --- NEW: SIMULATION ENGINE ---

        function calculateCurrentState(games) {
            // --- 1. Settings ---
            const boostEnabled = JSON.parse(localStorage.getItem('rr_boostWins') || 'false');
            // Convert user 1-based inputs to 0-based indices
            const streakCap = parseInt(localStorage.getItem('rr_streakCap') || '4', 10) - 1; 
            const martingaleStart = parseInt(localStorage.getItem('rr_martingaleStart') || '2', 10) - 1; 

            // Drain Settings
            const drainEnabled = dynamicBetsSettings.drainEnabled === true;
            // dStart is the Index (e.g. Input 3 -> Index 2)
            const dStart = (parseInt(dynamicBetsSettings.drainStart) || 3) - 1; 
            const dReps = parseInt(dynamicBetsSettings.drainRepeats) || 4;

            // --- 2. State ---
            let boostStep = 0; 
            let lossStreak = 0; 
            let winStreak = 0; 
            
            let drainActive = false;
            let drainIndex = 0;
            
            // Flag to track what happened in the VERY LAST processed game
            let lastGameWasRetreat = false;

            // --- 3. History ---
            const history = games.slice(0, 200).reverse();

            for (let i = 0; i < history.length; i++) {
                const game = history[i];
                lastGameWasRetreat = false; // Reset flag for this turn

                // A. Planned Step
                let plannedStep = 0;
                if (lossStreak === 0) {
                    plannedStep = boostStep;
                } else {
                    if (boostEnabled && boostStep > martingaleStart) {
                        plannedStep = boostStep - 1; 
                    } else {
                        plannedStep = martingaleStart + lossStreak;
                    }
                }

                // B. Trigger Check
                // NEW CONDITION ADDED: (lossStreak + 1) <= (dStart + 1)
                // This ensures we only trigger if the current streak is <= the Drain Start setting.
                const triggerHit = (
                    drainEnabled && 
                    !drainActive && 
                    game.result === 'lose' && 
                    plannedStep >= dStart && 
                    (lossStreak + 1) <= (dStart + 1)
                );

                // C. Update Brain
                if (game.result === 'win') {
                    lossStreak = 0; 
                    winStreak++; 
                    if (boostEnabled) {
                        if (winStreak > 1) {
                            if (boostStep < streakCap) boostStep++;
                            else if (boostStep === streakCap) boostStep = Math.max(0, boostStep - 1);
                        } else {
                            boostStep = 0; 
                        }
                    } else {
                        boostStep = 0; 
                    }
                } 
                else { // LOSS
                    lossStreak++; 
                    winStreak = 0; 
                    
                    // RETREAT LOGIC (Any loss above floor triggers retreat)
                    if (boostEnabled && boostStep > martingaleStart) {
                        boostStep--;
                        lastGameWasRetreat = true; // Mark this turn as a retreat
                    }
                }

                // D. Drain Status Update
                if (drainActive) {
                    drainIndex++; 
                    if (drainIndex >= dReps) {
                        drainActive = false; 
                        drainIndex = 0;
                    }
                } else if (triggerHit) {
                    drainActive = true;
                    drainIndex = 1; 
                    if (dReps <= 1) { drainActive = false; drainIndex = 0; } 
                }
            }

            // --- 4. Final Output ---
            if (drainActive) {
                return { step: dStart + drainIndex, isDrain: true };
            }

            let finalStep = 0;
            if (lossStreak === 0) {
                finalStep = boostStep;
            } else {
                // If the last thing we did was retreat, we play the new retreated boostStep.
                // If we hit the floor (didn't retreat further), we Slingshot.
                if (boostEnabled && lastGameWasRetreat) {
                    finalStep = boostStep;
                } else {
                    finalStep = martingaleStart + lossStreak;
                }
            }

            return { step: finalStep, isDrain: false };
        }



        // --- HELPER: Parse a batch of raw logs into Game Objects ---
        function parseRawLogsToGames(logs) {
            const parsedGames = [];
            // Sort logs by timestamp to ensure correct game assembly
            logs.sort((a, b) => a.timestamp - b.timestamp);
            
            const startGameIndices = [];
            logs.forEach((log, index) => { 
                if (log.log === 8392 || log.log === 8391) startGameIndices.push(index); 
            });

            for (let i = 0; i < startGameIndices.length; i++) {
                const startIndex = startGameIndices[i];
                // Look ahead for the next start log to define the boundary
                const endIndex = (i + 1 < startGameIndices.length) ? startGameIndices[i + 1] : logs.length;
                
                const gameSlice = logs.slice(startIndex, endIndex);
                let origin, result, bet, gameTimestamp;

                if (gameSlice.length > 0) {
                    const startLog = gameSlice[0];
                    origin = startLog.log === 8392 ? 'created' : 'joined';
                    
                    for (let j = 1; j < gameSlice.length; j++) {
                        const event = gameSlice[j];
                        if (event.log === 8395) { 
                            result = 'win'; 
                            bet = event.data.pot / 2; 
                            gameTimestamp = event.timestamp; 
                        }
                        else if (event.log === 8396) { 
                            result = 'lose'; 
                            bet = event.data.pot / 2; 
                            gameTimestamp = event.timestamp; 
                        }
                    }
                }
                
                if (result && gameTimestamp) {
                    parsedGames.push({ result, bet, timestamp: gameTimestamp, origin });
                }
            }
            return parsedGames;
        }





        // ===================================================================
        // ============= THE FINAL, BULLETPROOF SYNC FUNCTION ================
        // ===================================================================


        async function importApiData(isSilent = false, forceOverride = false) {
            // 1. Stop if Deep Sync is running (prevents conflicts)
            if (localStorage.getItem(DEEP_SYNC_KEY)) {
                if (!isSilent) console.log("RR Tracker: Standard sync skipped (Deep Sync active).");
                return;
            }

            // 2. FIX: Unstick the flag if forced (Fixes "Already Synced" bug)
            if (forceOverride) {
                isSyncing = false;
            }

            if (isSyncing) {
                if (!isSilent) console.log("RR Tracker: Sync already in progress.");
                return;
            }
            
            if (!apiKey || apiKey.length < 16) {
                if (!isSilent) alert('Please check API key settings.');
                return;
            }

            // Update Button Text
            const btn = document.getElementById('rr-force-sync-btn');
            if (btn && forceOverride) {
                btn.textContent = 'Checking...';
                btn.disabled = true;
            }

            const isInitialSync = !lastSyncTime || (Date.now() - lastSyncTime > 6 * 3600 * 1000) || forceOverride;
            let allRawLogs = [];

            try {
                isSyncing = true;
                if (!isSilent) document.body.style.cursor = 'wait';

                if (isInitialSync) {
                    // Full/Deep Scan logic (Paginated)
                    const updateSyncButton = (text) => { if (btn) btn.textContent = text; };
                    const logPromises = [8392, 8391, 8395, 8396].map(logType => 
                        fetchAllLogsPaginated(logType, (msg) => updateSyncButton(msg))
                    );
                    updateSyncButton("Downloading history...");
                    const allLogsArrays = await Promise.all(logPromises);
                    allRawLogs = [].concat(...allLogsArrays);
                } else {
                    // Standard "Quick Sync" logic (Last 1 hour)
                    const oneHourInMs = 60 * 60 * 1000;
                    const syncStartTime = lastSyncTime ? (lastSyncTime - oneHourInMs) : (Date.now() - oneHourInMs * 24);
                    
                    const logPromises = [8392, 8391, 8395, 8396].map(logType => fetchAllLogsSince(syncStartTime, logType));
                    const allLogsArrays = await Promise.all(logPromises);
                    allRawLogs = [].concat(...allLogsArrays);
                }

                if (allRawLogs.length > 0) {
                    // Use the helper to process logs into games
                    const newGames = parseRawLogsToGames(allRawLogs);
                    const existingTimestamps = new Set(results.map(r => r.timestamp));
                    const uniqueNew = newGames.filter(g => !existingTimestamps.has(g.timestamp));

                    if (uniqueNew.length > 0) {
                        console.log(`RR Tracker: Found ${uniqueNew.length} new games.`);
                        
                        // 1. Update Results
                        results = [...results, ...uniqueNew];
                        results.sort((a, b) => b.timestamp - a.timestamp);
                        
                        // 2. Update Stats
                        totalProfit = results.reduce((acc, game) => acc + (game.result === 'win' ? game.bet : -game.bet), 0);
                        if (isSessionActive) {
                            const sessionGames = results.filter(r => r.timestamp * 1000 >= sessionStartDate);
                            sessionProfit = sessionGames.reduce((acc, game) => acc + (game.result === 'win' ? game.bet : -game.bet), 0);
                        }

                        // 3. Save Everything
                        saveResults();
                        saveTotalProfit();
                        saveSessionState();

                        // 4. TRIGGER AUTO-BET (Crucial Step)
                        // This uses the NEW history to calculate the correct next step
                        if (typeof autoBet === 'function') {
                            autoBet(); 
                        }

                        // 5. Refresh UI
                        calculateBets();
                        refreshAll();
                    }
                }
                
                lastSyncTime = Date.now();
                localStorage.setItem(LAST_SYNC_KEY, lastSyncTime.toString());

            } catch (error) {
                console.error("RR Tracker: Sync Error", error);
            } finally {
                isSyncing = false;
                if (!isSilent) document.body.style.cursor = '';
                if (btn) {
                    btn.textContent = '🔄 Sync Now';
                    btn.disabled = false;
                }
            }
        }


        function loadManualBets() {
            try {
                const storedJson = localStorage.getItem(MANUAL_BETS_STORAGE_KEY);
                if (storedJson) {
                    const parsed = JSON.parse(storedJson);
                    if (Array.isArray(parsed)) return parsed;
                }
            } catch (e) { console.error("Error parsing stored manual bets:", e); }
            return [...DEFAULT_MANUAL_BETS];
        }

        function adjustManualBetsArray(bets) {
            const currentLength = bets.length;
            if (currentLength === 16) return bets;

            if (currentLength < 16) {
                const lastValue = currentLength > 0 ? bets[currentLength - 1] : 10000;
                for (let i = currentLength; i < 16; i++) {
                    bets.push(lastValue * Math.pow(2, i - currentLength + 1));
                }
            } else {
                bets = bets.slice(0, 16);
            }
            return bets;
        }


        function buildManualBetInputs() {
            manualEditGrid.innerHTML = '';
            manualEditInputs = [];
            for (let i = 0; i < 16; i++) {
                const label = document.createElement('label');
                label.textContent = `Bet ${i + 1}:`;
                Object.assign(label.style, { fontSize: '13px', paddingTop: '4px' });
                manualEditGrid.appendChild(label);

                const input = document.createElement('input');
                input.type = 'text';
                input.placeholder = 'e.g., 10k';
                input.title = `Set the manual bet amount for UI button ${i + 1}.`;
                Object.assign(input.style, { width: '80px', padding: '4px', border: '1px solid #555', borderRadius: '4px', background: 'rgba(255,255,255,0.1)', color: '#fff' });

                input.dataset.index = i;
                input.onchange = (e) => {
                    const index = parseInt(e.target.dataset.index, 10);
                    const parsed = parseBetInput(e.target.value);
                    if (parsed !== null) {
                        manualBets[index] = parsed;
                        saveManualBets();
                        e.target.value = formatNumberToKMB(parsed);
                        calculateBetsAndRefresh();
                    } else if (e.target.value !== '') {
                        alert('Invalid input. Please use numbers or suffixes like K/M/B (e.g., 25k, 2.5m).');
                        e.target.value = formatNumberToKMB(manualBets[index]);
                    }
                };
                manualEditGrid.appendChild(input);
                manualEditInputs.push(input);
            }
        }
        buildManualBetInputs();
        // New helper: Only puts the number in the box (Does not click Start)
        function injectBetOnly(amount) {
            const inputBox = document.querySelector('input[aria-label="Money value"]');
            if (inputBox) {
                const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;
                nativeSet.call(inputBox, amount.toLocaleString('en-US'));
                inputBox.dispatchEvent(new Event('input', { bubbles: true }));
                inputBox.dispatchEvent(new Event('change', { bubbles: true }));
            }
        }
        function startMatch(originalButtonBetValue) {
            const inputBox = document.querySelector('input[aria-label="Money value"]');

            // --- SCENARIO 1: CREATING A NEW GAME ---
            if (inputBox) {
                // 1. Inject the value into React
                const nativeSet = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;
                nativeSet.call(inputBox, originalButtonBetValue.toLocaleString('en-US'));
                inputBox.dispatchEvent(new Event('input', { bubbles: true }));
                inputBox.dispatchEvent(new Event('change', { bubbles: true }));

                // 2. Safety Check
                const betAfterInputSet = parseBetInput(inputBox.value);
                if (betAfterInputSet === null || betAfterInputSet <= 0) {
                    alert("Invalid bet amount.");
                    return;
                }
                if (betAfterInputSet < originalButtonBetValue) {
                    alert(`Bet mismatch. Box has ${betAfterInputSet}, button was ${originalButtonBetValue}.`);
                    return;
                }

                // 3. Click the "Start" Button
                const startButton = document.querySelector('button.submit___Yr2z1');
                if (startButton) {
                    startButton.click();

                    // 4. THE FIX: Auto-Confirm Logic
                    // We must wait a tiny bit (400ms) for the "Are you sure?" popup to render
                    setTimeout(() => {
                        // Look for the "Yes" button.
                        // 'button___QgVxd' is the standard class Torn uses for primary confirmation buttons.
                        const confirmButton = document.querySelector('button.button___QgVxd');
                        if (confirmButton) {
                            confirmButton.click();
                        }
                    }, 400);
                }
                // Fallback: If start button not found, look for Close/Error buttons
                else {
                    const closeButton = document.querySelector('button.button___aQaRr');
                    if (closeButton) closeButton.click();
                }
            }
            // --- SCENARIO 2: JOINING AN EXISTING GAME ---
            else {
                const yesButton = document.querySelector('button.button___QgVxd');
                if (yesButton) {
                    yesButton.click();
                } else {
                    const closeButton = document.querySelector('button.button___aQaRr');
                    if (closeButton) closeButton.click();
                }
            }
        }


        function getSumOfRatios(L, M, reinforce, numCoeffs, boosted, drainSettings) {
            // drainSettings: { enabled: bool, start: int, repeats: int }
            if (numCoeffs <= 0 || M <= 1) return { sum: 0, coeffs: [] };
            
            const allCoeffs = [];
            let currentSum = 0;

            // Robustly get intervals, ensuring they are numbers
            let rInterval = parseInt(dynamicBetsSettings.reinforceInterval);
            if (isNaN(rInterval) || rInterval < 1) rInterval = 2;

            let bInterval = parseInt(dynamicBetsSettings.boostInterval);
            if (isNaN(bInterval) || bInterval < 1) bInterval = 5;

            // Prepare Drain indices
            const dEnabled = drainSettings && drainSettings.enabled;
            const dStart = (drainSettings && drainSettings.start) ? drainSettings.start - 1 : -1;
            const dEnd = dStart + (drainSettings ? drainSettings.repeats : 0);

            for (let i = 0; i < numCoeffs; i++) {
                let currentCoeff;
                const betNumber = i + 1;

                // --- LOGIC TREE ---

                // 1. DRAIN MODE (Flat)

	if (dEnabled && i > dStart && i < dEnd) {
    currentCoeff = allCoeffs[dStart]; 
	}


                // 2. DRAIN MODE (Recovery Jump)
                else if (dEnabled && i === dEnd) {
                    currentCoeff = currentSum * M;
                }
                // 3. REINFORCE LOGIC
                // (Only active if 'reinforce' is checked AND we are at the correct interval step)
                // Note: We use (betNumber - 1) so that for interval 2, we hit steps 3, 5, 7...
                // This ensures we have a valid history (Step 1) to look back on.
                else if (reinforce && betNumber > 1 && (betNumber - 1) % rInterval === 0) {
                     const reinforcementCoeff = allCoeffs[i - rInterval] || 0;
                     currentCoeff = (M * allCoeffs[i - 1]) + reinforcementCoeff;
                }
                // 4. STANDARD MARTINGALE (Default)
                else {
                    if (i === 0) currentCoeff = 1;
                    else currentCoeff = allCoeffs[i - 1] * M;
                }

                // --- BOOST LOGIC ---
                // Applies to ALL modes except the flat Drain phase
                const isDrainFlatPhase = (dEnabled && i > dStart && i < dEnd);
                if (boosted && !isDrainFlatPhase && (betNumber % bInterval === 0)) {
                    currentCoeff *= 2;
                }

                allCoeffs.push(currentCoeff);
                currentSum += currentCoeff;
            }

            const sum = allCoeffs.slice(0, L).reduce((acc, val) => acc + val, 0);
            return { sum, coeffs: allCoeffs };
        }

        function formatNumberToKMB(num, decimals = 2) {
            if (num === null || isNaN(num)) return '';
            if (num === 0) return '0';

            const sign = num < 0 ? "-" : "";
            const absNum = Math.abs(num);

            const lookup = [
                { value: 1e9,  symbol: "b" },
                { value: 1e6,  symbol: "m" },
                { value: 1e3,  symbol: "k" }
            ];

            const item = lookup.find(item => absNum >= item.value);

            if (item) {
                // For billions, use 3 decimal places, otherwise use the default.
                const effectiveDecimals = item.symbol === 'b' ? 3 : decimals;
                // Use .replace to remove trailing zeros from the decimal part
                const formatted = (absNum / item.value).toFixed(effectiveDecimals).replace(/\.?0+$/, "");
                return sign + formatted + item.symbol;
            }

            return num.toLocaleString();
        }

function calculateBetsAndRefresh() {
            calculateBets();
            refreshAll();
        }

        function parseBetInput(str) {
            if (typeof str !== 'string') str = String(str);
            str = str.toLowerCase().replace(/,/g, '').trim();
            let m = 1;
            if (str.endsWith('k')) { m = 1e3; str = str.slice(0, -1); }
            else if (str.endsWith('m')) { m = 1e6; str = str.slice(0, -1); }
            else if (str.endsWith('b')) { m = 1e9; str = str.slice(0, -1); }
            let v = parseFloat(str);
            return (isNaN(v) || v < 0) ? null : Math.floor(v * m);
        }

        function getBetForStep(stepIndex) {
            if (bettingMode === 'manual') return manualBets[stepIndex] || 0;

            const { capital, martingaleValue, reinforce, boostedBets, lockedField } = dynamicBetsSettings;

            // --- FIX: Define Drain Settings Here ---
            const drainSettings = {
                enabled: dynamicBetsSettings.drainEnabled === true,
                start: parseInt(dynamicBetsSettings.drainStart) || 3,
                repeats: parseInt(dynamicBetsSettings.drainRepeats) || 4
            };

            // Pass drainSettings to the calculator
            const { sum, coeffs } = getSumOfRatios(
                stepIndex + 1, 
                martingaleValue, 
                reinforce, 
                stepIndex + 1, 
                boostedBets, 
                drainSettings // <--- PASSED HERE
            );

            let startingBet = dynamicBetsSettings.startingBet;

            if (lockedField === 'capital') {
                // For capital lock, we still need a reference sum. 
                // We use the full 16-step calculation to keep the base unit consistent.
                const standardCalc = getSumOfRatios(
                    dynamicBetsSettings.maxLStreak, 
                    martingaleValue, 
                    reinforce, 
                    16, 
                    boostedBets,
                    drainSettings // <--- AND HERE
                );
                startingBet = Math.floor(capital / standardCalc.sum);
            }

            const multiplier = coeffs[stepIndex];
            return Math.floor(startingBet * multiplier);
        }



                function calculateBets() {
            if (dynamicBetsEnabled) {
                const { capital, maxLStreak, martingaleValue, reinforce, lockedField } = dynamicBetsSettings;
                let startingBet = dynamicBetsSettings.startingBet;
                const numCoeffsToGenerate = 16;

                // Explicitly construct the settings object
                const drainSettings = {
                    enabled: dynamicBetsSettings.drainEnabled === true,
                    start: parseInt(dynamicBetsSettings.drainStart) || 3,
                    repeats: parseInt(dynamicBetsSettings.drainRepeats) || 4
                };

                const { sum, coeffs } = getSumOfRatios(
                    maxLStreak, 
                    martingaleValue, 
                    reinforce, 
                    numCoeffsToGenerate, 
                    dynamicBetsSettings.boostedBets, 
                    drainSettings
                );

                if (lockedField === 'capital') {
                    startingBet = (sum > 0) ? Math.floor(capital / sum) : 0;
                    dynamicBetsSettings.startingBet = startingBet;
                } else {
                    dynamicBetsSettings.capital = Math.floor(startingBet * sum);
                }

                currentBets = [];
                for (let i = 0; i < coeffs.length; i++) {
                    const betValue = Math.floor(startingBet * coeffs[i]);
                    currentBets.push(betValue);
                }
            } else {
                currentBets = [...manualBets];
            }
        }



        

        function buildBetButtons() {
            // 1. Clear containers
            mainBetGridContainer.innerHTML = '';
            miniBetGridContainer.innerHTML = '';
            const circlesContainer = document.getElementById('rr-mini-circles-container');
            if (circlesContainer) circlesContainer.innerHTML = '';

            // 2. VISIBILITY CHECK
            // Only show the main grid if we are NOT in settings, stats, simulator, or collapsed.
            const isMainViewActive = (!isMinimized && !collapsed && !showSettings && !showStatsPanel && !showSimulatorPanel && !showEditBetsPanel);
            // Stop-Loss Check
            if (isStopLossActive) {
                mainBetGridContainer.innerHTML = `<div style="text-align:center; padding: 10px; color: #ff7a7a;">Daily loss limit reached.</div>`;
                miniBetGridContainer.innerHTML = `<div style="text-align:center; font-size:10px; color: #ff7a7a;">STOP LOSS</div>`;
                mainBetGridContainer.style.display = isMainViewActive ? 'block' : 'none';
                return;
            }

            // --- A. SIMPLE MODE (4 Buttons) ---
            if (bettingMode === 'simple') {
                const currentBetAmount = getBetForStep(simpleModeStep);
                const formattedBet = formatNumberToKMB(currentBetAmount);

                // ==============================
                // 1. MAIN PANEL (Full Size)
                // ==============================
                mainBetGridContainer.style.display = isMainViewActive ? 'flex' : 'none';
                mainBetGridContainer.style.flexDirection = 'column';
                mainBetGridContainer.style.gap = '8px';

                // Info Text
                const infoDiv = document.createElement('div');
                infoDiv.innerHTML = `Step: <b style="color: #fff">${simpleModeStep + 1}</b>`;
                infoDiv.style.textAlign = 'center';
                infoDiv.style.fontSize = '12px';
                infoDiv.style.color = '#ccc';
                mainBetGridContainer.appendChild(infoDiv);

                const btnRow = document.createElement('div');
                Object.assign(btnRow.style, { display: 'flex', gap: '5px' });

                // Main Buttons
                const prevBtn = document.createElement('button');
                prevBtn.textContent = '◀';
                Object.assign(prevBtn.style, { padding: '10px', background: '#333', color: '#fff', border: '1px solid #555', borderRadius: '6px', cursor: 'pointer' });
                prevBtn.onclick = () => { if (simpleModeStep > 0) { simpleModeStep--; localStorage.setItem(SIMPLE_STEP_KEY, simpleModeStep.toString()); refreshAll(); }};

                const betBtn = document.createElement('button');
                betBtn.innerHTML = `<span style="font-size:11px; display:block; color:#aaa;">SET BET</span><span style="font-size:15px; font-weight:bold;">$${formattedBet}</span>`;
                Object.assign(betBtn.style, { flex: '1', padding: '6px', background: 'rgba(255,255,255,0.1)', color: '#fff', border: '1px solid #777', borderRadius: '6px', cursor: 'pointer' });
                betBtn.onclick = () => injectBetOnly(currentBetAmount);

                const startBtn = document.createElement('button');
                startBtn.textContent = '🚀';
                Object.assign(startBtn.style, { padding: '0 15px', background: '#4CAF50', color: '#fff', border: 'none', borderRadius: '6px', cursor: 'pointer', fontSize: '18px' });
                startBtn.onclick = () => startMatch(currentBetAmount);

                const nextBtn = document.createElement('button');
                nextBtn.textContent = '▶';
                Object.assign(nextBtn.style, { padding: '10px', background: '#333', color: '#fff', border: '1px solid #555', borderRadius: '6px', cursor: 'pointer' });
                nextBtn.onclick = () => { simpleModeStep++; localStorage.setItem(SIMPLE_STEP_KEY, simpleModeStep.toString()); refreshAll(); };

                btnRow.append(prevBtn, betBtn, startBtn, nextBtn);
                mainBetGridContainer.appendChild(btnRow);

                // Reset Button
                const resetRow = document.createElement('div');
                const resetBtn = document.createElement('button');
                resetBtn.textContent = "Reset to Start";
                Object.assign(resetBtn.style, { width: '100%', padding: '4px', background: 'rgba(255,255,255,0.1)', border: '1px solid #444', borderRadius: '4px', color: '#ccc', cursor: 'pointer', fontSize: '11px' });
                resetBtn.onclick = () => { simpleModeStep = 0; localStorage.setItem(SIMPLE_STEP_KEY, simpleModeStep.toString()); refreshAll(); };
                resetRow.appendChild(resetBtn);
                mainBetGridContainer.appendChild(resetRow);

                // ==============================
                // 2. MINI PANEL (Compact 4 Buttons)
                // ==============================
                miniBetGridContainer.style.display = 'flex'; // Use flex instead of grid
                miniBetGridContainer.style.gap = '3px';

                // Mini Prev
                const mPrev = document.createElement('button');
                mPrev.textContent = '◀';
                Object.assign(mPrev.style, { padding: '2px 6px', background: '#333', color: '#fff', border: '1px solid #555', borderRadius: '4px', cursor: 'pointer', fontSize: '10px' });
                mPrev.onclick = prevBtn.onclick;

                // Mini Set (Shows Amount)
                const mSet = document.createElement('button');
                mSet.textContent = formattedBet;
                Object.assign(mSet.style, { flex: '1', padding: '2px', background: 'rgba(255,255,255,0.1)', color: '#fff', border: '1px solid #777', borderRadius: '4px', cursor: 'pointer', fontSize: '11px', fontWeight: 'bold' });
                mSet.onclick = betBtn.onclick;

                // Mini Start
                const mStart = document.createElement('button');
                mStart.textContent = '🚀';
                Object.assign(mStart.style, { padding: '2px 6px', background: '#4CAF50', color: '#fff', border: 'none', borderRadius: '4px', cursor: 'pointer', fontSize: '12px' });
                mStart.onclick = startBtn.onclick;

                // Mini Next
                const mNext = document.createElement('button');
                mNext.textContent = '▶';
                Object.assign(mNext.style, { padding: '2px 6px', background: '#333', color: '#fff', border: '1px solid #555', borderRadius: '4px', cursor: 'pointer', fontSize: '10px' });
                mNext.onclick = nextBtn.onclick;

                miniBetGridContainer.append(mPrev, mSet, mStart, mNext);

            }
            // --- B. GRID MODES (Manual/Dynamic) ---
            else {
                // Set Layout
                mainBetGridContainer.style.display = isMainViewActive ? 'grid' : 'none';
                mainBetGridContainer.style.gridTemplateColumns = 'repeat(4, 1fr)';
                mainBetGridContainer.style.gap = '4px';

                // Restore Mini Grid to 4 columns for the 16-button layout
                miniBetGridContainer.style.display = 'grid';
                miniBetGridContainer.style.gridTemplateColumns = 'repeat(4, 1fr)';
                miniBetGridContainer.style.gap = '3px';

                if (!currentBets || currentBets.length === 0) return;

                // Calculate Highlight
                let losingStreak = 0;
                for (const r of results) { if (r.result === 'lose') losingStreak++; else break; }
                const highlightIndex = losingStreak > 0 ? losingStreak : -1;

                // Generate 16 Buttons
                for (let i = 0; i < 16; i++) {
                    const bet = currentBets[i];
                    const formattedBet = formatNumberToKMB(bet);

                    // 1. MAIN Button
                    const mainBtn = document.createElement('button');
                    mainBtn.textContent = formattedBet;
                    mainBtn.title = `$${bet.toLocaleString()}`;
                    Object.assign(mainBtn.style, {
                        background: 'rgba(255,255,255,0.08)', color: '#fff', border: '1px solid #444',
                        borderRadius: '6px', padding: '4px 2px', cursor: 'pointer', fontSize: '11px'
                    });
                    mainBtn.onmouseenter = () => { if (!mainBtn.classList.contains('next-bet-highlight')) mainBtn.style.background = 'rgba(255,255,255,0.2)'; };
                    mainBtn.onmouseleave = () => { if (!mainBtn.classList.contains('next-bet-highlight')) mainBtn.style.background = 'rgba(255,255,255,0.08)'; };
                    mainBtn.onclick = () => startMatch(bet);
                    if (i === highlightIndex) mainBtn.classList.add('next-bet-highlight');
                    mainBetGridContainer.appendChild(mainBtn);

                    // 2. MINI Button
                    const miniBtn = document.createElement('button');
                    miniBtn.textContent = formattedBet;
                    Object.assign(miniBtn.style, {
                        background: 'rgba(255,255,255,0.08)', color: '#fff', border: '1px solid #444',
                        borderRadius: '4px', padding: '2px', cursor: 'pointer', fontSize: `${miniButtonSize}px`
                    });
                    miniBtn.onclick = () => startMatch(bet);
                    if (i === highlightIndex) miniBtn.classList.add('next-bet-highlight');
                    miniBetGridContainer.appendChild(miniBtn);
                }
            }

            // Common: Populate circles in mini bar
            if (circlesContainer) {
                results.slice(0, miniBarCount).forEach((r, idx) => circlesContainer.append(makeCircle(r.result, r.bet, idx)));
            }
        }

        const makeCircle = (result, bet, index) => {
            const container = document.createElement('span');
            Object.assign(container.style, { display: 'inline-block', width: '14px', height: '14px', borderRadius: '50%', backgroundColor: result === 'win' ? '#4CAF50' : '#E53935', marginRight: '2px', cursor: 'pointer', position: 'relative' });
            container.title = `${result.toUpperCase()}: $${bet.toLocaleString()}`;
            container.addEventListener('click', (e) => {
                e.stopPropagation();
                if (isDragging || isTwoFingerDragging) return;

                const existingPopup = document.querySelector('.rr-temp-popup');
                if (existingPopup) existingPopup.remove();

                const tempPopup = document.createElement('div');
                tempPopup.classList.add('rr-temp-popup');
                tempPopup.textContent = `${result.toUpperCase()}: $${bet.toLocaleString()}`;
                Object.assign(tempPopup.style, {
                    position: 'fixed',
                    background: 'rgba(0,0,0,0.9)',
                    border: '1px solid #555',
                    color: 'white',
                    padding: '4px 8px',
                    borderRadius: '4px',
                    fontSize: '12px',
                    whiteSpace: 'nowrap',
                    zIndex: '99999999',
                    pointerEvents: 'none',
                    opacity: '0',
                    transition: 'opacity 0.2s ease-in-out, top 0.2s ease-in-out'
                });

                document.body.appendChild(tempPopup);

                const rect = container.getBoundingClientRect();
                tempPopup.style.left = `${rect.left + (rect.width / 2) - (tempPopup.offsetWidth / 2)}px`;
                tempPopup.style.top = `${rect.top - tempPopup.offsetHeight - 5}px`;

                setTimeout(() => {
                    tempPopup.style.opacity = '1';
                    tempPopup.style.top = `${rect.top - tempPopup.offsetHeight - 8}px`;
                }, 10);

                setTimeout(() => {
                    tempPopup.style.opacity = '0';
                    setTimeout(() => {
                        if (document.body.contains(tempPopup)) {
                            document.body.removeChild(tempPopup);
                        }
                    }, 200);
                }, 1800);
            });
            return container;
        };



        function updateStatus() { statusDiv.textContent = collapsed ? '▪' : '►'; }

        function updatePanelVisibility() {
            panel.style.display = 'flex';
        }


        // --- NEW HELPER: Calculates streak but enforces "Sticky" drain logic ---
        function calculateEffectiveStreak(games, drainSettings) {
            // If Drain is disabled, use standard "count consecutive losses backwards" logic
            if (!drainSettings || !drainSettings.enabled) {
                let l = 0;
                for (const r of games) { if (r.result === 'lose') l++; else break; }
                return l;
            }

            // If Drain is enabled, we must simulate forward to account for "ignored wins"
            const dStart = (drainSettings.start || 1) - 1; // Convert 1-based to 0-based
            const dReps = drainSettings.repeats || 0;
            const dEnd = dStart + dReps;

            // Take the last 200 games and reverse them (Oldest -> Newest) to simulate the session
            // We limit to 200 for performance; this is plenty to find a "reset" point.
            const history = games.slice(0, 200).reverse();

            let currentStep = 0;

            for (const game of history) {
                // LOGIC: Are we currently inside the "Drain Zone"?
                // If yes, we stick to the plan (increment step) regardless of Win/Loss.
                if (currentStep >= dStart && currentStep < dEnd) {
                    currentStep++; 
                } 
                // LOGIC: We are outside the Drain Zone (Standard Martingale)
                else {
                    if (game.result === 'win') {
                        currentStep = 0; // Reset on Win
                    } else {
                        currentStep++; // Increment on Loss
                    }
                }
            }
            
            return currentStep;
        }


        // --- NEW SHOOT BUTTON LOGIC (Strict Validation) ---
        
        // 1. Inject CSS for Flashes
        const rrFlashStyle = document.createElement('style');
        rrFlashStyle.type = "text/css";
        rrFlashStyle.innerText = `
            @keyframes rr-success-flash { 0% { background-color: rgba(76, 175, 80, 0.5); } 100% { background-color: transparent; } }
            @keyframes rr-fail-flash { 0% { background-color: rgba(229, 57, 53, 0.5); } 100% { background-color: transparent; } }
            .rr-flash-green { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 2147483647; animation: rr-success-flash 0.5s ease-out forwards; }
            .rr-flash-red { position: fixed; top: 0; left: 0; width: 100vw; height: 100vh; pointer-events: none; z-index: 2147483647; animation: rr-fail-flash 0.5s ease-out forwards; }
        `;
        document.head.appendChild(rrFlashStyle);

        // 2. Create the Buttons (Standardized Design)
        
        // --- BUTTON 1 (x1) ---
        const shootGlobalBtn = document.createElement('button');
        shootGlobalBtn.innerHTML = 'x1'; // Default placeholder
        shootGlobalBtn.title = "Instantly shoot 1 round.";
        Object.assign(shootGlobalBtn.style, {
            background: '#E53935', color: '#fff', border: '1px solid #b71c1c', 
            borderRadius: '4px', cursor: 'pointer', fontWeight: 'bold',
            fontSize: '11px', padding: '3px 0', flex: '1', // Matches x2/x3 exactly
            display: 'none', textAlign: 'center'
        });

        // --- BUTTON 2 (x2) ---
        const shoot2Btn = document.createElement('button');
        shoot2Btn.innerHTML = 'x2';
        shoot2Btn.title = "Instantly shoot 2 rounds.";
        Object.assign(shoot2Btn.style, {
            background: '#C62828', color: '#fff', border: '1px solid #8E0000', 
            borderRadius: '4px', cursor: 'pointer', fontWeight: 'bold',
            fontSize: '11px', padding: '3px 0', flex: '1',
            display: 'none', textAlign: 'center'
        });

        // --- BUTTON 3 (x3) ---
        const shoot3Btn = document.createElement('button');
        shoot3Btn.innerHTML = 'x3';
        shoot3Btn.title = "Instantly shoot 3 rounds.";
        Object.assign(shoot3Btn.style, {
            background: '#B71C1C', color: '#fff', border: '1px solid #7f0000', 
            borderRadius: '4px', cursor: 'pointer', fontWeight: 'bold',
            fontSize: '11px', padding: '3px 0', flex: '1',
            display: 'none', textAlign: 'center'
        });

        // Container to hold them side-by-side
        const shootContainer = document.createElement('div');
        Object.assign(shootContainer.style, {
            display: 'flex', gap: '2px', width: '100%', marginTop: '4px'
        });


        // 3. Helper: Trigger Flash
        function triggerFlash(type) {
            // Check the setting first!
            if (!flashEnabled) return; 

            const overlay = document.createElement('div');
            overlay.className = type === 'win' ? 'rr-flash-green' : 'rr-flash-red';
            document.body.appendChild(overlay);
            setTimeout(() => { if (document.body.contains(overlay)) overlay.remove(); }, 500);
        }


        // 4. Helper: Get Token
        function getRfcVToken() {
            const cookieString = document.cookie;
            const cookieArray = cookieString.split('; ');
            for (const cookie of cookieArray) {
                const [cookieName, cookieValue] = cookie.split('=');
                if (cookieName === 'rfc_v') return cookieValue;
            }
            return null;
        }

        // 5. The API Request (Updated to handle target button animation)
        function performShootRequest(shots = 1, targetBtn = shootGlobalBtn) {
            const rfc = getRfcVToken();
            if (!rfc) {
                console.error("RR Tracker: RFC Token not found.");
                return;
            }

            const originalText = targetBtn.innerHTML;
            targetBtn.innerHTML = '💥 ...';
            targetBtn.disabled = true;

            fetch("https://www.torn.com/page.php?sid=russianRouletteData&rfcv=" + rfc, {
                "headers": {
                    "accept": "application/json, text/javascript, */*; q=0.01",
                    "content-type": "multipart/form-data; boundary=----WebKitFormBoundarysjciiQrGixS0J6tF",
                    "x-requested-with": "XMLHttpRequest"
                },
                "body": `------WebKitFormBoundarysjciiQrGixS0J6tF\r\nContent-Disposition: form-data; name=\"step\"\r\n\r\nmakeTurn\r\n------WebKitFormBoundarysjciiQrGixS0J6tF\r\nContent-Disposition: form-data; name=\"shotsAmount\"\r\n\r\n${shots}\r\n------WebKitFormBoundarysjciiQrGixS0J6tF--\r\n`,
                "method": "POST",
            })
            .then(response => response.json())
            .then(data => {
                if (data.status === 'turnMade') {
                    console.log(`RR Tracker: Shot (${shots}) fired successfully.`);
                } 
                else {
                    console.log("RR Tracker: Shoot ignored. Status:", data.status);
                    targetBtn.innerHTML = '⚠️ Wait';
                }
                
                setTimeout(() => {
                    targetBtn.innerHTML = originalText;
                    targetBtn.disabled = false;
                }, 400);
            })
            .catch(err => {
                console.error("RR Tracker: Shoot Error", err);
                targetBtn.innerHTML = '❌ Error';
                setTimeout(() => {
                    targetBtn.innerHTML = originalText;
                    targetBtn.disabled = false;
                }, 1000);
            });
        }

        // Click Handlers
        shootGlobalBtn.onclick = (e) => { e.stopPropagation(); performShootRequest(1, shootGlobalBtn); };
        shoot2Btn.onclick = (e) => { e.stopPropagation(); performShootRequest(2, shoot2Btn); };
        shoot3Btn.onclick = (e) => { e.stopPropagation(); performShootRequest(3, shoot3Btn); };


        


        function refreshAll() {
            // This is the controller that decides which panel view is active.
            const allContent = [statsGroup, mainBetGridContainer, buttonContainer, settingsPanel, editBetsPanel, statsDisplayPanel, miniBar, profitMini, alertMessageDiv, simulatorPanel];
            
            // --- NEW: Calculate lifetime streaks here to use in multiple places ---
            const { maxWinStreak, maxLossStreak } = calculateLifetimeStreaks();

            // First, hide ALL content panels to ensure a clean slate.
            allContent.forEach(p => p.style.display = 'none');
            
            // --- START OF NEW CODE ---
            // 1. Reset: Remove buttons from wherever they currently are
            shootContainer.remove();
            shootGlobalBtn.remove();
            shoot2Btn.remove();
            shoot3Btn.remove();

            // 2. Configure Visibility based on Settings
            shootGlobalBtn.style.display = 'block'; 
            shoot2Btn.style.display = enableShoot2 ? 'block' : 'none';
            shoot3Btn.style.display = enableShoot3 ? 'block' : 'none';

            // 3. Put buttons back into the container
            shootContainer.innerHTML = ''; 
            shootContainer.appendChild(shootGlobalBtn);
            if(enableShoot2) shootContainer.appendChild(shoot2Btn);
            if(enableShoot3) shootContainer.appendChild(shoot3Btn);

            // 4. Decide labels and location based on view mode
            if (isMinimized) {
                // Minimized View: Very compact
                shootGlobalBtn.innerHTML = '1'; 
                shoot2Btn.innerHTML = '2'; 
                shoot3Btn.innerHTML = '3';
                panel.appendChild(shootContainer);

            } else if (collapsed) {
                // Collapsed View: Short Uniform Labels (Fixes fitting issue)
                shootGlobalBtn.innerHTML = 'x1'; 
                shoot2Btn.innerHTML = 'x2';
                shoot3Btn.innerHTML = 'x3';
                
                // Add to miniBar
                miniBar.appendChild(shootContainer);

            } else {
                // Normal View: Full Labels with Icon
                shootGlobalBtn.innerHTML = '🔫 x1';
                shoot2Btn.innerHTML = '🔫 x2';
                shoot3Btn.innerHTML = '🔫 x3';
                
                // Only append if we are in the main view
                if (!showSettings && !showEditBetsPanel && !showStatsPanel && !showSimulatorPanel) {
                    panel.appendChild(shootContainer);
                }
            }
            // --- END OF NEW CODE ---

            // --- 1. SETUP: Prepare the Container ---
            // Remove everything first to prevent duplicates
            shootContainer.remove();
            shootGlobalBtn.remove();
            shoot2Btn.remove();
            shoot3Btn.remove();

            // Clear the container and re-add buttons based on settings
            shootContainer.innerHTML = ''; 
            
            // x1 is always enabled
            shootGlobalBtn.style.display = 'block'; 
            shootContainer.appendChild(shootGlobalBtn);

            // x2 (Only add if setting is enabled)
            if (enableShoot2) {
                shoot2Btn.style.display = 'block';
                shootContainer.appendChild(shoot2Btn);
            }

            // x3 (Only add if setting is enabled)
            if (enableShoot3) {
                shoot3Btn.style.display = 'block';
                shootContainer.appendChild(shoot3Btn);
            }

            // --- 2. LOGIC: Place the container based on view ---
            // Now, selectively RE-ENABLE the correct view based on the current state.
            if (isMinimized) {
                panel.style.width = '100px';
                panel.style.padding = '36px 4px 8px';
                statusDiv.style.display = 'none';
                minimizeButton.innerHTML = '&#9723;';
                
                // MINIMIZED VIEW: Very small text ('1', '2', '3')
                shootGlobalBtn.innerHTML = '1'; 
                shoot2Btn.innerHTML = '2'; 
                shoot3Btn.innerHTML = '3';
                
                // Append the CONTAINER, not just the button
                panel.appendChild(shootContainer);

            } else {
                statusDiv.style.display = 'block';
                minimizeButton.innerHTML = '—';

                if (collapsed) {
                    panel.style.width = '250px';
                    panel.style.padding = '36px 8px 8px';
                    miniBar.style.display = 'block';
                    
                    // COLLAPSED VIEW: Short text ('x1', 'x2', 'x3')
                    shootGlobalBtn.innerHTML = 'x1'; 
                    shoot2Btn.innerHTML = 'x2'; 
                    shoot3Btn.innerHTML = 'x3';
                    
                    // Append CONTAINER to MiniBar
                    miniBar.appendChild(shootContainer);

                } else {
                    // Default and other expanded states
                    panel.style.width = '400px';
                    panel.style.padding = '36px 12px 12px';

                    if (showSettings) {
                        settingsPanel.style.display = 'flex';
                    } else if (showEditBetsPanel) {
                        editBetsPanel.style.display = 'flex';
                    } else if (showStatsPanel) {
                        statsDisplayPanel.style.display = 'flex';
                    } else if (showSimulatorPanel) {
                        simulatorPanel.style.display = 'flex';
                    } else {
                        // MAIN VIEW
                        statsGroup.style.display = 'flex';
                        mainBetGridContainer.style.display = 'grid';
                        buttonContainer.style.display = 'flex';
                        
                        // EXPANDED VIEW: Full text with Icon
                        shootGlobalBtn.innerHTML = '🔫 x1';
                        shoot2Btn.innerHTML = '🔫 x2';
                        shoot3Btn.innerHTML = '🔫 x3';

                        // Append CONTAINER to Panel
                        panel.appendChild(shootContainer);
                    }
                }
            }


            // --- This part runs regardless of the panel's state ---
            updateStatus();
            updatePanelVisibility();

            // --- TIME CALCULATION (TORN TIME / UTC) ---
            const now = new Date();
            // Create a timestamp for 00:00:00 UTC of the current day
            const startOfTodayUTC = new Date(Date.UTC(now.getUTCFullYear(), now.getUTCMonth(), now.getUTCDate()));
            const startOfTodayTimestamp = Math.floor(startOfTodayUTC.getTime() / 1000);

            let dailyProfit = 0;
            for (const game of results) {
                if (game.timestamp >= startOfTodayTimestamp) {
                    dailyProfit += (game.result === 'win' ? game.bet : -game.bet);
                } else {
                    break;
                }
            }


            // Update alerts
            let showAlert = false, alertText = '', alertBackgroundColor = '', alertBorderColor = '';

            if (stopLossEnabled && lossLimit > 0 && dailyProfit <= -lossLimit) {
                showAlert = true;
                isStopLossActive = true;
                alertText = `🚨 DAILY LOSS LIMIT! Bets disabled.`;
                alertBackgroundColor = 'rgba(229, 57, 53, 0.8)';
                alertBorderColor = '#E53935';
            }
            else if (profitTarget > 0 && dailyProfit >= profitTarget) {
                showAlert = true;
                alertText = `🎯 DAILY PROFIT TARGET REACHED!`;
                alertBackgroundColor = 'rgba(76, 175, 80, 0.8)';
                alertBorderColor = '#4CAF50';
            }

            if (showAlert && !isMinimized && !collapsed && !hideAlerts) {
                alertMessageDiv.textContent = alertText;
                Object.assign(alertMessageDiv.style, { background: alertBackgroundColor, borderColor: alertBorderColor, display: 'block' });
            }

            const dailySign = dailyProfit >= 0 ? '+' : '–';
            document.getElementById('rr-daily-profit').textContent = `📅 Daily: ${dailySign}$${Math.abs(dailyProfit).toLocaleString()}`;
            document.getElementById('rr-daily-profit').style.color = dailyProfit >= 0 ? '#4CAF50' : '#E53935';

            if (isSessionActive) {
                const sessionSign = sessionProfit >= 0 ? '+' : '–';
                sessionDiv.textContent = `🔵 Session: ${sessionSign}$${Math.abs(sessionProfit).toLocaleString()}`;
                sessionDiv.style.color = sessionProfit >= 0 ? '#64B4FF' : '#FF7A7A';
                sessionButton.textContent = '⏹️ Stop Session';
                sessionButton.title = `Session started on ${new Date(sessionStartDate).toLocaleString()}`;
            } else {
                sessionDiv.textContent = '🔵 Session: Inactive';
                sessionDiv.style.color = '#888';
                sessionButton.textContent = '▶️ Start Session';
                sessionButton.title = 'Start a new tracking session.';
            }

            const sign = totalProfit >= 0 ? '+' : '–';
            profitMini.textContent = `${sign}$${Math.abs(totalProfit).toLocaleString()}`;
            profitMini.style.color = totalProfit >= 0 ? '#4CAF50' : '#E53935';
            document.getElementById('rr-lifetime-profit').textContent = `💰 LifeTime Profit: ${sign}$${Math.abs(totalProfit).toLocaleString()}`;
            document.getElementById('rr-lifetime-profit').style.color = totalProfit >= 0 ? '#4CAF50' : '#E53935';

            const wins = results.filter(r => r.result === 'win').length;
            const tot = results.length;
            document.getElementById('rr-winrate').textContent = `🎯 Win Rate: ${tot ? ((wins / tot) * 100).toFixed(1) : '0.0'}% (${wins}/${tot})`;

            let w = 0, l = 0;
            for (const r of results) { if (r.result === 'win') { if (l) break; w++; } else { if (w) break; l++; } }
            document.getElementById('rr-streak').textContent = w ? `🔥 Streak: ${w}` : l ? `💀 Streak: ${l}` : '⏸️ No streak';

            // --- RISK ANALYSIS ---
            const riskPanel = document.getElementById('rr-risk-analysis');
            // Recalculate 'l' using your streak logic if needed, but for display we stick to standard 'l'
            if (l > 0 && dynamicBetsEnabled) { 
                const streakLength = l;
                const cumulativeLoss = results.slice(0, streakLength).reduce((acc, game) => acc + game.bet, 0);

                const tornInput = document.querySelector('input[aria-label="Money value"]');
                let nextBet = 0;
                if (tornInput && tornInput.value) {
                    nextBet = parseBetInput(tornInput.value);
                }
                if (!nextBet || nextBet <= 0) {
                    if (bettingMode === 'simple') {
                        nextBet = getBetForStep(simpleModeStep);
                    } else {
                        nextBet = currentBets[l] || 0;
                    }
                }
                const potentialLoss = cumulativeLoss + nextBet;
                const capital = dynamicBetsSettings.capital;
                const capitalAtRisk = capital > 0 ? ((potentialLoss / capital) * 100).toFixed(1) : 0;
                const profitOnWin = nextBet - cumulativeLoss;
                const riskRewardRatio = profitOnWin > 0 ? (potentialLoss / profitOnWin).toFixed(0) : 0;
                let threatLevel = { text: 'LOW', color: '#4CAF50' };
                if (streakLength >= 4) threatLevel = { text: 'MODERATE', color: '#FFC107' };
                if (streakLength >= 7) threatLevel = { text: 'HIGH', color: '#FF9800' };
                if (streakLength >= 10) threatLevel = { text: 'CRITICAL', color: '#E53935' };
                const probNextLoss = (Math.pow(0.5, streakLength + 1) * 100).toFixed(2);
                let lossesUntilBroke = 'N/A';
                if (capital > 0) {
                    let futureLoss = potentialLoss;
                    let steps = 1;
                    while (futureLoss < capital && (streakLength + steps) < currentBets.length) {
                        futureLoss += currentBets[streakLength + steps];
                        steps++;
                    }
                    if (futureLoss >= capital) lossesUntilBroke = `${steps} Loss${steps > 1 ? 'es' : ''}`;
                    else lossesUntilBroke = `> ${steps - 1}`;
                }

                riskPanel.innerHTML = `
            <div style="display: flex; justify-content: space-between; font-weight: bold; margin-bottom: 5px; padding-bottom: 4px; border-bottom: 1px solid #555;">
                <span>Martingale Risk Analysis (L${streakLength} / Max L${maxLossStreak})</span>
                <span style="color: ${threatLevel.color};">Risk: ${threatLevel.text}</span>
            </div>
            <div style="display: grid; grid-template-columns: auto 1fr; gap: 2px 8px;">
                <span>Profit on Win:</span> <span style="text-align: right; color: #4CAF50;">+$${profitOnWin.toLocaleString()}</span>
                <span>Potential Loss:</span> <span style="text-align: right; color: #FF9800;">-$${potentialLoss.toLocaleString()}</span>
                <span>Cumulative Loss:</span> <span style="text-align: right; color: #E53935;">-$${cumulativeLoss.toLocaleString()}</span>
                <span title="You are risking ${potentialLoss.toLocaleString()} to win ${profitOnWin.toLocaleString()}">Risk/Reward Ratio:</span> <span style="text-align: right;">${riskRewardRatio} : 1</span>
                <span>Capital at Risk:</span> <span style="text-align: right;">${capitalAtRisk}%</span>
                <span>P(Streak ≥ ${streakLength + 1}):</span> <span style="text-align: right;">${probNextLoss}%</span>
            </div>
            <div style="margin-top: 6px; padding-top: 6px; border-top: 1px solid #555; text-align: center; font-weight: bold;">
                <span style="color: #E53935;">Capital Breach In: ${lossesUntilBroke}</span>
            </div>
        `;
                riskPanel.style.borderColor = threatLevel.color;
                riskPanel.style.display = 'flex'; 
            }

            miniStreakDiv.textContent = document.getElementById('rr-streak').textContent;
            miniDailyProfitDiv.innerHTML = `📅 <small>${dailySign}$${Math.abs(dailyProfit).toLocaleString()}</small>`;
            miniDailyProfitDiv.style.color = document.getElementById('rr-daily-profit').style.color;
            miniSessionDiv.innerHTML = sessionDiv.textContent.replace('Session:', '<small>Session:</small>');
            miniSessionDiv.style.color = sessionDiv.style.color;

            resultsContainer.innerHTML = '';
            results.slice(0, maxDisplayMatches).forEach((r, i) => {
                const row = document.createElement('div');
                const winLossCircle = makeCircle(r.result, r.bet, i);
                const textNode = document.createTextNode(` ${i + 1}. ${r.result.toUpperCase()} — $${r.bet.toLocaleString()}`);
                row.append(winLossCircle, textNode);
                resultsContainer.appendChild(row);
            });

            if (showEditBetsPanel) {
                capitalInput.value = formatNumberToKMB(dynamicBetsSettings.capital);
                startingBetInput.value = formatNumberToKMB(dynamicBetsSettings.startingBet);
                capitalLock.textContent = dynamicBetsSettings.lockedField === 'capital' ? '🔒' : '🔓';
                startingBetLock.textContent = dynamicBetsSettings.lockedField === 'startingBet' ? '🔒' : '🔓';
                capitalInput.readOnly = dynamicBetsSettings.lockedField !== 'capital';
                startingBetInput.readOnly = dynamicBetsSettings.lockedField !== 'startingBet';
                capitalInput.style.background = dynamicBetsSettings.lockedField === 'capital' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.2)';
                startingBetInput.style.background = dynamicBetsSettings.lockedField === 'startingBet' ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.2)';
            }
            if (showSettings) {
                profitTargetInput.value = formatNumberToKMB(profitTarget);
                lossLimitInput.value = formatNumberToKMB(lossLimit);
            }

            buildBetButtons();
        }

        

        const savePos = () => localStorage.setItem(POS_KEY, JSON.stringify({ top: panel.style.top, left: panel.style.left }));
        function onDragMove(e) {
            if (!isDragging) return;
            e.preventDefault();
            const moveEvent = e.touches ? e.touches[0] : e;
            if (typeof moveEvent.clientX === 'undefined') return;

            const dx = moveEvent.clientX - dragMouseX;
            const dy = moveEvent.clientY - dragMouseY;
            dragMouseX = moveEvent.clientX;
            dragMouseY = moveEvent.clientY;

            let newLeft = panel.offsetLeft + (dx / panelScale);
            let newTop = panel.offsetTop + (dy / panelScale);

            // --- Boundary Checks (Corrected) ---
            const panelRenderedWidth = panel.offsetWidth * panelScale;
            const panelRenderedHeight = panel.offsetHeight * panelScale;

            const minX = 0;
            const maxX = window.innerWidth - panelRenderedWidth;
            const minY = 0;
            const maxY = window.innerHeight - panelRenderedHeight;


            newLeft = Math.max(minX, Math.min(newLeft, maxX));
            newTop = Math.max(minY, Math.min(newTop, maxY));

            panel.style.left = newLeft + 'px';
            panel.style.top = newTop + 'px';
        }

        function onDragEnd() { if (!isDragging) return; isDragging = false; document.removeEventListener('mousemove', onDragMove); document.removeEventListener('mouseup', onDragEnd); document.removeEventListener('touchmove', onDragMove); document.removeEventListener('touchend', onDragEnd); savePos(); panel.style.cursor = ''; document.body.style.cursor = ''; }
        function startDrag(e) { if (isTwoFingerDragging) return; e.preventDefault(); const startEvent = e.touches ? e.touches[0] : e; if (typeof startEvent.clientX === 'undefined') return; isDragging = true; dragMouseX = startEvent.clientX; dragMouseY = startEvent.clientY; panel.style.cursor = 'grabbing'; document.body.style.cursor = 'grabbing'; document.addEventListener('mousemove', onDragMove); document.addEventListener('mouseup', onDragEnd); document.addEventListener('touchmove', onDragMove, { passive: false }); document.addEventListener('touchend', onDragEnd); }
        dragHandle.addEventListener('mousedown', startDrag);
        dragHandle.addEventListener('touchstart', e => { if (e.touches.length === 1) startDrag(e); });
        panel.addEventListener('mousedown', e => { if (e.shiftKey && e.target !== dragHandle) startDrag(e); });
        panel.addEventListener('touchstart', e => { if (e.touches.length === 2) { e.preventDefault(); isTwoFingerDragging = true; isDragging = false; initialTouchMidX = (e.touches[0].clientX + e.touches[1].clientX) / 2; initialTouchMidY = (e.touches[0].clientY + e.touches[1].clientY) / 2; initialPanelX = panel.offsetLeft; initialPanelY = panel.offsetTop; panel.style.cursor = 'grabbing'; document.body.style.cursor = 'grabbing'; document.addEventListener('touchmove', onTwoFingerMove, { passive: false }); document.addEventListener('touchend', onTwoFingerEnd); } });
        function onTwoFingerMove(e) {
            if (!isTwoFingerDragging || e.touches.length !== 2) { onTwoFingerEnd(e); return; }
            e.preventDefault();
            const currentTouchMidX = (e.touches[0].clientX + e.touches[1].clientX) / 2;
            const currentTouchMidY = (e.touches[0].clientY + e.touches[1].clientY) / 2;
            const dx = currentTouchMidX - initialTouchMidX;
            const dy = currentTouchMidY - initialTouchMidY;

            let newLeft = initialPanelX + (dx / panelScale);
            let newTop = initialPanelY + (dy / panelScale);

            // --- Boundary Checks (Corrected) ---
            const panelRenderedWidth = panel.offsetWidth * panelScale;
            const panelRenderedHeight = panel.offsetHeight * panelScale;

            const minX = 0;
            const maxX = window.innerWidth - panelRenderedWidth;
            const minY = 0;
            const maxY = window.innerHeight - panelRenderedHeight;


            newLeft = Math.max(minX, Math.min(newLeft, maxX));
            newTop = Math.max(minY, Math.min(newTop, maxY));

            panel.style.left = newLeft + 'px';
            panel.style.top = newTop + 'px';
        }

        function onTwoFingerEnd(e) { if (!isTwoFingerDragging) return; if (e.touches.length < 2) { document.removeEventListener('touchmove', onTwoFingerMove); document.removeEventListener('touchend', onTwoFingerEnd); savePos(); isTwoFingerDragging = false; panel.style.cursor = ''; document.body.style.cursor = ''; } }

        statusDiv.addEventListener('click', () => {
            if (isDragging || isTwoFingerDragging) return;
            collapsed = !collapsed;
            // The lines that reset the view have been removed from here.
            saveCollapsed();
            refreshAll();
        });

        // --- REAL-TIME INPUT LISTENER ---
        // This detects when you type manually in the Torn input box and updates the Risk Panel immediately.
        document.body.addEventListener('input', (e) => {
            if (e.target && e.target.getAttribute('aria-label') === 'Money value') {
                refreshAll();
            }
        });

        // --- Main Loop ---

        // --- STARTUP SEQUENCE ---
        
        // 1. Check if Deep Sync was interrupted and resume it
        if (localStorage.getItem(DEEP_SYNC_KEY)) {
            console.log("RR Tracker: Resuming interrupted Deep Sync...");
            processDeepSyncStep();
        }
        calculateBetsAndRefresh();
        initiateSyncing();
        syncCountdownInterval = setInterval(updateSyncTimer, 1000);
        
        
        enableNetworkInterception(); // <--- ADD THIS CALL
        enableTextBasedDetection(); // You can comment this out if you trust the network interceptor


        // --- Simulator Panel Logic ---
        const simulatorDynamicToggle = document.getElementById('simulator-dynamic-toggle');
        const simulatorManualBetsContainer = document.getElementById('simulator-manual-bets-container');
        const simulatorManualBetsInput = document.getElementById('simulator-manual-bets');
        const simulatorCapitalInput = document.getElementById('simulator-capital');
        const simulatorMaxStreakInput = document.getElementById('simulator-max-streak');
        const simulatorMatchesInput = document.getElementById('simulator-matches');
        const simulatorSessionsInput = document.getElementById('simulator-sessions');
        const simulatorRunBtn = document.getElementById('simulator-run-btn');
        const simulatorResultsContainer = document.getElementById('simulator-results-container');
        const simulatorCopyBtn = document.getElementById('simulator-copy-dynamic-btn');

        // Populate inputs from saved values
        simulatorCapitalInput.value = simCapital;
        simulatorMaxStreakInput.value = simMaxLStreak;
        simulatorMatchesInput.value = simMatches;
        simulatorSessionsInput.value = simSessions;
        simulatorManualBetsInput.value = simulatorManualBetsString;

        // Set the initial state of the toggle from our loaded variable
        simulatorDynamicToggle.checked = simUseDynamic;

        // Save changes when inputs are modified
        simulatorCapitalInput.onchange = () => localStorage.setItem(SIM_CAPITAL_KEY, simulatorCapitalInput.value);
        simulatorMaxStreakInput.onchange = () => localStorage.setItem(SIM_STREAK_KEY, simulatorMaxStreakInput.value);
        simulatorMatchesInput.onchange = () => localStorage.setItem(SIM_MATCHES_KEY, simulatorMatchesInput.value);
        simulatorSessionsInput.onchange = () => localStorage.setItem(SIM_SESSIONS_KEY, simulatorSessionsInput.value);
        simulatorManualBetsInput.onchange = () => {
            simulatorManualBetsString = simulatorManualBetsInput.value;
            localStorage.setItem(SIM_MANUAL_BETS_KEY, simulatorManualBetsString);
        };

        document.getElementById('simulator-back-btn').onclick = () => { showSimulatorPanel = false; refreshAll(); };

        const syncSimulatorUI = () => {
            const useDynamic = simulatorDynamicToggle.checked;
            if (useDynamic) {
                simulatorManualBetsString = simulatorManualBetsInput.value;
                simulatorManualBetsContainer.style.display = 'none';
            } else {
                simulatorManualBetsContainer.style.display = 'flex';
                simulatorManualBetsInput.value = simulatorManualBetsString;
            }
        };

        // This is the updated onchange handler that saves the state
        simulatorDynamicToggle.onchange = () => {
            simUseDynamic = simulatorDynamicToggle.checked; // Update state variable
            localStorage.setItem(SIM_USE_DYNAMIC_KEY, JSON.stringify(simUseDynamic)); // Save the new choice
            syncSimulatorUI(); // Update the UI
        };

        // --- NEW, SMARTER LOGIC FOR THE COPY BUTTON ---
        simulatorCopyBtn.onclick = () => {
            if (!dynamicBetsEnabled || !currentBets || currentBets.length === 0) {
                alert("Please enable 'Dynamic Bets' in the main settings and ensure a valid strategy is calculated.");
                return;
            }

            const desiredStreakLength = parseInt(simulatorMaxStreakInput.value, 10);
            if (isNaN(desiredStreakLength) || desiredStreakLength < 1) {
                alert("Please enter a valid 'Max L Streak' in the simulator panel first.");
                return;
            }

            // Get the core components of the current dynamic strategy
            const startingBet = currentBets[0];
            const { martingaleValue, reinforce, boostedBets } = dynamicBetsSettings;

            // Use the script's own ratio calculator to generate a new progression
            const { coeffs } = getSumOfRatios(desiredStreakLength, martingaleValue, reinforce, desiredStreakLength, boostedBets);

            // Build the new bet array based on the starting bet and the new coefficients
            const newProgression = coeffs.map(ratio => Math.floor(startingBet * ratio));

            const betsString = newProgression.join(', ');
            simulatorManualBetsInput.value = betsString;
            simulatorManualBetsInput.dispatchEvent(new Event('change')); // Trigger save
        };

        // --- New Onclick Handler for the Deep Simulation Button ---
        const simulatorDeepRunBtn = document.getElementById('simulator-deep-run-btn');
        const deepResultsContainer = document.getElementById('simulator-deep-results-container');

        simulatorDeepRunBtn.onclick = () => {
            const simulatorGraphCanvas = document.getElementById('simulator-graph-canvas');

            // Hide other panels and show a loading message
            document.getElementById('simulator-results-container').style.display = 'none';
            simulatorGraphCanvas.style.display = 'none';
            deepResultsContainer.style.display = 'block';
            deepResultsContainer.innerHTML = 'Running deep analysis... This can take some time for high simulation counts.';
            simulatorDeepRunBtn.disabled = true;
            document.getElementById('simulator-run-btn').disabled = true;

            setTimeout(() => {
                try {
                    // 1. GATHER PARAMETERS
                    const capital = parseBetInput(simulatorCapitalInput.value);
                    const matches = parseInt(simulatorMatchesInput.value, 10);
                    const simulations = parseInt(simulatorSessionsInput.value, 10);
                    let bets;
                    const useDynamic = simulatorDynamicToggle.checked;
                    if (useDynamic) { bets = currentBets; }
                    else {
                        bets = simulatorManualBetsInput.value.split(',').map(s => parseBetInput(s.trim())).filter(n => n !== null && n > 0);
                    }

                    // --- ADD THIS VALIDATION BLOCK ---
                    if (!simulations || simulations < 1 || !matches || matches < 1 || !capital) {
                        deepResultsContainer.innerHTML = `<div style="color: #FFC107; text-align: center; padding: 10px;">
                        <strong>Invalid Input</strong><br>
                        Please ensure Capital, Matches, and Number of Simulations are all valid numbers greater than 0.
                        </div>`;
                        // Re-enable buttons and stop the function
                        simulatorDeepRunBtn.disabled = false;
                        document.getElementById('simulator-run-btn').disabled = false;
                        return;
                    }
                    // --- END OF VALIDATION BLOCK ---

                    // 2. RUN THE ANALYSIS
                    const results = runDeepAnalysis({ capital, bets, matches, simulations });

                    if (results.length === 0) {
                        deepResultsContainer.innerHTML = 'Analysis could not be completed. Check your inputs or try more matches/simulations.';
                        return;
                    }

                    const bestProfitResult = [...results].sort((a, b) => b.avgProfit - a.avgProfit)[0];
                    const safestProfitable = results.filter(r => r.avgProfit > 0).sort((a,b) => a.bankRate - b.bankRate)[0];

                    // 3. BUILD THE HTML TABLE
                    let tableHTML = `
                    <div style="font-weight: bold; font-size: 14px; margin-bottom: 10px; text-align: center;">🔬 Deep Simulation Results</div>
                    <div style="max-height: 220px; overflow-y: auto; border: 1px solid #333; border-radius: 4px;">
                    <table style="width: 100%; border-collapse: collapse; font-size: 12px;">
                        <thead>
                            <tr style="text-align: left; border-bottom: 1px solid #888; position: sticky; top: 0; background: rgba(0,0,0,0.8);">
                                <th style="padding: 4px;">Max L Streak</th>
                                <th style="padding: 4px; text-align: right;">Avg. Profit</th>
                                <th style="padding: 4px; text-align: right;">Bankrupt %</th>
                                <th style="padding: 4px;">Safety</th>
                            </tr>
                        </thead>
                        <tbody>
                `;
                    results.forEach(res => {
                        const profitColor = res.avgProfit > 0 ? '#4CAF50' : '#E53935';
                        let safety, safetyColor;
                        if (res.bankRate === 0)      { safety = 'Perfect ✅';   safetyColor = '#4CAF50'; }
                        else if (res.bankRate < 1)   { safety = 'Very Safe';    safetyColor = '#8BC34A'; }
                        else if (res.bankRate < 5)   { safety = 'Safe';         safetyColor = '#CDDC39'; }
                        else if (res.bankRate < 15)  { safety = 'Moderate 🤔';  safetyColor = '#FFC107'; }
                        else if (res.bankRate < 30)  { safety = 'Risky ⚠️';     safetyColor = '#FF9800'; }
                        else if (res.bankRate < 50)  { safety = 'Very Risky ‼️'; safetyColor = '#FF5722'; }
                        else                         { safety = 'Suicidal 💀';  safetyColor = '#E53935'; }
                        let limitText = `L${res.limit}`;
                        if (res.bankRate === 100) {
                            limitText += ` <span style="color: #E53935;">(bankruptcy)</span>`;
                        }
                        tableHTML += `
                        <tr style="border-bottom: 1px solid #444;">
                            <td style="padding: 4px; color: #fff;">${limitText}</td>
                            <td style="padding: 4px; text-align: right; color: ${profitColor};">${bestProfitResult && res.limit === bestProfitResult.limit ? '🔥' : ''}$${formatNumberToKMB(res.avgProfit)}</td>
                            <td style="padding: 4px; text-align: right;">${res.bankRate.toFixed(2)}%</td>
                            <td style="padding: 4px; color: ${safetyColor};">${safety}</td>
                        </tr>
                    `;
                    });
                    tableHTML += `</tbody></table></div>`;

                    // 4. ADD THE FINAL SUMMARY
                    let summaryHTML = `<div style="margin-top: 15px; padding-top: 10px; border-top: 1px solid #555; text-align: center;">`;
                    if (bestProfitResult) {
                        summaryHTML += `<strong>Highest Profit:</strong> Set Max L Streak to <strong>L${bestProfitResult.limit}</strong> for an average of <strong style="color: #4CAF50;">$${formatNumberToKMB(bestProfitResult.avgProfit)}</strong> per run.<br>`;
                    }
                    if (safestProfitable) {
                        summaryHTML += `<strong>Safest Profitable Option:</strong> Set Max L Streak to <strong>L${safestProfitable.limit}</strong>, with a bankruptcy rate of <strong>${safestProfitable.bankRate.toFixed(2)}%</strong>.`;
                    } else {
                        summaryHTML += `<strong style="color: #E53935;">No strategy was found to be consistently profitable with these settings.</strong>`;
                    }
                    summaryHTML += `</div>`;

                    deepResultsContainer.innerHTML = tableHTML + summaryHTML;

                    // 5. SHOW and DRAW the graph
                    simulatorGraphCanvas.style.display = 'block';
                    drawDeepAnalysisGraph(simulatorGraphCanvas, results);

                } catch (e) {
                    deepResultsContainer.innerHTML = `An error occurred during deep analysis: ${e.message}`;
                    console.error("Deep simulation failed", e);
                } finally {
                    simulatorDeepRunBtn.disabled = false;
                    document.getElementById('simulator-run-btn').disabled = false;
                }
            }, 50);
        };

        // A variable to hold our chart so we can destroy it later
        let simulatorChart = null;

        simulatorRunBtn.onclick = () => {
            const simulatorGraphCanvas = document.getElementById('simulator-graph-canvas');
            document.getElementById('simulator-deep-results-container').style.display = 'none';
            document.getElementById('simulator-results-container').style.display = 'block';

            simulatorResultsContainer.textContent = 'Running simulations... This may take a moment.';
            simulatorRunBtn.disabled = true;
            document.getElementById('simulator-deep-run-btn').disabled = true;
            simulatorGraphCanvas.style.display = 'none';

            if (simulatorChart) {
                simulatorChart.destroy();
                simulatorChart = null;
            }

            setTimeout(() => {
                try {
                    // 1. GATHER PARAMETERS
                    const capital = parseBetInput(simulatorCapitalInput.value);
                    const maxLStreak = parseInt(simulatorMaxStreakInput.value, 10);
                    const matches = parseInt(simulatorMatchesInput.value, 10);
                    const sessions = parseInt(simulatorSessionsInput.value, 10);
                    let bets;
                    const useDynamic = simulatorDynamicToggle.checked;
                    if (useDynamic) { bets = currentBets; }
                    else {
                        bets = simulatorManualBetsInput.value.split(',').map(s => parseBetInput(s.trim())).filter(n => n !== null && n > 0);
                    }

                    // VALIDATION
                    if (!sessions || sessions < 1 || !matches || matches < 1 || !capital) {
                        simulatorResultsContainer.innerHTML = `<div style="color: #FFC107; text-align: center; padding: 10px;"><strong>Invalid Input</strong><br>Please ensure Capital, Matches, and Sessions are all valid numbers greater than 0.</div>`;
                        simulatorRunBtn.disabled = false; document.getElementById('simulator-deep-run-btn').disabled = false;
                        return;
                    }
                    if ((matches * sessions) > 10000000) {
                        simulatorResultsContainer.innerHTML = `<div style="color: #FFC107; text-align: center; padding: 10px;"><strong>Limit Exceeded</strong><br>Total matches (Matches × Sessions) cannot exceed 10 million. Please adjust your inputs.</div>`;
                        simulatorRunBtn.disabled = false; document.getElementById('simulator-deep-run-btn').disabled = false;
                        return;
                    }

                    const simParams = { capital, maxLStreak, bets, matches, sessions };

                    // 2A: Run the Multi-Session Analysis
                    const summary = runMultipleSimulations(simParams);

                    // 2B: Run the Cumulative Simulation
                    const cumulativeResult = runCumulativeSimulation(simParams);

                    // 3. BUILD THE COMBINED REPORT
                    let multiStreakReport = 'Total L-Streak Occurrences:\n';
                    const multiSortedStreaks = Object.keys(summary.aggregateStreaks).map(Number).sort((a, b) => a - b);
                    if (multiSortedStreaks.length > 0) {
                        multiSortedStreaks.forEach(streakLen => {
                            const count = summary.aggregateStreaks[streakLen];
                            multiStreakReport += `  L${streakLen}: ${count.toLocaleString()} times\n`;
                        });
                    } else { multiStreakReport += '  None recorded.'; }
                    const avgProfitColor = summary.averageProfit >= 0 ? '#4CAF50' : '#E53935';
                    const medianProfitColor = summary.medianProfit >= 0 ? '#4CAF50' : '#E53935';

                    const cumulativeProfit = cumulativeResult.finalCapital - capital;
                    const cumulativeProfitSign = cumulativeProfit >= 0 ? '+' : '-';
                    const cumulativeProfitColor = cumulativeProfit >= 0 ? '#4CAF50' : '#E53935';
                    let cumulativeStreakReport = 'L-Streak Occurrences:\n';
                    const cumulativeSortedStreaks = Object.keys(cumulativeResult.streakCounts).map(Number).sort((a, b) => a - b);
                    if (cumulativeSortedStreaks.length > 0) {
                        cumulativeSortedStreaks.forEach(streakLen => {
                            const count = cumulativeResult.streakCounts[streakLen];
                            cumulativeStreakReport += `  L${streakLen}: ${count.toLocaleString()} times\n`;
                        });
                    } else { cumulativeStreakReport += '  None recorded.'; }

                    simulatorResultsContainer.innerHTML = `
                <div style="font-weight: bold; font-size: 14px; margin-bottom: 8px; padding-bottom: 5px; border-bottom: 1px solid #555; text-align: center;">📈 Multi-Session Analysis <small>(${summary.sessions.toLocaleString()} independent runs)</small></div>
                <div style="display: grid; grid-template-columns: auto 1fr; gap: 4px 10px;">
                    <span>Success Rate:</span> <span style="text-align: right; font-weight: bold; color: #4CAF50;">${(100 - summary.bankruptRate).toFixed(2)}%</span>
                    <span>Total Resets:</span> <span style="text-align: right; font-weight: bold; color: #FFC107;">${summary.totalResets.toLocaleString()}</span>
                    <span>Average P/L:</span> <span style="text-align: right; font-weight: bold; color: ${avgProfitColor};">$${formatNumberToKMB(summary.averageProfit)}</span>
                    <span>Median P/L:</span> <span style="text-align: right; font-weight: bold; color: ${medianProfitColor};">$${formatNumberToKMB(summary.medianProfit)}</span>
                    <span>Main Failure Point:</span> <span style="text-align: right; color: #E53935;">${summary.mostCommonFailure}</span>
                </div>
                <pre style="margin-top: 10px; padding-top: 8px; border-top: 1px solid #444; font-size: 12px; color: #ccc; white-space: pre-wrap;">${multiStreakReport}</pre>

                <div style="font-weight: bold; font-size: 14px; margin: 20px 0 8px 0; padding-bottom: 5px; border-bottom: 1px solid #555; text-align: center;">➡️ Cumulative Run <small>(One continuous journey)</small></div>
                <div style="font-style: italic; color: #ccc; margin-bottom: 8px; text-align: center;">${cumulativeResult.stopReason}</div>
                <div style="display: grid; grid-template-columns: auto 1fr; gap: 4px 10px;">
                    <span>Final Capital:</span> <span style="text-align: right; font-weight: bold;">$${formatNumberToKMB(cumulativeResult.finalCapital)}</span>
                    <span>Cumulative Profit:</span> <span style="text-align: right; font-weight: bold; color: ${cumulativeProfitColor};">${cumulativeProfitSign}$${formatNumberToKMB(Math.abs(cumulativeProfit))}</span>
                    <span>Total Resets:</span> <span style="text-align: right; font-weight: bold; color: #FFC107;">${cumulativeResult.resetCount.toLocaleString()}</span>
                </div>
                <pre style="margin-top: 10px; padding-top: 8px; border-top: 1px solid #444; font-size: 12px; color: #ccc; white-space: pre-wrap;">${cumulativeStreakReport}</pre>`;

                    // --- DATA SAMPLING FOR PERFORMANCE ---
                    if (cumulativeResult.capitalHistory.length > 1) {
                        const fullData = cumulativeResult.capitalHistory;
                        const sampledData = sampleData(fullData, 2000); // Sample down to a max of 2000 points

                        const dataPoints = sampledData.map((value, index) => {
                            // We need to scale the index to represent the full timeline
                            const originalIndex = Math.floor(index * (fullData.length / sampledData.length));
                            return { timestamp: originalIndex, cumulativeProfit: value };
                        });

                        simulatorGraphCanvas.style.display = 'block';
                        simulatorChart = new RrChart(simulatorGraphCanvas, dataPoints, null);
                    }

                } catch (e) {
                    simulatorResultsContainer.textContent = `An unexpected error occurred during simulation: ${e.message}`;
                    console.error("Simulation failed", e);
                } finally {
                    simulatorRunBtn.disabled = false;
                    document.getElementById('simulator-deep-run-btn').disabled = false;
                }
            }, 50);
        };


        // Set initial state of the simulator UI
        simulatorDynamicToggle.checked = true;
        syncSimulatorUI();


        // --- Add these new handlers at the end of the script ---
        document.getElementById('simulator-configure-btn').onclick = () => {
            showSimulatorConfig = true;
            refreshSimulatorView();
        };

        document.getElementById('simulator-config-back-btn').onclick = () => {
            showSimulatorConfig = false;
            refreshSimulatorView();
        };



    } catch (error) { // <<< ADD THIS ENTIRE BLOCK
        console.error("RR Tracker CRITICAL ERROR:", error); // Also log to the real console for good measure

        const errorPopup = document.createElement('div');
        Object.assign(errorPopup.style, {
            position: 'fixed',
            top: '20px',
            left: '20px',
            background: 'rgba(40, 0, 0, 0.95)',
            color: '#ffcdd2',
            border: '2px solid #e53935',
            borderRadius: '8px',
            padding: '20px',
            zIndex: '999999999',
            maxWidth: '90vw',
            fontFamily: 'monospace',
            fontSize: '14px',
            boxShadow: '0 0 15px rgba(0,0,0,0.5)'
        });

        errorPopup.innerHTML = `
            <h2 style="color: #ef5350; margin: 0 0 15px 0;">🚨 RR Tracker Script Crashed!</h2>
            <p style="margin: 5px 0;"><strong>Error Type:</strong> <span style="color: white;">${error.name}</span></p>
            <p style="margin: 5px 0 15px 0;"><strong>Message:</strong> <span style="color: white;">${error.message}</span></p>
            <strong style="color: white; display: block; margin-bottom: 5px;">Stack Trace (Location of the error):</strong>
            <pre style="background: #1a1a1a; padding: 10px; border-radius: 4px; white-space: pre-wrap; word-break: break-all; color: #ffcdd2;">${error.stack}</pre>
        `;

        const closeButton = document.createElement('button');
        closeButton.textContent = '❌ Close';
        Object.assign(closeButton.style, {
            position: 'absolute',
            top: '10px',
            right: '10px',
            background: '#c62828',
            color: 'white',
            border: 'none',
            borderRadius: '4px',
            padding: '5px 10px',
            cursor: 'pointer'
        });
        closeButton.onclick = () => errorPopup.remove();

        errorPopup.prepend(closeButton);
        document.body.appendChild(errorPopup);
    }
// --- NETWORK INTERCEPTOR ---
function enableNetworkInterception() {
    const originalOpen = XMLHttpRequest.prototype.open;
    const originalSend = XMLHttpRequest.prototype.send;

    XMLHttpRequest.prototype.open = function(method, url) {
        this._url = url;
        return originalOpen.apply(this, arguments);
    };

    XMLHttpRequest.prototype.send = function(body) {
        if (this._url && this._url.includes('sid=russianRouletteData')) {
            this.addEventListener('load', function() {
                try {
                    const response = JSON.parse(this.responseText);
                    
                    // Check if the response contains game data
                    if (response && response.data) {
                        const data = response.data;
                        
                        // 1. DETECT GAME OVER (Winner determined)
                        // If winner is NOT null, someone died.
                        if (data.winner) {
                            console.log("RR Tracker (Net): Game Over detected via Network.");
                            
                            // Trigger Sync
                            importApiData(true);

                            // Trigger Flash
                            // We need to know who won. We can check the 'message' or 'winner.ID'.
                            // However, since we don't have the User's ID stored easily in a global var in this scope,
                            // We can infer from the message or just trigger sync and let the text observer handle the flash backup,
                            // OR we can parse the "message" string.
                            
                            if (response.user && response.user.player_id) {
                                // If the API provided the user ID (sometimes it does in wrapper)
                                if (data.winner.ID === response.user.player_id) triggerFlash('win');
                                else triggerFlash('loss');
                            } else {
                                // Fallback: Check message text in the JSON
                                if (data.message && data.message.includes("You take your winnings")) triggerFlash('win');
                                else if (data.message && data.message.includes("You fall down")) triggerFlash('loss');
                            }
                            
                            // Handle Instant Leave if enabled
                            const instantLeave = JSON.parse(localStorage.getItem('rr_instantLeave') || 'false');
                            if (instantLeave) {
                                setTimeout(() => {
                                    window.location.href = "https://www.torn.com/page.php?sid=russianRoulette";
                                }, 500);
                            }
                        }
                    }
                } catch (e) {
                    console.error("RR Tracker: Network Parse Error", e);
                }
            });
        }
        return originalSend.apply(this, arguments);
    };
    console.log("RR Tracker: Network Interception Enabled.");
}


})()