×
Einen neuen Artikel erstellen
Schreibe den Seitennamen hierhin:
Wir haben derzeit 9.336 Artikel auf VAULTPEDIA. Gib deinen Artikelnamen oberhalb von oder klicke auf einen der unten stehenden Titel und beginne zu schreiben! ein



    VAULTPEDIA
    9.336Artikel

    MediaWiki:Common.js: Unterschied zwischen den Versionen

    VAULTPEDIA.DE ist seit dem 02.02.2026 öffentlich zugänglich.

    Da es sich um ein frisch migriertes Wiki handelt, können vereinzelt noch Datenbank-, Seiten- oder Designfehler auftreten.

    Tritt unserem Discord bei, um Fehler zu melden oder direkt mit dem Team in Kontakt zu treten.

    Alessio79 (Diskussion | Beiträge)
    Inhalt testweise ersetzt
    Alessio79 (Diskussion | Beiträge)
    K Änderung 24130 von Alessio79 (Diskussion) rückgängig gemacht. (keine bedeutsamen Änderungen)
    Zeile 1: Zeile 1:
    /* <nowiki> */
    /* ######################################################################## */
    /* ######################################################################## */
    /* ### JavaScript here will be loaded for all users on every page load. ### */
    /* ### JavaScript here is loaded for all users and all skins.           ### */
    /* ######################################################################## */
    /* ######################################################################## */


    // <nowiki><pre>
    /* ######################################################################## */
     
    /* ### TITLE ICONS (Template:Games)                                    ### */
    // ============================================================
    /* ### ---------------------------------------------------------------- ### */
    // BEGIN Scripts for Internet Explorer 6
    /* ### Description: Add icons to article title                          ### */
    // ============================================================
    /* ### Credit:      User:Porter21                                      ### */
    /* ######################################################################## */


    // Description: Import scripts specific to Internet Explorer 6
    function addTitleIcons () {
    // Credit:      This script is from Wikipedia. Please see http://en.wikipedia.org/w/index.php?title=MediaWiki:Common.js&action=history
      var iconBar = $('#va-titleicons');
      var previewBar = $('#va-titleicons-preview');


    if (navigator.appName == "Microsoft Internet Explorer") {
      if (skin != 'monobook' && skin != 'oasis' && skin != 'wikia') {
      if (navigator.appVersion.substr(22, 1) == "6") {
           return;
           importScript("MediaWiki:Common.js/IE60Fixes.js")
       }
       }
    }


    // ============================================================
      if (iconBar.length > 0 && $('a', previewBar).length > 0) {
    // END Scripts for Internet Explorer 6
          if (skin == 'oasis' || skin == 'wikia') {
    // ============================================================
            var articleDiv = $('#WikiaArticle');


    // ============================================================
            if (articleDiv.length > 0) {
    // BEGIN Template:Games
                iconBar.css('display', 'block').prependTo(articleDiv);
    // ============================================================
            }
          } else if (skin == 'monobook') {
            var firstHeading = $('#firstHeading').css('position', 'relative');


    // Description: Add game icons to top right corner of articles
            if (firstHeading.length > 0) {
    // Credit:      User:Mirar (based on Template:Eras by User:Sikon)
                iconBar.css('display', 'block').appendTo(firstHeading.css('padding-right', previewBar.width() + 25));
     
            }
    function addTitleGames() {
      var titleDiv = document.getElementById("title-games");
      if (titleDiv != null && titleDiv != undefined)
      {
          var content = document.getElementById('article');
          if (!content) {
            var content = document.getElementById('content');
           }
           }


           if (content) {
           $('#va-titleicons-more').append('<img width="0" height="0" class="va-titleicons-chevron" src="http://images.wikia.com/common/skins/common/blank.gif">');
            var hs = content.getElementsByTagName('h1');
            var firstHeading;
            for (var i = 0; i < hs.length; i++)
            {
                if ( (' '+hs[i].className+' ').indexOf(' firstHeading ') != -1){
                  firstHeading=hs[i];
                  break;
                }
            }


            var cloneNode = titleDiv.cloneNode(true);
          iconBar.hover(
             firstHeading.insertBefore(cloneNode, firstHeading.childNodes[0]);
             function () {
            cloneNode.style.display = "block";
                $(this).addClass('va-titleicons-hover');
             cloneNode.style.visibility = "visible";
             }, function () {
            if (skin != "monaco") {
                 $(this).removeClass('va-titleicons-hover');
                 cloneNode.style.marginTop = "-11px";
             });
             }
          }
       }
       }
    }
    }


    addOnloadHook( addTitleGames );
    /* ######################################################################## */
     
    /* ### COLLAPSIBLE TABLES                                              ### */
    // ============================================================
    /* ### ---------------------------------------------------------------- ### */
    // END Template:Games
    /* ### Description: Allow tables to be collapsible                     ### */
    // ============================================================
    /* ### Credit:      http://en.wikipedia.org/wiki/MediaWiki:Common.js   ### */
     
    /* ###             Customized for Fallout Wiki by User:Porter21       ### */
    // ============================================================
    /* ######################################################################## */
    // BEGIN Collapsible tables
    // ============================================================
     
    // Description: Allow tables to be collapsible
    // Credit:      This script is from Wikipedia. Please see http://en.wikipedia.org/w/index.php?title=MediaWiki:Common.js&action=history
    //             Customized for Fallout Wiki by User:Porter21


    /* Test if an element has a certain class **************************************
    /* Test if an element has a certain class **************************************
    Zeile 95: Zeile 75:


    var autoCollapse = 1;
    var autoCollapse = 1;
    var collapseCaption = "fechar";
    var collapseCaption = "hide";
    var expandCaption = "abrir";
    var expandCaption = "show";


    function collapseTable( tableIndex ) {
    function collapseTable(tableIndex) {
       var Button = document.getElementById( "collapseButton" + tableIndex );
       var Button = document.getElementById( "collapseButton" + tableIndex );
       var Table = document.getElementById( "collapsibleTable" + tableIndex );
       var Table = document.getElementById( "collapsibleTable" + tableIndex );
    Zeile 184: Zeile 164:
    }
    }


    addOnloadHook( createCollapseButtons );
    /* ######################################################################## */
    /* ### ARCHIVE TOOL                                                    ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: AJAX-archiving of talk pages via GUI                ### */
    /* ### Credit:      User:Dantman (original)                             ### */
    /* ###              User:Porter21 (Oasis & Monobook support)            ### */
    /* ######################################################################## */
     
    /*
    * Copyright © 2009, Daniel Friesen
    * All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions are met:
    *    * Redistributions of source code must retain the above copyright
    *      notice, this list of conditions and the following disclaimer.
    *    * Redistributions in binary form must reproduce the above copyright
    *      notice, this list of conditions and the following disclaimer in the
    *      documentation and/or other materials provided with the distribution.
    *    * Neither the name of the script nor the
    *      names of its contributors may be used to endorse or promote products
    *      derived from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY DANIEL FRIESEN ''AS IS'' AND ANY
    * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
    * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
    * DISCLAIMED. IN NO EVENT SHALL DANIEL FRIESEN BE LIABLE FOR ANY
    * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
    * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
    * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
    * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
    * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */


    // ============================================================
    function archiveTool () {
    // END Collapsible tables
      // Configuration
    // ============================================================
      var userconfig = (window.ArchiveToolConfig) ? window.ArchiveToolConfig : {};
      var config = $.extend(true, {
          archiveListTemplate: 'Archives',
          archivePageTemplate: 'Archivepage',
          archiveSubpage: 'Archive',
          userLang: false,
          // English
          en: {
            buttonArchiveTool: "Archive",
            buttonArchiveToolTooltip: "Archive this page",
            buttonSelectAll: "Select all",
            buttonDeselectAll: "Deselect all",
            buttonSaveArchive: "Save archive",
            buttonAbort: "Abort",
            labelLines: "Lines",
            labelSections: "Sections",
            summaryArchiveFrom: "ArchiveTool: Archiving from",
            summaryArchiveTo: "ArchiveTool: Archiving to"
          }
      }, userconfig);


    // ============================================================
      // Function for multi-language support
    // BEGIN ArchiveTool
      function msg(name) {
    // ============================================================
          if ( config.userLang && wgUserLanguage in config && name in config[wgUserLanguage] )
            return config[wgUserLanguage][name];
          if ( wgContentLanguage in config && name in config[wgContentLanguage] )
            return config[wgContentLanguage][name];
          return config.en[name];
      }
     
      if (skin != "monaco" && skin != 'monobook' && skin != 'oasis' && skin != 'wikia') {
          return;
      }


    // Description: Add tool for easier talk page archiving
      if ((wgNamespaceNumber%2 != 0 && wgNamespaceNumber != 501) && (wgAction == "view" || wgAction == "purge")) {
    // Credit:     User:Dantman (http://dev.wikia.com)
          var skinConfig = {
            textCont: '', pageControls: '', controlsMarkup: '',
            buttonOpenPri: '', buttonOpenSec: '', buttonClose: ''
          };


    var archiveListTemplate = 'Archives';  
          switch(skin) {
    var archivePageTemplate = 'Archivepage';  
            case 'monaco':
    importScriptPage('ArchiveTool/code.js', 'dev');
                skinConfig.textCont = '#bodyContent';
                skinConfig.pageControls = '#page_controls';
                skinConfig.controlsMarkup = '<li id="control_archive"><img src="/skins/common/blank.gif" class="sprite move" /><a id="ca-archive" title="' + msg('buttonArchiveToolTooltip') + '" href="#" rel="nofollow">' + msg('buttonArchiveTool') + '</a></li>';
                skinConfig.buttonOpenPri = '<a class="wikia-button">';
                skinConfig.buttonOpenSec = '<a class="wikia-button secondary">';
                skinConfig.buttonClose = '</a>';
                break;
            case 'monobook':
                skinConfig.textCont = '#bodyContent';
                skinConfig.pageControls = '#p-cactions > div > ul';
                skinConfig.controlsMarkup = '<li id="control_archive"><a id="ca-archive" title="' + msg('buttonArchiveToolTooltip') + '" href="#" rel="nofollow">' + msg('buttonArchiveTool') + '</a></li>';
                skinConfig.buttonOpenPri = '<input type="submit" style="font-weight: bold;" value="';
                skinConfig.buttonOpenSec = '<input type="submit" value="';
                skinConfig.buttonClose = '" />';
                break;
            case 'oasis':
            case 'wikia':
                skinConfig.textCont = '#WikiaArticle';
                skinConfig.pageControls = ((wgNamespaceNumber == 3) ? '#WikiaUserPagesHeader' : '#WikiaPageHeader') + ' > ul.wikia-menu-button > li > ul';
                skinConfig.controlsMarkup = '<li id="control_archive"><a id="ca-archive" rel="nofollow">' + msg('buttonArchiveTool') + '</a></li>';
                skinConfig.buttonOpenPri = '<a class="wikia-button">';
                skinConfig.buttonOpenSec = '<a class="wikia-button secondary">';
                skinConfig.buttonClose = '</a>';
                break;
          }


    // ============================================================
          $(function() {
    // END ArchiveTool
            function api(q, fn) {
    // ============================================================
                q.format = 'json';
                return $.post(wgScriptPath + '/api.php', q, fn, "json");
            }
            function token(page, fn) {
                api({
                  action: 'query',
                  query: 'prop',
                  prop: 'info',
                  titles: page,
                  intoken: 'edit'
                }, function(q) {
                  for ( var k in q.query.pages )
                      return fn(q.query.pages[k]);
                });
            }
           
            function startArchiving() {
                var c = config.archiveListTemplate.substr(0,1);
                var archiveListRegex = '['+c.toUpperCase()+c.toLowerCase()+']'+config.archiveListTemplate.substr(1);
                var bc = $(skinConfig.textCont).addClass('va-archiving').empty();


    // ============================================================
                $('<img class="ajax" alt="Loading..." />')
    // BEGIN AjaxRC
                  .attr({src: stylepath+'/common/progress-wheel.gif'}).appendTo(bc);
    // ============================================================
                api({
                  action: 'query',
                  prop: 'revisions',
                  titles: wgPageName,
                  rvprop: 'timestamp|content'
                }, function(q) {
                  bc.empty();
                  var rev = q.query.pages[wgArticleId].revisions[0];
                  var time = rev.timestamp;
                  var talkToken, tokenTime;
                  var content = rev['*'];
                  token(wgPageName, function(p) {
                      talkToken = p.edittoken;
                      tokenTime = p.starttimestamp;
                  });
                 
                  var lines = content.split('\n');
                 
                  var table = $('<table style="margin: 10px 0;"><thead><tr><th>' + msg('labelLines') + '</th><th title="' + msg('labelSections') + '">{&hellip;}</th></tr></thead></table>').appendTo(bc);
                  var ul = $('<tbody/>').appendTo(table);
                 
                  for ( var l = 0; l < lines.length; l++ ) {
                      var line = lines[l];
                      $('<tr/>').toggleClass('noarchive', (new RegExp('^\\{\\{'+archiveListRegex+'\}\}')).test(line))
                        .attr({line:line})
                        .append( $('<td class=line />').text(line).append('&nbsp;') ).appendTo(ul);
                  }
                 
                  var sections = [];
                  var sectionEnd = lines.length-1;
                  for ( var l = lines.length-1; l >= 0; l-- ) {
                      var line = lines[l];
                     
                      if ( /^=.+?=/.test(line) || l === 0 ) {
                        var section = { start: l, end: sectionEnd };
                        section.length = section.end - section.start + 1;
                        sections.unshift(section);
                       
                        sectionEnd = l-1;
                      }
                  }
                 
                  var section;
                  while( section = sections.shift() ) {
                      var tr = ul.children().eq(section.start);
                      $('<td class=section />').attr({rowspan: section.length}).appendTo(tr);
                  }
                 
                  $('<div class="buttons" style="text-align: right;" />').append(
                      $(skinConfig.buttonOpenSec + msg('buttonSelectAll') + skinConfig.buttonClose).click(function(e) {
                        e.preventDefault();
                        ul.children('tr').addClass('archive');
                      }), ' ',
                      $(skinConfig.buttonOpenSec + msg('buttonDeselectAll') + skinConfig.buttonClose).click(function(e) {
                        e.preventDefault();
                        ul.children('tr').removeClass('archive');
                      }), ' ',
                      $(skinConfig.buttonOpenPri + msg('buttonSaveArchive') + skinConfig.buttonClose).click(function(e) {
                        archive();
                      }), ' ',
                      $(skinConfig.buttonOpenPri + msg('buttonAbort') + skinConfig.buttonClose).click(function(e) {
                        bc.find('.ajax').remove();
                        location = wgServer+wgScript+'?title='+encodeURI(wgPageName)+'&action=purge';
                      })
                  ).prependTo(bc).clone(true).appendTo(bc);
                 
                  var click = false;
                  var add;
                  table.mousedown(function(e) {
                      e.preventDefault();
                      var $li = $(e.target).closest('tr');
                      if(!$li.length) return;
                      var $section = $(e.target).closest('.section');
                      if ( $section.length ) {
                        var slist = $li.nextAll(':lt('+(parseInt($section.attr('rowspan'),10)-1)+')').andSelf();
                        var sadd = slist.filter(function() { return !$(this).hasClass('archive') }).length;
                        slist.toggleClass('archive', !!sadd);
                        return;
                      }
                      click = true;
                      add = !$li.hasClass('archive');
                     
                      $li.toggleClass('archive', !!add);
                  });
                  table.mouseover(function(e) {
                      if (!click) return;
                      var $li = $(e.target).closest('tr');
                      if(!$li.length) return;
                     
                      $li.toggleClass('archive', !!add);
                  });
                  $('body').mouseup(function(e) {
                      click = false;
                  });
                 
                  function archive() {
                      var talkLines = [];
                      var archiveLines = [];
                      ul.children().each(function() {
                        var arr = $(this).hasClass('noarchive') || !$(this).hasClass('archive')
                            ? talkLines : archiveLines;
                       
                        arr.push( $(this).attr('line') );
                      });
                     
                      if ( !(new RegExp('^\\{\\{'+archiveListRegex+'\}\}')).test(talkLines[0]) )
                        talkLines = ['{{'+config.archiveListTemplate+'}}', ''].concat(talkLines);
                      archiveLines = ['{{'+config.archivePageTemplate+'}}', ''].concat(archiveLines);
                     
                      bc.empty();
                      $('<img class="ajax" alt="Loading..." />')
                        .attr({src: stylepath+'/common/progress-wheel.gif'}).appendTo(bc);
                     
                      runArchive(talkLines.join('\n'), archiveLines.join('\n'));
                  }
                 
                  var archiveTitle;
                  function runArchive(talkContent, archiveContent) {
                      var archiveNo;
                      function findArchives() {
                        var m = $('<p>Finding archive id: </p>').appendTo(bc);
                        api({
                            action: 'query',
                            list: 'allpages',
                            apnamespace: wgNamespaceNumber,
                            apprefix: wgTitle+'/'+config.archiveSubpage,
                            aplimit: 1,
                            apdir: 'descending'
                        }, function(q) {
                            archiveNo = q.query.allpages.length ?
                              parseInt(q.query.allpages[0].title.substr(wgPageName.length+("/"+config.archiveSubpage).length),10)+1 :
                              1;
                            archiveTitle = wgPageName+'/'+config.archiveSubpage+' '+archiveNo;
                            m.append('done... (using '+archiveNo+')');
                           
                            saveArchive();
                        });
                      }
                     
                      function saveArchive() {
                        var m = $('<p>Finding token for '+archiveTitle+': </p>').appendTo(bc);
                        token(archiveTitle, function(p) {
                            m.append('done...');
                            m = $('<p>Saving archive page: </p>').appendTo(bc);
                            api({
                              action: 'edit',
                              title: archiveTitle,
                              text: archiveContent,
                              token: p.edittoken,
                              summary: msg('summaryArchiveFrom') + " [[" + wgPageName + "]].",
                              minor: true,
                              createonly: true
                            }, function(q) {
                              if ( q.error && q.error.code === "articleexists" ) {
                                  m.append('failed...');
                                  bc.append("<p>The archive page we tried to create already exists.</p>");
                                  return abort();
                              }
                              m.append('done...');
                             
                              saveTalk();
                            });
                        });
                      }
                     
                      function saveTalk() {
                        var m = $('<p>Finding token for '+wgPageName+': </p>').appendTo(bc);
                        m.append('done...');
                        m = $('<p>Updating talk page: </p>').appendTo(bc);
                        api({
                            action: 'edit',
                            title: wgPageName,
                            text: talkContent,
                            token: talkToken,
                            summary: msg('summaryArchiveTo') + " [[" + archiveTitle + "]].",
                            minor: true,
                            basetimestamp: time,
                            starttimestamp: tokenTime
                        }, function(q) {
                            if ( q.edit.result === "Success" ) {
                              m.append('done...');
                              bc.find('.ajax').remove();
                              location = wgServer+wgScript+'?title='+encodeURI(wgPageName)+'&action=purge';
                            } else {
                              m.append('failed...');
                              bc.append("<p>Failed to update talkpage, you may wish to have the archive subpage we just created deleted.</p>");
                              return abort();
                            }
                        });
                      }
                     
                      function abort() {
                        bc.find('.ajax').remove();
                        bc.append("<p>Aborting...</p>");
                       
                        $("<p>You may want to </p>")
                            .append( $('<a>refresh</a>').attr({href: wgServer+wgArticlePath.replace('$1', encodeURI(wgPageName))}) )
                            .append(' and try again.')
                            .appendTo(bc);
                      }
                     
                      // start
                      findArchives();
                  }
                });
            }
           
            $(skinConfig.controlsMarkup)
                .click(startArchiving)
                .appendTo(skinConfig.pageControls);
          });
      }
    }


    // Description: Automatically refreshes "Recent changes"
    /* ######################################################################## */
    // Credit:      User:pcj (http://www.wowwiki.com)
    /* ### AJAX RC                                                          ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Automatically refresh "Recent changes" via AJAX    ### */
    /* ### Credit:      User:pcj (http://www.wowpedia.org)                 ### */
    /* ######################################################################## */


    var AjaxRCRefreshText = 'Auto-refresh';
    var ajaxIndicator = stylepath + '/common/progress-wheel.gif';
    importScriptPage('AjaxRC/code.js', 'dev');
    var ajaxPages = new Array("Special:RecentChanges", "Special:WikiActivity", "The_Vault:WikiActivity");
    var ajaxTimer;
    var ajaxRefresh = 60000;
    var refreshText = 'Auto-refresh';
    var refreshHover = 'Enable auto-refreshing page loads';
    var doRefresh = true;


    // ============================================================
    function setCookie(c_name,value,expiredays) {
    // END AjaxRC
      var exdate=new Date()
    // ============================================================
      exdate.setDate(exdate.getDate()+expiredays)
      document.cookie=c_name+ "=" +escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString())
    }
    function getCookie(c_name) {
      if (document.cookie.length>0) {
          c_start=document.cookie.indexOf(c_name + "=")
          if (c_start!=-1) {
            c_start=c_start + c_name.length+1
            c_end=document.cookie.indexOf(";",c_start)
            if (c_end==-1) c_end=document.cookie.length
            return unescape(document.cookie.substring(c_start,c_end))
          }
      }
      return ""
    }
    function preloadAJAXRL() {
      ajaxRLCookie = (getCookie("ajaxload-"+wgPageName)=="on") ? true:false;
      appTo = ($("#WikiaPageHeader").length)?$("#WikiaPageHeader > h1"):$(".firstHeading");
      appTo.append('&#160;<span style="font-size: xx-small; line-height: 100%;" id="ajaxRefresh"><span style="border-bottom: 1px dotted; cursor: help;" id="ajaxToggleText" title="' + refreshHover + '">' + refreshText + ':</span><input type="checkbox" style="margin-bottom: 0;" id="ajaxToggle"><span style="display: none;" id="ajaxLoadProgress"><img src="' + ajaxIndicator + '" style="vertical-align: baseline;" border="0" alt="Refreshing page" /></span></span>');
      $("#ajaxLoadProgress").ajaxSend(function (event, xhr, settings){
          if (location.href == settings.url) $(this).show();
      }).ajaxComplete (function (event, xhr, settings){
          if (location.href == settings.url) $(this).hide();
      });
      $("#ajaxToggle").click(toggleAjaxReload);
      $("#ajaxToggle").attr("checked", ajaxRLCookie);
      if (getCookie("ajaxload-"+wgPageName)=="on") loadPageData();
    }
    function toggleAjaxReload() {
      if ($("#ajaxToggle").attr("checked") == true) {
          setCookie("ajaxload-"+wgPageName, "on", 30);
          doRefresh = true;
          loadPageData();
      } else {
          setCookie("ajaxload-"+wgPageName, "off", 30);
          doRefresh = false;
          clearTimeout(ajaxTimer);
      }
    }


    // ============================================================
    function loadPageData() {
    // BEGIN Facebook Fanbox
      cC = ($("#WikiaArticle").length)?"#WikiaArticle":"#bodyContent";
    // ============================================================
      $(cC).load(location.href + " " + cC + " > *", function (data) {
          if (doRefresh) ajaxTimer = setTimeout("loadPageData();", ajaxRefresh);
      });
    }


    // Description: Integrate Facebook Fanbox into Wiki
    /* ######################################################################## */
    // Credit:      User:edricteo (http://redwall.wikia.com)
    /* ### DISABLE ARCHIVE EDIT                                            ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Remove section edit links and gray out main edit    ### */
    /* ###              button on archived talk pages                      ### */
    /* ### Credit:      User:Porter21                                      ### */
    /* ######################################################################## */


    function fBox() {
    function disableArchiveEdit () {
       $('#Wikifbox').append('<iframe marginheight="0" marginwidth="0" src="http://www.facebook.com/connect/connect.php?id=104178646292440&amp;connections=10&amp;stream=1" align="top" frameborder="0" width="300" height="550" scrolling="no" />');
       // Configuration
      var userconfig = (window.DisableArchiveEditConfig) ? window.DisableArchiveEditConfig : {};
      var config = $.extend(true, {
          archiveSubpage: 'Archive',
          disableCompletely: false,
          textColor: '#D9D9D9',
          userLang: false,
          // English
          en: {
            archived: "Archived",
            archivedTooltip: "This page is an archive and should not be edited."
          }
      }, userconfig);
      // Function for multi-language support (by Daniel Friesen aka User:Dantman)
      function msg(name) {
          if ( config.userLang && wgUserLanguage in config && name in config[wgUserLanguage] )
            return config[wgUserLanguage][name];
          if ( wgContentLanguage in config && name in config[wgContentLanguage] )
            return config[wgContentLanguage][name];
          return config.en[name];
      }
      // Check whether page is an archive
      if ((new RegExp('\\/\[' + config.archiveSubpage.substr(0,1).toUpperCase()
          + config.archiveSubpage.substr(0,1).toLowerCase() + '\]' + config.archiveSubpage.substr(1)
          + '\\s\*\\d\*')).test(wgTitle)) {
          // Remove "add new section" links and prepare altering "edit" page control
          switch (skin) {
            case 'monaco':
                $('#control_addsection').remove();
                $('#fe_newsection').remove();
                editlink = $('#ca-edit');
                break;
            case 'monobook':
                $('#ca-addsection').remove();
                editlink = $('#ca-edit > a');
                break;
            case 'oasis':
            case 'wikia':
                var oasisButton = $(((wgNamespaceNumber == 3) ? '#WikiaUserPagesHeader' : '#WikiaPageHeader') + ' > ul.wikia-menu-button > li');
                oasisButton.children("a:first").prependTo($('ul:first', oasisButton)).wrap('<li />').children('img').remove();
                oasisButton.prepend('<a />');
                $('a[data-id="addtopic"]', oasisButton).parent().remove();
                editlink = $('a:first', oasisButton);
                break;
          }
          // Remove "edit section" links
          $('span.editsection').remove();
          // Alter "edit" page control
          if (config.disableCompletely) {
            editlink.remove();
          } else {
            editlink.attr('title', msg('archivedTooltip')).css('color', config.textColor).text(msg('archived'));
          }
      }
    }
    }
    /* ######################################################################## */
    /* ### COUNTDOWN                                                        ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Adds countdown to specific date to a page.          ### */
    /* ###              (jQuery version of http://dev.wikia.com/Countdown)  ### */
    /* ### Credit:      User:Splarka (original)                            ### */
    /* ###              User:Porter21 (jQuery version)                      ### */
    /* ######################################################################## */


    $(fBox);
    // Usage example:
    // <span class="countdown" style="display:none;">January 01 2020 00:00:00 PST</span>


    // ============================================================
    function updateCountdowns(targets, countdowns) {
    // END Facebook Fanbox
      var now = new Date();
    // ============================================================


    // ============================================================
      now = now.getTime();
    // BEGIN Grayed-out edit button for archived talk pages
    // ============================================================


    // Description: Remove section edit links and gray out main edit button on archived talk pages
      countdowns.each(function(i) {
    // Credit:      User:Porter21 (based on "Archive edit tab disabling" by User:Spang and User:Uberfuzzy)
          var diff = Math.floor((targets[i]-now)/1000);


    function disableArchiveEdit () {
          // determine plus/minus
      if ((wgNamespaceNumber%2 == 0 && wgNamespaceNumber%2 != 501) ||
          if (diff < 0 ) { diff = -diff; }
        (wgTitle.indexOf('/Archive ') == -1 && wgTitle.indexOf('/archive ') == -1)) {
     
        return;
          // convert the difference into readable formatting
       }
          var left = (diff%60) + ' seconds';
     
          diff = Math.floor(diff/60);
          if (diff > 0) { left = (diff%60) + ' minutes ' + left; }
          diff = Math.floor(diff/60);
          if (diff > 0) { left = (diff%24) + ' hours ' + left; }
          diff = Math.floor(diff/24);
          if (diff > 0) { left = diff + ' days ' + left; }
     
          $(this).text(left);
      });
     
       setTimeout(function() { updateCountdowns(targets, countdowns); }, 1000);
    }


      if (document.getElementById('ca-edit')) {
    function addCountdowns() {
        if (skin == 'monaco') {
      var targets = [];
          editLink = document.getElementById('ca-edit');
      var countdowns = $('span.countdown').filter(function() {
        }
          var content = $(this).text();
        else if (skin == 'monobook') {
          var converted = new Date(content);
          editLink = document.getElementById('ca-edit').firstChild;
        }
        editLink.title = 'This page is an archive and should usually not be edited.';
        editLink.style.color = 'gray';
        editLink.innerHTML = 'Archived';
      }


      $('span.editsection').remove();
          if (content == "" || isNaN(converted)) {
            return false;
          } else {
            $(this).css("display", "inline");
            targets[targets.length] = converted.getTime();
            return true;
          }
      });


       if((skin == 'monaco' && document.getElementById('control_addsection')) ||
       if (targets.length <= 0) {
        (skin == 'monobook' && document.getElementById('ca-addsection'))) {
          return;
        if (skin == 'monaco') {
          addsectionButton = document.getElementById('control_addsection');
        }
        else if (skin == 'monobook') {
          addsectionButton = document.getElementById('ca-addsection');
        }
        addsectionButton.style.display = 'none';
        addsectionButton.style.visibility = 'hidden';
       }
       }


       if (skin == 'monaco' && document.getElementById('fe_newsection')) {
       updateCountdowns(targets, countdowns);
        document.getElementById('fe_newsection').style.display = 'none';
        document.getElementById('fe_newsection').style.visibility = 'hidden';
      }
    }
    }


    addOnloadHook (disableArchiveEdit);
    /* ######################################################################## */
    /* ### DUPLICATE FILE LIST                                              ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Finds duplicate files on the wiki.                  ### */
    /* ### Credit:      User:pcj (http://www.wowpedia.org)                 ### */
    /* ######################################################################## */
     
    function findDupFiles(gf) {
      var fileDiv = $('#mw-dupfiles');
     
      if (fileDiv.length) {
          dil = new Array();
          ajaxIndicator = stylepath + '/common/progress-wheel.gif';
          output = '';
          url = '/api.php?action=query&generator=allimages&prop=duplicatefiles&gailimit=500&format=json';


    // ============================================================
          if (!($('#dupFilesProgress').length)) {
    // END Grayed-out edit button for archived talk pages
            fileDiv.prepend('<span style="float: right;" id="dupFilesProgress" title="In progress..."><img src="' + ajaxIndicator + '" style="vertical-align: baseline;" border="0" alt="In progress..." /></span>');
    // ============================================================
          }


    // ============================================================
          if (gf) {
    // BEGIN Intro text for My Home
            url += "&gaifrom=" + gf;
    // ============================================================
          }


    // Description: Add intro text to Special:MyHome
          $.getJSON( url, function (data) {
    // Credit:      User:Porter21 (based on Template:Eras by User:Sikon)
            if ( data.query ) {
    // Notes:      The intro text and style is stored in [[MediaWiki:Myhome-intro]].
                pages = data.query.pages;
    //              Also requires {{:MediaWiki:Myhome-intro}} in e.g. [[MediaWiki:Community-corner]].


    function addMyHomeIntro() {
                for (pageID in pages) {
      if ( skin == 'monaco' && wgNamespaceNumber == -1 && wgCanonicalSpecialPageName == 'MyHome' && wgUserName != null ) {
                  dils = "," + dil.join();
          var introDiv = document.getElementById("fw-myhome-intro");
          if (introDiv != null && introDiv != undefined) {
            var bodyDiv = document.getElementById('article');


            if (bodyDiv != null && bodyDiv != undefined) {
                  if ( dils.indexOf("," + pages[pageID].title) == -1
                var cloneDiv = introDiv.cloneNode(true);
                      && pages[pageID].title.indexOf("File::") == -1 && pages[pageID].duplicatefiles ) {
                cloneDiv.style.display = "block";
                      output += "<h3><a href='/wiki/" + encodeURIComponent(pages[pageID].title).replace(/'/g, "%27") + "'>" + pages[pageID].title + "</a></h3>\n<ul>\n";
                cloneDiv.style.visibility = "visible";


                bodyDiv.insertBefore(cloneDiv, bodyDiv.childNodes[0]);
                      for ( x = 0; x < pages[pageID].duplicatefiles.length; x++ ) {
                        output += "<li><a href='/wiki/File:" + encodeURIComponent(pages[pageID].duplicatefiles[x].name).replace(/'/g, "%27") + "'>File:" + pages[pageID].duplicatefiles[x].name + "</a></li>\n";
                        dil.push("File:" + pages[pageID].duplicatefiles[x].name.replace(/_/g, " "));
                      }
                      output += "</ul>\n\n"
                  }
                }
     
                fileDiv.append(output);
     
                if (data["query-continue"]) {
                  setTimeout("findDupFiles('" + encodeURIComponent(data["query-continue"].allimages.gaifrom).replace(/'/g, "%27") + "');", 5000);
                } else {
                  $('#dupFilesProgress').hide();
                }
             }
             }
           }
           } );
       }
       }
    }
    }


    addOnloadHook( addMyHomeIntro );
    /* ######################################################################## */
    /* ### SCRIPT LOADER                                                    ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Loads all the other scripts                        ### */
    /* ### Credit:      User:Porter21                                      ### */
    /* ######################################################################## */
     
    function vaultScriptLoader () {
      // Always loaded
      addCountdowns();
      createCollapseButtons();
     
      // Only loaded for specific namespaces
      if ((wgNamespaceNumber == 0 || wgNamespaceNumber == 4 || wgNamespaceNumber == 110 || wgNamespaceNumber == 502) &&
          !wgIsMainpage) {
          addTitleIcons();
      }
     
      if (wgNamespaceNumber%2 != 0 && wgNamespaceNumber != 501) {
          archiveTool();
          disableArchiveEdit();
      }
     
      // Only loaded for specific pages
      if (wgPageName == 'The_Vault:Duplicate_files') {
          findDupFiles();
      }
      for (x in ajaxPages) {
          if (wgPageName == ajaxPages[x] && $("#ajaxToggle").length==0) preloadAJAXRL();
      }
    }


    // ============================================================
    jQuery(function($) {
    // END Intro text for My Home
      vaultScriptLoader();
    // ============================================================
    });


    // </nowiki></pre>
    /* </nowiki> */

    Version vom 6. Juli 2011, 23:48 Uhr

    /* <nowiki> */
    
    /* ######################################################################## */
    /* ### JavaScript here is loaded for all users and all skins.           ### */
    /* ######################################################################## */
    
    /* ######################################################################## */
    /* ### TITLE ICONS (Template:Games)                                     ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Add icons to article title                          ### */
    /* ### Credit:      User:Porter21                                       ### */
    /* ######################################################################## */
    
    function addTitleIcons () {
       var iconBar = $('#va-titleicons');
       var previewBar = $('#va-titleicons-preview');
    
       if (skin != 'monobook' && skin != 'oasis' && skin != 'wikia') {
          return;
       }
    
       if (iconBar.length > 0 && $('a', previewBar).length > 0) {
          if (skin == 'oasis' || skin == 'wikia') {
             var articleDiv = $('#WikiaArticle');
    
             if (articleDiv.length > 0) {
                iconBar.css('display', 'block').prependTo(articleDiv);
             }
          } else if (skin == 'monobook') {
             var firstHeading = $('#firstHeading').css('position', 'relative');
    
             if (firstHeading.length > 0) {
                iconBar.css('display', 'block').appendTo(firstHeading.css('padding-right', previewBar.width() + 25));
             }
          }
    
          $('#va-titleicons-more').append('<img width="0" height="0" class="va-titleicons-chevron" src="http://images.wikia.com/common/skins/common/blank.gif">');
    
          iconBar.hover(
             function () {
                $(this).addClass('va-titleicons-hover');
             }, function () {
                $(this).removeClass('va-titleicons-hover');
             });
       }
    }
    
    /* ######################################################################## */
    /* ### COLLAPSIBLE TABLES                                               ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Allow tables to be collapsible                      ### */
    /* ### Credit:      http://en.wikipedia.org/wiki/MediaWiki:Common.js    ### */
    /* ###              Customized for Fallout Wiki by User:Porter21        ### */
    /* ######################################################################## */
    
    /* Test if an element has a certain class **************************************
     *
     * 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);
       };
    })();
    
    /** Collapsible tables *********************************************************
     *
     *  Description: Allows tables to be collapsed, showing only the header. See
     *               [[Wikipedia:NavFrame]].
     *  Maintainers: [[User:R. Koot]]
     */
    
    var autoCollapse = 1;
    var collapseCaption = "hide";
    var expandCaption = "show";
    
    function collapseTable(tableIndex) {
       var Button = document.getElementById( "collapseButton" + tableIndex );
       var Table = document.getElementById( "collapsibleTable" + tableIndex );
    
       if ( !Table || !Button ) {
          return false;
       }
    
       var Rows = Table.rows;
    
       if ( Button.firstChild.data == collapseCaption ) {
          for ( var i = 1; i < Rows.length; i++ ) {
              Rows[i].style.display = "none";
          }
          Button.firstChild.data = expandCaption;
       } else {
          for ( var i = 1; i < Rows.length; i++ ) {
              Rows[i].style.display = Rows[0].style.display;
          }
          Button.firstChild.data = collapseCaption;
       }
    }
    
    function createCollapseButtons() {
       var tableIndex = 0;
       var collapseIndex = 0;
       var NavigationBoxes = new Object();
       var Tables = document.getElementsByTagName( "table" );
    
       for ( var i = 0; i < Tables.length; i++ ) {
          if ( hasClass( Tables[i], "collapsible" ) ) {
    
             /* only add button and increment count if there is a header row to work with */
             var HeaderRow = Tables[i].getElementsByTagName( "tr" )[0];
             if (!HeaderRow) continue;
             var Header = HeaderRow.getElementsByTagName( "th" )[0];
             if (!Header) continue;
    
             NavigationBoxes[ tableIndex ] = Tables[i];
             Tables[i].setAttribute( "id", "collapsibleTable" + tableIndex );
    
             var Button     = document.createElement( "span" );
             var ButtonLink = document.createElement( "a" );
             var ButtonText = document.createTextNode( collapseCaption );
    
             Button.style.styleFloat = "right";
             Button.style.cssFloat = "right";
             Button.style.fontWeight = "normal";
             Button.style.textAlign = "right";
             Button.style.width = "4em";
             Button.className = "t_show_hide";
    
             ButtonLink.style.color = Header.style.color;
             ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
             ButtonLink.setAttribute( "href", "javascript:collapseTable(" + tableIndex + ");" );
             ButtonLink.appendChild( ButtonText );
    
             Button.appendChild( document.createTextNode( "[" ) );
             Button.appendChild( ButtonLink );
             Button.appendChild( document.createTextNode( "]" ) );
    
             Header.insertBefore( Button, Header.childNodes[0] );
    
             if ( !hasClass( Tables[i], "nocount" ) ) {
                collapseIndex++;
    	 }
             tableIndex++;
          }
       }
    
       for ( var i = 0;  i < tableIndex; i++ ) {
          if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( collapseIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
             collapseTable( i );
          } 
          else if ( hasClass( NavigationBoxes[i], "innercollapse" ) ) {
             var element = NavigationBoxes[i];
             while (element = element.parentNode) {
                if ( hasClass( element, "outercollapse" ) ) {
                   collapseTable ( i );
                   break;
                }
             }
          }
       }
    }
    
    /* ######################################################################## */
    /* ### ARCHIVE TOOL                                                     ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: AJAX-archiving of talk pages via GUI                ### */
    /* ### Credit:      User:Dantman (original)                             ### */
    /* ###              User:Porter21 (Oasis & Monobook support)            ### */
    /* ######################################################################## */
    
    /*
     * Copyright © 2009, Daniel Friesen
     * All rights reserved.
     * 
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *     * Redistributions of source code must retain the above copyright
     *       notice, this list of conditions and the following disclaimer.
     *     * Redistributions in binary form must reproduce the above copyright
     *       notice, this list of conditions and the following disclaimer in the
     *       documentation and/or other materials provided with the distribution.
     *     * Neither the name of the script nor the
     *       names of its contributors may be used to endorse or promote products
     *       derived from this software without specific prior written permission.
     * 
     * THIS SOFTWARE IS PROVIDED BY DANIEL FRIESEN ''AS IS'' AND ANY
     * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     * DISCLAIMED. IN NO EVENT SHALL DANIEL FRIESEN BE LIABLE FOR ANY
     * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
     * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     */
    
    function archiveTool () {
       // Configuration
       var userconfig = (window.ArchiveToolConfig) ? window.ArchiveToolConfig : {};
       var config = $.extend(true, {
          archiveListTemplate: 'Archives',
          archivePageTemplate: 'Archivepage',
          archiveSubpage: 'Archive',
          userLang: false,
          // English
          en: {
             buttonArchiveTool: "Archive",
             buttonArchiveToolTooltip: "Archive this page",
             buttonSelectAll: "Select all",
             buttonDeselectAll: "Deselect all",
             buttonSaveArchive: "Save archive",
             buttonAbort: "Abort",
             labelLines: "Lines",
             labelSections: "Sections",
             summaryArchiveFrom: "ArchiveTool: Archiving from",
             summaryArchiveTo: "ArchiveTool: Archiving to"
          }
       }, userconfig);
    
       // Function for multi-language support
       function msg(name) {
          if ( config.userLang && wgUserLanguage in config && name in config[wgUserLanguage] )
             return config[wgUserLanguage][name];
          if ( wgContentLanguage in config && name in config[wgContentLanguage] )
             return config[wgContentLanguage][name];
          return config.en[name];
       }
       
       if (skin != "monaco" && skin != 'monobook' && skin != 'oasis' && skin != 'wikia') {
          return;
       }
    
       if ((wgNamespaceNumber%2 != 0 && wgNamespaceNumber != 501) && (wgAction == "view" || wgAction == "purge")) {
          var skinConfig = {
             textCont: '', pageControls: '', controlsMarkup: '',
             buttonOpenPri: '', buttonOpenSec: '', buttonClose: ''
          };
    
          switch(skin) {
             case 'monaco':
                skinConfig.textCont = '#bodyContent';
                skinConfig.pageControls = '#page_controls';
                skinConfig.controlsMarkup = '<li id="control_archive"><img src="/skins/common/blank.gif" class="sprite move" /><a id="ca-archive" title="' + msg('buttonArchiveToolTooltip') + '" href="#" rel="nofollow">' + msg('buttonArchiveTool') + '</a></li>';
                skinConfig.buttonOpenPri = '<a class="wikia-button">';
                skinConfig.buttonOpenSec = '<a class="wikia-button secondary">';
                skinConfig.buttonClose = '</a>';
                break;
             case 'monobook':
                skinConfig.textCont = '#bodyContent';
                skinConfig.pageControls = '#p-cactions > div > ul';
                skinConfig.controlsMarkup = '<li id="control_archive"><a id="ca-archive" title="' + msg('buttonArchiveToolTooltip') + '" href="#" rel="nofollow">' + msg('buttonArchiveTool') + '</a></li>';
                skinConfig.buttonOpenPri = '<input type="submit" style="font-weight: bold;" value="';
                skinConfig.buttonOpenSec = '<input type="submit" value="';
                skinConfig.buttonClose = '" />';
                break;
             case 'oasis':
             case 'wikia':
                skinConfig.textCont = '#WikiaArticle';
                skinConfig.pageControls = ((wgNamespaceNumber == 3) ? '#WikiaUserPagesHeader' : '#WikiaPageHeader') + ' > ul.wikia-menu-button > li > ul';
                skinConfig.controlsMarkup = '<li id="control_archive"><a id="ca-archive" rel="nofollow">' + msg('buttonArchiveTool') + '</a></li>';
                skinConfig.buttonOpenPri = '<a class="wikia-button">';
                skinConfig.buttonOpenSec = '<a class="wikia-button secondary">';
                skinConfig.buttonClose = '</a>';
                break;
          }
    
          $(function() {
             function api(q, fn) {
                q.format = 'json';
                return $.post(wgScriptPath + '/api.php', q, fn, "json");
             }
             function token(page, fn) {
                api({
                   action: 'query',
                   query: 'prop',
                   prop: 'info',
                   titles: page,
                   intoken: 'edit'
                }, function(q) {
                   for ( var k in q.query.pages )
                      return fn(q.query.pages[k]);
                });
             }
             
             function startArchiving() {
                var c = config.archiveListTemplate.substr(0,1);
                var archiveListRegex = '['+c.toUpperCase()+c.toLowerCase()+']'+config.archiveListTemplate.substr(1);
                var bc = $(skinConfig.textCont).addClass('va-archiving').empty();
    
                $('<img class="ajax" alt="Loading..." />')
                   .attr({src: stylepath+'/common/progress-wheel.gif'}).appendTo(bc);
                api({
                   action: 'query',
                   prop: 'revisions',
                   titles: wgPageName,
                   rvprop: 'timestamp|content'
                }, function(q) {
                   bc.empty();
                   var rev = q.query.pages[wgArticleId].revisions[0];
                   var time = rev.timestamp;
                   var talkToken, tokenTime;
                   var content = rev['*'];
                   token(wgPageName, function(p) {
                      talkToken = p.edittoken;
                      tokenTime = p.starttimestamp;
                   });
                   
                   var lines = content.split('\n');
                   
                   var table = $('<table style="margin: 10px 0;"><thead><tr><th>' + msg('labelLines') + '</th><th title="' + msg('labelSections') + '">{&hellip;}</th></tr></thead></table>').appendTo(bc);
                   var ul = $('<tbody/>').appendTo(table);
                   
                   for ( var l = 0; l < lines.length; l++ ) {
                      var line = lines[l];
                      $('<tr/>').toggleClass('noarchive', (new RegExp('^\\{\\{'+archiveListRegex+'\}\}')).test(line))
                         .attr({line:line})
                         .append( $('<td class=line />').text(line).append('&nbsp;') ).appendTo(ul);
                   }
                   
                   var sections = [];
                   var sectionEnd = lines.length-1;
                   for ( var l = lines.length-1; l >= 0; l-- ) {
                      var line = lines[l];
                      
                      if ( /^=.+?=/.test(line) || l === 0 ) {
                         var section = { start: l, end: sectionEnd };
                         section.length = section.end - section.start + 1;
                         sections.unshift(section);
                         
                         sectionEnd = l-1;
                      }
                   }
                   
                   var section;
                   while( section = sections.shift() ) {
                      var tr = ul.children().eq(section.start);
                      $('<td class=section />').attr({rowspan: section.length}).appendTo(tr);
                   }
                   
                   $('<div class="buttons" style="text-align: right;" />').append(
                      $(skinConfig.buttonOpenSec + msg('buttonSelectAll') + skinConfig.buttonClose).click(function(e) {
                         e.preventDefault();
                         ul.children('tr').addClass('archive');
                      }), ' ',
                      $(skinConfig.buttonOpenSec + msg('buttonDeselectAll') + skinConfig.buttonClose).click(function(e) {
                         e.preventDefault();
                         ul.children('tr').removeClass('archive');
                      }), ' ',
                      $(skinConfig.buttonOpenPri + msg('buttonSaveArchive') + skinConfig.buttonClose).click(function(e) {
                         archive();
                      }), ' ',
                      $(skinConfig.buttonOpenPri + msg('buttonAbort') + skinConfig.buttonClose).click(function(e) {
                         bc.find('.ajax').remove();
                         location = wgServer+wgScript+'?title='+encodeURI(wgPageName)+'&action=purge';
                      })
                   ).prependTo(bc).clone(true).appendTo(bc);
                   
                   var click = false;
                   var add;
                   table.mousedown(function(e) {
                      e.preventDefault();
                      var $li = $(e.target).closest('tr');
                      if(!$li.length) return;
                      var $section = $(e.target).closest('.section');
                      if ( $section.length ) {
                         var slist = $li.nextAll(':lt('+(parseInt($section.attr('rowspan'),10)-1)+')').andSelf();
                         var sadd = slist.filter(function() { return !$(this).hasClass('archive') }).length;
                         slist.toggleClass('archive', !!sadd);
                         return;
                      }
                      click = true;
                      add = !$li.hasClass('archive');
                      
                      $li.toggleClass('archive', !!add);
                   });
                   table.mouseover(function(e) {
                      if (!click) return;
                      var $li = $(e.target).closest('tr');
                      if(!$li.length) return;
                      
                      $li.toggleClass('archive', !!add);
                   });
                   $('body').mouseup(function(e) {
                      click = false;
                   });
                   
                   function archive() {
                      var talkLines = [];
                      var archiveLines = [];
                      ul.children().each(function() {
                         var arr = $(this).hasClass('noarchive') || !$(this).hasClass('archive')
                            ? talkLines : archiveLines;
                         
                         arr.push( $(this).attr('line') );
                      });
                      
                      if ( !(new RegExp('^\\{\\{'+archiveListRegex+'\}\}')).test(talkLines[0]) )
                         talkLines = ['{{'+config.archiveListTemplate+'}}', ''].concat(talkLines);
                      archiveLines = ['{{'+config.archivePageTemplate+'}}', ''].concat(archiveLines);
                      
                      bc.empty();
                      $('<img class="ajax" alt="Loading..." />')
                         .attr({src: stylepath+'/common/progress-wheel.gif'}).appendTo(bc);
                      
                      runArchive(talkLines.join('\n'), archiveLines.join('\n'));
                   }
                   
                   var archiveTitle;
                   function runArchive(talkContent, archiveContent) {
                      var archiveNo;
                      function findArchives() {
                         var m = $('<p>Finding archive id: </p>').appendTo(bc);
                         api({
                            action: 'query',
                            list: 'allpages',
                            apnamespace: wgNamespaceNumber,
                            apprefix: wgTitle+'/'+config.archiveSubpage,
                            aplimit: 1,
                            apdir: 'descending'
                         }, function(q) {
                            archiveNo = q.query.allpages.length ?
                               parseInt(q.query.allpages[0].title.substr(wgPageName.length+("/"+config.archiveSubpage).length),10)+1 :
                               1;
                            archiveTitle = wgPageName+'/'+config.archiveSubpage+' '+archiveNo;
                            m.append('done... (using '+archiveNo+')');
                            
                            saveArchive();
                         });
                      }
                      
                      function saveArchive() {
                         var m = $('<p>Finding token for '+archiveTitle+': </p>').appendTo(bc);
                         token(archiveTitle, function(p) {
                            m.append('done...');
                            m = $('<p>Saving archive page: </p>').appendTo(bc);
                            api({
                               action: 'edit',
                               title: archiveTitle,
                               text: archiveContent,
                               token: p.edittoken,
                               summary: msg('summaryArchiveFrom') + " [[" + wgPageName + "]].",
                               minor: true,
                               createonly: true
                            }, function(q) {
                               if ( q.error && q.error.code === "articleexists" ) {
                                  m.append('failed...');
                                  bc.append("<p>The archive page we tried to create already exists.</p>");
                                  return abort();
                               }
                               m.append('done...');
                               
                               saveTalk();
                            });
                         });
                      }
                      
                      function saveTalk() {
                         var m = $('<p>Finding token for '+wgPageName+': </p>').appendTo(bc);
                         m.append('done...');
                         m = $('<p>Updating talk page: </p>').appendTo(bc);
                         api({
                            action: 'edit',
                            title: wgPageName,
                            text: talkContent,
                            token: talkToken,
                            summary: msg('summaryArchiveTo') + " [[" + archiveTitle + "]].",
                            minor: true,
                            basetimestamp: time,
                            starttimestamp: tokenTime
                         }, function(q) {
                            if ( q.edit.result === "Success" ) {
                               m.append('done...');
                               bc.find('.ajax').remove();
                               location = wgServer+wgScript+'?title='+encodeURI(wgPageName)+'&action=purge';
                            } else {
                               m.append('failed...');
                               bc.append("<p>Failed to update talkpage, you may wish to have the archive subpage we just created deleted.</p>");
                               return abort();
                            }
                         });
                      }
                      
                      function abort() {
                         bc.find('.ajax').remove();
                         bc.append("<p>Aborting...</p>");
                         
                         $("<p>You may want to </p>")
                            .append( $('<a>refresh</a>').attr({href: wgServer+wgArticlePath.replace('$1', encodeURI(wgPageName))}) )
                            .append(' and try again.')
                            .appendTo(bc);
                      }
                      
                      // start
                      findArchives();
                   }
                });
             }
             
             $(skinConfig.controlsMarkup)
                .click(startArchiving)
                .appendTo(skinConfig.pageControls);
          });
       }
    }
    
    /* ######################################################################## */
    /* ### AJAX RC                                                          ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Automatically refresh "Recent changes" via AJAX     ### */
    /* ### Credit:      User:pcj (http://www.wowpedia.org)                  ### */
    /* ######################################################################## */
    
    var ajaxIndicator = stylepath + '/common/progress-wheel.gif';
    var ajaxPages = new Array("Special:RecentChanges", "Special:WikiActivity", "The_Vault:WikiActivity");
    var ajaxTimer;
    var ajaxRefresh = 60000;
    var refreshText = 'Auto-refresh';
    var refreshHover = 'Enable auto-refreshing page loads';
    var doRefresh = true;
    
    function setCookie(c_name,value,expiredays) {
       var exdate=new Date()
       exdate.setDate(exdate.getDate()+expiredays)
       document.cookie=c_name+ "=" +escape(value) + ((expiredays==null) ? "" : ";expires="+exdate.toGMTString())
    }
     
    function getCookie(c_name) {
       if (document.cookie.length>0) {
          c_start=document.cookie.indexOf(c_name + "=")
          if (c_start!=-1) { 
             c_start=c_start + c_name.length+1 
             c_end=document.cookie.indexOf(";",c_start)
             if (c_end==-1) c_end=document.cookie.length
             return unescape(document.cookie.substring(c_start,c_end))
          } 
       }
       return ""
    }
     
    function preloadAJAXRL() {
       ajaxRLCookie = (getCookie("ajaxload-"+wgPageName)=="on") ? true:false;
       appTo = ($("#WikiaPageHeader").length)?$("#WikiaPageHeader > h1"):$(".firstHeading");
       appTo.append('&#160;<span style="font-size: xx-small; line-height: 100%;" id="ajaxRefresh"><span style="border-bottom: 1px dotted; cursor: help;" id="ajaxToggleText" title="' + refreshHover + '">' + refreshText + ':</span><input type="checkbox" style="margin-bottom: 0;" id="ajaxToggle"><span style="display: none;" id="ajaxLoadProgress"><img src="' + ajaxIndicator + '" style="vertical-align: baseline;" border="0" alt="Refreshing page" /></span></span>');
       $("#ajaxLoadProgress").ajaxSend(function (event, xhr, settings){
          if (location.href == settings.url) $(this).show();
       }).ajaxComplete (function (event, xhr, settings){
          if (location.href == settings.url) $(this).hide();
       });
       $("#ajaxToggle").click(toggleAjaxReload);
       $("#ajaxToggle").attr("checked", ajaxRLCookie);
       if (getCookie("ajaxload-"+wgPageName)=="on") loadPageData();
    }
     
    function toggleAjaxReload() {
       if ($("#ajaxToggle").attr("checked") == true) {
          setCookie("ajaxload-"+wgPageName, "on", 30);
          doRefresh = true;
          loadPageData();
       } else {
          setCookie("ajaxload-"+wgPageName, "off", 30);
          doRefresh = false;
          clearTimeout(ajaxTimer);
       }
    }
    
    function loadPageData() {
       cC = ($("#WikiaArticle").length)?"#WikiaArticle":"#bodyContent";
       $(cC).load(location.href + " " + cC + " > *", function (data) { 
          if (doRefresh) ajaxTimer = setTimeout("loadPageData();", ajaxRefresh);
       });
    }
    
    /* ######################################################################## */
    /* ### DISABLE ARCHIVE EDIT                                             ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Remove section edit links and gray out main edit    ### */
    /* ###              button on archived talk pages                       ### */
    /* ### Credit:      User:Porter21                                       ### */
    /* ######################################################################## */
    
    function disableArchiveEdit () {
       // Configuration
       var userconfig = (window.DisableArchiveEditConfig) ? window.DisableArchiveEditConfig : {};
       var config = $.extend(true, {
          archiveSubpage: 'Archive',
          disableCompletely: false,
          textColor: '#D9D9D9',
          userLang: false,
          // English
          en: {
             archived: "Archived",
             archivedTooltip: "This page is an archive and should not be edited."
          }
       }, userconfig);
     
       // Function for multi-language support (by Daniel Friesen aka User:Dantman)
       function msg(name) {
          if ( config.userLang && wgUserLanguage in config && name in config[wgUserLanguage] )
             return config[wgUserLanguage][name];
          if ( wgContentLanguage in config && name in config[wgContentLanguage] )
             return config[wgContentLanguage][name];
          return config.en[name];
       }
     
       // Check whether page is an archive
       if ((new RegExp('\\/\[' + config.archiveSubpage.substr(0,1).toUpperCase()
          + config.archiveSubpage.substr(0,1).toLowerCase() + '\]' + config.archiveSubpage.substr(1)
          + '\\s\*\\d\*')).test(wgTitle)) {
          // Remove "add new section" links and prepare altering "edit" page control
          switch (skin) {
             case 'monaco':
                $('#control_addsection').remove();
                $('#fe_newsection').remove();
     
                editlink = $('#ca-edit');
                break;
             case 'monobook':
                $('#ca-addsection').remove();
     
                editlink = $('#ca-edit > a');
                break;
             case 'oasis':
             case 'wikia':
                var oasisButton = $(((wgNamespaceNumber == 3) ? '#WikiaUserPagesHeader' : '#WikiaPageHeader') + ' > ul.wikia-menu-button > li');
     
                oasisButton.children("a:first").prependTo($('ul:first', oasisButton)).wrap('<li />').children('img').remove();
                oasisButton.prepend('<a />');
                $('a[data-id="addtopic"]', oasisButton).parent().remove();
     
                editlink = $('a:first', oasisButton);
                break;
          }
     
          // Remove "edit section" links
          $('span.editsection').remove();
     
          // Alter "edit" page control
          if (config.disableCompletely) {
             editlink.remove();
          } else {
             editlink.attr('title', msg('archivedTooltip')).css('color', config.textColor).text(msg('archived'));
          }
       }
    }
     
    /* ######################################################################## */
    /* ### COUNTDOWN                                                        ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Adds countdown to specific date to a page.          ### */
    /* ###              (jQuery version of http://dev.wikia.com/Countdown)  ### */
    /* ### Credit:      User:Splarka (original)                             ### */
    /* ###              User:Porter21 (jQuery version)                      ### */
    /* ######################################################################## */
    
    // Usage example:
    // <span class="countdown" style="display:none;">January 01 2020 00:00:00 PST</span>
    
    function updateCountdowns(targets, countdowns) {
       var now = new Date();
    
       now = now.getTime();
    
       countdowns.each(function(i) {
          var diff = Math.floor((targets[i]-now)/1000);
    
          // determine plus/minus
          if (diff < 0 ) { diff = -diff; }
    
          // convert the difference into readable formatting
          var left = (diff%60) + ' seconds';
    
          diff = Math.floor(diff/60);
          if (diff > 0) { left = (diff%60) + ' minutes ' + left; }
          diff = Math.floor(diff/60);
          if (diff > 0) { left = (diff%24) + ' hours ' + left; }
          diff = Math.floor(diff/24);
          if (diff > 0) { left = diff + ' days ' + left; }
    
          $(this).text(left);
       });
    
       setTimeout(function() { updateCountdowns(targets, countdowns); }, 1000);
    }
    
    function addCountdowns() {
       var targets = [];
       var countdowns = $('span.countdown').filter(function() {
          var content = $(this).text();
          var converted = new Date(content);
    
          if (content == "" || isNaN(converted)) {
             return false;
          } else {
             $(this).css("display", "inline");
             targets[targets.length] = converted.getTime();
             return true;
          }
       });
    
       if (targets.length <= 0) {
          return;
       }
    
       updateCountdowns(targets, countdowns);
    }
    
    /* ######################################################################## */
    /* ### DUPLICATE FILE LIST                                              ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Finds duplicate files on the wiki.                  ### */
    /* ### Credit:      User:pcj (http://www.wowpedia.org)                  ### */
    /* ######################################################################## */
    
    function findDupFiles(gf) {
       var fileDiv = $('#mw-dupfiles');
    
       if (fileDiv.length) {
          dil = new Array();
          ajaxIndicator = stylepath + '/common/progress-wheel.gif';
          output = '';
          url = '/api.php?action=query&generator=allimages&prop=duplicatefiles&gailimit=500&format=json';
    
          if (!($('#dupFilesProgress').length)) {
             fileDiv.prepend('<span style="float: right;" id="dupFilesProgress" title="In progress..."><img src="' + ajaxIndicator + '" style="vertical-align: baseline;" border="0" alt="In progress..." /></span>');
          }
    
          if (gf) {
             url += "&gaifrom=" + gf;
          }
    
          $.getJSON( url, function (data) {
             if ( data.query ) {
                pages = data.query.pages;
    
                for (pageID in pages) {
                   dils = "," + dil.join();
    
                   if ( dils.indexOf("," + pages[pageID].title) == -1 
                      && pages[pageID].title.indexOf("File::") == -1 && pages[pageID].duplicatefiles ) {
                      output += "<h3><a href='/wiki/" + encodeURIComponent(pages[pageID].title).replace(/'/g, "%27") + "'>" + pages[pageID].title + "</a></h3>\n<ul>\n";
    
                      for ( x = 0; x < pages[pageID].duplicatefiles.length; x++ ) {
                         output += "<li><a href='/wiki/File:" + encodeURIComponent(pages[pageID].duplicatefiles[x].name).replace(/'/g, "%27") + "'>File:" + pages[pageID].duplicatefiles[x].name + "</a></li>\n";
                         dil.push("File:" + pages[pageID].duplicatefiles[x].name.replace(/_/g, " "));
                      }
                      output += "</ul>\n\n"
                   }
                }
    
                fileDiv.append(output);
    
                if (data["query-continue"]) {
                   setTimeout("findDupFiles('" + encodeURIComponent(data["query-continue"].allimages.gaifrom).replace(/'/g, "%27") + "');", 5000);
                } else {
                   $('#dupFilesProgress').hide();
                }
             }
          } );
       }
    }
    
    /* ######################################################################## */
    /* ### SCRIPT LOADER                                                    ### */
    /* ### ---------------------------------------------------------------- ### */
    /* ### Description: Loads all the other scripts                         ### */
    /* ### Credit:      User:Porter21                                       ### */
    /* ######################################################################## */
    
    function vaultScriptLoader () {
       // Always loaded
       addCountdowns();
       createCollapseButtons();
    
       // Only loaded for specific namespaces
       if ((wgNamespaceNumber == 0 || wgNamespaceNumber == 4 || wgNamespaceNumber == 110 || wgNamespaceNumber == 502) &&
          !wgIsMainpage) {
          addTitleIcons();
       }
    
       if (wgNamespaceNumber%2 != 0 && wgNamespaceNumber != 501) {
          archiveTool();
          disableArchiveEdit();
       }
    
       // Only loaded for specific pages
       if (wgPageName == 'The_Vault:Duplicate_files') {
          findDupFiles();
       }
       for (x in ajaxPages) {
          if (wgPageName == ajaxPages[x] && $("#ajaxToggle").length==0) preloadAJAXRL();
       }
    }
    
    jQuery(function($) {
       vaultScriptLoader();
    });
    
    /* </nowiki> */