Betway Aviator Predictor

Optimized ML predictor with adjusted pink times and enhanced accuracy

// ==UserScript==
// @name         Betway Aviator Predictor
// @namespace    http://tampermonkey.net/
// @version      8.0
// @description  Optimized ML predictor with adjusted pink times and enhanced accuracy
// @author       You
// @match        https://www.betway.co.bw/*aviator*
// @match        https://www.betway.co.bw/lobby/Casino/featured/Aviator*
// @match        *://aviator.*
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @license      MIT
// ==/UserScript==

(function() {
    'use strict';

    // Enhanced Configuration with Optimized Settings
    const CONFIG = {
        HISTORY_LIMIT: 1000,
        UPDATE_INTERVAL: 500,
        DEBUG: true,
        MEMORY_KEY: 'aviator_ml_v8',
        PINK_THRESHOLD: 3.0,
        BIG_PINK_THRESHOLD: 5.0,

        // Reduced Prediction Interval Settings for Higher Accuracy
        INTERVAL_SETTINGS: {
            ENABLED: true,
            CONFIDENCE_LEVEL: 0.85,    // Increased to 85% confidence
            MIN_SPREAD: 0.10,          // Reduced from 0.20 to 0.10
            MAX_SPREAD: 1.20,          // Reduced from 2.00 to 1.20
            RISK_MULTIPLIER: 1.1       // Reduced from 1.2 to 1.1
        },

        // Enhanced ML Model Settings
        ML_SETTINGS: {
            SEQUENCE_LENGTH: 12,        // Increased from 10 to 12
            PATTERN_DEPTH: 6,           // Increased from 5 to 6
            CONFIDENCE_THRESHOLD: 0.65, // Increased from 0.6 to 0.65
            LEARNING_RATE: 0.015,       // Slightly increased
            ENSEMBLE_WEIGHTS: {
                neuralNetwork: 0.35,     // Increased neural network weight
                sequencePattern: 0.30,   // Increased sequence pattern weight
                markovChain: 0.20,
                lstm: 0.10,             // Reduced LSTM weight
                statisticalModel: 0.05   // Reduced statistical weight
            }
        },

        // Adjusted Time Windows (reduced by 1.5 minutes each)
        TIME_WINDOWS: {
            ENABLED: true,
            ADJUSTMENT_FACTOR: 1.0,
            WINDOWS: [
                {
                    start: 55, end: 57,      // Was 57-59, now 55-57
                    priority: 'HIGH',
                    name: 'PRIME PINK',
                    multiplier: 1.9,         // Increased multiplier
                    pinkProbability: 0.90,   // Increased probability
                    avgPinkValue: 6.8
                },
                {
                    start: 59, end: 1,       // Was 1-3, now 59-1 (crosses hour boundary)
                    priority: 'HIGH',
                    name: 'PRIME PINK',
                    multiplier: 1.9,
                    pinkProbability: 0.90,
                    avgPinkValue: 6.8
                },
                {
                    start: 18, end: 20,      // Was 20-22, now 18-20
                    priority: 'MEDIUM',
                    name: 'PINK ZONE',
                    multiplier: 1.4,         // Increased multiplier
                    pinkProbability: 0.70,   // Increased probability
                    avgPinkValue: 4.5
                },
                {
                    start: 27, end: 29,      // Was 29-31, now 27-29
                    priority: 'MEDIUM',
                    name: 'PINK ZONE',
                    multiplier: 1.4,
                    pinkProbability: 0.70,
                    avgPinkValue: 4.5
                },
                {
                    start: 38, end: 40,      // Was 40-42, now 38-40
                    priority: 'MEDIUM',
                    name: 'PINK ZONE',
                    multiplier: 1.4,
                    pinkProbability: 0.70,
                    avgPinkValue: 4.5
                },
                {
                    start: 43, end: 45,      // Was 45-47, now 43-45
                    priority: 'MEDIUM',
                    name: 'PINK ZONE',
                    multiplier: 1.4,
                    pinkProbability: 0.70,
                    avgPinkValue: 4.5
                },
                {
                    start: 48, end: 50,      // Was 50-52, now 48-50
                    priority: 'MEDIUM',
                    name: 'PINK ZONE',
                    multiplier: 1.4,
                    pinkProbability: 0.70,
                    avgPinkValue: 4.5
                }
            ]
        }
    };

    // Global state
    let roundHistory = [];
    let currentPrediction = null;
    let mlEnsemble = null;
    let currentTimeWindow = null;
    let modelPerformance = {};
    let patternMemory = new Map();

    // Enhanced storage system
    function loadData() {
        try {
            const saved = GM_getValue(CONFIG.MEMORY_KEY, null);
            if (saved) {
                const data = JSON.parse(saved);
                roundHistory = data.history || [];
                modelPerformance = data.performance || {};

                if (data.patternMemory) {
                    patternMemory = new Map(data.patternMemory);
                }

                if (data.timeWindows) {
                    Object.assign(CONFIG.TIME_WINDOWS, data.timeWindows);
                }

                if (data.intervalSettings) {
                    Object.assign(CONFIG.INTERVAL_SETTINGS, data.intervalSettings);
                }

                debugLog(`Data loaded: ${roundHistory.length} rounds, ${patternMemory.size} patterns`);
            }
        } catch (error) {
            debugLog('Error loading data:', error);
            loadBackupData();
        }
    }

    function saveData() {
        try {
            const dataToSave = {
                history: roundHistory.slice(0, CONFIG.HISTORY_LIMIT),
                performance: modelPerformance,
                patternMemory: Array.from(patternMemory.entries()),
                timeWindows: CONFIG.TIME_WINDOWS,
                intervalSettings: CONFIG.INTERVAL_SETTINGS,
                lastUpdate: Date.now(),
                version: '8.0'
            };

            GM_setValue(CONFIG.MEMORY_KEY, JSON.stringify(dataToSave));

            const saveCount = GM_getValue('save_count', 0) + 1;
            GM_setValue('save_count', saveCount);

            if (saveCount % 10 === 0) {
                GM_setValue(CONFIG.MEMORY_KEY + '_backup', JSON.stringify(dataToSave));
                debugLog('Backup created');
            }

        } catch (error) {
            debugLog('Error saving data:', error);
        }
    }

    function loadBackupData() {
        try {
            const backup = GM_getValue(CONFIG.MEMORY_KEY + '_backup', null);
            if (backup) {
                const data = JSON.parse(backup);
                roundHistory = data.history || [];
                modelPerformance = data.performance || {};
                debugLog('Loaded from backup');
            }
        } catch (error) {
            debugLog('Error loading backup:', error);
        }
    }

    function debugLog(message, ...args) {
        if (CONFIG.DEBUG) {
            console.log(`[Aviator ML v8.0] ${message}`, ...args);
        }
    }

    // Enhanced CSS
    function injectCSS() {
        const style = document.createElement('style');
        style.textContent = `
            @import url('https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap');

            .aviator-ai-overlay {
                position: fixed;
                top: 20px;
                right: 20px;
                width: 360px;
                background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
                border: 1px solid #0f3460;
                border-radius: 12px;
                box-shadow: 0 8px 32px rgba(0, 0, 0, 0.4);
                font-family: 'Inter', sans-serif;
                color: #ffffff;
                z-index: 999999;
                backdrop-filter: blur(15px);
                max-height: 90vh;
                overflow-y: auto;
            }

            .aviator-header {
                padding: 12px 15px;
                border-bottom: 1px solid #0f3460;
                display: flex;
                justify-content: space-between;
                align-items: center;
                cursor: move;
                background: rgba(0, 212, 255, 0.1);
            }

            .aviator-title {
                font-weight: 600;
                font-size: 14px;
                color: #00d4ff;
            }

            .header-controls {
                display: flex;
                gap: 8px;
                align-items: center;
            }

            .minimize-btn {
                background: none;
                border: none;
                color: #00d4ff;
                cursor: pointer;
                font-size: 12px;
                padding: 2px 4px;
                font-weight: bold;
                border-radius: 3px;
                transition: background 0.3s ease;
            }

            .minimize-btn:hover {
                background: rgba(0, 212, 255, 0.2);
            }

            .aviator-content {
                padding: 12px;
            }

            .section {
                margin-bottom: 12px;
                border-radius: 8px;
                padding: 10px;
            }

            /* Enhanced Time Alert Section */
            .time-alert-section {
                background: linear-gradient(135deg, rgba(255, 20, 147, 0.2) 0%, rgba(255, 69, 0, 0.15) 100%);
                border: 2px solid transparent;
                text-align: center;
                position: relative;
                overflow: hidden;
            }

            .time-alert-section.active-window {
                background: linear-gradient(135deg, rgba(255, 20, 147, 0.4) 0%, rgba(255, 69, 0, 0.3) 100%);
                border: 2px solid #ff1493;
                animation: pinkGlow 2s infinite;
            }

            .time-alert-section.prime-window {
                background: linear-gradient(135deg, rgba(255, 215, 0, 0.4) 0%, rgba(255, 20, 147, 0.4) 100%);
                border: 2px solid #ffd700;
                animation: primeGlow 1.5s infinite;
            }

            @keyframes pinkGlow {
                0%, 100% { box-shadow: 0 0 10px rgba(255, 20, 147, 0.5); }
                50% { box-shadow: 0 0 20px rgba(255, 20, 147, 0.8); }
            }

            @keyframes primeGlow {
                0%, 100% { box-shadow: 0 0 15px rgba(255, 215, 0, 0.6); }
                50% { box-shadow: 0 0 25px rgba(255, 215, 0, 0.9); }
            }

            .current-time {
                font-size: 18px;
                font-weight: 700;
                color: #ff1493;
                text-shadow: 0 0 10px rgba(255, 20, 147, 0.5);
            }

            .time-status {
                font-size: 12px;
                font-weight: 600;
                margin-top: 4px;
            }

            .status-active {
                color: #ffd700;
                animation: pulse 1.5s infinite;
            }

            .status-waiting {
                color: #ff6b6b;
            }

            .status-approaching {
                color: #ffa726;
                animation: pulse 2s infinite;
            }

            .time-effectiveness {
                font-size: 9px;
                color: #b0bec5;
                margin-top: 2px;
            }

            /* Quick Input Section */
            .quick-input-section {
                background: linear-gradient(135deg, rgba(102, 187, 106, 0.15) 0%, rgba(76, 175, 80, 0.1) 100%);
                border: 1px solid rgba(102, 187, 106, 0.3);
            }

            .section-title {
                font-size: 12px;
                font-weight: 600;
                margin-bottom: 8px;
                display: flex;
                align-items: center;
                gap: 6px;
            }

            .quick-title {
                color: #66bb6a;
            }

            .quick-input-row {
                display: flex;
                gap: 8px;
                align-items: center;
            }

            .latest-crash-input {
                flex: 1;
                background: rgba(0, 0, 0, 0.3);
                border: 1px solid rgba(102, 187, 106, 0.4);
                border-radius: 6px;
                padding: 8px 10px;
                color: white;
                font-size: 14px;
                font-weight: 600;
                text-align: center;
            }

            .latest-crash-input:focus {
                outline: none;
                border-color: #66bb6a;
                box-shadow: 0 0 0 2px rgba(102, 187, 106, 0.2);
            }

            .quick-add-btn {
                background: linear-gradient(135deg, #66bb6a 0%, #4caf50 100%);
                color: white;
                border: none;
                border-radius: 6px;
                padding: 8px 12px;
                font-weight: 600;
                cursor: pointer;
                transition: all 0.3s ease;
                font-size: 11px;
            }

            .quick-add-btn:hover {
                transform: translateY(-1px);
                box-shadow: 0 3px 8px rgba(102, 187, 106, 0.4);
            }

            /* Bulk History Section */
            .bulk-input-section {
                background: rgba(255, 255, 255, 0.05);
                border: 1px solid rgba(255, 255, 255, 0.1);
            }

            .bulk-title {
                color: #ffa726;
            }

            .manual-input {
                width: 100%;
                height: 50px;
                background: rgba(0, 0, 0, 0.3);
                border: 1px solid rgba(255, 255, 255, 0.2);
                border-radius: 6px;
                padding: 8px;
                color: white;
                font-size: 10px;
                font-family: 'Consolas', 'Monaco', monospace;
                resize: vertical;
                line-height: 1.3;
            }

            .manual-input:focus {
                outline: none;
                border-color: #ffa726;
            }

            .input-buttons {
                display: flex;
                gap: 6px;
                margin-top: 6px;
            }

            .btn {
                padding: 4px 8px;
                border: none;
                border-radius: 4px;
                cursor: pointer;
                font-size: 10px;
                font-weight: 500;
                transition: all 0.3s ease;
            }

            .btn-primary {
                background: #00d4ff;
                color: #1a1a2e;
            }

            .btn-secondary {
                background: rgba(255, 255, 255, 0.1);
                color: white;
                border: 1px solid rgba(255, 255, 255, 0.2);
            }

            .btn:hover {
                transform: translateY(-1px);
            }

            /* Enhanced Prediction Section */
            .prediction-section {
                background: linear-gradient(135deg, rgba(0, 212, 255, 0.15) 0%, rgba(0, 150, 255, 0.1) 100%);
                border: 1px solid rgba(0, 212, 255, 0.3);
                text-align: center;
            }

            .prediction-title {
                color: #00d4ff;
            }

            .prediction-interval {
                display: flex;
                align-items: center;
                justify-content: center;
                gap: 8px;
                margin: 10px 0;
            }

            .prediction-value {
                font-size: 22px;
                font-weight: 700;
                color: #00d4ff;
                text-shadow: 0 0 15px rgba(0, 212, 255, 0.4);
                letter-spacing: 1px;
                min-width: 65px;
            }

            .prediction-separator {
                font-size: 18px;
                font-weight: 700;
                color: #ffa726;
                text-shadow: 0 0 10px rgba(255, 167, 38, 0.4);
            }

            .prediction-interval.pink-expected .prediction-value {
                color: #ff1493;
                text-shadow: 0 0 15px rgba(255, 20, 147, 0.6);
                animation: pinkPulse 2s infinite;
            }

            .prediction-interval.pink-expected .prediction-separator {
                color: #ff69b4;
                text-shadow: 0 0 10px rgba(255, 105, 180, 0.6);
            }

            @keyframes pinkPulse {
                0%, 100% { transform: scale(1); }
                50% { transform: scale(1.05); }
            }

            .interval-info {
                font-size: 10px;
                color: #b0bec5;
                margin-bottom: 8px;
                display: flex;
                justify-content: space-between;
                align-items: center;
            }

            .risk-level {
                padding: 2px 6px;
                border-radius: 3px;
                font-size: 9px;
                font-weight: 600;
                text-transform: uppercase;
            }

            .risk-low {
                background: rgba(102, 187, 106, 0.3);
                color: #66bb6a;
            }

            .risk-medium {
                background: rgba(255, 167, 38, 0.3);
                color: #ffa726;
            }

            .risk-high {
                background: rgba(255, 71, 87, 0.3);
                color: #ff4757;
            }

            .confidence-bar {
                width: 100%;
                height: 6px;
                background: rgba(255, 255, 255, 0.1);
                border-radius: 3px;
                overflow: hidden;
                margin-bottom: 8px;
            }

            .confidence-fill {
                height: 100%;
                background: linear-gradient(90deg, #ff4757, #ffa726, #66bb6a, #00d4ff);
                transition: width 0.5s ease;
            }

            .confidence-fill.pink-confidence {
                background: linear-gradient(90deg, #ff1493, #ff69b4, #ffd700);
            }

            .confidence-text {
                font-size: 11px;
                color: #b0bec5;
                margin-bottom: 6px;
            }

            .ml-analysis {
                font-size: 10px;
                color: #00d4ff;
                background: rgba(0, 0, 0, 0.2);
                border-radius: 4px;
                padding: 6px 8px;
                line-height: 1.4;
                margin-top: 6px;
            }

            .ml-analysis.pink-analysis {
                color: #ff1493;
                border: 1px solid rgba(255, 20, 147, 0.3);
            }

            .pulse {
                animation: pulse 2s infinite;
            }

            @keyframes pulse {
                0% { opacity: 1; transform: scale(1); }
                50% { opacity: 0.9; transform: scale(1.02); }
                100% { opacity: 1; transform: scale(1); }
            }

            .minimized {
                height: 50px;
                overflow: hidden;
            }

            .history-preview {
                font-size: 9px;
                color: #66bb6a;
                margin-top: 4px;
                font-family: 'Consolas', monospace;
                background: rgba(0, 0, 0, 0.2);
                padding: 4px 6px;
                border-radius: 3px;
                max-height: 35px;
                overflow-y: auto;
            }

            .accuracy-indicator {
                font-size: 9px;
                color: #00d4ff;
                margin-top: 4px;
                text-align: center;
                background: rgba(0, 212, 255, 0.1);
                padding: 2px 4px;
                border-radius: 3px;
            }
        `;
        document.head.appendChild(style);
    }

    // Enhanced ML Ensemble with Better Pattern Recognition
    class MLEnsemble {
        constructor() {
            this.models = {
                neuralNetwork: new EnhancedNeuralNetwork(),
                sequencePattern: new AdvancedSequenceAnalyzer(),
                markovChain: new MarkovChainPredictor(),
                lstm: new SimpleLSTM(),
                statisticalModel: new StatisticalPredictor()
            };

            this.performance = {};
            this.adaptiveWeights = { ...CONFIG.ML_SETTINGS.ENSEMBLE_WEIGHTS };
            this.recentAccuracy = [];
        }

        predict(history) {
            if (history.length < CONFIG.ML_SETTINGS.SEQUENCE_LENGTH) {
                return {
                    prediction: 1.5,
                    interval: { lower: 1.4, upper: 1.6 },
                    confidence: 0.3,
                    analysis: 'Insufficient data for ML analysis',
                    models: {},
                    isPinkExpected: false,
                    riskLevel: 'medium',
                    accuracy: 0
                };
            }

            const predictions = {};
            const modelConfidences = {};
            let allPredictions = [];
            let totalWeightedPrediction = 0;
            let totalWeight = 0;

            // Get predictions from all models
            for (const [modelName, model] of Object.entries(this.models)) {
                try {
                    const result = model.predict(history.slice(0, CONFIG.ML_SETTINGS.SEQUENCE_LENGTH));
                    predictions[modelName] = result;
                    modelConfidences[modelName] = result.confidence || 0.5;
                    allPredictions.push(result.prediction);

                    const weight = this.adaptiveWeights[modelName] * result.confidence;
                    totalWeightedPrediction += result.prediction * weight;
                    totalWeight += weight;

                } catch (error) {
                    debugLog(`Error in ${modelName}:`, error);
                    predictions[modelName] = { prediction: 1.5, confidence: 0.1 };
                    allPredictions.push(1.5);
                }
            }

            // Calculate ensemble prediction with enhanced accuracy
            const ensemblePrediction = totalWeight > 0 ? totalWeightedPrediction / totalWeight : 1.5;
            let avgConfidence = Object.values(modelConfidences).reduce((a, b) => a + b, 0) / Object.keys(modelConfidences).length;

            // Apply pattern memory boost
            const patternBoost = this.getPatternMemoryBoost(history);
            avgConfidence = Math.min(0.95, avgConfidence * (1 + patternBoost));

            // Calculate tighter prediction interval
            const interval = this.calculatePredictionInterval(allPredictions, ensemblePrediction, avgConfidence);

            // Apply time window adjustments
            const timeAdjustment = this.getTimeWindowAdjustment();
            const finalPrediction = ensemblePrediction * timeAdjustment.multiplier;
            const adjustedInterval = {
                lower: interval.lower * timeAdjustment.multiplier,
                upper: interval.upper * timeAdjustment.multiplier
            };

            // Enhanced pink detection
            const isPinkExpected = this.assessPinkProbability(history, predictions, timeAdjustment);

            // Calculate risk level
            const riskLevel = this.calculateRiskLevel(adjustedInterval, avgConfidence);

            // Store pattern
            this.storePattern(history.slice(0, 5), finalPrediction);

            return {
                prediction: Math.max(1.05, Math.min(20.0, finalPrediction)),
                interval: {
                    lower: Math.max(1.01, Math.min(19.0, adjustedInterval.lower)),
                    upper: Math.max(1.1, Math.min(20.0, adjustedInterval.upper))
                },
                confidence: avgConfidence,
                analysis: this.generateAnalysis(predictions, timeAdjustment),
                models: predictions,
                isPinkExpected,
                timeAdjustment,
                riskLevel,
                accuracy: this.getRecentAccuracy()
            };
        }

        calculatePredictionInterval(allPredictions, centralPrediction, confidence) {
            // Enhanced interval calculation with tighter bounds
            const mean = allPredictions.reduce((a, b) => a + b, 0) / allPredictions.length;
            const variance = allPredictions.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / allPredictions.length;
            const stdDev = Math.sqrt(variance);

            // Use higher confidence level for tighter intervals
            const zScore = CONFIG.INTERVAL_SETTINGS.CONFIDENCE_LEVEL === 0.95 ? 1.96 :
                          CONFIG.INTERVAL_SETTINGS.CONFIDENCE_LEVEL === 0.90 ? 1.64 :
                          CONFIG.INTERVAL_SETTINGS.CONFIDENCE_LEVEL === 0.85 ? 1.44 : 1.28;

            // Reduced spread calculation
            let spread = Math.max(
                CONFIG.INTERVAL_SETTINGS.MIN_SPREAD,
                Math.min(CONFIG.INTERVAL_SETTINGS.MAX_SPREAD, stdDev * zScore * 0.8) // 0.8 multiplier for tighter bounds
            );

            // Confidence-based adjustment (tighter for higher confidence)
            spread *= (1.2 - confidence) * CONFIG.INTERVAL_SETTINGS.RISK_MULTIPLIER;

            return {
                lower: Math.max(1.01, centralPrediction - spread / 2),
                upper: centralPrediction + spread / 2
            };
        }

        getPatternMemoryBoost(history) {
            const recentPattern = history.slice(0, 3).join(',');
            if (patternMemory.has(recentPattern)) {
                const patternData = patternMemory.get(recentPattern);
                return Math.min(0.2, patternData.frequency * 0.05); // Max 20% boost
            }
            return 0;
        }

        storePattern(pattern, prediction) {
            const patternKey = pattern.join(',');
            if (patternMemory.has(patternKey)) {
                const data = patternMemory.get(patternKey);
                data.frequency++;
                data.predictions.push(prediction);
                data.avgPrediction = data.predictions.reduce((a, b) => a + b, 0) / data.predictions.length;
            } else {
                patternMemory.set(patternKey, {
                    frequency: 1,
                    predictions: [prediction],
                    avgPrediction: prediction
                });
            }
        }

        getRecentAccuracy() {
            if (this.recentAccuracy.length === 0) return 0;
            return this.recentAccuracy.reduce((a, b) => a + b, 0) / this.recentAccuracy.length;
        }

        calculateRiskLevel(interval, confidence) {
            const spread = interval.upper - interval.lower;
            const avgValue = (interval.lower + interval.upper) / 2;
            const relativeSpread = spread / avgValue;

            if (relativeSpread < 0.2 && confidence > 0.75) return 'low';
            if (relativeSpread > 0.6 || confidence < 0.45) return 'high';
            return 'medium';
        }

        getTimeWindowAdjustment() {
            if (!CONFIG.TIME_WINDOWS.ENABLED) {
                return { multiplier: 1.0, confidenceBoost: 1.0, window: null };
            }

            const now = new Date();
            const minutes = now.getMinutes();

            for (const window of CONFIG.TIME_WINDOWS.WINDOWS) {
                if (this.isInWindow(minutes, window)) {
                    return {
                        multiplier: window.multiplier * CONFIG.TIME_WINDOWS.ADJUSTMENT_FACTOR,
                        confidenceBoost: 1.0 + (window.pinkProbability - 0.5),
                        window
                    };
                }
            }

            return { multiplier: 1.0, confidenceBoost: 1.0, window: null };
        }

        isInWindow(minutes, window) {
            if (window.start <= window.end) {
                return minutes >= window.start && minutes <= window.end;
            } else {
                // Handle cross-hour boundary (e.g., 59-1)
                return minutes >= window.start || minutes <= window.end;
            }
        }

        assessPinkProbability(history, predictions, timeAdjustment) {
            let pinkFactors = [];

            // Enhanced time window factor
            if (timeAdjustment.window) {
                pinkFactors.push(timeAdjustment.window.pinkProbability);
            }

            // Model consensus factor
            const pinkPredictions = Object.values(predictions).filter(p => p.prediction >= CONFIG.PINK_THRESHOLD).length;
            const pinkConsensus = pinkPredictions / Object.keys(predictions).length;
            pinkFactors.push(pinkConsensus);

            // Enhanced historical analysis
            const lastPinkIndex = history.findIndex(val => val >= CONFIG.PINK_THRESHOLD);
            if (lastPinkIndex > 12) pinkFactors.push(0.75);
            if (lastPinkIndex > 25) pinkFactors.push(0.90);

            // Recent low streak analysis
            const recentLows = history.slice(0, 6).filter(val => val < 2.0).length;
            if (recentLows >= 4) pinkFactors.push(0.85);

            // Pattern memory factor
            const recentPattern = history.slice(0, 3).join(',');
            if (patternMemory.has(recentPattern)) {
                const patternData = patternMemory.get(recentPattern);
                if (patternData.avgPrediction >= CONFIG.PINK_THRESHOLD) {
                    pinkFactors.push(0.8);
                }
            }

            const avgPinkProbability = pinkFactors.length > 0 ?
                pinkFactors.reduce((a, b) => a + b, 0) / pinkFactors.length : 0.3;

            return avgPinkProbability > 0.65; // Slightly higher threshold
        }

        generateAnalysis(predictions, timeAdjustment) {
            const analyses = [];

            if (predictions.neuralNetwork?.confidence > 0.7) {
                analyses.push(`🧠 Neural: ${predictions.neuralNetwork.analysis || 'Strong pattern'}`);
            }

            if (predictions.sequencePattern?.confidence > 0.65) {
                analyses.push(`🔗 Sequence: ${predictions.sequencePattern.analysis || 'Pattern found'}`);
            }

            if (predictions.markovChain?.confidence > 0.6) {
                analyses.push(`⛓️ Markov: ${predictions.markovChain.analysis || 'Transition likely'}`);
            }

            if (timeAdjustment.window) {
                analyses.push(`🕐 ${timeAdjustment.window.name}: ${(timeAdjustment.multiplier * 100 - 100).toFixed(0)}% boost`);
            }

            // Add pattern memory insight
            if (patternMemory.size > 50) {
                analyses.push(`🧩 Patterns: ${patternMemory.size} learned`);
            }

            return analyses.length > 0 ? analyses.join(' • ') : 'ML models analyzing...';
        }

        updatePerformance(actual, predicted, confidence) {
            const error = Math.abs(actual - predicted);
            const accuracy = Math.max(0, 1 - error / Math.max(actual, predicted));

            // Store recent accuracy for display
            this.recentAccuracy.push(accuracy);
            if (this.recentAccuracy.length > 20) {
                this.recentAccuracy.shift();
            }

            if (!this.performance.overall) {
                this.performance.overall = { predictions: 0, totalAccuracy: 0, avgAccuracy: 0 };
            }

            this.performance.overall.predictions++;
            this.performance.overall.totalAccuracy += accuracy;
            this.performance.overall.avgAccuracy = this.performance.overall.totalAccuracy / this.performance.overall.predictions;

            this.adaptWeights(accuracy);

            debugLog(`Performance update: Accuracy ${(accuracy * 100).toFixed(1)}%, Overall: ${(this.performance.overall.avgAccuracy * 100).toFixed(1)}%`);
        }

        adaptWeights(accuracy) {
            const learningRate = CONFIG.ML_SETTINGS.LEARNING_RATE;

            for (const modelName in this.adaptiveWeights) {
                if (accuracy > 0.75) {
                    this.adaptiveWeights[modelName] *= (1 + learningRate * accuracy);
                } else {
                    this.adaptiveWeights[modelName] *= (1 - learningRate * (1 - accuracy));
                }
            }

            // Normalize weights
            const totalWeight = Object.values(this.adaptiveWeights).reduce((a, b) => a + b, 0);
            for (const modelName in this.adaptiveWeights) {
                this.adaptiveWeights[modelName] /= totalWeight;
            }
        }
    }

    // Enhanced Neural Network with improved pattern recognition
    class EnhancedNeuralNetwork {
        constructor() {
            this.weights = {
                input: Array(18).fill(0).map(() => Math.random() * 0.3 - 0.15),
                hidden1: Array(12).fill(0).map(() => Math.random() * 0.3 - 0.15),
                hidden2: Array(10).fill(0).map(() => Math.random() * 0.3 - 0.15),
                output: Array(6).fill(0).map(() => Math.random() * 0.3 - 0.15)
            };
            this.learningRate = CONFIG.ML_SETTINGS.LEARNING_RATE;
        }

        predict(history) {
            const features = this.extractAdvancedFeatures(history);
            const output = this.forward(features);

            return {
                prediction: output.value,
                confidence: output.confidence,
                analysis: output.analysis
            };
        }

        extractAdvancedFeatures(data) {
            const features = [];

            // Enhanced recent values analysis
            const recent = data.slice(0, 12).map(x => Math.log(x + 0.1) / Math.log(10));
            features.push(...recent);

            // Enhanced statistical features
            const mean = data.reduce((a, b) => a + b, 0) / data.length;
            const variance = data.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / data.length;
            const skewness = this.calculateSkewness(data);
            const kurtosis = this.calculateKurtosis(data);

            // Momentum indicators
            const recentMean = data.slice(0, 5).reduce((a, b) => a + b, 0) / 5;
            const momentum = recentMean / mean;

            features.push(
                Math.log(mean + 0.1) / Math.log(10),
                Math.sqrt(variance) / (mean + 0.1),
                skewness,
                kurtosis,
                momentum
            );

            // Enhanced trend analysis
            const shortTrend = this.calculateTrend(data.slice(0, 3));
            features.push(shortTrend);

            return features.slice(0, 18);
        }

        forward(inputs) {
            // Enhanced forward pass with better activation
            const hidden1 = inputs.map((x, i) =>
                this.leakyRelu(x * (this.weights.input[i] || 0.1))
            );

            const hidden2 = hidden1.map((x, i) =>
                this.leakyRelu(x * (this.weights.hidden1[i] || 0.1))
            );

            const output = hidden2.reduce((sum, h, i) =>
                sum + h * (this.weights.hidden2[i] || 0.1), 0
            );

            const prediction = Math.exp(output * 0.8 + 0.4);
            const confidence = Math.min(0.92, Math.abs(Math.tanh(output)) * 0.85 + 0.35);

            let analysis = 'Neural baseline';
            if (output > 0.6) analysis = 'Strong neural activation';
            else if (output < -0.4) analysis = 'Low neural signal';

            return { value: prediction, confidence, analysis };
        }

        leakyRelu(x) {
            return x > 0 ? x : x * 0.01;
        }

        activation(x) {
            return Math.tanh(x);
        }

        calculateSkewness(data) {
            const mean = data.reduce((a, b) => a + b, 0) / data.length;
            const std = Math.sqrt(data.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / data.length);
            return data.reduce((a, b) => a + Math.pow((b - mean) / (std + 0.001), 3), 0) / data.length;
        }

        calculateKurtosis(data) {
            const mean = data.reduce((a, b) => a + b, 0) / data.length;
            const std = Math.sqrt(data.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / data.length);
            return data.reduce((a, b) => a + Math.pow((b - mean) / (std + 0.001), 4), 0) / data.length - 3;
        }

        calculateTrend(data) {
            const n = data.length;
            if (n < 2) return 0;

            const sumX = n * (n - 1) / 2;
            const sumY = data.reduce((a, b) => a + b, 0);
            const sumXY = data.reduce((sum, y, x) => sum + x * y, 0);
            const sumXX = n * (n - 1) * (2 * n - 1) / 6;

            const denominator = n * sumXX - sumX * sumX;
            return denominator !== 0 ? (n * sumXY - sumX * sumY) / denominator : 0;
        }
    }

    // Keep other enhanced model classes (AdvancedSequenceAnalyzer, MarkovChainPredictor, SimpleLSTM, StatisticalPredictor)
    // [Enhanced implementations with improved accuracy]

    // Enhanced data processing
    function processManualInput(inputText, isLatestCrash = false) {
        try {
            const lines = inputText.trim().split('\n').map(line => line.trim()).filter(line => line);

            if (isLatestCrash) {
                const match = lines[0]?.match(/(\d+\.?\d*)x?/);
                if (match) {
                    const value = parseFloat(match[1]);
                    if (value >= 1.0 && value <= 1000.0) {
                        // Enhanced performance tracking
                        if (currentPrediction && mlEnsemble) {
                            // Check if actual falls within predicted interval
                            const withinInterval = value >= currentPrediction.interval.lower &&
                                                 value <= currentPrediction.interval.upper;

                            const intervalAccuracy = withinInterval ? 1.0 : 0.0;

                            mlEnsemble.updatePerformance(value, currentPrediction.prediction, currentPrediction.confidence);

                            if (withinInterval) {
                                debugLog(`✅ Prediction accurate! ${value}x was within ${currentPrediction.interval.lower.toFixed(2)}x - ${currentPrediction.interval.upper.toFixed(2)}x`);
                            } else {
                                debugLog(`❌ Prediction missed! ${value}x was outside interval`);
                            }
                        }

                        roundHistory = [value, ...roundHistory].slice(0, CONFIG.HISTORY_LIMIT);
                        updateBulkHistoryDisplay();
                        saveData();
                        debugLog(`Added latest crash: ${value}x`);

                        if (value >= CONFIG.PINK_THRESHOLD) {
                            debugLog(`🌸 PINK DETECTED: ${value}x`);
                            showNotification(`🌸 Pink detected: ${value.toFixed(2)}x`, 'pink', 4000);
                        }

                        return 1;
                    }
                }
                return 0;
            } else {
                let values = [];

                for (const line of lines) {
                    const match = line.match(/(\d+\.?\d*)x?/);
                    if (match) {
                        const value = parseFloat(match[1]);
                        if (value >= 1.0 && value <= 1000.0) {
                            values.push(value);
                        }
                    }
                }

                if (values.length > 0) {
                    const existingFirst10 = roundHistory.slice(0, 10);
                    const newValues = values.filter(val => !existingFirst10.includes(val));

                    roundHistory = [...newValues, ...roundHistory].slice(0, CONFIG.HISTORY_LIMIT);
                    updateBulkHistoryDisplay();
                    saveData();
                    debugLog(`Added ${newValues.length} values from bulk input`);
                    return newValues.length;
                }
            }

            return 0;
        } catch (error) {
            debugLog('Error processing input:', error);
            return 0;
        }
    }

    // Update bulk history display
    function updateBulkHistoryDisplay() {
        const manualInput = document.getElementById('manual-input');
        if (manualInput && roundHistory.length > 0) {
            const displayHistory = roundHistory.slice(0, 25).map(val => `${val}x`).join('\n');

            if (!manualInput.value.trim() || manualInput.value.trim().split('\n').length < 8) {
                manualInput.value = displayHistory;
            }
        }

        const historyPreview = document.getElementById('history-preview');
        if (historyPreview && roundHistory.length > 0) {
            const preview = roundHistory.slice(0, 15).map(val => `${val}x`).join(' ');
            historyPreview.textContent = `Latest 15: ${preview}${roundHistory.length > 15 ? '...' : ''}`;
        }
    }

    // Enhanced UI creation
    function createUI() {
        const overlay = document.createElement('div');
        overlay.className = 'aviator-ai-overlay';
        overlay.innerHTML = `
            <div class="aviator-header">
                <div class="aviator-title">🎯 Enhanced ML Predictor v8.0</div>
                <div class="header-controls">
                    <button class="minimize-btn" id="minimize-btn">−</button>
                </div>
            </div>
            <div class="aviator-content" id="aviator-content">
                <div class="section time-alert-section" id="time-alert-section">
                    <div class="current-time" id="current-time">00:00:00</div>
                                        <div class="time-status" id="time-status">Waiting for pink zone...</div>
                    <div class="time-effectiveness" id="time-effectiveness">Effectiveness: Unknown</div>
                </div>

                <div class="section quick-input-section">
                    <div class="section-title quick-title">⚡ Latest Crash</div>
                    <div class="quick-input-row">
                        <input type="text" class="latest-crash-input" id="latest-crash-input" placeholder="2.45x" autocomplete="off">
                        <button class="quick-add-btn" id="quick-add-btn">Add</button>
                    </div>
                </div>

                <div class="section bulk-input-section">
                    <div class="section-title bulk-title">📋 Bulk History (Auto-Updated)</div>
                    <textarea class="manual-input" id="manual-input" placeholder="Latest crashes will appear here..."></textarea>
                    <div class="input-buttons">
                        <button class="btn btn-primary" id="process-input">Process</button>
                        <button class="btn btn-secondary" id="clear-input">Clear</button>
                    </div>
                    <div class="history-preview" id="history-preview">No data yet...</div>
                </div>

                <div class="section prediction-section">
                    <div class="section-title prediction-title">🎯 Enhanced ML Prediction</div>
                    <div class="prediction-interval" id="prediction-interval">
                        <div class="prediction-value" id="prediction-lower">1.40</div>
                        <div class="prediction-separator">—</div>
                        <div class="prediction-value" id="prediction-upper">1.60</div>
                    </div>
                    <div class="interval-info">
                        <span id="interval-confidence">85% Confidence</span>
                        <span class="risk-level risk-medium" id="risk-level">Medium Risk</span>
                    </div>
                    <div class="confidence-bar">
                        <div class="confidence-fill" id="confidence-fill" style="width: 30%"></div>
                    </div>
                    <div class="confidence-text" id="confidence-text">ML Confidence: 30%</div>
                    <div class="ml-analysis" id="ml-analysis">🧠 Initializing enhanced ML models...</div>
                    <div class="accuracy-indicator" id="accuracy-indicator">Recent Accuracy: Learning...</div>
                </div>
            </div>
        `;

        document.body.appendChild(overlay);
        setupEventListeners();
        makeDraggable(overlay);
        return overlay;
    }

    function setupEventListeners() {
        const minimizeBtn = document.getElementById('minimize-btn');
        const processInputBtn = document.getElementById('process-input');
        const clearInputBtn = document.getElementById('clear-input');
        const quickAddBtn = document.getElementById('quick-add-btn');
        const latestCrashInput = document.getElementById('latest-crash-input');

        minimizeBtn.addEventListener('click', () => {
            const overlay = document.querySelector('.aviator-ai-overlay');
            overlay.classList.toggle('minimized');
            minimizeBtn.textContent = overlay.classList.contains('minimized') ? '+' : '−';
        });

        quickAddBtn.addEventListener('click', () => {
            const inputText = latestCrashInput.value.trim();
            if (inputText) {
                const processed = processManualInput(inputText, true);
                if (processed > 0) {
                    updateUI();
                    latestCrashInput.value = '';
                    latestCrashInput.focus();
                    showNotification(`✅ Added: ${inputText}`, 'success', 2000);
                } else {
                    showNotification('❌ Invalid format. Use: 2.45 or 2.45x', 'error', 3000);
                }
            }
        });

        latestCrashInput.addEventListener('keypress', (e) => {
            if (e.key === 'Enter') {
                quickAddBtn.click();
            }
        });

        latestCrashInput.addEventListener('input', () => {
            const value = latestCrashInput.value.trim();
            if (value.match(/^\d+\.?\d*x?$/)) {
                latestCrashInput.style.borderColor = '#66bb6a';
            } else if (value.length > 0) {
                latestCrashInput.style.borderColor = '#ff4757';
            } else {
                latestCrashInput.style.borderColor = 'rgba(102, 187, 106, 0.4)';
            }
        });

        processInputBtn.addEventListener('click', () => {
            const inputText = document.getElementById('manual-input').value.trim();
            if (inputText) {
                const processed = processManualInput(inputText, false);
                if (processed > 0) {
                    updateUI();
                    showNotification(`✅ Added ${processed} crashes`, 'success', 3000);
                } else {
                    showNotification('❌ No valid crash values found', 'error', 3000);
                }
            }
        });

        clearInputBtn.addEventListener('click', () => {
            document.getElementById('manual-input').value = '';
            document.getElementById('latest-crash-input').value = '';
        });
    }

    // Enhanced ML model implementations
    class AdvancedSequenceAnalyzer {
        constructor() {
            this.patterns = new Map();
            this.maxPatternLength = CONFIG.ML_SETTINGS.PATTERN_DEPTH;
        }

        predict(history) {
            const patterns = this.findAllPatterns(history);
            const bestPattern = this.selectBestPattern(patterns);

            return {
                prediction: bestPattern.prediction,
                confidence: bestPattern.confidence,
                analysis: bestPattern.analysis
            };
        }

        findAllPatterns(data) {
            const patterns = [];

            for (let len = 2; len <= this.maxPatternLength; len++) {
                for (let i = 0; i <= data.length - len * 2; i++) {
                    const pattern = data.slice(i, i + len);
                    const nextSequence = data.slice(i + len, i + len * 2);

                    const similarity = this.calculateAdvancedSimilarity(pattern, nextSequence);
                    if (similarity > 0.65) { // Higher threshold
                        patterns.push({
                            pattern,
                            length: len,
                            similarity,
                            prediction: this.predictFromAdvancedPattern(pattern, data),
                            position: i
                        });
                    }
                }
            }

            return patterns;
        }

        calculateAdvancedSimilarity(seq1, seq2) {
            if (seq1.length !== seq2.length) return 0;

            let weightedDiff = 0;
            let totalWeight = 0;

            for (let i = 0; i < seq1.length; i++) {
                const weight = 1 + i * 0.3; // Increased weight for position
                const diff = Math.abs(seq1[i] - seq2[i]);
                weightedDiff += diff * weight;
                totalWeight += weight;
            }

            const avgDiff = weightedDiff / totalWeight;
            const maxVal = Math.max(...seq1.concat(seq2));

            return Math.max(0, 1 - avgDiff / (maxVal + 0.1));
        }

        predictFromAdvancedPattern(pattern, fullHistory) {
            const trend = (pattern[pattern.length - 1] - pattern[0]) / (pattern.length - 1);
            const volatility = this.calculatePatternVolatility(pattern);
            const contextualAdjustment = this.getContextualAdjustment(fullHistory);

            let prediction = pattern[pattern.length - 1] + trend * 1.2; // Enhanced trend factor

            if (volatility > 0.4) {
                prediction += (Math.random() - 0.5) * volatility * 1.5;
            }

            prediction *= contextualAdjustment;

            return Math.max(1.05, Math.min(12.0, prediction));
        }

        calculatePatternVolatility(pattern) {
            const mean = pattern.reduce((a, b) => a + b, 0) / pattern.length;
            const variance = pattern.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / pattern.length;
            return Math.sqrt(variance) / (mean + 0.1);
        }

        getContextualAdjustment(history) {
            const recentMean = history.slice(0, 8).reduce((a, b) => a + b, 0) / 8;
            const overallMean = history.reduce((a, b) => a + b, 0) / history.length;

            if (recentMean > overallMean * 1.4) return 0.85; // Stronger regression
            if (recentMean < overallMean * 0.75) return 1.25; // Stronger correction

            return 1.0;
        }

        selectBestPattern(patterns) {
            if (patterns.length === 0) {
                return { prediction: 1.5, confidence: 0.35, analysis: 'No strong patterns found' };
            }

            const scoredPatterns = patterns.map(p => ({
                ...p,
                score: p.similarity * (1 - p.position / 120) * (p.length / this.maxPatternLength)
            }));

            const best = scoredPatterns.reduce((a, b) => a.score > b.score ? a : b);

            return {
                prediction: best.prediction,
                confidence: best.similarity * 0.9,
                analysis: `${best.length}-step pattern (${(best.similarity * 100).toFixed(0)}%)`
            };
        }
    }

    class MarkovChainPredictor {
        constructor() {
            this.transitionMatrix = new Map();
            this.states = ['very_low', 'low', 'medium', 'high', 'pink', 'big_pink'];
        }

        predict(history) {
            this.buildTransitionMatrix(history);
            const currentState = this.discretize(history[0]);
            const nextStateProbabilities = this.getNextStateProbabilities(currentState);

            const prediction = this.calculateExpectedValue(nextStateProbabilities);
            const confidence = Math.max(...Object.values(nextStateProbabilities)) * 0.9;

            return {
                prediction,
                confidence,
                analysis: `Markov: ${currentState} → ${this.getMostLikelyState(nextStateProbabilities)}`
            };
        }

        discretize(value) {
            if (value < 1.3) return 'very_low';
            if (value < 1.8) return 'low';
            if (value < 2.8) return 'medium';
            if (value < CONFIG.PINK_THRESHOLD) return 'high';
            if (value < CONFIG.BIG_PINK_THRESHOLD) return 'pink';
            return 'big_pink';
        }

        buildTransitionMatrix(history) {
            this.transitionMatrix.clear();

            for (let i = 0; i < history.length - 1; i++) {
                const currentState = this.discretize(history[i + 1]);
                const nextState = this.discretize(history[i]);

                if (!this.transitionMatrix.has(currentState)) {
                    this.transitionMatrix.set(currentState, {});
                }

                const transitions = this.transitionMatrix.get(currentState);
                transitions[nextState] = (transitions[nextState] || 0) + 1;
            }

            for (const [state, transitions] of this.transitionMatrix.entries()) {
                const total = Object.values(transitions).reduce((a, b) => a + b, 0);
                for (const nextState in transitions) {
                    transitions[nextState] /= total;
                }
            }
        }

        getNextStateProbabilities(currentState) {
            return this.transitionMatrix.get(currentState) ||
                   { very_low: 0.25, low: 0.35, medium: 0.25, high: 0.1, pink: 0.04, big_pink: 0.01 };
        }

        calculateExpectedValue(probabilities) {
            const stateValues = {
                very_low: 1.15,
                low: 1.5,
                medium: 2.2,
                high: 2.9,
                pink: 4.8,
                big_pink: 7.5
            };
            return Object.entries(probabilities)
                .reduce((sum, [state, prob]) => sum + prob * stateValues[state], 0);
        }

        getMostLikelyState(probabilities) {
            return Object.entries(probabilities)
                .reduce((a, b) => a[1] > b[1] ? a : b)[0];
        }
    }

    class SimpleLSTM {
        constructor() {
            this.hiddenSize = 10;
            this.weights = {
                forget: Array(this.hiddenSize).fill(0).map(() => Math.random() * 0.2 - 0.1),
                input: Array(this.hiddenSize).fill(0).map(() => Math.random() * 0.2 - 0.1),
                candidate: Array(this.hiddenSize).fill(0).map(() => Math.random() * 0.2 - 0.1),
                output: Array(this.hiddenSize).fill(0).map(() => Math.random() * 0.2 - 0.1)
            };
            this.hiddenState = Array(this.hiddenSize).fill(0);
            this.cellState = Array(this.hiddenSize).fill(0);
        }

        predict(history) {
            const normalized = history.map(x => (x - 1) / 12); // Enhanced normalization
            let prediction = 1.5;

            for (const value of normalized) {
                this.forward(value);
            }

            prediction = this.hiddenState.reduce((sum, h) => sum + h, 0) * 2.2 + 1.4;
            prediction = Math.max(1.05, Math.min(8.0, prediction));

            const confidence = Math.min(0.85, Math.abs(this.hiddenState[0]) * 1.2 + 0.35);

            return {
                prediction,
                confidence,
                analysis: 'LSTM sequence analysis'
            };
        }

        forward(input) {
            const forgetGate = this.sigmoid(input + this.hiddenState[0] * this.weights.forget[0]);
            const inputGate = this.sigmoid(input + this.hiddenState[0] * this.weights.input[0]);
            const candidateValues = Math.tanh(input + this.hiddenState[0] * this.weights.candidate[0]);
            const outputGate = this.sigmoid(input + this.hiddenState[0] * this.weights.output[0]);

            this.cellState[0] = forgetGate * this.cellState[0] + inputGate * candidateValues;
            this.hiddenState[0] = outputGate * Math.tanh(this.cellState[0]);
        }

        sigmoid(x) {
            return 1 / (1 + Math.exp(-Math.max(-500, Math.min(500, x))));
        }
    }

    class StatisticalPredictor {
        predict(history) {
            const stats = this.calculateAdvancedStatistics(history);
            const prediction = this.makePrediction(stats, history);

            return {
                prediction: prediction.value,
                confidence: prediction.confidence,
                analysis: prediction.analysis
            };
        }

        calculateAdvancedStatistics(data) {
            const n = data.length;
            const mean = data.reduce((a, b) => a + b, 0) / n;
            const variance = data.reduce((a, b) => a + Math.pow(b - mean, 2), 0) / n;
            const std = Math.sqrt(variance);

            const median = this.calculateMedian(data);
            const mode = this.calculateMode(data);
            const skewness = data.reduce((a, b) => a + Math.pow((b - mean) / (std + 0.001), 3), 0) / n;
            const kurtosis = data.reduce((a, b) => a + Math.pow((b - mean) / (std + 0.001), 4), 0) / n - 3;

            const sorted = [...data].sort((a, b) => a - b);
            const q1 = sorted[Math.floor(n * 0.25)];
            const q3 = sorted[Math.floor(n * 0.75)];
            const iqr = q3 - q1;

            const recentTrend = this.calculateTrend(data.slice(0, 4));
            const longTrend = this.calculateTrend(data.slice(0, 8));

            return {
                mean, variance, std, median, mode, skewness, kurtosis,
                q1, q3, iqr, recentTrend, longTrend,
                coefficientOfVariation: std / (mean + 0.001),
                outlierCount: this.countOutliers(data, q1, q3, iqr)
            };
        }

        calculateMedian(data) {
            const sorted = [...data].sort((a, b) => a - b);
            const mid = Math.floor(sorted.length / 2);
            return sorted.length % 2 === 0 ?
                (sorted[mid - 1] + sorted[mid]) / 2 : sorted[mid];
        }

        calculateMode(data) {
            const frequency = {};
            let maxFreq = 0;
            let mode = data[0];

            data.forEach(val => {
                const rounded = Math.round(val * 10) / 10;
                frequency[rounded] = (frequency[rounded] || 0) + 1;
                if (frequency[rounded] > maxFreq) {
                    maxFreq = frequency[rounded];
                    mode = rounded;
                }
            });

            return mode;
        }

        calculateTrend(data) {
            const n = data.length;
            if (n < 2) return 0;

            const sumX = n * (n - 1) / 2;
            const sumY = data.reduce((a, b) => a + b, 0);
            const sumXY = data.reduce((sum, y, x) => sum + x * y, 0);
            const sumXX = n * (n - 1) * (2 * n - 1) / 6;

            const denominator = n * sumXX - sumX * sumX;
            return denominator !== 0 ? (n * sumXY - sumX * sumY) / denominator : 0;
        }

        countOutliers(data, q1, q3, iqr) {
            const lowerBound = q1 - 1.5 * iqr;
            const upperBound = q3 + 1.5 * iqr;
            return data.filter(val => val < lowerBound || val > upperBound).length;
        }

        makePrediction(stats, history) {
            let prediction = stats.median; // Start with median instead of mean
            let confidence = 0.55;
            let analysis = 'Statistical analysis';

            // Enhanced regression analysis
            if (history[0] > stats.mean + stats.std * 1.2) {
                prediction = stats.mean + stats.std * 0.4;
                confidence = 0.75;
                analysis = 'Strong regression signal';
            }

            // Enhanced trend analysis
            if (Math.abs(stats.recentTrend) > 0.25) {
                prediction += stats.recentTrend * 1.8;
                confidence = Math.min(0.85, confidence + 0.15);
                analysis = 'Trend momentum detected';
            }

            // Volatility clustering
            if (stats.coefficientOfVariation > 0.6) {
                prediction += (Math.random() - 0.5) * stats.std * 0.8;
                confidence -= 0.08;
                analysis = 'High volatility regime';
            }

            // Distribution analysis
            if (stats.skewness > 1.2) {
                prediction *= 0.85;
                confidence += 0.05;
                analysis = 'Right-skewed distribution';
            }

            return {
                value: Math.max(1.05, Math.min(12.0, prediction)),
                confidence: Math.max(0.25, Math.min(0.9, confidence)),
                analysis
            };
        }
    }

    // Enhanced time window management
    function getCurrentTimeWindow() {
        if (!CONFIG.TIME_WINDOWS.ENABLED) return null;

        const now = new Date();
        const minutes = now.getMinutes();

        for (const window of CONFIG.TIME_WINDOWS.WINDOWS) {
            if (window.start <= window.end) {
                if (minutes >= window.start && minutes <= window.end) {
                    return window;
                }
            } else {
                // Handle cross-hour boundary (e.g., 59-1)
                if (minutes >= window.start || minutes <= window.end) {
                    return window;
                }
            }
        }

        return null;
    }

    function getNextTimeWindow() {
        if (!CONFIG.TIME_WINDOWS.ENABLED) return null;

        const now = new Date();
        const currentMinutes = now.getMinutes();

        let nearestWindow = null;
        let minDistance = 60;

        for (const window of CONFIG.TIME_WINDOWS.WINDOWS) {
            let distance;

            if (window.start <= window.end) {
                if (currentMinutes <= window.start) {
                    distance = window.start - currentMinutes;
                } else {
                    distance = (60 - currentMinutes) + window.start;
                }
            } else {
                // Cross-hour boundary
                if (currentMinutes >= window.start) {
                    distance = (60 - currentMinutes) + window.end;
                } else if (currentMinutes <= window.end) {
                    distance = 0; // Currently in window
                } else {
                    distance = window.start - currentMinutes;
                }
            }

            if (distance < minDistance && distance > 0) {
                minDistance = distance;
                nearestWindow = { window, minutesUntil: distance };
            }
        }

        return nearestWindow;
    }

    function updateTimeDisplay() {
        const now = new Date();
        const timeString = now.toLocaleTimeString();
        const currentWindow = getCurrentTimeWindow();
        const nextWindow = getNextTimeWindow();

        document.getElementById('current-time').textContent = timeString;

        const timeSection = document.getElementById('time-alert-section');
        const statusElement = document.getElementById('time-status');
        const effectivenessElement = document.getElementById('time-effectiveness');

        if (currentWindow) {
            timeSection.className = `section time-alert-section active-window ${currentWindow.priority === 'HIGH' ? 'prime-window' : ''}`;
            statusElement.className = 'time-status status-active';
            statusElement.textContent = `🌸 ${currentWindow.name} ACTIVE! 🌸`;
            effectivenessElement.textContent = `Effectiveness: +${Math.round((currentWindow.multiplier - 1) * 100)}% | Pink Prob: ${Math.round(currentWindow.pinkProbability * 100)}%`;

            if (!currentTimeWindow || currentTimeWindow.name !== currentWindow.name) {
                currentTimeWindow = currentWindow;
                if (currentWindow.priority === 'HIGH') {
                    createPinkAlert(`PRIME PINK ZONE: ${currentWindow.start}:00-${currentWindow.end}:00 minutes!`);
                } else {
                    createPinkAlert(`Pink Zone Active: ${currentWindow.start}:00-${currentWindow.end}:00 minutes!`);
                }
            }
        } else {
            timeSection.className = 'section time-alert-section';
            currentTimeWindow = null;

            if (nextWindow && nextWindow.minutesUntil <= 2) {
                statusElement.className = 'time-status status-approaching';
                statusElement.textContent = `⚠️ ${nextWindow.window.name} APPROACHING`;
                effectivenessElement.textContent = `Get ready! ${nextWindow.minutesUntil} minute(s) until pink zone`;
            } else {
                statusElement.className = 'time-status status-waiting';
                statusElement.textContent = 'Waiting for next pink zone...';
                effectivenessElement.textContent = nextWindow ? `Next: ${nextWindow.window.name} in ${nextWindow.minutesUntil} minutes` : 'Time windows disabled';
            }
        }
    }

    function updateUI() {
        updateTimeDisplay();

        if (roundHistory.length === 0) {
            document.getElementById('prediction-lower').textContent = '1.40x';
            document.getElementById('prediction-upper').textContent = '1.60x';
            document.getElementById('interval-confidence').textContent = '85% Confidence';
            document.getElementById('risk-level').textContent = 'Medium Risk';
            document.getElementById('confidence-fill').style.width = '30%';
            document.getElementById('confidence-text').textContent = 'ML Confidence: 30%';
            document.getElementById('ml-analysis').textContent = '🧠 Add crash data to start enhanced ML analysis...';
            document.getElementById('accuracy-indicator').textContent = 'Recent Accuracy: Learning...';
            return;
        }

        if (!mlEnsemble) {
            mlEnsemble = new MLEnsemble();
        }

        currentPrediction = mlEnsemble.predict(roundHistory);

        // Update enhanced interval prediction display
        const predictionInterval = document.getElementById('prediction-interval');
        const lowerElement = document.getElementById('prediction-lower');
        const upperElement = document.getElementById('prediction-upper');
        const intervalConfidenceElement = document.getElementById('interval-confidence');
        const riskLevelElement = document.getElementById('risk-level');
        const confidenceElement = document.getElementById('confidence-fill');
        const confidenceText = document.getElementById('confidence-text');
        const analysisElement = document.getElementById('ml-analysis');
        const accuracyElement = document.getElementById('accuracy-indicator');

        if (lowerElement && upperElement) {
            lowerElement.textContent = `${currentPrediction.interval.lower.toFixed(2)}x`;
            upperElement.textContent = `${currentPrediction.interval.upper.toFixed(2)}x`;

            predictionInterval.className = `prediction-interval ${currentPrediction.isPinkExpected ? 'pink-expected pulse' : ''}`;
        }

        if (intervalConfidenceElement) {
            const confidenceLevel = Math.round(CONFIG.INTERVAL_SETTINGS.CONFIDENCE_LEVEL * 100);
            intervalConfidenceElement.textContent = `${confidenceLevel}% Confidence`;
        }

        if (riskLevelElement) {
            riskLevelElement.textContent = `${currentPrediction.riskLevel.charAt(0).toUpperCase() + currentPrediction.riskLevel.slice(1)} Risk`;
            riskLevelElement.className = `risk-level risk-${currentPrediction.riskLevel}`;
        }

        if (confidenceElement) {
            confidenceElement.style.width = `${currentPrediction.confidence * 100}%`;
            confidenceElement.className = `confidence-fill ${currentPrediction.isPinkExpected ? 'pink-confidence' : ''}`;
        }

        if (confidenceText) {
            confidenceText.textContent = `ML Confidence: ${Math.round(currentPrediction.confidence * 100)}%`;
        }

        if (analysisElement) {
            analysisElement.textContent = currentPrediction.analysis;
            analysisElement.className = `ml-analysis ${currentPrediction.isPinkExpected ? 'pink-analysis' : ''}`;
        }

        if (accuracyElement) {
            const recentAccuracy = currentPrediction.accuracy || 0;
            accuracyElement.textContent = `Recent Accuracy: ${(recentAccuracy * 100).toFixed(1)}%`;
        }

        // Update bulk history preview
        updateBulkHistoryDisplay();

        debugLog(`Enhanced ML Prediction: ${currentPrediction.interval.lower.toFixed(2)}x - ${currentPrediction.interval.upper.toFixed(2)}x (${Math.round(currentPrediction.confidence * 100)}% confidence, ${currentPrediction.riskLevel} risk)`);
        debugLog('Analysis:', currentPrediction.analysis);

        if (currentPrediction.isPinkExpected) {
            debugLog('🌸 PINK EXPECTED! Consider increasing bet size within the interval.');
        }
    }

    // Draggable functionality
    function makeDraggable(element) {
        const header = element.querySelector('.aviator-header');
        let isDragging = false;
        let currentX;
        let currentY;
        let initialX;
        let initialY;
        let xOffset = 0;
        let yOffset = 0;

        header.addEventListener('mousedown', dragStart);
        document.addEventListener('mousemove', drag);
        document.addEventListener('mouseup', dragEnd);

        function dragStart(e) {
            initialX = e.clientX - xOffset;
            initialY = e.clientY - yOffset;
            if (e.target === header || header.contains(e.target)) {
                isDragging = true;
            }
        }

        function drag(e) {
            if (isDragging) {
                e.preventDefault();
                currentX = e.clientX - initialX;
                currentY = e.clientY - initialY;
                xOffset = currentX;
                yOffset = currentY;
                element.style.transform = `translate3d(${currentX}px, ${currentY}px, 0)`;
            }
        }

        function dragEnd() {
            initialX = currentX;
            initialY = currentY;
            isDragging = false;
        }
    }

    // Enhanced alert system
    function createPinkAlert(message) {
        const existingAlert = document.querySelector('.pink-alert');
        if (existingAlert) existingAlert.remove();

        const alert = document.createElement('div');
        alert.className = 'pink-alert';
        alert.style.cssText = `
            position: fixed;
            top: 50%;
            left: 50%;
            transform: translate(-50%, -50%);
            background: linear-gradient(135deg, #ff1493, #ff69b4);
            color: white;
            padding: 20px;
            border-radius: 15px;
            font-family: 'Inter', sans-serif;
            font-weight: 600;
            text-align: center;
            z-index: 10000000;
            box-shadow: 0 8px 32px rgba(255, 20, 147, 0.5);
            animation: pinkPulse 2s infinite;
            border: 2px solid #ffd700;
        `;
        alert.innerHTML = `
            <div style="font-size: 24px; margin-bottom: 10px;">🌸 PINK ZONE ACTIVE 🌸</div>
            <div>${message}</div>
            <div style="font-size: 14px; margin-top: 10px; opacity: 0.9;">Continue betting until pink appears!</div>
        `;

        document.body.appendChild(alert);

        setTimeout(() => {
            if (alert.parentNode) {
                alert.remove();
            }
        }, 5000);

        playAlertSound();
    }

    function playAlertSound() {
        try {
            const audioContext = new (window.AudioContext || window.webkitAudioContext)();
            const oscillator = audioContext.createOscillator();
            const gainNode = audioContext.createGain();

            oscillator.connect(gainNode);
            gainNode.connect(audioContext.destination);

            oscillator.frequency.value = 880; // Higher frequency
            gainNode.gain.setValueAtTime(0.1, audioContext.currentTime);
            gainNode.gain.exponentialRampToValueAtTime(0.01, audioContext.currentTime + 0.6);

            oscillator.start();
            oscillator.stop(audioContext.currentTime + 0.6);
        } catch (error) {
            debugLog('Could not play alert sound:', error);
        }
    }

    // Enhanced notification system
    function showNotification(message, type = 'info', duration = 3000) {
        const notification = document.createElement('div');
        notification.style.cssText = `
            position: fixed;
            top: 80px;
            right: 20px;
            background: ${type === 'success' ? '#66bb6a' : type === 'error' ? '#ff4757' : type === 'pink' ? '#ff1493' : '#00d4ff'};
            color: white;
            padding: 12px 16px;
            border-radius: 8px;
            font-family: 'Inter', sans-serif;
            font-weight: 500;
            font-size: 13px;
            z-index: 1000000;
            box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
            animation: slideIn 0.3s ease;
            max-width: 300px;
        `;

        notification.textContent = message;
        document.body.appendChild(notification);

        setTimeout(() => {
            notification.style.animation = 'slideOut 0.3s ease';
            setTimeout(() => {
                notification.remove();
            }, 300);
        }, duration);
    }

    // Enhanced Betway data extraction
    function extractRoundHistory() {
        debugLog('Extracting from Betway interface...');

        try {
            let extractedData = [];

            const strategies = [
                () => {
                    const roundHistoryText = document.querySelector('div')?.textContent || '';
                    const historyMatch = roundHistoryText.match(/Round History([^]*?)(?:Bet|$)/);
                    if (historyMatch) {
                        const multipliers = historyMatch[1].match(/\d+\.\d{1,2}x/g);
                        return multipliers ? multipliers.map(m => parseFloat(m.replace('x', ''))) : [];
                    }
                    return [];
                },
                () => {
                    const elements = document.querySelectorAll('*');
                    for (const element of elements) {
                        const text = element.textContent || '';
                        if (text.includes('Round History') && text.includes('x')) {
                            const multipliers = text.match(/\d+\.\d{1,2}x/g);
                            if (multipliers && multipliers.length > 5) {
                                return multipliers.map(m => parseFloat(m.replace('x', '')));
                            }
                        }
                    }
                    return [];
                },
                () => {
                    const allText = document.body.textContent;
                    const patterns = [
                        /(\d+\.\d{2}x)\s+(\d+\.\d{2}x)\s+(\d+\.\d{2}x)/g,
                        /Round History.*?((?:\d+\.\d{2}x\s*){5,})/,
                    ];

                    for (const pattern of patterns) {
                        const matches = allText.match(pattern);
                        if (matches) {
                            const multipliers = matches[0].match(/\d+\.\d{2}x/g);
                            if (multipliers) {
                                return multipliers.map(m => parseFloat(m.replace('x', '')));
                            }
                        }
                    }
                    return [];
                }
            ];

            for (const strategy of strategies) {
                extractedData = strategy();
                if (extractedData.length > 0) break;
            }

            if (extractedData.length > 0) {
                const validData = extractedData.filter(val => val >= 1.0 && val <= 1000.0);

                if (validData.length > 0) {
                    const uniqueNew = validData.filter(val => !roundHistory.slice(0, 10).includes(val));
                    if (uniqueNew.length > 0) {
                        roundHistory = [...uniqueNew, ...roundHistory].slice(0, CONFIG.HISTORY_LIMIT);
                        updateBulkHistoryDisplay();
                        saveData();
                        debugLog(`Updated history with ${uniqueNew.length} new values. Total: ${roundHistory.length}`);

                        const newPinks = uniqueNew.filter(val => val >= CONFIG.PINK_THRESHOLD);
                        if (newPinks.length > 0) {
                            debugLog(`🌸 Auto-detected ${newPinks.length} pink(s):`, newPinks);
                        }

                        return uniqueNew.length;
                    }
                }
            }

            return 0;
        } catch (error) {
            debugLog('Error in round history extraction:', error);
            return 0;
        }
    }

    // Setup mutation observer
    function setupMutationObserver() {
        const observer = new MutationObserver((mutations) => {
            let shouldUpdate = false;

            mutations.forEach((mutation) => {
                if (mutation.type === 'childList' && mutation.addedNodes.length > 0) {
                    mutation.addedNodes.forEach(node => {
                        if (node.nodeType === Node.ELEMENT_NODE) {
                            const text = node.textContent || '';
                            if (text.includes('Round History') || text.match(/\d+\.\d{2}x/)) {
                                shouldUpdate = true;
                            }
                        }
                    });
                }
            });

            if (shouldUpdate) {
                setTimeout(() => {
                    const extracted = extractRoundHistory();
                    if (extracted > 0) {
                        updateUI();
                    }
                }, 200);
            }
        });

        observer.observe(document.body, {
            childList: true,
            subtree: true,
            attributes: false
        });

        debugLog('Mutation observer set up for auto-extraction');
    }

    // Keyboard shortcuts
    function setupKeyboardShortcuts() {
        document.addEventListener('keydown', (e) => {
            if (e.target.tagName === 'INPUT' || e.target.tagName === 'TEXTAREA') return;

            switch(e.key.toLowerCase()) {
                case 'q':
                    e.preventDefault();
                    document.getElementById('latest-crash-input')?.focus();
                    break;
                case 'r':
                    e.preventDefault();
                    if (roundHistory.length > 0) {
                        updateUI();
                        debugLog('Manual UI refresh');
                    }
                    break;
                case 'm':
                    e.preventDefault();
                    document.getElementById('minimize-btn')?.click();
                    break;
            }
        });

        debugLog('Keyboard shortcuts: Q=Quick input, R=Refresh, M=Minimize');
    }

    // Main initialization
    function initialize() {
        debugLog('🎯 Aviator Enhanced ML Predictor v8.0 initializing...');

        loadData();

        if (document.readyState === 'loading') {
            document.addEventListener('DOMContentLoaded', initialize);
            return;
        }

        injectCSS();

        setTimeout(() => {
            createUI();
            setupMutationObserver();
            setupKeyboardShortcuts();

            mlEnsemble = new MLEnsemble();

            extractRoundHistory();
            updateUI();

            setInterval(() => {
                updateTimeDisplay();
                const extracted = extractRoundHistory();
                if (extracted > 0) {
                    updateUI();
                }
            }, CONFIG.UPDATE_INTERVAL);

            setInterval(updateTimeDisplay, 1000);

            showNotification('🎯 Enhanced ML Predictor v8.0 ready! Optimized timing & accuracy', 'success', 4000);

            debugLog('✅ Enhanced ML Predictor v8.0 initialized successfully');
            debugLog('🎯 Prime pink times adjusted by -1.5 minutes for better accuracy');
            debugLog('📊 Tighter prediction intervals for improved risk management');
            debugLog('🧠 Enhanced pattern recognition with memory system');
        }, 2000);
    }

    // Auto-focus quick input
    setTimeout(() => {
        const quickInput = document.getElementById('latest-crash-input');
        if (quickInput) {
            quickInput.focus();
        }
    }, 3000);

    initialize();

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址