MediaWiki:Common.js: Difference between revisions

From Citizendium
Jump to navigation Jump to search
imported>Larry Sanger
(Adding code that might (?) let us sort tables)
(updating Google Analytics tag number)
 
(46 intermediate revisions by 5 users not shown)
Line 1: Line 1:
/** Tooltips and access keys ***************************************************
/* <nowiki> */
  *
  *  Ported straight from Wikipedia, substituted 'Citizendium' for both 'Wikipedia'
  *  and 'Wikimedia'--probably a lot of stuff is broken here
  *  Description: Adds tooltips and access keys to links part of the MediaWiki
  *              interface.
  *  Maintainers (on Wikipedia): [[User:Gwicke|Gwicke]]?, [[User:Simetrical|Simetrical]]?, [[User:Ruud Koot|Ruud Koot]]
  */
ta = new Object();
ta["n-mainpage"]            = new Array("z","Visit the main page");
ta["n-Main-page"]          = new Array("z","Visit the main page");
ta["n-Featured-content"]    = new Array("","Featured content — the best of Citizendium");
ta["n-help"]                = new Array("","The place to find out about Citizendium");
ta["n-contact"]            = new Array("","How to contact Citizendium");
ta["n-sitesupport"]        = new Array("","Help keep Citizendium running");
ta["t-print"]              = new Array("","Printable version of this page");
ta["t-permalink"]          = new Array("","Permanent link to this version of the page");
ta["t-cite"]                = new Array("","Cite this Citizendium article");
ta["ca-nstab-project"]      = new Array("c","View the project page");
ta["n-Contents"]            = new Array("","Guides to browsing Citizendium");


  /** Import module *************************************************************
  /** Import module *************************************************************
   *
   *
   *  Description: Includes a raw wiki page as javascript or CSS,  
   *  Description: Includes a raw wiki page as javascript or CSS, used for including user made modules.
  *              used for including user made modules.
   *   
   *  Maintainers: [[User:AzaToth]]
  *  Doesn't work in WebKit or IE7...
   */
   */
importedScripts = {}; // object keeping track of included scripts, so a script ain't included twice
var loadedScripts = {}; // included-scripts tracker
function importScript( page ) {
function importScript(page) {
    if( importedScripts[page] ) {
var url = wgScript + '?title=' + encodeURIComponent(page.replace(/ /g,'_')).replace(/%2F/ig,'/').replace(/%3A/ig,':') + '&action=raw&ctype=text/javascript';
        return;
    }
if (loadedScripts[url]) return null;
    importedScripts[page] = true;
loadedScripts[url] = true;
    var url = wgScriptPath
            + '/wiki?title='
var s = document.createElement('script');
            + encodeURIComponent( page.replace( ' ', '_' ) )
s.setAttribute('src',url);
            + '&action=raw&ctype=text/javascript';
s.setAttribute('type','text/javascript');
    var scriptElem = document.createElement( 'script' );
document.getElementsByTagName('head')[0].appendChild(s);
    scriptElem.setAttribute( 'src' , url );
}
    scriptElem.setAttribute( 'type' , 'text/javascript' );
 
    document.getElementsByTagName( 'head' )[0].appendChild( scriptElem );
}
   
   
  function importStylesheet( page ) {
  function importStylesheet( page ) {
Line 55: Line 33:
  }
  }


/* Test if an element has a certain class **************************************
/* Import more specific scripts if necessary */
  *
//if (wgAction == 'edit' || wgAction == 'submit')
  * Description: Uses regular expressions and caching for better performance.
//    importScript("MediaWiki:Common.js/edit.js");
  * Maintainers: [[User:Mike Dillon]], [[User:R. Koot]], [[User:SG]]
//if (wgPageName == 'Special:Upload')
  */
//    importScript("MediaWiki:Common.js/upload.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);
    };
})();


/** Internet Explorer bug fix **************************************************
/** Extra toolbar options ******************************************************
   *
   *
   *  Description: UNDOCUMENTED
   *  Description: UNDOCUMENTED
   *  Maintainers: [[User:Tom-]]?
   *  Maintainers:  
   */
   */
if (window.showModalDialog && document.compatMode && document.compatMode == "CSS1Compat")
{
  var oldWidth;
  var docEl = document.documentElement;
  function fixIEScroll()
  {
    if (!oldWidth || docEl.clientWidth > oldWidth)
      doFixIEScroll();
    else
      setTimeout(doFixIEScroll, 1);
 
    oldWidth = docEl.clientWidth;
  }
  function doFixIEScroll() {
    docEl.style.overflowX = (docEl.scrollWidth - docEl.clientWidth < 4) ? "hidden" : "";
  }
  document.attachEvent("onreadystatechange", fixIEScroll);
  attachEvent("onresize", fixIEScroll);
}


/** Interwiki links to featured articles ***************************************
/* To disable this script, add    mwCustomEditButtons = [];    to [[Special:Mypage/Pinkwich5.js]] */
  *
 
  *  Description: Highlights interwiki links to featured articles (or
function imageButons(){
  *               equivalents) by changing the bullet before the interwiki link
if (wgAction == 'edit' || wgAction == 'submit') {
  *              into a star.
/* Make the Image insertion button use the CZ image template */
  *  Maintainers: [[User:R. Koot]]
mwEditButtons[5].speedTip = 'Image';
  */
mwEditButtons[5].tagOpen = '{{Image|';
mwEditButtons[5].tagClose = '|right|250px|Image Caption}}';
function LinkFA()  
{
/* Add extra image buttons */
    if ( document.getElementById( "p-lang" ) ) {
if (mwCustomEditButtons) {
        var InterwikiLinks = document.getElementById( "p-lang" ).getElementsByTagName( "li" );
mwCustomEditButtons[mwCustomEditButtons.length] = {
"imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c8/Button_redirect.png",
        for ( var i = 0; i < InterwikiLinks.length; i++ ) {
"speedTip": "Redirect",
            if ( document.getElementById( InterwikiLinks[i].className + "-fa" ) ) {
"tagOpen": "#REDIRECT [[",
                InterwikiLinks[i].className += " FA"
"tagClose": "]]",
                InterwikiLinks[i].title = "This is a featured article in another language.";
"sampleText": "Insert text"};
            }
        }
mwCustomEditButtons[mwCustomEditButtons.length] = {
    }
"imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c9/Button_strike.png",
}
"speedTip": "Strike",
"tagOpen": "<s>",
addOnloadHook( LinkFA );
"tagClose": "</s>",
"sampleText": "Strike-through text"};
mwCustomEditButtons[mwCustomEditButtons.length] = {
"imageFile": "http://upload.wikimedia.org/wikipedia/en/1/13/Button_enter.png",
"speedTip": "Line break",
"tagOpen": "<br />",
"tagClose": "",
"sampleText": ""};
mwCustomEditButtons[mwCustomEditButtons.length] = {
"imageFile": "http://upload.wikimedia.org/wikipedia/en/8/80/Button_upper_letter.png",
"speedTip": "Superscript",
"tagOpen": "<sup>",
"tagClose": "</sup>",
"sampleText": "Superscript text"};
mwCustomEditButtons[mwCustomEditButtons.length] = {
"imageFile": "http://upload.wikimedia.org/wikipedia/en/7/70/Button_lower_letter.png",
"speedTip": "Subscript",
"tagOpen": "<sub>",
"tagClose": "</sub>",
"sampleText": "Subscript text"};
mwCustomEditButtons[mwCustomEditButtons.length] = {
"imageFile": "http://upload.wikimedia.org/wikipedia/en/5/58/Button_small.png",
"speedTip": "Small",
"tagOpen": "<small>",
"tagClose": "</small>",
"sampleText": "Small Text"};
mwCustomEditButtons[mwCustomEditButtons.length] = {
"imageFile": "http://upload.wikimedia.org/wikipedia/en/6/60/Button_insert_table.png",
"speedTip": "Insert a table",
"tagOpen": '{| class="wikitable"\n|-\n',
"tagClose": "\n|}",
"sampleText": "! header 1\n! header 2\n! header 3\n|-\n| row 1, cell 1\n| row 1, cell 2\n| row 1, cell 3\n|-\n| row 2, cell 1\n| row 2, cell 2\n| row 2, cell 3"};
mwCustomEditButtons[mwCustomEditButtons.length] = {
"imageFile": "http://upload.wikimedia.org/wikipedia/commons/7/79/Button_reflink.png",
"speedTip": "Insert a reference",
"tagOpen": "<ref>",
"tagClose": "</ref>",
"sampleText": "Insert footnote text here"};
}
}
}
addOnloadHook(imageButons);
 


/** Collapsible tables *********************************************************
/** Upload Wizard ***************************************************
  *
*
  * Description: Allows tables to be collapsed, showing only the header. See
* Adds many enhancements to the upload form
  *              [[Citizendium:NavFrame]].
*
  *  Maintainers: [[User:R. Koot]]
* Maintainer : [[User:Caesar Schinas]]
  */
*/
 
var autoCollapse = 2;
function uploadForm() {
var collapseCaption = "hide";
if ((wgPageName == 'Special:Upload') && (wgUserLanguage != 'basic')) {
var expandCaption = "show";
if ((document.getElementById('wpUploadDescription').value == '') && document.getElementById('preload')) {
document.getElementById('wpUploadDescription').value = document.getElementById('preload').innerHTML;
function collapseTable( tableIndex )
document.getElementById('preload').parentNode.innerHTML = 'Fill in all the details you know:';
{
}
    var Button = document.getElementById( "collapseButton" + tableIndex );
if (wgUserLanguage == 'replace') {
    var Table = document.getElementById( "collapsibleTable" + tableIndex );
document.getElementById('wpDestFile').parentNode.parentNode.style.display = 'none';
   
document.getElementById('wpUploadDescription').setAttribute('rows','5');
    if ( !Table || !Button ) {
}
        return false;
if ((document.getElementById('wpUploadDescription').value.indexOf('{{Image_Details') != -1) && (wgUserLanguage != 'advanced')) {
    }
/* get an array of licences */
var license = document.getElementById('wpLicense');
    var Rows = Table.getElementsByTagName( "tr" );  
var licenses = Array();
for (var i in license.childNodes) {
    if ( Button.firstChild.data == collapseCaption ) {
if (license.childNodes[i].nodeName == 'OPTION' && license.childNodes[i].value != '') {
        for ( var i = 1; i < Rows.length; i++ ) {
licenses.push(license.childNodes[i].value);
            Rows[i].style.display = "none";
}
        }
}
        Button.firstChild.data = expandCaption;
/* if there is only one licence available select it and hide the input */
    } else {
if (licenses.length == 1) {
        for ( var i = 1; i < Rows.length; i++ ) {
license.value = licenses[0];
            Rows[i].style.display = Rows[0].style.display;
licenseSelectorCheck();
        }
license.style.display = 'none';
        Button.firstChild.data = collapseCaption;
}
    }
  }
/* Create individual fields for the image details */
var labels = {
'description' : 'Image description:',
'author' : 'Creator name:',
'copyright' : 'Copyright holder:',
'source' : 'Source:',
'date-created' : 'Date created:',
'pub-country' : 'Publication country:',
'notes' : 'Notes:',
'versions' : 'Other versions:'
};
var sig = '~~'+'~';
var summary = document.getElementById('wpUploadDescription');
var table = summary.parentNode.parentNode.parentNode;
var next = summary.parentNode.parentNode.nextSibling;
var args = Array();
if (summary.value.indexOf('Details|') != -1)
args = summary.value.substring(summary.value.indexOf('Details|')+8,summary.value.indexOf('\n')).split('|');
var details = summary.value.substring(summary.value.indexOf('\n|')+2,summary.value.indexOf('\n}}')).split('\n|');
for (var i in details) {
details[i] = details[i].split('=');
}
for (var i in details) {
var tr = document.createElement('tr');
var td1 = document.createElement('td');
var td2 = document.createElement('td');
tr.appendChild(td1);
tr.appendChild(td2);
td1.setAttribute('class','mw-label');
td2.setAttribute('class','mw-input');
td1.style.width = '12em';
 
// added by dnessett on 3/12/2010 to increase visible region for Notes
if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'notes') {
var textarea = document.createElement('textarea');
textarea.setAttribute('wrap','virtual');
textarea.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
textarea.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
textarea.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
textarea.setAttribute('rows','5');
td2.appendChild(textarea);
textarea.style.width = '90%';
} else {
var input = document.createElement('input');
input.setAttribute('type','text');
input.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
input.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
input.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
td2.appendChild(input);
input.style.width = '90%';
}
var label = document.createElement('label');
label.setAttribute('for',details[i][0].replace(/^\s+|\s+$/g,''));
label.appendChild(document.createTextNode(labels[details[i][0].replace(/^\s+|\s+$/g,'')]));
td1.appendChild(label);
table.insertBefore(tr,next);
if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'author' && (details[i][1].replace(/^\s+|\s+$/g,'') == sig)) tr.style.display = 'none';
}
summary.parentNode.parentNode.style.display = 'none';
var septr = document.createElement('tr');
var septd = document.createElement('td');
septr.appendChild(septd);
septd.appendChild(document.createElement('br'));
table.insertBefore(septr,summary.parentNode.parentNode);
document.getElementById('mw-upload-form').onsubmit = function(){
var temp = '{{Image_Details';
for (i in args) {
temp += '|' + args[i];
}
for (i in details) {
temp += '\n|' + details[i][0] + '= ' + document.getElementById(details[i][0].replace(/^\s+|\s+$/g,'')).value;
}
temp += '\n}}';
summary.value = temp;
if (license.value == '') {
alert('Please select a licence!');
return false;
}
}
}
}
}
addOnloadHook(uploadForm);
 
function uploadReplaceLink () {
if (wgNamespaceNumber == 6) {
var a = document.getElementsByTagName('a');
for (var i in a) {
if (a[i].getAttribute('href') && a[i].getAttribute('href').indexOf('wpDestFile') != -1)
a[i].setAttribute('href', a[i].getAttribute('href') + '&uselang=replace');
}
}
}
addOnloadHook(uploadReplaceLink);
 
 
/** Credit Line Editor ***************************************************
*
*  Creates a simple form for editing credit lines.
  *
*  Maintainer : [[User:Caesar Schinas]]
*/
function creditEdit() {
  if ((wgPageName.indexOf('/credit') != -1) && (wgAction == 'edit')) {
var text = document.getElementById('wpTextbox1').value;
if (text.indexOf('{{creditline') == -1) return false;
var args = text.substring(text.indexOf('|')+1,text.indexOf('}}')).split('|');
var bodycontent = document.getElementById('bodycontent');
bodycontent.setAttribute('id','bodycontent-old');
bodycontent.style.display = 'none';
var div = document.createElement('div');
bodycontent.parentNode.appendChild(div);
div.setAttribute('id','bodycontent');
div.innerHTML = "\
<table>\n\
  <tr>\n\
<th style='text-align:right; padding-right:1em;'>\n\
  <label for='licence'>Licence Type</label>\n\
</th>\n\
<td>\n\
  <select id='licence' name='licence' style='width:25em;'>\n\
<option value='C'>C - Copyright, used by permission</option>\n\
<option value='CC'>CC - Creative Commons</option>\n\
<option value='GNU'>GNU</option>\n\
<option value='PD'>PD - Public Domain</option>\n\
<option value='other' selected='selected'>Other (please only enter letters)</option>\n\
  </select>\n\
  <input type='text' id='licence-other' name='imagetype-other' />\n\
</td>\n\
  </tr>\n\
  <tr>\n\
<th style='text-align:right; padding-right:1em;'>\n\
  <label for='imagetype'>Image Type</label>\n\
</th>\n\
<td>\n\
  <select id='imagetype' name='imagetype' style='width:25em;'>\n\
<option value='Image'>Image</option>\n\
<option value='Photo'>Photo</option>\n\
<option value='Diagram'>Diagram</option>\n\
<option value='Drawing'>Drawing</option>\n\
<option value='Painting'>Painting</option>\n\
<option value='Artwork'>Artwork</option>\n\
<option value='other' selected='selected'>Other</option>\n\
  </select>\n\
  <input type='text' id='imagetype-other' name='imagetype-other' />\n\
</td>\n\
  </tr>\n\
  <tr>\n\
<th style='text-align:right; padding-right:1em;'>\n\
  <label for='author'>Author</label>\n\
</th>\n\
<td>\n\
  <input type='text' id='author' name='author' style='width:25em;' />\n\
</td>\n\
  </tr>\n\
  <tr>\n\
<th>\n\
</th>\n\
<td>\n\
  <input type='button' id='save' value='Save Credit Line' />\n\
</td>\n\
  </tr>\n\
</table>\n\
";
// set form field values
if (args[0] && args[0] != 'licence') {
  document.getElementById('licence-other').value = args[0];
  for (var i=0; i<4; i++) {
if (args[0].toUpperCase() == Array('CC','GNU','PD','C')[i]) {
document.getElementById('licence').value = args[0].toUpperCase();
document.getElementById('licence-other').style.display = 'none';
}
  }
} else {
  document.getElementById('licence').value = 'C';
  document.getElementById('licence-other').style.display = 'none';
}
if (args[1] && args[1] != 'imagetype') {
  document.getElementById('imagetype-other').value = args[1];
  for (var i=0; i<6; i++) {
if (args[1].toLowerCase() == Array('Image','Photo','Diagram','Drawing','Painting','Artwork')[i].toLowerCase()) {
document.getElementById('imagetype').value = Array('Image','Photo','Diagram','Drawing','Painting','Artwork')[i];
document.getElementById('imagetype-other').style.display = 'none';
}
  }
} else {
  document.getElementById('imagetype').value = 'Image';
  document.getElementById('imagetype-other').style.display = 'none';
}
if (args[2] && args[2] != 'author')
  document.getElementById('author').value = args[2];
// onchange handlers for selects
document.getElementById('licence').onchange = function() {
  if (document.getElementById('licence').value == 'other')
document.getElementById('licence-other').style.display = 'inline';
  else
document.getElementById('licence-other').style.display = 'none';
}
document.getElementById('imagetype').onchange = function() {
  if (document.getElementById('imagetype').value == 'other')
document.getElementById('imagetype-other').style.display = 'inline';
  else
document.getElementById('imagetype-other').style.display = 'none';
}
// save the credit line
document.getElementById('save').onclick = function() {
  var value = '{{creditline';
 
  if (document.getElementById('licence').value != 'other')
value += '|' + document.getElementById('licence').value;
  else if (document.getElementById('licence-other').value != '')
value += '|' + document.getElementById('licence-other').value;
 
  if (document.getElementById('imagetype').value != 'Image' || document.getElementById('author').value != '') {
if (document.getElementById('imagetype').value != 'other')
value += '|' + document.getElementById('imagetype').value;
else if (document.getElementById('imagetype-other').value != '')
value += '|' + document.getElementById('imagetype-other').value;
if (document.getElementById('author').value != '')
value += '|' + document.getElementById('author').value;
  }
 
  value += '}}';
 
  document.getElementById('wpTextbox1').value = value;
  document.getElementById('editform').submit();
}
  }
}
addOnloadHook(creditEdit);
 
 
 
 
  /* 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]]
  */
   
   
  function createCollapseButtons()
  var hasClass = (function () {
{
     var reCache = {};
     var tableIndex = 0;
     return function (element, className) {
     var NavigationBoxes = new Object();
        return (reCache[className] ? reCache[className] : (reCache[className] = new RegExp("(?:\\s|^)" + className + "(?:\\s|$)"))).test(element.className);
     var Tables = document.getElementsByTagName( "table" );
     };
})();
 
 
 
   
   
    for ( var i = 0; i < Tables.length; i++ ) {
 
        if ( hasClass( Tables[i], "collapsible" ) ) {
/** Collapsible tables *********************************************************
            NavigationBoxes[ tableIndex ] = Tables[i];
  *
            Tables[i].setAttribute( "id", "collapsibleTable" + tableIndex );
  *  Description: Allows tables to be collapsed, showing only the header. See
  *              [[Citizendium:NavFrame]].
  *  Maintainers: [[User:R. Koot]]
  */
   
   
            var Button    = document.createElement( "span" );
var autoCollapse = 2;
            var ButtonLink = document.createElement( "a" );
var collapseCaption = "hide";
            var ButtonText = document.createTextNode( collapseCaption );
var expandCaption = "show";
   
   
            Button.style.styleFloat = "right";
function collapseTable( tableIndex )
            Button.style.cssFloat = "right";
{
            Button.style.fontWeight = "normal";
    var Button = document.getElementById( "collapseButton" + tableIndex );
            Button.style.textAlign = "right";
    var Table = document.getElementById( "collapsibleTable" + tableIndex );
            Button.style.width = "6em";
   
   
            ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
    if ( !Table || !Button ) {
            ButtonLink.setAttribute( "href", "javascript:collapseTable(" + tableIndex + ");" );
        return false;
            ButtonLink.appendChild( ButtonText );
    }
   
   
            Button.appendChild( document.createTextNode( "[" ) );
    var Rows = Table.getElementsByTagName( "tr" );  
            Button.appendChild( ButtonLink );
            Button.appendChild( document.createTextNode( "]" ) );
   
   
            var Header = Tables[i].getElementsByTagName( "tr" )[0].getElementsByTagName( "th" )[0];
    if ( Button.firstChild.data == collapseCaption ) {
            /* only add button and increment count if there is a header row to work with */
        for ( var i = 1; i < Rows.length; i++ ) {
            if (Header) {
             Rows[i].style.display = "none";
                Header.insertBefore( Button, Header.childNodes[0] );
                tableIndex++;
             }
         }
         }
     }
        Button.firstChild.data = expandCaption;
     } else {
    for ( var i = 0; i < tableIndex; i++ ) {
        for ( var i = 1; i < Rows.length; i++ ) {
        if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
            Rows[i].style.display = Rows[0].style.display;
            collapseTable( i );
         }
         }
        Button.firstChild.data = collapseCaption;
     }
     }
  }
  }
   
   
  addOnloadHook( createCollapseButtons );
  function createCollapseButtons()
 
{
  /** Dynamic Navigation Bars (experimental) *************************************
    var tableIndex = 0;
  *
    var NavigationBoxes = new Object();
  *  Description: See [[Citizendium:NavFrame]].
    var Tables = document.getElementsByTagName( "table" );
  *  Maintainers: UNMAINTAINED
   
  */
    for ( var i = 0; i < Tables.length; i++ ) {
        if ( hasClass( Tables[i], "collapsible" ) ) {
            NavigationBoxes[ tableIndex ] = Tables[i];
            Tables[i].setAttribute( "id", "collapsibleTable" + tableIndex );
   
   
  // set up the words in your language
            var Button     = document.createElement( "span" );
  var NavigationBarHide = '[' + collapseCaption + ']';
            var ButtonLink = document.createElement( "a" );
  var NavigationBarShow = '[' + expandCaption + ']';
            var ButtonText = document.createTextNode( collapseCaption );
 
  // set up max count of Navigation Bars on page,
            Button.style.styleFloat = "right";
  // if there are more, all will be hidden
            Button.style.cssFloat = "right";
  // NavigationBarShowDefault = 0; // all bars will be hidden
             Button.style.fontWeight = "normal";
  // NavigationBarShowDefault = 1; // on pages with more than 1 bar all bars will be hidden
             Button.style.textAlign = "right";
  var NavigationBarShowDefault = autoCollapse;
             Button.style.width = "6em";
 
 
            ButtonLink.setAttribute( "id", "collapseButton" + tableIndex );
  // shows and hides content and picture (if available) of navigation bars
            ButtonLink.setAttribute( "href", "javascript:collapseTable(" + tableIndex + ");" );
  // Parameters:
            ButtonLink.appendChild( ButtonText );
  //     indexNavigationBar: the index of navigation bar to be toggled
  function toggleNavigationBar(indexNavigationBar)
            Button.appendChild( document.createTextNode( "[" ) );
  {
             Button.appendChild( ButtonLink );
    var NavToggle = document.getElementById("NavToggle" + indexNavigationBar);
             Button.appendChild( document.createTextNode( "]" ) );
    var NavFrame = document.getElementById("NavFrame" + indexNavigationBar);
 
            var Header = Tables[i].getElementsByTagName( "tr" )[0].getElementsByTagName( "th" )[0];
    if (!NavFrame || !NavToggle) {
             /* only add button and increment count if there is a header row to work with */
        return false;
             if (Header) {
    }
                 Header.insertBefore( Button, Header.childNodes[0] );
 
                tableIndex++;
    // 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;
     }
     }
  }
 
     for ( var i = 0; i < tableIndex; i++ ) {
  // adds show/hide-button to navigation bars
         if ( hasClass( NavigationBoxes[i], "collapsed" ) || ( tableIndex >= autoCollapse && hasClass( NavigationBoxes[i], "autocollapse" ) ) ) {
  function createNavigationBarToggleButton()
             collapseTable( i );
  {
    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);
            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);
         }
         }
     }
     }
    // if more Navigation Bars found than Default: hide all
}
    if (NavigationBarShowDefault < indexNavigationBar) {
addOnloadHook( createCollapseButtons );
        for(
 
                var i=1;
                i<=indexNavigationBar;
                i++
        ) {
            toggleNavigationBar(i);
        }
    }
 
  }
 
  addOnloadHook( createNavigationBarToggleButton );


  /** Main Page layout fixes *********************************************************
  /** Add dismiss button to watchlist-message *************************************
   *
   *
   *  Description:       Various layout fixes for the main page, including an
   *  Description: Hide the watchlist message for one week.
  *                      additional link to the complete list of languages available
   *  Maintainers: [[User:Ruud Koot|Ruud Koot]]
  *                      and the renaming of the 'Article' to to 'Main Page'.
   *  Maintainers:       [[User:AzaToth]], [[User:R. Koot]]
   */
   */
   
   
  function mainPageRenameNamespaceTab() {
  function addDismissButton() {
    try {
    var watchlistMessage = document.getElementById("watchlist-message");
        var Node = document.getElementById( 'ca-nstab-main' ).firstChild;
    if ( watchlistMessage == null ) return;
        if ( Node.textContent ) {      // Per DOM Level 3
            Node.textContent = 'Main Page';
        } else if ( Node.innerText ) { // IE doesn't handle .textContent
            Node.innerText = 'Main Page';
        } else {                      // Fallback
            Node.replaceChild( Node.firstChild, document.createTextNode( 'Main Page' ) );  
        }
    } catch(e) {
        // bailing out!
    }
}
   
   
function mainPageAppendCompleteListLink() {
    if ( document.cookie.indexOf( "hidewatchlistmessage=yes" ) != -1 ) {
    try {
        watchlistMessage.style.display = "none";
        var node = document.getElementById( "p-lang" )
    }
                            .getElementsByTagName('div')[0]
                            .getElementsByTagName('ul')[0];
   
   
        var aNode = document.createElement( 'a' );
    var Button    = document.createElement( "span" );
        var liNode = document.createElement( 'li' );
    var ButtonLink = document.createElement( "a" );
    var ButtonText = document.createTextNode( "dismiss" );
   
   
        aNode.appendChild( document.createTextNode( 'Complete list' ) );
    ButtonLink.setAttribute( "id", "dismissButton" );
        aNode.setAttribute( 'href' , 'http://meta.citizendium.org/wiki/List_of_Citizendiums' );
    ButtonLink.setAttribute( "href", "javascript:dismissWatchlistMessage();" );
        liNode.appendChild( aNode );
    ButtonLink.setAttribute( "title", "Hide this message for one week" );
        liNode.className = 'interwiki-completelist';
    ButtonLink.appendChild( ButtonText );
        node.appendChild( liNode );
      } catch(e) {
    Button.appendChild( document.createTextNode( "[" ) );
        // lets just ignore what's happened
    Button.appendChild( ButtonLink );
        return;
    Button.appendChild( document.createTextNode( "]" ) );
    }
    watchlistMessage.appendChild( Button );
  }
  }
   
   
  if ( wgTitle == 'Main Page' && ( wgNamespaceNumber == 0 || wgNamespaceNumber == 1 ) ) {
  function dismissWatchlistMessage() {
        addOnloadHook( mainPageRenameNamespaceTab );
    var e = new Date();
    e.setTime( e.getTime() + (7*24*60*60*1000) );
    document.cookie = "hidewatchlistmessage=yes; expires=" + e.toGMTString() + "; path=/";
    var watchlistMessage = document.getElementById("watchlist-message");
    watchlistMessage.style.display = "none";
  }
  }
   
   
  if ( wgTitle == 'Main Page' && wgNamespaceNumber == 0 ) {
  addOnloadHook( addDismissButton );
        addOnloadHook( mainPageAppendCompleteListLink );
}


  /** Extra toolbar options ****************************************************** <nowiki>
  /** Numeric sorting ***************************************************
   *
   *
   *  Description: UNDOCUMENTED
   *  Description: Fixes a bug (part of [[bugzilla:8115]])
   *  Maintainers: [[User:MarkS]]?, [[User:Voice of All]], [[User:R. Koot]]
   *  in http://svn.citizendium.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
  *  regarding [[Help:Sorting|table sorting]]:
  *  it allows sorting of numbers with more than one comma (thousands separator).
  *  Maintainer: [[User:Patrick|Patrick]]
   */
   */
   
  function ts_parseFloat(num) {
//This is a modified copy of a script by User:MarkS for extra features added by User:Voice of All.
if (!num) return 0;
// This is based on the original code on Citizendium:Tools/Editing tools
num = parseFloat(num.replace(/,/g, ""));
// To disable this script, add <code>mwCustomEditButtons = [];<code> to [[Special:Mypage/monobook.js]]
return (isNaN(num) ? 0 : num);
if (mwCustomEditButtons) {
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_redirect.png",
    "speedTip": "Redirect",
    "tagOpen": "#REDIRECT [[",
    "tagClose": "]]",
    "sampleText": "Insert text"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_strike.png",
    "speedTip": "Strike",
    "tagOpen": "<s>",
    "tagClose": "</s>",
    "sampleText": "Strike-through text"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_enter.png",
    "speedTip": "Line break",
    "tagOpen": "<br />",
    "tagClose": "",
    "sampleText": ""};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_upper_letter.png",
    "speedTip": "Superscript",
    "tagOpen": "<sup>",
    "tagClose": "</sup>",
    "sampleText": "Superscript text"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_lower_letter.png",
    "speedTip": "Subscript",
    "tagOpen": "<sub>",
    "tagClose": "</sub>",
    "sampleText": "Subscript text"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_small.png",
    "speedTip": "Small",
    "tagOpen": "<small>",
    "tagClose": "</small>",
    "sampleText": "Small Text"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_hide_comment.png",
    "speedTip": "Insert hidden Comment",
    "tagOpen": "<!-- ",
    "tagClose": " -->",
    "sampleText": "Comment"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_gallery.png",
    "speedTip": "Insert a picture gallery",
    "tagOpen": "\n<gallery>\n",
    "tagClose": "\n</gallery>",
    "sampleText": "Image:Example.jpg|Caption1\nImage:Example.jpg|Caption2"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_blockquote.png",
    "speedTip": "Insert block of quoted text",
    "tagOpen": "<blockquote>\n",
    "tagClose": "\n</blockquote>",
    "sampleText": "Block quote"};
  mwCustomEditButtons[mwCustomEditButtons.length] = {
    "imageFile": "http://en.citizendium.org/skins/common/images/Button_insert_table.png",
    "speedTip": "Insert a table",
    "tagOpen": '{| class="wikitable"\n|-\n',
    "tagClose": "\n|}",
    "sampleText": "! header 1\n! header 2\n! header 3\n|-\n| row 1, cell 1\n| row 1, cell 2\n| row 1, cell 3\n|-\n| row 2, cell 1\n| row 2, cell 2\n| row 2, cell 3"};
  }
  }
/*</nowiki>*/


/** pageview counter ***********************************************************
  *
  *  Description: Please talk to de:User:LeonWeber before changing anything or
  *              if there are any issues with that.
  *  Maintainers: [[:de:User:LeonWeber]]?
  */
 
  // this should be adjusted to a good value.
  // BE CAREFUL, you will break zedler if it's too low!
  // And then DaB. will kill Leon :-(
  var disable_counter = 0;
  var counter_factor = 6000;
 
  function pgcounter_setup()
  {
  if(disable_counter == 0)
  {
  var url = window.location.href;
  if(Math.floor(Math.random()*counter_factor)==42)  // the probability thing
  {
  if(wgIsArticle==true || wgArticleId==0) // do not count history pages etc.
  {
  var pgcountNs = wgCanonicalNamespace;
  if(wgCanonicalNamespace=="")
  {
  pgcountNs = "0";
  }
  var cnt_url = "http://pgcount.citizendium.de/index.png?ns=" + pgcountNs + "&title=" + encodeURI(wgTitle) + "&factor=" + counter_factor +"&wiki=enwiki";
  var img = new Image();
  img.src = cnt_url;
  }
  }
  }
  }
  // Do not use aOnloadFunctions[aOnloadFunctions.length] = pgcounter_setup;, some browsers don't like that.
  pgcounter_setup();


/** "Technical restrictions" title fix *****************************************
*
* Description:
* Maintainers: User:Interiot, User:Mets501, User:Freakofnurture
*/
//
// For pages that have something like Template:Lowercase, replace the title, but only if it is cut-and-pasteable as a valid wikilink.
// (for instance iPod's title is updated. But [[C#]] is not an equivalent
// wikilink, so [[C Sharp]] doesn't have its main title changed)
// Likewise for users who have selected the U.K. date format ("1 March") the 
// titles of day-of-the-year articles will appear in that style. Users with any
// other date setting are not affected.
//
// The function looks for a banner like this:
// &lt;div id="RealTitleBanner"&gt;  ... &lt;span id="RealTitle"&gt;title&lt;/span&gt; ... &lt;/div&gt;
// An element with id=DisableRealTitle disables the function.
//
var disableRealTitle = 0; // users can set disableRealTitle = 1 locally to disable.
if (wgIsArticle) { // don't display the RealTitle when editing, since it is apparently inconsistent (doesn't show when editing sections, doesn't show when not previewing)
  addOnloadHook(function() {
    try {
        var realTitleBanner = document.getElementById("RealTitleBanner");
        if (realTitleBanner && !document.getElementById("DisableRealTitle") && !disableRealTitle ) {
            var realTitle = document.getElementById("RealTitle");
            if (realTitle) {
                var realTitleHTML = realTitle.innerHTML;
                realTitleText = pickUpText(realTitle);


                var isPasteable = 0;
// MediaWiki JavaScript support functions
                //var containsHTML = /</.test(realTitleHTML);    // contains ANY HTML
                var containsTooMuchHTML = /</.test( realTitleHTML.replace(/<\/?(sub|sup|small|big)>/gi, "") ); // contains HTML that will be ignored when cut-n-pasted as a wikilink
                // calculate whether the title is pasteable
                var verifyTitle = realTitleText.replace(/^ +/, "");      // trim left spaces
                verifyTitle = verifyTitle.charAt(0).toUpperCase() + verifyTitle.substring(1, verifyTitle.length);    // uppercase first character


                // if the namespace prefix is there, remove it on our verification copy. If it isn't there, add it to the original realValue copy.
var clientPC = navigator.userAgent.toLowerCase(); // Get client info
                if (wgNamespaceNumber != 0) {
var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
                    if (wgCanonicalNamespace == verifyTitle.substr(0, wgCanonicalNamespace.length).replace(/ /g, "_") && verifyTitle.charAt(wgCanonicalNamespace.length) == ":") {
                && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
                        verifyTitle = verifyTitle.substr(wgCanonicalNamespace.length + 1);
var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
                    } else {
var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
                        realTitleText = wgCanonicalNamespace.replace(/_/g, " ") + ":" + realTitleText;
// For accesskeys
                        realTitleHTML = wgCanonicalNamespace.replace(/_/g, " ") + ":" + realTitleHTML;
var is_ff2_win = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('windows')!=-1;
                    }
var is_ff2_x11 = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('x11')!=-1;
                }
if (clientPC.indexOf('opera') != -1) {
 
var is_opera = true;
                // verify whether wgTitle matches
var is_opera_preseven = (window.opera && !document.childNodes);
                verifyTitle = verifyTitle.replace(/[\s_]+/g, " ");     // underscores and multiple spaces to single spaces
var is_opera_seven = (window.opera && document.childNodes);
                verifyTitle = verifyTitle.replace(/^\s+/, "").replace(/\s+$/, "");        // trim left and right spaces
var is_opera_95 = (clientPC.search(/opera\/(9.[5-9]|[1-9][0-9])/)!=-1);
                verifyTitle = verifyTitle.charAt(0).toUpperCase() + verifyTitle.substring(1, verifyTitle.length);   // uppercase first character
}
                if ( (verifyTitle == wgTitle) || (verifyTitle == wgTitle.replace(/^(.+)?(January|February|March|April|May|June|July|August|September|October|November|December)\s+([12]?[0-9]|3[0123])([^\d].*)?$/g, "$1$3 $2$4") )) isPasteable = 1;
                var h1 = document.getElementsByTagName("h1")[0];
                if (h1 && isPasteable) {
                    h1.innerHTML = containsTooMuchHTML ? realTitleText : realTitleHTML;
                    if (!containsTooMuchHTML)
                        realTitleBanner.style.display = "none";
                }
                document.title = realTitleText + " - Citizendium, the free encyclopedia";
            }
        }
    } catch (e) {
        /* Something went wrong. */
    }
  });
}
 
// similar to innerHTML, but only returns the text portions of the insides, excludes HTML
function pickUpText(aParentElement) {
var str = "";


function pickUpTextInternal(aElement) {
// Global external objects used by this script.
  var child = aElement.firstChild;
/*extern ta, stylepath, skin */
  while (child) {
  if (child.nodeType == 1)    // ELEMENT_NODE
    pickUpTextInternal(child);
  else if (child.nodeType == 3)  // TEXT_NODE
    str += child.nodeValue;


  child = child.nextSibling;
// add any onload functions in this hook (please don't hard-code any events in the xhtml source)
  }
var doneOnloadHook;
}


  pickUpTextInternal(aParentElement);
if (!window.onloadFuncts) {
  return str;
var onloadFuncts = [];
}
}


//fix edit summary prompt for undo
function addOnloadHook(hookFunct) {
//this code fixes the fact that the undo function combined with the "no edit summary prompter" causes problems if leaving the
// Allows add-on scripts to add onload functions
//edit summary unchanged
onloadFuncts[onloadFuncts.length] = hookFunct;
//this was added by [[User:Deskana]], code by [[User:Tra]]
}
addOnloadHook(function () {
  if (document.location.search.indexOf("undo=") != -1
  && document.getElementsByName('wpAutoSummary')[0]) {
    document.getElementsByName('wpAutoSummary')[0].value='';
  }
})


/** Add dismiss button to watchlist-message *************************************
function hookEvent(hookName, hookFunct) {
  *
if (window.addEventListener) {
  *  Description: Hide the watchlist message for one week.
window.addEventListener(hookName, hookFunct, false);
  *  Maintainers: [[User:Ruud Koot|Ruud Koot]]
} else if (window.attachEvent) {
  */
window.attachEvent("on" + hookName, hookFunct);
}
function addDismissButton() {
}
    var watchlistMessage = document.getElementById("watchlist-message");
 
    if ( watchlistMessage == null ) return;
// document.write special stylesheet links
if (typeof stylepath != 'undefined' && typeof skin != 'undefined') {
    if ( document.cookie.indexOf( "hidewatchlistmessage=yes" ) != -1 ) {
if (is_opera_preseven) {
        watchlistMessage.style.display = "none";
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css">');
    }
} else if (is_opera_seven && !is_opera_95) {
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css">');
    var Button    = document.createElement( "span" );
} else if (is_opera_95) {
    var ButtonLink = document.createElement( "a" );
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera95Fixes.css">');
    var ButtonText = document.createTextNode( "dismiss" );
} else if (is_khtml) {
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css">');
    ButtonLink.setAttribute( "id", "dismissButton" );
}
    ButtonLink.setAttribute( "href", "javascript:dismissWatchlistMessage();" );
}
    ButtonLink.setAttribute( "title", "Hide this message for one week" );
 
    ButtonLink.appendChild( ButtonText );
if (wgBreakFrames) {
// Un-trap us from framesets
    Button.appendChild( document.createTextNode( "[" ) );
if (window.top != window) {
    Button.appendChild( ButtonLink );
window.top.location = window.location;
    Button.appendChild( document.createTextNode( "]" ) );
}
}
    watchlistMessage.appendChild( Button );
 
}
// for enhanced RecentChanges
function toggleVisibility(_levelId, _otherId, _linkId) {
function dismissWatchlistMessage() {
var thisLevel = document.getElementById(_levelId);
    var e = new Date();
var otherLevel = document.getElementById(_otherId);
    e.setTime( e.getTime() + (7*24*60*60*1000) );
var linkLevel = document.getElementById(_linkId);
    document.cookie = "hidewatchlistmessage=yes; expires=" + e.toGMTString() + "; path=/";
if (thisLevel.style.display == 'none') {
    var watchlistMessage = document.getElementById("watchlist-message");
thisLevel.style.display = 'block';
    watchlistMessage.style.display = "none";
otherLevel.style.display = 'none';
}
linkLevel.style.display = 'inline';
} else {
addOnloadHook( addDismissButton );
thisLevel.style.display = 'none';
otherLevel.style.display = 'inline';
linkLevel.style.display = 'none';
}
}


/** Numeric sorting ***************************************************
function historyRadios(parent) {
  *
var inputs = parent.getElementsByTagName('input');
  *  Description: Fixes a bug (part of [[bugzilla:8115]])
var radios = [];
  *  in http://svn.citizendium.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
for (var i = 0; i < inputs.length; i++) {
  *  regarding [[Help:Sorting|table sorting]]:
if (inputs[i].name == "diff" || inputs[i].name == "oldid") {
  *  it allows sorting of numbers with more than one comma (thousands separator).
radios[radios.length] = inputs[i];
  *  Maintainer: [[User:Patrick|Patrick]]
}
  */
}
function ts_parseFloat(num) {
return radios;
if (!num) return 0;
}
num = parseFloat(num.replace(/,/g, ""));
return (isNaN(num) ? 0 : num);
}


/** Main Page deletion image *******************************************************
// check selection and tweak visibility/class onclick
  *
function diffcheck() {
  *  Description: If the Main Page does not exist (i.e., it's been deleted) then insert an image
var dli = false; // the li where the diff radio is checked
  *              instead of showing the "page does not exist" text.
var oli = false; // the li where the oldid radio is checked
  *  Created by: [[User:Mark]], with invaluable help from [[User:Pathoschild]]
var hf = document.getElementById('pagehistory');
  */
if (!hf) {
return true;
function MainPageDeletedImage() {
}
  try {
var lis = hf.getElementsByTagName('li');
for (var i=0;i<lis.length;i++) {
    //If the article does not exist and it is the Main Page, proceed
var inputs = historyRadios(lis[i]);
    if ( document.getElementById( "noarticletext" ) && wgTitle == 'Main Page' ) {
if (inputs[1] && inputs[0]) {
if (inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
      // Insert a protected commons image at the end of the document explaining it.
if (inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value) {
      var contentbox = document.getElementById('content');
return false;
      var newimg = document.createElement('img');
}
      newimg.setAttribute('src','http://upload.citizendium.org/Citizendium/commons/9/99/CitizendiumTechnical.png');
if (oli) { // it's the second checked radio
      contentbox.appendChild(newimg);
if (inputs[1].checked) {
oli.className = "selected";
      // Hide the article-does-not-exist text
return false;
      var NoArticleMessage = document.getElementById('noarticletext');
}
      NoArticleMessage.style.display="none";
} else if (inputs[0].checked) {
return false;
      // Hide the edit button
}
      var EditThisPageButton = document.getElementById('ca-edit');
if (inputs[0].checked) {
      EditThisPageButton.style.display="none";
dli = lis[i];
    }
}
  } catch(e) {
if (!oli) {
      // In case it does not work, do nothing
inputs[0].style.visibility = 'hidden';
      return;
}
  }
if (dli) {
}
inputs[1].style.visibility = 'hidden';
}
addOnloadHook( MainPageDeletedImage );
lis[i].className = "selected";
 
oli = lis[i];
/** MediaWiki media player *******************************************************
} else { // no radio is checked in this row
  *
if (!oli) {
  *  Description: A Java player for in-browser playback of media files.
inputs[0].style.visibility = 'hidden';
  *  Created by: [[User:Gmaxwell]]
} else {
  */
inputs[0].style.visibility = 'visible';
}
document.write('<script type="text/javascript" src="'
if (dli) {
            + 'http://en.Citizendium.org/wiki/Mediawiki:Citizendiumplayer.js'
inputs[1].style.visibility = 'hidden';
            + '&action=raw&ctype=text/javascript&smaxage=86400"></script>');
} else {
 
inputs[1].style.visibility = 'visible';
/** Change Special:Search to use a drop-down menu *******************************************************
}
  *
lis[i].className = "";
  *  Description: Change Special:Search to use a drop-down menu, with the default being
}
  *              the internal MediaWiki engine
}
  *  Created and maintained by: [[User:Gracenotes]]
}
  */
return true;
if (wgPageName == "Special:Search") {
        var searchEngines = [];
        addOnloadHook(SpecialSearchEnhanced);
}
function SpecialSearchEnhanced() {
        var createOption = function(site, action, mainQ, addQ, addV) {
                var opt = document.createElement('option');
                opt.appendChild(document.createTextNode(site));
                searchEngines[searchEngines.length] = [action, mainQ, addQ, addV];
                return opt;
        }
        var searchForm = document.forms['search'];
        var selectBox = document.createElement('select');
        selectBox.id = 'searchEngine';
        searchForm.onsubmit = function() {
                var optSelected = searchEngines[document.getElementById('searchEngine').selectedIndex];
                searchForm.action = optSelected[0];
                searchForm.lsearchbox.name = optSelected[1];
                searchForm.title.value = optSelected[3];
                searchForm.title.name = optSelected[2];
        }
        selectBox.appendChild(createOption('MediaWiki search', wgScriptPath + '/index.php', 'search', 'title', 'Special:Search'));
        selectBox.appendChild(createOption('Google', 'http://www.google.com/search', 'q', 'sitesearch', 'en.Citizendium.org'));
        selectBox.appendChild(createOption('Yahoo', 'http://search.yahoo.com/search', 'p', 'vs', 'en.Citizendium.org'));
        selectBox.appendChild(createOption('Windows Live', 'http://search.live.com/results.aspx', 'q', 'q1', 'site:http://en.Citizendium.org'));
        selectBox.appendChild(createOption('Wikiwix', 'http://www.wikiwix.com/', 'action', 'lang', 'en'));
        selectBox.appendChild(createOption('Exalead', 'http://www.exalead.com/Citizendium/results', 'q', 'language', 'en'));
        searchForm.lsearchbox.style.marginLeft = '0px';
        var lStat = document.getElementById('loadStatus');
        lStat.parentNode.insertBefore(selectBox, lStat);
  }
 
//Basic Hide/Show Function
function hideshow( ElementID)
{
theElement = document.getElementById(ElementID);
theElement.style.display = (div.style.display=="none" ? "block" : "none"); //If "none", make it "block".  Else, set it to "none"
}
 
// MediaWiki JavaScript support functions
 
var clientPC = navigator.userAgent.toLowerCase(); // Get client info
var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
                && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
// For accesskeys
var is_ff2_win = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('windows')!=-1;
var is_ff2_x11 = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('x11')!=-1;
if (clientPC.indexOf('opera') != -1) {
var is_opera = true;
var is_opera_preseven = (window.opera && !document.childNodes);
var is_opera_seven = (window.opera && document.childNodes);
var is_opera_95 = (clientPC.search(/opera\/(9.[5-9]|[1-9][0-9])/)!=-1);
}
}


// Global external objects used by this script.
// page history stuff
/*extern ta, stylepath, skin */
// attach event handlers to the input elements on history page
 
function histrowinit() {
// add any onload functions in this hook (please don't hard-code any events in the xhtml source)
var hf = document.getElementById('pagehistory');
var doneOnloadHook;
if (!hf) {
 
return;
if (!window.onloadFuncts) {
}
var onloadFuncts = [];
var lis = hf.getElementsByTagName('li');
for (var i = 0; i < lis.length; i++) {
var inputs = historyRadios(lis[i]);
if (inputs[0] && inputs[1]) {
inputs[0].onclick = diffcheck;
inputs[1].onclick = diffcheck;
}
}
diffcheck();
}
}


function addOnloadHook(hookFunct) {
// generate toc from prefs form, fold sections
// Allows add-on scripts to add onload functions
// XXX: needs testing on IE/Mac and safari
onloadFuncts[onloadFuncts.length] = hookFunct;
// more comments to follow
}
function tabbedprefs() {
 
var prefform = document.getElementById('preferences');
function hookEvent(hookName, hookFunct) {
if (!prefform || !document.createElement) {
if (window.addEventListener) {
return;
window.addEventListener(hookName, hookFunct, false);
} else if (window.attachEvent) {
window.attachEvent("on" + hookName, hookFunct);
}
}
}
if (prefform.nodeName.toLowerCase() == 'a') {
 
return; // Occasional IE problem
// document.write special stylesheet links
if (typeof stylepath != 'undefined' && typeof skin != 'undefined') {
if (is_opera_preseven) {
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css">');
} else if (is_opera_seven && !is_opera_95) {
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css">');
} else if (is_opera_95) {
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera95Fixes.css">');
} else if (is_khtml) {
document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css">');
}
}
}
prefform.className = prefform.className + 'jsprefs';
 
var sections = [];
if (wgBreakFrames) {
var children = prefform.childNodes;
// Un-trap us from framesets
var seci = 0;
if (window.top != window) {
for (var i = 0; i < children.length; i++) {
window.top.location = window.location;
if (children[i].nodeName.toLowerCase() == 'fieldset') {
}
children[i].id = 'prefsection-' + seci;
}
children[i].className = 'prefsection';
 
if (is_opera || is_khtml) {
// for enhanced RecentChanges
children[i].className = 'prefsection operaprefsection';
function toggleVisibility(_levelId, _otherId, _linkId) {
}
var thisLevel = document.getElementById(_levelId);
var legends = children[i].getElementsByTagName('legend');
var otherLevel = document.getElementById(_otherId);
sections[seci] = {};
var linkLevel = document.getElementById(_linkId);
legends[0].className = 'mainLegend';
if (thisLevel.style.display == 'none') {
if (legends[0] && legends[0].firstChild.nodeValue) {
thisLevel.style.display = 'block';
sections[seci].text = legends[0].firstChild.nodeValue;
otherLevel.style.display = 'none';
} else {
linkLevel.style.display = 'inline';
sections[seci].text = '# ' + seci;
} else {
}
thisLevel.style.display = 'none';
sections[seci].secid = children[i].id;
otherLevel.style.display = 'inline';
seci++;
linkLevel.style.display = 'none';
if (sections.length != 1) {
children[i].style.display = 'none';
} else {
var selectedid = children[i].id;
}
}
}
}
}
var toc = document.createElement('ul');
 
toc.id = 'preftoc';
function historyRadios(parent) {
toc.selectedid = selectedid;
var inputs = parent.getElementsByTagName('input');
for (i = 0; i < sections.length; i++) {
var radios = [];
var li = document.createElement('li');
for (var i = 0; i < inputs.length; i++) {
if (i === 0) {
if (inputs[i].name == "diff" || inputs[i].name == "oldid") {
li.className = 'selected';
radios[radios.length] = inputs[i];
}
}
var a = document.createElement('a');
a.href = '#' + sections[i].secid;
a.onmousedown = a.onclick = uncoversection;
a.appendChild(document.createTextNode(sections[i].text));
a.secid = sections[i].secid;
li.appendChild(a);
toc.appendChild(li);
}
}
return radios;
prefform.parentNode.insertBefore(toc, prefform.parentNode.childNodes[0]);
document.getElementById('prefsubmit').id = 'prefcontrol';
}
}


// check selection and tweak visibility/class onclick
function uncoversection() {
function diffcheck() {
var oldsecid = this.parentNode.parentNode.selectedid;
var dli = false; // the li where the diff radio is checked
var newsec = document.getElementById(this.secid);
var oli = false; // the li where the oldid radio is checked
if (oldsecid != this.secid) {
var hf = document.getElementById('pagehistory');
var ul = document.getElementById('preftoc');
if (!hf) {
document.getElementById(oldsecid).style.display = 'none';
return true;
newsec.style.display = 'block';
ul.selectedid = this.secid;
var lis = ul.getElementsByTagName('li');
for (var i = 0; i< lis.length; i++) {
lis[i].className = '';
}
this.parentNode.className = 'selected';
}
}
var lis = hf.getElementsByTagName('li');
return false;
for (var i=0;i<lis.length;i++) {
}
var inputs = historyRadios(lis[i]);
 
if (inputs[1] && inputs[0]) {
// Timezone stuff
if (inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
// tz in format [+-]HHMM
if (inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value) {
function checkTimezone(tz, msg) {
return false;
var localclock = new Date();
}
// returns negative offset from GMT in minutes
if (oli) { // it's the second checked radio
var tzRaw = localclock.getTimezoneOffset();
if (inputs[1].checked) {
var tzHour = Math.floor( Math.abs(tzRaw) / 60);
oli.className = "selected";
var tzMin = Math.abs(tzRaw) % 60;
return false;
var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
}
if (tz != tzString) {
} else if (inputs[0].checked) {
var junk = msg.split('$1');
return false;
document.write(junk[0] + "UTC" + tzString + junk[1]);
}
}
if (inputs[0].checked) {
}
dli = lis[i];
 
}
function unhidetzbutton() {
if (!oli) {
var tzb = document.getElementById('guesstimezonebutton');
inputs[0].style.visibility = 'hidden';
if (tzb) {
}
tzb.style.display = 'inline';
if (dli) {
inputs[1].style.visibility = 'hidden';
}
lis[i].className = "selected";
oli = lis[i];
} else { // no radio is checked in this row
if (!oli) {
inputs[0].style.visibility = 'hidden';
} else {
inputs[0].style.visibility = 'visible';
}
if (dli) {
inputs[1].style.visibility = 'hidden';
} else {
inputs[1].style.visibility = 'visible';
}
lis[i].className = "";
}
}
}
}
return true;
}
}


// page history stuff
// in [-]HH:MM format...
// attach event handlers to the input elements on history page
// won't yet work with non-even tzs
function histrowinit() {
function fetchTimezone() {
var hf = document.getElementById('pagehistory');
// FIXME: work around Safari bug
if (!hf) {
var localclock = new Date();
return;
// returns negative offset from GMT in minutes
}
var tzRaw = localclock.getTimezoneOffset();
var lis = hf.getElementsByTagName('li');
var tzHour = Math.floor( Math.abs(tzRaw) / 60);
for (var i = 0; i < lis.length; i++) {
var tzMin = Math.abs(tzRaw) % 60;
var inputs = historyRadios(lis[i]);
var tzString = ((tzRaw >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
if (inputs[0] && inputs[1]) {
":" + ((tzMin < 10) ? "0" : "") + tzMin;
inputs[0].onclick = diffcheck;
return tzString;
inputs[1].onclick = diffcheck;
}
}
diffcheck();
}
}


// generate toc from prefs form, fold sections
function guessTimezone(box) {
// XXX: needs testing on IE/Mac and safari
document.getElementsByName("wpHourDiff")[0].value = fetchTimezone();
// more comments to follow
}
function tabbedprefs() {
 
var prefform = document.getElementById('preferences');
function showTocToggle() {
if (!prefform || !document.createElement) {
if (document.createTextNode) {
return;
// Uses DOM calls to avoid document.write + XHTML issues
}
 
if (prefform.nodeName.toLowerCase() == 'a') {
var linkHolder = document.getElementById('toctitle');
return; // Occasional IE problem
if (!linkHolder) {
}
return;
prefform.className = prefform.className + 'jsprefs';
}
var sections = [];
 
var children = prefform.childNodes;
var outerSpan = document.createElement('span');
var seci = 0;
outerSpan.className = 'toctoggle';
for (var i = 0; i < children.length; i++) {
 
if (children[i].nodeName.toLowerCase() == 'fieldset') {
var toggleLink = document.createElement('a');
children[i].id = 'prefsection-' + seci;
toggleLink.id = 'togglelink';
children[i].className = 'prefsection';
toggleLink.className = 'internal';
if (is_opera || is_khtml) {
toggleLink.href = 'javascript:toggleToc()';
children[i].className = 'prefsection operaprefsection';
toggleLink.appendChild(document.createTextNode(tocHideText));
}
 
var legends = children[i].getElementsByTagName('legend');
outerSpan.appendChild(document.createTextNode('['));
sections[seci] = {};
outerSpan.appendChild(toggleLink);
legends[0].className = 'mainLegend';
outerSpan.appendChild(document.createTextNode(']'));
if (legends[0] && legends[0].firstChild.nodeValue) {
 
sections[seci].text = legends[0].firstChild.nodeValue;
linkHolder.appendChild(document.createTextNode(' '));
} else {
linkHolder.appendChild(outerSpan);
sections[seci].text = '# ' + seci;
 
}
var cookiePos = document.cookie.indexOf("hidetoc=");
sections[seci].secid = children[i].id;
if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) {
seci++;
toggleToc();
if (sections.length != 1) {
children[i].style.display = 'none';
} else {
var selectedid = children[i].id;
}
}
}
}
}
var toc = document.createElement('ul');
}
toc.id = 'preftoc';
 
toc.selectedid = selectedid;
function changeText(el, newText) {
for (i = 0; i < sections.length; i++) {
// Safari work around
var li = document.createElement('li');
if (el.innerText) {
if (i === 0) {
el.innerText = newText;
li.className = 'selected';
} else if (el.firstChild && el.firstChild.nodeValue) {
}
el.firstChild.nodeValue = newText;
var a = document.createElement('a');
a.href = '#' + sections[i].secid;
a.onmousedown = a.onclick = uncoversection;
a.appendChild(document.createTextNode(sections[i].text));
a.secid = sections[i].secid;
li.appendChild(a);
toc.appendChild(li);
}
}
prefform.parentNode.insertBefore(toc, prefform.parentNode.childNodes[0]);
document.getElementById('prefsubmit').id = 'prefcontrol';
}
}


function uncoversection() {
function toggleToc() {
var oldsecid = this.parentNode.parentNode.selectedid;
var toc = document.getElementById('toc').getElementsByTagName('ul')[0];
var newsec = document.getElementById(this.secid);
var toggleLink = document.getElementById('togglelink');
if (oldsecid != this.secid) {
 
var ul = document.getElementById('preftoc');
if (toc && toggleLink && toc.style.display == 'none') {
document.getElementById(oldsecid).style.display = 'none';
changeText(toggleLink, tocHideText);
newsec.style.display = 'block';
toc.style.display = 'block';
ul.selectedid = this.secid;
document.cookie = "hidetoc=0";
var lis = ul.getElementsByTagName('li');
} else {
for (var i = 0; i< lis.length; i++) {
changeText(toggleLink, tocShowText);
lis[i].className = '';
toc.style.display = 'none';
}
document.cookie = "hidetoc=1";
this.parentNode.className = 'selected';
}
}
return false;
}
}


// Timezone stuff
function escapeQuotes(text) {
// tz in format [+-]HHMM
var re = new RegExp("'","g");
function checkTimezone(tz, msg) {
text = text.replace(re,"\\'");
var localclock = new Date();
re = new RegExp("\\n","g");
// returns negative offset from GMT in minutes
text = text.replace(re,"\\n");
var tzRaw = localclock.getTimezoneOffset();
return escapeQuotesHTML(text);
var tzHour = Math.floor( Math.abs(tzRaw) / 60);
var tzMin = Math.abs(tzRaw) % 60;
var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
if (tz != tzString) {
var junk = msg.split('$1');
document.write(junk[0] + "UTC" + tzString + junk[1]);
}
}
}


function unhidetzbutton() {
function escapeQuotesHTML(text) {
var tzb = document.getElementById('guesstimezonebutton');
var re = new RegExp('&',"g");
if (tzb) {
text = text.replace(re,"&amp;");
tzb.style.display = 'inline';
re = new RegExp('"',"g");
}
text = text.replace(re,"&quot;");
re = new RegExp('<',"g");
text = text.replace(re,"&lt;");
re = new RegExp('>',"g");
text = text.replace(re,"&gt;");
return text;
}
}


// in [-]HH:MM format...
// apply tagOpen/tagClose to selection in textarea,
// won't yet work with non-even tzs
// use sampleText instead of selection if there is none
function fetchTimezone() {
function insertTags(tagOpen, tagClose, sampleText) {
// FIXME: work around Safari bug
var txtarea;
var localclock = new Date();
if (document.editform) {
// returns negative offset from GMT in minutes
txtarea = document.editform.wpTextbox1;
var tzRaw = localclock.getTimezoneOffset();
} else {
var tzHour = Math.floor( Math.abs(tzRaw) / 60);
// some alternate form? take the first one we can find
var tzMin = Math.abs(tzRaw) % 60;
var areas = document.getElementsByTagName('textarea');
var tzString = ((tzRaw >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
txtarea = areas[0];
":" + ((tzMin < 10) ? "0" : "") + tzMin;
}
return tzString;
var selText, isSample = false;
}


function guessTimezone(box) {
if (document.selection  && document.selection.createRange) { // IE/Opera
document.getElementsByName("wpHourDiff")[0].value = fetchTimezone();
}


function showTocToggle() {
//save window scroll position
if (document.createTextNode) {
if (document.documentElement && document.documentElement.scrollTop)
// Uses DOM calls to avoid document.write + XHTML issues
var winScroll = document.documentElement.scrollTop
 
else if (document.body)
var linkHolder = document.getElementById('toctitle');
var winScroll = document.body.scrollTop;
if (!linkHolder) {
//get current selection 
return;
txtarea.focus();
var range = document.selection.createRange();
selText = range.text;
//insert tags
checkSelectedText();
range.text = tagOpen + selText + tagClose;
//mark sample text as selected
if (isSample && range.moveStart) {
if (window.opera)
tagClose = tagClose.replace(/\n/g,'');
range.moveStart('character', - tagClose.length - selText.length);
range.moveEnd('character', - tagClose.length);  
}
}
range.select(); 
//restore window scroll position
if (document.documentElement && document.documentElement.scrollTop)
document.documentElement.scrollTop = winScroll
else if (document.body)
document.body.scrollTop = winScroll;


var outerSpan = document.createElement('span');
} else if (txtarea.selectionStart || txtarea.selectionStart == '0') { // Mozilla
outerSpan.className = 'toctoggle';


var toggleLink = document.createElement('a');
//save textarea scroll position
toggleLink.id = 'togglelink';
var textScroll = txtarea.scrollTop;
toggleLink.className = 'internal';
//get current selection
toggleLink.href = 'javascript:toggleToc()';
txtarea.focus();
toggleLink.appendChild(document.createTextNode(tocHideText));
var startPos = txtarea.selectionStart;
var endPos = txtarea.selectionEnd;
selText = txtarea.value.substring(startPos, endPos);
//insert tags
checkSelectedText();
txtarea.value = txtarea.value.substring(0, startPos)
+ tagOpen + selText + tagClose
+ txtarea.value.substring(endPos, txtarea.value.length);
//set new selection
if (isSample) {
txtarea.selectionStart = startPos + tagOpen.length;
txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
} else {
txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
txtarea.selectionEnd = txtarea.selectionStart;
}
//restore textarea scroll position
txtarea.scrollTop = textScroll;
}


outerSpan.appendChild(document.createTextNode('['));
function checkSelectedText(){
outerSpan.appendChild(toggleLink);
if (!selText) {
outerSpan.appendChild(document.createTextNode(']'));
selText = sampleText;
isSample = true;
} else if (selText.charAt(selText.length - 1) == ' ') { //exclude ending space char
selText = selText.substring(0, selText.length - 1);
tagClose += ' '
}
}


linkHolder.appendChild(document.createTextNode(' '));
linkHolder.appendChild(outerSpan);
var cookiePos = document.cookie.indexOf("hidetoc=");
if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) {
toggleToc();
}
}
}
}


function changeText(el, newText) {
// Safari work around
if (el.innerText) {
el.innerText = newText;
} else if (el.firstChild && el.firstChild.nodeValue) {
el.firstChild.nodeValue = newText;
}
}


function toggleToc() {
/**
var toc = document.getElementById('toc').getElementsByTagName('ul')[0];
* Set the accesskey prefix based on browser detection.
var toggleLink = document.getElementById('togglelink');
*/
 
var tooltipAccessKeyPrefix = 'alt-';
if (toc && toggleLink && toc.style.display == 'none') {
if (is_opera) {
changeText(toggleLink, tocHideText);
tooltipAccessKeyPrefix = 'shift-esc-';
toc.style.display = 'block';
} else if (is_safari
document.cookie = "hidetoc=0";
  || navigator.userAgent.toLowerCase().indexOf('mac') != -1
} else {
  || navigator.userAgent.toLowerCase().indexOf('konqueror') != -1 ) {
changeText(toggleLink, tocShowText);
tooltipAccessKeyPrefix = 'ctrl-';
toc.style.display = 'none';
} else if (is_ff2_x11 || is_ff2_win) {
document.cookie = "hidetoc=1";
tooltipAccessKeyPrefix = 'alt-shift-';
}
}
}
var tooltipAccessKeyRegexp = /\[(ctrl-)?(alt-)?(shift-)?(esc-)?.\]$/;


var mwEditButtons = [];
/**
var mwCustomEditButtons = []; // eg to add in MediaWiki:Common.js
* Add the appropriate prefix to the accesskey shown in the tooltip.
 
* If the nodeList parameter is given, only those nodes are updated;
// this function generates the actual toolbar buttons with localized text
* otherwise, all the nodes that will probably have accesskeys by
// we use it to avoid creating the toolbar where javascript is not enabled
* default are updated.
function addButton(imageFile, speedTip, tagOpen, tagClose, sampleText, imageId) {
*
// Don't generate buttons for browsers which don't fully
* @param Array nodeList -- list of elements to update
// support it.
*/
mwEditButtons[mwEditButtons.length] =
function updateTooltipAccessKeys( nodeList ) {
{"imageId": imageId,
if ( !nodeList ) {
"imageFile": imageFile,
// skins without a "column-one" element don't seem to have links with accesskeys either
"speedTip": speedTip,
var columnOne = document.getElementById("column-one");
"tagOpen": tagOpen,
if ( columnOne )
"tagClose": tagClose,
updateTooltipAccessKeys( columnOne.getElementsByTagName("a") );
"sampleText": sampleText};
// these are rare enough that no such optimization is needed
}
updateTooltipAccessKeys( document.getElementsByTagName("input") );
 
updateTooltipAccessKeys( document.getElementsByTagName("label") );
// this function generates the actual toolbar buttons with localized text
return;
// we use it to avoid creating the toolbar where javascript is not enabled
function mwInsertEditButton(parent, item) {
var image = document.createElement("img");
image.width = 23;
image.height = 22;
image.className = "mw-toolbar-editbutton";
if (item.imageId) image.id = item.imageId;
image.src = item.imageFile;
image.border = 0;
image.alt = item.speedTip;
image.title = item.speedTip;
image.style.cursor = "pointer";
image.onclick = function() {
insertTags(item.tagOpen, item.tagClose, item.sampleText);
return false;
};
 
parent.appendChild(image);
return true;
}
 
function mwSetupToolbar() {
var toolbar = document.getElementById('toolbar');
if (!toolbar) { return false; }
 
var textbox = document.getElementById('wpTextbox1');
if (!textbox) { return false; }
 
// Don't generate buttons for browsers which don't fully
// support it.
if (!(document.selection && document.selection.createRange)
&& textbox.selectionStart === null) {
return false;
}
}


for (var i = 0; i < mwEditButtons.length; i++) {
for ( var i = 0; i < nodeList.length; i++ ) {
mwInsertEditButton(toolbar, mwEditButtons[i]);
var element = nodeList[i];
}
var tip = element.getAttribute("title");
for (var i = 0; i < mwCustomEditButtons.length; i++) {
var key = element.getAttribute("accesskey");
mwInsertEditButton(toolbar, mwCustomEditButtons[i]);
if ( key && tooltipAccessKeyRegexp.exec(tip) ) {
tip = tip.replace(tooltipAccessKeyRegexp,
  "["+tooltipAccessKeyPrefix+key+"]");
element.setAttribute("title", tip );
}
}
}
return true;
}
}


function escapeQuotes(text) {
/**
var re = new RegExp("'","g");
* Add a link to one of the portlet menus on the page, including:
text = text.replace(re,"\\'");
*
re = new RegExp("\\n","g");
* p-cactions: Content actions (shown as tabs above the main content in Monobook)
text = text.replace(re,"\\n");
* p-personal: Personal tools (shown at the top right of the page in Monobook)
return escapeQuotesHTML(text);
* p-navigation: Navigation
}
* p-tb: Toolbox
 
*
function escapeQuotesHTML(text) {
* This function exists for the convenience of custom JS authors. All
var re = new RegExp('&',"g");
* but the first three parameters are optional, though providing at
text = text.replace(re,"&amp;");
* least an id and a tooltip is recommended.
re = new RegExp('"',"g");
*
text = text.replace(re,"&quot;");
* By default the new link will be added to the end of the list.  To
re = new RegExp('<',"g");
* add the link before a given existing item, pass the DOM node of
text = text.replace(re,"&lt;");
* that item (easily obtained with document.getElementById()) as the
re = new RegExp('>',"g");
* nextnode parameter; to add the link _after_ an existing item, pass
text = text.replace(re,"&gt;");
* the node's nextSibling instead.
return text;
*
}
* @param String portlet -- id of the target portlet ("p-cactions", "p-personal", "p-navigation" or "p-tb")
 
* @param String href -- link URL
// apply tagOpen/tagClose to selection in textarea,
* @param String text -- link text (will be automatically lowercased by CSS for p-cactions in Monobook)
// use sampleText instead of selection if there is none
* @param String id -- id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-")
function insertTags(tagOpen, tagClose, sampleText) {
* @param String tooltip -- text to show when hovering over the link, without accesskey suffix
var txtarea;
* @param String accesskey -- accesskey to activate this link (one character, try to avoid conflicts)
if (document.editform) {
* @param Node nextnode -- the DOM node before which the new item should be added, should be another item in the same list
txtarea = document.editform.wpTextbox1;
*
} else {
* @return Node -- the DOM node of the new item (an LI element) or null
// some alternate form? take the first one we can find
*/
var areas = document.getElementsByTagName('textarea');
function addPortletLink(portlet, href, text, id, tooltip, accesskey, nextnode) {
txtarea = areas[0];
var node = document.getElementById(portlet);
}
if ( !node ) return null;
var selText, isSample = false;
node = node.getElementsByTagName( "ul" )[0];
if ( !node ) return null;


if (document.selection  && document.selection.createRange) { // IE/Opera
var link = document.createElement( "a" );
link.appendChild( document.createTextNode( text ) );
link.href = href;


//save window scroll position
var item = document.createElement( "li" );
if (document.documentElement && document.documentElement.scrollTop)
item.appendChild( link );
var winScroll = document.documentElement.scrollTop
if ( id ) item.id = id;
else if (document.body)
var winScroll = document.body.scrollTop;
//get current selection 
txtarea.focus();
var range = document.selection.createRange();
selText = range.text;
//insert tags
checkSelectedText();
range.text = tagOpen + selText + tagClose;
//mark sample text as selected
if (isSample && range.moveStart) {
if (window.opera)
tagClose = tagClose.replace(/\n/g,'');
range.moveStart('character', - tagClose.length - selText.length);
range.moveEnd('character', - tagClose.length);  
}
range.select();  
//restore window scroll position
if (document.documentElement && document.documentElement.scrollTop)
document.documentElement.scrollTop = winScroll
else if (document.body)
document.body.scrollTop = winScroll;


} else if (txtarea.selectionStart || txtarea.selectionStart == '0') { // Mozilla
if ( accesskey ) {
link.setAttribute( "accesskey", accesskey );
tooltip += " ["+accesskey+"]";
}
if ( tooltip ) {
link.setAttribute( "title", tooltip );
}
if ( accesskey && tooltip ) {
updateTooltipAccessKeys( new Array( link ) );
}
 
if ( nextnode && nextnode.parentNode == node )
node.insertBefore( item, nextnode );
else
node.appendChild( item );  // IE compatibility (?)
 
return item;
}


//save textarea scroll position
var textScroll = txtarea.scrollTop;
//get current selection
txtarea.focus();
var startPos = txtarea.selectionStart;
var endPos = txtarea.selectionEnd;
selText = txtarea.value.substring(startPos, endPos);
//insert tags
checkSelectedText();
txtarea.value = txtarea.value.substring(0, startPos)
+ tagOpen + selText + tagClose
+ txtarea.value.substring(endPos, txtarea.value.length);
//set new selection
if (isSample) {
txtarea.selectionStart = startPos + tagOpen.length;
txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
} else {
txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
txtarea.selectionEnd = txtarea.selectionStart;
}
//restore textarea scroll position
txtarea.scrollTop = textScroll;
}


function checkSelectedText(){
/**
if (!selText) {
* Set up accesskeys/tooltips from the deprecated ta array.  If doId
selText = sampleText;
* is specified, only set up for that id.  Note that this function is
isSample = true;
* deprecated and will not be supported indefinitely -- use
} else if (selText.charAt(selText.length - 1) == ' ') { //exclude ending space char
* updateTooltipAccessKey() instead.
selText = selText.substring(0, selText.length - 1);
*
tagClose += ' '
* @param mixed doId string or null
}
*/
function akeytt( doId ) {
// A lot of user scripts (and some of the code below) break if
// ta isn't defined, so we make sure it is.  Explictly using
// window.ta avoids a "ta is not defined" error.
if (!window.ta) window.ta = new Array;
 
// Make a local, possibly restricted, copy to avoid clobbering
// the original.
var ta;
if ( doId ) {
ta = [doId];
} else {
ta = window.ta;
}
}


}
// Now deal with evil deprecated ta
 
var watchCheckboxExists = document.getElementById( 'wpWatchthis' ) ? true : false;
 
for (var id in ta) {
/**
var n = document.getElementById(id);
* Set the accesskey prefix based on browser detection.
if (n) {
*/
var a = null;
var tooltipAccessKeyPrefix = 'alt-';
var ak = '';
if (is_opera) {
// Are we putting accesskey in it
tooltipAccessKeyPrefix = 'shift-esc-';
if (ta[id][0].length > 0) {
} else if (is_safari
// Is this object a object? If not assume it's the next child.
  || navigator.userAgent.toLowerCase().indexOf('mac') != -1
  || navigator.userAgent.toLowerCase().indexOf('konqueror') != -1 ) {
tooltipAccessKeyPrefix = 'ctrl-';
} else if (is_ff2_x11 || is_ff2_win) {
tooltipAccessKeyPrefix = 'alt-shift-';
}
var tooltipAccessKeyRegexp = /\[(ctrl-)?(alt-)?(shift-)?(esc-)?.\]$/;


/**
if (n.nodeName.toLowerCase() == "a") {
* Add the appropriate prefix to the accesskey shown in the tooltip.
a = n;
* If the nodeList parameter is given, only those nodes are updated;
} else {
* otherwise, all the nodes that will probably have accesskeys by
a = n.childNodes[0];
* default are updated.
}
*
// Don't add an accesskey for the watch tab if the watch
* @param Array nodeList -- list of elements to update
// checkbox is also available.
*/
if (a && ((id != 'ca-watch' && id != 'ca-unwatch') || !watchCheckboxExists)) {
function updateTooltipAccessKeys( nodeList ) {
a.accessKey = ta[id][0];
if ( !nodeList ) {
ak = ' ['+tooltipAccessKeyPrefix+ta[id][0]+']';
// skins without a "column-one" element don't seem to have links with accesskeys either
}
var columnOne = document.getElementById("column-one");
} else {
if ( columnOne )
// We don't care what type the object is when assigning tooltip
updateTooltipAccessKeys( columnOne.getElementsByTagName("a") );
a = n;
// these are rare enough that no such optimization is needed
ak = '';
updateTooltipAccessKeys( document.getElementsByTagName("input") );
}
updateTooltipAccessKeys( document.getElementsByTagName("label") );
return;
}


for ( var i = 0; i < nodeList.length; i++ ) {
if (a) {
var element = nodeList[i];
a.title = ta[id][1]+ak;
var tip = element.getAttribute("title");
}
var key = element.getAttribute("accesskey");
if ( key && tooltipAccessKeyRegexp.exec(tip) ) {
tip = tip.replace(tooltipAccessKeyRegexp,
  "["+tooltipAccessKeyPrefix+key+"]");
element.setAttribute("title", tip );
}
}
}
}
}
}


/**
function setupRightClickEdit() {
* Add a link to one of the portlet menus on the page, including:
if (document.getElementsByTagName) {
*
var spans = document.getElementsByTagName('span');
* p-cactions: Content actions (shown as tabs above the main content in Monobook)
for (var i = 0; i < spans.length; i++) {
* p-personal: Personal tools (shown at the top right of the page in Monobook)
var el = spans[i];
* p-navigation: Navigation
if(el.className == 'editsection') {
* p-tb: Toolbox
addRightClickEditHandler(el);
*
}
* This function exists for the convenience of custom JS authors.  All
}
* but the first three parameters are optional, though providing at
}
* least an id and a tooltip is recommended.
}
*
* By default the new link will be added to the end of the list.  To
* add the link before a given existing item, pass the DOM node of
* that item (easily obtained with document.getElementById()) as the
* nextnode parameter; to add the link _after_ an existing item, pass
* the node's nextSibling instead.
*
* @param String portlet -- id of the target portlet ("p-cactions", "p-personal", "p-navigation" or "p-tb")
* @param String href -- link URL
* @param String text -- link text (will be automatically lowercased by CSS for p-cactions in Monobook)
* @param String id -- id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-")
* @param String tooltip -- text to show when hovering over the link, without accesskey suffix
* @param String accesskey -- accesskey to activate this link (one character, try to avoid conflicts)
* @param Node nextnode -- the DOM node before which the new item should be added, should be another item in the same list
*
* @return Node -- the DOM node of the new item (an LI element) or null
*/
function addPortletLink(portlet, href, text, id, tooltip, accesskey, nextnode) {
var node = document.getElementById(portlet);
if ( !node ) return null;
node = node.getElementsByTagName( "ul" )[0];
if ( !node ) return null;


var link = document.createElement( "a" );
function addRightClickEditHandler(el) {
link.appendChild( document.createTextNode( text ) );
for (var i = 0; i < el.childNodes.length; i++) {
link.href = href;
var link = el.childNodes[i];
if (link.nodeType == 1 && link.nodeName.toLowerCase() == 'a') {
var editHref = link.getAttribute('href');
// find the enclosing (parent) header
var prev = el.parentNode;
if (prev && prev.nodeType == 1 &&
prev.nodeName.match(/^[Hh][1-6]$/)) {
prev.oncontextmenu = function(e) {
if (!e) { e = window.event; }
// e is now the event in all browsers
var targ;
if (e.target) { targ = e.target; }
else if (e.srcElement) { targ = e.srcElement; }
if (targ.nodeType == 3) { // defeat Safari bug
targ = targ.parentNode;
}
// targ is now the target element


var item = document.createElement( "li" );
// We don't want to deprive the noble reader of a context menu
item.appendChild( link );
// for the section edit link, do we?  (Might want to extend this
if ( id ) item.id = id;
// to all <a>'s?)
 
if (targ.nodeName.toLowerCase() != 'a'
if ( accesskey ) {
|| targ.parentNode.className != 'editsection') {
link.setAttribute( "accesskey", accesskey );
document.location = editHref;
tooltip += " ["+accesskey+"]";
return false;
}
}
if ( tooltip ) {
return true;
link.setAttribute( "title", tooltip );
};
}
}
if ( accesskey && tooltip ) {
}
updateTooltipAccessKeys( new Array( link ) );
}
}
}


if ( nextnode && nextnode.parentNode == node )
var checkboxes;
node.insertBefore( item, nextnode );
var lastCheckbox;
else
node.appendChild( item ); // IE compatibility (?)


return item;
function setupCheckboxShiftClick() {
checkboxes = [];
lastCheckbox = null;
var inputs = document.getElementsByTagName('input');
addCheckboxClickHandlers(inputs);
}
}


function addCheckboxClickHandlers(inputs, start) {
if ( !start) start = 0;


/**
var finish = start + 250;
* Set up accesskeys/tooltips from the deprecated ta array.  If doId
if ( finish > inputs.length )
* is specified, only set up for that id.  Note that this function is
finish = inputs.length;
* deprecated and will not be supported indefinitely -- use
* updateTooltipAccessKey() instead.
*
* @param mixed doId string or null
*/
function akeytt( doId ) {
// A lot of user scripts (and some of the code below) break if
// ta isn't defined, so we make sure it is.  Explictly using
// window.ta avoids a "ta is not defined" error.
if (!window.ta) window.ta = new Array;


// Make a local, possibly restricted, copy to avoid clobbering
for ( var i = start; i < finish; i++ ) {
// the original.
var cb = inputs[i];
var ta;
if ( !cb.type || cb.type.toLowerCase() != 'checkbox' )
if ( doId ) {
continue;
ta = [doId];
var end = checkboxes.length;
} else {
checkboxes[end] = cb;
ta = window.ta;
cb.index = end;
cb.onclick = checkboxClickHandler;
}
}


// Now deal with evil deprecated ta
if ( finish < inputs.length ) {
var watchCheckboxExists = document.getElementById( 'wpWatchthis' ) ? true : false;
setTimeout( function () {
for (var id in ta) {
addCheckboxClickHandlers(inputs, finish);
var n = document.getElementById(id);
}, 200 );
if (n) {
}
var a = null;
}
var ak = '';
// Are we putting accesskey in it
if (ta[id][0].length > 0) {
// Is this object a object? If not assume it's the next child.


if (n.nodeName.toLowerCase() == "a") {
function checkboxClickHandler(e) {
a = n;
if (typeof e == 'undefined') {
} else {
e = window.event;
a = n.childNodes[0];
}
// Don't add an accesskey for the watch tab if the watch
// checkbox is also available.
if (a && ((id != 'ca-watch' && id != 'ca-unwatch') || !watchCheckboxExists)) {
a.accessKey = ta[id][0];
ak = ' ['+tooltipAccessKeyPrefix+ta[id][0]+']';
}
} else {
// We don't care what type the object is when assigning tooltip
a = n;
ak = '';
}
 
if (a) {
a.title = ta[id][1]+ak;
}
}
}
}
}
if ( !e.shiftKey || lastCheckbox === null ) {
 
lastCheckbox = this.index;
function setupRightClickEdit() {
return true;
if (document.getElementsByTagName) {
}
var spans = document.getElementsByTagName('span');
var endState = this.checked;
for (var i = 0; i < spans.length; i++) {
var start, finish;
var el = spans[i];
if ( this.index < lastCheckbox ) {
if(el.className == 'editsection') {
start = this.index + 1;
addRightClickEditHandler(el);
finish = lastCheckbox;
}
} else {
}
start = lastCheckbox;
finish = this.index - 1;
}
for (var i = start; i <= finish; ++i ) {
checkboxes[i].checked = endState;
}
}
lastCheckbox = this.index;
return true;
}
}


function addRightClickEditHandler(el) {
function toggle_element_activation(ida,idb) {
for (var i = 0; i < el.childNodes.length; i++) {
if (!document.getElementById) {
var link = el.childNodes[i];
return;
if (link.nodeType == 1 && link.nodeName.toLowerCase() == 'a') {
}
var editHref = link.getAttribute('href');
document.getElementById(ida).disabled=true;
// find the enclosing (parent) header
document.getElementById(idb).disabled=false;
var prev = el.parentNode;
}
if (prev && prev.nodeType == 1 &&
prev.nodeName.match(/^[Hh][1-6]$/)) {
prev.oncontextmenu = function(e) {
if (!e) { e = window.event; }
// e is now the event in all browsers
var targ;
if (e.target) { targ = e.target; }
else if (e.srcElement) { targ = e.srcElement; }
if (targ.nodeType == 3) { // defeat Safari bug
targ = targ.parentNode;
}
// targ is now the target element


// We don't want to deprive the noble reader of a context menu
function toggle_element_check(ida,idb) {
// for the section edit link, do we?  (Might want to extend this
if (!document.getElementById) {
// to all <a>'s?)
return;
if (targ.nodeName.toLowerCase() != 'a'
|| targ.parentNode.className != 'editsection') {
document.location = editHref;
return false;
}
return true;
};
}
}
}
}
document.getElementById(ida).checked=true;
document.getElementById(idb).checked=false;
}
}


var checkboxes;
/**
var lastCheckbox;
* Restore the edit box scroll state following a preview operation,
 
* and set up a form submission handler to remember this state
function setupCheckboxShiftClick() {
*/
checkboxes = [];
function scrollEditBox() {
lastCheckbox = null;
var editBox = document.getElementById( 'wpTextbox1' );
var inputs = document.getElementsByTagName('input');
var scrollTop = document.getElementById( 'wpScrolltop' );
addCheckboxClickHandlers(inputs);
var editForm = document.getElementById( 'editform' );
if( editBox && scrollTop ) {
if( scrollTop.value )
editBox.scrollTop = scrollTop.value;
addHandler( editForm, 'submit', function() {
document.getElementById( 'wpScrolltop' ).value = document.getElementById( 'wpTextbox1' ).scrollTop;  
} );
}
}
}
hookEvent( 'load', scrollEditBox );


function addCheckboxClickHandlers(inputs, start) {
var allmessages_nodelist = false;
if ( !start) start = 0;
var allmessages_modified = false;
var allmessages_timeout = false;
var allmessages_running = false;


var finish = start + 250;
function allmessagesmodified() {
if ( finish > inputs.length )
allmessages_modified = !allmessages_modified;
finish = inputs.length;
allmessagesfilter();
}


for ( var i = start; i < finish; i++ ) {
function allmessagesfilter() {
var cb = inputs[i];
if ( allmessages_timeout )
if ( !cb.type || cb.type.toLowerCase() != 'checkbox' )
window.clearTimeout( allmessages_timeout );
continue;
var end = checkboxes.length;
checkboxes[end] = cb;
cb.index = end;
cb.onclick = checkboxClickHandler;
}


if ( finish < inputs.length ) {
if ( !allmessages_running )
setTimeout( function () {
allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
addCheckboxClickHandlers(inputs, finish);
}, 200 );
}
}
}


function checkboxClickHandler(e) {
function allmessagesfilter_do() {
if (typeof e == 'undefined') {
if ( !allmessages_nodelist )
e = window.event;
return;
}
 
if ( !e.shiftKey || lastCheckbox === null ) {
var text = document.getElementById('allmessagesinput').value;
lastCheckbox = this.index;
var nodef = allmessages_modified;
return true;
}
var endState = this.checked;
var start, finish;
if ( this.index < lastCheckbox ) {
start = this.index + 1;
finish = lastCheckbox;
} else {
start = lastCheckbox;
finish = this.index - 1;
}
for (var i = start; i <= finish; ++i ) {
checkboxes[i].checked = endState;
}
lastCheckbox = this.index;
return true;
}


function toggle_element_activation(ida,idb) {
allmessages_running = true;
if (!document.getElementById) {
return;
}
document.getElementById(ida).disabled=true;
document.getElementById(idb).disabled=false;
}


function toggle_element_check(ida,idb) {
for ( var name in allmessages_nodelist ) {
if (!document.getElementById) {
var nodes = allmessages_nodelist[name];
return;
var display = ( name.indexOf( text ) == -1 ? 'none' : '' );
 
for ( var i = 0; i < nodes.length; i++)
nodes[i].style.display =
( nodes[i].className == "def" && nodef
  ? 'none' : display );
}
}
document.getElementById(ida).checked=true;
 
document.getElementById(idb).checked=false;
if ( text != document.getElementById('allmessagesinput').value ||
    nodef != allmessages_modified )
allmessagesfilter_do(); // repeat
 
allmessages_running = false;
}
}


/**
function allmessagesfilter_init() {
* Restore the edit box scroll state following a preview operation,
if ( allmessages_nodelist )
* and set up a form submission handler to remember this state
return;
*/
 
function scrollEditBox() {
var nodelist = new Array();
var editBox = document.getElementById( 'wpTextbox1' );
var templist = new Array();
var scrollTop = document.getElementById( 'wpScrolltop' );
var editForm = document.getElementById( 'editform' );
if( editBox && scrollTop ) {
if( scrollTop.value )
editBox.scrollTop = scrollTop.value;
addHandler( editForm, 'submit', function() {
document.getElementById( 'wpScrolltop' ).value = document.getElementById( 'wpTextbox1' ).scrollTop;
} );
}
}
hookEvent( 'load', scrollEditBox );


var allmessages_nodelist = false;
var table = document.getElementById('allmessagestable');
var allmessages_modified = false;
if ( !table ) return;
var allmessages_timeout = false;
var allmessages_running = false;


function allmessagesmodified() {
var rows = document.getElementsByTagName('tr');
allmessages_modified = !allmessages_modified;
for ( var i = 0; i < rows.length; i++ ) {
allmessagesfilter();
var id = rows[i].getAttribute('id')
}
if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
templist[ id ] = rows[i];
}
 
var spans = table.getElementsByTagName('span');
for ( var i = 0; i < spans.length; i++ ) {
var id = spans[i].getAttribute('id')
if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;


function allmessagesfilter() {
var nodes = new Array();
if ( allmessages_timeout )
var row1 = templist[ id.replace('i', 'r1') ];
window.clearTimeout( allmessages_timeout );
var row2 = templist[ id.replace('i', 'r2') ];


if ( !allmessages_running )
if ( row1 ) nodes[nodes.length] = row1;
allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
if ( row2 ) nodes[nodes.length] = row2;
}
nodelist[ spans[i].firstChild.nodeValue ] = nodes;
}


function allmessagesfilter_do() {
var k = document.getElementById('allmessagesfilter');
if ( !allmessages_nodelist )
if (k) { k.style.display = ''; }
return;


var text = document.getElementById('allmessagesinput').value;
allmessages_nodelist = nodelist;
var nodef = allmessages_modified;
 
allmessages_running = true;
 
for ( var name in allmessages_nodelist ) {
var nodes = allmessages_nodelist[name];
var display = ( name.indexOf( text ) == -1 ? 'none' : '' );
 
for ( var i = 0; i < nodes.length; i++)
nodes[i].style.display =
( nodes[i].className == "def" && nodef
  ? 'none' : display );
}
 
if ( text != document.getElementById('allmessagesinput').value ||
    nodef != allmessages_modified )
allmessagesfilter_do();  // repeat
 
allmessages_running = false;
}
}


function allmessagesfilter_init() {
hookEvent( "load", allmessagesfilter_init );
if ( allmessages_nodelist )
return;


var nodelist = new Array();
/*
var templist = new Array();
Written by Jonathan Snook, http://www.snook.ca/jonathan
 
Add-ons by Robert Nyman, http://www.robertnyman.com
var table = document.getElementById('allmessagestable');
Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
if ( !table ) return;
From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
 
*/
var rows = document.getElementsByTagName('tr');
function getElementsByClassName(oElm, strTagName, oClassNames){
for ( var i = 0; i < rows.length; i++ ) {
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var id = rows[i].getAttribute('id')
var arrReturnElements = new Array();
if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
var arrRegExpClassNames = new Array();
templist[ id ] = rows[i];
if(typeof oClassNames == "object"){
for(var i=0; i<oClassNames.length; i++){
arrRegExpClassNames[arrRegExpClassNames.length] =
new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)");
}
}
}
 
else{
var spans = table.getElementsByTagName('span');
arrRegExpClassNames[arrRegExpClassNames.length] =
for ( var i = 0; i < spans.length; i++ ) {
new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)");
var id = spans[i].getAttribute('id')
if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;
 
var nodes = new Array();
var row1 = templist[ id.replace('i', 'r1') ];
var row2 = templist[ id.replace('i', 'r2') ];
 
if ( row1 ) nodes[nodes.length] = row1;
if ( row2 ) nodes[nodes.length] = row2;
nodelist[ spans[i].firstChild.nodeValue ] = nodes;
}
}
 
var oElement;
var k = document.getElementById('allmessagesfilter');
var bMatchesAll;
if (k) { k.style.display = ''; }
for(var j=0; j<arrElements.length; j++){
 
oElement = arrElements[j];
allmessages_nodelist = nodelist;
bMatchesAll = true;
for(var k=0; k<arrRegExpClassNames.length; k++){
if(!arrRegExpClassNames[k].test(oElement.className)){
bMatchesAll = false;
break;
}
}
if(bMatchesAll){
arrReturnElements[arrReturnElements.length] = oElement;
}
}
return (arrReturnElements)
}
}


hookEvent( "load", allmessagesfilter_init );
function redirectToFragment(fragment) {
 
var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
/*
if (match) {
Written by Jonathan Snook, http://www.snook.ca/jonathan
var webKitVersion = parseInt(match[1]);
Add-ons by Robert Nyman, http://www.robertnyman.com
if (webKitVersion < 420) {
Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
// Released Safari w/ WebKit 418.9.1 messes up horribly
From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
// Nightlies of 420+ are ok
*/
return;
function getElementsByClassName(oElm, strTagName, oClassNames){
var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
var arrReturnElements = new Array();
var arrRegExpClassNames = new Array();
if(typeof oClassNames == "object"){
for(var i=0; i<oClassNames.length; i++){
arrRegExpClassNames[arrRegExpClassNames.length] =
new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)");
}
}
}
}
else{
if (is_gecko) {
arrRegExpClassNames[arrRegExpClassNames.length] =
// Mozilla needs to wait until after load, otherwise the window doesn't scroll
new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)");
addOnloadHook(function () {
if (window.location.hash == "")
window.location.hash = fragment;
});
} else {
if (window.location.hash == "")
window.location.hash = fragment;
}
}
var oElement;
}
var bMatchesAll;
 
for(var j=0; j<arrElements.length; j++){
 
oElement = arrElements[j];
/*
bMatchesAll = true;
* Table sorting script  by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/.
for(var k=0; k<arrRegExpClassNames.length; k++){
* Based on a script from http://www.kryogenix.org/code/browser/sorttable/.
if(!arrRegExpClassNames[k].test(oElement.className)){
* Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html .
bMatchesAll = false;
*
break;
* Copyright (c) 1997-2006 Stuart Langridge, Joost de Valk.
}
*
}
* @todo don't break on colspans/rowspans (bug 8028)
if(bMatchesAll){
* @todo language-specific digit grouping/decimals (bug 8063)
arrReturnElements[arrReturnElements.length] = oElement;
* @todo support all accepted date formats (bug 8226)
}
*/
}
return (arrReturnElements)
}


function redirectToFragment(fragment) {
var ts_image_path = stylepath+"/common/images/";
var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
var ts_image_up = "sort_up.gif";
if (match) {
var ts_image_down = "sort_down.gif";
var webKitVersion = parseInt(match[1]);
var ts_image_none = "sort_none.gif";
if (webKitVersion < 420) {
var ts_europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true"
// Released Safari w/ WebKit 418.9.1 messes up horribly
var ts_alternate_row_colors = true;
// Nightlies of 420+ are ok
var SORT_COLUMN_INDEX;
return;
 
function sortables_init() {
var idnum = 0;
// Find all tables with class sortable and make them sortable
var tables = getElementsByClassName(document, "table", "sortable");
for (var ti = 0; ti < tables.length ; ti++) {
if (!tables[ti].id) {
tables[ti].setAttribute('id','sortable_table_id_'+idnum);
++idnum;
}
}
ts_makeSortable(tables[ti]);
}
}
if (is_gecko) {
}
// Mozilla needs to wait until after load, otherwise the window doesn't scroll
 
addOnloadHook(function () {
function ts_makeSortable(table) {
if (window.location.hash == "")
var firstRow;
window.location.hash = fragment;
if (table.rows && table.rows.length > 0) {
});
if (table.tHead && table.tHead.rows.length > 0) {
} else {
firstRow = table.tHead.rows[table.tHead.rows.length-1];
if (window.location.hash == "")
} else {
window.location.hash = fragment;
firstRow = table.rows[0];
}
}
if (!firstRow) return;
 
// We have a first row: assume it's the header, and make its contents clickable links
for (var i = 0; i < firstRow.cells.length; i++) {
var cell = firstRow.cells[i];
if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) {
cell.innerHTML += '&nbsp;&nbsp;<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;"><span class="sortarrow"><img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/></span></a>';
}
}
if (ts_alternate_row_colors) {
ts_alternate(table);
}
}
}
}


/*
function ts_getInnerText(el) {
* Table sorting script  by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/.
if (typeof el == "string") return el;
* Based on a script from http://www.kryogenix.org/code/browser/sorttable/.
if (typeof el == "undefined") { return el };
* Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html .
if (el.textContent) return el.textContent; // not needed but it is faster
*
if (el.innerText) return el.innerText;    // IE doesn't have textContent
* Copyright (c) 1997-2006 Stuart Langridge, Joost de Valk.
var str = "";
*
* @todo don't break on colspans/rowspans (bug 8028)
* @todo language-specific digit grouping/decimals (bug 8063)
* @todo support all accepted date formats (bug 8226)
*/


var ts_image_path = stylepath+"/common/images/";
var cs = el.childNodes;
var ts_image_up = "sort_up.gif";
var l = cs.length;
var ts_image_down = "sort_down.gif";
for (var i = 0; i < l; i++) {
var ts_image_none = "sort_none.gif";
switch (cs[i].nodeType) {
var ts_europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true"
case 1: //ELEMENT_NODE
var ts_alternate_row_colors = true;
str += ts_getInnerText(cs[i]);
var SORT_COLUMN_INDEX;
break;
 
case 3: //TEXT_NODE
function sortables_init() {
str += cs[i].nodeValue;
var idnum = 0;
break;
// Find all tables with class sortable and make them sortable
var tables = getElementsByClassName(document, "table", "sortable");
for (var ti = 0; ti < tables.length ; ti++) {
if (!tables[ti].id) {
tables[ti].setAttribute('id','sortable_table_id_'+idnum);
++idnum;
}
}
ts_makeSortable(tables[ti]);
}
}
return str;
}
}


function ts_makeSortable(table) {
function ts_resortTable(lnk) {
var firstRow;
// get the span
if (table.rows && table.rows.length > 0) {
var span = lnk.getElementsByTagName('span')[0];
if (table.tHead && table.tHead.rows.length > 0) {
firstRow = table.tHead.rows[table.tHead.rows.length-1];
} else {
firstRow = table.rows[0];
}
}
if (!firstRow) return;


// We have a first row: assume it's the header, and make its contents clickable links
var td = lnk.parentNode;
for (var i = 0; i < firstRow.cells.length; i++) {
var tr = td.parentNode;
var cell = firstRow.cells[i];
var column = td.cellIndex;
if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) {
 
cell.innerHTML += '&nbsp;&nbsp;<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;"><span class="sortarrow"><img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/></span></a>';
var table = tr.parentNode;
}
while (table && !(table.tagName && table.tagName.toLowerCase() == 'table'))
}
table = table.parentNode;
if (ts_alternate_row_colors) {
if (!table) return;
ts_alternate(table);
}
}


function ts_getInnerText(el) {
// Work out a type for the column
if (typeof el == "string") return el;
if (table.rows.length <= 1) return;
if (typeof el == "undefined") { return el };
if (el.textContent) return el.textContent; // not needed but it is faster
if (el.innerText) return el.innerText;    // IE doesn't have textContent
var str = "";


var cs = el.childNodes;
// Skip the first row if that's where the headings are
var l = cs.length;
var rowStart = (table.tHead && table.tHead.rows.length > 0 ? 0 : 1);
for (var i = 0; i < l; i++) {
 
switch (cs[i].nodeType) {
var itm = "";
case 1: //ELEMENT_NODE
for (var i = rowStart; i < table.rows.length; i++) {
str += ts_getInnerText(cs[i]);
if (table.rows[i].cells.length > column) {
break;
itm = ts_getInnerText(table.rows[i].cells[column]);
case 3: //TEXT_NODE
itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, "");
str += cs[i].nodeValue;
if (itm != "") break;
break;
}
}
}
}
return str;
}


function ts_resortTable(lnk) {
sortfn = ts_sort_caseinsensitive;
// get the span
if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/))
var span = lnk.getElementsByTagName('span')[0];
sortfn = ts_sort_date;
if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/))
sortfn = ts_sort_date;
if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/))
sortfn = ts_sort_date;
if (itm.match(/^[\u00a3$\u20ac]/)) // pound dollar euro
sortfn = ts_sort_currency;
if (itm.match(/^[\d.,]+\%?$/))
sortfn = ts_sort_numeric;


var td = lnk.parentNode;
var reverse = (span.getAttribute("sortdir") == 'down');
var tr = td.parentNode;
var column = td.cellIndex;


var table = tr.parentNode;
var newRows = new Array();
while (table && !(table.tagName && table.tagName.toLowerCase() == 'table'))
for (var j = rowStart; j < table.rows.length; j++) {
table = table.parentNode;
var row = table.rows[j];
if (!table) return;
var keyText = ts_getInnerText(row.cells[column]);
var oldIndex = (reverse ? -j : j);


// Work out a type for the column
newRows[newRows.length] = new Array(row, keyText, oldIndex);
if (table.rows.length <= 1) return;
}


// Skip the first row if that's where the headings are
newRows.sort(sortfn);
var rowStart = (table.tHead && table.tHead.rows.length > 0 ? 0 : 1);


var itm = "";
var arrowHTML;
for (var i = rowStart; i < table.rows.length; i++) {
if (reverse) {
if (table.rows[i].cells.length > column) {
arrowHTML = '<img src="'+ ts_image_path + ts_image_down + '" alt="&darr;"/>';
itm = ts_getInnerText(table.rows[i].cells[column]);
newRows.reverse();
itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, "");
span.setAttribute('sortdir','up');
if (itm != "") break;
} else {
}
arrowHTML = '<img src="'+ ts_image_path + ts_image_up + '" alt="&uarr;"/>';
span.setAttribute('sortdir','down');
}
}


sortfn = ts_sort_caseinsensitive;
// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/))
// don't do sortbottom rows
sortfn = ts_sort_date;
for (var i = 0; i < newRows.length; i++) {
if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/))
if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1)
sortfn = ts_sort_date;
table.tBodies[0].appendChild(newRows[i][0]);
if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/))
}
sortfn = ts_sort_date;
// do sortbottom rows only
if (itm.match(/^[\u00a3$\u20ac]/)) // pound dollar euro
for (var i = 0; i < newRows.length; i++) {
sortfn = ts_sort_currency;
if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1)
if (itm.match(/^[\d.,]+\%?$/))
table.tBodies[0].appendChild(newRows[i][0]);
sortfn = ts_sort_numeric;
}


var reverse = (span.getAttribute("sortdir") == 'down');
// Delete any other arrows there may be showing
var spans = getElementsByClassName(tr, "span", "sortarrow");
for (var i = 0; i < spans.length; i++) {
spans[i].innerHTML = '<img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/>';
}
span.innerHTML = arrowHTML;


var newRows = new Array();
ts_alternate(table);
for (var j = rowStart; j < table.rows.length; j++) {
}
var row = table.rows[j];
var keyText = ts_getInnerText(row.cells[column]);
var oldIndex = (reverse ? -j : j);


newRows[newRows.length] = new Array(row, keyText, oldIndex);
function ts_dateToSortKey(date) {
}
// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
 
if (date.length == 11) {
newRows.sort(sortfn);
switch (date.substr(3,3).toLowerCase()) {
 
case "jan": var month = "01"; break;
var arrowHTML;
case "feb": var month = "02"; break;
if (reverse) {
case "mar": var month = "03"; break;
arrowHTML = '<img src="'+ ts_image_path + ts_image_down + '" alt="&darr;"/>';
case "apr": var month = "04"; break;
newRows.reverse();
case "may": var month = "05"; break;
span.setAttribute('sortdir','up');
case "jun": var month = "06"; break;
} else {
case "jul": var month = "07"; break;
arrowHTML = '<img src="'+ ts_image_path + ts_image_up + '" alt="&uarr;"/>';
case "aug": var month = "08"; break;
span.setAttribute('sortdir','down');
case "sep": var month = "09"; break;
}
case "oct": var month = "10"; break;
 
case "nov": var month = "11"; break;
// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
case "dec": var month = "12"; break;
// don't do sortbottom rows
// default: var month = "00";
for (var i = 0; i < newRows.length; i++) {
}
if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1)
return date.substr(7,4)+month+date.substr(0,2);
table.tBodies[0].appendChild(newRows[i][0]);
} else if (date.length == 10) {
}
if (ts_europeandate == false) {
// do sortbottom rows only
return date.substr(6,4)+date.substr(0,2)+date.substr(3,2);
for (var i = 0; i < newRows.length; i++) {
} else {
if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1)
return date.substr(6,4)+date.substr(3,2)+date.substr(0,2);
table.tBodies[0].appendChild(newRows[i][0]);
}
}
} else if (date.length == 8) {
 
yr = date.substr(6,2);
// Delete any other arrows there may be showing
if (parseInt(yr) < 50) {  
var spans = getElementsByClassName(tr, "span", "sortarrow");
yr = '20'+yr;
for (var i = 0; i < spans.length; i++) {
} else {
spans[i].innerHTML = '<img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/>';
yr = '19'+yr;
}
if (ts_europeandate == true) {
return yr+date.substr(3,2)+date.substr(0,2);
} else {
return yr+date.substr(0,2)+date.substr(3,2);
}
}
}
span.innerHTML = arrowHTML;
return "00000000";
}


ts_alternate(table);
function ts_parseFloat(num) {
if (!num) return 0;
num = parseFloat(num.replace(/,/g, ""));
return (isNaN(num) ? 0 : num);
}
}


function ts_dateToSortKey(date) {
function ts_sort_date(a,b) {
// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
var aa = ts_dateToSortKey(a[1]);
if (date.length == 11) {
var bb = ts_dateToSortKey(b[1]);
switch (date.substr(3,3).toLowerCase()) {
return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);
case "jan": var month = "01"; break;
}
case "feb": var month = "02"; break;
 
case "mar": var month = "03"; break;
function ts_sort_currency(a,b) {
case "apr": var month = "04"; break;
var aa = ts_parseFloat(a[1].replace(/[^0-9.]/g,''));
case "may": var month = "05"; break;
var bb = ts_parseFloat(b[1].replace(/[^0-9.]/g,''));
case "jun": var month = "06"; break;
return (aa != bb ? aa - bb : a[2] - b[2]);
case "jul": var month = "07"; break;
}
case "aug": var month = "08"; break;
 
case "sep": var month = "09"; break;
function ts_sort_numeric(a,b) {
case "oct": var month = "10"; break;
var aa = ts_parseFloat(a[1]);
case "nov": var month = "11"; break;
var bb = ts_parseFloat(b[1]);
case "dec": var month = "12"; break;
return (aa != bb ? aa - bb : a[2] - b[2]);
// default: var month = "00";
}
}
 
return date.substr(7,4)+month+date.substr(0,2);
function ts_sort_caseinsensitive(a,b) {
} else if (date.length == 10) {
var aa = a[1].toLowerCase();
if (ts_europeandate == false) {
var bb = b[1].toLowerCase();
return date.substr(6,4)+date.substr(0,2)+date.substr(3,2);
return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);
} else {
return date.substr(6,4)+date.substr(3,2)+date.substr(0,2);
}
} else if (date.length == 8) {
yr = date.substr(6,2);
if (parseInt(yr) < 50) {
yr = '20'+yr;  
} else {
yr = '19'+yr;
}
if (ts_europeandate == true) {
return yr+date.substr(3,2)+date.substr(0,2);
} else {
return yr+date.substr(0,2)+date.substr(3,2);
}
}
return "00000000";
}
}


function ts_parseFloat(num) {
function ts_sort_default(a,b) {
if (!num) return 0;
return (a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]);
num = parseFloat(num.replace(/,/g, ""));
return (isNaN(num) ? 0 : num);
}
}


function ts_sort_date(a,b) {
function ts_alternate(table) {
var aa = ts_dateToSortKey(a[1]);
// Take object table and get all it's tbodies.
var bb = ts_dateToSortKey(b[1]);
var tableBodies = table.getElementsByTagName("tbody");
return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);
// Loop through these tbodies
}
for (var i = 0; i < tableBodies.length; i++) {
 
// Take the tbody, and get all it's rows
function ts_sort_currency(a,b) {
var tableRows = tableBodies[i].getElementsByTagName("tr");
var aa = ts_parseFloat(a[1].replace(/[^0-9.]/g,''));
// Loop through these rows
var bb = ts_parseFloat(b[1].replace(/[^0-9.]/g,''));
// Start at 1 because we want to leave the heading row untouched
return (aa != bb ? aa - bb : a[2] - b[2]);
for (var j = 0; j < tableRows.length; j++) {
// Check if j is even, and apply classes for both possible results
var oldClasses = tableRows[j].className.split(" ");
var newClassName = "";
for (var k = 0; k < oldClasses.length; k++) {
if (oldClasses[k] != "" && oldClasses[k] != "even" && oldClasses[k] != "odd")
newClassName += oldClasses[k] + " ";
}
tableRows[j].className = newClassName + (j % 2 == 0 ? "even" : "odd");
}
}
}
}


function ts_sort_numeric(a,b) {
/*
var aa = ts_parseFloat(a[1]);
* End of table sorting code
var bb = ts_parseFloat(b[1]);
*/
return (aa != bb ? aa - bb : a[2] - b[2]);
}
 
/**
function ts_sort_caseinsensitive(a,b) {
* Add a cute little box at the top of the screen to inform the user of
var aa = a[1].toLowerCase();
* something, replacing any preexisting message.
var bb = b[1].toLowerCase();
*
return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);
* @param String message HTML to be put inside the right div
}
* @param String className  Used in adding a class; should be different for each
 
*  call to allow CSS/JS to hide different boxes.  null = no class used.
function ts_sort_default(a,b) {
* @return Boolean      True on success, false on failure
return (a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]);
*/
}
function jsMsg( message, className ) {
 
if ( !document.getElementById ) {
function ts_alternate(table) {
return false;
// Take object table and get all it's tbodies.
}
var tableBodies = table.getElementsByTagName("tbody");
// We special-case skin structures provided by the software.  Skins that
// Loop through these tbodies
// choose to abandon or significantly modify our formatting can just define
for (var i = 0; i < tableBodies.length; i++) {
// an mw-js-message div to start with.
// Take the tbody, and get all it's rows
var messageDiv = document.getElementById( 'mw-js-message' );
var tableRows = tableBodies[i].getElementsByTagName("tr");
if ( !messageDiv ) {
// Loop through these rows
messageDiv = document.createElement( 'div' );
// Start at 1 because we want to leave the heading row untouched
if ( document.getElementById( 'column-content' )
for (var j = 0; j < tableRows.length; j++) {
&& document.getElementById( 'content' ) ) {
// Check if j is even, and apply classes for both possible results
// MonoBook, presumably
var oldClasses = tableRows[j].className.split(" ");
document.getElementById( 'content' ).insertBefore(
var newClassName = "";
messageDiv,
for (var k = 0; k < oldClasses.length; k++) {
document.getElementById( 'content' ).firstChild
if (oldClasses[k] != "" && oldClasses[k] != "even" && oldClasses[k] != "odd")
);
newClassName += oldClasses[k] + " ";
} else if ( document.getElementById('content')
}
&& document.getElementById( 'article' ) ) {
tableRows[j].className = newClassName + (j % 2 == 0 ? "even" : "odd");
// Non-Monobook but still recognizable (old-style)
}
document.getElementById( 'article').insertBefore(
messageDiv,
document.getElementById( 'article' ).firstChild
);
} else {
return false;
}
}
 
messageDiv.setAttribute( 'id', 'mw-js-message' );
if( className ) {
messageDiv.setAttribute( 'class', 'mw-js-message-'+className );
}
}
messageDiv.innerHTML = message;
return true;
}
}


/*
* End of table sorting code
*/
/**
/**
  * Add a cute little box at the top of the screen to inform the user of
  * Inject a cute little progress spinner after the specified element
* something, replacing any preexisting message.
  *
  *
  * @param String message HTML to be put inside the right div
  * @param element Element to inject after
  * @param String className  Used in adding a class; should be different for each
  * @param id Identifier string (for use with removeSpinner(), below)
*  call to allow CSS/JS to hide different boxes.  null = no class used.
* @return Boolean      True on success, false on failure
  */
  */
function jsMsg( message, className ) {
function injectSpinner( element, id ) {
if ( !document.getElementById ) {
var spinner = document.createElement( "img" );
return false;
spinner.id = "mw-spinner-" + id;
spinner.src = stylepath + "/common/images/spinner.gif";
spinner.alt = spinner.title = "...";
if( element.nextSibling ) {
element.parentNode.insertBefore( spinner, element.nextSibling );
} else {
element.parentNode.appendChild( spinner );
}
}
// We special-case skin structures provided by the software. Skins that
}
// choose to abandon or significantly modify our formatting can just define
 
// an mw-js-message div to start with.
/**
var messageDiv = document.getElementById( 'mw-js-message' );
* Remove a progress spinner added with injectSpinner()
if ( !messageDiv ) {
*
messageDiv = document.createElement( 'div' );
  * @param id Identifier string
if ( document.getElementById( 'column-content' )
*/
&& document.getElementById( 'content' ) ) {
function removeSpinner( id ) {
// MonoBook, presumably
var spinner = document.getElementById( "mw-spinner-" + id );
document.getElementById( 'content' ).insertBefore(
if( spinner ) {
messageDiv,
spinner.parentNode.removeChild( spinner );
document.getElementById( 'content' ).firstChild
);
} else if ( document.getElementById('content')
&& document.getElementById( 'article' ) ) {
// Non-Monobook but still recognizable (old-style)
document.getElementById( 'article').insertBefore(
messageDiv,
document.getElementById( 'article' ).firstChild
);
} else {
return false;
}
}
}
}


messageDiv.setAttribute( 'id', 'mw-js-message' );
if( className ) {
messageDiv.setAttribute( 'class', 'mw-js-message-'+className );
}
messageDiv.innerHTML = message;
return true;
}


/**
/**
  * Inject a cute little progress spinner after the specified element
  * Add an event handler to an element
  *
  *
  * @param element Element to inject after
  * @param Element element Element to add handler to
  * @param id Identifier string (for use with removeSpinner(), below)
* @param String attach Event to attach to
  * @param callable handler Event handler callback
  */
  */
function injectSpinner( element, id ) {
function addHandler( element, attach, handler ) {
var spinner = document.createElement( "img" );
if( window.addEventListener ) {
spinner.id = "mw-spinner-" + id;
element.addEventListener( attach, handler, false );
spinner.src = stylepath + "/common/images/spinner.gif";
} else if( window.attachEvent ) {
spinner.alt = spinner.title = "...";
element.attachEvent( 'on' + attach, handler );
if( element.nextSibling ) {
element.parentNode.insertBefore( spinner, element.nextSibling );
} else {
element.parentNode.appendChild( spinner );
}
}
}
}


/**
/**
  * Remove a progress spinner added with injectSpinner()
  * Add a click event handler to an element
  *
  *
  * @param id Identifier string
  * @param Element element Element to add handler to
  */
* @param callable handler Event handler callback
function removeSpinner( id ) {
*/
var spinner = document.getElementById( "mw-spinner-" + id );
function addClickHandler( element, handler ) {
if( spinner ) {
addHandler( element, 'click', handler );
spinner.parentNode.removeChild( spinner );
}
}
 
 
function runOnloadHook() {
// don't run anything below this for non-dom browsers
if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName)) {
return;
}
 
// set this before running any hooks, since any errors below
// might cause the function to terminate prematurely
doneOnloadHook = true;
 
histrowinit();
unhidetzbutton();
//
// prefs.js calls addOnloadHook( tabbedprefs ), so the following call is redundant and causes the tabbedprefs toc to display twice.
//
// tabbedprefs();
updateTooltipAccessKeys( null );
akeytt( null );
scrollEditBox();
setupCheckboxShiftClick();
sortables_init();
 
// Run any added-on functions
for (var i = 0; i < onloadFuncts.length; i++) {
onloadFuncts[i]();
}
}
 
// Note: all skins should call runOnloadHook() at the end of html output, so the below should be redundant. It's there just in case.
hookEvent("load", runOnloadHook);
 
 
 
/**
  * Create Google Analytics instance for Citizendium
  */
function loadga() {
var c; (c = document.createElement("script")).src = "https://www.googletagmanager.com/gtag/js?id=G-W7ML9SNPXT";
document.head.appendChild(c);
 
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-W7ML9SNPXT');
}
 
//Call prior function
loadga();
 
 
/**
  * Modify link behavior to open in a new tab when contained in a span.newtab
  */
function checklinks(){
Array.from(document.getElementsByClassName("newtab")).forEach(function(obj){obj.getElementsByTagName("a")[0].target="_blank"});
}
}


function runOnloadHook() {
//Call prior function
// don't run anything below this for non-dom browsers
checklinks();
if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName)) {
return;
}
 
// set this before running any hooks, since any errors below
// might cause the function to terminate prematurely
doneOnloadHook = true;
 
histrowinit();
unhidetzbutton();
tabbedprefs();
updateTooltipAccessKeys( null );
akeytt( null );
scrollEditBox();
setupCheckboxShiftClick();
sortables_init();
 
// Run any added-on functions
for (var i = 0; i < onloadFuncts.length; i++) {
onloadFuncts[i]();
}
}


/**
* Add an event handler to an element
*
* @param Element element Element to add handler to
* @param String attach Event to attach to
* @param callable handler Event handler callback
*/
function addHandler( element, attach, handler ) {
if( window.addEventListener ) {
element.addEventListener( attach, handler, false );
} else if( window.attachEvent ) {
element.attachEvent( 'on' + attach, handler );
}
}


/**
/* </nowiki> */
* Add a click event handler to an element
*
* @param Element element Element to add handler to
* @param callable handler Event handler callback
*/
function addClickHandler( element, handler ) {
addHandler( element, 'click', handler );
}
//note: all skins should call runOnloadHook() at the end of html output,
//     so the below should be redundant. It's there just in case.
hookEvent("load", runOnloadHook);
hookEvent("load", mwSetupToolbar);

Latest revision as of 08:41, 30 January 2023

/* <nowiki> */

 /** Import module *************************************************************
  *
  *  Description: Includes a raw wiki page as javascript or CSS, used for including user made modules.
  *  
  *  Doesn't work in WebKit or IE7...
  */
var loadedScripts = {}; // included-scripts tracker
function importScript(page) {
	var url = wgScript + '?title=' + encodeURIComponent(page.replace(/ /g,'_')).replace(/%2F/ig,'/').replace(/%3A/ig,':') + '&action=raw&ctype=text/javascript';
	
	if (loadedScripts[url]) return null;
	loadedScripts[url] = true;
	
	var s = document.createElement('script');
	s.setAttribute('src',url);
	s.setAttribute('type','text/javascript');
	document.getElementsByTagName('head')[0].appendChild(s);
}

 
 function importStylesheet( page ) {
     var sheet = '@import "'
               + wgScriptPath
               + '/wiki?title='
               + encodeURIComponent( page.replace( ' ', '_' ) )
               + '&action=raw&ctype=text/css";'
     var styleElem = document.createElement( 'style' );
     styleElem.setAttribute( 'type' , 'text/css' );
     styleElem.appendChild( document.createTextNode( sheet ) );
     document.getElementsByTagName( 'head' )[0].appendChild( styleElem );
 }

/* Import more specific scripts if necessary */
//if (wgAction == 'edit' || wgAction == 'submit')
//    importScript("MediaWiki:Common.js/edit.js");
//if (wgPageName == 'Special:Upload')
//    importScript("MediaWiki:Common.js/upload.js");



/** Extra toolbar options ******************************************************
  *
  *  Description: UNDOCUMENTED
  *  Maintainers: 
  */

/* To disable this script, add    mwCustomEditButtons = [];    to [[Special:Mypage/Pinkwich5.js]] */

function imageButons(){
	if (wgAction == 'edit' || wgAction == 'submit') {
		/* Make the Image insertion button use the CZ image template */
		mwEditButtons[5].speedTip = 'Image';
		mwEditButtons[5].tagOpen	= '{{Image|';
		mwEditButtons[5].tagClose = '|right|250px|Image Caption}}';
		
		/* Add extra image buttons */
		if (mwCustomEditButtons) {
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c8/Button_redirect.png",
				"speedTip": "Redirect",
				"tagOpen": "#REDIRECT [[",
				"tagClose": "]]",
				"sampleText": "Insert text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/c/c9/Button_strike.png",
				"speedTip": "Strike",
				"tagOpen": "<s>",
				"tagClose": "</s>",
				"sampleText": "Strike-through text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/1/13/Button_enter.png",
				"speedTip": "Line break",
				"tagOpen": "<br />",
				"tagClose": "",
				"sampleText": ""};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/8/80/Button_upper_letter.png",
				"speedTip": "Superscript",
				"tagOpen": "<sup>",
				"tagClose": "</sup>",
				"sampleText": "Superscript text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/7/70/Button_lower_letter.png",
				"speedTip": "Subscript",
				"tagOpen": "<sub>",
				"tagClose": "</sub>",
				"sampleText": "Subscript text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/5/58/Button_small.png",
				"speedTip": "Small",
				"tagOpen": "<small>",
				"tagClose": "</small>",
				"sampleText": "Small Text"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/en/6/60/Button_insert_table.png",
				"speedTip": "Insert a table",
				"tagOpen": '{| class="wikitable"\n|-\n',
				"tagClose": "\n|}",
				"sampleText": "! header 1\n! header 2\n! header 3\n|-\n| row 1, cell 1\n| row 1, cell 2\n| row 1, cell 3\n|-\n| row 2, cell 1\n| row 2, cell 2\n| row 2, cell 3"};
		
			mwCustomEditButtons[mwCustomEditButtons.length] = {
				"imageFile": "http://upload.wikimedia.org/wikipedia/commons/7/79/Button_reflink.png",
				"speedTip": "Insert a reference",
				"tagOpen": "<ref>",
				"tagClose": "</ref>",
				"sampleText": "Insert footnote text here"};
		}
	}
}
addOnloadHook(imageButons);


/** Upload Wizard ***************************************************
 *
 *  Adds many enhancements to the upload form
 *
 *  Maintainer : [[User:Caesar Schinas]]
 */

function uploadForm() {
	if ((wgPageName == 'Special:Upload') && (wgUserLanguage != 'basic')) {
		if ((document.getElementById('wpUploadDescription').value == '') && document.getElementById('preload')) {
			document.getElementById('wpUploadDescription').value = document.getElementById('preload').innerHTML;
			document.getElementById('preload').parentNode.innerHTML = 'Fill in all the details you know:';
		}
		if (wgUserLanguage == 'replace') {
			document.getElementById('wpDestFile').parentNode.parentNode.style.display = 'none';
			document.getElementById('wpUploadDescription').setAttribute('rows','5');
		}
		if ((document.getElementById('wpUploadDescription').value.indexOf('{{Image_Details') != -1) && (wgUserLanguage != 'advanced')) {
			/* get an array of licences */
			var license = document.getElementById('wpLicense');
			var licenses = Array();
			for (var i in license.childNodes) {
				if (license.childNodes[i].nodeName == 'OPTION' && license.childNodes[i].value != '') {
					licenses.push(license.childNodes[i].value);
				}
			}
			/* if there is only one licence available select it and hide the input */
			if (licenses.length == 1) {
				license.value = licenses[0];
				licenseSelectorCheck();
				license.style.display = 'none';
			}
			
			
			/* Create individual fields for the image details */
			
			var labels = {
				'description'	: 'Image description:',
				'author'		: 'Creator name:',
				'copyright'		: 'Copyright holder:',
				'source'		: 'Source:',
				'date-created'	: 'Date created:',
				'pub-country'	: 'Publication country:',
				'notes'			: 'Notes:',
				'versions'		: 'Other versions:'
			};
			var sig = '~~'+'~';
			
			var summary = document.getElementById('wpUploadDescription');
			var table = summary.parentNode.parentNode.parentNode;
			var next = summary.parentNode.parentNode.nextSibling;
			
			var args = Array();
			if (summary.value.indexOf('Details|') != -1)
				args = summary.value.substring(summary.value.indexOf('Details|')+8,summary.value.indexOf('\n')).split('|');
			
			var details = summary.value.substring(summary.value.indexOf('\n|')+2,summary.value.indexOf('\n}}')).split('\n|');
			for (var i in details) {
				details[i] = details[i].split('=');
			}
			for (var i in details) {
				var tr = document.createElement('tr');
				var td1 = document.createElement('td');
				var td2 = document.createElement('td');
				tr.appendChild(td1);
				tr.appendChild(td2);
				td1.setAttribute('class','mw-label');
				td2.setAttribute('class','mw-input');
				td1.style.width = '12em';

				// added by dnessett on 3/12/2010 to increase visible region for Notes
				if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'notes') {
					var textarea = document.createElement('textarea');
					textarea.setAttribute('wrap','virtual');
					textarea.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
					textarea.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
					textarea.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
					textarea.setAttribute('rows','5');
					td2.appendChild(textarea);
					textarea.style.width = '90%';
				} else {
					var input = document.createElement('input');
					input.setAttribute('type','text');
					input.setAttribute('id',details[i][0].replace(/^\s+|\s+$/g,''));
					input.setAttribute('name',details[i][0].replace(/^\s+|\s+$/g,''));
					input.setAttribute('value',details[i][1].replace(/^\s+|\s+$/g,''));
					td2.appendChild(input);
					input.style.width = '90%';
				}
				
				var label = document.createElement('label');
				label.setAttribute('for',details[i][0].replace(/^\s+|\s+$/g,''));
				label.appendChild(document.createTextNode(labels[details[i][0].replace(/^\s+|\s+$/g,'')]));
				td1.appendChild(label);
				
				table.insertBefore(tr,next);
				
				if ((details[i][0].replace(/^\s+|\s+$/g,'')) == 'author' && (details[i][1].replace(/^\s+|\s+$/g,'') == sig)) tr.style.display = 'none';
			}
			summary.parentNode.parentNode.style.display = 'none';
			
			var septr = document.createElement('tr');
			var septd = document.createElement('td');
			septr.appendChild(septd);
			septd.appendChild(document.createElement('br'));
			table.insertBefore(septr,summary.parentNode.parentNode);
			
			document.getElementById('mw-upload-form').onsubmit = function(){
				var temp = '{{Image_Details';
				for (i in args) {
					temp += '|' + args[i];
				}
				for (i in details) {
					temp += '\n|' + details[i][0] + '= ' + document.getElementById(details[i][0].replace(/^\s+|\s+$/g,'')).value;
				}
				temp += '\n}}';
				summary.value = temp;
				
				if (license.value == '') {
					alert('Please select a licence!');
					return false;
				}
			}
		}
	}
}
addOnloadHook(uploadForm);

function uploadReplaceLink () {
	if (wgNamespaceNumber == 6) {
		var a = document.getElementsByTagName('a');
		for (var i in a) {
			if (a[i].getAttribute('href') && a[i].getAttribute('href').indexOf('wpDestFile') != -1)
				a[i].setAttribute('href', a[i].getAttribute('href') + '&uselang=replace');
		}
	}
}
addOnloadHook(uploadReplaceLink);


/** Credit Line Editor ***************************************************
 *
 *  Creates a simple form for editing credit lines.
 *
 *  Maintainer : [[User:Caesar Schinas]]
 */
function creditEdit() {
  if ((wgPageName.indexOf('/credit') != -1) && (wgAction == 'edit')) {
	var text = document.getElementById('wpTextbox1').value;
	if (text.indexOf('{{creditline') == -1) return false;
	var args = text.substring(text.indexOf('|')+1,text.indexOf('}}')).split('|');
	
	var bodycontent = document.getElementById('bodycontent');
	bodycontent.setAttribute('id','bodycontent-old');
	bodycontent.style.display = 'none';
	
	var div = document.createElement('div');
	bodycontent.parentNode.appendChild(div);
	div.setAttribute('id','bodycontent');
	
	div.innerHTML = "\
<table>\n\
  <tr>\n\
	<th style='text-align:right; padding-right:1em;'>\n\
	  <label for='licence'>Licence Type</label>\n\
	</th>\n\
	<td>\n\
	  <select id='licence' name='licence' style='width:25em;'>\n\
		<option value='C'>C - Copyright, used by permission</option>\n\
		<option value='CC'>CC - Creative Commons</option>\n\
		<option value='GNU'>GNU</option>\n\
		<option value='PD'>PD - Public Domain</option>\n\
		<option value='other' selected='selected'>Other (please only enter letters)</option>\n\
	  </select>\n\
	  <input type='text' id='licence-other' name='imagetype-other' />\n\
	</td>\n\
  </tr>\n\
  <tr>\n\
	<th style='text-align:right; padding-right:1em;'>\n\
	  <label for='imagetype'>Image Type</label>\n\
	</th>\n\
	<td>\n\
	  <select id='imagetype' name='imagetype' style='width:25em;'>\n\
		<option value='Image'>Image</option>\n\
		<option value='Photo'>Photo</option>\n\
		<option value='Diagram'>Diagram</option>\n\
		<option value='Drawing'>Drawing</option>\n\
		<option value='Painting'>Painting</option>\n\
		<option value='Artwork'>Artwork</option>\n\
		<option value='other' selected='selected'>Other</option>\n\
	  </select>\n\
	  <input type='text' id='imagetype-other' name='imagetype-other' />\n\
	</td>\n\
  </tr>\n\
  <tr>\n\
	<th style='text-align:right; padding-right:1em;'>\n\
	  <label for='author'>Author</label>\n\
	</th>\n\
	<td>\n\
	  <input type='text' id='author' name='author' style='width:25em;' />\n\
	</td>\n\
  </tr>\n\
  <tr>\n\
	<th>\n\
	</th>\n\
	<td>\n\
	  <input type='button' id='save' value='Save Credit Line' />\n\
	</td>\n\
  </tr>\n\
</table>\n\
";
	
	// set form field values
	
	if (args[0] && args[0] != 'licence') {
	  document.getElementById('licence-other').value = args[0];
	  for (var i=0; i<4; i++) {
		if (args[0].toUpperCase() == Array('CC','GNU','PD','C')[i]) {
			document.getElementById('licence').value = args[0].toUpperCase();
			document.getElementById('licence-other').style.display = 'none';
		}
	  }
	} else {
	  document.getElementById('licence').value = 'C';
	  document.getElementById('licence-other').style.display = 'none';
	}
	
	if (args[1] && args[1] != 'imagetype') {
	  document.getElementById('imagetype-other').value = args[1];
	  for (var i=0; i<6; i++) {
		if (args[1].toLowerCase() == Array('Image','Photo','Diagram','Drawing','Painting','Artwork')[i].toLowerCase()) {
			document.getElementById('imagetype').value = Array('Image','Photo','Diagram','Drawing','Painting','Artwork')[i];
			document.getElementById('imagetype-other').style.display = 'none';
		}
	  }
	} else {
	  document.getElementById('imagetype').value = 'Image';
	  document.getElementById('imagetype-other').style.display = 'none';
	}
	
	if (args[2] && args[2] != 'author')
	  document.getElementById('author').value = args[2];
	
	
	// onchange handlers for selects
	
	document.getElementById('licence').onchange = function() {
	  if (document.getElementById('licence').value == 'other')
		document.getElementById('licence-other').style.display = 'inline';
	  else
		document.getElementById('licence-other').style.display = 'none';
	}
	
	document.getElementById('imagetype').onchange = function() {
	  if (document.getElementById('imagetype').value == 'other')
		document.getElementById('imagetype-other').style.display = 'inline';
	  else
		document.getElementById('imagetype-other').style.display = 'none';
	}
	
	
	// save the credit line
	
	document.getElementById('save').onclick = function() {
	  var value = '{{creditline';
	  
	  if (document.getElementById('licence').value != 'other')
		value += '|' + document.getElementById('licence').value;
	  else if (document.getElementById('licence-other').value != '')
		value += '|' + document.getElementById('licence-other').value;
	  
	  if (document.getElementById('imagetype').value != 'Image' || document.getElementById('author').value != '') {
		if (document.getElementById('imagetype').value != 'other')
			value += '|' + document.getElementById('imagetype').value;
		else if (document.getElementById('imagetype-other').value != '')
			value += '|' + document.getElementById('imagetype-other').value;
		
		if (document.getElementById('author').value != '')
			value += '|' + document.getElementById('author').value;
	  }
	  
	  value += '}}';
	  
	  document.getElementById('wpTextbox1').value = value;
	  document.getElementById('editform').submit();
	}
  }
}
addOnloadHook(creditEdit);




 /* 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
  *               [[Citizendium:NavFrame]].
  *  Maintainers: [[User:R. Koot]]
  */
 
 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.getElementsByTagName( "tr" ); 
 
     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" ) ) {
             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 = "6em";
 
             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( "]" ) );
 
             var Header = Tables[i].getElementsByTagName( "tr" )[0].getElementsByTagName( "th" )[0];
             /* only add button and increment count if there is a header row to work with */
             if (Header) {
                 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 );


 /** Add dismiss button to watchlist-message *************************************
  *
  *  Description: Hide the watchlist message for one week.
  *  Maintainers: [[User:Ruud Koot|Ruud Koot]]
  */
 
 function addDismissButton() {
    var watchlistMessage = document.getElementById("watchlist-message");
    if ( watchlistMessage == null ) return;
 
    if ( document.cookie.indexOf( "hidewatchlistmessage=yes" ) != -1 ) {
        watchlistMessage.style.display = "none";
    }
 
    var Button     = document.createElement( "span" );
    var ButtonLink = document.createElement( "a" );
    var ButtonText = document.createTextNode( "dismiss" );
 
    ButtonLink.setAttribute( "id", "dismissButton" );
    ButtonLink.setAttribute( "href", "javascript:dismissWatchlistMessage();" );
    ButtonLink.setAttribute( "title", "Hide this message for one week" );
    ButtonLink.appendChild( ButtonText );
 
    Button.appendChild( document.createTextNode( "[" ) );
    Button.appendChild( ButtonLink );
    Button.appendChild( document.createTextNode( "]" ) );
 
    watchlistMessage.appendChild( Button );
 }
 
 function dismissWatchlistMessage() {
     var e = new Date();
     e.setTime( e.getTime() + (7*24*60*60*1000) );
     document.cookie = "hidewatchlistmessage=yes; expires=" + e.toGMTString() + "; path=/";
     var watchlistMessage = document.getElementById("watchlist-message");
     watchlistMessage.style.display = "none";
 }
 
 addOnloadHook( addDismissButton );

 /** Numeric sorting ***************************************************
  *
  *  Description: Fixes a bug (part of [[bugzilla:8115]])
  *  in http://svn.citizendium.org/viewvc/mediawiki/trunk/phase3/skins/common/wikibits.js
  *  regarding [[Help:Sorting|table sorting]]:
  *  it allows sorting of numbers with more than one comma (thousands separator).
  *  Maintainer: [[User:Patrick|Patrick]]
  */
 function ts_parseFloat(num) {
 	if (!num) return 0;
 	num = parseFloat(num.replace(/,/g, ""));
 	return (isNaN(num) ? 0 : num);
 }



// MediaWiki JavaScript support functions

var clientPC = navigator.userAgent.toLowerCase(); // Get client info
var is_gecko = ((clientPC.indexOf('gecko')!=-1) && (clientPC.indexOf('spoofer')==-1)
                && (clientPC.indexOf('khtml') == -1) && (clientPC.indexOf('netscape/7.0')==-1));
var is_safari = ((clientPC.indexOf('applewebkit')!=-1) && (clientPC.indexOf('spoofer')==-1));
var is_khtml = (navigator.vendor == 'KDE' || ( document.childNodes && !document.all && !navigator.taintEnabled ));
// For accesskeys
var is_ff2_win = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('windows')!=-1;
var is_ff2_x11 = (clientPC.indexOf('firefox/2')!=-1 || clientPC.indexOf('minefield/3')!=-1) && clientPC.indexOf('x11')!=-1;
if (clientPC.indexOf('opera') != -1) {
	var is_opera = true;
	var is_opera_preseven = (window.opera && !document.childNodes);
	var is_opera_seven = (window.opera && document.childNodes);
	var is_opera_95 = (clientPC.search(/opera\/(9.[5-9]|[1-9][0-9])/)!=-1);
}

// Global external objects used by this script.
/*extern ta, stylepath, skin */

// add any onload functions in this hook (please don't hard-code any events in the xhtml source)
var doneOnloadHook;

if (!window.onloadFuncts) {
	var onloadFuncts = [];
}

function addOnloadHook(hookFunct) {
	// Allows add-on scripts to add onload functions
	onloadFuncts[onloadFuncts.length] = hookFunct;
}

function hookEvent(hookName, hookFunct) {
	if (window.addEventListener) {
		window.addEventListener(hookName, hookFunct, false);
	} else if (window.attachEvent) {
		window.attachEvent("on" + hookName, hookFunct);
	}
}

// document.write special stylesheet links
if (typeof stylepath != 'undefined' && typeof skin != 'undefined') {
	if (is_opera_preseven) {
		document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera6Fixes.css">');
	} else if (is_opera_seven && !is_opera_95) {
		document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera7Fixes.css">');
	} else if (is_opera_95) {
		document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/Opera95Fixes.css">');
	} else if (is_khtml) {
		document.write('<link rel="stylesheet" type="text/css" href="'+stylepath+'/'+skin+'/KHTMLFixes.css">');
	}
}

if (wgBreakFrames) {
	// Un-trap us from framesets
	if (window.top != window) {
		window.top.location = window.location;
	}
}

// for enhanced RecentChanges
function toggleVisibility(_levelId, _otherId, _linkId) {
	var thisLevel = document.getElementById(_levelId);
	var otherLevel = document.getElementById(_otherId);
	var linkLevel = document.getElementById(_linkId);
	if (thisLevel.style.display == 'none') {
		thisLevel.style.display = 'block';
		otherLevel.style.display = 'none';
		linkLevel.style.display = 'inline';
	} else {
		thisLevel.style.display = 'none';
		otherLevel.style.display = 'inline';
		linkLevel.style.display = 'none';
	}
}

function historyRadios(parent) {
	var inputs = parent.getElementsByTagName('input');
	var radios = [];
	for (var i = 0; i < inputs.length; i++) {
		if (inputs[i].name == "diff" || inputs[i].name == "oldid") {
			radios[radios.length] = inputs[i];
		}
	}
	return radios;
}

// check selection and tweak visibility/class onclick
function diffcheck() {
	var dli = false; // the li where the diff radio is checked
	var oli = false; // the li where the oldid radio is checked
	var hf = document.getElementById('pagehistory');
	if (!hf) {
		return true;
	}
	var lis = hf.getElementsByTagName('li');
	for (var i=0;i<lis.length;i++) {
		var inputs = historyRadios(lis[i]);
		if (inputs[1] && inputs[0]) {
			if (inputs[1].checked || inputs[0].checked) { // this row has a checked radio button
				if (inputs[1].checked && inputs[0].checked && inputs[0].value == inputs[1].value) {
					return false;
				}
				if (oli) { // it's the second checked radio
					if (inputs[1].checked) {
						oli.className = "selected";
						return false;
					}
				} else if (inputs[0].checked) {
					return false;
				}
				if (inputs[0].checked) {
					dli = lis[i];
				}
				if (!oli) {
					inputs[0].style.visibility = 'hidden';
				}
				if (dli) {
					inputs[1].style.visibility = 'hidden';
				}
				lis[i].className = "selected";
				oli = lis[i];
			}  else { // no radio is checked in this row
				if (!oli) {
					inputs[0].style.visibility = 'hidden';
				} else {
					inputs[0].style.visibility = 'visible';
				}
				if (dli) {
					inputs[1].style.visibility = 'hidden';
				} else {
					inputs[1].style.visibility = 'visible';
				}
				lis[i].className = "";
			}
		}
	}
	return true;
}

// page history stuff
// attach event handlers to the input elements on history page
function histrowinit() {
	var hf = document.getElementById('pagehistory');
	if (!hf) {
		return;
	}
	var lis = hf.getElementsByTagName('li');
	for (var i = 0; i < lis.length; i++) {
		var inputs = historyRadios(lis[i]);
		if (inputs[0] && inputs[1]) {
			inputs[0].onclick = diffcheck;
			inputs[1].onclick = diffcheck;
		}
	}
	diffcheck();
}

// generate toc from prefs form, fold sections
// XXX: needs testing on IE/Mac and safari
// more comments to follow
function tabbedprefs() {
	var prefform = document.getElementById('preferences');
	if (!prefform || !document.createElement) {
		return;
	}
	if (prefform.nodeName.toLowerCase() == 'a') {
		return; // Occasional IE problem
	}
	prefform.className = prefform.className + 'jsprefs';
	var sections = [];
	var children = prefform.childNodes;
	var seci = 0;
	for (var i = 0; i < children.length; i++) {
		if (children[i].nodeName.toLowerCase() == 'fieldset') {
			children[i].id = 'prefsection-' + seci;
			children[i].className = 'prefsection';
			if (is_opera || is_khtml) {
				children[i].className = 'prefsection operaprefsection';
			}
			var legends = children[i].getElementsByTagName('legend');
			sections[seci] = {};
			legends[0].className = 'mainLegend';
			if (legends[0] && legends[0].firstChild.nodeValue) {
				sections[seci].text = legends[0].firstChild.nodeValue;
			} else {
				sections[seci].text = '# ' + seci;
			}
			sections[seci].secid = children[i].id;
			seci++;
			if (sections.length != 1) {
				children[i].style.display = 'none';
			} else {
				var selectedid = children[i].id;
			}
		}
	}
	var toc = document.createElement('ul');
	toc.id = 'preftoc';
	toc.selectedid = selectedid;
	for (i = 0; i < sections.length; i++) {
		var li = document.createElement('li');
		if (i === 0) {
			li.className = 'selected';
		}
		var a = document.createElement('a');
		a.href = '#' + sections[i].secid;
		a.onmousedown = a.onclick = uncoversection;
		a.appendChild(document.createTextNode(sections[i].text));
		a.secid = sections[i].secid;
		li.appendChild(a);
		toc.appendChild(li);
	}
	prefform.parentNode.insertBefore(toc, prefform.parentNode.childNodes[0]);
	document.getElementById('prefsubmit').id = 'prefcontrol';
}

function uncoversection() {
	var oldsecid = this.parentNode.parentNode.selectedid;
	var newsec = document.getElementById(this.secid);
	if (oldsecid != this.secid) {
		var ul = document.getElementById('preftoc');
		document.getElementById(oldsecid).style.display = 'none';
		newsec.style.display = 'block';
		ul.selectedid = this.secid;
		var lis = ul.getElementsByTagName('li');
		for (var i = 0; i< lis.length; i++) {
			lis[i].className = '';
		}
		this.parentNode.className = 'selected';
	}
	return false;
}

// Timezone stuff
// tz in format [+-]HHMM
function checkTimezone(tz, msg) {
	var localclock = new Date();
	// returns negative offset from GMT in minutes
	var tzRaw = localclock.getTimezoneOffset();
	var tzHour = Math.floor( Math.abs(tzRaw) / 60);
	var tzMin = Math.abs(tzRaw) % 60;
	var tzString = ((tzRaw >= 0) ? "-" : "+") + ((tzHour < 10) ? "0" : "") + tzHour + ((tzMin < 10) ? "0" : "") + tzMin;
	if (tz != tzString) {
		var junk = msg.split('$1');
		document.write(junk[0] + "UTC" + tzString + junk[1]);
	}
}

function unhidetzbutton() {
	var tzb = document.getElementById('guesstimezonebutton');
	if (tzb) {
		tzb.style.display = 'inline';
	}
}

// in [-]HH:MM format...
// won't yet work with non-even tzs
function fetchTimezone() {
	// FIXME: work around Safari bug
	var localclock = new Date();
	// returns negative offset from GMT in minutes
	var tzRaw = localclock.getTimezoneOffset();
	var tzHour = Math.floor( Math.abs(tzRaw) / 60);
	var tzMin = Math.abs(tzRaw) % 60;
	var tzString = ((tzRaw >= 0) ? "-" : "") + ((tzHour < 10) ? "0" : "") + tzHour +
		":" + ((tzMin < 10) ? "0" : "") + tzMin;
	return tzString;
}

function guessTimezone(box) {
	document.getElementsByName("wpHourDiff")[0].value = fetchTimezone();
}

function showTocToggle() {
	if (document.createTextNode) {
		// Uses DOM calls to avoid document.write + XHTML issues

		var linkHolder = document.getElementById('toctitle');
		if (!linkHolder) {
			return;
		}

		var outerSpan = document.createElement('span');
		outerSpan.className = 'toctoggle';

		var toggleLink = document.createElement('a');
		toggleLink.id = 'togglelink';
		toggleLink.className = 'internal';
		toggleLink.href = 'javascript:toggleToc()';
		toggleLink.appendChild(document.createTextNode(tocHideText));

		outerSpan.appendChild(document.createTextNode('['));
		outerSpan.appendChild(toggleLink);
		outerSpan.appendChild(document.createTextNode(']'));

		linkHolder.appendChild(document.createTextNode(' '));
		linkHolder.appendChild(outerSpan);

		var cookiePos = document.cookie.indexOf("hidetoc=");
		if (cookiePos > -1 && document.cookie.charAt(cookiePos + 8) == 1) {
			toggleToc();
		}
	}
}

function changeText(el, newText) {
	// Safari work around
	if (el.innerText) {
		el.innerText = newText;
	} else if (el.firstChild && el.firstChild.nodeValue) {
		el.firstChild.nodeValue = newText;
	}
}

function toggleToc() {
	var toc = document.getElementById('toc').getElementsByTagName('ul')[0];
	var toggleLink = document.getElementById('togglelink');

	if (toc && toggleLink && toc.style.display == 'none') {
		changeText(toggleLink, tocHideText);
		toc.style.display = 'block';
		document.cookie = "hidetoc=0";
	} else {
		changeText(toggleLink, tocShowText);
		toc.style.display = 'none';
		document.cookie = "hidetoc=1";
	}
}

function escapeQuotes(text) {
	var re = new RegExp("'","g");
	text = text.replace(re,"\\'");
	re = new RegExp("\\n","g");
	text = text.replace(re,"\\n");
	return escapeQuotesHTML(text);
}

function escapeQuotesHTML(text) {
	var re = new RegExp('&',"g");
	text = text.replace(re,"&amp;");
	re = new RegExp('"',"g");
	text = text.replace(re,"&quot;");
	re = new RegExp('<',"g");
	text = text.replace(re,"&lt;");
	re = new RegExp('>',"g");
	text = text.replace(re,"&gt;");
	return text;
}

// apply tagOpen/tagClose to selection in textarea,
// use sampleText instead of selection if there is none
function insertTags(tagOpen, tagClose, sampleText) {
	var txtarea;
	if (document.editform) {
		txtarea = document.editform.wpTextbox1;
	} else {
		// some alternate form? take the first one we can find
		var areas = document.getElementsByTagName('textarea');
		txtarea = areas[0];
	}
	var selText, isSample = false;

	if (document.selection  && document.selection.createRange) { // IE/Opera

		//save window scroll position
		if (document.documentElement && document.documentElement.scrollTop)
			var winScroll = document.documentElement.scrollTop
		else if (document.body)
			var winScroll = document.body.scrollTop;
		//get current selection  
		txtarea.focus();
		var range = document.selection.createRange();
		selText = range.text;
		//insert tags
		checkSelectedText();
		range.text = tagOpen + selText + tagClose;
		//mark sample text as selected
		if (isSample && range.moveStart) {
			if (window.opera)
				tagClose = tagClose.replace(/\n/g,'');
			range.moveStart('character', - tagClose.length - selText.length); 
			range.moveEnd('character', - tagClose.length); 
		}
		range.select();   
		//restore window scroll position
		if (document.documentElement && document.documentElement.scrollTop)
			document.documentElement.scrollTop = winScroll
		else if (document.body)
			document.body.scrollTop = winScroll;

	} else if (txtarea.selectionStart || txtarea.selectionStart == '0') { // Mozilla

		//save textarea scroll position
		var textScroll = txtarea.scrollTop;
		//get current selection
		txtarea.focus();
		var startPos = txtarea.selectionStart;
		var endPos = txtarea.selectionEnd;
		selText = txtarea.value.substring(startPos, endPos);
		//insert tags
		checkSelectedText();
		txtarea.value = txtarea.value.substring(0, startPos)
			+ tagOpen + selText + tagClose
			+ txtarea.value.substring(endPos, txtarea.value.length);
		//set new selection
		if (isSample) {
			txtarea.selectionStart = startPos + tagOpen.length;
			txtarea.selectionEnd = startPos + tagOpen.length + selText.length;
		} else {
			txtarea.selectionStart = startPos + tagOpen.length + selText.length + tagClose.length;
			txtarea.selectionEnd = txtarea.selectionStart;
		}
		//restore textarea scroll position
		txtarea.scrollTop = textScroll;
	} 

	function checkSelectedText(){
		if (!selText) {
			selText = sampleText;
			isSample = true;
		} else if (selText.charAt(selText.length - 1) == ' ') { //exclude ending space char
			selText = selText.substring(0, selText.length - 1);
			tagClose += ' '
		} 
	}

}


/**
 * Set the accesskey prefix based on browser detection.
 */
var tooltipAccessKeyPrefix = 'alt-';
if (is_opera) {
	tooltipAccessKeyPrefix = 'shift-esc-';
} else if (is_safari
	   || navigator.userAgent.toLowerCase().indexOf('mac') != -1
	   || navigator.userAgent.toLowerCase().indexOf('konqueror') != -1 ) {
	tooltipAccessKeyPrefix = 'ctrl-';
} else if (is_ff2_x11 || is_ff2_win) {
	tooltipAccessKeyPrefix = 'alt-shift-';
}
var tooltipAccessKeyRegexp = /\[(ctrl-)?(alt-)?(shift-)?(esc-)?.\]$/;

/**
 * Add the appropriate prefix to the accesskey shown in the tooltip.
 * If the nodeList parameter is given, only those nodes are updated;
 * otherwise, all the nodes that will probably have accesskeys by
 * default are updated.
 *
 * @param Array nodeList -- list of elements to update
 */
function updateTooltipAccessKeys( nodeList ) {
	if ( !nodeList ) {
		// skins without a "column-one" element don't seem to have links with accesskeys either
		var columnOne = document.getElementById("column-one");
		if ( columnOne )
			updateTooltipAccessKeys( columnOne.getElementsByTagName("a") );
		// these are rare enough that no such optimization is needed
		updateTooltipAccessKeys( document.getElementsByTagName("input") );
		updateTooltipAccessKeys( document.getElementsByTagName("label") );
		return;
	}

	for ( var i = 0; i < nodeList.length; i++ ) {
		var element = nodeList[i];
		var tip = element.getAttribute("title");
		var key = element.getAttribute("accesskey");
		if ( key && tooltipAccessKeyRegexp.exec(tip) ) {
			tip = tip.replace(tooltipAccessKeyRegexp,
					  "["+tooltipAccessKeyPrefix+key+"]");
			element.setAttribute("title", tip );
		}
	}
}

/**
 * Add a link to one of the portlet menus on the page, including:
 *
 * p-cactions: Content actions (shown as tabs above the main content in Monobook)
 * p-personal: Personal tools (shown at the top right of the page in Monobook)
 * p-navigation: Navigation
 * p-tb: Toolbox
 *
 * This function exists for the convenience of custom JS authors.  All
 * but the first three parameters are optional, though providing at
 * least an id and a tooltip is recommended.
 *
 * By default the new link will be added to the end of the list.  To
 * add the link before a given existing item, pass the DOM node of
 * that item (easily obtained with document.getElementById()) as the
 * nextnode parameter; to add the link _after_ an existing item, pass
 * the node's nextSibling instead.
 *
 * @param String portlet -- id of the target portlet ("p-cactions", "p-personal", "p-navigation" or "p-tb")
 * @param String href -- link URL
 * @param String text -- link text (will be automatically lowercased by CSS for p-cactions in Monobook)
 * @param String id -- id of the new item, should be unique and preferably have the appropriate prefix ("ca-", "pt-", "n-" or "t-")
 * @param String tooltip -- text to show when hovering over the link, without accesskey suffix
 * @param String accesskey -- accesskey to activate this link (one character, try to avoid conflicts)
 * @param Node nextnode -- the DOM node before which the new item should be added, should be another item in the same list
 *
 * @return Node -- the DOM node of the new item (an LI element) or null
 */
function addPortletLink(portlet, href, text, id, tooltip, accesskey, nextnode) {
	var node = document.getElementById(portlet);
	if ( !node ) return null;
	node = node.getElementsByTagName( "ul" )[0];
	if ( !node ) return null;

	var link = document.createElement( "a" );
	link.appendChild( document.createTextNode( text ) );
	link.href = href;

	var item = document.createElement( "li" );
	item.appendChild( link );
	if ( id ) item.id = id;

	if ( accesskey ) {
		link.setAttribute( "accesskey", accesskey );
		tooltip += " ["+accesskey+"]";
	}
	if ( tooltip ) {
		link.setAttribute( "title", tooltip );
	}
	if ( accesskey && tooltip ) {
		updateTooltipAccessKeys( new Array( link ) );
	}

	if ( nextnode && nextnode.parentNode == node )
		node.insertBefore( item, nextnode );
	else
		node.appendChild( item );  // IE compatibility (?)

	return item;
}


/**
 * Set up accesskeys/tooltips from the deprecated ta array.  If doId
 * is specified, only set up for that id.  Note that this function is
 * deprecated and will not be supported indefinitely -- use
 * updateTooltipAccessKey() instead.
 *
 * @param mixed doId string or null
 */
function akeytt( doId ) {
	// A lot of user scripts (and some of the code below) break if
	// ta isn't defined, so we make sure it is.  Explictly using
	// window.ta avoids a "ta is not defined" error.
	if (!window.ta) window.ta = new Array;

	// Make a local, possibly restricted, copy to avoid clobbering
	// the original.
	var ta;
	if ( doId ) {
		ta = [doId];
	} else {
		ta = window.ta;
	}

	// Now deal with evil deprecated ta
	var watchCheckboxExists = document.getElementById( 'wpWatchthis' ) ? true : false;
	for (var id in ta) {
		var n = document.getElementById(id);
		if (n) {
			var a = null;
			var ak = '';
			// Are we putting accesskey in it
			if (ta[id][0].length > 0) {
				// Is this object a object? If not assume it's the next child.

				if (n.nodeName.toLowerCase() == "a") {
					a = n;
				} else {
					a = n.childNodes[0];
				}
			 	// Don't add an accesskey for the watch tab if the watch
			 	// checkbox is also available.
				if (a && ((id != 'ca-watch' && id != 'ca-unwatch') || !watchCheckboxExists)) {
					a.accessKey = ta[id][0];
					ak = ' ['+tooltipAccessKeyPrefix+ta[id][0]+']';
				}
			} else {
				// We don't care what type the object is when assigning tooltip
				a = n;
				ak = '';
			}

			if (a) {
				a.title = ta[id][1]+ak;
			}
		}
	}
}

function setupRightClickEdit() {
	if (document.getElementsByTagName) {
		var spans = document.getElementsByTagName('span');
		for (var i = 0; i < spans.length; i++) {
			var el = spans[i];
			if(el.className == 'editsection') {
				addRightClickEditHandler(el);
			}
		}
	}
}

function addRightClickEditHandler(el) {
	for (var i = 0; i < el.childNodes.length; i++) {
		var link = el.childNodes[i];
		if (link.nodeType == 1 && link.nodeName.toLowerCase() == 'a') {
			var editHref = link.getAttribute('href');
			// find the enclosing (parent) header
			var prev = el.parentNode;
			if (prev && prev.nodeType == 1 &&
			prev.nodeName.match(/^[Hh][1-6]$/)) {
				prev.oncontextmenu = function(e) {
					if (!e) { e = window.event; }
					// e is now the event in all browsers
					var targ;
					if (e.target) { targ = e.target; }
					else if (e.srcElement) { targ = e.srcElement; }
					if (targ.nodeType == 3) { // defeat Safari bug
						targ = targ.parentNode;
					}
					// targ is now the target element

					// We don't want to deprive the noble reader of a context menu
					// for the section edit link, do we?  (Might want to extend this
					// to all <a>'s?)
					if (targ.nodeName.toLowerCase() != 'a'
					|| targ.parentNode.className != 'editsection') {
						document.location = editHref;
						return false;
					}
					return true;
				};
			}
		}
	}
}

var checkboxes;
var lastCheckbox;

function setupCheckboxShiftClick() {
	checkboxes = [];
	lastCheckbox = null;
	var inputs = document.getElementsByTagName('input');
	addCheckboxClickHandlers(inputs);
}

function addCheckboxClickHandlers(inputs, start) {
	if ( !start) start = 0;

	var finish = start + 250;
	if ( finish > inputs.length )
		finish = inputs.length;

	for ( var i = start; i < finish; i++ ) {
		var cb = inputs[i];
		if ( !cb.type || cb.type.toLowerCase() != 'checkbox' )
			continue;
		var end = checkboxes.length;
		checkboxes[end] = cb;
		cb.index = end;
		cb.onclick = checkboxClickHandler;
	}

	if ( finish < inputs.length ) {
		setTimeout( function () {
			addCheckboxClickHandlers(inputs, finish);
		}, 200 );
	}
}

function checkboxClickHandler(e) {
	if (typeof e == 'undefined') {
		e = window.event;
	}
	if ( !e.shiftKey || lastCheckbox === null ) {
		lastCheckbox = this.index;
		return true;
	}
	var endState = this.checked;
	var start, finish;
	if ( this.index < lastCheckbox ) {
		start = this.index + 1;
		finish = lastCheckbox;
	} else {
		start = lastCheckbox;
		finish = this.index - 1;
	}
	for (var i = start; i <= finish; ++i ) {
		checkboxes[i].checked = endState;
	}
	lastCheckbox = this.index;
	return true;
}

function toggle_element_activation(ida,idb) {
	if (!document.getElementById) {
		return;
	}
	document.getElementById(ida).disabled=true;
	document.getElementById(idb).disabled=false;
}

function toggle_element_check(ida,idb) {
	if (!document.getElementById) {
		return;
	}
	document.getElementById(ida).checked=true;
	document.getElementById(idb).checked=false;
}

/**
 * Restore the edit box scroll state following a preview operation,
 * and set up a form submission handler to remember this state
 */
function scrollEditBox() {
	var editBox = document.getElementById( 'wpTextbox1' );
	var scrollTop = document.getElementById( 'wpScrolltop' );
	var editForm = document.getElementById( 'editform' );
	if( editBox && scrollTop ) {
		if( scrollTop.value )
			editBox.scrollTop = scrollTop.value;
		addHandler( editForm, 'submit', function() {
			document.getElementById( 'wpScrolltop' ).value = document.getElementById( 'wpTextbox1' ).scrollTop; 
		} );
	}
}
hookEvent( 'load', scrollEditBox );

var allmessages_nodelist = false;
var allmessages_modified = false;
var allmessages_timeout = false;
var allmessages_running = false;

function allmessagesmodified() {
	allmessages_modified = !allmessages_modified;
	allmessagesfilter();
}

function allmessagesfilter() {
	if ( allmessages_timeout )
		window.clearTimeout( allmessages_timeout );

	if ( !allmessages_running )
		allmessages_timeout = window.setTimeout( 'allmessagesfilter_do();', 500 );
}

function allmessagesfilter_do() {
	if ( !allmessages_nodelist )
		return;

	var text = document.getElementById('allmessagesinput').value;
	var nodef = allmessages_modified;

	allmessages_running = true;

	for ( var name in allmessages_nodelist ) {
		var nodes = allmessages_nodelist[name];
		var display = ( name.indexOf( text ) == -1 ? 'none' : '' );

		for ( var i = 0; i < nodes.length; i++)
			nodes[i].style.display =
				( nodes[i].className == "def" && nodef
				  ? 'none' : display );
	}

	if ( text != document.getElementById('allmessagesinput').value ||
	     nodef != allmessages_modified )
		allmessagesfilter_do();  // repeat

	allmessages_running = false;
}

function allmessagesfilter_init() {
	if ( allmessages_nodelist )
		return;

	var nodelist = new Array();
	var templist = new Array();

	var table = document.getElementById('allmessagestable');
	if ( !table ) return;

	var rows = document.getElementsByTagName('tr');
	for ( var i = 0; i < rows.length; i++ ) {
		var id = rows[i].getAttribute('id')
		if ( id && id.substring(0,16) != 'sp-allmessages-r' ) continue;
		templist[ id ] = rows[i];
	}

	var spans = table.getElementsByTagName('span');
	for ( var i = 0; i < spans.length; i++ ) {
		var id = spans[i].getAttribute('id')
		if ( id && id.substring(0,17) != 'sp-allmessages-i-' ) continue;
		if ( !spans[i].firstChild || spans[i].firstChild.nodeType != 3 ) continue;

		var nodes = new Array();
		var row1 = templist[ id.replace('i', 'r1') ];
		var row2 = templist[ id.replace('i', 'r2') ];

		if ( row1 ) nodes[nodes.length] = row1;
		if ( row2 ) nodes[nodes.length] = row2;
		nodelist[ spans[i].firstChild.nodeValue ] = nodes;
	}

	var k = document.getElementById('allmessagesfilter');
	if (k) { k.style.display = ''; }

	allmessages_nodelist = nodelist;
}

hookEvent( "load", allmessagesfilter_init );

/*
	Written by Jonathan Snook, http://www.snook.ca/jonathan
	Add-ons by Robert Nyman, http://www.robertnyman.com
	Author says "The credit comment is all it takes, no license. Go crazy with it!:-)"
	From http://www.robertnyman.com/2005/11/07/the-ultimate-getelementsbyclassname/
*/
function getElementsByClassName(oElm, strTagName, oClassNames){
	var arrElements = (strTagName == "*" && oElm.all)? oElm.all : oElm.getElementsByTagName(strTagName);
	var arrReturnElements = new Array();
	var arrRegExpClassNames = new Array();
	if(typeof oClassNames == "object"){
		for(var i=0; i<oClassNames.length; i++){
			arrRegExpClassNames[arrRegExpClassNames.length] =
				new RegExp("(^|\\s)" + oClassNames[i].replace(/\-/g, "\\-") + "(\\s|$)");
		}
	}
	else{
		arrRegExpClassNames[arrRegExpClassNames.length] =
			new RegExp("(^|\\s)" + oClassNames.replace(/\-/g, "\\-") + "(\\s|$)");
	}
	var oElement;
	var bMatchesAll;
	for(var j=0; j<arrElements.length; j++){
		oElement = arrElements[j];
		bMatchesAll = true;
		for(var k=0; k<arrRegExpClassNames.length; k++){
			if(!arrRegExpClassNames[k].test(oElement.className)){
				bMatchesAll = false;
				break;
			}
		}
		if(bMatchesAll){
			arrReturnElements[arrReturnElements.length] = oElement;
		}
	}
	return (arrReturnElements)
}

function redirectToFragment(fragment) {
	var match = navigator.userAgent.match(/AppleWebKit\/(\d+)/);
	if (match) {
		var webKitVersion = parseInt(match[1]);
		if (webKitVersion < 420) {
			// Released Safari w/ WebKit 418.9.1 messes up horribly
			// Nightlies of 420+ are ok
			return;
		}
	}
	if (is_gecko) {
		// Mozilla needs to wait until after load, otherwise the window doesn't scroll
		addOnloadHook(function () {
			if (window.location.hash == "")
				window.location.hash = fragment;
		});
	} else {
		if (window.location.hash == "")
			window.location.hash = fragment;
	}
}


/*
 * Table sorting script  by Joost de Valk, check it out at http://www.joostdevalk.nl/code/sortable-table/.
 * Based on a script from http://www.kryogenix.org/code/browser/sorttable/.
 * Distributed under the MIT license: http://www.kryogenix.org/code/browser/licence.html .
 *
 * Copyright (c) 1997-2006 Stuart Langridge, Joost de Valk.
 *
 * @todo don't break on colspans/rowspans (bug 8028)
 * @todo language-specific digit grouping/decimals (bug 8063)
 * @todo support all accepted date formats (bug 8226)
 */

var ts_image_path = stylepath+"/common/images/";
var ts_image_up = "sort_up.gif";
var ts_image_down = "sort_down.gif";
var ts_image_none = "sort_none.gif";
var ts_europeandate = wgContentLanguage != "en"; // The non-American-inclined can change to "true"
var ts_alternate_row_colors = true;
var SORT_COLUMN_INDEX;

function sortables_init() {
	var idnum = 0;
	// Find all tables with class sortable and make them sortable
	var tables = getElementsByClassName(document, "table", "sortable");
	for (var ti = 0; ti < tables.length ; ti++) {
		if (!tables[ti].id) {
			tables[ti].setAttribute('id','sortable_table_id_'+idnum);
			++idnum;
		}
		ts_makeSortable(tables[ti]);
	}
}

function ts_makeSortable(table) {
	var firstRow;
	if (table.rows && table.rows.length > 0) {
		if (table.tHead && table.tHead.rows.length > 0) {
			firstRow = table.tHead.rows[table.tHead.rows.length-1];
		} else {
			firstRow = table.rows[0];
		}
	}
	if (!firstRow) return;

	// We have a first row: assume it's the header, and make its contents clickable links
	for (var i = 0; i < firstRow.cells.length; i++) {
		var cell = firstRow.cells[i];
		if ((" "+cell.className+" ").indexOf(" unsortable ") == -1) {
			cell.innerHTML += '&nbsp;&nbsp;<a href="#" class="sortheader" onclick="ts_resortTable(this);return false;"><span class="sortarrow"><img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/></span></a>';
		}
	}
	if (ts_alternate_row_colors) {
		ts_alternate(table);
	}
}

function ts_getInnerText(el) {
	if (typeof el == "string") return el;
	if (typeof el == "undefined") { return el };
	if (el.textContent) return el.textContent; // not needed but it is faster
	if (el.innerText) return el.innerText;     // IE doesn't have textContent
	var str = "";

	var cs = el.childNodes;
	var l = cs.length;
	for (var i = 0; i < l; i++) {
		switch (cs[i].nodeType) {
			case 1: //ELEMENT_NODE
				str += ts_getInnerText(cs[i]);
				break;
			case 3:	//TEXT_NODE
				str += cs[i].nodeValue;
				break;
		}
	}
	return str;
}

function ts_resortTable(lnk) {
	// get the span
	var span = lnk.getElementsByTagName('span')[0];

	var td = lnk.parentNode;
	var tr = td.parentNode;
	var column = td.cellIndex;

	var table = tr.parentNode;
	while (table && !(table.tagName && table.tagName.toLowerCase() == 'table'))
		table = table.parentNode;
	if (!table) return;

	// Work out a type for the column
	if (table.rows.length <= 1) return;

	// Skip the first row if that's where the headings are
	var rowStart = (table.tHead && table.tHead.rows.length > 0 ? 0 : 1);

	var itm = "";
	for (var i = rowStart; i < table.rows.length; i++) {
		if (table.rows[i].cells.length > column) {
			itm = ts_getInnerText(table.rows[i].cells[column]);
			itm = itm.replace(/^[\s\xa0]+/, "").replace(/[\s\xa0]+$/, "");
			if (itm != "") break;
		}
	}

	sortfn = ts_sort_caseinsensitive;
	if (itm.match(/^\d\d[\/. -][a-zA-Z]{3}[\/. -]\d\d\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^\d\d[\/.-]\d\d[\/.-]\d\d$/))
		sortfn = ts_sort_date;
	if (itm.match(/^[\u00a3$\u20ac]/)) // pound dollar euro
		sortfn = ts_sort_currency;
	if (itm.match(/^[\d.,]+\%?$/))
		sortfn = ts_sort_numeric;

	var reverse = (span.getAttribute("sortdir") == 'down');

	var newRows = new Array();
	for (var j = rowStart; j < table.rows.length; j++) {
		var row = table.rows[j];
		var keyText = ts_getInnerText(row.cells[column]);
		var oldIndex = (reverse ? -j : j);

		newRows[newRows.length] = new Array(row, keyText, oldIndex);
	}

	newRows.sort(sortfn);

	var arrowHTML;
	if (reverse) {
			arrowHTML = '<img src="'+ ts_image_path + ts_image_down + '" alt="&darr;"/>';
			newRows.reverse();
			span.setAttribute('sortdir','up');
	} else {
			arrowHTML = '<img src="'+ ts_image_path + ts_image_up + '" alt="&uarr;"/>';
			span.setAttribute('sortdir','down');
	}

	// We appendChild rows that already exist to the tbody, so it moves them rather than creating new ones
	// don't do sortbottom rows
	for (var i = 0; i < newRows.length; i++) {
		if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") == -1)
			table.tBodies[0].appendChild(newRows[i][0]);
	}
	// do sortbottom rows only
	for (var i = 0; i < newRows.length; i++) {
		if ((" "+newRows[i][0].className+" ").indexOf(" sortbottom ") != -1)
			table.tBodies[0].appendChild(newRows[i][0]);
	}

	// Delete any other arrows there may be showing
	var spans = getElementsByClassName(tr, "span", "sortarrow");
	for (var i = 0; i < spans.length; i++) {
		spans[i].innerHTML = '<img src="'+ ts_image_path + ts_image_none + '" alt="&darr;"/>';
	}
	span.innerHTML = arrowHTML;

	ts_alternate(table);		
}

function ts_dateToSortKey(date) {	
	// y2k notes: two digit years less than 50 are treated as 20XX, greater than 50 are treated as 19XX
	if (date.length == 11) {
		switch (date.substr(3,3).toLowerCase()) {
			case "jan": var month = "01"; break;
			case "feb": var month = "02"; break;
			case "mar": var month = "03"; break;
			case "apr": var month = "04"; break;
			case "may": var month = "05"; break;
			case "jun": var month = "06"; break;
			case "jul": var month = "07"; break;
			case "aug": var month = "08"; break;
			case "sep": var month = "09"; break;
			case "oct": var month = "10"; break;
			case "nov": var month = "11"; break;
			case "dec": var month = "12"; break;
			// default: var month = "00";
		}
		return date.substr(7,4)+month+date.substr(0,2);
	} else if (date.length == 10) {
		if (ts_europeandate == false) {
			return date.substr(6,4)+date.substr(0,2)+date.substr(3,2);
		} else {
			return date.substr(6,4)+date.substr(3,2)+date.substr(0,2);
		}
	} else if (date.length == 8) {
		yr = date.substr(6,2);
		if (parseInt(yr) < 50) { 
			yr = '20'+yr; 
		} else { 
			yr = '19'+yr; 
		}
		if (ts_europeandate == true) {
			return yr+date.substr(3,2)+date.substr(0,2);
		} else {
			return yr+date.substr(0,2)+date.substr(3,2);
		}
	}
	return "00000000";
}

function ts_parseFloat(num) {
	if (!num) return 0;
	num = parseFloat(num.replace(/,/g, ""));
	return (isNaN(num) ? 0 : num);
}

function ts_sort_date(a,b) {
	var aa = ts_dateToSortKey(a[1]);
	var bb = ts_dateToSortKey(b[1]);
	return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);
}

function ts_sort_currency(a,b) {
	var aa = ts_parseFloat(a[1].replace(/[^0-9.]/g,''));
	var bb = ts_parseFloat(b[1].replace(/[^0-9.]/g,''));
	return (aa != bb ? aa - bb : a[2] - b[2]);
}

function ts_sort_numeric(a,b) {
	var aa = ts_parseFloat(a[1]);
	var bb = ts_parseFloat(b[1]);
	return (aa != bb ? aa - bb : a[2] - b[2]);
}

function ts_sort_caseinsensitive(a,b) {
	var aa = a[1].toLowerCase();
	var bb = b[1].toLowerCase();
	return (aa < bb ? -1 : aa > bb ? 1 : a[2] - b[2]);
}

function ts_sort_default(a,b) {
	return (a[1] < b[1] ? -1 : a[1] > b[1] ? 1 : a[2] - b[2]);
}

function ts_alternate(table) {
	// Take object table and get all it's tbodies.
	var tableBodies = table.getElementsByTagName("tbody");
	// Loop through these tbodies
	for (var i = 0; i < tableBodies.length; i++) {
		// Take the tbody, and get all it's rows
		var tableRows = tableBodies[i].getElementsByTagName("tr");
		// Loop through these rows
		// Start at 1 because we want to leave the heading row untouched
		for (var j = 0; j < tableRows.length; j++) {
			// Check if j is even, and apply classes for both possible results
			var oldClasses = tableRows[j].className.split(" ");
			var newClassName = "";
			for (var k = 0; k < oldClasses.length; k++) {
				if (oldClasses[k] != "" && oldClasses[k] != "even" && oldClasses[k] != "odd")
					newClassName += oldClasses[k] + " ";
			}
			tableRows[j].className = newClassName + (j % 2 == 0 ? "even" : "odd");
		}
	}
}

/*
 * End of table sorting code
 */
 
 
/**
 * Add a cute little box at the top of the screen to inform the user of
 * something, replacing any preexisting message.
 *
 * @param String message HTML to be put inside the right div
 * @param String className   Used in adding a class; should be different for each
 *   call to allow CSS/JS to hide different boxes.  null = no class used.
 * @return Boolean       True on success, false on failure
 */
function jsMsg( message, className ) {
	if ( !document.getElementById ) {
		return false;
	}
	// We special-case skin structures provided by the software.  Skins that
	// choose to abandon or significantly modify our formatting can just define
	// an mw-js-message div to start with.
	var messageDiv = document.getElementById( 'mw-js-message' );
	if ( !messageDiv ) {
		messageDiv = document.createElement( 'div' );
		if ( document.getElementById( 'column-content' )
		&& document.getElementById( 'content' ) ) {
			// MonoBook, presumably
			document.getElementById( 'content' ).insertBefore(
				messageDiv,
				document.getElementById( 'content' ).firstChild
			);
		} else if ( document.getElementById('content')
		&& document.getElementById( 'article' ) ) {
			// Non-Monobook but still recognizable (old-style)
			document.getElementById( 'article').insertBefore(
				messageDiv,
				document.getElementById( 'article' ).firstChild
			);
		} else {
			return false;
		}
	}

	messageDiv.setAttribute( 'id', 'mw-js-message' );
	if( className ) {
		messageDiv.setAttribute( 'class', 'mw-js-message-'+className );
	}
	messageDiv.innerHTML = message;
	return true;
}

/**
 * Inject a cute little progress spinner after the specified element
 *
 * @param element Element to inject after
 * @param id Identifier string (for use with removeSpinner(), below)
 */
function injectSpinner( element, id ) {
	var spinner = document.createElement( "img" );
	spinner.id = "mw-spinner-" + id;
	spinner.src = stylepath + "/common/images/spinner.gif";
	spinner.alt = spinner.title = "...";
	if( element.nextSibling ) {
		element.parentNode.insertBefore( spinner, element.nextSibling );
	} else {
		element.parentNode.appendChild( spinner );
	}
}

/**
 * Remove a progress spinner added with injectSpinner()
 *
 * @param id Identifier string
 */
function removeSpinner( id ) {
	var spinner = document.getElementById( "mw-spinner-" + id );
	if( spinner ) {
		spinner.parentNode.removeChild( spinner );
	}
}


/**
 * Add an event handler to an element
 *
 * @param Element element Element to add handler to
 * @param String attach Event to attach to
 * @param callable handler Event handler callback
 */
function addHandler( element, attach, handler ) {
	if( window.addEventListener ) {
		element.addEventListener( attach, handler, false );
	} else if( window.attachEvent ) {
		element.attachEvent( 'on' + attach, handler );
	}
}

/**
 * Add a click event handler to an element
 *
 * @param Element element Element to add handler to
 * @param callable handler Event handler callback
 */
function addClickHandler( element, handler ) {
	addHandler( element, 'click', handler );
}


function runOnloadHook() {
	// don't run anything below this for non-dom browsers
	if (doneOnloadHook || !(document.getElementById && document.getElementsByTagName)) {
		return;
	}

	// set this before running any hooks, since any errors below
	// might cause the function to terminate prematurely
	doneOnloadHook = true;

	histrowinit();
	unhidetzbutton();
//
//	prefs.js calls addOnloadHook( tabbedprefs ), so the following call is redundant and causes the tabbedprefs toc to display twice.
//
//	tabbedprefs();
	updateTooltipAccessKeys( null );
	akeytt( null );
	scrollEditBox();
	setupCheckboxShiftClick();
	sortables_init();

	// Run any added-on functions
	for (var i = 0; i < onloadFuncts.length; i++) {
		onloadFuncts[i]();
	}
}

// Note: all skins should call runOnloadHook() at the end of html output, so the below should be redundant. It's there just in case.
hookEvent("load", runOnloadHook);



/**
  * Create Google Analytics instance for Citizendium
 */
function loadga() {
	var c; (c = document.createElement("script")).src = "https://www.googletagmanager.com/gtag/js?id=G-W7ML9SNPXT";
	document.head.appendChild(c);

	window.dataLayer = window.dataLayer || [];
	function gtag(){dataLayer.push(arguments);}
	gtag('js', new Date());
	gtag('config', 'G-W7ML9SNPXT');
}

//Call prior function
loadga();


/**
  * Modify link behavior to open in a new tab when contained in a span.newtab
  */
function checklinks(){
	Array.from(document.getElementsByClassName("newtab")).forEach(function(obj){obj.getElementsByTagName("a")[0].target="_blank"});
}

//Call prior function
checklinks();


/* </nowiki> */