MediaWiki:Common.js: Difference between revisions

From The Sims Wiki, a collaborative database for The Sims series
Jump to navigation Jump to search
Content added Content deleted
(stuff from Wikipedia)
(Undid revision 2658 by K6ka (talk))
Line 516: Line 516:
/* END countdown timer */
/* END countdown timer */


/** Collapsible tables *********************************************************
/**
* Collapsible tables
*
*
* Allows tables to be collapsed, showing only the header. See [[Help:Collapsing]].
* Description: Allows tables to be collapsed, showing only the header. See
* [[Wikipedia:NavFrame]].
*
* Taken from Wikipedia's Common.js.
* @version 2.0.3 (2014-03-14)
* @source https://www.mediawiki.org/wiki/MediaWiki:Gadget-collapsibleTables.js
* @author [[User:R. Koot]]
* @author [[User:Krinkle]]
* @deprecated Since MediaWiki 1.20: Use class="mw-collapsible" instead which
* is supported in MediaWiki core.
*
* Taken from [[wikipedia:MediaWiki:Common.js]]
*/
*/

var hasClass = (function() {
var reCache = {};
return function(element, className) {
return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
};
})();
var autoCollapse = 2;
var autoCollapse = 2;
var collapseCaption = 'hide';
var collapseCaption = "hide";
var expandCaption = 'show';
var expandCaption = "show";
var tableIndex = 0;
function collapseTable(tableIndex) {

var Button = document.getElementById("collapseButton" + tableIndex);
function collapseTable( tableIndex ) {
var Button = document.getElementById( 'collapseButton' + tableIndex );
var Table = document.getElementById("collapsibleTable" + tableIndex);
var Table = document.getElementById( 'collapsibleTable' + tableIndex );
if (!Table || !Button) {

if ( !Table || !Button ) {
return false;
return false;
}
}

var Rows = Table.rows;
var Rows = Table.rows;
var i;
if (Button.firstChild.data == collapseCaption) {
var $row0 = $(Rows[0]);
for (var i = 1; i < Rows.length; i++) {

Rows[i].style.display = "none";
if ( Button.firstChild.data === collapseCaption ) {
for ( i = 1; i < Rows.length; i++ ) {
Rows[i].style.display = 'none';
}
}
Button.firstChild.data = expandCaption;
Button.firstChild.data = expandCaption;
} else {
} else {
for ( i = 1; i < Rows.length; i++ ) {
for (var i = 1; i < Rows.length; i++) {
Rows[i].style.display = $row0.css( 'display' );
Rows[i].style.display = Rows[0].style.display;
}
}
Button.firstChild.data = collapseCaption;
Button.firstChild.data = collapseCaption;
}
}
}
}

function createClickHandler( tableIndex ) {
function createCollapseButtons() {
return function ( e ) {
var tableIndex = 0;
e.preventDefault();
var NavigationBoxes = new Object();
var Tables = document.getElementsByTagName("table");
collapseTable( tableIndex );
};
for (var i = 0; i < Tables.length; i++) {
}
if (hasClass(Tables[i], "collapsible")) {

function createCollapseButtons( $content ) {
var NavigationBoxes = {};
var $Tables = $content.find( 'table' );
var i;

$Tables.each( function( i, table ) {
if ( $(table).hasClass( 'collapsible' ) ) {

/* only add button and increment count if there is a header row to work with */
/* only add button and increment count if there is a header row to work with */
var HeaderRow = table.getElementsByTagName( 'tr' )[0];
var HeaderRow = Tables[i].getElementsByTagName("tr")[0];
if ( !HeaderRow ) {
if (!HeaderRow) continue;
return;
var Header = HeaderRow.getElementsByTagName("th")[0];
}
if (!Header) continue;
var Header = table.getElementsByTagName( 'th' )[0];
if ( !Header ) {
NavigationBoxes[tableIndex] = Tables[i];
return;
Tables[i].setAttribute("id", "collapsibleTable" + tableIndex);
}
var Button = document.createElement("span");

NavigationBoxes[ tableIndex ] = table;
var ButtonLink = document.createElement("a");
var ButtonText = document.createTextNode(collapseCaption);
table.setAttribute( 'id', 'collapsibleTable' + tableIndex );

var Button = document.createElement( 'span' );
Button.style.styleFloat = "right";
var ButtonLink = document.createElement( 'a' );
Button.style.cssFloat = "right";
Button.style.fontWeight = "normal";
var ButtonText = document.createTextNode( collapseCaption );
Button.style.textAlign = "right";
// Styles are declared in [[MediaWiki:Common.css]]
Button.className = 'collapseButton';
Button.style.width = "3.5em";

ButtonLink.style.color = Header.style.color;
ButtonLink.style.color = Header.style.color;
ButtonLink.setAttribute( 'id', 'collapseButton' + tableIndex );
ButtonLink.setAttribute("id", "collapseButton" + tableIndex);
ButtonLink.setAttribute( 'href', '#' );
ButtonLink.setAttribute("href", "javascript:collapseTable(" + tableIndex + ");");
$( ButtonLink ).on( 'click', createClickHandler( tableIndex ) );
ButtonLink.appendChild(ButtonText);
ButtonLink.appendChild( ButtonText );
Button.appendChild(document.createTextNode("["));

Button.appendChild( document.createTextNode( '[' ) );
Button.appendChild(ButtonLink);
Button.appendChild( ButtonLink );
Button.appendChild(document.createTextNode("]"));
Button.appendChild( document.createTextNode( ']' ) );
Header.insertBefore(Button, Header.childNodes[0]);

Header.insertBefore( Button, Header.firstChild );
tableIndex++;
tableIndex++;
}
}
} );
}

for ( i = 0; i < tableIndex; i++ ) {
for (var i = 0; i < tableIndex; i++) {
if ( $( NavigationBoxes[i] ).hasClass( 'collapsed' ) ||
if (hasClass(NavigationBoxes[i], "collapsed") || (tableIndex >= autoCollapse && hasClass(NavigationBoxes[i], "autocollapse"))) {
collapseTable(i);
( tableIndex >= autoCollapse && $( NavigationBoxes[i] ).hasClass( 'autocollapse' ) )
) {
collapseTable( i );
}
else if ( $( NavigationBoxes[i] ).hasClass ( 'innercollapse' ) ) {
var element = NavigationBoxes[i];
while ((element = element.parentNode)) {
if ( $( element ).hasClass( 'outercollapse' ) ) {
collapseTable ( i );
break;
}
}
}
}
}
}
}
}
addOnloadHook(createCollapseButtons);
/* END Collapsible Tables */


/** Dynamic Navigation Bars (experimental) *************************************
mw.hook( 'wikipage.content' ).add( createCollapseButtons );

/**
* Add support to mw-collapsible for autocollapse, innercollapse and outercollapse
*
*
* Description: See [[Wikipedia:NavFrame]].
* Maintainers: TheDJ
* Taken from Wikipedia's Common.js.
*/
*/
function mwCollapsibleSetup( $collapsibleContent ) {
// set up the words in your language
var $element,
autoCollapseThreshold = 2;
$.each( $collapsibleContent, function (index, element) {
$element = $( element );
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();
}
}
} );
}

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

/**
* Dynamic Navigation Bars (experimental)
*
* Description: See [[Wikipedia:NavFrame]].
* Taken from [[wikipedia:MediaWiki:Common.js]]
*/

/* set up the words in your language */
var NavigationBarHide = '[' + collapseCaption + ']';
var NavigationBarHide = '[' + collapseCaption + ']';
var NavigationBarShow = '[' + expandCaption + ']';
var NavigationBarShow = '[' + expandCaption + ']';
var indexNavigationBar = 0;
// shows and hides content and picture (if available) of navigation bars

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

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

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

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

event.preventDefault();
// adds show/hide-button to navigation bars
};

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

// if found a navigation bar
if (hasClass(NavFrame, "NavFrame")) {
indexNavigationBar++;
indexNavigationBar++;
var NavToggle = document.createElement( 'a' );
var NavToggle = document.createElement("a");
NavToggle.className = 'NavToggle';
NavToggle.className = 'NavToggle';
NavToggle.setAttribute( 'id', 'NavToggle' + indexNavigationBar );
NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
NavToggle.setAttribute( 'href', '#' );
NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
$( NavToggle ).on( 'click', $.proxy( window.toggleNavigationBar, window, indexNavigationBar ) );
var NavToggleText = document.createTextNode(NavigationBarHide);

var isCollapsed = $( NavFrame ).hasClass( 'collapsed' );
for (
/**
var NavChild = NavFrame.firstChild;
NavChild != null;
* Check if any children are already hidden. This loop is here for backwards compatibility:
NavChild = NavChild.nextSibling) {
* the old way of making NavFrames start out collapsed was to manually add style="display:none"
if (hasClass(NavChild, 'NavPic') || hasClass(NavChild, 'NavContent')) {
* to all the NavPic/NavContent elements. Since this was bad for accessibility (no way to make
if (NavChild.style.display == 'none') {
* the content visible without JavaScript support), the new recommended way is to add the class
NavToggleText = document.createTextNode(NavigationBarShow);
* "collapsed" to the NavFrame itself, just like with collapsible tables.
*/
break;
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 ) {
NavToggle.appendChild(NavToggleText);
for ( NavChild = NavFrame.firstChild; NavChild != null; NavChild = NavChild.nextSibling ) {
// Find the NavHead and attach the toggle link (Must be this complicated because Moz's firstChild handling is borked)
if ( $( NavChild ).hasClass( 'NavPic' ) || $( NavChild ).hasClass( 'NavContent' ) ) {
NavChild.style.display = 'none';
for (
}
var j = 0;
j < NavFrame.childNodes.length;
j++) {
if (hasClass(NavFrame.childNodes[j], "NavHead")) {
NavFrame.childNodes[j].appendChild(NavToggle);
}
}
}
}
NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
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 );
addOnloadHook(createNavigationBarToggleButton);
/* END Create Navbar Toggle Button */

/* END adds show/hide-button to navigation bars */

Revision as of 21:02, 23 February 2019

/* Any JavaScript here will be loaded for all users on every page load. */

/* Begin countdown timer */
// __NOWYSIWYG__
/**
 * Countdown
 *
 * @version 2.1
 *
 * @author Pecoes <https://c.wikia.com/wiki/User:Pecoes>
 * @author Asaba <https://dev.wikia.com/wiki/User:Asaba>
 *
 * Version 1 authors:
 * - Splarka <https://c.wikia.com/wiki/User:Splarka>
 * - Eladkse <https://c.wikia.com/wiki/User:Eladkse>
 *
 * documentation and examples at:
 * <https://dev.wikia.com/wiki/Countdown>
 */
 
/*jshint jquery:true, browser:true, devel:true, camelcase:true, curly:false, undef:true, bitwise:true, eqeqeq:true, forin:true, immed:true, latedef:true, newcap:true, noarg:true, unused:true, regexp:true, strict:true, trailing:false */
/*global mediaWiki:true*/
 
;(function (module, mw, $, undefined) {
 
	'use strict';
 
	var translations = $.extend(true, {
		// Language list - start
		// Arabic (العربية)
		ar: {
			and: 'و',
			second: 'ثانية',
			seconds: 'ثواني',
			minute: 'دقيقة',
			minutes: 'دقائق',
			hour: 'ساعة',
			hours: 'ساعات',
			day: 'يوم',
			days: 'أيام'
		},
		// Belarusian (Беларуская)
		be: {
			and: 'і',
			second: 'секунда',
			seconds: 'секунд',
			minute: 'хвіліна',
			minutes: 'хвілін',
			hour: 'гадзіну',
			hours: 'гадзін',
			day: 'дзень',
			days: 'дзён'
		},
		// Catalan (Català)
		ca: {
			and: 'i',
			second: 'segon',
			seconds: 'segons',
			minute: 'minut',
			minutes: 'minuts',
			hour: 'hora',
			hours: 'hores',
			day: 'dia',
			days: 'dies'
		},
		// German (Deutsch)
		de: {
			and: 'und',
			second: 'Sekunde',
			seconds: 'Sekunden',
			minute: 'Minute',
			minutes: 'Minuten',
			hour: 'Stunde',
			hours: 'Stunden',
			day: 'Tag',
			days: 'Tage'
		},
		// English (English)
		en: {
			and: 'and',
			second: 'second',
			seconds: 'seconds',
			minute: 'minute',
			minutes: 'minutes',
			hour: 'hour',
			hours: 'hours',
			day: 'day',
			days: 'days'
		},
		// Greek (Ελληνικά)
		el: {
			and: 'και',
			second: 'δευτερόλεπτο',
			seconds: 'δευτερόλεπτα',
			minute: 'λεπτό',
			minutes: 'λεπτά',
			hour: 'ώρα',
			hours: 'ώρες',
			day: 'ημέρα',
			days: 'ημέρες'
		},
		// Spanish (Español)
		es: {
			and: 'y',
			second: 'segundo',
			seconds: 'segundos',
			minute: 'minuto',
			minutes: 'minutos',
			hour: 'hora',
			hours: 'horas',
			day: 'día',
			days: 'días'
		},
		// French (Français)
		fr: {
			and: 'et',
			second: 'seconde',
			seconds: 'secondes',
			minute: 'minute',
			minutes: 'minutes',
			hour: 'heure',
			hours: 'heures',
			day: 'jour',
			days: 'jours'
		},
		// Hungarian (Magyar)
		hu: {
			and: 'és',
			second: 'másodperc',
			seconds: 'másodperc',
			minute: 'perc',
			minutes: 'perc',
			hour: 'óra',
			hours: 'óra',
			day: 'nap',
			days: 'nap'
		},
		// Indonesia (Bahasa Indonesia)
		id: {
			and: 'dan',
			second: 'detik',
			seconds: 'detik',
			minute: 'menit',
			minutes: 'menit',
			hour: 'jam',
			hours: 'jam',
			day: 'hari',
			days: 'hari'
		},
		// Italian (Italiano)
		it: {
			and: 'e',
			second: 'secondo',
			seconds: 'secondi',
			minute: 'minuto',
			minutes: 'minuti',
			hour: 'ora',
			hours: 'ore',
			day: 'giorno',
			days: 'giorni'
		},
		// Japanese (日本語)
		ja: {
			and: '',
			second: '秒',
			seconds: '秒',
			minute: '分',
			minutes: '分',
			hour: '時間',
			hours: '時間',
			day: '日',
			days: '日'
		},
		// Malay (Bahasa Melayu)
		ms: {
			and: 'dan',
			second: 'saat',
			seconds: 'saat',
			minute: 'minit',
			minutes: 'minit',
			hour: 'jam',
			hours: 'jam',
			day: 'hari',
			days: 'hari'
		},
		// Dutch (Nederlands)
		nl: {
			and: 'en',
			second: 'seconde',
			seconds: 'seconden',
			minute: 'minuut',
			minutes: 'minuten',
			hour: 'uur',
			hours: 'uur',
			day: 'dag',
			days: 'dagen'
		},
		// Polish (Polski)
		pl: {
			and: 'i',
			second: 'sekunda',
			seconds: 'sekund(y)',
			minute: 'minuta',
			minutes: 'minut(y)',
			hour: 'godzina',
			hours: 'godzin(y)',
			day: 'dzień',
			days: 'dni'
		},
		// Portuguese (Português)
		pt: {
			and: 'e',
			second: 'segundo',
			seconds: 'segundos',
			minute: 'minuto',
			minutes: 'minutos',
			hour: 'hora',
			hours: 'horas',
			day: 'dia',
			days: 'dias'
		},
		// Brazilian Portuguese (Português do Brasil)
		'pt-br': {
			and: 'e',
			second: 'segundo',
			seconds: 'segundos',
			minute: 'minuto',
			minutes: 'minutos',
			hour: 'hora',
			hours: 'horas',
			day: 'dia',
			days: 'dias'
		},
		// Romanian (Română)
		ro: {
			and: 'și',
			second: 'secundă',
			seconds: 'secunde',
			minute: 'minut',
			minutes: 'minute',
			hour: 'oră',
			hours: 'ore',
			day: 'zi',
			days: 'zile',
		},
		// Russian (русский)
		ru: {
			and: 'и',
			second: 'секунда',
			seconds: 'секунд',
			minute: 'минута',
			minutes: 'минут',
			hour: 'час',
			hours: 'часов',
			day: 'день',
			days: 'дней'
		},
		// Serbian (српски језик)
		sr: {
			and: 'i',
			second: 'sekundu',
			seconds: 'sekunde/-i',
			minute: 'minutu',
			minutes: 'minute/-a',
			hour: 'sat',
			hours: 'sata/-i',
			day: 'dan',
			days: 'dana'
		},
		// Tagalog
		tl: {
			and: 'at',
			second: 'segundo',
			seconds: 'mga segundo',
			minute: 'minuto',
			minutes: 'mga minuto',
			hour: 'oras',
			hours: 'mga oras',
			day: 'araw',
			days: 'mga araw'
		},
		// Turkish (Türkçe)
		tr: {
			and: 've',
			second: 'saniye',
			seconds: 'saniye',
			minute: 'dakika',
			minutes: 'dakika',
			hour: 'saat',
			hours: 'saat',
			day: 'gün',
			days: 'gün'
		},
		// Ukrainian (Українська)
		uk: {
			and: 'та',
			second: 'секунда',
			seconds: 'секунд',
			minute: 'хвилина',
			minutes: 'хвилин',
			hour: 'годину',
			hours: 'годин',
			day: 'день',
			days: 'днів'
		},
		// Vietnamese (Tiếng Việt)
		vi: {
			and: 'và',
			second: 'giây',
			seconds: 'giây',
			minute: 'phút',
			minutes: 'phút',
			hour: 'giờ',
			hours: 'giờ',
			day: 'ngày',
			days: 'ngày'
		},
		// Chinese (中文)
		zh: {
			and: ' ',
			second: '秒',
			seconds: '秒',
			minute: '分',
			minutes: '分',
			hour: '小时',
			hours: '小时',
			day: '天',
			days: '天'
		},
 
		// Chinese (繁體中文)
		'zh-tw':{
			and: ' ',
			second: '秒',
			seconds: '秒',
			minute: '分',
			minutes: '分',
			hour: '小時',
			hours: '小時',
			day: '天',
			days: '天'
		},
 
		// Chinese (香港)
		'zh-hk':{
			and: ' ',
			second: '秒',
			seconds: '秒',
			minute: '分',
			minutes: '分',
			hour: '小時',
			hours: '小時',
			day: '天',
			days: '天'
		}
		// Language list - stop
	}, module.translations || {}),
	i18n = translations[
		mw.config.get('wgContentLanguage')
	] || translations.en;
 
	var countdowns = [];
 
	var NO_LEADING_ZEROS = 1,
	SHORT_FORMAT = 2,
	NO_ZEROS = 4;
 
	function output (i, diff) {
		/*jshint bitwise:false*/
		var delta, result, parts = [];
		delta = diff % 60;
		result = ' ' + i18n[delta === 1 ? 'second' : 'seconds'];
		if (countdowns[i].opts & SHORT_FORMAT) result = result.charAt(1);
		parts.unshift(delta + result);
		diff = Math.floor(diff / 60);
		delta = diff % 60;
		result = ' ' + i18n[delta === 1 ? 'minute' : 'minutes'];
		if (countdowns[i].opts & SHORT_FORMAT) result = result.charAt(1);
		parts.unshift(delta + result);
		diff = Math.floor(diff / 60);
		delta = diff % 24;
		result = ' ' + i18n[delta === 1 ? 'hour'   : 'hours'  ];
		if (countdowns[i].opts & SHORT_FORMAT) result = result.charAt(1);
		parts.unshift(delta + result);
		diff = Math.floor(diff / 24);
		result = ' ' + i18n[diff  === 1 ? 'day'    : 'days'   ];
		if (countdowns[i].opts & SHORT_FORMAT) result = result.charAt(1);
		parts.unshift(diff  + result);
		result = parts.pop();
		if (countdowns[i].opts & NO_LEADING_ZEROS) {
			while (parts.length && parts[0][0] === '0') {
				parts.shift();
			}
		}
		if (countdowns[i].opts & NO_ZEROS) {
			parts = parts.filter(function(part) {
				return part[0] !== '0';
			});
		}
		if (parts.length) {
			if (countdowns[i].opts & SHORT_FORMAT) {
				result = parts.join(' ') + ' ' + result;
			} else {
				result = parts.join(', ') + ' ' + i18n.and + ' ' + result;
			}
		}
		countdowns[i].node.text(result);
	}
 
	function end(i) {
		var c = countdowns[i].node.parent();
		switch (c.attr('data-end')) {
		case 'remove':
			c.remove();
			return true;
		case 'stop':
			output(i, 0);
			return true;
		case 'toggle':
			var toggle = c.attr('data-toggle');
			if (toggle && toggle == 'next') {
				c.next().css('display', 'inline');
				c.css('display', 'none');
				return true;
			}
			if (toggle && $(toggle).length) {
				$(toggle).css('display', 'inline');
				c.css('display', 'none');
				return true;
			}
			break;
		case 'callback':
			var callback = c.attr('data-callback');
			if (callback && $.isFunction(module[callback])) {
				output(i, 0);
				module[callback].call(c);
				return true;
			}
			break;
		}
		countdowns[i].countup = true;
		output(i, 0);
		return false;
	}
 
	function update () {
		var now = Date.now();
		var countdownsToRemove = [];
		$.each(countdowns.slice(0), function (i, countdown) {
			var diff = Math.floor((countdown.date - now) / 1000);
			if (diff <= 0 && !countdown.countup) {
				if (end(i)) countdownsToRemove.push(i);
			} else {
				output(i, Math.abs(diff));
			}
		});
		var x;
		while((x = countdownsToRemove.pop()) !== undefined) {
			countdowns.splice(x, 1);
		}
		if (countdowns.length) {
			window.setTimeout(function () {
				update();
			}, 1000);
		}
	}
 
	function getOptions (node) {
		/*jshint bitwise:false*/
		var text = node.parent().attr('data-options'),
			opts = 0;
		if (text) {
			if (/no-leading-zeros/.test(text)) {
				opts |= NO_LEADING_ZEROS;
			}
			if (/short-format/.test(text)) {
				opts |= SHORT_FORMAT;
			}
			if (/no-zeros/.test(text)) {
				opts |= NO_ZEROS;
			}
		}
		return opts;
	}
 
	function init() {
		var countdown = $('.countdown:not(.handled)');
		if (!countdown.length) return;
		$('.nocountdown').css('display', 'none');
		countdown
		.css('display', 'inline')
		.find('.countdowndate')
		.each(function () {
			var $this = $(this),
				date = (new Date($this.text())).valueOf();
			if (isNaN(date)) {
				$this.text('BAD DATE');
				return;
			}
			countdowns.push({
				node: $this,
				opts: getOptions($this),
				date: date,
			});
		});
		countdown.addClass('handled');
		if (countdowns.length) {
			update();
		}
	}
 
	mw.hook('wikipage.content').add(init);
 
}(window.countdownTimer = window.countdownTimer || {}, mediaWiki, jQuery));

/* END countdown timer */

/** Collapsible tables *********************************************************
 *
 *  Description: Allows tables to be collapsed, showing only the header. See
 *               [[Wikipedia:NavFrame]].
 *  Taken from Wikipedia's Common.js.
 */
 
var hasClass = (function() {
    var reCache = {};
    return function(element, className) {
        return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
    };
})();
 
var autoCollapse = 2;
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 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 = "3.5em";
 
            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]);
            tableIndex++;
        }
    }
 
    for (var i = 0; i < tableIndex; i++) {
        if (hasClass(NavigationBoxes[i], "collapsed") || (tableIndex >= autoCollapse && hasClass(NavigationBoxes[i], "autocollapse"))) {
            collapseTable(i);
        }
    }
}
 
addOnloadHook(createCollapseButtons);
/* END Collapsible Tables */

/** Dynamic Navigation Bars (experimental) *************************************
 *
 *  Description: See [[Wikipedia:NavFrame]].
 *  Taken from Wikipedia's Common.js.
 */
 
// 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
 
 
function toggleNavigationBar(indexNavigationBar) {
    var NavToggle = document.getElementById("NavToggle" + indexNavigationBar);
    var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);
 
    if (!NavFrame || !NavToggle) {
        return false;
    }
 
    // if shown now
    if (NavToggle.firstChild.data == NavigationBarHide) {
        for (
        var NavChild = NavFrame.firstChild;
        NavChild != null;
        NavChild = NavChild.nextSibling) {
            if (hasClass(NavChild, 'NavPic')) {
                NavChild.style.display = 'none';
            }
            if (hasClass(NavChild, 'NavContent')) {
                NavChild.style.display = 'none';
            }
        }
        NavToggle.firstChild.data = NavigationBarShow;
 
        // if hidden now
    } else if (NavToggle.firstChild.data == NavigationBarShow) {
        for (
        var NavChild = NavFrame.firstChild;
        NavChild != null;
        NavChild = NavChild.nextSibling) {
            if (hasClass(NavChild, 'NavPic')) {
                NavChild.style.display = 'block';
            }
            if (hasClass(NavChild, 'NavContent')) {
                NavChild.style.display = 'block';
            }
        }
        NavToggle.firstChild.data = NavigationBarHide;
    }
}
 
// adds show/hide-button to navigation bars
 
 
function createNavigationBarToggleButton() {
    var indexNavigationBar = 0;
    // iterate over all < div >-elements
    var divs = document.getElementsByTagName("div");
    for (
    var i = 0;
    NavFrame = divs[i];
    i++) {
        // if found a navigation bar
        if (hasClass(NavFrame, "NavFrame")) {
 
            indexNavigationBar++;
            var NavToggle = document.createElement("a");
            NavToggle.className = 'NavToggle';
            NavToggle.setAttribute('id', 'NavToggle' + indexNavigationBar);
            NavToggle.setAttribute('href', 'javascript:toggleNavigationBar(' + indexNavigationBar + ');');
 
            var NavToggleText = document.createTextNode(NavigationBarHide);
            for (
            var NavChild = NavFrame.firstChild;
            NavChild != null;
            NavChild = NavChild.nextSibling) {
                if (hasClass(NavChild, 'NavPic') || hasClass(NavChild, 'NavContent')) {
                    if (NavChild.style.display == 'none') {
                        NavToggleText = document.createTextNode(NavigationBarShow);
                        break;
                    }
                }
            }
 
            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 (hasClass(NavFrame.childNodes[j], "NavHead")) {
                    NavFrame.childNodes[j].appendChild(NavToggle);
                }
            }
            NavFrame.setAttribute('id', 'NavFrame' + indexNavigationBar);
        }
    }
}
 
addOnloadHook(createNavigationBarToggleButton);
/* END Create Navbar Toggle Button */