MZone Advanced: Table, Stats & Play-off / MZone Gelişmiş: Tablo, İstatistik & Play-off

A powerful suite combining the Advanced League Table (live scores, FD), Player Stat Averages, and the new Play-off/Play-out Predictor. Now with Excel export, Shortlist Filtering and Transfer Tracker with charts.

// ==UserScript==
// @name         MZone Advanced: Table, Stats & Play-off / MZone Gelişmiş: Tablo, İstatistik & Play-off
// @name:tr      MZone Gelişmiş: Tablo, İstatistik & Play-off
// @namespace    http://tampermonkey.net/
// @version      2.24
// @description  A powerful suite combining the Advanced League Table (live scores, FD), Player Stat Averages, and the new Play-off/Play-out Predictor. Now with Excel export, Shortlist Filtering and Transfer Tracker with charts.
// @description:tr Gelişmiş Lig Tablosu (canlı skorlar, FZ), Oyuncu İstatistik Ortalamaları ve yeni Play-Off/Play-Out Tahmincisi betiklerini tek bir güçlü araçta birleştirir. Şimdi Excel'e aktarma, Takip Listesi Filtreleme ve Grafikli Transfer Takipçisi özelliğiyle.
// @author       alex66
// @match        https://www.managerzone.com/?p=league*
// @match        https://www.managerzone.com/?p=friendlyseries*
// @match        https://www.managerzone.com/?p=private_cup*
// @match        https://www.managerzone.com/?p=cup*
// @match        https://www.managerzone.com/?p=players*
// @match        https://www.managerzone.com/?p=player&pid=*
// @match        https://www.managerzone.com/?p=match&sub=played*
// @match        https://www.managerzone.com/?p=match&sub=result*
// @match        https://www.managerzone.com/?p=match&sub=stats*
// @match        https://www.managerzone.com/?p=shortlist*
// @match        https://www.managerzone.com/?p=transfer*
// @icon         https://www.google.com/s2/favicons?sz=64&domain=managerzone.com
// @run-at       document-idle
// @grant        GM_xmlhttpRequest
// @grant        GM_addStyle
// @grant        GM_openInTab
// @grant        GM_info
// @grant        GM_getResourceText
// @grant        GM_setValue
// @grant        GM_getValue
// @grant        GM_deleteValue
// @grant        GM
// @require      https://cdnjs.cloudflare.com/ajax/libs/nprogress/0.2.0/nprogress.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.18.5/xlsx.full.min.js
// @require      https://code.highcharts.com/highcharts.js
// @resource     NPROGRESS_CSS https://unpkg.com/[email protected]/nprogress.css
// ==/UserScript==

(async function() {
    'use strict';
    // DÜZELTME: Betiğin sayfanın jQuery'sine erişebilmesi için 'unsafeWindow' kullanılıyor.
    // Bu, @grant direktifleri nedeniyle oluşan "sandbox" ortamını aşmak için gereklidir.
    const $ = unsafeWindow.jQuery;

    /****************************************************************************************
     *                                                                                      *
     *  BÖLÜM 1: GELİŞMİŞ LİG TABLOSU BETİĞİ (ManagerZone Universal Advanced League Table)     *
     *                                                                                      *
     ****************************************************************************************/
    function initializeLeagueTableScript() {
        // =================================================================================
        // BÖLÜM -1: ULUSLARARASILAŞTIRMA (i18n)
        // =================================================================================

        const i18n = {
            translations: {
                en: {
                    scriptName: 'ManagerZone Universal Advanced League Table',
                    leagueTableTitle: 'Table',
                    fixtureDifficultyHeader: 'FD',
                    fixtureDifficultyTitle: 'Fixture Difficulty (Higher value is advantageous, lower is disadvantageous)',
                    settingsTitle: 'Change settings',
                    fetchLiveScoresBtn: 'Fetch Live Scores',
                    processingBtn: 'Processing...',
                    tableUpdatedBtn: 'Table Updated!',
                    scriptUpdatedTitle: "'${scriptName}' has been updated!",
                    updateNotesIntro: "Here's what's new in version v${version}:",
                    updateModalCloseBtn: 'Got it, Close',
                    settingsModalTitle: 'Settings',
                    logoVisibilityLabel: 'Logo Visibility (Show team logos)',
                    saveBtn: 'Save',
                    roundPrefix: 'Round',
                    fzNotAvailable: 'Fixture analysis is not available for this page.',
                    fzTooltip: 'Remaining matches: ${remaining}\nOpponent rank sum: ${rankSum}',
                    fzNoMatchesLeft: 'No matches left',
                    locationHome: '(H)',
                    locationAway: '(A)',
                    updateNotes: {
                        '2.6': ["Fixed a critical bug where the script would fail on non-Turkish/English languages. The script now correctly parses fixture data regardless of the selected language and uses an English UI for all non-Turkish languages."]
                    }
                },
                tr: {
                    scriptName: 'ManagerZone Evrensel Gelişmiş Lig Tablosu',
                    leagueTableTitle: 'Puan Tablosu',
                    fixtureDifficultyHeader: 'FZ',
                    fixtureDifficultyTitle: 'Fikstür Zorluğu (Değer yüksekse avantajlı, düşükse dezavantajlı)',
                    settingsTitle: 'Ayarları değiştir',
                    fetchLiveScoresBtn: 'Canlı Maç Sonuçlarını Al',
                    processingBtn: 'İşleniyor...',
                    tableUpdatedBtn: 'Tablo Güncellendi!',
                    scriptUpdatedTitle: "'${scriptName}' Güncellendi!",
                    updateNotesIntro: "Yeni sürüm (v${version}) ile gelen yenilikler:",
                    updateModalCloseBtn: 'Anladım, Kapat',
                    settingsModalTitle: 'Ayarlar',
                    logoVisibilityLabel: 'Logo Görünürlüğü (Takım logoları gösterilsin)',
                    saveBtn: 'Kaydet',
                    roundPrefix: 'Tur',
                    fzNotAvailable: 'Fikstür analizi bu sayfa için mevcut değil.',
                    fzTooltip: 'Kalan maç: ${remaining}\nRakip sıra top: ${rankSum}',
                    fzNoMatchesLeft: 'Kalan maç yok',
                    locationHome: '(E)',
                    locationAway: '(D)',
                    updateNotes: {
                        '2.6': ["Türkçe/İngilizce dışındaki dillerde betiğin çalışmamasına neden olan kritik hata düzeltildi. Betik artık seçilen dilden bağımsız olarak fikstür verisini doğru bir şekilde analiz ediyor ve Türkçe dışındaki tüm diller için İngilizce arayüz kullanıyor."]
                    }
                }
            },
            detectLanguage: function() {
                const langMeta = document.querySelector('meta[name="language"]');
                if (langMeta && langMeta.getAttribute('content') === 'tr') {
                    return 'tr';
                }
                return 'en';
            },
            get: function(key, replacements = {}) {
                let lang = this.currentLang || this.detectLanguage();
                let text;
                if (this.translations[lang] && this.translations[lang][key] !== undefined) {
                    text = this.translations[lang][key];
                } else {
                    text = this.translations['en']?.[key];
                }
                if (text === undefined) {
                    console.warn(`i18n key not found: ${key}`);
                    return `[${key}]`;
                }
                if (key === 'updateNotes' && typeof text === 'object') {
                    return text;
                }
                for (const placeholder in replacements) {
                    text = text.replace(new RegExp(`\\$\\{${placeholder}\\}`, 'g'), replacements[placeholder]);
                }
                return text;
            }
        };

        i18n.currentLang = i18n.detectLanguage();


        // =================================================================================
        // BÖLÜM 0: YAPILANDIRMA VE SABİTLER
        // =================================================================================

        const CONFIG = {
            SELECTORS: {
                LEAGUE_TABLE: 'table.nice_table',
                TABLE_HEADER_ROW: 'table.nice_table thead tr',
                TABLE_BODY: 'table.nice_table tbody',
                TABLE_ROWS: 'table.nice_table tbody tr',
                TEAM_LINK_IN_ROW: 'a[href*="&tid="]',
                MY_TEAM_ROW: 'tr.highlight_row',
                ONGOING_MATCH_LINK: 'table.hitlist a[href*="mid="], .team-matches-vs a[href*="mid="]',
                LEAGUE_TABLE_HEADER: 'h2.subheader',
                SCHEDULE_TAB_LINK: '#league_tab_schedule',
                UPDATE_BUTTON: '.mz-fetch-button',
                SETTINGS_BUTTON: '.mz-settings-button',
                CONTENT_DIV: '#contentDiv',
                SETTINGS_MODAL: '#mz-settings-modal',
                SETTINGS_MODAL_CLOSE: '.mz-modal-close',
                SETTINGS_MODAL_SAVE: '#mz-settings-save',
                LOGO_VISIBILITY_CHECKBOX: '#mz-logo-visibility-checkbox',
                UPDATE_MODAL: '#mz-update-modal',
                UPDATE_MODAL_CLOSE: '#mz-update-close-button',
            },
            CLASSES: {
                NEXT_OPPONENT: 'mz-next-opponent',
                UPDATED_CELL: 'updated-cell',
                INDICATORS_WRAPPER: 'mz-indicators-wrapper',
                TOOLTIP: 'mz-custom-tooltip',
                BUTTON_DISABLED: 'disabled',
                BUTTON_DONE: 'done',
                FZ_HEADER: 'mz-fz-header',
                TEAM_LOGO: 'mz-team-logo',
                SETTINGS_ACTIVE: 'mz-settings-active',
            },
            COLUMNS: {
                POSITION: 0,
                TEAM_NAME: 1,
                PLAYED: 2,
                WINS: 3,
                DRAWS: 4,
                LOSSES: 5,
                GOALS_FOR: 6,
                GOALS_AGAINST: 7,
                GOAL_DIFFERENCE: 8,
                POINTS: 9,
                FIXTURE_DIFFICULTY: 10
            },
            API: {
                MATCH_INFO: 'https://www.managerzone.com/xml/match_info.php?sport_id=1&match_id=',
            }
        };


        const SCRIPT_INFO = GM_info.script;
        const LAST_SEEN_VERSION_KEY = 'mz_advanced_table_last_version';
        const UPDATE_NOTES = i18n.get('updateNotes');

        function injectStyles() {
            GM_addStyle(GM_getResourceText('NPROGRESS_CSS'));
            GM_addStyle(`
            .mz-team-cell { display: flex; align-items: center; }
            .mz-team-logo { height: 2.0em; width: auto; margin-right: 6px; vertical-align: middle; flex-shrink: 0; }
            .mz-indicators-wrapper { margin-left: auto; margin-right: 15px; display: flex; align-items: center; white-space: nowrap; padding-left: 10px; }
            .match-indicator { display: inline-block; width: 13.5px; height: 12.5px; border-radius: 50%; margin-left: 8px; vertical-align: middle; border: 1px solid rgba(0,0,0,0.6); cursor: pointer; flex-shrink: 0; }
            .match-win { background-color: #28a745; }
            .match-loss { background-color: #dc3545; }
            .match-draw { background-color: #ffc107; }
            .match-future { font-size: 11px; color: #000; margin-left: 5px; font-style: italic; font-weight: bold; }
            .mz-next-opponent { background-color: #fff3cd !important; font-weight: bold; }
            .mz-next-opponent:hover { background-color: #ffeeba !important; }
            .mz-next-opponent a { color: #856404 !important; }

            .mz-custom-tooltip { position: absolute; display: none; padding: 8px 12px; color: #fff; border-radius: 6px; font-size: 14px; font-weight: bold; z-index: 9999; pointer-events: none; box-shadow: 0 4px 8px rgba(0,0,0,0.3); text-shadow: 1px 1px 2px rgba(0,0,0,0.5); line-height: 1; white-space: nowrap; }
            .mz-custom-tooltip::before { content: ''; position: absolute; top: 50%; right: 100%; margin-top: -6px; border-width: 6px; border-style: solid; }
            .tooltip-win { background-color: #28a745; border: 1px solid #1e7e34; }
            .tooltip-win::before { border-color: transparent #1e7e34 transparent transparent; }
            .tooltip-loss { background-color: #dc3545; border: 1px solid #b21f2d; }
            .tooltip-loss::before { border-color: transparent #b21f2d transparent transparent; }
            .tooltip-draw { background-color: #ffc107; border: 1px solid #d39e00; color: #212529; text-shadow: none; }
            .tooltip-draw::before { border-color: transparent #d39e00 transparent transparent; }

            .mz-fetch-button { margin-left: 10px; padding: 5px 10px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; transition: background-color 0.3s; }
            .mz-fetch-button:hover:not(.disabled) { background-color: #45a049; }
            .mz-fetch-button.disabled { background-color: #ccc; cursor: not-allowed; }
            .mz-fetch-button.done { background-color: #007bff; }
            .${CONFIG.CLASSES.FZ_HEADER}, table.nice_table td:nth-child(${CONFIG.COLUMNS.FIXTURE_DIFFICULTY + 1}) { text-align: center; font-weight: bold; cursor: help; }

            .mz-settings-button { margin-left: 8px; cursor: pointer; color: #999; font-size: 1.1em; transition: color 0.3s; vertical-align: middle;}
            .mz-settings-button:hover { color: #333; }
            .mz-settings-button.mz-settings-active { color: #4CAF50; }

            .mz-modal-overlay { position: fixed; top: 0; left: 0; width: 100%; height: 100%; background-color: rgba(0,0,0,0.6); z-index: 10000; display: none; justify-content: center; align-items: center; }
            .mz-modal-content { background: #fefefe; padding: 20px; border-radius: 8px; box-shadow: 0 5px 15px rgba(0,0,0,0.3); min-width: 300px; display: flex; flex-direction: column; max-width: 500px; }
            .mz-modal-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #ddd; padding-bottom: 10px; margin-bottom: 15px; }
            .mz-modal-header h3 { margin: 0; font-size: 18px; }
            .mz-modal-close { font-size: 24px; font-weight: bold; cursor: pointer; color: #888; }
            .mz-modal-close:hover { color: #000; }
            .mz-modal-body { display: flex; flex-direction: column; gap: 15px; }
            .mz-modal-body label { display: flex; align-items: center; font-size: 16px; cursor: pointer; }
            .mz-modal-body input[type="checkbox"] { width: 18px; height: 18px; margin-right: 10px; }
            .mz-modal-footer { border-top: 1px solid #ddd; padding-top: 15px; margin-top: 20px; text-align: right; }
            #mz-settings-save { padding: 8px 16px; background-color: #4CAF50; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; }
            #mz-settings-save:hover { background-color: #45a049; }

            #mz-update-modal .mz-modal-body ul { list-style-type: none; padding-left: 0; margin: 10px 0; }
            #mz-update-modal .mz-modal-body li { margin-bottom: 10px; padding-left: 20px; position: relative; }
            #mz-update-modal .mz-modal-body li::before { content: '✓'; color: #4CAF50; position: absolute; left: 0; font-weight: bold; }
            #mz-update-modal .mz-modal-footer { text-align: center; }
            #mz-update-close-button { padding: 10px 25px; background-color: #007bff; color: white; border: none; border-radius: 4px; cursor: pointer; font-weight: bold; }
            #mz-update-close-button:hover { background-color: #0069d9; }

            @media (max-width: 768px) {
                .mz-team-logo { height: 1.6em !important; width: auto !important; max-width: 20px !important; }

                /* === MOBİL GÖRÜNÜM DÜZELTMESİ BURADA === */
                .mz-indicators-wrapper {
                    flex-wrap: nowrap; /* İkonların ve yazıların alt satıra kaymasını engeller */
                    margin-left: auto;   /* İkon grubunu hücrenin sağına yaslar */
                    margin-right: 5px;
                    justify-content: flex-end;
                }
                /* === DÜZELTME SONU === */

                .mz-team-cell a { white-space: normal; }
            }
        `);
        }

        function request(options) {
            return new Promise((resolve, reject) => {
                GM_xmlhttpRequest({ ...options,
                                   onload: resolve,
                                   onerror: reject,
                                   ontimeout: reject
                                 });
            });
        }

        let myTeamInfo = {
            id: null,
            name: null
        };
        let originalTableBody = null;
        const liveMatchResults = new Map();
        const tooltip = document.createElement('div');
        document.body.appendChild(tooltip);
        let fullScheduleCache = null;
        let isLogoDisplayEnabled = true;

        function findOngoingMatches() {
            const ongoingMatches = [];
            document.querySelectorAll(CONFIG.SELECTORS.ONGOING_MATCH_LINK).forEach(link => {
                const scoreText = link.textContent.trim();
                if (!/^\d+\s*-\s*\d+$/.test(scoreText) && !scoreText.includes('X - X')) {
                    const mid = new URLSearchParams(link.href).get('mid');
                    if (mid) ongoingMatches.push({
                        mid,
                        linkElement: link
                    });
                }
            });
            return ongoingMatches;
        }

        function findMainLeagueTableHeader() {
            const allHeaders = document.querySelectorAll(CONFIG.SELECTORS.LEAGUE_TABLE_HEADER);
            for (const header of allHeaders) {
                const nextElement = header.nextElementSibling;
                if (nextElement && (nextElement.matches(CONFIG.SELECTORS.LEAGUE_TABLE) || nextElement.querySelector(CONFIG.SELECTORS.LEAGUE_TABLE))) {
                    return header;
                }
            }
            return null;
        }

        function isMainLeagueTableVisible() {
            const tables = document.querySelectorAll('#contentDiv table.nice_table');
            for (const table of tables) {
                const header = table.querySelector('thead');
                const body = table.querySelector('tbody');
                if (header && body && body.rows.length > 2 && header.rows[0].cells.length >= 8) {
                    return true;
                }
            }
            return false;
        }

        function setupLiveUpdateFeature() {
            const ongoingMatches = findOngoingMatches();
            if (ongoingMatches.length === 0) return;
            const titleHeader = findMainLeagueTableHeader();
            if (!titleHeader || document.querySelector(CONFIG.SELECTORS.UPDATE_BUTTON)) return;
            const button = document.createElement('button');
            button.className = 'mz-fetch-button';
            button.textContent = i18n.get('fetchLiveScoresBtn');
            button.addEventListener('click', () => handleLiveUpdateClick(button, ongoingMatches));
            titleHeader.appendChild(button);
        }

        function createUpdateModal(version, notes) {
            if (document.querySelector(CONFIG.SELECTORS.UPDATE_MODAL)) return;
            const modalOverlay = document.createElement('div');
            modalOverlay.id = 'mz-update-modal';
            modalOverlay.className = 'mz-modal-overlay';
            const notesHtml = notes.map(note => `<li>${note}</li>`).join('');
            const scriptName = i18n.get('scriptName');
            modalOverlay.innerHTML = `
            <div class="mz-modal-content">
                <div class="mz-modal-header">
                    <h3>${i18n.get('scriptUpdatedTitle', { scriptName })}</h3>
                </div>
                <div class="mz-modal-body">
                    <p>${i18n.get('updateNotesIntro', { version })}</p>
                    <ul>${notesHtml}</ul>
                </div>
                <div class="mz-modal-footer">
                    <button id="mz-update-close-button">${i18n.get('updateModalCloseBtn')}</button>
                </div>
            </div>`;
            document.body.appendChild(modalOverlay);
            modalOverlay.querySelector(CONFIG.SELECTORS.UPDATE_MODAL_CLOSE).addEventListener('click', async () => {
                modalOverlay.style.display = 'none';
                await GM_setValue(LAST_SEEN_VERSION_KEY, SCRIPT_INFO.version);
            });
        }

        function createSettingsModal() {
            if (document.querySelector(CONFIG.SELECTORS.SETTINGS_MODAL)) return;
            const modalOverlay = document.createElement('div');
            modalOverlay.id = 'mz-settings-modal';
            modalOverlay.className = 'mz-modal-overlay';
            modalOverlay.innerHTML = `
            <div class="mz-modal-content">
                <div class="mz-modal-header">
                    <h3>${i18n.get('settingsModalTitle')}</h3>
                    <span class="mz-modal-close">×</span>
                </div>
                <div class="mz-modal-body">
                    <label>
                        <input type="checkbox" id="mz-logo-visibility-checkbox" />
                        ${i18n.get('logoVisibilityLabel')}
                    </label>
                </div>
                <div class="mz-modal-footer">
                    <button id="mz-settings-save">${i18n.get('saveBtn')}</button>
                </div>
            </div>`;
            document.body.appendChild(modalOverlay);
            modalOverlay.querySelector(CONFIG.SELECTORS.SETTINGS_MODAL_CLOSE).addEventListener('click', closeSettingsModal);
            modalOverlay.querySelector(CONFIG.SELECTORS.SETTINGS_MODAL_SAVE).addEventListener('click', saveSettingsAndClose);
            modalOverlay.addEventListener('click', (e) => {
                if (e.target === modalOverlay) {
                    closeSettingsModal();
                }
            });
        }

        function openSettingsModal() {
            const modal = document.querySelector(CONFIG.SELECTORS.SETTINGS_MODAL);
            const checkbox = document.querySelector(CONFIG.SELECTORS.LOGO_VISIBILITY_CHECKBOX);
            if (!modal || !checkbox) return;
            checkbox.checked = isLogoDisplayEnabled;
            modal.style.display = 'flex';
        }

        function closeSettingsModal() {
            const modal = document.querySelector(CONFIG.SELECTORS.SETTINGS_MODAL);
            if (modal) modal.style.display = 'none';
        }

        function saveSettingsAndClose() {
            const checkbox = document.querySelector(CONFIG.SELECTORS.LOGO_VISIBILITY_CHECKBOX);
            if (!checkbox) return;
            isLogoDisplayEnabled = checkbox.checked;
            GM_setValue('showTeamLogos', isLogoDisplayEnabled);
            updateSettingsIconState();
            toggleLogoVisibility();
            closeSettingsModal();
        }

        function setupSettingsMenu() {
            const titleHeader = findMainLeagueTableHeader();
            if (!titleHeader || document.querySelector(CONFIG.SELECTORS.SETTINGS_BUTTON)) return;
            const settingsIcon = document.createElement('span');
            settingsIcon.className = CONFIG.CLASSES.SETTINGS_BUTTON;
            settingsIcon.textContent = '⚙️';
            settingsIcon.addEventListener('click', openSettingsModal);
            titleHeader.appendChild(settingsIcon);
            updateSettingsIconState();
        }

        function updateSettingsIconState() {
            const settingsIcon = document.querySelector(CONFIG.SELECTORS.SETTINGS_BUTTON);
            if (!settingsIcon) return;
            settingsIcon.classList.toggle(CONFIG.CLASSES.SETTINGS_ACTIVE, isLogoDisplayEnabled);
            settingsIcon.title = i18n.get('settingsTitle');
        }

        async function handleLiveUpdateClick(button, matches) {
            button.textContent = i18n.get('processingBtn');
            button.classList.add(CONFIG.CLASSES.BUTTON_DISABLED);
            button.disabled = true;
            NProgress.start();
            const currentTbody = document.querySelector(CONFIG.SELECTORS.TABLE_BODY);
            if (currentTbody && originalTableBody) {
                currentTbody.parentNode.replaceChild(originalTableBody.cloneNode(true), currentTbody);
                addFixtureDifficultyColumn();
                toggleLogoVisibility();
            }
            liveMatchResults.clear();
            for (let i = 0; i < matches.length; i++) {
                NProgress.set((i / matches.length) * 0.5);
                try {
                    const response = await request({
                        method: 'GET',
                        url: CONFIG.API.MATCH_INFO + matches[i].mid
                    });
                    const xmlDoc = new DOMParser().parseFromString(response.responseText, 'application/xml');
                    const homeNode = xmlDoc.querySelector('Team[field="home"]');
                    const awayNode = xmlDoc.querySelector('Team[field="away"]');
                    if (homeNode && awayNode) {
                        const matchData = {
                            mid: matches[i].mid,
                            homeTid: homeNode.getAttribute('id'),
                            awayTid: awayNode.getAttribute('id'),
                            homeGoals: parseInt(homeNode.getAttribute('goals'), 10) || 0,
                            awayGoals: parseInt(awayNode.getAttribute('goals'), 10) || 0
                        };
                        liveMatchResults.set(matchData.mid, matchData);
                        matches[i].linkElement.textContent = `${matchData.homeGoals} - ${matchData.awayGoals}`;
                    }
                } catch (error) {
                    console.error(`Maç ID ${matches[i].mid} için veri çekilemedi:`, error);
                }
            }
            NProgress.set(0.6);
            liveMatchResults.forEach(data => {
                const {
                    homeResult,
                    awayResult
                } = calculateMatchResult(data);
                updateTeamRow(data.homeTid, homeResult);
                updateTeamRow(data.awayTid, awayResult);
            });
            NProgress.set(0.8);
            sortTableByPoints();
            await calculateAndDisplayFixtureDifficulty(liveMatchResults);
            if (myTeamInfo.id) {
                NProgress.set(0.9);
                await performFullOpponentAnalysis();
            }
            NProgress.done();
            button.textContent = i18n.get('tableUpdatedBtn');
            button.classList.add(CONFIG.CLASSES.BUTTON_DONE);
        }

        function calculateMatchResult(data) {
            if (data.homeGoals > data.awayGoals) return {
                homeResult: {
                    p: 3,
                    w: 1,
                    d: 0,
                    l: 0,
                    gf: data.homeGoals,
                    ga: data.awayGoals
                },
                awayResult: {
                    p: 0,
                    w: 0,
                    d: 0,
                    l: 1,
                    gf: data.awayGoals,
                    ga: data.homeGoals
                }
            };
            if (data.homeGoals < data.awayGoals) return {
                homeResult: {
                    p: 0,
                    w: 0,
                    d: 0,
                    l: 1,
                    gf: data.homeGoals,
                    ga: data.awayGoals
                },
                awayResult: {
                    p: 3,
                    w: 1,
                    d: 0,
                    l: 0,
                    gf: data.awayGoals,
                    ga: data.homeGoals
                }
            };
            return {
                homeResult: {
                    p: 1,
                    w: 0,
                    d: 1,
                    l: 0,
                    gf: data.homeGoals,
                    ga: data.awayGoals
                },
                awayResult: {
                    p: 1,
                    w: 0,
                    d: 1,
                    l: 0,
                    gf: data.awayGoals,
                    ga: data.homeGoals
                }
            };
        }

        function updateTeamRow(tid, result) {
            const teamRow = document.querySelector(`.nice_table a[href*="&tid=${tid}"]`)?.closest('tr');
            if (!teamRow) return;
            const cells = teamRow.cells;
            const C = CONFIG.COLUMNS;
            const parseCellInt = (index) => parseInt(cells[index]?.textContent.trim(), 10) || 0;
            const updateCell = (index, value) => {
                if (cells[index]) {
                    cells[index].textContent = value;
                    cells[index].classList.add(CONFIG.CLASSES.UPDATED_CELL);
                    setTimeout(() => cells[index].classList.remove(CONFIG.CLASSES.UPDATED_CELL), 2000);
                }
            };
            updateCell(C.PLAYED, parseCellInt(C.PLAYED) + 1);
            updateCell(C.WINS, parseCellInt(C.WINS) + result.w);
            updateCell(C.DRAWS, parseCellInt(C.DRAWS) + result.d);
            updateCell(C.LOSSES, parseCellInt(C.LOSSES) + result.l);
            const newGF = parseCellInt(C.GOALS_FOR) + result.gf;
            const newGA = parseCellInt(C.GOALS_AGAINST) + result.ga;
            updateCell(C.GOALS_FOR, newGF);
            updateCell(C.GOALS_AGAINST, newGA);
            updateCell(C.GOAL_DIFFERENCE, newGF - newGA);
            updateCell(C.POINTS, parseCellInt(C.POINTS) + result.p);
        }

        function sortTableByPoints() {
            const tbody = document.querySelector(CONFIG.SELECTORS.TABLE_BODY);
            if (!tbody) return;
            const rows = Array.from(tbody.rows);
            const C = CONFIG.COLUMNS;
            rows.sort((a, b) => {
                const val = (r, i) => parseInt(r.cells[i]?.textContent.trim(), 10) || 0;
                return val(b, C.POINTS) - val(a, C.POINTS) || val(b, C.GOAL_DIFFERENCE) - val(a, C.GOAL_DIFFERENCE) || val(b, C.GOALS_FOR) - val(a, C.GOALS_FOR);
            });
            rows.forEach((row, index) => {
                row.cells[C.POSITION].textContent = index + 1;
                tbody.appendChild(row);
            });
        }

        function toggleLogoVisibility() {
            if (isLogoDisplayEnabled) {
                addTeamLogos();
            } else {
                removeTeamLogos();
            }
        }

        function addTeamLogos() {
            if (!isLogoDisplayEnabled) return;
            document.querySelectorAll(CONFIG.SELECTORS.TABLE_ROWS).forEach(row => {
                const teamLink = row.querySelector(CONFIG.SELECTORS.TEAM_LINK_IN_ROW);
                if (teamLink && teamLink.parentNode && !row.querySelector(`.${CONFIG.CLASSES.TEAM_LOGO}`)) {
                    const tid = new URLSearchParams(teamLink.href).get('tid');
                    if (tid) {
                        const logo = document.createElement('img');
                        logo.src = `/dynimg/badge.php?team_id=${tid}&sport=soccer`;
                        logo.className = CONFIG.CLASSES.TEAM_LOGO;
                        logo.alt = 'Logo';
                        teamLink.parentNode.insertBefore(logo, teamLink);
                    }
                }
            });
        }

        function removeTeamLogos() {
            document.querySelectorAll(`.${CONFIG.CLASSES.TEAM_LOGO}`).forEach(logo => logo.remove());
        }

        async function performFullOpponentAnalysis() {
            try {
                if (!myTeamInfo.name || !fullScheduleCache) return;
                const fixtureData = parseMyTeamFixture(fullScheduleCache.htmlText);
                applyAllVisuals(fixtureData);
            } catch (error) {
                console.error("Opponent analysis failed:", error);
            }
        }

        function applyAllVisuals({
            fixture,
            nextOpponentName
        }) {
            if (!fixture) return;
            const tableBody = document.querySelector(CONFIG.SELECTORS.TABLE_BODY);
            if (!tableBody) return;
            document.querySelectorAll(`.${CONFIG.CLASSES.INDICATORS_WRAPPER}`).forEach(el => el.remove());
            document.querySelectorAll(`.${CONFIG.CLASSES.NEXT_OPPONENT}`).forEach(el => el.classList.remove(CONFIG.CLASSES.NEXT_OPPONENT));
            tableBody.querySelectorAll("tr").forEach(row => {
                const teamLink = row.querySelector(CONFIG.SELECTORS.TEAM_LINK_IN_ROW);
                if (!teamLink || row.classList.contains('highlight_row')) return;
                const teamCell = teamLink.parentNode;
                teamCell.classList.add('mz-team-cell');
                const teamName = teamLink.textContent.trim();
                const result = fixture[teamName];
                if (nextOpponentName === teamName) row.classList.add(CONFIG.CLASSES.NEXT_OPPONENT);
                if (result) {
                    const wrapper = document.createElement('span');
                    wrapper.className = CONFIG.CLASSES.INDICATORS_WRAPPER;
                    if (result.played && result.played.length > 0) {
                        result.played.forEach(playedMatch => {
                            const icon = document.createElement('span');
                            icon.className = `match-indicator match-${playedMatch.status}`;
                            icon.dataset.tooltipText = `${playedMatch.location} ${playedMatch.score}`;
                            icon.dataset.status = playedMatch.status;
                            icon.addEventListener('click', () => GM_openInTab(playedMatch.matchURL, true));
                            addTooltipEvents(icon);
                            wrapper.appendChild(icon);
                        });
                    }
                    if (result.futureRounds.length > 0) {
                        const text = document.createElement('span');
                        text.className = 'match-future';
                        text.textContent = `(${result.futureRounds.join(', ')})`;
                        wrapper.appendChild(text);
                    }
                    if (wrapper.hasChildNodes()) teamCell.appendChild(wrapper);
                }
            });
        }

        function addTooltipEvents(element) {
            element.addEventListener('mouseenter', (e) => {
                const target = e.currentTarget;
                const wrapperElement = target.closest(`.${CONFIG.CLASSES.INDICATORS_WRAPPER}`);
                const positioningElement = wrapperElement || target;
                const rect = positioningElement.getBoundingClientRect();
                tooltip.className = `${CONFIG.CLASSES.TOOLTIP} tooltip-${target.dataset.status}`;
                tooltip.textContent = target.dataset.tooltipText;
                tooltip.style.display = 'block';
                tooltip.style.top = `${rect.top + window.scrollY + rect.height / 2 - tooltip.offsetHeight / 2}px`;
                tooltip.style.left = `${rect.right + window.scrollX + 10}px`;
            });
            element.addEventListener('mouseleave', () => {
                tooltip.style.display = 'none';
            });
        }

        function addFixtureDifficultyColumn() {
            const headerRow = document.querySelector(CONFIG.SELECTORS.TABLE_HEADER_ROW);
            if (!headerRow || headerRow.querySelector(`.${CONFIG.CLASSES.FZ_HEADER}`)) return;
            const newHeader = document.createElement('th');
            newHeader.textContent = i18n.get('fixtureDifficultyHeader');
            newHeader.title = i18n.get('fixtureDifficultyTitle');
            newHeader.classList.add(CONFIG.CLASSES.FZ_HEADER);
            headerRow.insertBefore(newHeader, headerRow.children[CONFIG.COLUMNS.POINTS + 1]);
            document.querySelectorAll(CONFIG.SELECTORS.TABLE_ROWS).forEach(row => {
                const newCell = row.insertCell(CONFIG.COLUMNS.FIXTURE_DIFFICULTY);
                newCell.textContent = '...';
            });
        }

        async function fetchAndCacheSchedule() {
            if (fullScheduleCache) return fullScheduleCache;
            const scheduleTabLink = document.querySelector(CONFIG.SELECTORS.SCHEDULE_TAB_LINK);
            if (!scheduleTabLink) return null;
            try {
                const response = await request({
                    method: "GET",
                    url: scheduleTabLink.href
                });
                fullScheduleCache = {
                    htmlText: response.responseText
                };
                return fullScheduleCache;
            } catch (error) {
                console.error("Could not fetch schedule page:", error);
                return null;
            }
        }

        function parseMyTeamFixture(htmlText) {
            const doc = new DOMParser().parseFromString(htmlText, 'text/html');
            const fixture = {};
            let nextMatch = {
                round: Infinity,
                opponentName: null
            };
            const roundRegex = /\d+/;

            doc.querySelectorAll(CONFIG.SELECTORS.LEAGUE_TABLE_HEADER).forEach(header => {
                const roundMatch = header.textContent.match(roundRegex);
                if (!roundMatch) return;

                const round = parseInt(roundMatch[0], 10);
                const table = header.nextElementSibling?.querySelector('table');
                if (!table) return;

                table.querySelectorAll('tr').forEach(row => {
                    const [homeCell, scoreCell, awayCell] = row.cells;
                    if (!homeCell || !scoreCell || !awayCell) return;
                    const homeTeam = homeCell.textContent.trim();
                    const awayTeam = awayCell.textContent.trim();
                    if (homeTeam === myTeamInfo.name || awayTeam === myTeamInfo.name) {
                        const opponentName = homeTeam === myTeamInfo.name ? awayTeam : homeTeam;
                        if (!fixture[opponentName]) fixture[opponentName] = {
                            played: [],
                            futureRounds: []
                        };
                        const scoreLink = scoreCell.querySelector('a');
                        const mid = scoreLink ? new URLSearchParams(scoreLink.href).get('mid') : null;

                        const location = homeTeam === myTeamInfo.name ? i18n.get('locationHome') : i18n.get('locationAway');
                        const currentRoundText = `${i18n.get('roundPrefix')} ${round}`;

                        if (mid && liveMatchResults.has(mid)) {
                            const d = liveMatchResults.get(mid);
                            const myScore = d.homeTid === myTeamInfo.id ? d.homeGoals : d.awayGoals;
                            const oppScore = d.homeTid === myTeamInfo.id ? d.awayGoals : d.homeGoals;
                            fixture[opponentName].played.push({
                                score: `${myScore} - ${oppScore}`,
                                matchURL: scoreLink.href,
                                location: location,
                                status: myScore > oppScore ? 'win' : (myScore < oppScore ? 'loss' : 'draw'),
                            });
                        } else if (scoreLink && /^\d+\s*-\s*\d+$/.test(scoreLink.textContent.trim())) {
                            const scores = scoreLink.textContent.trim().split('-').map(s => parseInt(s.trim()));
                            const myScore = homeTeam === myTeamInfo.name ? scores[0] : scores[1];
                            const oppScore = homeTeam === myTeamInfo.name ? scores[1] : scores[0];
                            fixture[opponentName].played.push({
                                score: `${myScore} - ${oppScore}`,
                                matchURL: scoreLink.href,
                                location: location,
                                status: myScore > oppScore ? 'win' : (myScore < oppScore ? 'loss' : 'draw'),
                            });
                        } else {
                            fixture[opponentName].futureRounds.push(currentRoundText);
                            if (round < nextMatch.round) nextMatch = {
                                round,
                                opponentName
                            };
                        }
                    }
                });
            });
            return {
                fixture,
                nextOpponentName: nextMatch.opponentName
            };
        }

        function parseScheduleForAllTeams(htmlText, newlyFinishedMatches = new Map()) {
            const doc = new DOMParser().parseFromString(htmlText, 'text/html');
            const allFixtures = {};
            document.querySelectorAll(CONFIG.SELECTORS.TABLE_ROWS).forEach(row => {
                const teamLink = row.querySelector(CONFIG.SELECTORS.TEAM_LINK_IN_ROW);
                if (teamLink) allFixtures[teamLink.textContent.trim()] = {
                    futureOpponents: []
                };
            });
            const matchRows = doc.querySelectorAll('table.hitlist tbody tr, .matches_container table tbody tr');
            matchRows.forEach(row => {
                if (row.cells.length < 3) return;
                const scoreCell = row.cells[1];
                const scoreText = scoreCell.textContent.trim();
                const scoreLink = scoreCell.querySelector('a[href*="mid="]');
                const mid = scoreLink ? new URLSearchParams(scoreLink.href).get('mid') : null;
                if ((!/^\d+\s*-\s*\d+$/.test(scoreText) || scoreText.includes('vs')) && !newlyFinishedMatches.has(mid)) {
                    const homeTeam = row.cells[0].textContent.trim();
                    const awayTeam = row.cells[2].textContent.trim();
                    if (allFixtures[homeTeam] && allFixtures[awayTeam]) {
                        allFixtures[homeTeam].futureOpponents.push(awayTeam);
                        allFixtures[awayTeam].futureOpponents.push(homeTeam);
                    }
                }
            });
            return allFixtures;
        }

        async function calculateAndDisplayFixtureDifficulty(newlyFinishedMatches = new Map()) {
            const scheduleData = await fetchAndCacheSchedule();
            if (!scheduleData) {
                document.querySelectorAll(`td:nth-child(${CONFIG.COLUMNS.FIXTURE_DIFFICULTY + 1})`).forEach(cell => {
                    if (cell) {
                        cell.textContent = '-';
                        cell.title = i18n.get('fzNotAvailable');
                    }
                });
                return;
            }
            const allFixtures = parseScheduleForAllTeams(scheduleData.htmlText, newlyFinishedMatches);
            const teamRankings = new Map();
            document.querySelectorAll(CONFIG.SELECTORS.TABLE_ROWS).forEach(row => {
                const teamLink = row.querySelector(CONFIG.SELECTORS.TEAM_LINK_IN_ROW);
                const rank = parseInt(row.cells[CONFIG.COLUMNS.POSITION].textContent, 10);
                if (teamLink && !isNaN(rank)) teamRankings.set(teamLink.textContent.trim(), rank);
            });
            document.querySelectorAll(CONFIG.SELECTORS.TABLE_ROWS).forEach(row => {
                const teamLink = row.querySelector(CONFIG.SELECTORS.TEAM_LINK_IN_ROW);
                if (!teamLink) return;
                const teamName = teamLink.textContent.trim();
                const teamFixture = allFixtures[teamName];
                const fzCell = row.cells[CONFIG.COLUMNS.FIXTURE_DIFFICULTY];
                if (fzCell && teamFixture && teamFixture.futureOpponents.length > 0) {
                    const rankSum = teamFixture.futureOpponents.reduce((sum, opponentName) => sum + (teamRankings.get(opponentName) || 0), 0);
                    const fzValue = rankSum / teamFixture.futureOpponents.length;
                    fzCell.textContent = fzValue.toFixed(1);
                    fzCell.title = i18n.get('fzTooltip', {
                        remaining: teamFixture.futureOpponents.length,
                        rankSum: rankSum
                    });
                } else if (fzCell) {
                    fzCell.textContent = '-';
                    fzCell.title = i18n.get('fzNoMatchesLeft');
                }
            });
        }

        async function run() {
            if (!isMainLeagueTableVisible()) {
                return;
            }
            if (!originalTableBody) {
                const tbody = document.querySelector(CONFIG.SELECTORS.TABLE_BODY);
                if (tbody) originalTableBody = tbody.cloneNode(true);
            }
            toggleLogoVisibility();
            addFixtureDifficultyColumn();
            const myTeamRow = document.querySelector(CONFIG.SELECTORS.MY_TEAM_ROW);
            const myTeamLink = myTeamRow?.querySelector(CONFIG.SELECTORS.TEAM_LINK_IN_ROW);
            if (myTeamLink) {
                myTeamInfo.name = myTeamLink.textContent.trim();
                myTeamInfo.id = new URLSearchParams(myTeamLink.href).get('tid');
            }
            await fetchAndCacheSchedule();
            await calculateAndDisplayFixtureDifficulty();
            if (myTeamInfo.id) {
                await performFullOpponentAnalysis();
            }
            setupLiveUpdateFeature();
            setupSettingsMenu();
        }

        async function initializeScript() {
            isLogoDisplayEnabled = await GM_getValue('showTeamLogos', true);
            injectStyles();
            createSettingsModal();
            NProgress.configure({
                showSpinner: false
            });
            const contentArea = document.querySelector(CONFIG.SELECTORS.CONTENT_DIV);
            if (!contentArea) return;
            const observer = new MutationObserver((mutations) => {
                for (const mutation of mutations) {
                    if (mutation.addedNodes.length) {
                        if (isMainLeagueTableVisible() && !document.querySelector(`.${CONFIG.CLASSES.FZ_HEADER}`)) {
                            fullScheduleCache = null;
                            originalTableBody = null;
                            run();
                            break;
                        }
                    }
                }
            });
            observer.observe(contentArea, {
                childList: true,
                subtree: true
            });
            run();
        }

        initializeScript();
    }


    /****************************************************************************************
     *                                                                                      *
     *  BÖLÜM 2: OYUNCU İSTATİSTİK BETİĞİ (ManagerZone Player Stat Averages)                  *
     *                                                                                      *
     ****************************************************************************************/
    function initializePlayerStatsScript() {
        // --- INTERNATIONALIZATION (i18n) ---
        const translations = {
            tr: {
                // UI Buttons & Titles
                autoScan: "Otomatik Tara",
                statistics: "İstatistikler",
                compare: "Karşılaştır",
                clearData: "Verileri Sil",
                compareAllPlayers: "Tüm Oyuncuları Karşılaştır",
                autoScanOptions: "Otomatik Tarama Seçenekleri",
                playerComparison: "Oyuncu Karşılaştırması",
                scanSelectedCategories: (count) => `Seçilen ${count} Kategoride Taramayı Başlat`,
                avgStatsForMatches: (count) => `Ortalama İstatistikler (${count} maç)`,
                exportToExcel: "Excel'e Aktar",
                exporting: "Dışa aktarılıyor...",
                // UI Texts & Placeholders
                scanInfo: "Aşağıdan istatistiklerini toplamak istediğiniz maç türlerini seçin.",
                selectAll: "Tümünü Seç",
                deselectAll: "Seçimi Kaldır",
                // Popups & Alerts
                loadingPlayerList: "Oyuncu listeniz oluşturuluyor, lütfen bekleyin...",
                noDataFound: "Karşılaştırılacak oyuncu veya istatistik bulunamadı. Lütfen önce 'Oyuncular' sayfanızı ziyaret ederek listenizi oluşturun veya bir tarama yapın.",
                confirmClearData: "Tüm oyuncu istatistikleri ve taranan maç kayıtları kalıcı olarak silinecek. Emin misiniz?",
                allDataCleared: "Tüm istatistik verileri başarıyla temizlendi.",
                noMatchTypes: "Taranacak maç tipi bulunamadı.",
                confirmScan: (count) => `${count} farklı maç tipi taranacak. Bu işlem arka planda çalışacak ve biraz zaman alabilir. Devam edilsin mi?`,
                scanStarting: "Tarama başlıyor...",
                scanningCategory: (name, current, total) => `Kategori taranıyor: ${name} (${current}/${total})`,
                // *** DEĞİŞİKLİK BURADA BAŞLIYOR ***
                processingNewMatch: (catIndex, catTotal, category, matchCurrent, matchTotal, totalScanned, totalOverall) => `Kategori: ${catIndex}/${catTotal} (${category}) | Maç: ${matchCurrent}/${matchTotal} | Toplam: ${totalScanned}/${totalOverall}`,
                // *** DEĞİŞİKLİK BURADA BİTİYOR ***
                errorFetchingMatch: (mid) => `Hata: Maç ID ${mid} çekilemedi.`,
                errorProcessingCategory: (name) => `Hata: ${name} işlenemedi. Sonrakine geçiliyor...`,
                scanFinishedVerifying: "Tarama bitti, kadro listesi doğrulanıyor...",
                scanSuccessNewMatches: "Otomatik tarama başarıyla tamamlandı! Yeni maç istatistikleri eklendi.",
                scanSuccessNoNewMatches: "Tarama tamamlandı. Seçilen kategorilerde taranacak yeni maç bulunamadı.",
                noPlayersToShow: "Gösterilecek oyuncu bulunamadı.",
                noMatchesForCriteria: "Seçili kriterlere uygun maç bulunamadı.",
                exportError: "Excel'e aktarma sırasında bir hata oluştu.",
                // Filters & Table Headers
                all: "Tümü",
                none: "Yok",
                league: "Lig", // Kategori için eklendi
                under18: "Altı 18",
                under21: "Altı 21",
                under23: "Altı 23",
                player: "Oyuncu",
                age: "Yaş",
                matches: "Maç",
                totalSuffix: "(Toplam)",
                avgSuffix: "(Ort.)",
                // Stat Mappings (Türkçe)
                statMappings: {
                    'MP': 'Oynadığı Süre (dk)', 'G': 'Gol', 'A': 'Asist', 'S': 'Şut', 'G%': 'Gol Yüzdesi',
                    'SOT': 'Kaleyi Bulan Şut', 'SOT%': 'Kaleyi Bulan Şut Yüzdesi', 'P%': 'Başarılı Pas Yüzdesi',
                    'PL': 'Ortalama Başarılı Pas Mesafesi (m)', 'In': 'Akın Kesme', 'T': 'Top Çalma',
                    'T%': 'Top Çalma Yüzdesi', 'Pos%': 'Tüm takım içinde topa sahip olma yüzdesi', 'Dist': 'Kat Edilen Mesafe (km)',
                    'DistP': 'Topla toplam katedilen mesafesi (km)', 'SpP': 'Topla ortalama hızı (km/s)',
                    'SpR': 'Koşarken ortalama hızı (km/s)', 'Pen': 'Penaltı', 'YC': 'Sarı Kart',
                    'RC': 'Kırmızı Kart', 'SV': 'Kurtarış'
                }
            },
            en: {
                // UI Buttons & Titles
                autoScan: "Auto-Scan",
                statistics: "Statistics",
                compare: "Compare",
                clearData: "Clear Data",
                compareAllPlayers: "Compare All Players",
                autoScanOptions: "Auto-Scan Options",
                playerComparison: "Player Comparison",
                scanSelectedCategories: (count) => `Start Scan for ${count} Selected Categories`,
                avgStatsForMatches: (count) => `Average Statistics (${count} matches)`,
                exportToExcel: "Export to Excel",
                exporting: "Exporting...",
                // UI Texts & Placeholders
                scanInfo: "Select the match types you want to collect statistics from below.",
                selectAll: "Select All",
                deselectAll: "Deselect All",
                // Popups & Alerts
                loadingPlayerList: "Creating your player list, please wait...",
                noDataFound: "No players or statistics found to compare. Please visit your 'Squad' page first to create your list or perform a scan.",
                confirmClearData: "All player statistics and scanned match records will be permanently deleted. Are you sure?",
                allDataCleared: "All statistics data has been successfully cleared.",
                noMatchTypes: "No match types found to scan.",
                confirmScan: (count) => `${count} different match types will be scanned. This process will run in the background and may take some time. Do you want to continue?`,
                scanStarting: "Scan is starting...",
                scanningCategory: (name, current, total) => `Scanning category: ${name} (${current}/${total})`,
                // *** DEĞİŞİKLİK BURADA BAŞLIYOR ***
                processingNewMatch: (catIndex, catTotal, category, matchCurrent, matchTotal, totalScanned, totalOverall) => `Category: ${catIndex}/${catTotal} (${category}) | Match: ${matchCurrent}/${matchTotal} | Total: ${totalScanned}/${totalOverall}`,
                // *** DEĞİŞİKLİK BURADA BİTİYOR ***
                errorFetchingMatch: (mid) => `Error: Could not fetch match ID ${mid}.`,
                errorProcessingCategory: (name) => `Error: Could not process ${name}. Skipping to the next one...`,
                scanFinishedVerifying: "Scan finished, verifying squad list...",
                scanSuccessNewMatches: "Automated scan completed successfully! New match statistics have been added.",
                scanSuccessNoNewMatches: "Scan completed. No new matches were found to scan in the selected categories.",
                noPlayersToShow: "No players to display.",
                noMatchesForCriteria: "No matches found for the selected criteria.",
                exportError: "An error occurred during the Excel export.",
                // Filters & Table Headers
                all: "All",
                none: "None",
                league: "League", // Added for category
                under18: "Under 18",
                under21: "Under 21",
                under23: "Under 23",
                player: "Player",
                age: "Age",
                matches: "Matches",
                totalSuffix: "(Total)",
                avgSuffix: "(Avg.)",
                // Stat Mappings (English) - Based on the provided HTML
                statMappings: {
                    'MP': 'Minutes played', 'G': 'Goals', 'A': 'Assists', 'S': 'Shots', 'G%': 'Goal percentage',
                    'SOT': 'Shots on target', 'SOT%': 'Shots on target percentage', 'P%': 'Successful pass percentage',
                    'PL': 'Average successful pass length (m)', 'In': 'Interceptions', 'T': 'Tackles',
                    'T%': 'Successful tackle percentage', 'Pos%': 'Team possession percentage', 'Dist': 'Distance covered (km)',
                    'DistP': 'Distance covered with ball (km)', 'SpP': 'Average speed with ball (km/h)',
                    'SpR': 'Average running speed (km/h)', 'Pen': 'Penalties', 'YC': 'Yellow Cards',
                    'RC': 'Red Cards', 'SV': 'Saves'
                }
            }
        };

        // Detect site language from the meta tag.
        const detectedLang = $('meta[name="language"]').attr('content') || 'en';
        // Use Turkish if the site language is 'tr', otherwise default to English for all other languages.
        const lang = detectedLang === 'tr' ? 'tr' : 'en';
        const i18n = translations[lang];

        function getShortCategoryName(category) {
            if (category === "Federasyon Çatışması Gözlemci Maçı") return "Fed. Gözlemci";
            if (category === "Federasyon Çatışması Mücadelesi") return "Fed. Mücadelesi";
            if (category === "Ödüllü/Dostluk Kupası") return "Ödüllü/Dostluk";
            if (category === "Federation Clash Scout Match") return "Fed. Scout";
            if (category === "Federation Clash Challenge") return "Fed. Challenge";
            if (category === "Prized/Friendly Cup") return "Prized/Friendly";
            if (category === "Federationsclash: Scoutmatch") return "Fed. Scout";
            if (category === "Federationsclash: Utmaning") return "Fed. Utmaning";
            return category;
        }

        // Global variable
        let squadPlayersWithStats = [];

        // --- Helper Functions ---
        const sleep = (ms) => new Promise(resolve => setTimeout(resolve, ms));

        // --- Style Definitions ---
        GM_addStyle(`
        .mz-script-button {
            padding: 8px 15px; border: none; border-radius: 5px; cursor: pointer;
            font-size: 14px; font-weight: bold; color: white; text-align: center;
            transition: background-color 0.2s, opacity 0.2s; vertical-align: middle; margin: 5px;
        }
        .mz-script-button:disabled { background-color: #6c757d !important; opacity: 0.7; cursor: not-allowed; }
        .mz-script-button:hover:not(:disabled) { filter: brightness(110%); }
        #comparePlayersButton { background-color: #17a2b8; }
        #player-stats-popup, #player-comparison-popup, #scrape-options-popup {
            position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%);
            background-color: #f8f9fa; border: 2px solid #343a40; border-radius: 10px;
            padding: 15px; z-index: 10000; box-shadow: 0 5px 15px rgba(0,0,0,0.3);
            color: #212529; font-family: Dosis, sans-serif;
            width: 95vw; max-width: 1500px; max-height: 85vh;
            overflow: hidden; display: flex; flex-direction: column; box-sizing: border-box;
        }
        .popup-content-scrollable { overflow-y: auto; flex-grow: 1; padding-right: 5px; }
        .popup-header { display: flex; justify-content: space-between; align-items: center; border-bottom: 1px solid #dee2e6; padding-bottom: 10px; margin-bottom: 15px; flex-shrink: 0; }
        .popup-header h3 { margin: 0; color: #00529B; font-size: 1.1rem; }
        .popup-filters { display: flex; gap: 10px; margin-bottom: 15px; flex-wrap: wrap; flex-shrink: 0; align-items: center; }
        .popup-filters select, #player-switcher { padding: 8px; border-radius: 4px; border: 1px solid #ccc; background-color: white; }
        #player-switcher { margin-right: 15px; }
        #player-stats-popup table, #player-comparison-popup table { width: 100%; border-collapse: collapse; font-size: 13px; }
        #player-stats-popup th, #player-stats-popup td, #player-comparison-popup th, #player-comparison-popup td { border: 1px solid #dee2e6; padding: 8px; text-align: left; white-space: nowrap; }
        #player-stats-popup th, #player-comparison-popup th { background-color: #e9ecef; }
        [data-tooltip] { cursor: help !important; }
        #player-comparison-popup .sort-asc::after { content: ' ▲'; color: #007bff; }
        #player-comparison-popup .sort-desc::after { content: ' ▼'; color: #007bff; }
        #player-comparison-popup .sort-sum-desc::after { content: ' (T ▼)'; color: #dc3545; }
        #player-comparison-popup .sort-sum-asc::after { content: ' (T ▲)'; color: #dc3545; }
        #player-comparison-popup .sort-avg-desc::after { content: ' (O ▼)'; color: #28a745; }
        #player-comparison-popup .sort-avg-asc::after { content: ' (O ▲)'; color: #28a745; }
        .table-responsive-wrapper { width: 100%; overflow-x: auto; -webkit-overflow-scrolling: touch; border: 1px solid #ddd; border-radius: 5px; }
        .popup-close { font-size: 28px; font-weight: bold; cursor: pointer; color: #adb5bd; line-height: 1; }
        #mz-stat-loader { position: fixed; top: 0; left: 0; width: 100%; background: #28a745; color: white; padding: 10px 0; z-index: 10001; font-weight: bold; box-shadow: 0 2px 5px rgba(0,0,0,0.2); text-align: center; font-size: 16px; display: none; }
        #custom-tooltip { position: fixed; display: none; background-color: #222; color: white; padding: 8px 12px; border-radius: 5px; z-index: 10005; font-size: 12px; max-width: 250px; text-align: center; pointer-events: none; }
        .colored-cell { color: black; font-weight: bold; }
        #mz-stats-actions-container { display: inline-flex; gap: 8px; margin-left: 15px; vertical-align: middle; flex-wrap: wrap; justify-content: center; }
        #mz-stats-actions-container button {
            padding: 8px 12px; border: none; border-radius: 5px; cursor: pointer; font-size: 12px;
            font-weight: bold; color: white; text-align: center; transition: opacity 0.2s, background-color 0.2s;
        }
        #mz-stats-actions-container button:disabled { background-color: #6c757d !important; opacity: 0.7; cursor: not-allowed; }
        #scrapeStatsButton { background-color: #007bff; }
        #viewPlayerStatsButton { background-color: #fd7e14; }
        #comparePlayersButtonMatchPage { background-color: #17a2b8; }
        #clearAllStatsButton { background-color: #dc3545; }
        #scrape-options-list { list-style-type: none; padding: 0; margin: 0 0 15px 0; display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 10px; max-height: 300px; overflow-y: auto; }
        #scrape-options-list li { background: #e9ecef; padding: 8px; border-radius: 4px; }
        #scrape-options-list label { display: flex; align-items: center; gap: 8px; font-size: 14px; cursor: pointer; }
        .scrape-options-controls { display: flex; justify-content: space-between; align-items: center; margin-bottom: 15px; }
        #start-scrape-button { background-color: #28a745; color: white; padding: 12px 20px; font-size: 16px; border: none; border-radius: 5px; cursor: pointer; width: 100%; }

        #player-stats-popup {
            width: auto;
            min-width: 500px;
        }
        #popup-stats-table {
            margin: 0 auto;
        }

        /* GÜNCELLENMİŞ STİLLER: Dinamik İstatistik Kutusu */
        .dynamic-stats-container {
            position: relative;
            display: inline-flex;
            align-items: center;
            vertical-align: middle;
            margin-left: 4px;
            white-space: nowrap;
        }
        .stats-display-area {
            display: inline-flex;
            align-items: center;
            gap: 5px;
            cursor: pointer;
            font-size: 11px; /* Orijinal ikonlarla aynı boyutta */
        }
        .stats-display-area .category-name {
            font-weight: bold;
            color: #00529B;
        }
        .stats-display-area .stats-values span {
            display: inline-flex;
            align-items: center;
            gap: 2px;
            margin-left: 4px;
        }
        .stats-display-area img {
            width: 10px;
            height: 10px;
            vertical-align: middle;
        }
        .assist-icon {
            font-family: "Arial", sans-serif;
            font-weight: bold;
            font-size: 14px;
            color: #28a745; /* Yeşil renk */
            vertical-align: middle;
            line-height: 1;
        }
        .stats-category-dropdown {
            display: none;
            position: absolute;
            top: 100%;
            left: 0;
            background-color: white;
            border: 1px solid #ccc;
            border-radius: 4px;
            box-shadow: 0 4px 8px rgba(0,0,0,0.1);
            z-index: 10010;
            list-style-type: none;
            padding: 5px 0;
            margin: 2px 0 0 0;
            max-height: 200px;
            overflow-y: auto;
        }
        .stats-category-dropdown li {
            padding: 6px 15px;
            cursor: pointer;
            font-size: 13px;
            white-space: nowrap;
        }
        .stats-category-dropdown li:hover {
            background-color: #f0f0f0;
        }


        @media (max-width: 768px) {
            .popup-filters { flex-direction: column; align-items: stretch; }
            #player-switcher { margin: 10px 0; }
            .popup-header h3 { font-size: 1rem; }
        }
    `);

        // --- Page Router ---
        const params = new URLSearchParams(window.location.search);
        const p = params.get('p');
        const sub = params.get('sub');

        if (p === 'match' && sub === 'played') {
            initMatchPage();
        } else if (p === 'players' || (p === 'player' && params.has('pid'))) {
            initPlayersPage();
        }


        // --- Core Functions ---
        async function updateUserPlayerList() {
            const players = [];
            $('.playerContainer').each(function() {
                const pid = $(this).find('span.player_id_span').text();
                const name = $(this).find('h2.subheader a .player_name').text().trim();
                if (pid && name) {
                    const ageText = $(this).find('.dg_playerview_info table tr:first-child td:first-child').text();
                    let age = parseInt(ageText.replace(/[^0-9]/g, ''));
                    if (isNaN(age)) {
                        age = 0;
                    }
                    players.push({
                        pid: pid,
                        name: name,
                        age: age
                    });
                }
            });
            if (players.length > 0) {
                await GM_setValue('myPlayerList', JSON.stringify(players));
            }
        }

        async function populateSquadPlayers() {
            const myPlayerList = JSON.parse(await GM_getValue('myPlayerList', '[]'));
            if (myPlayerList.length > 0) {
                squadPlayersWithStats = [...myPlayerList];
                squadPlayersWithStats.sort((a, b) => a.name.localeCompare(b.name, lang === 'tr' ? 'tr-TR' : undefined));
            } else {
                squadPlayersWithStats = [];
            }
        }

        async function refreshUserPlayerListFromSource() {
            try {
                const response = await fetch('https://www.managerzone.com/?p=players');
                if (!response.ok) {
                    return false;
                }
                const html = await response.text();
                const doc = new DOMParser().parseFromString(html, 'text/html');
                const players = [];
                $(doc).find('.playerContainer').each(function() {
                    const pid = $(this).find('span.player_id_span').text();
                    const name = $(this).find('h2.subheader a .player_name').text().trim();
                    if (pid && name) {
                        const ageText = $(this).find('.dg_playerview_info table tr:first-child td:first-child').text();
                        let age = parseInt(ageText.replace(/[^0-9]/g, ''));
                        if (isNaN(age)) {
                            age = 0;
                        }
                        players.push({
                            pid: pid,
                            name: name,
                            age: age
                        });
                    }
                });
                if (players.length > 0) {
                    await GM_setValue('myPlayerList', JSON.stringify(players));
                    return true;
                } else {
                    return false;
                }
            } catch (error) {
                return false;
            }
        }


        // =================================================================== //
        // --- MATCH PAGE FUNCTIONS --- //
        // =================================================================== //

        async function initMatchPage() {
            $('body').append('<div id="custom-tooltip"></div>').append(`<div id="mz-stat-loader"></div>`);
            setupTooltipListeners();
            const targetElement = $('#squad-search-toggle').length ? $('#squad-search-toggle') : $('.match-info-r1.block').first();
            if (targetElement.length > 0) {
                const actionsContainer = $('<div id="mz-stats-actions-container"></div>');
                targetElement.after(actionsContainer);
                createScrapeButton(actionsContainer);
                createMatchPageActionButtons(actionsContainer);
            }
        }

        function createScrapeButton(container) {
            $(`<button id="scrapeStatsButton" class="mz-script-button">${i18n.autoScan}</button>`)
                .appendTo(container)
                .on('click', showMatchTypeSelectionPopup);
        }

        async function ensurePlayerListIsPopulated() {
            await populateSquadPlayers();
            if (squadPlayersWithStats.length === 0) {
                const loader = $('#mz-stat-loader');
                loader.text(i18n.loadingPlayerList).show();
                const success = await refreshUserPlayerListFromSource();
                loader.hide();
                if (success) {
                    await populateSquadPlayers();
                }
            }
            if (squadPlayersWithStats.length === 0) {
                alert(i18n.noDataFound);
                return false;
            }
            return true;
        }

        async function updateMatchPageButtonStates() {
            const statsData = await GM_getValue('playerStatsRaw', '{}');
            const hasData = Object.keys(JSON.parse(statsData)).length > 0;
            $('#viewPlayerStatsButton').prop('disabled', !hasData);
            $('#comparePlayersButtonMatchPage').prop('disabled', !hasData);
            $('#clearAllStatsButton').prop('disabled', !hasData);
        }

        function createMatchPageActionButtons(container) {
            container.find('#viewPlayerStatsButton, #comparePlayersButtonMatchPage, #clearAllStatsButton').remove();
            $(`<button id="viewPlayerStatsButton" class="mz-script-button">${i18n.statistics}</button>`)
                .appendTo(container)
                .on('click', async () => {
                if (await ensurePlayerListIsPopulated()) showStatsPopup(squadPlayersWithStats[0].pid);
            });
            $(`<button id="comparePlayersButtonMatchPage" class="mz-script-button">${i18n.compare}</button>`)
                .appendTo(container)
                .on('click', async () => {
                if (await ensurePlayerListIsPopulated()) showAllPlayersComparisonPopup();
            });
            $(`<button id="clearAllStatsButton" class="mz-script-button">${i18n.clearData}</button>`)
                .appendTo(container)
                .on('click', async () => {
                if (confirm(i18n.confirmClearData)) {
                    await GM_deleteValue('playerStatsRaw');
                    await GM_deleteValue('processedMatchIds');
                    // AŞAĞIDAKİ SATIRI SİLİN VEYA DEVRE DIŞI BIRAKIN
                    // alert(i18n.allDataCleared);
                    await updateMatchPageButtonStates();
                }
            });
            updateMatchPageButtonStates();
        }

        function showMatchTypeSelectionPopup() {
            $('#scrape-options-popup').remove();
            const matchTypes = [];

            $('select[name="selectType"] optgroup:first option').each(function() {
                matchTypes.push({
                    value: $(this).val(),
                    text: $(this).text().trim()
                });
            });

            if (matchTypes.length === 0) {
                alert(i18n.noMatchTypes);
                return;
            }

            const optionsHTML = matchTypes.map(mt => `<li><label><input type="checkbox" class="match-type-checkbox" value="${mt.value}" data-text="${mt.text}" checked> ${mt.text}</label></li>`).join('');
            const popupHTML = `
            <div id="scrape-options-popup">
                <div class="popup-header"><h3>${i18n.autoScanOptions}</h3><span class="popup-close">×</span></div>
                <div class="popup-content-scrollable">
                    <p>${i18n.scanInfo}</p>
                    <div class="scrape-options-controls"><a href="#" id="select-all-types">${i18n.selectAll}</a><a href="#" id="deselect-all-types">${i18n.deselectAll}</a></div>
                    <ul id="scrape-options-list">${optionsHTML}</ul>
                    <button id="start-scrape-button">${i18n.scanSelectedCategories(matchTypes.length)}</button>
                </div>
            </div>`;
            $('body').append(popupHTML);
            $('.popup-close').on('click', () => $('#scrape-options-popup').remove());
            $('#select-all-types').on('click', (e) => {
                e.preventDefault();
                $('.match-type-checkbox').prop('checked', true).trigger('change');
            });
            $('#deselect-all-types').on('click', (e) => {
                e.preventDefault();
                $('.match-type-checkbox').prop('checked', false).trigger('change');
            });
            $('.match-type-checkbox').on('change', () => {
                const count = $('.match-type-checkbox:checked').length;
                $('#start-scrape-button').text(i18n.scanSelectedCategories(count)).prop('disabled', count === 0);
            });
            $('#start-scrape-button').on('click', function() {
                const selectedTypes = [];
                $('.match-type-checkbox:checked').each(function() {
                    selectedTypes.push({
                        value: $(this).val(),
                        text: $(this).data('text')
                    });
                });
                if (selectedTypes.length > 0) {
                    $('#scrape-options-popup').remove();
                    startAutomatedScrape(selectedTypes);
                }
                $(this).prop('disabled', true);
            });
        }

        // *** DEĞİŞTİRİLEN FONKSİYON ***
        async function startAutomatedScrape(selectedTypes) {
            const loader = $('#mz-stat-loader');
            loader.text(i18n.scanStarting).show();

            const canonicalStatHeaders = [
                null, 'Po', 'MP', 'G', 'A', 'S', 'G%', 'SOT', 'SOT%', 'OG', 'P', 'P_S', 'P_F',
                'P%', 'PL', 'In', 'T_raw', 'T_S', 'T_F', 'T%', 'PosTime', 'Pos%', 'Dist',
                'DistP', 'SpP', 'SpR', 'Cr', 'Fk', 'Pen', 'YC', 'RC', 'SV'
            ];

            let newMatchesFound = false,
                playerStats = JSON.parse(await GM_getValue('playerStatsRaw', '{}')),
                processedMatchIds = new Set(JSON.parse(await GM_getValue('processedMatchIds', '[]'))),
                myPlayerList = JSON.parse(await GM_getValue('myPlayerList', '[]')),
                myPlayerPids = new Set(myPlayerList.map(p => p.pid));

            let totalMatchesToScan = 0;
            let totalMatchesScanned = 0;

            // 1. ADIM: Toplam taranacak yeni maç sayısını hesapla
            loader.text(lang === 'tr' ? 'Taranacak toplam maç sayısı hesaplanıyor...' : 'Calculating total matches to scan...').show();
            for (const category of selectedTypes) {
                try {
                    const categoryUrl = `https://www.managerzone.com/?p=match&sub=played&selectType=${category.value}&selectTimeLimit=maximum`;
                    const categoryResponse = await fetch(categoryUrl);
                    const categoryHtml = await categoryResponse.text();
                    const categoryDoc = new DOMParser().parseFromString(categoryHtml, 'text/html');
                    const uniqueLinksMap = new Map();
                    $(categoryDoc).find('#fixtures-results-list a.gradientSunriseIcon[href*="sub=stats"]').each(function() {
                        const href = $(this).attr('href'),
                              mid = new URLSearchParams(href.split('?')[1]).get('mid');
                        if (mid && !uniqueLinksMap.has(mid)) uniqueLinksMap.set(mid, { mid: mid });
                    });
                    const newLinksToScrape = Array.from(uniqueLinksMap.values()).filter(linkInfo => !processedMatchIds.has(linkInfo.mid));
                    totalMatchesToScan += newLinksToScrape.length;
                } catch (e) {
                     console.error(`Ön tarama hatası: ${category.text}`, e);
                }
            }


            // 2. ADIM: Asıl tarama işlemini yap
            for (const [categoryIndex, category] of selectedTypes.entries()) {
                // Kategori adını göster (opsiyonel ama kullanıcı dostu)
                loader.text(i18n.scanningCategory(category.text, categoryIndex + 1, selectedTypes.length));
                try {
                    const categoryUrl = `https://www.managerzone.com/?p=match&sub=played&selectType=${category.value}&selectTimeLimit=maximum`;
                    const categoryResponse = await fetch(categoryUrl);
                    const categoryHtml = await categoryResponse.text();
                    const categoryDoc = new DOMParser().parseFromString(categoryHtml, 'text/html');
                    const uniqueLinksMap = new Map();
                    $(categoryDoc).find('#fixtures-results-list a.gradientSunriseIcon[href*="sub=stats"]').each(function() {
                        const href = $(this).attr('href'),
                              mid = new URLSearchParams(href.split('?')[1]).get('mid');
                        if (mid && !uniqueLinksMap.has(mid)) uniqueLinksMap.set(mid, {
                            href: href,
                            mid: mid
                        });
                    });
                    const newLinksToScrape = Array.from(uniqueLinksMap.values()).filter(linkInfo => !processedMatchIds.has(linkInfo.mid));

                    if (newLinksToScrape.length > 0) {
                        newMatchesFound = true;
                        for (const [linkIndex, linkInfo] of newLinksToScrape.entries()) {
                            totalMatchesScanned++;
                            // 3. ADIM: Detaylı ilerleme bilgisini göster
                            loader.text(i18n.processingNewMatch(
                                categoryIndex + 1,
                                selectedTypes.length,
                                category.text,
                                linkIndex + 1,
                                newLinksToScrape.length,
                                totalMatchesScanned,
                                totalMatchesToScan
                            ));

                            try {
                                const matchUrl = new URL('https://www.managerzone.com/');
                                matchUrl.search = new URLSearchParams(linkInfo.href.split('?')[1]);
                                const matchResponse = await fetch(matchUrl.toString());
                                const matchHtml = await matchResponse.text();
                                const matchDoc = new DOMParser().parseFromString(matchHtml, 'text/html');

                                let ageLimit = i18n.none;
                                const categoryTextLower = category.text.toLowerCase();
                                if (categoryTextLower.includes('18')) ageLimit = i18n.under18;
                                else if (categoryTextLower.includes('21')) ageLimit = i18n.under21;
                                else if (categoryTextLower.includes('23')) ageLimit = i18n.under23;

                                $(matchDoc).find('.matchStats--detailed tbody tr').each(function() {
                                    const playerLink = $(this).find('a.player_link');
                                    if (playerLink.length) {
                                        const pid = new URLSearchParams(playerLink.attr('href').split('?')[1]).get('pid'),
                                              name = playerLink.text().trim();
                                        if (!myPlayerPids.has(pid)) {
                                            myPlayerList.push({
                                                pid,
                                                name,
                                                age: 0
                                            });
                                            myPlayerPids.add(pid);
                                        }
                                        if (!playerStats[pid]) playerStats[pid] = {
                                            name: name,
                                            matches: []
                                        };
                                        playerStats[pid].name = name;
                                        const currentMatchStats = {};

                                        $(this).find('td').each(function(colIndex) {
                                            const statName = canonicalStatHeaders[colIndex];
                                            if (statName && !['Po', 'OG', 'Cr', 'Fk', 'P', 'P_S', 'P_F', 'T_raw', 'T_S', 'T_F', 'PosTime'].includes(statName)) {
                                                const rawValue = $(this).text().trim().replace('%', '').replace(',', '.').replace("'", "");
                                                let numValue = parseFloat(rawValue);
                                                if (statName === 'T' && currentMatchStats['T%'] !== undefined) {
                                                } else if (!isNaN(numValue)) {
                                                    currentMatchStats[statName] = numValue;
                                                }
                                            }
                                        });

                                        if (Object.keys(currentMatchStats).length > 0) {
                                            playerStats[pid].matches.push({
                                                matchId: linkInfo.mid,
                                                matchType: category.text,
                                                ageLimit: ageLimit,
                                                stats: currentMatchStats
                                            });
                                        }
                                    }
                                });
                                processedMatchIds.add(linkInfo.mid);
                            } catch (error) {
                                console.error(i18n.errorFetchingMatch(linkInfo.mid), error);
                            }
                            await sleep(250);
                        }
                    } else {
                        await sleep(500);
                    }
                } catch (error) {
                    loader.text(i18n.errorProcessingCategory(category.text));
                    await sleep(2000);
                }
            }
            await GM_setValue('playerStatsRaw', JSON.stringify(playerStats));
            await GM_setValue('processedMatchIds', JSON.stringify(Array.from(processedMatchIds)));
            loader.text(i18n.scanFinishedVerifying);
            await refreshUserPlayerListFromSource();
            await populateSquadPlayers();
            loader.hide();
            await updateMatchPageButtonStates();
            $('#start-scrape-button').prop('disabled', false);
        }

        // ========================================================================= //
        // --- PLAYER PAGE FUNCTIONS --- //
        // ========================================================================= //

        const displayColumns = ['MP', 'G', 'A', 'S', 'G%', 'SOT', 'SOT%', 'P%', 'PL', 'In', 'T%', 'Pos%', 'Dist', 'DistP', 'SpP', 'SpR', 'YC', 'RC', 'SV'];
        const sumAvgColumns = ['G', 'A', 'YC', 'RC'];

        function calculateAverages(playerData, filterType, filterAge) {
            if (!playerData || !playerData.matches) return null;
            const filteredMatches = playerData.matches.filter(match => (filterType === i18n.all || match.matchType === filterType) && (filterAge === i18n.all || match.ageLimit === filterAge));
            if (filteredMatches.length === 0) return {
                name: playerData.name,
                matches: 0
            };
            const totalStats = {},
                  statCounts = {};
            filteredMatches.forEach(match => {
                for (const key in match.stats) {
                    totalStats[key] = (totalStats[key] || 0) + match.stats[key];
                    statCounts[key] = (statCounts[key] || 0) + 1;
                }
            });
            const summary = {};
            for (const key in totalStats) {
                if (sumAvgColumns.includes(key)) {
                    summary[`${key}_sum`] = totalStats[key];
                    summary[`${key}_avg`] = (totalStats[key] / filteredMatches.length).toFixed(2);
                } else {
                    summary[key] = (totalStats[key] / statCounts[key]).toFixed(2);
                }
            }
            return {
                name: playerData.name,
                matches: filteredMatches.length,
                ...summary
            };
        }

        async function initPlayersPage() {
            $('body').append('<div id="custom-tooltip"></div>');
            if ($('.playerContainer').length > 0) {
                await updateUserPlayerList();
                $(`<button id="comparePlayersButton" class="mz-script-button">${i18n.compareAllPlayers}</button>`)
                    .insertAfter('#squad-search-toggle')
                    .on('click', showAllPlayersComparisonPopup);
            }
            await populateSquadPlayers();
            await injectStatsIcons(); // Make async to handle data fetching
            setupTooltipListeners();
            $(document).on('click', '.stats-button', function() {
                showStatsPopup($(this).data('pid'));
            });

            // GÜNCELLENMİŞ: Dinamik istatistik kutusu için olay dinleyicileri
            // Dropdown'ı aç/kapat
            $(document).on('click', '.stats-display-area', function(e) {
                e.stopPropagation();
                // Önce açık olan diğer tüm dropdown'ları kapat
                $('.stats-category-dropdown').not($(this).siblings('.stats-category-dropdown')).hide();
                $(this).siblings('.stats-category-dropdown').toggle();
            });

            // Kategori seçimi
            $(document).on('click', '.stats-category-dropdown li', async function(e) {
                e.stopPropagation();
                const selectedCategory = $(this).data('category'); // Orijinal ismi al
                const container = $(this).closest('.dynamic-stats-container');
                const pid = container.data('pid');

                const rawData = JSON.parse(await GM_getValue('playerStatsRaw', '{}'));
                const stats = getCategorySummaryStats(pid, selectedCategory, rawData);

                // Görünen alanı güncelle
                const displayArea = container.find('.stats-display-area');
                // YENİ: Görünen isme kısaltılmış halini yaz
                displayArea.find('.category-name').text(getShortCategoryName(selectedCategory));
                displayArea.find('.stat-g').text(stats.G);
                displayArea.find('.stat-a').text(stats.A);
                displayArea.find('.stat-yc').text(stats.YC);
                displayArea.find('.stat-rc').text(stats.RC);

                $(this).parent().hide(); // Dropdown'ı kapat
            });

            // Dışarı tıklayınca dropdown'ı kapat
            $(document).on('click', function() {
                $('.stats-category-dropdown').hide();
            });
        }


        async function injectStatsIcons() {
            await populateSquadPlayers();
            const rawData = JSON.parse(await GM_getValue('playerStatsRaw', '{}'));
            if (Object.keys(rawData).length === 0) return;

            const myPlayerPidsWithStats = new Set(Object.keys(rawData));
            const statsButtonHTML = `<button class="stats-button" style="padding: 2px 8px; font-size: 12px; margin-left: 10px; vertical-align: middle; background-color: #007bff; color: white; border: 1px solid #006fe6; border-radius: 12px; cursor: pointer;">${i18n.statistics}</button>`;

            const injectContent = (container) => {
                const pid = container.find('span.player_id_span').text().trim() || new URLSearchParams(window.location.search).get('pid');
                if (!pid) return;

                const isSinglePlayerPage = container.is('div.player-title');
                const headerTarget = isSinglePlayerPage ? container.find('h2') : container.find('h2.subheader a');

                if (myPlayerPidsWithStats.has(pid) && headerTarget.parent().find('.stats-button').length === 0) {
                    $(statsButtonHTML).data('pid', pid).insertAfter(headerTarget);
                }

                const statsTd = container.find('td[colspan="2"][style*="padding-top: 12px;"]');
                if (statsTd.length > 0 && statsTd.find('.dynamic-stats-container').length === 0 && myPlayerPidsWithStats.has(pid)) {
                    const playerData = rawData[pid];
                    if (!playerData || !playerData.matches || playerData.matches.length === 0) return;

                    const availableCategories = [...new Set(playerData.matches.map(m => m.matchType).filter(Boolean))];
                    if (availableCategories.length === 0) return;

                    let sortedCategories = availableCategories.sort();
                    sortedCategories.unshift(i18n.all);

                    const defaultCategory = i18n.all;
                    const defaultStats = getCategorySummaryStats(pid, defaultCategory, rawData);

                    const dropdownItemsHTML = sortedCategories.map(cat => `<li data-category="${cat}">${getShortCategoryName(cat)}</li>`).join('');

                    const dynamicStatsHTML = `
                        <div class="dynamic-stats-container" data-pid="${pid}">
                            <div class="stats-display-area" title="İstatistik kategorisini değiştirmek için tıklayın">
                                <span class="category-name">${getShortCategoryName(defaultCategory)}</span><span style="font-weight: bold; font-size: 10px; margin-left: 2px;">▼</span>
                                <div class="stats-values">
                                    <span title="${i18n.statMappings['G']}"><img src="/nocache-936/img/soccer/goal.gif"> <strong class="stat-g">${defaultStats.G}</strong></span>
                                    <span title="${i18n.statMappings['A']}"><span class="assist-icon">👟</span> <strong class="stat-a">${defaultStats.A}</strong></span>
                                    <span title="${i18n.statMappings['YC']}"><img src="/nocache-936/img/card_yellow.gif"> <strong class="stat-yc">${defaultStats.YC}</strong></span>
                                    <span title="${i18n.statMappings['RC']}"><img src="/nocache-936/img/card_red.gif"> <strong class="stat-rc">${defaultStats.RC}</strong></span>
                                </div>
                            </div>
                            <ul class="stats-category-dropdown">${dropdownItemsHTML}</ul>
                        </div>
                    `;

                    statsTd.find('img[src*="goal.gif"], img[src*="card_yellow.gif"], img[src*="card_red.gif"], br').remove();
                    statsTd.contents().filter(function() { return this.nodeType === 3; }).remove();
                    statsTd.prepend(dynamicStatsHTML);
                }
            };

            if ($('.playerContainer').length > 0) {
                $('.playerContainer').each(function() {
                    injectContent($(this));
                });
            } else if (window.location.href.includes('p=player&pid=')) {
                injectContent($('div.player-title').closest('.mainContent'));
            }
        }

        // DÜZELTİLDİ: Bu fonksiyon artık "Lig" kategorisini doğru ve kesin bir şekilde eşleştiriyor.
        function getCategorySummaryStats(pid, filterType, rawData) {
            const playerData = rawData[pid];
            if (!playerData || !playerData.matches) return { G: 0, A: 0, YC: 0, RC: 0 };

            const filteredMatches = playerData.matches.filter(match => {
                 if (!match.matchType) return false;
                 if (filterType === i18n.all) return true;
                 if (filterType === i18n.league) {
                     const matchTypeLower = match.matchType.toLowerCase();
                     return matchTypeLower === i18n.league.toLowerCase() || matchTypeLower.startsWith('div');
                 }
                 return match.matchType === filterType;
            });

            if (filteredMatches.length === 0) return { G: 0, A: 0, YC: 0, RC: 0 };

            return filteredMatches.reduce((acc, match) => {
                acc.G += match.stats.G || 0;
                acc.A += match.stats.A || 0;
                acc.YC += match.stats.YC || 0;
                acc.RC += match.stats.RC || 0;
                return acc;
            }, { G: 0, A: 0, YC: 0, RC: 0 });
        }


        // DÜZELTİLDİ: Bu fonksiyon artık oyuncuya özel kategorileri yükler ve 0 istatistikli olanları gizler.
        async function showStatsPopup(pid) {
            $('#player-stats-popup').remove();
            await populateSquadPlayers();
            if (squadPlayersWithStats.length === 0) {
                alert(i18n.noPlayersToShow);
                return;
            }

            const rawData = JSON.parse(await GM_getValue('playerStatsRaw', '{}'));
            const playerOptionsHTML = squadPlayersWithStats.map(player => `<option value="${player.pid}" ${player.pid === pid ? 'selected' : ''}>${player.name}</option>`).join('');

            const popupHTML = `
                <div id="player-stats-popup">
                    <div class="popup-header">
                        <h3 id="popup-title"></h3><span class="popup-close">×</span>
                    </div>
                    <div class="popup-content-scrollable">
                         <div style="display: flex; align-items: center;">
                           <select id="player-switcher">${playerOptionsHTML}</select>
                         </div>
                        <div id="popup-category-selector" class="popup-filters" style="flex-direction: column; align-items: stretch; border: 1px solid #ccc; border-radius: 5px; padding: 5px; cursor: pointer; position: relative; margin-top: 15px;">
                            <div id="category-display-wrapper" style="display: flex; justify-content: space-between; align-items: center;">
                                <span id="current-category-name" style="font-weight: bold; color: #00529B;"></span>
                                <div id="current-category-stats" style="display: flex; gap: 10px; align-items: center; font-size: 12px;"></div>
                                <span id="category-dropdown-trigger" style="font-weight: bold; padding: 0 5px;">▼</span>
                            </div>
                            <ul id="category-dropdown-list" style="display: none; position: absolute; top: 100%; left: -1px; right: -1px; background: white; border: 1px solid #ccc; list-style: none; padding: 0; margin: 5px 0 0; z-index: 10001; max-height: 200px; overflow-y: auto; border-radius: 0 0 5px 5px;">
                            </ul>
                        </div>
                        <table id="popup-stats-table" style="margin-top:15px;"><thead><tr><th>${i18n.statistics}</th><th>Value</th></tr></thead><tbody></tbody></table>
                    </div>
                </div>`;
            $('body').append(popupHTML);

            // Merkezi güncelleme fonksiyonu
            const updatePopupForPlayer = (currentPid) => {
                const playerData = rawData[currentPid];
                const playerName = (squadPlayersWithStats.find(p => p.pid === currentPid) || {}).name || '...';

                const availableCategories = new Set();
                if (playerData && playerData.matches) {
                     playerData.matches.forEach(m => { if(m.matchType) availableCategories.add(m.matchType) });
                }
                const sortedCategories = [...availableCategories].sort();

                if (sortedCategories.length > 0) {
                    // DEĞİŞİKLİK: "Tümü" seçeneğini her zaman listenin başına ekle
                    sortedCategories.unshift(i18n.all);

                    const categoryDropdown = $('#category-dropdown-list').empty();
                    sortedCategories.forEach(cat => {
                        categoryDropdown.append(`<li data-value="${cat}" style="padding: 8px 12px; cursor: pointer;">${getShortCategoryName(cat)}</li>`);
                    });
                    $('#popup-category-selector').show();

                    // DEĞİŞİKLİK: Varsayılan kategoriyi her zaman "Tümü" olarak ayarla
                    const defaultCategory = i18n.all;

                    $('#popup-category-selector').attr('data-selected-category', defaultCategory);
                    $('#current-category-name').text(getShortCategoryName(defaultCategory));
                    updateCategoryStatsDisplay(currentPid, defaultCategory, rawData);
                    updateStatsPopupTable(currentPid, defaultCategory);
                } else {
                     $('#popup-category-selector').hide();
                     updateStatsPopupTable(currentPid, i18n.all);
                }
            };

            const updateCategoryStatsDisplay = (currentPid, category, rawData) => {
                const stats = getCategorySummaryStats(currentPid, category, rawData);
                $('#current-category-stats').html(`
                    <span title="${i18n.statMappings['G']}"><img src="/nocache-936/img/soccer/goal.gif" style="width:10px; vertical-align: middle;"> ${stats.G}</span>
                    <span title="${i18n.statMappings['A']}"><span class="assist-icon" style="vertical-align: middle;">👟</span> ${stats.A}</span>
                    <span title="${i18n.statMappings['YC']}"><img src="/nocache-936/img/card_yellow.gif" style="width:8px; vertical-align: middle;"> ${stats.YC}</span>
                    <span title="${i18n.statMappings['RC']}"><img src="/nocache-936/img/card_red.gif" style="width:8px; vertical-align: middle;"> ${stats.RC}</span>
                `);
            };

            // Olay dinleyicileri
            $('#player-switcher').on('change', function() {
                 updatePopupForPlayer($(this).val());
            });

            $('#popup-category-selector').on('click', (e) => {
                e.stopPropagation();
                $('#category-dropdown-list').slideToggle(200);
            });

            $('#category-dropdown-list').on('mouseenter', 'li', function(){ $(this).css('background-color', '#f0f0f0'); });
            $('#category-dropdown-list').on('mouseleave', 'li', function(){ $(this).css('background-color', 'white'); });
            $('#category-dropdown-list').on('click', 'li', function(e) {
                e.stopPropagation();
                const selectedCategory = $(this).data('value');
                $('#popup-category-selector').attr('data-selected-category', selectedCategory);
                $('#current-category-name').text(getShortCategoryName(selectedCategory));
                const currentPid = $('#player-switcher').val();
                updateCategoryStatsDisplay(currentPid, selectedCategory, rawData);
                updateStatsPopupTable(currentPid, selectedCategory);
                $('#category-dropdown-list').hide();
            });

            $(document).on('click.statsPopup', function(e) {
                if (!$('#popup-category-selector').is(e.target) && $('#popup-category-selector').has(e.target).length === 0) {
                    $('#category-dropdown-list').slideUp(200);
                }
            });

            $('#player-stats-popup .popup-close').on('click', () => {
                 $('#player-stats-popup').remove();
                 $(document).off('click.statsPopup'); // Event listener'ı temizle
            });

            // İlk yükleme
            updatePopupForPlayer(pid);
        }

        async function updateStatsPopupTable(pid, filterType) {
            $('#player-stats-popup').data('pid', pid);
            const rawData = JSON.parse(await GM_getValue('playerStatsRaw', '{}'));
            let data = calculateAverages(rawData[pid], filterType, i18n.all);

            const tableBody = $('#popup-stats-table tbody').empty();
            if (!data) {
                const playerInfo = squadPlayersWithStats.find(p => p.pid === pid);
                data = { name: playerInfo ? playerInfo.name : 'Unknown Player', matches: 0 };
            }

            const matchesText = data.matches > 0 ? i18n.avgStatsForMatches(data.matches) : '';
             $('#popup-title').html(`${data.name} <br><small style="color: #6c757d;">${matchesText}</small>`);

            if (data.matches > 0) {
                displayColumns.forEach(key => {
                    const displayName = i18n.statMappings[key] || key;
                    if (sumAvgColumns.includes(key)) {
                        const sum = data[`${key}_sum`] || 0,
                              avg = data[`${key}_avg`] || '0.00';
                        tableBody.append(`<tr><td>${displayName} (Tot/Avg)</td><td><strong>${sum} / ${avg}</strong></td></tr>`);
                    } else if (data[key] !== undefined) {
                        const suffix = key.includes('%') ? ' %' : '';
                        tableBody.append(`<tr><td>${displayName}</td><td><strong>${data[key]}${suffix}</strong></td></tr>`);
                    }
                });
            } else {
                tableBody.append(`<tr><td colspan="2">${i18n.noMatchesForCriteria}</td></tr>`);
            }
        }


        async function showAllPlayersComparisonPopup() {
            $('#player-comparison-popup').remove();
            if (window.location.href.includes('?p=players')) {
                await updateUserPlayerList();
            }
            await populateSquadPlayers();
            if (squadPlayersWithStats.length === 0) {
                alert(i18n.noDataFound);
                return;
            }
            const rawData = JSON.parse(await GM_getValue('playerStatsRaw', '{}'));
            const allMatches = Object.values(rawData).flatMap(p => p.matches || []);
            const matchTypes = [i18n.all, ...new Set(allMatches.map(m => m.matchType).filter(Boolean))];
            const ageLimits = [i18n.all, i18n.none, i18n.under18, i18n.under21, i18n.under23];
            let tableHeaderHTML = `<th data-sort-type="text" data-tooltip="${i18n.player}">${i18n.player}</th><th data-sort-type="numeric" data-tooltip="${i18n.age}">${i18n.age}</th><th data-sort-type="numeric" data-tooltip="${i18n.matches}">${i18n.matches}</th>${displayColumns.map(col => `<th data-sort-type="numeric" data-tooltip="${i18n.statMappings[col] || col}">${col}</th>`).join('')}`;
            const popupHTML = `
            <div id="player-comparison-popup">
                <div class="popup-header"><h3>${i18n.playerComparison}</h3><span class="popup-close">×</span></div>
                <div class="popup-content-scrollable">
                    <div class="popup-filters">
                        <select id="compare-filter-type">${[...new Set(matchTypes)].map(opt => `<option>${opt}</option>`).join('')}</select>
                        <select id="compare-filter-age">${ageLimits.map(opt => `<option>${opt}</option>`).join('')}</select>
                        <button id="export-to-excel-btn" class="mz-script-button" style="background-color: #28a745; margin-left: auto;">${i18n.exportToExcel}</button>
                    </div>
                    <div class="table-responsive-wrapper">
                        <table id="comparison-table"><thead><tr>${tableHeaderHTML}</tr></thead><tbody></tbody></table>
                    </div>
                </div>
            </div>`;
            $('body').append(popupHTML);
            updateComparisonTable();
            $('#player-comparison-popup .popup-close').on('click', () => $('#player-comparison-popup').remove());
            $('#player-comparison-popup .popup-filters select').on('change', updateComparisonTable);
            $('#export-to-excel-btn').on('click', handleExcelExport);
        }

        async function handleExcelExport() {
            const button = $('#export-to-excel-btn');
            const originalText = button.text();
            button.text(i18n.exporting).prop('disabled', true);

            try {
                const wb = XLSX.utils.book_new();
                const rawData = JSON.parse(await GM_getValue('playerStatsRaw', '{}'));
                const filterAge = $('#compare-filter-age').val();

                const matchTypes = $('#compare-filter-type option').map(function() {
                    return $(this).val();
                }).get();

                for (const filterType of matchTypes) {
                    const sheetData = await generateSheetData(rawData, filterType, filterAge);
                    if (sheetData.length > 0) {
                        const ws = XLSX.utils.json_to_sheet(sheetData);
                        const sheetName = filterType.replace(/[\/\\?*\[\]]/g, '').substring(0, 31);
                        XLSX.utils.book_append_sheet(wb, ws, sheetName);
                    }
                }

                XLSX.writeFile(wb, 'ManagerZone_Player_Comparison.xlsx');

            } catch (error) {
                console.error("Excel export failed:", error);
                alert(i18n.exportError);
            } finally {
                button.text(originalText).prop('disabled', false);
            }
        }

        async function generateSheetData(rawData, filterType, filterAge) {
            const dataForSheet = [];
            for (const player of squadPlayersWithStats) {
                const data = calculateAverages(rawData[player.pid], filterType, filterAge);
                if (data && data.matches > 0) {
                    const playerRow = {};
                    playerRow[i18n.player] = player.name;
                    playerRow[i18n.age] = player.age > 0 ? player.age : '?';
                    playerRow[i18n.matches] = data.matches;

                    displayColumns.forEach(col => {
                        const displayName = i18n.statMappings[col] || col;
                        if (sumAvgColumns.includes(col)) {
                            const sum = data[`${col}_sum`] || 0;
                            const avg = data[`${col}_avg`] || '0.00';
                            playerRow[`${displayName} ${i18n.totalSuffix}`] = sum;
                            playerRow[`${displayName} ${i18n.avgSuffix}`] = parseFloat(avg);
                        } else {
                            const statValue = data[col] || '0.00';
                            playerRow[displayName] = parseFloat(statValue);
                        }
                    });
                    dataForSheet.push(playerRow);
                }
            }
            return dataForSheet;
        }

        async function updateComparisonTable() {
            const filterType = $('#compare-filter-type').val(),
                  filterAge = $('#compare-filter-age').val(),
                  rawData = JSON.parse(await GM_getValue('playerStatsRaw', '{}')),
                  tableBody = $('#comparison-table tbody').empty();
            for (const player of squadPlayersWithStats) {
                const data = calculateAverages(rawData[player.pid], filterType, filterAge);
                if (data && data.matches > 0) {
                    const currentAge = player.age,
                          displayAge = currentAge > 0 ? currentAge : '?';
                    let row = `<tr data-pid="${player.pid}"><td>${player.name}</td><td data-sort="${currentAge}">${displayAge}</td><td data-sort="${data.matches}">${data.matches}</td>`;
                    displayColumns.forEach(col => {
                        if (sumAvgColumns.includes(col)) {
                            const sum = data[`${col}_sum`] || 0,
                                  avg = data[`${col}_avg`] || '0.00';
                            row += `<td data-sort-sum="${sum}" data-sort-avg="${avg}">${sum} / ${avg}</td>`;
                        } else {
                            const statValue = data[col] || '0.00',
                                  suffix = col.includes('%') ? ' %' : '';
                            row += `<td data-sort="${parseFloat(statValue)}">${statValue}${suffix}</td>`;
                        }
                    });
                    row += '</tr>';
                    tableBody.append(row);
                }
            }
            makeTableSortable($('#comparison-table'));
            applyCellColoring($('#comparison-table'));
        }

        function makeTableSortable(table) {
            table.find('th[data-sort-type]').off('click').on('click', function() {
                const th = $(this),
                      index = th.index(),
                      headerText = th.text().trim(),
                      isSpecialSort = sumAvgColumns.includes(headerText);
                table.find('th').not(th).removeClass('sort-asc sort-desc sort-sum-asc sort-sum-desc sort-avg-asc sort-avg-desc').removeAttr('data-sort-state');
                let sortKey, direction, sortAttribute;
                if (isSpecialSort) {
                    const states = ['sum-desc', 'sum-asc', 'avg-desc', 'avg-asc'],
                          currentState = th.attr('data-sort-state') || '',
                          nextIndex = (states.indexOf(currentState) + 1) % states.length,
                          newState = states[nextIndex];
                    th.attr('data-sort-state', newState).removeClass('sort-asc sort-desc sort-sum-asc sort-sum-desc sort-avg-asc sort-avg-desc').addClass(`sort-${newState}`);
                    [sortKey, direction] = newState.split('-');
                    sortAttribute = `data-sort-${sortKey}`;
                } else {
                    direction = th.hasClass('sort-asc') ? 'desc' : 'asc';
                    th.removeClass('sort-asc sort-desc').addClass(`sort-${direction}`);
                    sortAttribute = 'data-sort';
                    th.removeAttr('data-sort-state');
                }
                const rows = table.find('tbody tr').get();
                rows.sort((a, b) => {
                    let valA, valB;
                    const tdA = $(a).find('td').eq(index),
                          tdB = $(b).find('td').eq(index);
                    if (isSpecialSort) {
                        valA = parseFloat(tdA.attr(sortAttribute)) || 0;
                        valB = parseFloat(tdB.attr(sortAttribute)) || 0;
                    } else {
                        valA = tdA.attr(sortAttribute) || 0;
                        valB = tdB.attr(sortAttribute) || 0;
                        if (isNaN(parseFloat(valA)) || isNaN(parseFloat(valB))) return direction === 'asc' ? valA.localeCompare(valB, lang === 'tr' ? 'tr-TR' : undefined) : valB.localeCompare(valA, lang === 'tr' ? 'tr-TR' : undefined);
                        valA = parseFloat(valA);
                        valB = parseFloat(valB);
                    }
                    return direction === 'asc' ? valA - valB : valB - valA;
                });
                $.each(rows, (idx, row) => table.children('tbody').append(row));
            });
        }

        function applyCellColoring(table) {
            const headers = table.find('thead th').map(function() {
                return $(this).text();
            }).get();
            // Good stats: Higher is better
            const goodStats = ['MP', 'G', 'A', 'S', 'G%', 'SOT', 'SOT%', 'P%', 'PL', 'In', 'T', 'T%', 'Pos%', 'Dist', 'DistP', 'SpR', 'SV'];
            // Bad stats: Lower is better
            const badStats = ['SpP', 'YC', 'RC'];
            headers.forEach((header, index) => {
                if (goodStats.includes(header) || badStats.includes(header)) {
                    let values = [];
                    table.find(`tbody tr td:nth-child(${index + 1})`).each(function() {
                        let sortVal = sumAvgColumns.includes(header) ? $(this).attr('data-sort-avg') : $(this).attr('data-sort');
                        values.push(parseFloat(sortVal) || 0);
                    });
                    const min = Math.min(...values),
                          max = Math.max(...values);
                    if (min === max) return;
                    table.find(`tbody tr td:nth-child(${index + 1})`).each(function() {
                        let sortVal = sumAvgColumns.includes(header) ? $(this).attr('data-sort-avg') : $(this).attr('data-sort');
                        const value = parseFloat(sortVal) || 0,
                              normalized = max === min ? 0.5 : (value - min) / (max - min);
                        let hue = badStats.includes(header) ? 120 - (normalized * 120) : normalized * 120;
                        $(this).css('background-color', `hsla(${hue}, 70%, 75%, 0.6)`).addClass('colored-cell');
                    });
                }
            });
        }

        function setupTooltipListeners() {
            const tooltip = $('#custom-tooltip');
            let currentTarget = null;
            $(document).on('click', '[data-tooltip]', function(e) {
                e.stopPropagation();
                const target = $(this);
                const tooltipText = target.attr('data-tooltip');
                if (currentTarget && currentTarget[0] === target[0]) {
                    tooltip.hide();
                    currentTarget = null;
                    return;
                }
                currentTarget = target;
                if (tooltipText) {
                    tooltip.html(tooltipText).show();
                    const targetOffset = target.offset(),
                          targetHeight = target.outerHeight(),
                          targetWidth = target.outerWidth(),
                          tooltipHeight = tooltip.outerHeight(),
                          tooltipWidth = tooltip.outerWidth();
                    let top = targetOffset.top - tooltipHeight - 10;
                    let left = targetOffset.left + (targetWidth / 2) - (tooltipWidth / 2);
                    if (top < 0) top = targetOffset.top + targetHeight + 10;
                    if (left < 0) left = 5;
                    if (left + tooltipWidth > $(window).width()) left = $(window).width() - tooltipWidth - 5;
                    tooltip.css({
                        top: top,
                        left: left
                    });
                }
            });
            $(document).on('click', function(e) {
                if (currentTarget && !$(e.target).is(currentTarget)) {
                    tooltip.hide();
                    currentTarget = null;
                }
            });
            $(document).on('mouseenter', '[data-tooltip]', function() {
                if ('ontouchstart' in window) return; // Don't show on hover for touch devices
                const target = $(this);
                const tooltipText = target.attr('data-tooltip');
                if (tooltipText) {
                    tooltip.html(tooltipText).show();
                    const targetOffset = target.offset(),
                          targetHeight = target.outerHeight(),
                          targetWidth = target.outerWidth(),
                          tooltipHeight = tooltip.outerHeight(),
                          tooltipWidth = tooltip.outerWidth();
                    let top = targetOffset.top - tooltipHeight - 10;
                    let left = targetOffset.left + (targetWidth / 2) - (tooltipWidth / 2);
                    if (top < 0) top = targetOffset.top + targetHeight + 10;
                    if (left < 0) left = 5;
                    if (left + tooltipWidth > $(window).width()) left = $(window).width() - tooltipWidth - 5;
                    tooltip.css({
                        top: top,
                        left: left
                    });
                }
            }).on('mouseleave', '[data-tooltip]', function() {
                if ('ontouchstart' in window) return; // Don't hide on leave for touch devices if it was opened by click
                if (!currentTarget) { // Only hide if it wasn't "click-locked"
                    tooltip.hide();
                }
            });
        }
    }


    /****************************************************************************************
     *                                                                                      *
     *  BÖLÜM 3: PLAY-OFF/PLAY-OUT TAHMİNCİSİ (Evrensel)                                     *
     *                                                                                      *
     ****************************************************************************************/
    function initializePlayoffPredictorScript() {
        let isJobRunning = false;

        /**
         * Verilen lig adını seviye ve indeksine ayrıştırır.
         * @param {string} name - Ligin adı (örn: "Allsvenskan", "div2.5").
         * @returns {{level: number, index: number, isTopLeague: boolean}|null}
         */
        function parseLeagueName(name) {
            const lowerName = name.toLowerCase().trim();
            const match = lowerName.match(/div(\d+)\.(\d+)/);

            if (match) {
                return {
                    level: parseInt(match[1], 10),
                    index: parseInt(match[2], 10),
                    isTopLeague: false
                };
            } else if (lowerName && !lowerName.startsWith('div')) {
                return {
                    level: 0,
                    index: 1,
                    isTopLeague: true
                };
            }
            return null;
        }

        /**
         * Ligin seviyesine ve indeksine göre dinamik olarak play-off/play-out kuralları üretir.
         * Bu fonksiyon, bir ligin hem yükselme hem de düşme gruplarını oluşturur.
         * @param {number} level - Ligin seviyesi (0 = en üst, 1 = div1, vs.).
         * @param {number} index - Ligin kendi seviyesindeki indeksi (örn: div2.5 için 5).
         * @param {string} currentLeagueName - Görüntülenen mevcut ligin tam adı.
         * @param {boolean} isTopLeague - Ligin en üst lig olup olmadığı.
         * @returns {Array} İlgili kuralların bir dizisi.
         */
        function generateRules(level, index, currentLeagueName, isTopLeague) {
            const generatedRules = [];

            // --- Play-Off (YÜKSELME) Kuralları ---
            if (!isTopLeague) {
                const parentLevel = level - 1;
                const parentIndex = Math.floor((index - 1) / 3) + 1;

                const leagueSelect = getLeagueSelect();
                let parentLeagueName = `div${parentLevel}.${parentIndex}`;
                if (parentLevel === 0) {
                    for (const option of leagueSelect.options) {
                        const leagueInfo = parseLeagueName(option.text);
                        if (leagueInfo && leagueInfo.isTopLeague) {
                            parentLeagueName = option.text;
                            break;
                        }
                    }
                }

                const firstSiblingIndex = (parentIndex - 1) * 3 + 1;
                const childLeague1 = `div${level}.${firstSiblingIndex}`;
                const childLeague2 = `div${level}.${firstSiblingIndex + 1}`;
                const childLeague3 = `div${level}.${firstSiblingIndex + 2}`;

                const groupBaseNum = parentIndex * 2;

                generatedRules.push({
                    name: `Play-Off Grup ${groupBaseNum - 1} (Yükselme)`,
                    type: 'playoff',
                    teams: [
                        { league: parentLeagueName, rank: 8 },
                        { league: childLeague1, rank: 2 },
                        { league: childLeague2, rank: 3 },
                        { league: childLeague3, rank: 3 }
                    ]
                });
                generatedRules.push({
                    name: `Play-Off Grup ${groupBaseNum} (Yükselme)`,
                    type: 'playoff',
                    teams: [
                        { league: parentLeagueName, rank: 9 },
                        { league: childLeague1, rank: 3 },
                        { league: childLeague2, rank: 2 },
                        { league: childLeague3, rank: 2 }
                    ]
                });
            }

            // --- Play-Out (DÜŞME) Kuralları ---
            if (level < 6) {
                const nextLevel = level + 1;
                const childBaseIndex = (index - 1) * 3;
                const childLeague1 = `div${nextLevel}.${childBaseIndex + 1}`;
                const childLeague2 = `div${nextLevel}.${childBaseIndex + 2}`;
                const childLeague3 = `div${nextLevel}.${childBaseIndex + 3}`;

                const groupNameSuffix = isTopLeague ? "(Yükselme/Düşme)" : "(Düşme)";

                const groupBaseIndex = isTopLeague ? 0 : (((3 ** (level - 1) - 1) / 2) + index - 1);
                const groupNum1 = (groupBaseIndex * 2) + 1;
                const groupNum2 = (groupBaseIndex * 2) + 2;

                generatedRules.push({
                    name: `Play-Out Grup ${isTopLeague ? 'A' : groupNum1} ${groupNameSuffix}`,
                    type: 'playout',
                    teams: [
                        { league: currentLeagueName, rank: 8 },
                        { league: childLeague1, rank: 2 },
                        { league: childLeague2, rank: 3 },
                        { league: childLeague3, rank: 3 }
                    ]
                });
                generatedRules.push({
                    name: `Play-Out Grup ${isTopLeague ? 'B' : groupNum2} ${groupNameSuffix}`,
                    type: 'playout',
                    teams: [
                        { league: currentLeagueName, rank: 9 },
                        { league: childLeague1, rank: 3 },
                        { league: childLeague2, rank: 2 },
                        { league: childLeague3, rank: 2 }
                    ]
                });
            }

            const uniqueRules = [];
            const seenNames = new Set();
            for (const rule of generatedRules) {
                if (!seenNames.has(rule.name)) {
                    uniqueRules.push(rule);
                    seenNames.add(rule.name);
                }
            }

            if (isTopLeague) {
                return uniqueRules.filter(rule => rule.type === 'playout');
            }

            return uniqueRules;
        }

        /**
         * Görüntülenen lige uygun kuralları bulur ve döndürür.
         * @param {string} currentLeagueName - Görüntülenen ligin adı.
         * @returns {Array} İlgili kuralların bir dizisi.
         */
        function findRelevantRules(currentLeagueName) {
            const leagueInfo = parseLeagueName(currentLeagueName);
            if (!leagueInfo) {
                console.warn("Mevcut lig ayrıştırılamadı:", currentLeagueName);
                return [];
            }

            if (leagueInfo.level >= 7) {
                return [];
            }

            return generateRules(leagueInfo.level, leagueInfo.index, currentLeagueName, leagueInfo.isTopLeague);
        }

        async function startJob() {
            if (isJobRunning) {
                alert("Zaten devam eden bir işlem var. Lütfen tamamlanmasını bekleyin.");
                return;
            }
            isJobRunning = true;
            showProgressIndicator("İşlem Başlatılıyor...");

            const leagueSelect = getLeagueSelect();
            if (!leagueSelect) {
                alert("Lig seçme menüsü bulunamadı!");
                isJobRunning = false;
                removeProgressIndicator();
                return;
            }

            const currentLeagueName = leagueSelect.options[leagueSelect.selectedIndex].text;
            const relevantRules = findRelevantRules(currentLeagueName);

            if (!relevantRules || relevantRules.length === 0) {
                let predictorContainer = document.getElementById('playoff-predictor-container');
                if (!predictorContainer) {
                    const mainContentArea = document.querySelector('#league_navigation > div.ui-tabs-panel');
                    predictorContainer = setupContainer(mainContentArea);
                }
                predictorContainer.innerHTML = `<div style="padding: 15px; background-color: #f8f9fa; border: 1px solid #dee2e6; text-align: center; margin-top: 20px;">Bu lig (${currentLeagueName}) için gösterilecek Play-Off/Out kuralı bulunmuyor.</div>`;
                isJobRunning = false;
                removeProgressIndicator();
                return;
            }

            const allTeamDefs = getUniqueTeamDefs(relevantRules);
            const leagueIdMap = createLeagueIdMap(leagueSelect);
            const collectedData = [];
            let hiddenIframe = null;

            try {
                hiddenIframe = document.createElement('iframe');
                hiddenIframe.style.cssText = 'display: none !important;';
                document.body.appendChild(hiddenIframe);

                const teamDefsToFetchInIframe = allTeamDefs.filter(def => def.league.toLowerCase() !== currentLeagueName.toLowerCase());
                const teamDefsOnCurrentPage = allTeamDefs.filter(def => def.league.toLowerCase() === currentLeagueName.toLowerCase());

                teamDefsOnCurrentPage.forEach(def => {
                    const teamData = parseTeamFromDocument(document, def.rank, window.location.href);
                    if (teamData) collectedData.push({ ...teamData,
                                                      league: def.league
                                                    });
                });

                let leaguesProcessed = teamDefsOnCurrentPage.length;
                for (const teamDef of teamDefsToFetchInIframe) {
                    if (!isJobRunning) {
                        throw new Error("İşlem kullanıcı tarafından iptal edildi.");
                    }
                    updateProgressIndicator(`Lig Verileri Toplanıyor... (${leaguesProcessed}/${allTeamDefs.length}) - ${teamDef.league}`);
                    const teamData = await fetchLeagueDataViaIframe(teamDef, leagueIdMap, hiddenIframe);
                    collectedData.push(teamData);
                    leaguesProcessed++;
                }

                updateProgressIndicator("Lig verileri toplandı. Takım değerleri hesaplanıyor...");
                let teamsWithValueProcessed = 0;
                const validTeams = collectedData.filter(d => d && d.url && d.url !== '#');
                const totalTeamsWithValue = validTeams.length;

                const valuePromises = validTeams.map(team => {
                    if (!isJobRunning) return Promise.reject(new Error("İşlem iptal edildi."));
                    return fetchTop11Value(team).then(result => {
                        teamsWithValueProcessed++;
                        updateProgressIndicator(`En İyi 11 Değerleri Hesaplanıyor... (${teamsWithValueProcessed}/${totalTeamsWithValue})`);
                        return result;
                    });
                });
                const finalDataWithValues = await Promise.all(valuePromises);

                const finalData = collectedData.map(team => {
                    const teamWithValue = finalDataWithValues.find(t => t && team && t.url === team.url);
                    return teamWithValue || team;
                });

                if (!isJobRunning) return;
                updateProgressIndicator("Tablo Oluşturuluyor...");
                const mainContentArea = document.querySelector('#league_navigation > div.ui-tabs-panel');
                let predictorContainer = setupContainer(mainContentArea);
                const finalHtml = createTablesHTML(relevantRules, finalData);
                predictorContainer.innerHTML = finalHtml;

            } catch (error) {
                if (error.message.includes("iptal edildi")) {
                    console.log("İşlem durduruldu.");
                } else {
                    console.error("Betiğin çalışması sırasında bir hata oluştu:", error);
                    alert("Betiğin çalışması sırasında bir hata oluştu. Lütfen konsolu kontrol edin.");
                }
            } finally {
                if (hiddenIframe) hiddenIframe.remove();
                removeProgressIndicator();
                isJobRunning = false;
            }
        }

        function fetchLeagueDataViaIframe(teamDef, leagueIdMap, iframe) {
            return new Promise((resolve) => {
                const leagueNameLower = teamDef.league.toLowerCase();
                const sid = leagueIdMap[leagueNameLower];
                if (!sid) {
                    console.warn(`Lig ID bulunamadı: ${teamDef.league}`);
                    resolve({
                        rank: teamDef.rank,
                        league: teamDef.league,
                        name: `(Lig bulunamadı)`,
                        url: '#'
                    });
                    return;
                }
                const url = `https://www.managerzone.com/?p=league&type=senior&sid=${sid}`;

                let poller = null;
                let timeout = null;

                const cleanup = () => {
                    if (poller) clearInterval(poller);
                    if (timeout) clearTimeout(timeout);
                    iframe.onload = null;
                    iframe.onerror = null;
                };

                const fail = (errorType) => {
                    console.warn(`${errorType} for league: ${teamDef.league}`);
                    cleanup();
                    resolve({
                        rank: teamDef.rank,
                        league: teamDef.league,
                        name: `(${errorType})`,
                        url: '#'
                    });
                };

                timeout = setTimeout(() => fail('Timeout Hatası'), 15000);

                iframe.onload = () => {
                    poller = setInterval(() => {
                        try {
                            const doc = iframe.contentDocument;
                            if (doc && doc.querySelector('.nice_table tbody tr')) {
                                cleanup();
                                const teamData = parseTeamFromDocument(doc, teamDef.rank, url);
                                resolve({ ...teamData,
                                          league: teamDef.league
                                        });
                            }
                        } catch (e) {
                            // ignore error
                        }
                    }, 300);
                };

                iframe.onerror = () => fail('Yükleme Hatası');
                iframe.src = url;
            });
        }

        function fetchTop11Value(team) {
            if (!team || !team.url) return Promise.resolve({ ...team,
                                                            top11Value: 'URL Yok'
                                                          });
            const teamId = new URL(team.url).searchParams.get('tid');
            if (!teamId) return Promise.resolve({ ...team,
                                                 top11Value: 'ID Yok'
                                               });
            const playersUrl = `https://www.managerzone.com/?p=players&sub=alt&tid=${teamId}`;
            return fetch(playersUrl)
                .then(response => {
                if (!response.ok) throw new Error(`HTTP hatası! Durum: ${response.status}`);
                return response.text();
            })
                .then(html => ({ ...team,
                                top11Value: calculateTop11ValueFromHTML(html)
                              }))
                .catch(error => {
                console.error(`Takım ID ${teamId} için "En İyi 11" değeri alınamadı:`, error);
                return { ...team,
                        top11Value: 'Hata'
                       };
            });
        }

        function waitForElement(selector, callback) {
            const i = setInterval(() => {
                const e = document.querySelector(selector);
                if (e) {
                    clearInterval(i);
                    callback();
                }
            }, 100);
        }

        function createLeagueIdMap(leagueSelect) {
            const map = {};
            for (const o of leagueSelect.options) {
                map[o.text.toLowerCase().trim()] = o.value;
            }
            return map;
        }

        function setupContainer(parent) {
            let c = document.getElementById('playoff-predictor-container');
            if (c) {
                c.innerHTML = '';
            } else {
                c = document.createElement('div');
                c.id = 'playoff-predictor-container';
                const t = parent.querySelector('.nice_table');
                if (t) t.parentNode.insertAdjacentElement('afterend', c);
                else parent.appendChild(c);
            }
            return c;
        }

        function getLeagueSelect() {
            const s = document.querySelectorAll('select[onchange*="p=league&type=senior&sid="]');
            return s.length > 1 ? s[1] : s[0];
        }

        function getUniqueTeamDefs(rules) {
            const u = [];
            const seen = new Set();
            rules.forEach(g => {
                g.teams.forEach(t => {
                    const key = `${t.league}-${t.rank}`;
                    if (!seen.has(key)) {
                        u.push(t);
                        seen.add(key);
                    }
                });
            });
            return u;
        }

        function parseTeamFromDocument(doc, rank, sourceUrl = 'Bilinmiyor') {
            if (!doc) {
                console.warn(`Belge (document) yok. Sıra: ${rank}, Kaynak: ${sourceUrl}`);
                return {
                    rank,
                    name: `(Belge Okunamadı)`,
                    url: '#'
                };
            }
            const tr = [...doc.querySelectorAll('.nice_table tbody tr')].find(r => r.cells[0]?.textContent.trim() == rank);
            if (tr && tr.cells[1]) {
                const a = tr.cells[1].querySelector('a[href*="p=team&tid="]');
                if (a) {
                    const stats = {
                        g: tr.cells[3]?.textContent.trim(),
                        b: tr.cells[4]?.textContent.trim(),
                        m: tr.cells[5]?.textContent.trim(),
                        a: tr.cells[6]?.textContent.trim(),
                        y: tr.cells[7]?.textContent.trim(),
                        av: tr.cells[8]?.textContent.trim(),
                        p: tr.cells[9]?.textContent.trim()
                    };
                    return {
                        rank,
                        name: a.textContent.trim(),
                        url: a.href,
                        ...stats
                    };
                }
            }
            console.warn(`Takım bulunamadı. Sıra: ${rank}, Kaynak: ${sourceUrl}`);
            return {
                rank,
                name: `(Sıra ${rank} bulunamadı)`,
                url: '#'
            };
        }

        // *** GÜNCELLENMİŞ FONKSİYON: "En Değerli 11" için daha sağlam sütun tespiti ***
        function calculateTop11ValueFromHTML(htmlText) {
            try {
                const doc = new DOMParser().parseFromString(htmlText, 'text/html');
                const playerTable = doc.getElementById('playerAltViewTable');
                if (!playerTable) return 'Tablo Yok';

                const firstDataRow = playerTable.querySelector('tbody tr');
                if (!firstDataRow) return 'Oyuncu Yok';

                // DİL BAĞIMSIZ SÜTUN BULMA: Para birimini ('EUR') içeren ilk sütunu bularak
                // "Değer" sütununun indeksini tespit et. Bu, arayüz dilinden bağımsız olarak çalışır.
                let valueColumnIndex = -1;
                const cells = firstDataRow.cells;
                for (let i = 0; i < cells.length; i++) {
                    if (cells[i].textContent.includes('EUR')) {
                        valueColumnIndex = i;
                        break;
                    }
                }

                // Eğer 'EUR' ile sütun bulunamazsa (beklenmedik bir durum), hata mesajı döndür.
                if (valueColumnIndex === -1) {
                    console.warn("Değer sütunu ('EUR' içeren) bulunamadı.");
                    return 'Sütun Yok';
                }

                const values = [];
                playerTable.querySelectorAll('tbody tr').forEach(row => {
                    const cell = row.cells[valueColumnIndex];
                    if (cell) {
                        const numericValue = parseInt(cell.textContent.trim().replace(/[^0-9]/g, ''), 10);
                        if (!isNaN(numericValue)) {
                            values.push(numericValue);
                        }
                    }
                });

                if (values.length === 0) return 'Değer Yok';

                values.sort((a, b) => b - a);
                const sum = values.slice(0, 11).reduce((acc, val) => acc + val, 0);

                // Sonucu Almanca formatında (binlik ayıracı olarak nokta) göster
                return `${sum.toLocaleString('de-DE')} EUR`;
            } catch (e) {
                console.error("HTML parse/hesaplama hatası:", e);
                return "Hesaplama Hatası";
            }
        }

        function createTablesHTML(rules, data) {
            const playoffRules = rules.filter(r => r.type === 'playoff');
            const playoutRules = rules.filter(r => r.type === 'playout');

            let h = `<h2 class="subheader clearfix" style="margin-top: 20px;">Potansiyel Play-Off / Play-Out Grupları</h2><div style="font-size: 0.9em; padding: 5px; background-color: #fff3cd; border: 1px solid #ffeeba; border-radius: 4px; margin-bottom: 10px; color: #856404;"><strong>Not:</strong> Bu tablolar, anlık puan durumlarına göre oluşturulmuş bir <strong>tahmindir</strong> ve resmi değildir.</div>`;

            const generateHtmlForRules = (ruleSet) => {
                let partialHtml = '';
                ruleSet.forEach(g => {
                    partialHtml += `<h3 class="subheader clearfix">${g.name}</h3><div class="mainContent" style="padding: 5px; margin-bottom: 20px;"><table class="nice_table" style="width:100%;">
                <thead><tr><th style="width:15%;">Lig</th><th style="width:5%; text-align: center;">Sıra</th><th style="width:20%;">Potansiyel Takım</th><th title="Galibiyet" style="width:4%; text-align: center;">G</th><th title="Beraberlik" style="width:4%; text-align: center;">B</th><th title="Mağlubiyet" style="width:4%; text-align: center;">M</th><th title="Attığı Gol" style="width:4%; text-align: center;">A</th><th title="Yediği Gol" style="width:4%; text-align: center;">Y</th><th title="Averaj" style="width:4%; text-align: center;">Av</th><th title="Puan" style="width:5%; text-align: center;">P</th><th style="width:15%; text-align: center;">En Değerli 11</th></tr></thead><tbody>`;
                    g.teams.forEach(t => {
                        const d = data.find(ad => ad && ad.league && t.league && ad.league.toLowerCase() === t.league.toLowerCase() && ad.rank === t.rank);
                        let teamCell = `...`;
                        let statsCells = '<td colspan="7" style="text-align:center;">- Veri Yok -</td>';
                        let top11Cell = '<td>...</td>';
                        let rankCell = `<td style="text-align: center;">${t.rank}</td>`;
                        if (d) {
                            teamCell = d.url && d.url !== '#' ? `<a href="${d.url}" target="_blank" title="${d.name}">${d.name}</a>` : d.name;
                            if (d.p !== undefined) statsCells = `<td style="text-align: center;">${d.g || '-'}</td><td style="text-align: center;">${d.b || '-'}</td><td style="text-align: center;">${d.m || '-'}</td><td style="text-align: center;">${d.a || '-'}</td><td style="text-align: center;">${d.y || '-'}</td><td style="text-align: center;">${d.av || '-'}</td><td style="text-align: center;"><b>${d.p}</b></td>`;
                            top11Cell = `<td style="text-align: center;">${d.top11Value || 'Hesaplanıyor...'}</td>`;
                        } else {
                            teamCell = `<span style="color:red;">(Veri alınamadı)</span>`;
                        }
                        partialHtml += `<tr><td>${t.league}</td>${rankCell}<td>${teamCell}</td>${statsCells}${top11Cell}</tr>`;
                    });
                    partialHtml += `</tbody></table></div>`;
                });
                return partialHtml;
            };

            if (playoffRules.length > 0) {
                h += generateHtmlForRules(playoffRules);
            }
            if (playoutRules.length > 0) {
                h += generateHtmlForRules(playoutRules);
            }

            h += `<hr><div style="font-size:0.9em; padding:10px; background-color: #f0f0f0; border: 1px solid #ddd; border-radius: 4px;"><h4>Bilgi</h4><p>Yukarıdaki puan tablosunun kesin olmadığını, takım pozisyonlarının çekişmeli olması durumunda play-off/out gruplarının değişebileceğini unutmayın. Olası eşitlik durumlarında sıralamaların hesaplanması için aşağıdaki öncelik sırasına göre bir dizi kural uygulanır:</p><ul><li><strong>Puanı en yüksek olan takım:</strong> En temel sıralama ölçütüdür.</li><li><strong>Averaj:</strong> Puan eşitliğinde averajı daha iyi olan takım üstte yer alır.</li><li><strong>Sezon içi galibiyet sayısı:</strong> Puan ve averaj eşitliğinde daha fazla galibiyeti olan takım önceliklidir.</li><li><strong>Gol sayısı:</strong> Yukarıdaki tüm kriterler eşitse, daha fazla gol atan takım üstte yer alır.</li><li><strong>Kura çekimi:</strong> Tüm istatistiklerin tamamen aynı olması gibi çok nadir bir durumda sıralama kura ile belirlenir.</li></ul></div>`;
            return h;
        }

        function showProgressIndicator(message) {
            removeProgressIndicator();
            const i = document.createElement('div');
            i.id = 'mz-predictor-progress';
            i.style = "position: fixed; top: 0; left: 0; width: 100%; background: #00529B; color: white; padding: 10px; z-index: 9999; text-align: center; font-size: 1.1em; border-bottom: 2px solid #003666; box-shadow: 0 2px 5px rgba(0,0,0,0.5);";
            i.innerHTML = `<span><i class="fa fa-spinner fa-pulse"></i> ${message}</span> <button id="cancelJobBtn" style="margin-left: 20px; background: #c00; color: white; border: 1px solid white; border-radius: 4px; cursor: pointer; padding: 2px 8px;">Durdur</button>`;
            document.body.appendChild(i);
            document.getElementById('cancelJobBtn').onclick = () => {
                isJobRunning = false;
            };
        }

        function updateProgressIndicator(message) {
            const i = document.getElementById('mz-predictor-progress');
            if (i) i.querySelector('span').innerHTML = `<i class="fa fa-spinner fa-pulse"></i> ${message}`;
        }

        function removeProgressIndicator() {
            const i = document.getElementById('mz-predictor-progress');
            if (i) i.remove();
        }

        function initButton() {
            const container = document.querySelector('div[style*="float: right; line-height: 36px;"]');
            if (container && !document.getElementById('runPredictorBtn')) {
                const btn = document.createElement('a');
                btn.href = '#';
                btn.className = 'mzbtn buttondiv button_account';
                btn.id = 'runPredictorBtn';
                btn.style.marginLeft = '10px';
                btn.innerHTML = `<span class="buttonClassMiddle"><span style="white-space: nowrap;"><i class="fa fa-sitemap" aria-hidden="true"></i> Play-Off/Out Tahmin Et</span></span><span class="buttonClassRight"> </span>`;
                btn.addEventListener('click', (e) => {
                    e.preventDefault();
                    startJob();
                });
                container.appendChild(btn);
            }
        }

        waitForElement('div[style*="float: right; line-height: 36px;"]', initButton);
    }


    /****************************************************************************************
     *                                                                                      *
     *  BÖLÜM 4: TAKİP LİSTESİ FİLTRELEME (Shortlist Filter) - DÜZELTİLDİ v3                  *
     *                                                                                      *
     ****************************************************************************************/
    function initializeShortlistFilterScript() {
        let userCountry = null;

        async function fetchAndSetUserCountry() {
            if (userCountry !== null) return userCountry;

            try {
                const cachedCountry = await GM_getValue('user_country');
                if (cachedCountry) {
                    userCountry = cachedCountry;
                    return userCountry;
                }
                const response = await new Promise((resolve, reject) => {
                    GM_xmlhttpRequest({
                        method: "GET",
                        url: "https://www.managerzone.com/?p=team",
                        onload: resolve,
                        onerror: reject
                    });
                });

                const html = response.responseText;
                const doc = new DOMParser().parseFromString(html, 'text/html');
                const dds = doc.querySelectorAll('#infoAboutTeam dd');
                let countryImg = null;
                dds.forEach(dd => {
                    const expText = dd.querySelector('.teamExpText');
                    if (expText && (expText.textContent.trim() === 'Lig:' || expText.textContent.trim() === 'League:')) {
                        countryImg = dd.querySelector('img[src*="img/flags/s_"]');
                    }
                });

                if (countryImg) {
                    userCountry = countryImg.getAttribute('title');
                    await GM_setValue('user_country', userCountry);
                    console.log('Kullanıcı ülkesi tespit edildi:', userCountry);
                } else {
                    console.error('Kullanıcı ülkesi Takım sayfasından tespit edilemedi.');
                    userCountry = '';
                }
            } catch (error) {
                console.error("Kullanıcı ülkesi alınırken hata oluştu:", error);
                userCountry = '';
            }
            return userCountry;
        }

        function addFilterUI() {
            GM_addStyle(`
                /* --- KOD DEĞİŞİKLİĞİ BAŞLANGICI --- */

                /* Butonlar için ortak stil */
                .sl-action-btn {
                    padding: 5px 12px !important;
                    cursor: pointer;
                    color: white !important;
                    border: 1px solid rgba(0,0,0,0.2) !important;
                    border-radius: 4px !important;
                    font-weight: bold !important;
                    font-size: 13px !important;
                    text-decoration: none !important;
                    display: inline-block !important;
                    line-height: normal !important; /* Dikey hizalama için */
                    height: auto !important; /* Dikey hizalama için */
                }
                #shortlist-filter-btn { background-color: #4CAF50; }
                #shortlist-filter-btn:hover { background-color: #45a049; }

                /* Tüm betik kontrolleri için yeni ana sarmalayıcı */
                #script-controls-wrapper {
                    display: flex;
                    gap: 10px;
                    align-items: center;
                    margin-bottom: 10px; /* Butonlar ve alttaki metin arasına boşluk ekle */
                    padding: 10px;
                    background: #f1f1f1;
                    border: 1px solid #ddd;
                    border-radius: 5px;
                }
                #shortlist-filter-controls {
                    display: flex;
                    align-items: center;
                    gap: 5px;
                }
                #shortlist-filter-count {
                    font-weight: bold;
                    color: #00529B;
                }

                /* --- KOD DEĞİŞİKLİĞİ SONU --- */

                 .sl-modal-overlay {
                    position: fixed; top: 0; left: 0; width: 100%; height: 100%;
                    background-color: rgba(0,0,0,0.6); z-index: 10010;
                    display: none; justify-content: center; align-items: center;
                }
                .sl-modal-content {
                    background: #fefefe; padding: 20px; border-radius: 8px;
                    box-shadow: 0 5px 15px rgba(0,0,0,0.3); min-width: 300px;
                    display: flex; flex-direction: column; max-width: 450px;
                }
                .sl-modal-header {
                    display: flex; justify-content: space-between; align-items: center;
                    border-bottom: 1px solid #ddd; padding-bottom: 10px; margin-bottom: 15px;
                }
                .sl-modal-header h3 { margin: 0; font-size: 18px; }
                .sl-modal-close { font-size: 24px; font-weight: bold; cursor: pointer; color: #888; }
                .sl-modal-body {
                    display: grid; grid-template-columns: 1fr 1fr; gap: 15px;
                }
                .sl-filter-group {
                    border: 1px solid #ddd; padding: 10px; border-radius: 5px; background: #fafafa;
                }
                .sl-filter-group h4 {
                    margin-top: 0; margin-bottom: 10px; border-bottom: 1px solid #eee; padding-bottom: 5px;
                }
                 .sl-filter-group label { display: block; margin-bottom: 5px; }
                .sl-age-inputs {
                    display: flex; align-items: center; gap: 5px;
                }
                .sl-modal-content input[type="number"] {
                    width: 60px; padding: 5px; border: 1px solid #ccc; border-radius: 3px;
                }
                .sl-modal-footer {
                    border-top: 1px solid #ddd; padding-top: 15px; margin-top: 20px; text-align: center;
                }
                .sl-modal-footer button {
                     padding: 8px 16px; border: none; border-radius: 4px; cursor: pointer;
                     font-weight: bold; color: white; margin: 0 5px;
                }
                #shortlist-filter-apply { background-color: #007bff; }
                #shortlist-filter-reset { background-color: #6c757d; }
            `);

            const modalHTML = `
                <div id="shortlist-filter-modal" class="sl-modal-overlay">
                    <div class="sl-modal-content">
                        <div class="sl-modal-header">
                            <h3>Oyuncu Filtrele</h3>
                            <span class="sl-modal-close">×</span>
                        </div>
                        <div class="sl-modal-body">
                           <div class="sl-filter-group">
                                <h4>Yaş Aralığı</h4>
                                <div class="sl-age-inputs">
                                    <input type="number" id="min-age" placeholder="Min" min="15" max="40">
                                    <span>-</span>
                                    <input type="number" id="max-age" placeholder="Max" min="15" max="40">
                                </div>
                           </div>
                           <div class="sl-filter-group">
                                <h4>Diğer</h4>
                                <label>
                                    <input type="checkbox" id="retiring-only"> Emekli Olacaklar
                                </label>
                           </div>
                           <div class="sl-filter-group" style="grid-column: 1 / -1;">
                                <h4>Milliyet</h4>
                                <label><input type="radio" name="nationality" value="all" checked> Tümü</label>
                                <label><input type="radio" name="nationality" value="national"> Yerli</label>
                                <label><input type="radio" name="nationality" value="foreign"> Yabancı</label>
                           </div>
                        </div>
                        <div class="sl-modal-footer">
                            <button id="shortlist-filter-apply">Filtrele</button>
                            <button id="shortlist-filter-reset">Sıfırla</button>
                        </div>
                    </div>
                </div>
            `;
            $('body').append(modalHTML);

            const playersListContainer = $('#players_container');
            if (playersListContainer.length > 0 && $('#script-controls-wrapper').length === 0) {
                // *** DÜZELTME BAŞLANGICI ***
                // jQuery'nin HTML olarak algılaması için stringin '<' ile başlamasını sağlıyoruz.
                // Template literal içindeki baştaki ve sondaki yeni satır karakterleri kaldırıldı.
                const scriptWrapper = $(`<div id="script-controls-wrapper">
                    <div id="shortlist-filter-controls">
                         <button id="shortlist-filter-btn" class="sl-action-btn">Filtrele</button>
                         <span id="shortlist-filter-count"></span>
                    </div>
                </div>`);
                // *** DÜZELTME SONU ***

                playersListContainer.before(scriptWrapper);
            }

            $('#shortlist-filter-btn').on('click', () => $('#shortlist-filter-modal').css('display', 'flex'));
            $('#shortlist-filter-modal .sl-modal-close').on('click', () => $('#shortlist-filter-modal').hide());
            $('#shortlist-filter-apply').on('click', applyFilters);
            $('#shortlist-filter-reset').on('click', resetFilters);

            $('#shortlist-filter-modal input[type="number"]').on('keydown keyup keypress', function(event) {
                event.stopPropagation();
            });
        }

        function applyFilters() {
            const minAge = parseInt($('#min-age').val(), 10) || 0;
            const maxAge = parseInt($('#max-age').val(), 10) || 100;
            const retiringOnly = $('#retiring-only').is(':checked');
            const nationalityFilter = $('input[name="nationality"]:checked').val();

            let visibleCount = 0;
            $('.playerContainer').each(function() {
                const player = $(this);
                let show = true;

                const ageText = player.find('.dg_playerview_info table tr:first-child td:first-child').text();
                if (ageText.includes('Yaş') || ageText.includes('Age')) {
                    const age = parseInt(ageText.match(/\d+/)[0], 10);
                    if (age < minAge || age > maxAge) {
                        show = false;
                    }
                }

                if (show) {
                    const isRetiring = player.find('.dg_playerview_retire').length > 0;
                    if (retiringOnly && !isRetiring) {
                        show = false;
                    }
                }

                if (show && userCountry && nationalityFilter !== 'all') {
                    const playerNationality = player.find('td:contains("Milliyet:") .nobreak.bold, td:contains("Nationality:") .nobreak.bold').text().trim();
                    if (nationalityFilter === 'national' && playerNationality !== userCountry) {
                        show = false;
                    }
                    if (nationalityFilter === 'foreign' && playerNationality === userCountry) {
                        show = false;
                    }
                }

                player.toggle(show);
                if(show) {
                    visibleCount++;
                }
            });

            const isFiltered = minAge > 0 || maxAge < 100 || retiringOnly || nationalityFilter !== 'all';
            if (isFiltered) {
                $('#shortlist-filter-count').text(`${visibleCount} oyuncu filtrelendi.`);
            } else {
                $('#shortlist-filter-count').text('');
            }


            $('#shortlist-filter-modal').hide();
        }

        function resetFilters() {
            $('#min-age').val('');
            $('#max-age').val('');
            $('#retiring-only').prop('checked', false);
            $('input[name="nationality"][value="all"]').prop('checked', true);
            $('.playerContainer').show();
            $('#shortlist-filter-count').text('');
            $('#shortlist-filter-modal').hide();
        }

        function init() {
            if ($('#players_container').length) {
                fetchAndSetUserCountry();
                addFilterUI();
            }
        }
        init();
    }


    /****************************************************************************************
     *                                                                                      *
     *  BÖLÜM 5: TRANSFER TAKİPÇİSİ (Transfer Tracker) - YENİ MODÜL                         *
     *                                                                                      *
     ****************************************************************************************/
    function initializeTransferTrackerScript() {
        // --- Dil Desteği (i18n) ---
        const i18nData = {
            tr: {
                trackPlayer: "Oyuncunun Transfer Geçmişini Takip Et",
                historyFor: "için Transfer Geçmişi",
                checking: "Kontrol ediliyor...",
                noHistory: "Bu oyuncu için kayıtlı transfer geçmişi yok.",
                clearHistory: "Geçmişi Temizle",
                confirmClear: "Bu oyuncunun tüm transfer geçmişi silinecek. Emin misiniz?",
                date: "Tarih",
                status: "Durum",
                price: "Fiyat",
                bid: "Teklif",
                deadline: "Bitiş",
                buyer: "Alıcı",
                statusListed: "Listelendi",
                statusSold: "Satıldı",
                statusExpired: "Satılmadı",
                statusEnded: "Bitti (Kontrol bekleniyor)",
                statusBid: "Teklif Var",
                checkingShortlist: "Takip listesi transferleri kontrol ediliyor...",
                checkComplete: "Transfer kontrolü tamamlandı.",
                scanShortlistBtn: "Takip Listesini Tara",
            },
            en: {
                trackPlayer: "Track Player's Transfer History",
                historyFor: "Transfer History for",
                checking: "Checking...",
                noHistory: "No transfer history recorded for this player.",
                clearHistory: "Clear History",
                confirmClear: "Are you sure you want to delete all transfer history for this player?",
                date: "Date",
                status: "Status",
                price: "Price",
                bid: "Bid",
                deadline: "Deadline",
                buyer: "Buyer",
                statusListed: "Listed",
                statusSold: "Sold",
                statusExpired: "Expired",
                statusEnded: "Ended (Awaiting check)",
                statusBid: "Bid Placed",
                checkingShortlist: "Checking shortlist transfers...",
                checkComplete: "Transfer check complete.",
                scanShortlistBtn: "Scan Transfers",
            }
        };
        const lang = ($('meta[name="language"]').attr('content') || 'en') === 'tr' ? 'tr' : 'en';
        const getText = (key) => i18nData[lang][key];

        // --- Sabitler ---
        const TRANSFER_HISTORY_KEY = 'mz_transfer_history_v2';

        // --- Stiller ---
        GM_addStyle(`
            .transfer-track-btn {
                padding: 0px 7px; margin-left: 8px; font-weight: bold; cursor: pointer;
                background-color: #17a2b8; color: white; border: 1px solid #107686;
                border-radius: 4px; font-size: 12px; vertical-align: middle;
            }
            .tt-modal-overlay {
                position: fixed; top: 0; left: 0; width: 100%; height: 100%;
                background-color: rgba(0,0,0,0.6); z-index: 10020; display: none;
                justify-content: center; align-items: center;
            }
            .tt-modal-content {
                background: #f8f9fa; padding: 20px; border-radius: 8px;
                box-shadow: 0 5px 15px rgba(0,0,0,0.3); width: 90%; max-width: 850px;
                max-height: 90vh; display: flex; flex-direction: column;
            }
            .tt-modal-header {
                display: flex; justify-content: space-between; align-items: center;
                border-bottom: 1px solid #dee2e6; padding-bottom: 10px; margin-bottom: 15px;
            }
            .tt-modal-header h3 { margin: 0; font-size: 18px; color: #00529B;}
            .tt-modal-close { font-size: 24px; font-weight: bold; cursor: pointer; color: #888; }
            .tt-modal-body {
                overflow-y: auto;
                flex-grow: 1;
            }
            .tt-tab-container {
                display: flex;
                border-bottom: 1px solid #dee2e6;
                margin-bottom: 15px;
            }
            .tt-tab {
                padding: 8px 16px;
                cursor: pointer;
                border: 1px solid transparent;
                border-bottom: none;
                margin-bottom: -1px;
                font-weight: bold;
                color: #00529B;
            }
            .tt-tab.active {
                background-color: #fff;
                border-color: #dee2e6 #dee2e6 #fff;
                border-radius: 4px 4px 0 0;
            }
            .tt-tab-content {
                display: none;
            }
            .tt-tab-content.active {
                display: block;
            }
            #tt-chart-container {
                width: 100%;
                height: 400px;
            }
            .tt-history-table { width: 100%; border-collapse: collapse; font-size: 13px; }
            .tt-history-table th, .tt-history-table td { border: 1px solid #dee2e6; padding: 8px; text-align: left; }
            .tt-history-table th { background-color: #e9ecef; }
            .tt-history-table .status-listed { color: #007bff; }
            .tt-history-table .status-bid { color: #ff8c00; }
            .tt-history-table .status-sold { color: #28a745; font-weight: bold; }
            .tt-history-table .status-expired { color: #dc3545; }
            .tt-modal-footer { margin-top: 15px; text-align: right; }
        `);

        // --- Ana Fonksiyonlar ---
        async function showTransferHistoryModal(pid, playerName) {
            $('#transfer-tracker-modal').remove();

            const allHistory = JSON.parse(await GM_getValue(TRANSFER_HISTORY_KEY, '{}'));
            const playerHistory = allHistory[pid] || [];

            let tableRows = '';
            const chartData = [];
            let soldEntry = null;

            if (playerHistory.length > 0) {
                playerHistory.forEach(entry => {
                    const statusClass = `status-${entry.status.toLowerCase()}`;
                    const statusText = getText(`status${entry.status.charAt(0).toUpperCase() + entry.status.slice(1)}`) || entry.status;
                    const priceNum = parseInt((entry.askingPrice || '0').replace(/\D/g, ''), 10);
                    const bidNum = parseInt((entry.finalBid || '0').replace(/\D/g, ''), 10);

                    tableRows = `
                        <tr>
                            <td>${new Date(entry.timestamp).toLocaleString()}</td>
                            <td class="${statusClass}">${statusText}</td>
                            <td>${entry.askingPrice || '-'}</td>
                            <td>${entry.finalBid || '-'}</td>
                            <td>${entry.deadline || '-'}</td>
                            <td>${entry.buyer || '-'}</td>
                        </tr>` + tableRows; // Başa ekleyerek ters sıralama

                    if (priceNum > 0) {
                        chartData.push({
                            x: entry.timestamp,
                            y: priceNum,
                            name: `İstenen: ${entry.askingPrice}`
                        });
                    }
                    if (bidNum > 0) {
                        chartData.push({
                            x: entry.timestamp,
                            y: bidNum,
                            name: `Teklif: ${entry.finalBid}`
                        });
                    }
                    if (entry.status === 'sold') {
                        soldEntry = {
                            x: entry.timestamp,
                            y: bidNum,
                            name: `Satıldı: ${entry.finalBid}`
                        };
                    }
                });
            } else {
                tableRows = `<tr><td colspan="6" style="text-align:center;">${getText('noHistory')}</td></tr>`;
            }
            // Grafiğin doğru çizilebilmesi için verileri tarihe göre sırala
            chartData.sort((a, b) => a.x - b.x);

            const modalHTML = `
                <div id="transfer-tracker-modal" class="tt-modal-overlay">
                    <div class="tt-modal-content">
                        <div class="tt-modal-header">
                            <h3>${getText('historyFor')} ${playerName}</h3>
                            <span class="tt-modal-close">×</span>
                        </div>
                        <div class="tt-tab-container">
                            <div class="tt-tab active" data-tab="table">Tablo</div>
                            <div class="tt-tab" data-tab="chart">Grafik</div>
                        </div>
                        <div class="tt-modal-body">
                            <div id="tt-content-table" class="tt-tab-content active">
                                <table class="tt-history-table">
                                    <thead>
                                        <tr>
                                            <th>${getText('date')}</th>
                                            <th>${getText('status')}</th>
                                            <th>${getText('price')}</th>
                                            <th>${getText('bid')}</th>
                                            <th>${getText('deadline')}</th>
                                            <th>${getText('buyer')}</th>
                                        </tr>
                                    </thead>
                                    <tbody>${tableRows}</tbody>
                                </table>
                            </div>
                            <div id="tt-content-chart" class="tt-tab-content">
                                <div id="tt-chart-container"></div>
                            </div>
                        </div>
                        <div class="tt-modal-footer">
                             <button id="tt-clear-history" class="mz-script-button" style="background-color: #dc3545;">${getText('clearHistory')}</button>
                        </div>
                    </div>
                </div>`;
            $('body').append(modalHTML);

            // Sekme (Tab) işlevselliği
            $('.tt-tab').on('click', function() {
                const tabId = $(this).data('tab');
                $('.tt-tab').removeClass('active');
                $(this).addClass('active');
                $('.tt-tab-content').removeClass('active');
                $('#tt-content-' + tabId).addClass('active');
            });

            // Grafik oluşturma
            if (playerHistory.length > 0) {
                unsafeWindow.Highcharts.chart('tt-chart-container', {
                    chart: { type: 'line' },
                    title: { text: `${playerName} - Fiyat Değişimi` },
                    xAxis: {
                        type: 'datetime',
                        title: { text: 'Tarih' }
                    },
                    yAxis: {
                        title: { text: 'Fiyat (EUR)' },
                        labels: {
                            formatter: function() { return this.value.toLocaleString('de-DE') + ' EUR'; }
                        },
                        min: 0 // Y ekseni 0'dan başlasın
                    },
                    tooltip: {
                        formatter: function() {
                            return `<b>${this.point.name}</b><br/>${new Date(this.x).toLocaleString()}`;
                        }
                    },
                    series: [{
                        name: 'Fiyat Geçmişi',
                        data: chartData,
                        step: 'left',
                        marker: {
                           enabled: true,
                           radius: 4
                        }
                    },
                    // Eğer satıldıysa, son noktayı özel olarak işaretle
                    ...(soldEntry ? [{
                        type: 'scatter',
                        name: 'Satış Noktası',
                        data: [soldEntry],
                        marker: {
                            symbol: 'diamond',
                            fillColor: '#28a745',
                            radius: 7,
                            lineWidth: 2,
                            lineColor: '#FFF'
                        }
                    }] : [])]
                });
            } else {
                 $('#tt-chart-container').html(`<div style="text-align:center; padding-top: 50px;">${getText('noHistory')}</div>`);
            }


            const modal = $('#transfer-tracker-modal');
            modal.css('display', 'flex');
            modal.find('.tt-modal-close').on('click', () => modal.remove());
            modal.on('click', (e) => { if (e.target === modal[0]) modal.remove(); });
            $('#tt-clear-history').on('click', async () => {
                if(confirm(getText('confirmClear'))) {
                    const currentHistory = JSON.parse(await GM_getValue(TRANSFER_HISTORY_KEY, '{}'));
                    delete currentHistory[pid];
                    await GM_setValue(TRANSFER_HISTORY_KEY, JSON.stringify(currentHistory));
                    modal.remove();
                }
            });
        }

        function init() {
            $('.playerContainer').each(function() {
                const pid = $(this).find('span.player_id_span').text().trim();
                const playerName = $(this).find('span.player_name').text().trim();
                if (pid) {
                    const trackBtn = $(`<button class="transfer-track-btn" title="${getText('trackPlayer')}">T</button>`);
                    trackBtn.data('pid', pid).data('player-name', playerName);
                    $(this).find('h2.subheader .floatRight').append(trackBtn);
                }
            });

            $(document).on('click', '.transfer-track-btn', function() {
                const pid = $(this).data('pid');
                const playerName = $(this).data('player-name');
                showTransferHistoryModal(pid, playerName);
            });

            const wrapper = $('#script-controls-wrapper');
            if (wrapper.length && $('#manual-transfer-check-btn').length === 0) {
                const scanBtn = $(`<button id="manual-transfer-check-btn" class="sl-action-btn" style="background-color: #fd7e14;" title="Takip listenizdeki tüm oyuncuların transfer durumunu manuel olarak kontrol eder.">${getText('scanShortlistBtn')}</button>`);
                scanBtn.on('mouseenter', function() { $(this).css('background-color', '#e67112'); });
                scanBtn.on('mouseleave', function() { $(this).css('background-color', '#fd7e14'); });

                wrapper.append(scanBtn);

                scanBtn.on('click', function() {
                    if (window.isTransferCheckRunning) {
                        alert(lang === 'tr' ? 'Zaten devam eden bir tarama var.' : 'A scan is already in progress.');
                        return;
                    }
                    runBackgroundTransferCheck();
                });
            }
        }

        init();
    }


    /****************************************************************************************
     *                                                                                      *
     *  BÖLÜM 6: ARKA PLAN TRANSFER KONTROLÜ (Background Transfer Check) - YENİ             *
     *                                                                                      *
     ****************************************************************************************/
    async function runBackgroundTransferCheck() {
        const lang = ($('meta[name="language"]').attr('content') || 'en') === 'tr' ? 'tr' : 'en';
        const i18n = {
            checkingShortlist: lang === 'tr' ? 'Takip listesi transferleri kontrol ediliyor...' : 'Checking shortlist transfers...',
            checkComplete: lang === 'tr' ? 'Transfer kontrolü tamamlandı.' : 'Transfer check complete.',
        };

        if (window.isTransferCheckRunning) return;
        window.isTransferCheckRunning = true;

        const statusDiv = $('<div id="transfer-check-status" style="position:fixed; bottom:10px; right:10px; background: #00529B; color:white; padding: 8px 12px; border-radius:5px; z-index:99999; font-size:12px;"></div>').text(i18n.checkingShortlist);
        $('body').append(statusDiv);

        try {
            const shortlistResp = await GM.xmlHttpRequest({ method: "GET", url: "https://www.managerzone.com/?p=shortlist" });
            const shortlistDoc = new DOMParser().parseFromString(shortlistResp.responseText, 'text/html');

            const playersOnShortlist = new Map();
            $(shortlistDoc).find('.playerContainer').each(function() {
                const pid = $(this).find('span.player_id_span').text().trim();
                const playerLink = $(this).find('a[href*="&pid="]');
                const name = playerLink.find('.player_name').text().trim();
                if (pid && name) {
                    playersOnShortlist.set(pid, { name });
                }
            });


            const allHistory = JSON.parse(await GM_getValue('mz_transfer_history_v2', '{}'));
            let changed = false;

            const playerIds = Array.from(playersOnShortlist.keys());

            for (let i = 0; i < playerIds.length; i++) {
                const pid = playerIds[i];
                const playerInfo = playersOnShortlist.get(pid);

                await new Promise(r => setTimeout(r, 400));
                statusDiv.text(`${i18n.checkingShortlist} (${i + 1}/${playerIds.length}) - ${playerInfo.name}`);

                const searchResp = await GM.xmlHttpRequest({ method: "GET", url: `https://www.managerzone.com/?p=transfer&u=${pid}&issearch=true` });
                const searchDoc = new DOMParser().parseFromString(searchResp.responseText, 'text/html');

                const playerOnTransfer = $(searchDoc).find(`#player_id_${pid}`);
                const playerHistory = allHistory[pid] || [];
                const lastEntry = playerHistory.length > 0 ? playerHistory[playerHistory.length - 1] : null;

                if (playerOnTransfer.length > 0) { // Oyuncu transferde
                    const container = playerOnTransfer.closest('.playerContainer');
                    const deadlineText = container.find('td:contains("Bitiş tarihi"), td:contains("Deadline")').next().text().trim();
                    const askingPriceText = container.find('td:contains("İstenen Fiyat"), td:contains("Asking Price")').next().text().trim();
                    const bidTd = container.find('td:contains("En Son Teklif"), td:contains("Highest Bid")').next('td');
                    const bidText = bidTd.contents().filter(function() { return this.nodeType === 3; }).text().trim();
                    const bidderLink = bidTd.find('a[href*="p=team"]');
                    const bidderName = bidderLink.length > 0 ? bidderLink.text().trim() : '-';

                    let currentStatus = (bidText && bidText !== '0' && bidText !== '0 EUR') ? 'bid' : 'listed';

                    if (!lastEntry || lastEntry.status === 'expired' || lastEntry.status === 'sold' || lastEntry.deadline !== deadlineText) {
                         const sellerLink = container.find('a[href*="p=team&tid="]');
                         const sellerName = sellerLink.text().trim();
                         const sellerTidMatch = sellerLink.attr('href').match(/tid=(\d+)/);
                         const sellerTid = sellerTidMatch ? sellerTidMatch[1] : null;

                        playerHistory.push({
                            timestamp: Date.now(),
                            status: currentStatus,
                            askingPrice: askingPriceText,
                            finalBid: bidText || '0',
                            deadline: deadlineText,
                            buyer: bidderName,
                            sellerTid: sellerTid // Satıcıyı kaydet
                        });
                        allHistory[pid] = playerHistory;
                        changed = true;
                    } else if (lastEntry.status.includes('listed') || lastEntry.status.includes('bid')) {
                        // Eğer durum değiştiyse (teklif geldiyse) veya teklif güncellendiyse
                        if (lastEntry.status !== currentStatus || lastEntry.finalBid !== bidText) {
                            lastEntry.status = currentStatus;
                            lastEntry.finalBid = bidText;
                            lastEntry.buyer = bidderName;
                            changed = true;
                        }
                    }
                } else { // Oyuncu transferde değil
                    if (lastEntry && (lastEntry.status === 'listed' || lastEntry.status === 'bid')) {
                        const sellerTid = lastEntry.sellerTid; // Kaydedilmiş satıcıyı kullan

                        const playerPageResp = await GM.xmlHttpRequest({method: "GET", url: `https://www.managerzone.com/?p=player&pid=${pid}`});
                        const playerDoc = new DOMParser().parseFromString(playerPageResp.responseText, 'text/html');
                        const teamLink = $(playerDoc).find('h1.win_title a[href*="p=team"]');
                        const newTidMatch = teamLink.length ? teamLink.attr('href').match(/tid=(\d+)/) : null;
                        const newTid = newTidMatch ? newTidMatch[1] : null;

                        if (newTid && sellerTid && newTid !== sellerTid) {
                            lastEntry.status = 'sold';
                            // Son teklif veren alıcıdır
                            if (lastEntry.buyer === '-') {
                                lastEntry.buyer = teamLink.text().trim(); // Eğer teklif anında alıcı yakalanamadıysa, yeni kulübü yaz
                            }
                        } else {
                            lastEntry.status = 'expired';
                            lastEntry.buyer = '-';
                        }
                        changed = true;
                    }
                }
            }

            if (changed) {
                await GM_setValue('mz_transfer_history_v2', JSON.stringify(allHistory));
            }
            await GM_setValue('mz_last_transfer_check', Date.now());

            statusDiv.text(i18n.checkComplete).fadeOut(3000, () => statusDiv.remove());
        } catch (error) {
            console.error("Transfer check failed:", error);
            statusDiv.text("Hata oluştu!").css('background', '#dc3545').fadeOut(3000, () => statusDiv.remove());
        } finally {
            window.isTransferCheckRunning = false;
        }
    }


    /****************************************************************************************
     *                                                                                      *
     *  ANA YÖNLENDİRİCİ (MASTER ROUTER)                                                    *
     *  Bu bölüm, hangi sayfanın açık olduğunu kontrol eder ve ilgili betiği/betikleri      *
     *  çalıştırır.                                                                         *
     *                                                                                      *
     ****************************************************************************************/
    function masterRouter() {
        if (typeof $ === 'undefined' || typeof $.fn.on === 'undefined') {
            console.log("SUITE: jQuery is not available yet. Waiting...");
            setTimeout(masterRouter, 200); // jQuery yüklenene kadar bekle
            return;
        }

        const params = new URLSearchParams(window.location.search);
        const p_param = params.get('p');
        const sub_param = params.get('sub');
        const type_param = params.get('type');

        const leagueTablePages = ['league', 'friendlyseries', 'private_cup', 'cup'];
        if (leagueTablePages.includes(p_param)) {
            console.log("SUITE: Initializing Advanced League Table...");
            initializeLeagueTableScript();
        }

        const playerStatsPages_p = ['players', 'player'];
        const playerStatsPages_sub = ['played', 'result', 'stats'];
        if (playerStatsPages_p.includes(p_param) || (p_param === 'match' && playerStatsPages_sub.includes(sub_param))) {
            console.log("SUITE: Initializing Player Stats...");
            initializePlayerStatsScript();
        }

        if (p_param === 'league' && type_param === 'senior') {
            console.log("SUITE: Initializing Play-off Predictor...");
            initializePlayoffPredictorScript();
        }

        if (p_param === 'shortlist') {
             console.log("SUITE: Initializing Shortlist Filter...");
             initializeShortlistFilterScript();
             console.log("SUITE: Initializing Transfer Tracker UI...");
             initializeTransferTrackerScript();
        }
    }

    // --- OTOMATİK KONTROLLERİ ÇALIŞTIR ---
    const CHECK_INTERVAL = 12 * 60 * 60 * 1000; // 12 saat
    const LAST_CHECK_KEY = 'mz_last_transfer_check';
    const lastCheck = await GM_getValue(LAST_CHECK_KEY, 0);
    if (Date.now() - lastCheck > CHECK_INTERVAL) {
        console.log("SUITE: Otomatik transfer kontrol zamanı geldi. 10 saniye içinde başlatılacak.");
        setTimeout(runBackgroundTransferCheck, 10000); // Sayfa yüklemesini yavaşlatmamak için 10 sn bekle
    }

    // Yönlendiriciyi çalıştır
    masterRouter();

})();