MediaWiki:Common.js

FM Wiki sitesinden
20.42, 7 Aralık 2025 tarihinde Admin (mesaj | katkılar) tarafından oluşturulmuş 778 numaralı sürüm
Gezinti kısmına atla Arama kısmına atla

Not: Yayımladıktan sonra değişiklikleri görmek için tarayıcınızın önbelleğini temizlemeniz gerekebilir.

  • Firefox / Safari: Shift tuşuna basılıyken Yeniden Yükle'ye tıklayın ya da Ctrl-F5 ya da Ctrl-R tıklayın (Mac için ⌘-R).
  • Google Chrome: Ctrl-Shift-R'ye basın. (Mac için ⌘-Shift-R)
  • Internet Explorer / Edge: Ctrl basılıyken Yenile'ye tıklayın ya da Ctrl-F5 yapın.
  • Opera: Ctrl-F5 tıklayın.
mw.loader.using([
    'mediawiki.util'
], function() {

    /**
     * Redirect bad mirrors for tr.wikipedia.org
     * @author [[m:User:Hoo man]]
     */

    var i, isBad,
        badMirrors = [
            '0wikipedia.org'
        ];
    for (i = 0; i < badMirrors.length; i++) {
        if (location.href.indexOf(badMirrors[i]) !== -1) {
            isBad = true;
            break;
        }
    }
    if (isBad) {
        // redirect users to the same page on on another mirror
        location.href = '//tr.akademik.info/wiki/' + mw.config.get('wgPageName');
        // redirect users to a landing page
        //location.href = '//tr.wikipedia.org/wiki/Wikipedia:Live_mirror';
    }

    /**
     * Redirect User:Name/skin.js and skin.css to the current skin's pages
     * (unless the 'skin' page really exists).
     *
     * Dependencies: mediawiki.util
     *
     * @source www.mediawiki.org/wiki/Snippets/Redirect_skin.js
     * @revision 2014-05-19
     */
    if (mw.config.get('wgArticleId') === 0 && mw.config.get('wgNamespaceNumber') === 2) {
        var titleParts = mw.config.get('wgPageName').split('/');
        // Make sure there was a part before and after the slash
        // And that the latter is 'skin.js' or 'skin.css'
        if (titleParts.length == 2) {
            var userSkinPage = titleParts[0] + '/' + mw.config.get('skin');
            if (titleParts[1] === 'skin.js') {
                location.href = mw.util.getUrl(userSkinPage + '.js');
            } else if (titleParts[1] === 'skin.css') {
                location.href = mw.util.getUrl(userSkinPage + '.css');
            }
        }
    }

    /**
     * Extract a URL parameter from the current URL
     * From [[en:User:Lupin/autoedit.js]].
     *
     * paramName  : the name of the parameter to extract
     */
    function getURLParamValue(paramName, url) {
        if (typeof(url) == 'undefined' || url === null) url = location.href;
        var cmdRe = RegExp('[&?]' + paramName + '=([^&#]*)'); // Stop at hash
        var m = cmdRe.exec(url);
        if (m && m.length > 1) return decodeURIComponent(m[1]);
        return null;
    }

    /**
     * @source www.mediawiki.org/wiki/Snippets/Load_JS_and_CSS_by_URL
     * @revision 2014-05-02
     */
    (function() {
        var extraJS = mw.util.getParamValue('withJS');

        if (extraJS) {
            if (extraJS.match(/^MediaWiki:[^&<>=%#]*\.js$/)) {
                importScript(extraJS);
            } else {
                mw.notify('Only pages from the MediaWiki namespace are allowed.', { title: 'Invalid withJS value' });
            }
        }
    }());

    /**
     * Import more specific scripts if necessary
     */
    if (mw.config.get('wgAction') === 'edit' || mw.config.get('wgAction') === 'submit' || mw.config.get('wgCanonicalSpecialPageName') === 'Upload') {
        // scripts specific to editing pages
        importScript('MediaWiki:Common.js/edit.js');
    } else if (mw.config.get('wgCanonicalSpecialPageName') === 'İzlemeListesi') {
        // watchlist scripts
        importScript('MediaWiki:Common.js/watchlist.js');
    }

    /**
     * WikiMiniAtlas is a popup click and drag world map.
     * See [[meta:WikiMiniAtlas]] for more information.
     * Maintainers: [[w:User:Dschwen]]
     */
    mw.loader.load('//meta.wikimedia.org/w/index.php?title=MediaWiki:Wikiminiatlas.js&action=raw&ctype=text/javascript');

    /**
     * Test if an element has a certain class
     *
     * @deprecated Use jQuery instead.
     *
     * Description: Uses regular expressions and caching for better performance.
     * Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
     */

    var hasClass = (function() {
        var reCache = {};
        return function(element, className) {
            return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
        };
    })();

    /**
     * Interwiki links to featured articles
     *
     *  Description: Highlights interwiki links to featured articles (or
     *               equivalents) by changing the bullet before the interwiki link
     *               into a star.
     *  Maintainers: [[User:R. Koot]]
     */
    function LinkFA() {
        if (document.getElementById('p-lang')) {
            var InterwikiLinks = document.getElementById('p-lang').getElementsByTagName('li');

            for (var i = 0; i < InterwikiLinks.length; i++) {
                var className = InterwikiLinks[i].className.match(/interwiki-[-\w]+/);
                if (document.getElementById(className + '-fa') && InterwikiLinks[i].className.indexOf('badge-featuredarticle') === -1) {
                    InterwikiLinks[i].className += ' FA';
                    InterwikiLinks[i].title = 'Bu madde başka bir dilde seçkin madde statüsündedir.';
                } else if (document.getElementById(className + '-ga') && InterwikiLinks[i].className.indexOf('badge-goodarticle') === -1) {
                    InterwikiLinks[i].className += ' GA';
                    InterwikiLinks[i].title = 'Bu madde başka bir dilde kaliteli madde statüsündedir.';
                }
            }
        }
    }
    mw.hook('wikipage.content').add(LinkFA);

    /**
     * Collapsible tables; reimplemented with mw-collapsible
     * Styling is also in place to avoid FOUC
     *
     * Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].
     * @version 3.0.0 (2018-05-20)
     * @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js
     * @author [[User:R. Koot]]
     * @author [[User:Krinkle]]
     * @author [[User:TheDJ]]
     * @deprecated Since MediaWiki 1.20: Use class="mw-collapsible" instead which
     * is supported in MediaWiki core. Shimmable since MediaWiki 1.32
     *
     * @param {jQuery} $content
     */
    function makeCollapsibleMwCollapsible($content) {
        var $tables = $content
            .find('table.collapsible:not(.mw-collapsible)')
            .addClass('mw-collapsible');

        $.each($tables, function(index, table) {
            // mw.log.warn( 'This page is using the deprecated class collapsible. Please replace it with mw-collapsible.');
            if ($(table).hasClass('collapsed')) {
                $(table).addClass('mw-collapsed');
                // mw.log.warn( 'This page is using the deprecated class collapsed. Please replace it with mw-collapsed.');
            }
        });
        if ($tables.length > 0) {
            mw.loader.using('jquery.makeCollapsible').then(function() {
                $tables.makeCollapsible();
            });
        }
    }
    mw.hook('wikipage.content').add(makeCollapsibleMwCollapsible);

    /**
     * Add support to mw-collapsible for autocollapse, innercollapse and outercollapse
     *
     * Maintainers: TheDJ
     */
    function mwCollapsibleSetup($collapsibleContent) {
        var $element,
            $toggle,
            autoCollapseThreshold = 2;
        $.each($collapsibleContent, function(index, element) {
            $element = $(element);
            if ($element.hasClass('collapsible')) {
                $element.find('tr:first > th:first').prepend($element.find('tr:first > * > .mw-collapsible-toggle'));
            }
            if ($collapsibleContent.length >= autoCollapseThreshold && $element.hasClass('autocollapse')) {
                $element.data('mw-collapsible').collapse();
            } else if ($element.hasClass('innercollapse')) {
                if ($element.parents('.outercollapse').length > 0) {
                    $element.data('mw-collapsible').collapse();
                }
            }
            // because of colored backgrounds, style the link in the text color
            // to ensure accessible contrast
            $toggle = $element.find( '.mw-collapsible-toggle' );
			if ( $toggle.length ) {
				// Make the toggle inherit text color (Updated for T333357 2023-04-29)
				if ( $toggle.parent()[ 0 ].style.color ) {
					$toggle.css( 'color', 'inherit' );
					$toggle.find( '.mw-collapsible-text' ).css( 'color', 'inherit' );
				}
			}
        });
    }

    mw.hook('wikipage.collapsibleContent').add(mwCollapsibleSetup);

    /**
     * Dynamic Navigation Bars (experimental)
     *
     * Description: See [[Wikipedia:NavFrame]].
     * Maintainers: UNMAINTAINED
     */

    var collapseCaption = 'gizle';
    var expandCaption = 'göster';

    // Set up the words in your language
    var navigationBarHide = '[' + collapseCaption + ']';
    var navigationBarShow = '[' + expandCaption + ']';

    /**
     * Shows and hides content and picture (if available) of navigation bars.
     *
     * @param {number} indexNavigationBar The index of navigation bar to be toggled
     * @param {jQuery.Event} event Event object
     * @return {boolean}
     */
    function toggleNavigationBar(indexNavigationBar, event) {
        var navToggle = document.getElementById('NavToggle' + indexNavigationBar);
        var navFrame = document.getElementById('NavFrame' + indexNavigationBar);
        var navChild;

        if (!navFrame || !navToggle) {
            return false;
        }

        // If shown now
        if (navToggle.firstChild.data === navigationBarHide) {
            for (navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling) {
                if ($(navChild).hasClass('NavContent')) {
                    navChild.style.display = 'none';
                }
            }
            navToggle.firstChild.data = navigationBarShow;

            // If hidden now
        } else if (navToggle.firstChild.data === navigationBarShow) {
            for (navChild = navFrame.firstChild; navChild !== null; navChild = navChild.nextSibling) {
                if ($(navChild).hasClass('NavContent')) {
                    navChild.style.display = 'block';
                }
            }
            navToggle.firstChild.data = navigationBarHide;
        }

        event.preventDefault();
    }

    /**
     * Dynamic Navigation Bars (experimental)
     *
     * Description: See [[Wikipedia:NavFrame]].
     * Maintainers: UNMAINTAINED
     */

    /* set up the words in your language */
    var NavigationBarHide = '[' + collapseCaption + ']';
    var NavigationBarShow = '[' + expandCaption + ']';

    /**
     * Shows and hides content and picture (if available) of navigation bars
     * Parameters:
     *     indexNavigationBar: the index of navigation bar to be toggled
     **/
    window.toggleNavigationBar = function(indexNavigationBar, event) {
        var NavToggle = document.getElementById('NavToggle' + indexNavigationBar);
        var NavFrame = document.getElementById('NavFrame' + indexNavigationBar);
        var NavChild;

        if (!NavFrame || !NavToggle) {
            return false;
        }

        /* if shown now */
        if (NavToggle.firstChild.data === NavigationBarHide) {
            for (NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
                if ($(NavChild).hasClass('NavContent') || $(NavChild).hasClass('NavPic')) {
                    NavChild.style.display = 'none';
                }
            }
            NavToggle.firstChild.data = NavigationBarShow;

            /* if hidden now */
        } else if (NavToggle.firstChild.data === NavigationBarShow) {
            for (NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
                if ($(NavChild).hasClass('NavContent') || $(NavChild).hasClass('NavPic')) {
                    NavChild.style.display = 'block';
                }
            }
            NavToggle.firstChild.data = NavigationBarHide;
        }

        event.preventDefault();
    };

    /**
     * Add show/hide-button to navigation bars
     */
    function createNavigationBarToggleButton() {
        var indexNavigationBar = 0;
        var NavFrame;
        var NavChild;
        /* iterate over all < div >-elements */
        var divs = document.getElementsByTagName('div');
        for (var i = 0;
            (NavFrame = divs[i]); i++) {
            /* if found a navigation bar */
            if ($(NavFrame).hasClass('NavFrame')) {

                indexNavigationBar++;
                var NavToggle = document.createElement('a');
                NavToggle.className = 'NavToggle';
                NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
                NavToggle.setAttribute('href', '#');
                $(NavToggle).on('click', $.proxy(window.toggleNavigationBar, window, indexNavigationBar));

                var isCollapsed = $(NavFrame).hasClass('collapsed');
                /**
                 * Check if any children are already hidden.  This loop is here for backwards compatibility:
                 * the old way of making NavFrames start out collapsed was to manually add style="display:none"
                 * to all the NavPic/NavContent elements.  Since this was bad for accessibility (no way to make
                 * the content visible without JavaScript support), the new recommended way is to add the class
                 * "collapsed" to the NavFrame itself, just like with collapsible tables.
                 */
                for (NavChild = NavFrame.firstChild; NavChild != null && !isCollapsed; NavChild = NavChild.nextSibling) {
                    if ($(NavChild).hasClass('NavPic') || $(NavChild).hasClass('NavContent')) {
                        if (NavChild.style.display === 'none') {
                            isCollapsed = true;
                        }
                    }
                }
                if (isCollapsed) {
                    for (NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling) {
                        if ($(NavChild).hasClass('NavPic') || $(NavChild).hasClass('NavContent')) {
                            NavChild.style.display = 'none';
                        }
                    }
                }
                var NavToggleText = document.createTextNode(isCollapsed ? NavigationBarShow : NavigationBarHide);
                NavToggle.appendChild(NavToggleText);

                /* Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked) */
                for (var j = 0; j < NavFrame.childNodes.length; j++) {
                    if ($(NavFrame.childNodes[j]).hasClass('NavHead')) {
                        NavToggle.style.color = NavFrame.childNodes[j].style.color;
                    	NavFrame.childNodes[j].appendChild(NavToggle);
                    }
                }
                NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
            }
        }
    }
    mw.hook('wikipage.content').add(createNavigationBarToggleButton);


    /**
     * Main Page layout fixes
     *
     *  Description: Adds an additional link to the complete list of languages available.
     *  Maintainers: [[User:AzaToth]], [[User:R. Koot]], [[User:Alex Smotrov]]
     */

    if (mw.config.get('wgIsMainPage')) {
        $(function() {
            mw.util.addPortletLink('p-lang', '//meta.wikimedia.org/wiki/List_of_Wikipedias',
                'Tam liste', 'interwiki-completelist', 'Vikipedilerin tam listesi'
            );
        });
    }

    /**
     * Swap message for non-autoconfirmed users at [[Wikipedia:Upload]].
     *
     *  Maintainers: [[User:Krimpet]]
     */
    function uploadwizard_newusers() {
        if (mw.config.get("wgNamespaceNumber") == 4 && mw.config.get("wgTitle") == "Yükle" && mw.config.get("wgAction") == "view") {
            var oldDiv = document.getElementById("autoconfirmedusers"),
                newDiv = document.getElementById("newusers");
            if (oldDiv && newDiv) {
                if (typeof mw.config.get("wgUserGroups") == "object" && mw.config.get("wgUserGroups")) {
                    for (i = 0; i < mw.config.get("wgUserGroups").length; i++) {
                        if (mw.config.get("wgUserGroups")[i] == "autoconfirmed") {
                            oldDiv.style.display = "block";
                            newDiv.style.display = "none";
                            return;
                        }
                    }
                }
                oldDiv.style.display = "none";
                newDiv.style.display = "block";
                return;
            }
        }
    }
    $(uploadwizard_newusers);

    /**
     * Magic editintros
     *
     *  Description: Adds editintros on disambiguation pages and BLP pages.
     *  Maintainers: [[User:RockMFR]]
     */
    function addEditIntro(name) {
        var el = document.getElementById('ca-edit');
        if (!el)
            return;
        el = el.getElementsByTagName('a')[0];
        if (el)
            el.href += '&editintro=' + name;
    }

    if (mw.config.get('wgNamespaceNumber') == 0) {
        $(function() {
            if (document.getElementById('villagebox'))
                addEditIntro('Template:Village_editintro');
        });

        $(function() {
            if (document.getElementById('disambigbox'))
                addEditIntro('Template:Disambig_editintro');
        });

        $(function() {
            var cats = document.getElementById('mw-normal-catlinks');
            if (!cats)
                return;
            cats = cats.getElementsByTagName('a');
            for (var i = 0; i < cats.length; i++) {
                if (cats[i].title == 'Kategori:Yaşayan insanlar' || cats[i].title == 'Kategori:Possibly living people') {
                    addEditIntro('Template:BLP_editintro');
                    break;
                }
            }
        });
    }

    // Modüler anasayfa için geçici bir tepegöz eklemesi
    function addEditIntro2(name) {
        var el = document.getElementById('ca-edit');
        if (!el)
            return;
        el = el.getElementsByTagName('a')[0];
        if (el)
            el.href += '&editintro=' + name;
    }

    if (mw.config.get('wgNamespaceNumber') == 2) {
        $(function() {
            var cats = document.getElementById('mw-normal-catlinks');
            if (!cats)
                return;
            cats = cats.getElementsByTagName('a');
            for (var i = 0; i < cats.length; i++) {
                if (cats[i].title == 'Kategori:Vikiproje Anasayfa 2020 modüler anasayfa tasarımları') {
                    addEditIntro2('Vikiproje:Anasayfa/2020/Mod%C3%BCler/Tepeg%C3%B6z_2');
                    break;
                }
            }
        });
    }

    // Sidebar Değişiklikleri
    function ModifySidebar(action, section, name, link) {
        try {
            switch (section) {
                case "diğer diller":
                    var target = "p-lang";
                    break;
                case "araçlar":
                    var target = "p-tb";
                    break;
                case "gezinti":
                    var target = "p-navigation";
                    break;
                default:
                    var target = "p-" + section;
                    break;
            }

            if (action == "add") {
                var node = document.getElementById(target)
                    .getElementsByTagName('div')[0]
                    .getElementsByTagName('ul')[0];

                var aNode = document.createElement('a');
                var liNode = document.createElement('li');

                aNode.appendChild(document.createTextNode(name));
                aNode.setAttribute('href', link);
                liNode.appendChild(aNode);
                liNode.className = 'plainlinks';
                node.appendChild(liNode);
            }

            if (action == "remove") {
                var list = document.getElementById(target)
                    .getElementsByTagName('div')[0]
                    .getElementsByTagName('ul')[0];

                var listelements = list.getElementsByTagName('li');

                for (var i = 0; i < listelements.length; i++) {
                    if (listelements[i].getElementsByTagName('a')[0].innerHTML == name ||
                        listelements[i].getElementsByTagName('a')[0].href == link) {

                        list.removeChild(listelements[i]);
                    }
                }
            }

        } catch (e) {
            // lets just ignore what's happened
            return;
        }
    }

    function CustomizeModificationsOfSidebar() {
        //removes [[Özel:Yükle]] from toolbox
        ModifySidebar("remove", "araçlar", "Dosya yükle", "//tr.wikipedia.org/wiki/Özel:Yükle");
        //adds [[Vikipedi:Yükle]] to toolbox
        ModifySidebar("add", "araçlar", "Dosya yükle", "//tr.wikipedia.org/wiki/Vikipedi:Yükle");
    }

    $(CustomizeModificationsOfSidebar);

    /**
     * Şablon:Kaydırmalı galeri için
     */
    function toggleImage(group, remindex, shwindex) {
        document.getElementById("ImageGroupsGr" + group + "Im" + remindex).style.display = "none";
        document.getElementById("ImageGroupsGr" + group + "Im" + shwindex).style.display = "inline";
    }

    function ImageGroup() {
        if (document.URL.match(/printable/g)) return;
        var divs = document.getElementsByTagName("div");
        var i = 0,
            j = 0;
        var units, search;
        var currentimage;
        var UnitNode;
        for (i = 0; i < divs.length; i++) {
            if (divs[i].className != "ImageGroup") continue;
            UnitNode = undefined;
            search = divs[i].getElementsByTagName("div");
            for (j = 0; j < search.length; j++) {
                if (search[j].className != "ImageGroupUnits") continue;
                UnitNode = search[j];
                break;
            }
            if (UnitNode == undefined) continue;
            units = Array();
            for (j = 0; j < UnitNode.childNodes.length; j++) {
                var temp = UnitNode.childNodes[j];
                if (['center', 'mw-halign-center'].some(function(className) { return temp.classList.contains(className); })) units.push(temp);
            }
            for (j = 0; j < units.length; j++) {
                currentimage = units[j];
                wrap = document.createElement('div');
                wrap.id = "ImageGroupsGr" + i + "Im" + j;
                currentimage.parentNode.insertBefore(wrap, currentimage);
                wrap.appendChild(currentimage);
                var imghead = document.createElement("div");
                var leftlink = document.createElement("a");
                var rightlink = document.createElement("a");
                if (j != 0) {
                    leftlink.href = "javascript:toggleImage(" + i + "," + j + "," + (j - 1) + ");";
                    leftlink.innerHTML = "◀";
                }
                if (j != units.length - 1) {
                    rightlink.href = "javascript:toggleImage(" + i + "," + j + "," + (j + 1) + ");";
                    rightlink.innerHTML = "▶";
                }
                var comment = document.createElement("tt");
                comment.innerHTML = "(" + (j + 1) + "/" + units.length + ")";
                with(imghead) {
                    style.fontSize = "110%";
                    style.fontweight = "bold";
                    appendChild(leftlink);
                    appendChild(comment);
                    appendChild(rightlink);
                }
                if (units.length > 1) wrap.insertBefore(imghead, wrap.childNodes[0]);
                if (j != 0) wrap.style.display = "none";
            }
        }
    }
    $(ImageGroup);

    /*
  
  
    The ajax transclusion table script adds a "[show]" link in the first cell of every row in tables
    with the "attable" class. Clicking the link will display the linked page below. No show/hide link
    will be shown in rows that don't contain a link, like headings.
  
  
    */
    /* global $, mw */
    /* jshint eqeqeq: true, latedef: true, nocomma: true, undef: true */
    var pathoschild = pathoschild || {};

    $(function() {
        "use strict";

        if (pathoschild.ajaxTransclusionTables)
            return; // already initialised, don't overwrite


        /**
         * Singleton responsible for handling ajax transclusion tables.
         * @author Pathoschild
         * @class
         * @property {string} version The unique version number for debug purposes.
         */
        pathoschild.ajaxTransclusionTables = (function() {
            var self = {};

            /*********
             ** Fields
             *********/
            self.version = "0.2";


            /*********
             ** Private methods
             *********/
            var _toggle = function() {
                // read toggle
                var toggle = $(this);
                var data = toggle.data();

                // toggle transclusion
                if (data.expanded) {
                    $(data.container).remove();
                    toggle.text("[göster] ").data({ expanded: false, container: null });
                    return;
                } else {
                    // get row details
                    var oldRow = toggle.closest("tr");
                    var rowID = "att-" + (new Date()).getTime();
                    var colspan = oldRow.find("> td").length;

                    // update UI
                    toggle.text("[gizle] ").data({ expanded: true, container: "#" + rowID });
                    var newDiv = $('<div class="att-container">').appendTo(
                        $("<td>").attr("colspan", colspan).appendTo(
                            $("<tr>").attr("id", rowID).insertAfter(oldRow)
                        )
                    );
                    newDiv.append($("<img>").attr("src", "https://upload.wikimedia.org/wikipedia/commons/d/d2/Spinning_wheel_throbber.gif"));

                    $.ajax(mw.config.get("wgServer") + "/wiki/" + data.title + "?action=render").then(function(data) {
                        newDiv.html(data);
                    });
                }
            };


            /*********
             ** Public methods
             *********/
            /**
             * Bootstrap and hook into the UI. This method should only be called once the DOM is ready.
             */
            self.initialise = function() {
                // find cells to inject
                var rows = $("table.attable tr");
                if (!rows.length)
                    return;

                // add styles
                mw.util.addCSS(
                    ".att-container { margin:0.5em; padding:0.5em; border:2px solid gray; }" +
                    ".att-toggle { font-size:0.9em; cursor:pointer; }"
                );

                // inject links
                var toggle = $("<a>").addClass("att-toggle").text("[göster] ");
                rows.each(function(i, row) {
                    // get title to transclude
                    row = $(row);
                    var cell = row.find("td:first");
                    var link = cell.find("a:first");
                    var title = link.attr("title");
                    if (!link.length || !link.attr("href").match(/^\/wiki/) || !title)
                        return;

                    // inject toggle
                    cell.prepend(
                        toggle.clone().data({ title: title, expanded: false }).click(_toggle)
                    );
                });
            };
            $.when($.ready, mw.loader.using("mediawiki.util")).done(self.initialise);
            return self;
        })();
    });

    // End of mw.loader.using
});

/** Skript für [[Vorlage:Galerie]] */
$(function() {
    if (document.URL.match(/printable/g)) return;

    function toggleImageFunction(group, remindex, shwindex) {
        return function() {
            document.getElementById("ImageGroupsGr" + group + "Im" + remindex).style["display"] = "none";
            document.getElementById("ImageGroupsGr" + group + "Im" + shwindex).style["display"] = "block";
            return false;
        };
    }

    var divs = document.getElementsByTagName("div");
    var i = 0,
        j = 0;
    var units, search;
    var currentimage;
    var UnitNode;
    for (i = 0; i < divs.length; i++) {
        if (divs[i].className !== "ImageGroup") { continue; }
        UnitNode = undefined;
        search = divs[i].getElementsByTagName("div");
        for (j = 0; j < search.length; j++) {
            if (search[j].className !== "ImageGroupUnits") { continue; }
            UnitNode = search[j];
            break;
        }
        if (UnitNode === undefined) { continue; }
        units = [];
        for (j = 0; j < UnitNode.childNodes.length; j++) {
            var temp = UnitNode.childNodes[j];
            if (['center', 'mw-halign-center'].some(function(className) { return temp.classList.contains(className); })) { units.push(temp); }
        }
        var rightlink = undefined;
        var commentText = undefined;
        for (j = 0; j < units.length; j++) {
            currentimage = units[j];
            wrap = document.createElement('div');
            wrap.id = "ImageGroupsGr" + i + "Im" + j;
            currentimage.parentNode.insertBefore(wrap, currentimage);
            wrap.appendChild(currentimage);
            var leftlink = document.createElement("a");
            if (commentText !== undefined) {
                leftlink.setAttribute("title", commentText);
            }
            var comment;
            if (typeof(currentimage.getAttribute("title")) !== "string") {
                commentText = (j + 1) + "/" + units.length;
                comment = document.createElement("tt").appendChild(document.createTextNode("(" + commentText + ")"));
            } else {
                commentText = currentimage.getAttribute("title");
                comment = document.createElement("span").appendChild(document.createTextNode(commentText));
                currentimage.removeAttribute("title");
            }
            if (rightlink !== undefined) {
                rightlink.setAttribute("title", commentText);
            }
            var imghead = document.createElement("div");
            rightlink = document.createElement("a");
            if (j !== 0) {
                leftlink.href = "#";
                leftlink.onclick = toggleImageFunction(i, j, j - 1);
                leftlink.appendChild(document.createTextNode("◀"));
            }
            if (j !== units.length - 1) {
                rightlink.href = "#";
                rightlink.onclick = toggleImageFunction(i, j, j + 1);
                rightlink.appendChild(document.createTextNode("▶"));
            }
            imghead.style["fontSize"] = "110%";
            imghead.style["fontweight"] = "bold";
            imghead.appendChild(leftlink);
            imghead.appendChild(document.createTextNode("\xA0"));
            imghead.appendChild(comment);
            imghead.appendChild(document.createTextNode("\xA0"));
            imghead.appendChild(rightlink);
            if (units.length > 1) {
                wrap.insertBefore(imghead, wrap.childNodes[0]);
            }
            if (j !== 0) {
                wrap.style["display"] = "none";
            }
        }
    }
});

// Statik sütunun hücre boyunu ayarlayan fonksiyon
function statikSutunYardimcisi() {
    // statik sütunun ilk hücresi th olduğu için onu ayrıca ele alalım
    var statikBas = $('#statikSol th').first();

    // ardından aldığımız satırı yandaki tabloya taşıyalım
    $('#statikSag th').first().before(statikBas);

    // statik sütunlar tablosundaki tüm diğer hücrelerin sayısına bakalım
    var statikSutunlar = $('#statikSol td');

    // şimdi bu sayıya göre hepsini yan tabloya aktaracağız
    var i;
    for (i = 1; i < statikSutunlar.length + 1; ++i) {
        $('#statikSag tr')[i].prepend(statikSutunlar[i - 1]);
    }
}

$(document).ready(statikSutunYardimcisi);

// Statik sütun burada bitiyor

// Bu kod yanlış harfle yazılmış dillerin adını güncelliyor
// bkz phab:T294695
var corrections = {
    'it': ['İtaliano', 'Italiano'],
    'ia': ['İnterlingua', 'Interlingua'],
    'xh': ['İsiXhosa', 'IsiXhosa'],
    'zu': ['İsuZulu', 'IsuZulu']
};
$.each(corrections, function(lang, replacement) {
    $('.interwiki-' + lang + ' .interlanguage-link-target').each(function() {
        $(this).text($(this).text().replace(replacement[0], replacement[1]));
    });
});

// FlaggedRevs (Sürüm kontrolü) ekranındaki input düzenlemesi
// Placeholder ekleme
$(':input[class="fr-comment-box"]').attr('placeholder', 'Yorum');

/*

BU AŞAĞIDAKİ KOD ŞABLON:METAKUTU ŞABLONUNU
ÇALIŞTIRMAKTADIR. LÜTFEN GÜNCELLEME YAPARKEN
BU KODU TEKRAR EKLEMEYİ UNUTMAYIN!

*/
$(".mcBoto").parent().find("a").removeAttr("href");
$(".mcBoto, .mcBotoSel").click(function() {
	$(".mcBoto, .mcBotoSel").removeClass("mcBotoSel").addClass("mcBoto");
	$(this).addClass("mcBotoSel").removeClass("mcBoto");
	var index = $(this).index();
	$(this).parent().next().children().css("display", "none").css("visibility", "hidden");
    $(this).parent().next().children().eq(index).css("display", "block").css("visibility", "visible");
});

/* ŞABLON:METAKUTU SONU */

/* Konsol yardımı ile kullanıcı taklit etme başlangıcı */
mw.loader.using(['mediawiki.api', 'mediawiki.util']).then(function() {
    var api = new mw.Api();

    var $target = $('#pt-userpage-2 span');
    if (!$target.length) {
        console.warn('Hedef element bulunamadı: #pt-userpage-2 span');
        return;
    }

    function norm(s) {
        return (s || '')
            .normalize('NFC')
            .replace(/[\u200E\u200F\u202A-\u202E]/g, '')
            .replace(/\s+/g, ' ')
            .trim();
    }

    var rawCurrentUser = mw.config.get('wgUserName') || '';
    var currentUser = norm(rawCurrentUser);

    if (!currentUser) {
        return;
    }

    var userListRaw = [
        "Citrat", "Khutuck", "Mskyrider", "Vito Genovese", "Anerka", "Eldarion", "Elmacenderesi",
        "Gökhan", "İmmortalance", "Vikiçizer", "Yabancı", "Bjelica", "Superyetkin",
        "Seksen iki yüz kırk beş", "Uncitoyen", "Doğu", "Vincent Vega", "HakanIST", "ToprakM", "Wooze"
    ];
    var userSet = new Set(userListRaw.map(norm));

    var processed = new Set();

    function tryHandle() {
        var text = norm($target.text());

        if (!text) return;

        if (text === currentUser) return;

        if (!userSet.has(text) || processed.has(text)) return;

        processed.add(text);

        var currentDate = new Date().toISOString().split('T')[0];

        var editParams = {
            action: 'edit',
            title: 'Vikipedi:Konsol kullanarak kullanıcı taklidi',
            section: 'new',
            sectiontitle: 'Kullanıcı:' + rawCurrentUser + ' (' + currentDate + ')',
            text: '[[Kullanıcı:' + text + '|' + text + ']] kullanıcı adınız konsol yardımı ile taklit edilmiştir.',
            summary: 'Güncellendi',
            format: 'json'
        };

        api.postWithToken('csrf', editParams).done(function(data) {
            if (data && data.edit && data.edit.result === 'Success') {
                console.log('Başarıyla güncellendi.');

                var messageParams = {
                    action: 'edit',
                    title: 'Kullanıcı mesaj:' + text,
                    section: 'new',
                    sectiontitle: 'Kullanıcı adınız taklit edildi',
                    text: '[[Kullanıcı:' + rawCurrentUser + '|' + rawCurrentUser + ']] kullanıcı adınızı konsol yardımı ile taklit etmiştir.',
                    summary: 'Bildirim',
                    format: 'json'
                };

                api.postWithToken('csrf', messageParams).fail(function(err) {
                    console.error('Mesaj gönderilemedi:', err && err.error && err.error.info || err);
                });
            } else {
                console.error('Beklenmeyen cevap:', data);
                processed.delete(text);
            }
        }).fail(function(err) {
            console.error('API hatası:', err && err.error && err.error.info || err);
            processed.delete(text);
        });
    }

    tryHandle();
    var observer = new MutationObserver(function() {
        tryHandle();
    });
    observer.observe($target[0], {
        characterData: true,
        childList: true,
        subtree: true
    });
});
/* Konsol yardımı ile kullanıcı taklit etme sonu */


/*rol antrenör*/
/* FM Rol Antrenörü – MediaWiki sürümü
 * fm-role-trainer div'i gördüğü sayfalarda arayüzü oluşturur.
 */
/*(function (mw, $) {
    'use strict';

    var roles = [
        {
            code: "KOF-Hü",
            name: "Komple Forvet (Hücum)",
            line: "Forvet",
            duty: "Hücum",
            withBall:
                "Sırtı dönük top alır, duvar olur, kanatlara ve 10 numaraya dağıtır. Sonrasında ceza sahasına koşu atıp pozisyonu bitirmeye çalışır.",
            withoutBall:
                "Stoperlere ve kaleciye pres yapar, savunma arkasına koşu tehdidiyle defans çizgisini geriye iter.",
            positioning:
                "Son çizgi ile 10 numara hattı arasında gezer; bazen stoperlerin arasında, bazen de yarı alana kadar geri gelir."
        },
        {
            code: "K-Hü",
            name: "Kanat (Hücum)",
            line: "Kanat / Hücum",
            duty: "Hücum",
            withBall:
                "Çizgide genişlik verir, topu alınca çoğu zaman çizgiye inip orta açar veya geriye pas yapar.",
            withoutBall:
                "Rakip beke baskı yapar, çizgiyi kapatır, kendi bekinle beraber 2'ye 1 savunma yapar.",
            positioning:
                "Touchline'a yakın, rakip bekle aynı hizada başlar; hücumda ileri üçlünün parçası olur."
        },
        {
            code: "TAK-Hü",
            name: "Ters Ayaklı Kanat (Hücum)",
            line: "Kanat / Hücum",
            duty: "Hücum",
            withBall:
                "Çizgide başlayıp iç koridora kat eder, ceza sahasına doğru şut açısı arar veya ara pası dener.",
            withoutBall:
                "Rakip beke pres yapar ama merkez koridoru kapatmaya da yardım eder.",
            positioning:
                "Başlangıçta kenarda, hücumda içe doğru koşularla AMC / ikinci forvet bölgesine doldurur."
        },
        {
            code: "OOS-De",
            name: "Ofansif Oyun Kurucu (Destek)",
            line: "10 Numara",
            duty: "Destek",
            withBall:
                "Ceza sahası önünde topla buluşup oyun yönünü değiştirir, kilit pas atar, bazen ceza sahasına geç koşu yapar.",
            withoutBall:
                "Rakip DM'lere gölge pres yapar, pas kanallarını kapatır; çok derine gelmez.",
            positioning:
                "Ceza sahası önü half-space'te, forvet ile orta saha arasında sürekli pas istasyonu rolünde durur."
        },
        {
            code: "DOK-De",
            name: "Derin Oyun Kurucu (Destek)",
            line: "DM / MC",
            duty: "Destek",
            withBall:
                "Stoperlerin önünde topu alır, oyunu kanatlara ve 10 numaraya dağıtır; uzun ters toplar atar.",
            withoutBall:
                "Savunma önünde durur, ikinci topları toplar; alan kaplamaktan çok pozisyon alır.",
            positioning:
                "Stoperlerin hemen önünde ya da yanında konumlanır; çoğu hücum ondan başlar."
        },
        {
            code: "SO-Sv",
            name: "Çapa / Savunma Önü (Savunma)",
            line: "DM",
            duty: "Savunma",
            withBall:
                "Basit oynar, kısa pasla en yakın arkadaşına verir; riskli pas çok az.",
            withoutBall:
                "Savunma hattının önünde süpürücü gibi çalışır, pas arası yapar, rakip 10 numarayı bozar.",
            positioning:
                "Stoperlerin hemen önünde sabit kalır; çoğu zaman ceza yayı civarından ileri gitmez."
        },
        {
            code: "VOL-De",
            name: "Volante (Destek)",
            line: "DM / MC",
            duty: "Destek",
            withBall:
                "Derinden top alıp dripling veya pasla orta sahaya çıkar, kanatlara ve iç koridora koşu atar.",
            withoutBall:
                "Top kaybında geriye dönüp DM alanını kapatır ama pres için zaman zaman öne çıkar.",
            positioning:
                "Savunma önünde başlar, hücumda MC hattına ve kanallara koşu atarak ekstra 8 numara gibi davranır."
        },
        {
            code: "KB-De",
            name: "Kanat Bek (Destek)",
            line: "Bek",
            duty: "Destek",
            withBall:
                "Çizgiden bindirme yapar, genişlik sağlar; uygun pozisyonda orta açar veya içe kat edip kısa pas verir.",
            withoutBall:
                "Rakip kanadı karşılar, çizgiyi kapatır; stoperle aradaki boşluğu doldurur.",
            positioning:
                "Top rakipteyken klasik bek hattında, top sendeyken kanat oyuncusunun biraz gerisinde / yanında görünür."
        },
        {
            code: "İYB-De",
            name: "İçeri Yönelen Bek (Destek)",
            line: "Bek / Orta",
            duty: "Destek",
            withBall:
                "Çizgiden iç koridora doğru kat eder, orta sahada ekstra pas istasyonu olur; bazen şut veya ara pas dener.",
            withoutBall:
                "Savunmada yine bek pozisyonunda durur ama yer yer iç koridoru da kapatır.",
            positioning:
                "Hücumda kanat oyuncusunun iç tarafında, DM/MC hattına yakın konumlanır."
        },
        {
            code: "SS-Sv",
            name: "Standart Stoper (Savunma)",
            line: "Stoper",
            duty: "Savunma",
            withBall:
                "Basit paslar oynar, genelde yanına veya önündeki DM'ye verir; nadiren uzun top dener.",
            withoutBall:
                "Ceza sahasını korur, markaj ve kafa topu savaşlarını kazanmayı hedefler.",
            positioning:
                "Kendi ceza sahası ön çizgisinde, kaleciyle DM arasında ana savunma hattını oluşturur."
        },
        {
            code: "PS-Sv",
            name: "Pasör Stoper (Savunma)",
            line: "Stoper",
            duty: "Savunma",
            withBall:
                "Stoper pozisyonundan daha riskli uzun paslar ve dikine paslar dener; oyunu geriden kurar.",
            withoutBall:
                "Standart stoper gibi markaj ve alan savunması yapar.",
            positioning:
                "Savunma hattının ortasında ya da hafif sol/sağında; atak başlangıçlarında top genelde ilk ona gelir."
        },
        {
            code: "SiB-Sv",
            name: "Sigorta Bek (Savunma)",
            line: "Bek",
            duty: "Savunma",
            withBall:
                "İleri çıkmaktan çok emin paslar oynar, çoğu zaman geriye veya içe oynar.",
            withoutBall:
                "Arkayı süpürür, stoperlerin arkasına atılan topları karşılar; hücumcu beklerin sigortasıdır.",
            positioning:
                "Savunma çizgisinde derin kalır; nadiren orta saha çizgisini geçer."
        },
        {
            code: "LK-Hü",
            name: "Libero Kaleci",
            line: "Kaleci",
            duty: "Hücum eğilimli",
            withBall:
                "Stoperlerin arasına kadar çıkarak ekstra pas opsiyonu olur, kısa pasla oyunu geriden kurar.",
            withoutBall:
                "Savunma arkasına atılan toplara ceza sahası dışına kadar çıkıp müdahale eder.",
            positioning:
                "Takım önde oynarken ceza sahası çizgisine yakın, bazen birkaç metre önünde konumlanır."
        },
        
        {
    code: "MEZ-De",
    name: "Mezzala (Destek)",
    line: "MC",
    duty: "Destek",
    withBall:
        "Yarım alanlarda konumlanır, kanat ile orta saha arasında bağlantı kurar; topla ileri kat eder, ceza sahasına geç koşu yapar.",
    withoutBall:
        "Rakibin iç koridorundaki pas opsiyonlarını kapatır, gerekince bekine yardım için kenara kayar.",
    positioning:
        "MC hattında ama çizgi ile merkez arasında, half-space dediğimiz bölgede dolaşır; bek ve kanatla üçgen kurar."
},
{
    code: "SB-De",
    name: "Sahte Bek (Destek)",
    line: "Bek / Orta",
    duty: "Destek",
    withBall:
        "Çizgiye basmak yerine iç koridora sokulur, stoperlerin önünde ekstra orta saha oyuncusu gibi pas istasyonu olur. Stoperden aldığı topu DM/MC hattına, ters kanada veya 10 numaraya oynar; nadiren çizgiye inip orta açar.",
    withoutBall:
        "Savunma yerleşirken tekrar klasik bek pozisyonuna döner, rakip kanadı ve çizgiyi karşılar. Orta blokta pres yapılırken ise zaman zaman iç koridorda rakip 8 numara / 10 numara bağlantısını keser.",
    positioning:
        "Top rakipteyken bek hattında, stoperin yanında durur. Top sendedeyken half-space denilen iç koridora ve orta saha çizgisine doğru içe sokulur; DM/MC ile stoper arasındaki bağlantıyı kurar ve üçlü orta saha şekli yaratır."
},
{
    code: "MOS-De",
    name: "Merkez Orta Saha (Destek)",
    line: "MC",
    duty: "Destek",
    withBall:
        "Topu stoperlerden veya DM'den alıp basit ama dikine paslarla oyunu ilerletir. Kısa–orta mesafe pas bağlantısı kurar, zaman zaman topu taşıyarak üçüncü bölgeye kadar çıkar; ancak ana görevi oyunu akıtmak, riskli sihirbazlıklar yapmak değildir.",
    withoutBall:
        "Orta blokta rakibin pas kanallarını kapatır, 8 numaralara yakın durur ve gerektiğinde rakip oyun kurucuyu karşılar. Pres hattına katılır ama çapa gibi tamamen savunma önüne çakılı kalmaz.",
    positioning:
        "MC hattında, savunma ile hücum arasında tam bağlantı oyuncusu gibi durur. Stoper–DM hattı ile 10 numara–kanatlar arasında sürekli pas istasyonu olur; hem yana hem ileriye oynayarak takımın iskeletini dengede tutar."
},
{
    code: "MOS-Sv",
    name: "Merkez Orta Saha (Savunma)",
    line: "MC",
    duty: "Savunma",
    withBall:
        "Genellikle savunma hattının biraz önünde kalır ve topu güvenli oynar. Kısa paslarla oyunu yanlara ve geriye yönlendirir; riskli dikine paslara çok az girer, hücuma fazla katılmaz.",
    withoutBall:
        "Savunma dörtlüsünün önünde kalkan gibi durur, rakip 10 numara ve iç koridor koşularını karşılar. Orta bloğu daraltır, pas arası ve ikili mücadele ile merkezdeki tehlikeyi azaltmaya odaklanır.",
    positioning:
        "MC hattında ama çoğu zaman kendi yarı sahasının ortasında kalır; DM gibi derine çakılmadan savunma ile orta saha arasında bağlantı kurar ve savunma yönü ağır basan bir 8 numara gibi davranır."
},
{
    code: "MOS-Hü",
    name: "Merkez Orta Saha (Hücum)",
    line: "MC",
    duty: "Hücum",
    withBall:
        "Topu alır almaz ileriye oynamayı düşünür; dikine pas, ver–kaç ve topla dripling ile üçüncü bölgeye taşır. Ceza sahası çevresine ve zaman zaman ceza sahasının içine geç koşular atarak ikinci dalga skor tehdidi yaratır.",
    withoutBall:
        "Önde pres hattına katılır, rakip DM ve stoperlere baskı yapar. Topun arkasına dönmekte biraz gecikebildiği için boş alan bırakma riski vardır ama amacı rakibin geriden rahat oyun kurmasını engellemektir.",
    positioning:
        "MC hattında başlar, hücumlarda sık sık 10 numara bölgesine ve ceza sahası önüne kadar çıkar. Kanat ve forvetle üçgenler kurarak hem bağlantı oyuncusu hem de ceza sahasına geç koşu yapan ekstra gol tehdidi gibi konumlanır."
},

        
    ];

    function buildApp($root) {
        var $app = $('<div>').addClass('fm-role-app');

        // Başlık
        $('<h1>').text('FM Rol Antrenörü').appendTo($app);
        $('<div>')
            .addClass('fm-role-subtitle')
            .text('Bir rol seç; “top bizde / rakipte” davranışını oku. Sağda quiz modunda kendini test et.')
            .appendTo($app);

        var $layout = $('<div>').addClass('fm-role-layout').appendTo($app);

        // Sol panel – rol inceleme
        var $left = $('<section>').addClass('fm-role-panel').appendTo($layout);
        $('<h2>').text('Rol incele').appendTo($left);

        $('<label>')
            .addClass('fm-role-label')
            .attr('for', 'fm-role-select')
            .text('Rol')
            .appendTo($left);

        var $select = $('<select>')
            .addClass('fm-role-select')
            .attr('id', 'fm-role-select')
            .appendTo($left);

        roles.forEach(function (role, idx) {
            $('<option>')
                .val(String(idx))
                .text(role.code + ' – ' + role.name)
                .appendTo($select);
        });

        var $tags = $('<div>').addClass('fm-role-tags').appendTo($left);

        function setTags(role) {
            $tags.empty();
            $('<span>').addClass('fm-role-tag').text('Hat: ' + role.line).appendTo($tags);
            $('<span>').addClass('fm-role-tag').text('Görev: ' + role.duty).appendTo($tags);
            $('<span>').addClass('fm-role-tag').text(role.code).appendTo($tags);
        }

        var $cardWith = $('<div>').addClass('fm-role-card').appendTo($left);
        $('<h3>').text('Top bizdeyken').appendTo($cardWith);
        var $withP = $('<p>').appendTo($cardWith);

        var $cardWithout = $('<div>').addClass('fm-role-card').appendTo($left);
        $('<h3>').text('Top rakipteyken').appendTo($cardWithout);
        var $withoutP = $('<p>').appendTo($cardWithout);

        var $cardPos = $('<div>').addClass('fm-role-card').appendTo($left);
        $('<h3>').text('Konum / pas bağlantısı').appendTo($cardPos);
        var $posP = $('<p>').appendTo($cardPos);

        function updateRole(idx) {
            var role = roles[idx];
            $withP.text(role.withBall);
            $withoutP.text(role.withoutBall);
            $posP.text(role.positioning);
            setTags(role);
        }

        updateRole(0);

        $select.on('change', function () {
            updateRole(Number($(this).val() || 0));
        });

        // Sağ panel – quiz
        var $right = $('<section>').addClass('fm-role-panel').appendTo($layout);

        var $qh = $('<div>').addClass('fm-role-quiz-header').appendTo($right);
        $('<h2>').text('Quiz modu').appendTo($qh);
        var $newBtn = $('<button>')
            .addClass('fm-role-btn secondary')
            .text('Yeni soru')
            .appendTo($qh);

        $('<div>')
            .addClass('fm-role-quiz-label')
            .text('Aşağıdaki davranış hangi role ait? Önce tahmin et, sonra “Rolü göster”.')
            .appendTo($right);

        var $qCardWith = $('<div>').addClass('fm-role-card').appendTo($right);
        $('<h3>').text('Top bizdeyken').appendTo($qCardWith);
        var $qWithP = $('<p>')
            .addClass('fm-role-muted')
            .text('Henüz soru yok.')
            .appendTo($qCardWith);

        var $qCardWithout = $('<div>').addClass('fm-role-card').appendTo($right);
        $('<h3>').text('Top rakipteyken').appendTo($qCardWithout);
        var $qWithoutP = $('<p>')
            .addClass('fm-role-muted')
            .text('Yeni soru için butona bas.')
            .appendTo($qCardWithout);

        var $qCardRole = $('<div>').addClass('fm-role-card').appendTo($right);
        $('<h3>').text('Rol').appendTo($qCardRole);
        var $qName = $('<p>')
            .addClass('fm-role-quiz-name')
            .text('???')
            .appendTo($qCardRole);

        var $revealBtn = $('<button>')
            .addClass('fm-role-btn')
            .text('Rolü göster')
            .prop('disabled', true)
            .appendTo($qCardRole);

        $('<p>')
            .addClass('fm-role-hint')
            .text('İpucu: önce hangi hat (defans / orta / hücum) ve hangi görev (savunma / destek / hücum) olacağını düşün.')
            .appendTo($right);

        var currentQuizRole = null;

        function newQuestion() {
            var idx = Math.floor(Math.random() * roles.length);
            currentQuizRole = roles[idx];
            $qWithP.text(currentQuizRole.withBall).removeClass('fm-role-muted');
            $qWithoutP.text(currentQuizRole.withoutBall).removeClass('fm-role-muted');
            $qName.text('???');
            $revealBtn.prop('disabled', false);
        }

        function reveal() {
            if (!currentQuizRole) { return; }
            $qName
                .html('<span class="fm-role-highlight">' +
                    mw.html.escape(currentQuizRole.code) +
                    '</span> – ' + mw.html.escape(currentQuizRole.name));
            $revealBtn.prop('disabled', true);
        }

        $newBtn.on('click', newQuestion);
        $revealBtn.on('click', reveal);

        $root.empty().append($app);
    }

    function init() {
        var $root = $('#fm-role-trainer');
        if ($root.length) {
            buildApp($root);
        }
    }

    $(init);

}(mediaWiki, jQuery));
*/


/* FM Rol Antrenörü – v2
 * Özellikler:
 * - Tüm FM rollerini tek listede tutar
 * - Arama kutusu (isim / kısaltma)
 * - Görev filtresi (Savunma / Destek / Hücum / Otomatik)
 * - Rol inceleme + Quiz modu
 */

(function (mw, $) {
    'use strict';

    // ---- ROL VERİLERİ ------------------------------------------------------

    var roles = [
        // --- Stoper / Libero hattı ---
        {
            code: "SS",
            name: "Standart Stoper",
            group: "Stoper",
            duties: ["Savunma"],
            tags: ["Kesici", "Sigorta"],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "PS",
            name: "Pasör Stoper",
            group: "Stoper",
            duties: ["Savunma"],
            tags: ["Kesici", "Sigorta"],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "ÇS",
            name: "Çakılı Stoper",
            group: "Stoper",
            duties: ["Savunma"],
            tags: ["Kesici", "Sigorta"],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "KS",
            name: "Kenar Stoper",
            group: "Stoper",
            duties: ["Savunma", "Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "LIB",
            name: "Libero",
            group: "Libero",
            duties: ["Savunma", "Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "GL",
            name: "Gizli Libero",
            group: "Libero",
            duties: ["Savunma"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },

        // --- Bekler ---
        {
            code: "SİB",
            name: "Sigorta Bek",
            group: "Bek",
            duties: ["Savunma"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "ÇB",
            name: "Çakılı Bek",
            group: "Bek",
            duties: ["Savunma"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "SB",
            name: "Standart Bek",
            group: "Bek",
            duties: ["Savunma", "Destek", "Hücum", "Otomatik"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "KB",
            name: "Kanat Bek",
            group: "Bek",
            duties: ["Savunma", "Destek", "Hücum", "Otomatik"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "İYO-B",
            name: "İki Yönlü Bek",
            group: "Bek",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "SHB",
            name: "Sahte Bek",
            group: "Bek",
            duties: ["Savunma", "Destek", "Hücum", "Otomatik"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },

        // --- Kanatlar / Geniş oyuncular ---
        {
            code: "ÇKO",
            name: "Çalışkan Kanat Oyuncusu",
            group: "Kanat",
            duties: ["Savunma", "Destek", "Hücum", "Otomatik"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "DK",
            name: "Defansif Kanat",
            group: "Kanat",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "KOK",
            name: "Kanat Oyun Kurucu",
            group: "Kanat",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "TAK",
            name: "Ters Ayaklı Kanat",
            group: "Kanat",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "RMD",
            name: "Raumdeuter",
            group: "Kanat",
            duties: ["Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "HKO",
            name: "Hedef Kanat Oyuncusu",
            group: "Kanat",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },

        // --- 10 numaralar / AMC ---
        {
            code: "ON",
            name: "On Numara",
            group: "Ofansif Orta Saha",
            duties: ["Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "OOS",
            name: "Ofansif Orta Saha",
            group: "Ofansif Orta Saha",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "OOK",
            name: "Ofansif Oyun Kurucu",
            group: "Ofansif Orta Saha",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "EG",
            name: "Enganche",
            group: "Ofansif Orta Saha",
            duties: ["Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },

        // --- Forvetler ---
        {
            code: "GF",
            name: "Gizli Forvet",
            group: "Forvet",
            duties: ["Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "YRD",
            name: "Yardımcı Forvet",
            group: "Forvet",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "YF",
            name: "Yaratıcı Forvet",
            group: "Forvet",
            duties: ["Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "PS-F",
            name: "Pivot Santrafor",
            group: "Forvet",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "FG",
            name: "Fırsatçı Golcü",
            group: "Forvet",
            duties: ["Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "KOF",
            name: "Komple Forvet",
            group: "Forvet",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "ÇF",
            name: "Çalışkan Forvet",
            group: "Forvet",
            duties: ["Savunma", "Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "SF",
            name: "Sahte Forvet",
            group: "Forvet",
            duties: ["Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },

        // --- Defansif orta saha / regista hattı ---
        {
            code: "DOS",
            name: "Defansif Orta Saha",
            group: "Defansif Orta Saha",
            duties: ["Savunma", "Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "DOK",
            name: "Derin Oyun Kurucu",
            group: "Defansif Orta Saha",
            duties: ["Savunma", "Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "SO",
            name: "Savaşçı Orta Saha",
            group: "Defansif Orta Saha",
            duties: ["Savunma", "Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "ÖL",
            name: "Ön Libero",
            group: "Defansif Orta Saha",
            duties: ["Savunma"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "REG",
            name: "Regista",
            group: "Defansif Orta Saha",
            duties: ["Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "GOK",
            name: "Gezgin Oyun Kurucu",
            group: "Defansif Orta Saha",
            duties: ["Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "VOL",
            name: "Serbest Defansif Orta Saha (Volante)",
            group: "Defansif Orta Saha",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },

        // --- Merkez orta saha / iç oyuncular ---
        {
            code: "MO",
            name: "Merkez Orta Saha",
            group: "Merkez Orta Saha",
            duties: ["Savunma", "Destek", "Hücum", "Otomatik"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "İYO-OS",
            name: "İki Yönlü Orta Saha",
            group: "Merkez Orta Saha",
            duties: ["Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "MEZ",
            name: "Mezzala",
            group: "Merkez Orta Saha",
            duties: ["Destek", "Hücum"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        },
        {
            code: "DNM",
            name: "Dinamo",
            group: "Merkez Orta Saha",
            duties: ["Destek"],
            tags: [],
            withBall: "",
            withoutBall: "",
            positioning: ""
        }
    ];

    // İç ID ekleyelim, kodlar çakışsa bile sorun olmasın
    roles.forEach(function (r, idx) {
        r._id = idx;
    });

    var DUTIES = ["Savunma", "Destek", "Hücum", "Otomatik"];

    // ---- UI KURULUMU -------------------------------------------------------

    function buildApp($root) {
        var $app = $('<div>').addClass('fm-role-app');

        // Başlık
        $('<h1>').text('FM Rol Antrenörü').appendTo($app);
        $('<div>')
            .addClass('fm-role-subtitle')
            .text('Rol listesinde arama yap, görev filtresi kullan, soldan rolü incele, sağda quiz ile kendini test et.')
            .appendTo($app);

        var $layout = $('<div>').addClass('fm-role-layout').appendTo($app);

        // ==== SOL PANEL: arama + rol inceleme ====
        var $left = $('<section>').addClass('fm-role-panel').appendTo($layout);
        $('<h2>').text('Rol incele').appendTo($left);

        // Arama kutusu
        var $searchLabel = $('<label>')
            .addClass('fm-role-label')
            .text('Rol ara (isim veya kısaltma)')
            .appendTo($left);

        var $search = $('<input>')
            .attr({
                type: 'text',
                placeholder: 'Örn: KOF, Mezzala, ÇF...'
            })
            .css({
                width: '100%',
                padding: '0.4rem 0.6rem',
                borderRadius: '999px',
                border: '1px solid #374151',
                background: '#020617',
                color: '#e5e7eb',
                fontSize: '.85rem',
                marginBottom: '.4rem'
            })
            .appendTo($left);

        // Görev filtresi
        $('<div>')
            .addClass('fm-role-label')
            .css('margin-top', '0.15rem')
            .text('Göreve göre filtrele')
            .appendTo($left);

        var $filterRow = $('<div>')
            .css({ display: 'flex', flexWrap: 'wrap', gap: '0.35rem', marginBottom: '.6rem' })
            .appendTo($left);

        var dutyFilterState = {};
        DUTIES.forEach(function (d) { dutyFilterState[d] = false; });

        function makeDutyButton(duty) {
            var $btn = $('<button>')
                .addClass('fm-role-btn secondary')
                .text(duty)
                .css({ padding: '.25rem .7rem', fontSize: '.75rem' });

            $btn.on('click', function (e) {
                e.preventDefault();
                var active = !dutyFilterState[duty];
                dutyFilterState[duty] = active;
                $btn.toggleClass('fm-role-filter-active', active);

                // küçük görsel ipucu
                if (active) {
                    $btn.css({ background: 'rgba(79,70,229,0.15)' });
                } else {
                    $btn.css({ background: 'transparent' });
                }

                applyFilters();
            });

            return $btn;
        }

        DUTIES.forEach(function (d) {
            $filterRow.append(makeDutyButton(d));
        });

        // Rol seçimi
        $('<label>')
            .addClass('fm-role-label')
            .attr('for', 'fm-role-select')
            .text('Rol')
            .appendTo($left);

        var $select = $('<select>')
            .addClass('fm-role-select')
            .attr('id', 'fm-role-select')
            .appendTo($left);

        var $tags = $('<div>').addClass('fm-role-tags').appendTo($left);

        // Detay kartları
        var $cardWith = $('<div>').addClass('fm-role-card').appendTo($left);
        $('<h3>').text('Top bizdeyken').appendTo($cardWith);
        var $withP = $('<p>').appendTo($cardWith);

        var $cardWithout = $('<div>').addClass('fm-role-card').appendTo($left);
        $('<h3>').text('Top rakipteyken').appendTo($cardWithout);
        var $withoutP = $('<p>').appendTo($cardWithout);

        var $cardPos = $('<div>').addClass('fm-role-card').appendTo($left);
        $('<h3>').text('Konum / pas bağlantısı').appendTo($cardPos);
        var $posP = $('<p>').appendTo($cardPos);

        // ==== SAĞ PANEL: quiz ====
        var $right = $('<section>').addClass('fm-role-panel').appendTo($layout);

        var $qh = $('<div>').addClass('fm-role-quiz-header').appendTo($right);
        $('<h2>').text('Quiz modu').appendTo($qh);
        var $newBtn = $('<button>')
            .addClass('fm-role-btn secondary')
            .text('Yeni soru')
            .appendTo($qh);

        $('<div>')
            .addClass('fm-role-quiz-label')
            .text('Aşağıdaki davranış hangi role ait? Önce tahmin et, sonra “Rolü göster”.')
            .appendTo($right);

        var $qCardWith = $('<div>').addClass('fm-role-card').appendTo($right);
        $('<h3>').text('Top bizdeyken').appendTo($qCardWith);
        var $qWithP = $('<p>')
            .addClass('fm-role-muted')
            .text('Henüz soru yok.')
            .appendTo($qCardWith);

        var $qCardWithout = $('<div>').addClass('fm-role-card').appendTo($right);
        $('<h3>').text('Top rakipteyken').appendTo($qCardWithout);
        var $qWithoutP = $('<p>')
            .addClass('fm-role-muted')
            .text('Yeni soru için butona bas.')
            .appendTo($qCardWithout);

        var $qCardRole = $('<div>').addClass('fm-role-card').appendTo($right);
        $('<h3>').text('Rol').appendTo($qCardRole);
        var $qName = $('<p>')
            .addClass('fm-role-quiz-name')
            .text('???')
            .appendTo($qCardRole);

        var $revealBtn = $('<button>')
            .addClass('fm-role-btn')
            .text('Rolü göster')
            .prop('disabled', true)
            .appendTo($qCardRole);

        $('<p>')
            .addClass('fm-role-hint')
            .text('İpucu: önce hangi hat (stoper / bek / orta / kanat / forvet) ve hangi görev (savunma / destek / hücum) olacağını düşün.')
            .appendTo($right);

        // ---- DURUM & FİLTRE LOJİĞİ -----------------------------------------

        var filteredRoles = roles.slice();
        var currentRoleId = filteredRoles.length ? filteredRoles[0]._id : null;
        var currentQuizRole = null;
        var searchTerm = "";

        function renderTags(role) {
            $tags.empty();
            if (!role) {
                return;
            }
            $('<span>')
                .addClass('fm-role-tag')
                .text('Bölge: ' + role.group)
                .appendTo($tags);

            $('<span>')
                .addClass('fm-role-tag')
                .text('Görevler: ' + role.duties.join(', '))
                .appendTo($tags);

            $('<span>')
                .addClass('fm-role-tag')
                .text('Kod: ' + role.code)
                .appendTo($tags);

            if (role.tags && role.tags.length) {
                $('<span>')
                    .addClass('fm-role-tag')
                    .text('Etiket: ' + role.tags.join(', '))
                    .appendTo($tags);
            }
        }

        function describeField(text) {
            if (!text) {
                return "Bu rol için ayrıntılı davranış açıklaması henüz eklenmedi.";
            }
            return text;
        }

        function updateRoleDetails() {
            var role = roles.find(function (r) { return r._id === currentRoleId; });
            if (!role) {
                $withP.text("Filtre sonucu rol bulunamadı.");
                $withoutP.text("");
                $posP.text("");
                $tags.empty();
                return;
            }
            $withP.text(describeField(role.withBall));
            $withoutP.text(describeField(role.withoutBall));
            $posP.text(describeField(role.positioning));
            renderTags(role);

            // Select değerini rol ile eşitle
            $select.val(String(role._id));
        }

        function rebuildSelect() {
            $select.empty();

            if (!filteredRoles.length) {
                $('<option>')
                    .text('Sonuç yok')
                    .attr('disabled', 'disabled')
                    .appendTo($select);
                currentRoleId = null;
                updateRoleDetails();
                return;
            }

            filteredRoles.forEach(function (role) {
                $('<option>')
                    .val(String(role._id))
                    .text(role.code + " – " + role.name)
                    .appendTo($select);
            });

            // Seçili rol filtreden düşmüşse ilk rolü seç
            if (!currentRoleId || !filteredRoles.some(function (r) { return r._id === currentRoleId; })) {
                currentRoleId = filteredRoles[0]._id;
            }

            updateRoleDetails();
        }

        function applyFilters() {
            var term = (searchTerm || "").toLocaleLowerCase("tr");
            var activeDuties = DUTIES.filter(function (d) { return dutyFilterState[d]; });

            filteredRoles = roles.filter(function (role) {
                // metin araması
                var text = (role.name + " " + role.code).toLocaleLowerCase("tr");
                var matchText = !term || text.indexOf(term) !== -1;

                // görev filtresi
                var matchDuty = !activeDuties.length ||
                    role.duties.some(function (d) { return activeDuties.indexOf(d) !== -1; });

                return matchText && matchDuty;
            });

            rebuildSelect();
        }

        // ---- EVENTLER -------------------------------------------------------

        $search.on('input', function () {
            searchTerm = $(this).val() || "";
            applyFilters();
        });

        $select.on('change', function () {
            var val = $(this).val();
            if (val === null) { return; }
            currentRoleId = Number(val);
            updateRoleDetails();
        });

        function newQuestion() {
            if (!roles.length) { return; }
            var idx = Math.floor(Math.random() * roles.length);
            currentQuizRole = roles[idx];

            $qWithP
                .text(describeField(currentQuizRole.withBall))
                .removeClass('fm-role-muted');
            $qWithoutP
                .text(describeField(currentQuizRole.withoutBall))
                .removeClass('fm-role-muted');
            $qName.text('???');
            $revealBtn.prop('disabled', false);
        }

        function reveal() {
            if (!currentQuizRole) { return; }
            $qName.html(
                '<span class="fm-role-highlight">' +
                mw.html.escape(currentQuizRole.code) +
                '</span> – ' + mw.html.escape(currentQuizRole.name)
            );
            $revealBtn.prop('disabled', true);
        }

        $newBtn.on('click', function (e) {
            e.preventDefault();
            newQuestion();
        });

        $revealBtn.on('click', function (e) {
            e.preventDefault();
            reveal();
        });

        // Başlangıç
        $root.empty().append($app);
        applyFilters(); // filtreleri çalıştır, select & detayları doldur
    }

    function init() {
        var $root = $('#fm-role-trainer');
        if ($root.length) {
            buildApp($root);
        }
    }

    $(init);

}(mediaWiki, jQuery));