Увага: Після публікування слід очистити кеш браузера, щоб побачити зміни.

  • Firefox / Safari: тримайте Shift, коли натискаєте Оновити, або натисніть Ctrl-F5 чи Ctrl-Shift-R (⌘-R на Apple Mac)
  • Google Chrome: натисніть Ctrl-Shift-R (⌘-Shift-R на Apple Mac)
  • Internet Explorer / Edge: тримайте Ctrl, коли натискаєте Оновити, або натисніть Ctrl-F5
  • Opera: натисніть Ctrl-F5
// ============================================================
// MediaWiki:Common.js — Mafia Closed Circle
// Фінальна версія
// ============================================================

// ============================================================
// 1. RANDOM ARTICLES
// ============================================================
$(document).ready(function () {
    var apiUrl = mw.config.get('wgScriptPath') + '/api.php';
    $.getJSON(apiUrl, {
        action: 'query', format: 'json', list: 'random',
        rnnamespace: '0', rnlimit: '5',
        prop: 'extracts', exchars: '250', exlimit: 'max', explaintext: true
    }, function (data) {
        var html = '';
        $.each(data.query.random, function (i, article) {
            html += '<div class="random-article-preview">';
            html += '<h2><a href="/wiki/' + encodeURIComponent(article.title) + '">' + article.title + '</a></h2>';
            html += '</div>';
        });
        $('#random-articles-container').html(html);
    });
});

// ============================================================
// 2. L-BOX NAVIGATION
// ============================================================
$(function () {
    var $lbox = $('.l-box');
    if ($lbox.length === 0) return;

    var $items = $lbox.find('.l-box-item');

    function buildSectionMap() {
        var map = [];
        $items.each(function () {
            var target = $(this).data('target');
            if (target === 'top') {
                map.push({ $item: $(this), top: 0 });
            } else {
                var $el = $('#' + target);
                if ($el.length) {
                    map.push({ $item: $(this), top: $el.offset().top });
                }
            }
        });
        map.sort(function (a, b) { return a.top - b.top; });
        return map;
    }

    function updateActive(map) {
        var scrollY = $(window).scrollTop() + 110;
        var current = null;
        for (var i = 0; i < map.length; i++) {
            if (map[i].top <= scrollY) current = map[i].$item;
        }
        $items.removeClass('active');
        if (current) current.addClass('active');
    }

    $items.on('click', function () {
        var target = $(this).data('target');
        if (target === 'top') {
            $('html, body').animate({ scrollTop: 0 }, 280);
        } else {
            var $el = $('#' + target);
            if ($el.length) {
                $('html, body').animate({ scrollTop: $el.offset().top - 75 }, 280);
            }
        }
    });

    var sectionMap = buildSectionMap();

    $(document).on('mcc:content-loaded', function () {
        sectionMap = buildSectionMap();
        updateActive(sectionMap);
    });

    var ticking = false;
    $(window).on('scroll', function () {
        if (!ticking) {
            window.requestAnimationFrame(function () {
                updateActive(sectionMap);
                ticking = false;
            });
            ticking = true;
        }
    });

    $(window).on('resize', function () {
        sectionMap = buildSectionMap();
        updateActive(sectionMap);
    });

    updateActive(sectionMap);
});

// ============================================================
// 3. PROFILE ICONS — клік + inactive якщо немає URL
// ============================================================
$(document).ready(function () {
    $('.profile-icon').each(function () {
        var $icon = $(this);
        var url = ($icon.attr('data-url') || '').trim();

        if (url) {
            $icon.css('cursor', 'pointer');
            $icon.on('click', function () {
                window.open(url, '_blank');
            });
        } else {
            $icon.addClass('inactive');
        }
    });
});

// ============================================================
// 4. ДИНАМІЧНІ ПОСИЛАННЯ НА ГОЛОВНІЙ
// ============================================================
$(document).ready(function () {
    if (!$('body').hasClass('page-Головна_сторінка')) return;

    var block1Links = [{ title: 'Фінал Року', url: '/index.php/Фінал_Року' }];
    var block2Links = [
        { title: 'Перша статистика', url: '/index.php/Перша_статистика' },
        { title: 'Період',           url: '/index.php/Період' },
        { title: 'Друга статистика', url: '/index.php/Статистика' }
    ];
    var block3Links = [
        { title: 'Mafia Closed Cup I',        url: '/index.php/Mafia_Closed_Cup_I' },
        { title: 'Mafia Closed Cup I Online', url: '/index.php/Mafia_Closed_Cup_I_Online' },
        { title: 'My Closest Circle I',       url: '/index.php/My_Closest_Circle_I' }
    ];

    function rand(arr) { return arr[Math.floor(Math.random() * arr.length)]; }

    var $blocks = $('.home__block-image-block p');
    if ($blocks.length >= 3) {
        var l1 = rand(block1Links), l2 = rand(block2Links), l3 = rand(block3Links);
        $blocks.eq(0).html('<a href="' + l1.url + '">' + l1.title + '</a>');
        $blocks.eq(1).html('<a href="' + l2.url + '">' + l2.title + '</a>');
        $blocks.eq(2).html('<a href="' + l3.url + '">' + l3.title + '</a>');
    }
});

// ============================================================
// 5. PLAYER TABS + LAZY LOADING ІГОР
// ============================================================
$(function () {
    var $tabs     = $('.player-tab');
    var $contents = $('.player-tab-content');
    var $lbox     = $('.l-box');
    var $rbox     = $('.r-box');

    if ($tabs.length === 0) return;

    function isMobile() { return $(window).width() <= 768; }

    $tabs.on('click', function () {
        var $tab   = $(this);
        var tabId  = $tab.data('tab');
        var $content = $('#tab-' + tabId);

        $tabs.removeClass('active');
        $tab.addClass('active');
        $contents.removeClass('active');
        $content.addClass('active');

        // L-box — ховаємо на вкладці ігор
        if (tabId === 'games') {
            $lbox.fadeOut(200);
        } else {
            $lbox.fadeIn(200);
        }

        // R-box — на мобільних ховаємо при іграх
        if (isMobile()) {
            if (tabId === 'games') $rbox.slideUp(200);
            else                   $rbox.slideDown(200);
        }

        // Lazy load
        if (tabId === 'games' && !$content.data('loaded')) {
            var playerName = $content.data('player');
            if (!playerName) return;

            $content.html('<div class="tab-loader">Завантаження...</div>');

            $.ajax({
                url: mw.config.get('wgScriptPath') + '/api.php',
                data: {
                    action: 'expandtemplates', format: 'json',
                    text: '{{#invoke:FetchData|player_games|player=' + playerName + '}}',
                    prop: 'wikitext'
                },
                dataType: 'json',
                success: function (response) {
                    if (!response.expandtemplates || !response.expandtemplates.wikitext) return;

                    $.ajax({
                        url: mw.config.get('wgScriptPath') + '/api.php',
                        data: {
                            action: 'parse', format: 'json',
                            text: response.expandtemplates.wikitext,
                            contentmodel: 'wikitext',
                            disablelimitreport: true
                        },
                        dataType: 'json',
                        success: function (r) {
                            if (r.parse && r.parse.text) {
                                $content.html(r.parse.text['*']);
                                $content.data('loaded', true);
                                $content.find('table.sortable').tablesorter();

                                // Запускаємо пост-обробку для нового контенту
                                applyWinrateColors($content);
                                wrapWideTables($content);
                                $(document).trigger('mcc:content-loaded');
                            }
                        },
                        error: function () {
                            $content.html('<p style="color:#ff7777;text-align:center">Помилка завантаження.</p>');
                        }
                    });
                },
                error: function () {
                    $content.html('<p style="color:#ff7777;text-align:center">Помилка завантаження.</p>');
                }
            });
        }
    });

    $(window).on('resize', function () {
        if (!isMobile()) $rbox.show();
    });
});

// ============================================================
// 6. АНІМАЦІЯ РЯДКІВ ПРИ СОРТУВАННІ
// ============================================================
$(function () {
    $(document).on('sortEnd', 'table.wikitable', function () {
        var $t = $(this);
        $t.addClass('mcc-sorting').removeClass('mcc-sorted');
        setTimeout(function () {
            $t.removeClass('mcc-sorting').addClass('mcc-sorted');
            setTimeout(function () { $t.removeClass('mcc-sorted'); }, 600);
        }, 20);
    });
});

// ============================================================
// 7. ГОРИЗОНТАЛЬНИЙ СКРОЛ ДЛЯ ШИРОКИХ ТАБЛИЦЬ
// ============================================================
function wrapWideTables($context) {
    var $root = $context || $(document);

    function wrap($table) {
        if ($table.closest('.mcc-scroll-inner').length) return;

        $table.wrap('<div class="mcc-scroll-inner"></div>');
        $table.closest('.mcc-scroll-inner').wrap('<div class="mcc-scroll-outer"></div>');

        var $inner = $table.closest('.mcc-scroll-inner');
        var $outer = $inner.closest('.mcc-scroll-outer');

        function check() {
            var atEnd = $inner[0].scrollLeft + $inner[0].clientWidth >= $inner[0].scrollWidth - 4;
            $outer.toggleClass('mcc-no-fade', atEnd);
        }

        $inner.on('scroll', check);
        check();
    }

    // Явно задані широкі класи
    $root.find('.wikitable.wide-table, .wikitable.mcc-wide, .wikitable.full-width').each(function () {
        wrap($(this));
    });

    // Таблиці з >8 колонок (Запис ігор)
    $root.find('.wikitable').each(function () {
        var $t = $(this);
        if ($t.closest('.mcc-scroll-inner').length) return;
        if ($t.find('thead tr:first th').length > 8) {
            $t.addClass('mcc-wide-table');
            wrap($t);
        }
    });
}

$(function () { wrapWideTables(); });

// ============================================================
// 8. ВІНРЕЙТ — кольорове підсвічення клітинок з %
// ============================================================
// ============================================================
// REPLACE applyWinrateColors у Common.js
// (знайди функцію applyWinrateColors і замінь повністю)
// ============================================================

function applyWinrateColors($context) {
    var $root = $context || $(document);

    $root.find('.wikitable tbody td').each(function () {
        var $cell = $(this);

        // Вже оброблено
        if ($cell.hasClass('wr-hi') || $cell.hasClass('wr-lo')) return;

        // Беремо текстовий вміст (без HTML тегів)
        var text = $cell.text().trim();

        // Підтримуємо: "53%", "46.95%", "33.33%", "100%"
        var match = text.match(/^(\d+(?:\.\d+)?)%$/);
        if (!match) return;

        var val = parseFloat(match[1]);
        if      (val >= 55) $cell.addClass('wr-hi');
        else if (val <= 33) $cell.addClass('wr-lo');
    });
}

// ============================================================
// 9. МОБІЛЬНИЙ ПОШУК
// ============================================================
$(function () {
    if ($(window).width() > 768) return;
    if ($('.mobile-search-btn').length > 0) return;

    var $btn = $('<div class="mobile-search-btn">' +
        '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2">' +
        '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg></div>');

    var $overlay = $('<div class="mobile-search-overlay">' +
        '<input type="text" placeholder="Пошук..." autocomplete="off">' +
        '<div class="mobile-search-close">×</div></div>');

    $('.minerva-header .branding-box').after($btn);
    $('body').append($overlay);

    var $input = $overlay.find('input');
    var $close = $overlay.find('.mobile-search-close');

    $btn.on('click', function (e) {
        e.preventDefault(); e.stopPropagation();
        $overlay.addClass('active');
        setTimeout(function () { $input.focus(); }, 100);
    });

    $close.on('click', function () {
        $overlay.removeClass('active'); $input.val('');
    });

    $input.on('keydown', function (e) {
        if (e.keyCode === 13) {
            var q = $input.val().trim();
            if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
        }
        if (e.keyCode === 27) { $overlay.removeClass('active'); $input.val(''); }
    });

    $overlay.on('click', function (e) {
        if (e.target === this) { $overlay.removeClass('active'); $input.val(''); }
    });
});

// ============================================================
// 10. БЛОКУВАННЯ MINERVA SEARCH OVERLAY (ДЕСКТОП)
// ============================================================
$(function () {
    if ($(window).width() <= 768) return;

    var $searchInput = $('#searchInput');
    if ($searchInput.length === 0) return;

    setTimeout(function () {
        $searchInput.attr('placeholder', 'Пошук...');

        var $newInput = $searchInput.clone(false);
        $searchInput.replaceWith($newInput);
        $searchInput = $newInput;

        $searchInput.prop('readonly', false).removeAttr('readonly')
            .removeClass('skin-minerva-search-trigger');

        $searchInput.on('focus click', function (e) {
            e.stopPropagation();
            $('body').removeClass('overlay-enabled search-enabled');
            $('.overlay, .search-overlay').hide();
            if (window.location.hash === '#/search') {
                history.replaceState(null, null, window.location.pathname);
            }
        });

        $searchInput.on('keydown', function (e) {
            if (e.which === 13) {
                e.preventDefault();
                var q = $(this).val().trim();
                if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
                return false;
            }
        });
    }, 100);

    $(window).on('hashchange', function () {
        if (window.location.hash === '#/search') {
            history.replaceState(null, null, window.location.pathname);
            $('body').removeClass('overlay-enabled search-enabled');
            $('.overlay, .search-overlay').hide();
        }
    });

    if (window.location.hash === '#/search') {
        history.replaceState(null, null, window.location.pathname);
    }
});

// ============================================================
// 11. BANNER SEARCH
// ============================================================
$(function () {
    var $container = $('#bannerSearchContainer');
    if ($container.length === 0) return;

    var $input = $('<input>', { type: 'text', id: 'bannerSearchInput', placeholder: 'Пошук MCC...' });
    var $btn   = $('<button>', { id: 'bannerSearchBtn', text: 'Пошук' });

    $container.append($input).append($btn);

    function doSearch() {
        var q = $input.val().trim();
        if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
    }

    $btn.on('click', doSearch);
    $input.on('keydown', function (e) { if (e.keyCode === 13) { e.preventDefault(); doSearch(); } });
});

// ============================================================
// MediaWiki:Common.js — Mafia Closed Circle — ФІНАЛЬНА ВЕРСІЯ
// ============================================================

// ============================================================
// 1. RANDOM ARTICLES
// ============================================================
$(document).ready(function () {
    var apiUrl = mw.config.get('wgScriptPath') + '/api.php';
    $.getJSON(apiUrl, {
        action: 'query', format: 'json', list: 'random',
        rnnamespace: '0', rnlimit: '5'
    }, function (data) {
        var html = '';
        $.each(data.query.random, function (i, article) {
            html += '<div class="random-article-preview"><h2><a href="/wiki/' + encodeURIComponent(article.title) + '">' + article.title + '</a></h2></div>';
        });
        $('#random-articles-container').html(html);
    });
});

// ============================================================
// 2. L-BOX NAVIGATION
// ФІКС: використовуємо document.getElementById для кирилиці
// ============================================================
$(function () {
    var $lbox = $('.l-box');
    if ($lbox.length === 0) return;

    var $items = $lbox.find('.l-box-item');

    function buildSectionMap() {
        var map = [];
        $items.each(function () {
            var target = $(this).data('target');
            if (target === 'top') {
                map.push({ $item: $(this), top: 0 });
            } else {
                // ФІКС: document.getElementById коректно обробляє кирилицю
                var el = document.getElementById(target);
                if (el) {
                    var $el = $(el);
                    // Якщо el — це span.mw-headline, беремо батьківський h2
                    var $heading = $el.closest('h2, h3, h4').length
                        ? $el.closest('h2, h3, h4')
                        : $el;
                    map.push({ $item: $(this), top: $heading.offset().top });
                }
            }
        });
        map.sort(function (a, b) { return a.top - b.top; });
        return map;
    }

    function updateActive(map) {
        var scrollY = $(window).scrollTop() + 120;
        var current = null;
        for (var i = 0; i < map.length; i++) {
            if (map[i].top <= scrollY) current = map[i].$item;
        }
        $items.removeClass('active');
        if (current) current.addClass('active');
    }

    $items.on('click', function () {
        var target = $(this).data('target');
        if (target === 'top') {
            $('html, body').animate({ scrollTop: 0 }, 280);
        } else {
            var el = document.getElementById(target);
            if (el) {
                var $el = $(el);
                var $heading = $el.closest('h2, h3, h4').length
                    ? $el.closest('h2, h3, h4')
                    : $el;
                var offset = $heading.offset().top - 78;
                $('html, body').animate({ scrollTop: offset }, 280);
            }
        }
        // Активуємо одразу при кліку, не чекаємо скрол
        $items.removeClass('active');
        $(this).addClass('active');
    });

    var sectionMap = buildSectionMap();

    $(document).on('mcc:content-loaded', function () {
        sectionMap = buildSectionMap();
        updateActive(sectionMap);
    });

    var ticking = false;
    $(window).on('scroll', function () {
        if (!ticking) {
            window.requestAnimationFrame(function () {
                updateActive(sectionMap);
                ticking = false;
            });
            ticking = true;
        }
    });

    $(window).on('resize', function () {
        sectionMap = buildSectionMap();
        updateActive(sectionMap);
    });

    // Перший виклик — після мікро-затримки (DOM точно готовий)
    setTimeout(function () {
        sectionMap = buildSectionMap();
        updateActive(sectionMap);
    }, 200);
});

// ============================================================
// 3. PROFILE ICONS
// ============================================================
$(document).ready(function () {
    $('.profile-icon').each(function () {
        var $icon = $(this);
        var url = ($icon.attr('data-url') || '').trim();
        if (url) {
            $icon.css('cursor', 'pointer');
            $icon.on('click', function () { window.open(url, '_blank'); });
        } else {
            $icon.addClass('inactive');
        }
    });
});

// ============================================================
// 4. STATS OVERLAY НА ФОТО ГРАВЦЯ В R-BOX
// Читає ігри/перемоги/поразки з параметрів шаблону і додає overlay
// ============================================================
$(function () {
    var $rbox = $('.r-box');
    if ($rbox.length === 0) return;

    // Шукаємо рядки таблиці в r-box
    var games = '', wins = '', losses = '';

    $rbox.find('table tr').each(function () {
        var $th = $(this).find('th');
        var $td = $(this).find('td');
        if (!$th.length || !$td.length) return;
        var label = $th.text().trim().toLowerCase();
        var val   = $td.text().trim();

        if (label.indexOf('офіційних') !== -1 || label.indexOf('ігор') !== -1) {
            // "46.95% (208 - 235)" → витягуємо числа
            var m = val.match(/\((\d+)[^\d]+(\d+)\)/);
            if (m) { wins = m[1]; losses = m[2]; }
            var total = parseInt(wins || 0) + parseInt(losses || 0);
            if (total > 0) games = total;
        }
    });

    // Якщо знайшли дані — додаємо overlay на фото
    if (games && wins && losses) {
        var $figure = $rbox.find('figure');
        if ($figure.length && !$figure.find('.rp-stats-overlay').length) {
            var html = '<div class="rp-stats-overlay">'
                + '<div class="rp-stat-box"><span class="rp-sv">' + games  + '</span><span class="rp-sl">Ігор</span></div>'
                + '<div class="rp-stat-box"><span class="rp-sv">' + wins   + '</span><span class="rp-sl">Перемог</span></div>'
                + '<div class="rp-stat-box"><span class="rp-sv">' + losses + '</span><span class="rp-sl">Поразок</span></div>'
                + '</div>';
            $figure.append(html);
        }
    }
});

// ============================================================
// 5. ДИНАМІЧНІ ПОСИЛАННЯ НА ГОЛОВНІЙ
// ============================================================
$(document).ready(function () {
    if (!$('body').hasClass('page-Головна_сторінка')) return;

    var block1Links = [{ title: 'Фінал Року', url: '/index.php/Фінал_Року' }];
    var block2Links = [
        { title: 'Перша статистика', url: '/index.php/Перша_статистика' },
        { title: 'Період',           url: '/index.php/Період' },
        { title: 'Друга статистика', url: '/index.php/Статистика' }
    ];
    var block3Links = [
        { title: 'Mafia Closed Cup I',        url: '/index.php/Mafia_Closed_Cup_I' },
        { title: 'Mafia Closed Cup I Online', url: '/index.php/Mafia_Closed_Cup_I_Online' },
        { title: 'My Closest Circle I',       url: '/index.php/My_Closest_Circle_I' }
    ];

    function rand(arr) { return arr[Math.floor(Math.random() * arr.length)]; }

    var $blocks = $('.home__block-image-block p');
    if ($blocks.length >= 3) {
        var l1 = rand(block1Links), l2 = rand(block2Links), l3 = rand(block3Links);
        $blocks.eq(0).html('<a href="' + l1.url + '">' + l1.title + '</a>');
        $blocks.eq(1).html('<a href="' + l2.url + '">' + l2.title + '</a>');
        $blocks.eq(2).html('<a href="' + l3.url + '">' + l3.title + '</a>');
    }
});

// ============================================================
// 6. PLAYER TABS + LAZY LOADING
// ============================================================
$(function () {
    var $tabs     = $('.player-tab');
    var $contents = $('.player-tab-content');
    var $lbox     = $('.l-box');
    var $rbox     = $('.r-box');

    if ($tabs.length === 0) return;

    function isMobile() { return $(window).width() <= 768; }

    $tabs.on('click', function () {
        var $tab  = $(this);
        var tabId = $tab.data('tab');
        var $content = $('#tab-' + tabId);

        $tabs.removeClass('active');
        $tab.addClass('active');
        $contents.removeClass('active');
        $content.addClass('active');

        if (tabId === 'games') {
            $lbox.fadeOut(200);
        } else {
            $lbox.fadeIn(200);
        }

        if (isMobile()) {
            if (tabId === 'games') $rbox.slideUp(200);
            else                   $rbox.slideDown(200);
        }

        // Lazy load
        if (tabId === 'games' && !$content.data('loaded')) {
            var playerName = $content.data('player');
            if (!playerName) return;

            $content.html('<div class="tab-loader">Завантаження...</div>');

            $.ajax({
                url: mw.config.get('wgScriptPath') + '/api.php',
                data: {
                    action: 'expandtemplates', format: 'json',
                    text: '{{#invoke:FetchData|player_games|player=' + playerName + '}}',
                    prop: 'wikitext'
                },
                dataType: 'json',
                success: function (response) {
                    if (!response.expandtemplates || !response.expandtemplates.wikitext) return;

                    $.ajax({
                        url: mw.config.get('wgScriptPath') + '/api.php',
                        data: {
                            action: 'parse', format: 'json',
                            text: response.expandtemplates.wikitext,
                            contentmodel: 'wikitext',
                            disablelimitreport: true
                        },
                        dataType: 'json',
                        success: function (r) {
                            if (r.parse && r.parse.text) {
                                $content.html(r.parse.text['*']);
                                $content.data('loaded', true);

                                var $table = $content.find('table.sortable, table.wikitable');
                                $table.tablesorter();

                                // Додаємо фільтри над таблицею
                                injectGamesFilters($content, $table, playerName);

                                applyWinrateColors($content);
                                wrapWideTables($content);
                                applyRolePills($content);
                                $(document).trigger('mcc:content-loaded');
                            }
                        },
                        error: function () {
                            $content.html('<p style="color:#ff7777;text-align:center;padding:20px">Помилка завантаження.</p>');
                        }
                    });
                },
                error: function () {
                    $content.html('<p style="color:#ff7777;text-align:center;padding:20px">Помилка завантаження.</p>');
                }
            });
        }
    });

    $(window).on('resize', function () {
        if (!isMobile()) $rbox.show();
    });
});

// ============================================================
// 7. ФІЛЬТРИ НАД ТАБЛИЦЕЮ ІГОР
// ============================================================
function injectGamesFilters($container, $table, playerName) {
    if (!$table.length) return;
    if ($container.find('.mcc-games-filters').length) return;

    // Збираємо унікальні події з таблиці
    var events = [];
    $table.find('tbody tr').each(function () {
        var event = $(this).find('td').eq(0).text().trim();
        if (event && events.indexOf(event) === -1) events.push(event);
    });

    var eventOptions = '<option value="">Всі події</option>';
    events.forEach(function (e) {
        eventOptions += '<option value="' + e + '">' + e + '</option>';
    });

    var html = '<div class="mcc-games-filters">'
        + '<div class="mcc-filter-group">'
        +   '<span class="mcc-filter-label">Подія</span>'
        +   '<select class="mcc-filter-select" id="mcc-f-event">' + eventOptions + '</select>'
        + '</div>'
        + '<div class="mcc-filter-group">'
        +   '<span class="mcc-filter-label">Роль</span>'
        +   '<select class="mcc-filter-select" id="mcc-f-role">'
        +     '<option value="">Всі ролі</option>'
        +     '<option value="Мир">Мирний</option>'
        +     '<option value="Шер">Шериф</option>'
        +     '<option value="Маф">Мафія</option>'
        +     '<option value="Дон">Дон</option>'
        +   '</select>'
        + '</div>'
        + '<div class="mcc-filter-group">'
        +   '<span class="mcc-filter-label">Результат</span>'
        +   '<select class="mcc-filter-select" id="mcc-f-result">'
        +     '<option value="">Всі</option>'
        +     '<option value="В">Перемога</option>'
        +     '<option value="П">Поразка</option>'
        +   '</select>'
        + '</div>'
        + '<div class="mcc-filter-group mcc-duration-group">'
        +   '<span class="mcc-filter-label">Макс. тривалість</span>'
        +   '<div class="mcc-slider-wrap">'
        +     '<input type="range" class="mcc-duration-range" id="mcc-f-dur" min="20" max="70" value="70" step="1">'
        +     '<span class="mcc-slider-val" id="mcc-dur-val">70:00</span>'
        +   '</div>'
        + '</div>'
        + '<span class="mcc-filter-count" id="mcc-games-count"></span>'
        + '</div>';

    $table.before(html);

    var $filters = $container.find('.mcc-games-filters');

    function timeToMins(str) {
        str = str.trim();
        // Формати: "37:57" або "37 хв 26 с"
        var m1 = str.match(/^(\d+):(\d+)$/);
        if (m1) return parseInt(m1[1]) + parseInt(m1[2]) / 60;
        var m2 = str.match(/(\d+)\s*хв\s*(\d+)/);
        if (m2) return parseInt(m2[1]) + parseInt(m2[2]) / 60;
        return 999;
    }

    function filterTable() {
        var ev   = $('#mcc-f-event').val();
        var role = $('#mcc-f-role').val();
        var res  = $('#mcc-f-result').val();
        var dur  = parseInt($('#mcc-f-dur').val());

        var visible = 0;
        $table.find('tbody tr').each(function () {
            var $row = $(this);
            var tds  = $row.find('td');
            var evVal   = tds.eq(0).text().trim();
            var roleVal = tds.eq(1).text().trim();
            var timeVal = tds.eq(2).text().trim();
            var resVal  = tds.eq(3).text().trim();

            var show = true;
            if (ev   && evVal.indexOf(ev) === -1)   show = false;
            if (role && roleVal.indexOf(role) === -1) show = false;
            if (res  && resVal.indexOf(res) === -1)  show = false;
            if (timeToMins(timeVal) > dur)            show = false;

            $row.toggle(show);
            if (show) visible++;
        });

        $('#mcc-games-count').text(visible + ' ігор');
    }

    // Slider
    $('#mcc-f-dur').on('input', function () {
        var v = parseInt($(this).val());
        $('#mcc-dur-val').text(v + ':00');
        var pct = (v - 20) / (70 - 20) * 100;
        $(this).css('background-size', pct + '% 100%');
        filterTable();
    });

    $filters.find('.mcc-filter-select').on('change', filterTable);

    // Початковий підрахунок
    var total = $table.find('tbody tr').length;
    $('#mcc-games-count').text(total + ' ігор');

    // Початковий slider fill
    var initPct = (70 - 20) / (70 - 20) * 100;
    $('#mcc-f-dur').css('background-size', initPct + '% 100%');
}

// ============================================================
// 8. ROLE PILLS — замінюємо білий текст на кольорові пілюлі
// ============================================================
function applyRolePills($context) {
    var $root = $context || $(document);
    var roleMap = {
        'Мир':  { bg: 'rgba(76,175,125,0.12)',  color: '#7dd4a6', border: 'rgba(76,175,125,0.20)'  },
        'Шер':  { bg: 'rgba(91,143,255,0.12)',   color: '#7da8ff', border: 'rgba(91,143,255,0.20)'  },
        'Маф':  { bg: 'rgba(200,76,76,0.12)',    color: '#e08888', border: 'rgba(200,76,76,0.20)'   },
        'Дон':  { bg: 'rgba(255,215,0,0.10)',    color: '#ffd700', border: 'rgba(255,215,0,0.20)'   }
    };

    $root.find('.wikitable tbody td').each(function () {
        var $cell = $(this);
        // Перевіряємо span з inline color
        var $span = $cell.find('span').filter(function () {
            var s = $(this).attr('style') || '';
            return s.indexOf('color') !== -1;
        });

        if (!$span.length) return;

        var text = $span.text().trim();
        var style = roleMap[text];
        if (!style) return;

        $span.css({
            'display': 'inline-block',
            'padding': '2px 10px',
            'border-radius': '4px',
            'font-size': '12.5px',
            'font-weight': '600',
            'background': style.bg,
            'color': style.color,
            'border': '1px solid ' + style.border
        });
    });
}

$(function () { applyRolePills(); });

// ============================================================
// 9. АНІМАЦІЯ РЯДКІВ ПРИ СОРТУВАННІ
// ============================================================
$(function () {
    $(document).on('sortEnd', 'table.wikitable', function () {
        var $t = $(this);
        $t.addClass('mcc-sorting').removeClass('mcc-sorted');
        setTimeout(function () {
            $t.removeClass('mcc-sorting').addClass('mcc-sorted');
            setTimeout(function () { $t.removeClass('mcc-sorted'); }, 600);
        }, 20);
    });
});

// ============================================================
// 10. ГОРИЗОНТАЛЬНИЙ СКРОЛ ДЛЯ ШИРОКИХ ТАБЛИЦЬ
// ============================================================
function wrapWideTables($context) {
    var $root = $context || $(document);

    function wrap($table) {
        if ($table.closest('.mcc-scroll-inner').length) return;

        $table.wrap('<div class="mcc-scroll-inner"></div>');
        $table.closest('.mcc-scroll-inner').wrap('<div class="mcc-scroll-outer"></div>');

        var $inner = $table.closest('.mcc-scroll-inner');
        var $outer = $inner.closest('.mcc-scroll-outer');

        function check() {
            var atEnd = $inner[0].scrollLeft + $inner[0].clientWidth >= $inner[0].scrollWidth - 4;
            $outer.toggleClass('mcc-no-fade', atEnd);
        }

        $inner.on('scroll', check);
        check();
    }

    $root.find('.wikitable.wide-table, .wikitable.mcc-wide, .wikitable.full-width').each(function () {
        wrap($(this));
    });

    $root.find('.wikitable').each(function () {
        var $t = $(this);
        if ($t.closest('.mcc-scroll-inner, .r-box, .tournament-box').length) return;
        if ($t.find('thead tr:first th').length > 8) {
            $t.addClass('mcc-wide-table');
            wrap($t);
        }
    });
}

$(function () { wrapWideTables(); });

// ============================================================
// 11. ВІНРЕЙТ — кольорові класи
// ============================================================
function applyWinrateColors($context) {
    var $root = $context || $(document);
    $root.find('.wikitable tbody td').each(function () {
        var $cell = $(this);
        if ($cell.hasClass('wr-hi') || $cell.hasClass('wr-lo')) return;
        var text  = $cell.text().trim();
        var match = text.match(/^(\d+(?:\.\d+)?)%$/);
        if (!match) return;
        var val = parseFloat(match[1]);
        if      (val >= 55) $cell.addClass('wr-hi');
        else if (val <= 33) $cell.addClass('wr-lo');
    });
}

$(function () { applyWinrateColors(); });

// ============================================================
// 12. МОБІЛЬНИЙ ПОШУК
// ============================================================
$(function () {
    if ($(window).width() > 768) return;
    if ($('.mobile-search-btn').length > 0) return;

    var $btn = $('<div class="mobile-search-btn">'
        + '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="#fff" stroke-width="2">'
        + '<circle cx="11" cy="11" r="8"/><path d="m21 21-4.35-4.35"/></svg></div>');

    var $overlay = $('<div class="mobile-search-overlay">'
        + '<input type="text" placeholder="Пошук..." autocomplete="off">'
        + '<div class="mobile-search-close">×</div></div>');

    $('.minerva-header .branding-box').after($btn);
    $('body').append($overlay);

    var $input = $overlay.find('input');
    var $close = $overlay.find('.mobile-search-close');

    $btn.on('click', function (e) {
        e.preventDefault(); e.stopPropagation();
        $overlay.addClass('active');
        setTimeout(function () { $input.focus(); }, 100);
    });

    $close.on('click', function () { $overlay.removeClass('active'); $input.val(''); });

    $input.on('keydown', function (e) {
        if (e.keyCode === 13) {
            var q = $input.val().trim();
            if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
        }
        if (e.keyCode === 27) { $overlay.removeClass('active'); $input.val(''); }
    });

    $overlay.on('click', function (e) {
        if (e.target === this) { $overlay.removeClass('active'); $input.val(''); }
    });
});

// ============================================================
// 13. БЛОКУВАННЯ MINERVA SEARCH OVERLAY (ДЕСКТОП)
// ============================================================
$(function () {
    if ($(window).width() <= 768) return;

    var $searchInput = $('#searchInput');
    if ($searchInput.length === 0) return;

    setTimeout(function () {
        $searchInput.attr('placeholder', 'Пошук...');

        var $newInput = $searchInput.clone(false);
        $searchInput.replaceWith($newInput);
        $searchInput = $newInput;

        $searchInput.prop('readonly', false).removeAttr('readonly')
            .removeClass('skin-minerva-search-trigger');

        $searchInput.on('focus click', function (e) {
            e.stopPropagation();
            $('body').removeClass('overlay-enabled search-enabled');
            $('.overlay, .search-overlay').hide();
            if (window.location.hash === '#/search') {
                history.replaceState(null, null, window.location.pathname);
            }
        });

        $searchInput.on('keydown', function (e) {
            if (e.which === 13) {
                e.preventDefault();
                var q = $(this).val().trim();
                if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
                return false;
            }
        });
    }, 100);

    $(window).on('hashchange', function () {
        if (window.location.hash === '#/search') {
            history.replaceState(null, null, window.location.pathname);
            $('body').removeClass('overlay-enabled search-enabled');
            $('.overlay, .search-overlay').hide();
        }
    });

    if (window.location.hash === '#/search') {
        history.replaceState(null, null, window.location.pathname);
    }
});

// ============================================================
// 14. BANNER SEARCH
// ============================================================
$(function () {
    var $container = $('#bannerSearchContainer');
    if ($container.length === 0) return;

    var $input = $('<input>', { type: 'text', id: 'bannerSearchInput', placeholder: 'Пошук MCC...' });
    var $btn   = $('<button>', { id: 'bannerSearchBtn', text: 'Пошук' });

    $container.append($input).append($btn);

    function doSearch() {
        var q = $input.val().trim();
        if (q) window.location.href = '/index.php?title=Спеціальна:Пошук&search=' + encodeURIComponent(q);
    }

    $btn.on('click', doSearch);
    $input.on('keydown', function (e) { if (e.keyCode === 13) { e.preventDefault(); doSearch(); } });
});

// ============================================================
// ДОДАТИ в кінець Common.js (після всього іншого коду)
// ============================================================

// ── 1. PLAYER TABS — перетворюємо "(42)" на стилізований badge ──
$(function () {
    $('.player-tab').each(function () {
        var $tab = $(this);
        var text = $tab.text();
        // Шукаємо "(число)" в тексті табу
        var m = text.match(/\((\d+)\)/);
        if (!m) return;

        // Замінюємо "(42)" на <span class="mcc-tab-cnt">42</span>
        var cleanText = text.replace(/\s*\(\d+\)/, '').trim();
        $tab.text(cleanText);
        $tab.append('<span class="mcc-tab-cnt">' + m[1] + '</span>');
    });
});

// ── 2. СЕЗОНИ — підсвічуємо "Чемпіон" у таблиці ──
$(function () {
    function applySeasonColors($context) {
        var $root = $context || $(document);
        $root.find('.wikitable tbody td').each(function () {
            var $cell = $(this);
            var text  = $cell.text().trim();
            if (text === 'Чемпіон' || text === '♔ Чемпіон') {
                $cell.css({ color: '#7ab8ff', fontWeight: '700' });
            }
        });
    }

    applySeasonColors();

    // Після lazy load теж
    $(document).on('mcc:content-loaded', function () {
        applySeasonColors();
    });
});

// ── 3. ROLE PILLS — окремий надійний виклик ──
// (доповнює applyRolePills з основного коду)
$(function () {
    var roleStyles = {
        'Мир': { bg:'rgba(76,175,125,0.12)', color:'#7dd4a6', border:'rgba(76,175,125,0.22)' },
        'Шер': { bg:'rgba(91,143,255,0.12)', color:'#7da8ff', border:'rgba(91,143,255,0.22)' },
        'Маф': { bg:'rgba(200,76,76,0.12)',  color:'#e08888', border:'rgba(200,76,76,0.22)'  },
        'Дон': { bg:'rgba(255,215,0,0.10)',  color:'#ffd700', border:'rgba(255,215,0,0.22)'  }
    };

    function pillify($root) {
        ($root || $(document)).find('.wikitable tbody td').each(function () {
            var $cell = $(this);
            // Знаходимо span з inline color або просто текст ролі
            var $span = $cell.find('span').filter(function () {
                return $(this).attr('style') && $(this).attr('style').indexOf('color') !== -1;
            });

            var $target = $span.length ? $span : null;
            var roleText = $target ? $target.text().trim() : $cell.text().trim();
            var style    = roleStyles[roleText];

            if (!style) return;

            if (!$target) {
                // Якщо просто текст — обгортаємо
                var html = $cell.html();
                $cell.html('<span class="mcc-role-pill">' + html + '</span>');
                $target = $cell.find('.mcc-role-pill');
            }

            if (!$target.hasClass('mcc-pill-done')) {
                $target.addClass('mcc-pill-done').css({
                    display:       'inline-block',
                    padding:       '2px 10px',
                    borderRadius:  '4px',
                    fontSize:      '12.5px',
                    fontWeight:    '600',
                    background:    style.bg,
                    color:         style.color,
                    border:        '1px solid ' + style.border,
                    fontFamily:    "'Manrope', sans-serif"
                });
            }
        });
    }

    pillify();
    $(document).on('mcc:content-loaded', function () { pillify(); });
});

// ── 4. PROFILE ICONS — перевіряємо та фіксуємо layout ──
$(function () {
    function fixProfileIcons() {
        var $icons = $('.profile-links-icons');
        if (!$icons.length) return;

        // Примусово перевизначаємо через JS якщо CSS не спрацював
        $icons.css({
            'display': 'grid',
            'grid-template-columns': 'repeat(4, 1fr)',
            'gap': '0'
        });

        $icons.find('.profile-icon').css({
            'display': 'flex',
            'align-items': 'center',
            'justify-content': 'center',
            'padding': '13px 4px',
            'float': 'none',
            'width': 'auto'
        });
    }

    // Запускаємо одразу і через затримку (після рендеру)
    fixProfileIcons();
    setTimeout(fixProfileIcons, 300);
});