User:Funky Monkey/monobook.js

Source: Wikipedia, the free encyclopedia.
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
importScript('User:AzaToth/morebits.js');
importScript('User:AzaToth/twinklefluff.js');
importScript('Wikipedia:WikiProject User scripts/Scripts/Add LI menu');
importStylesheet('Wikipedia:WikiProject User scripts/Scripts/Add LI menu/css');
importScript('User:AzaToth/twinklewarn.js');
importScript('User:AzaToth/twinklearv.js');
importScript('User:AzaToth/twinklespeedy.js');
importScript('User:AzaToth/twinklediff.js');
importScript('User:Ioeth/friendly.js');

















// Script from [[User:ais523/editcount.js]]
document.write('<script type="text/javascript" src="' 
             + 'http://en.wikipedia.org/w/index.php?title=User:ais523/editcount.js' 
             + '&action=raw&ctype=text/javascript&dontcountme=s"></script>');



// see http://paperlined.org/apps/wikipedia/Tool2/ for instructions on adding this to your monobook.js

// To run this tool on other servers:
//	1. copy this script to the target server (this is required because of javascript cross-site security restrictions)

//	2. update the following URL
//		for example: "User:Interiot/Tool2/code.js"
var tool2_url = "User:Interiot/Tool2/code.js";

//	3. update this namespace list, extracted from something like http://en.wikiquote.org/wiki/Special:Export//
//			These *should not* have colons after them.
var namespaces = [
"Talk",
"User",
"User talk",
"Wikiquote",
"Wikiquote talk",
"Image",
"Image talk",
"MediaWiki",
"MediaWiki talk",
"Template",
"Template talk",
"Help",
"Help talk",
"Category",
"Category talk",
		// 3b. these two project project entries are not added by Special:Export, and might or might not need to be updated
"Wikipedia",
"Wikipedia talk"
];

//	4. update this date-parser to match the format and language of your specific wiki.  Feel free to contact Interiot regarding this, if you can't find another
//		copy of this script that uses the same language.
// input: a text string from Special:Contributions.    output: a javascript Date object
// documentation:  http://www.quirksmode.org/js/introdate.html#parse, http://www.elated.com/tutorials/programming/javascript/dates/
function date_parse(text) {
	var matches = text.match(/^([0-9:]+), +([0-9]+) +([a-z]+) +([0-9]+)$/i);
	if (!matches) {
		//dump_text("XXX");			// for debugging
		return matches;
	}

	parseme = matches[3] + ", " + matches[2] + " "  + matches[4] + " " + matches[1] + ":00";

	//dump_text(parseme);				// for debugging

	var dt = new Date();
	dt.setTime( Date.parse(parseme));

	//dump_text(dt.toLocaleString());		// for debugging

	return dt;
}

// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ end of server-specific configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^



// TODO:
//	- the current document.location method doesn't work when the page is accessed sans-mod_rewrite
//	- test with non-ASCII characters
//		- non-ascii usernames
//		- ??



var prefix = "";
var params = parse_params();

addOnloadFunction(function() {
  var path_len = document.location.pathname.length;
  // trigger once we view the right page
  if (document.location.pathname.substring(path_len - tool2_url.length, path_len) == tool2_url) {
    // get the prefix (needs to be fixed to work sans-mod_rewrite
    prefix = document.location.protocol + "//" + document.location.host + "/"
            + document.location.pathname.substring(1, path_len - tool2_url.length);

    // blank the inner contents of the page
    var bodyContent = document.getElementById("bodyContent");
    while (bodyContent.childNodes.length > 0) bodyContent.removeChild(bodyContent.lastChild);

    if (document.location.search.length == 0) {
      generate_input_form(bodyContent);
    } else {
      generate_main_report(bodyContent);
    }
  }
});


function generate_input_form(bodyContent) {
  if (navigator.userAgent.toLowerCase().indexOf('msie')+1)
  {
  bodyContent.innerHTML = "This counter does not currently work in Internet Explorer.  Please <a href='http://www.getfirefox.com'>get Firefox</a> or use <a href='http://en.wikipedia.org/wiki/Wikipedia:WikiProject_edit_counters/Flcelloguy%27s_Tool'>Flcelloguy's Tool</a> instead.";
  }
  else
  {
  bodyContent.innerHTML =
            "<form><table><tr><td>Username <td><input maxlength=128 name=username value='' id=username title='username'>" +
            "             <tr><td>         <td><input type=submit value='Submit'>" +
            "</table></form>";

  var form = bodyContent.getElementsByTagName("form")[0];
  form.method = "get";
  form.action = document.location;

  document.getElementById("username").focus();
  }
}

function generate_main_report() {
  fetch_data(params["username"].replace(/\+/g, " "),
		"", output_main_report, 0, []);
}


	function add_stats_row(left_col, right_col) {
		var row = document.createElement("tr");
		var left = document.createElement("td");
		var right = document.createElement("td");
	
		document.getElementById("basic_stats").appendChild(row);
		row.appendChild(left);
		row.appendChild(right);
		//left.innerHTML = left_col;
		left.appendChild( document.createTextNode(left_col) );
		right.appendChild( document.createTextNode(right_col) );
		return row;
	}

function output_main_report(history) {
	// -- generate summary statistics
	var unique_articles = new Array();
	var namespace_numedits = new Array();
	for (var i=0; i<namespaces.length; i++) {
		namespace_numedits[ namespaces[i] ] = 0;
	}
	namespace_numedits[""] = 0;
	for (var i=0; i<history.length; i++) {
		var h = history[i];
		unique_articles[  h["title"] ]++;
		namespace_numedits[  h["namespace"] ]++;
	}
	var unique_articles_keys = keys(unique_articles);

	// -- output report
	var table = document.createElement("table");
	table.id = "basic_stats";
	document.getElementById("bodyContent").appendChild(table);

	add_stats_row("Username", params["username"].replace(/\+/g, " "));
	add_stats_row("Total edits", history.length);
	add_stats_row("Distinct pages edited", unique_articles_keys.length);
	add_stats_row("Average edits/page", new Number(history.length / unique_articles_keys.length).toFixed(3));
	add_stats_row("First edit", history[ history.length-1 ]["date_text"] );

	// add a blank row
	add_stats_row("", "").childNodes[0].style.height = "1em";

	add_stats_row("(main)", namespace_numedits[""]);
	for (var i=0; i<namespaces.length; i++) {
		var nmspc = namespaces[i];
		if (namespace_numedits[nmspc]) {
			add_stats_row(nmspc, namespace_numedits[nmspc]);
		}
	}
}



// ===================================== HTML-scraping backend =========================================

function add_loading_notice() {
	if (document.getElementById("loading_notice"))
		return;
	var loading = document.createElement("div");
	loading.id = "loading_notice";
	loading.innerHTML = "<br><br>Retrieving data<blink>...</blink>";
	document.getElementById("bodyContent").appendChild(loading);
}
function remove_loading_notice() {
	var loading = document.getElementById("loading_notice");
	if (!loading) return;
	loading.parentNode.removeChild(loading);
}

var offset_regexp = /href="[^"]+:Contributions[^"]+offset=(\d+)/gi;
function fetch_data(username, end_date, handler, offset, page_list) {
	add_loading_notice();
	var url = prefix + "Special:Contributions/" + username + "?offset=" + offset + "&limit=5000";
	loadXMLDoc(url, 
		function (request) {
			var next_offset = 0;
			if (request.readyState != 4)   return;
			if (request.status == 200) {
				page_list.push(request.responseText);
				//dump_text(request.responseText);

				// see if there's another pageful to get
				var matches = map( function(p){
						return p.match( /(\d+)$/ )[0];
					}, request.responseText.match( offset_regexp ) );
				for (var i=0; i<matches.length; i++) {
					var v = matches[i] * 1;
					if (v != 0 && (offset == 0 || v < offset)) {
						next_offset = v;
						break;
					}
				}
			}

			//next_offset = 0;			// for testing only, retrieve just the first page of results

			if (next_offset == 0) {
				parse_data(page_list, handler);
			} else {
				// tail recurse
				fetch_data(username, end_date, handler, next_offset, page_list);
			}
		});
}


// input: a list of strings, each string containing the HTML from a single page
// output: a list, where each individual entry is a specific edit from history
function parse_data(page_list, handler) {
	//var total_len = 0;
	//for (var i=0; i<page_list.length; i++) total_len += page_list[i].length;
	//alert("parsing " + page_list.length + " pages comprising " + total_len + " total bytes");

	var last_history_ent = [];
	last_history_ent["title"] = "";
	last_history_ent["oldid"] = "";

	var edit_history = new Array();
	for (var pagecnt=0; pagecnt<page_list.length; pagecnt++) {
		var matches = page_list[pagecnt].match( /^<li>[^(]+\(<a href="[^"]+action=history.*/gim );
		//dump_lines(matches);
		for (var matchcnt=0; matchcnt<matches.length; matchcnt++) {
			var history_text = matches[matchcnt];

			var history_entry = new Array();
			history_entry["date_text"] = history_text.match( /^<li>([^(<]+)/i )[1]
					.replace( / +$/, "");
			history_entry["date"] = date_parse( history_entry["date_text"] );
			history_entry["title"] = history_text.match( /title="([^"]+)"/i )[1]
					.replace( /&quot;/g, "\"")
					.replace( /&amp;/g, "&");
			var find_comment = history_text.replace(/<span class="autocomment">.*?<\/span> ?/, "");
			history_entry["comment"] = ifmatch(find_comment.match( /<span class='comment'>(.*?)<\/span>/ ))
					.replace(/^\((.*)\)$/, "$1");
			history_entry["minor"] = /<span class="minor"/.test(history_text);
			history_entry["oldid"] = ifmatch(history_text.match(/oldid=([0-9]+)/i));

			history_entry["namespace"] = "";
			for (var nmspc_ctr=0; nmspc_ctr<namespaces.length; nmspc_ctr++) {
				var nmspc = namespaces[nmspc_ctr] + ":";
				if (history_entry["title"].substring(0, nmspc.length) == nmspc) {
					history_entry["namespace"] = namespaces[nmspc_ctr];
					break;
				}
			}

			//dump_object(history_entry);

			if (history_entry["title"] != last_history_ent["title"] || history_entry["oldid"] != last_history_ent["oldid"])
				edit_history.push(history_entry);
			last_history_ent = history_entry;
		}
	}

	remove_loading_notice();

	handler(edit_history);
}




// ===================================== test/debug functions =========================================

function dump_text(text) {
  //alert("dump_text, with text of size " + text.length);

  var pre = document.createElement("pre");

  var div = document.createElement("div");
  div.style.width = "60em";
  div.style.maxHeight = "40em";
  div.style.overflow = "auto";

  pre.appendChild(document.createTextNode(text));
  div.appendChild(pre);
  document.getElementById("bodyContent").appendChild(div);
}

function dump_lines(ary) {
  dump_text("--> " + ary.join("\n--> "));
}

function dump_object(obj) {
	var toString = "";
	for (var prop in obj) {
		toString += prop + ": " + obj[prop] + "\n";
	}
	dump_text(toString);
}


// ===================================== utility functions =========================================

function addOnloadFunction(f) {
  if (window.addEventListener) window.addEventListener("load",f,false);
  else if (window.attachEvent) window.attachEvent("onload",f);
  else {
    var oldOnload='_old_onload_'+addOnloadFunction.uid;
    addOnloadFunction[oldOnload] = window.onload ? window.onload : function () {};
    window.onload = function() { addOnloadFunction[oldOnload]();  f(); }
    ++addOnloadFunction.uid;
  }
}


function parse_params() {
  var pairs = document.location.search.substring(1).split("&");
  var ret = [];
  for (var i=0; i < pairs.length; i++) {
    var values = pairs[i].split("=");
    ret[values[0]] = unescape(values[1]);
  }
  return ret; 
}


function loadXMLDoc(url, handler)
{
    // branch for native XMLHttpRequest object
    if (window.XMLHttpRequest) {
        req = new XMLHttpRequest();
	req.onreadystatechange = function () {handler(req)};
        req.open("GET", url, true);
        req.send(null);
    // branch for IE/Windows ActiveX version
    } else if (window.ActiveXObject) {
        req = new ActiveXObject("Microsoft.XMLHTTP");
        if (req) {
            req.onreadystatechange = function () {handler(req)};
            req.open("GET", url, true);
            req.send();
        }
    }
}


// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#map
function map (handler, list) {
  var ret = new Array();
  for (var i=0; i<list.length; i++) {
    ret[i] = handler( list[i] );
    // ret.push( handler( list[i] ) );
  }
  return ret;
}

// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#keys
function keys (obj) {
	var ret = new Array();
	for (var key in obj) {
		ret.push(key);
	}
	return ret;
}


function ifmatch(ary) {
	if (ary && ary.length >= 2) {
		return ary[1];
	} else {
		return "";
	}
}







 // Script from [[User:MarkS/extraeditbuttons.js]]
document.write('<script type="text/javascript" src="' 
             + 'http://en.wikipedia.org/w/index.php?title=User:MarkS/extraeditbuttons.js' 
             + '&action=raw&ctype=text/javascript&dontcountme=s"></script>');




document.write('<script src="http://gladstone.uoregon.edu/~chill1/betterhistory/betterhistory.js"><\/script>');














/**** afd helper ****/
document.write('<script type="text/javascript"' +
  'src="http://en.wikipedia.org/w/index.php?title=User:Jnothman/afd_helper/' +
  'script.js&action=raw&ctype=text/javascript&dontcountme=s"></script>');

/* This is to keep track of who is using this extension: [[User:Jnothman/afd_helper/script.js]] */






// -----------------------------------------------------------------------------
// God-like Monobook skin
// (c) 2005 Sam Hocevar <[email protected]>
// $Id: godmode-light.js 911 2005-08-09 10:06:39Z sam $
// Modified for navpopups compatibility by Martijn Pieters. (?)
// Ampersand bug fixed by Ilmari Karonen.
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// Language support, taken from phase3/languages/*
// -----------------------------------------------------------------------------
var rollbacklink = 'rollback';
var cantrollback = 'Cannot revert edit; last contributor is only author of this page.';
var alreadyrolled = 'Cannot rollback last edit of [[$1]] by [[User:$2|$2]] ([[User talk:$2|Talk]]); someone else has edited or rolled back the page already. Last edit was by [[User:$3|$3]] ([[User talk:$3|Talk]]). ';
var revertpage = 'Reverted edits by [[Special:Contributions/$2|$2]] to last version by $1';
switch (document.getElementsByTagName('html')[0].lang) {
  case 'fr':
    rollbacklink = 'révoquer';
    cantrollback = 'Impossible de révoquer: dernier auteur est le seul à avoir modifié cet article';
    alreadyrolled = 'Impossible de révoquer la dernière modification de [[$1]] par  [[User:$2|$2]] ([[User talk:$2|Talk]]); quelqu\'un d\'autre à déjà modifer ou révoquer l\'article. La dernière modificaion était de [[User:$3|$3]] ([[User talk:$3|Talk]]). '; // lol @ pathetic grammar
    revertpage = "Révocation des modifications de [[Special:Contributions/$2|$2]] et restauration d'une précédente version de $1";
    break;
  case 'de':
    rollbacklink = 'Zurücksetzen';
    cantrollback = 'Die Änderung kann nicht zurückgenommen werden; der letzte Autor ist der einzige.';
    alreadyrolled = 'Die Zurücknahme des Artikels [[$1]] von [[Benutzer:$2|$2]] ([[Benutzer Diskussion:$2|Diskussion]]) ist nicht möglich, da eine andere Änderung oder Rücknahme erfolgt ist.  Die letzte Änderung ist von [[Benutzer:$3|$3]] ([[Benutzer Diskussion:$3|Diskussion]])';
    revertpage = 'Änderungen von [[Benutzer:$2]] rückgängig gemacht und letzte Version von [[Benutzer:$1]] wiederhergestellt';
    break;
  case 'es':
    rollbacklink = 'Revertir';
    cantrollback = 'No se pueden revertir las ediciones; el último colaborador es el único autor de este artículo.';
    alreadyrolled = 'No se puede revertir la última edición de [[$1]] por [[Colaborador:$2|$2]] ([[Colaborador Discusión:$2|Discusión]]); alguien más ya ha editado o revertido esa página.  La última edición fue hecha por [[Colaborador:$3|$3]] ([[Colaborador Discusión:$3|Discusión]]). ';
    revertpage = 'Revertida a la última edición de $1';
    break;
  case 'it':
    rollbacklink = 'rollback';
    cantrollback = 'Impossibile tornare ad una versione precedente: l\'ultima modifica è stata apportata dall\'unico utente che abbia lavorato a questo articolo.';
    //alreadyrolled = '';
    revertpage = 'Riportata alla revisione precedente da $1';
    break;
  case 'pt':
    rollbacklink = 'voltar';
    cantrollback = 'Não foi possível reverter a edição; o último contribuidor é o único autor deste artigo.';
    alreadyrolled = 'Não foi possível reverter as edições de  [[$1]] por [[User:$2|$2]] ([[User talk:$2|Talk]]); alguém o editou ou já o reverteu.  A última edição foi de  [[User:$3|$3]] ([[User talk:$3|Conversar com ele]]). ';
    revertpage = 'Revertidas edições por [[Special:Contributions/$2|$2]], para a última versão por $1';
    break;
}

// -----------------------------------------------------------------------------
// XMLHttpRequest support
// -----------------------------------------------------------------------------
if (document.implementation.createDocument && window.DOMParser) {
  var xmlparser = new DOMParser();
}

function XMLParse(xmlhttp) {
  if (document.implementation.createDocument && window.DOMParser) {
    return xmlparser.parseFromString(xmlhttp.responseText, "text/xml");
  } else if (window.ActiveXObject) {
    var xmldoc = new ActiveXObject("Microsoft.XMLDOM");
    xmldoc.async = "false";
    ret = xmldoc.loadXML(xmlhttp.responseText);      
    if (!ret)
      return null;
    return xmldoc.documentElement;
  }
  return xmlhttp.responseXML;
}

var xmlhttp;

function HTTPClient() {
  var http;
  if(window.XMLHttpRequest) {
    http = new XMLHttpRequest();
  } else if (window.ActiveXObject) {
    try {
      http = new ActiveXObject("Msxml2.XMLHTTP");
    } catch (e) {
      try {
        http = new ActiveXObject("Microsoft.XMLHTTP");
      } catch (E) {
        http = false;
      }
    }
  }
  return http;
}

// -----------------------------------------------------------------------------
// MD5 hash calculator
// -----------------------------------------------------------------------------
// Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
// Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
// Distributed under the BSD License
// See http://pajhome.org.uk/crypt/md5 for more info.
// -----------------------------------------------------------------------------
var hexcase = 0;
var b64pad  = "";
var chrsz   = 8;

function hex_md5(s){ return binl2hex(core_md5(str2binl(s), s.length * chrsz));}

function core_md5(x, len)
{
  x[len >> 5] |= 0x80 << ((len) % 32);
  x[(((len + 64) >>> 9) << 4) + 14] = len;

  var a =  1732584193;
  var b = -271733879;
  var c = -1732584194;
  var d =  271733878;

  for(var i = 0; i < x.length; i += 16)
  {
    var olda = a;
    var oldb = b;
    var oldc = c;
    var oldd = d;

    a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936); d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586); c = md5_ff(c, d, a, b, x[i+ 2], 17,  606105819); b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330); a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897); d = md5_ff(d, a, b, c, x[i+ 5], 12,  1200080426); c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341); b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983); a = md5_ff(a, b, c, d, x[i+ 8], 7 ,  1770035416); d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417); c = md5_ff(c, d, a, b, x[i+10], 17, -42063); b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162); a = md5_ff(a, b, c, d, x[i+12], 7 ,  1804603682); d = md5_ff(d, a, b, c, x[i+13], 12, -40341101); c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290); b = md5_ff(b, c, d, a, x[i+15], 22,  1236535329);

    a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510); d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632); c = md5_gg(c, d, a, b, x[i+11], 14,  643717713); b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302); a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691); d = md5_gg(d, a, b, c, x[i+10], 9 ,  38016083); c = md5_gg(c, d, a, b, x[i+15], 14, -660478335); b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848); a = md5_gg(a, b, c, d, x[i+ 9], 5 ,  568446438); d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690); c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961); b = md5_gg(b, c, d, a, x[i+ 8], 20,  1163531501); a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467); d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784); c = md5_gg(c, d, a, b, x[i+ 7], 14,  1735328473); b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);

    a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558); d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463); c = md5_hh(c, d, a, b, x[i+11], 16,  1839030562); b = md5_hh(b, c, d, a, x[i+14], 23, -35309556); a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060); d = md5_hh(d, a, b, c, x[i+ 4], 11,  1272893353); c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632); b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640); a = md5_hh(a, b, c, d, x[i+13], 4 ,  681279174); d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222); c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979); b = md5_hh(b, c, d, a, x[i+ 6], 23,  76029189); a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487); d = md5_hh(d, a, b, c, x[i+12], 11, -421815835); c = md5_hh(c, d, a, b, x[i+15], 16,  530742520); b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);

    a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844); d = md5_ii(d, a, b, c, x[i+ 7], 10,  1126891415); c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905); b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055); a = md5_ii(a, b, c, d, x[i+12], 6 ,  1700485571); d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606); c = md5_ii(c, d, a, b, x[i+10], 15, -1051523); b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799); a = md5_ii(a, b, c, d, x[i+ 8], 6 ,  1873313359); d = md5_ii(d, a, b, c, x[i+15], 10, -30611744); c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380); b = md5_ii(b, c, d, a, x[i+13], 21,  1309151649); a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070); d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379); c = md5_ii(c, d, a, b, x[i+ 2], 15,  718787259); b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);

    a = safe_add(a, olda);
    b = safe_add(b, oldb);
    c = safe_add(c, oldc);
    d = safe_add(d, oldd);
  }
  return Array(a, b, c, d);

}

function md5_cmn(q, a, b, x, s, t) { return safe_add(bit_rol(safe_add(safe_add(a, q), safe_add(x, t)), s),b); }
function md5_ff(a, b, c, d, x, s, t) { return md5_cmn((b & c) | ((~b) & d), a, b, x, s, t); }
function md5_gg(a, b, c, d, x, s, t) { return md5_cmn((b & d) | (c & (~d)), a, b, x, s, t); }
function md5_hh(a, b, c, d, x, s, t) { return md5_cmn(b ^ c ^ d, a, b, x, s, t); }
function md5_ii(a, b, c, d, x, s, t) { return md5_cmn(c ^ (b | (~d)), a, b, x, s, t); }

function safe_add(x, y)
{
  var lsw = (x & 0xFFFF) + (y & 0xFFFF);
  var msw = (x >> 16) + (y >> 16) + (lsw >> 16);
  return (msw << 16) | (lsw & 0xFFFF);
}

function bit_rol(num, cnt)
{
  return (num << cnt) | (num >>> (32 - cnt));
}

function str2binl(str)
{
  var bin = Array();
  var mask = (1 << chrsz) - 1;
  for(var i = 0; i < str.length * chrsz; i += chrsz)
    bin[i>>5] |= (str.charCodeAt(i / chrsz) & mask) << (i%32);
  return bin;
}

function binl2hex(binarray)
{
  var hex_tab = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
  var str = "";
  for(var i = 0; i < binarray.length * 4; i++)
  {
    str += hex_tab.charAt((binarray[i>>2] >> ((i%4)*8+4)) & 0xF) +
           hex_tab.charAt((binarray[i>>2] >> ((i%4)*8  )) & 0xF);
  }
  return str;
}

// -----------------------------------------------------------------------------
// Our nice Revert functions
// -----------------------------------------------------------------------------
var gml_vandal, gml_editor, gml_url;

function PerformRevert() {
  var l, token = '', revert = false;
  // Look for '&fakeaction=rollback' in URL
  gml_url = location.pathname;
  l = location.search.substring(1).split('&');
  for (i = 0; i < l.length; i++) {
    var n = l[i].indexOf('=');
    var name = l[i].substring(0, n);
    if (name == 'fakeaction') {
      if (l[i].substring(n + 1) == 'rollback')
        revert = true;
    } else if (name == 'vandal') {
      gml_vandal = unescape(l[i].substring(n + 1));
    } else if (name == 'token') {
      token = unescape(l[i].substring(n + 1));
    } else if (name == 'title') {
      gml_url += '?' + l[i];
    }
  }
  if (!revert)
    return;
  document.getElementById('bodyContent').innerHTML = 'Please wait, reverting edits by ' + gml_vandal + '...';
  // Avoid XSS kiddies by using a special token
  if (token == '' || token != hex_md5(gml_url + gml_vandal + document.cookie)) {
    document.getElementById('bodyContent').innerHTML += '<br />Bad authentication token!';
    return;
  }

  xmlhttp = HTTPClient();
  if (!xmlhttp)
    return;
  document.getElementById('bodyContent').innerHTML += '<br />Getting article history...';
  xmlhttp.open("GET", gml_url + '&action=history&limit=50', true);
  xmlhttp.onreadystatechange = RevertStepTwo;
  xmlhttp.send(null);
}

function RevertStepTwo() {
  if (xmlhttp.readyState != 4)
    return
  var l;
  var oldid;
  // Get the vandal and new editor names
  gml_vandal = gml_vandal.replace(/_/g, ' ');
  gml_editor = '';
  doc = XMLParse(xmlhttp);
  l = doc.getElementById('pagehistory').getElementsByTagName('li');
  //l = doc.selectSingleNode('//*[@id="pagehistory"]').getElementsByTagName('li');
  for (i = 0; i < l.length; i++) {
    var name = l[i].getElementsByTagName('span')[0].getElementsByTagName('a')[0].innerHTML.replace(/_/g, ' ');
    if (i == 0 && name != gml_vandal) {
      document.getElementById('bodyContent').innerHTML += '<br />Error: Last editor is ' + name + ', not ' + gml_vandal + '!';
      return;
    } else if (i > 0 && name != gml_vandal) {
      oldid = l[i].getElementsByTagName('input')[0].value;
      gml_editor = name;
      break;
    }
  }
  if (gml_editor == '') {
    document.getElementById('bodyContent').innerHTML += '<br />Error: ' + gml_vandal + ' is the only editor!';
    return;
  }

  xmlhttp = HTTPClient();
  if (!xmlhttp)
    return;
  document.getElementById('bodyContent').innerHTML += '<br />Getting article edit form (GET' + gml_url + '&action=edit&oldid=' + oldid + ')...';
  xmlhttp.open('GET', gml_url + '&action=edit&oldid=' + oldid, true);
  xmlhttp.onreadystatechange = RevertStepThree;
  xmlhttp.send(null);
}

function RevertStepThree() {
  if (xmlhttp.readyState != 4)
    return
  var form, newform, l;
  // Insert the downloaded form in our current page, using
  // only hidden form inputs.
  doc = XMLParse(xmlhttp);
  form = doc.getElementById('editform');
  newform = document.createElement('form');
  l = form.getElementsByTagName('textarea');
  for (i = l.length; i--; ) {
    var t = document.createElement('input');
    t.type = 'hidden';
    t.name = l[i].name;
    t.value = l[i].value;
    newform.appendChild(t);
  }
  l = form.getElementsByTagName('input');
  for (i = l.length; i--; ) {
    if (l[i].name == 'wpSummary') {
      l[i].value = revertpage.replace(/\$1/g, gml_editor).replace(/\$2/g, gml_vandal);
    } else if (l[i].name == 'wpMinoredit') {
      l[i].value = '1';
    } else if (l[i].name == 'wpWatchthis') {
      if (!l[i].checked)
        continue; // Don’t touch the "watch" status
      l[i].value = "on";
    } else if (l[i].name == 'wpPreview') {
      continue;
    } else if (l[i].name == 'wpDiff') {
      continue;
    }
    l[i].type = 'hidden';
    newform.appendChild(l[i]);
  }
  newform.name = form.name;
  newform.method = form.method;
  newform.id = form.id;
  newform.action = form.action;
  document.getElementById('bodyContent').innerHTML += '<br />Submitting form...';
  document.getElementById('bodyContent').appendChild(newform);
  // Submit the form
  newform.submit();
}

// -----------------------------------------------------------------------------
// Add revert buttons to the page
// -----------------------------------------------------------------------------
function AddRevertButtons() {
  var l, article = '', vandal;
  // Add 'revert' links to a diff page
  l = document.getElementById('bodyContent').getElementsByTagName('td');
  for (i = 0; i < l.length; i++) {
    if (l[i].className == 'diff-otitle') {
      article = l[i].getElementsByTagName('a')[0].href.split('&')[0].replace(/[^\/]*\/\/[^\/]*/, '');
    } else if (l[i].className == 'diff-ntitle') {
      var toplink = l[i].getElementsByTagName('a')[0];
      var vndlink = l[i].getElementsByTagName('a')[1];
      vandal = /^User:(.*)/.exec(vndlink.title);   
      if (!vandal) vandal = /\?title=Special:Contributions&target=([0-9.]+)/.exec(vndlink.href);  
      if (!vandal) return;   
      vandal = vandal[1];  
      if (article != '' && toplink.href.indexOf('oldid=') == -1) {  
        var rvlink = '    <strong>[<a href="' + article + '&fakeaction=rollback&vandal=' + vandal + '&token=' + hex_md5(article + vandal + document.cookie) + '">' + rollbacklink + '</a>]</strong> ';  
        l[i].innerHTML = l[i].innerHTML.replace(/<\/a>\)\s+<br/i, "</a>)"+rvlink+"<br"); 
      }
    }
  }
  // Add 'revert' links to a contributions page
  if (location.href.indexOf(':Contributions') != -1) {
    var c = document.getElementById('contentSub');
    var a = c.getElementsByTagName('a');
    if (a.length == 2) {
      vandal = a[0].innerHTML;
    } else {
      vandal = c.innerHTML.replace(/ \(.*/, '').replace(/.* /, '');
    }
    l = document.getElementById('bodyContent').getElementsByTagName('li');
    for (i = 0; i < l.length; i++) {
      var t = l[i].innerHTML
      // If we are already a sysop on this wiki, abort
      if (t.indexOf('>' + rollbacklink + '</a>]') != -1)
          break;
      //if (t.indexOf('&diff=0') != -1) {
      if (t.indexOf('<strong> (') != -1) {
        article = l[i].getElementsByTagName('a')[0].href.split('&')[0].replace(/[^\/]*\/\/[^\/]*/, '');
        l[i].innerHTML += ' [<a href="' + article + '&fakeaction=rollback&vandal=' + vandal + '&token=' + hex_md5(article + vandal + document.cookie) + '">' + rollbacklink + '</a>]';
      }
    }
  }
}

// -----------------------------------------------------------------------------
// Modify the page once it is loaded
// -----------------------------------------------------------------------------
$(PerformRevert);
$(AddRevertButtons);

// 







function inc (file) {
  mw.loader.load('/w/index.php?title='+file+'&action=raw&ctype=text/javascript&dontcountme=s');
}
inc("User:Lightdarkness/aiv.js");

function tnaddlilink(url, name)
{
  var na = document.createElement('a');
  na.setAttribute('href', url);

  var txt = document.createTextNode(name);
  na.appendChild(txt);

  var li = document.createElement('li');
  li.appendChild(na);
  return li;
}

function testn(number)
{
  var page = prompt("Vandalism to which article?")
  var f = document.editform, t = f.wpTextbox1;
  if (t.value.length > 0)
    t.value += '\n';
  t.value += "{{subst:" + "test" + number + "-n|" + page + "}} ~" + "~" + "~" + "~";
  f.wpSummary.value = "Vandalism to [[" + page + "]] - warning " + number;
}

function add_testn_tabs()
{
  var c1 = document.getElementById('column-one');
  var tabs = c1.getElementsByTagName('div')[0].getElementsByTagName('ul')[0];

  // Only add for pages with "Editing User talk:" somewhere in the title
  if (document.title.indexOf("Editing User talk:") != -1)
    {
      tabs.appendChild(tnaddlilink('javascript:testn(1)',"t1"));
      tabs.appendChild(tnaddlilink('javascript:testn(2)',"t2"));
      tabs.appendChild(tnaddlilink('javascript:testn(3)',"t3"));
      tabs.appendChild(tnaddlilink('javascript:testn(4)',"t4"));
    }
}

$(add_testn_tabs);

//


// Script from [[User:Lupin/recent2.js]]
mw.loader.load(
             'https://en.wikipedia.org/w/index.php?title=User:Lupin/recent2.js'
             + '&action=raw&ctype=text/javascript&dontcountme=s');

//<pre><nowiki>
var hide_spoilers_initially = false;
var hide_endspoiler_tag = false;

function addlink(url, name, node, prev)
{
  var na = document.createElement('a');
  na.setAttribute('href', '/wiki/' + url);

  var txt = document.createTextNode(name);
  na.appendChild(txt);

  if (node)
    if (prev)
      node.insertBefore(na, prev);
    else
      node.appendChild(na);
  else
    return na;
}

function addexplicitlink(url, name, node, prev)
{
  var na = document.createElement('a');
  na.setAttribute('href', url);

  var txt = document.createTextNode(name);
  na.appendChild(txt);

  if (node)
    if (prev)
      node.insertBefore(na, prev);
    else
      node.appendChild(na);
  else
    return na;
}

function add_id_link(url, name, id, node, prev)
{
  var na = document.createElement('a');
  na.setAttribute('href', url);

  var txt = document.createTextNode(name);
  na.appendChild(txt);

  na.id = id;

  if (node)
    if (prev)
      node.insertBefore(na, prev);
    else
      node.appendChild(na);
  else
    return na;
}

function pipe(node, txt, prev)
{
  if (node)
    if (prev)
      node.insertBefore(document.createTextNode(txt ? txt : ' | '), prev);
    else
      node.appendChild(document.createTextNode(txt ? txt : ' | '));
  else
    return document.createTextNode(' | ');
}

function set_cookie(name, value, expires, path, domain, secure)
{
  document.cookie = name + '=' + escape(value) + (expires ? '; expires=' + expires.toGMTString() : '') + (path ? '; path=' + path : '') + (domain ? '; domain=' + domain : '') + (secure ? '; secure' : '');
}

function set_cookie_no_escape(name, value, expires, path, domain, secure)
{
  document.cookie = name + '=' + value + (expires ? '; expires=' + expires.toGMTString() : '') + (path ? '; path=' + path : '') + (domain ? '; domain=' + domain : '') + (secure ? '; secure' : '');
}

function get_cookie(name)
{
  var dc = document.cookie;
  var prefix = name + '=';
  var begin = dc.indexOf('; ' + prefix);
  if (begin == -1)
    {
      begin = dc.indexOf(prefix);
      if (begin != 0)
        return null;
    }
  else
    begin += 2;
  var end = document.cookie.indexOf(';', begin);
  if (end == -1)
    end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}

function delete_cookie(name, path, domain)
{
  if (getCookie(name))
    document.cookie = name + '=' + (path ? '; path=' + path : '') + (domain ? '; domain=' + domain : '') + '; expires=Thu, 01-Jan-70 00:00:01 GMT';
}

function replace()
{
  var s = prompt('Search regexp?');
  if (s)
    {
      var r = prompt('Replace regexp?');
      var txt = document.editform.wpTextbox1;
      txt.value = txt.value.replace(new RegExp(s, 'g'), r);
    }
}

function set_preset_search_n_replace()
{
  var preset_search = prompt('Search regexp?');
  if (!preset_search)
    {
      delete_cookie('preset_search');
      delete_cookie('preset_replace');
      delete_cookie('preset_summary');
      return;
    }
  var preset_replace = prompt('Replace with?');
  var preset_summary = prompt('Summary?');
  if (!preset_summary)
    {
      delete_cookie('preset_search');
      delete_cookie('preset_replace');
      delete_cookie('preset_summary');
      return;
    }
  set_cookie('preset_search', preset_search);
  set_cookie('preset_replace', preset_replace);
  set_cookie('preset_summary', preset_summary);
}

function preset_search_n_replace()
{
  var f = document.editform;
  var txt = f.wpTextbox1;
  var preset_search = get_cookie('preset_search');
  var preset_replace = get_cookie('preset_replace');
  var preset_summary = get_cookie('preset_summary');

  txt.value = txt.value.replace(new RegExp(preset_search, 'g'), preset_replace);
  if (f.wpSummary.value.indexOf(preset_summary) < 0)
    f.wpSummary.value += preset_summary;
  f.wpWatchthis.checked = false;
  f.wpMinoredit.checked = true;
  f.wpDiff.click();
}

function unlk_per_afd()
{
  var f = document.editform;
  var txt = f.wpTextbox1;
  var last_whatlinkshere = get_cookie('last_whatlinkshere');
  var last_afd = get_cookie('last_afd');

  txt.value = txt.value.replace(new RegExp('\\[\\[ *(' + last_whatlinkshere + ') *\\]\\]', 'gi'), '$1');
  txt.value = txt.value.replace(new RegExp('\\[\\[ *' + last_whatlinkshere + ' *\\|([^\\]]*)\\]\\]', 'gi'), '$1');
  var summary = 'unlk [[' + last_whatlinkshere + ']] per [[' + last_afd + '|afd]]';
  if (f.wpSummary.value.indexOf(summary) < 0)
    f.wpSummary.value += summary;
  f.wpWatchthis.checked = false;
  f.wpMinoredit.checked = true;
  f.wpDiff.click();
}

function prod()
{
  var rationale = prompt('Rationale?');
  if (rationale)
    {
      document.editform.wpTextbox1.value = '{{prod|' + rationale + '}}\n' + document.editform.wpTextbox1.value;
      document.editform.wpSummary.value = '[[Wikipedia:Proposed deletion|Proposed for deletion]]: ' + rationale;
      document.editform.wpSave.onclick = '';
    }
}

function header_xfd(equals)
{
  var start = document.title.indexOf('/'), end = document.title.indexOf(' - Wikipedia, the free encyclopedia');
  document.editform.wpTextbox1.value = equals + '[[' + document.title.substring(start + 1, end) + ']]' + equals + '\n' + document.editform.wpTextbox1.value;
  document.editform.wpSummary.value = 'header';
}

function oldafdfull()
{
  var date = prompt('Date?');
  if (!date)
    return;
  if (date.match(/^ *([0-9]+) +([A-Z][a-z]+) +(200[0-9]) *$/))
    date = '[[' + RegExp.$1 + ' ' + RegExp.$2 + ']] [[' + RegExp.$3 + ']]';
  else if (date.match(/^ *([A-Z][a-z]+) +([0-9]+) +(200[0-9]) *$/))
    date = '[[' + RegExp.$1 + ' ' + RegExp.$2 + ']] [[' + RegExp.$3 + ']]';
  else
    {
      alert('Unrecognized date');
      return;
    }
  template('oldafdfull|date=' + date + '|result=\'\'\'keep\'\'\'|votepage={{subst:PAGENAME}}');
  document.editform.wpWatchthis.checked = false;
}

function template(tm)
{
  document.editform.wpTextbox1.value = '{{' + tm + '}}\n' + document.editform.wpTextbox1.value;
  document.editform.wpSummary.value = '{{' + tm + '}}';
}

function user_talk_template(tm, sum)
{
  if (document.editform.wpTextbox1.value.length > 0)
    document.editform.wpTextbox1.value += '\n';
  document.editform.wpTextbox1.value =  document.editform.wpTextbox1.value + '{{subst:' + tm + '}} ~~~~\n';
  document.editform.wpSummary.value = sum;
}

function makebutton(lbl, action)
{
  var button = document.createElement('input');
  button.type = 'button';
  button.value = lbl;
  button.setAttribute('onClick', action);
  return button;
}

function strip_namespace(target)
{
  var colon = target.indexOf(':');
  if (colon != -1)
    {
      var spaces = new Array('User', 'Wikipedia', 'Image', 'MediaWiki', 'Template', 'Help', 'Category');
      var ns = target.substring(0, colon);
      if (ns == '' || ns == 'Talk')
        return target.substring(colon + 1);
      else
        for (var i = 0; i < spaces.length; ++i)
          {
            if (ns == spaces[i]
                || ns == spaces[i] + '_talk')
              return target.substring(colon + 1);
          }
    }

  return target;
}

function vfd()
{
  document.editform.wpTextbox1.value = '{{subst:afd}}\n' + document.editform.wpTextbox1.value;
  document.editform.wpSummary.value = 'afd';

  var target = document.editform.action;
  target = target.substring(target.indexOf('title=') + 6,
                            target.lastIndexOf('&action=submit'));

  var months = new Array('January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December');
  var date = new Date();
  date = date.getUTCFullYear() + '_' + months[date.getUTCMonth()] + '_' + date.getUTCDate();

  var pagename = strip_namespace(target);

  window.open('/w/index.php?title=Wikipedia:Articles_for_deletion/' + pagename + '&action=edit&fakeaction=vfdsub&faketarget=' + target, '_blank');
  window.open('/w/index.php?title=Wikipedia:Articles_for_deletion/Log/' + date + '&action=edit&fakeaction=vfdlist&faketarget=' + pagename, '_blank');
}

function transwiki_log()
{
  var title = prompt('Title?');
  if (title)
    {
      var target = prompt('To project?')
      if (target)
        {
          if (target == 'k' || target == 'K' || target == 'd' || target == 'D')
            target = 'wikt';
          else if (target == 's' || target == 'S')
            target = 'wikisource';
          else if (target == 'c' || target == 'C')
            target = 'commons';

          var txt = document.editform.wpTextbox1;
          var vfdd = prompt('Afd at? (y/Y for [[Wikipedia:Articles for deletion/' + title + ']], or empty for none');
          if (vfdd == 'y' || vfdd == 'Y')
            vfdd = ' ([[Wikipedia:Articles for deletion/' + title + '|AfD]])';
          else if (vfdd == 'n' || vfdd == 'N' || vfdd == '')
            vfdd = '';
          else
            vfdd = ' ([[Wikipedia:Articles for deletion/' + vfdd + '|AfD]])';
          txt.value += '*[[' + title + ']] &rarr; [[' + target + ':Transwiki:' + title + ']] ~~~~' + vfdd;
          document.editform.wpSummary.value = '[[' + title + ']] transwikied to [[' + target + ':Transwiki:' + title + ']]' + vfdd;
        }
    }
}

function transwiki_to()
{
  var target = prompt('Transwiki to?\nwiKt/Books/Source/Commons/Meta/Quote');
  if (target == 'k' || target == 'K' || target == 'd' || target == 'D')
    target = 'en.wiktionary';
  else if (target == 'b' || target == 'B')
    target = 'en.wikibooks';
  else if (target == 's' || target == 'S')
    target = 'wikisource';
  else if (target == 'c' || target == 'C')
    target = 'commons.wikimedia';
  else if (target == 'm' || target == 'M')
    target = 'meta.wikimedia';
  else if (target == 'q' || target == 'Q')
    target = 'en.wikiquote';
  else
    {
      window.alert('Unknown target.');
      return;
    }

  var url = new String(document.location);
  url = url.replace(/en\.wikipedia/, target);
  url = url.replace(/index\.php\?title=/, 'index.php?title=Transwiki:');
  window.location = url;
}

function interwiki(lk, td, a, host, abbrev)
{
  host = lk.replace(/source/, host);
  addexplicitlink(host, abbrev, td, a);
  if (abbrev == 'D' || abbrev == 'd')
    {
      pipe(td, '/', a);
      addexplicitlink(host.toLowerCase(), 'lc', td, a);
    }
  pipe(td, 0, a);
}

function dbtranswiki()
{
  var target = prompt('Transwikied to project?');
  if (target == 'k' || target == 'K' || target == 'd' || target == 'D')
    target = 'wikt';
  else if (target == 's' || target == 'S')
    target = 'wikisource';
  else if (target == 'c' || target == 'C')
    target = 'commons';
  else if (target == '')
    return;
  var title = document.editform.action;
  title = title.substring(title.indexOf('title=') + 6,
                          title.lastIndexOf('&action=submit'));
  title = title.replace(/_/g, ' ');

  if (target)
    template('db|[[Wikipedia:Articles for deletion/' + title + '|Afd result to transwiki]]; transwiki to [[' + target + ':Transwiki:' + title
             + ']] complete, with author information at [[' + target + ':Talk:Transwiki:' + title + ']]');
}

function link_ul_edit(isnull)
{
  var uls = document.getElementsByTagName('ul');
  var edit = isnull ? '&action=edit&fakeaction=nulledit' : '&action=edit';
  for (var i = 0; i < uls.length; ++i)
    {
      var lis = uls[i].getElementsByTagName('li');
      for (var j = 0; j < lis.length; ++j)
        {
          var as = lis[j].getElementsByTagName('a');
          for (var k = 0; k < as.length; ++k)
            if (as[k].getAttribute('href').match(/^(.*)\/wiki\/(.*)$/))
              {
                as[k].setAttribute('href', RegExp.$1 + '/w/index.php?title=' + RegExp.$2 + edit);
                as[k].setAttribute('class', as[k].getAttribute('class') + ' modified');
              }
        }
    }

  if (isnull)
    {
      document.getElementById('link_ul_edit').style.display = 'inline';
      document.getElementById('link_ul_null_edit').style.display = 'none';
    }
  else
    {
      document.getElementById('link_ul_edit').style.display = 'none';
      document.getElementById('link_ul_null_edit').style.display = 'inline';
    }
}

function close_xfd(xfd)
{
  var result = prompt('Result?');
  if (result)
    {
      if (result.match(/'''(.*?)'''/))
        summary = 'close discussion: ' + RegExp.$1;
      else
        {
          summary = 'close discussion: ' + result;
          result = '\'\'\'' + result + '\'\'\'';
        }
      var txt = document.editform.wpTextbox1;
      txt.value = '{{subst:' + xfd + ' top}} ' + result + '. ~~~~\n' + txt.value + '{{subst:' + xfd + ' bottom}}';
      document.editform.wpSummary.value += summary;
    }
}

function add_revert_links_history()
{
  var lk = 0, i, j, spans, user, next, tgt, revertee = '', lis, as;

  try
    {
      lk = document.getElementById('pagehistory');
    }
  catch (i)
    {
      lk = 0;
    }

  if (!lk)
    return;

  lis = lk.getElementsByTagName('li');

  for (i = 0; i < lis.length; ++i)
    {
      j = lis[i].getElementsByTagName('a');
      j[0].href = j[0].href.replace(/#.*/, '');
      if (j[0].firstChild.data == 'cur')
        j[1].href = j[1].href.replace(/#.*/, '');

      user = 0;
      spans = lis[i].getElementsByTagName('span');
      for (j = 0; j < spans.length; ++j)
        if (spans[j].getAttribute('class').indexOf('history-user') >= 0)
          {
            user = spans[j];
            break;
          }

      if (!user)
        continue;

      date = user.previousSibling.previousSibling;
      tgt = date.getAttribute('href') + '&action=edit&fakeaction=revert&fakeuser=' + user.firstChild.firstChild.data + '&fakedate=' + date.firstChild.data;
      if (revertee != '' && revertee != ' ')
        tgt += '&fakerevertee=' + revertee;
      tgt += '&faketarget=';

      //addexplicitlink(tgt + 'vandalism', 'Vnd', lis[i], date);
      //addexplicitlink(tgt + 'test', 'Tst', lis[i], date);
      //addexplicitlink(tgt + 'blanking', 'Blk', lis[i], date);
      addexplicitlink(tgt + 'edits', '[rv] ', lis[i], date);
      //pipe(lis[i], ' ', date);

      // add an invisible |, for ease of pasting into {{unsigned2}}
      var hidden = document.createElement('span');
      pipe(hidden, '|');
      hidden.setAttribute('style', 'color: #ffffec;');
      lis[i].removeChild(date.nextSibling);
      lis[i].insertBefore(hidden, date.nextSibling);

      if (revertee == '')
        revertee = user.firstChild.firstChild.data;
      else if (revertee != user.firstChild.firstChild.data)
        revertee = ' ';
    }
}

// Like document.getElementsByTagName, but finds only direct children of a given node
function node_getElementsByTagName(node, tag)
{
  var arr = new Array;
  tag = tag.toUpperCase();
  for (node = node.firstChild; node; node = node.nextSibling)
    if (node.tagName == tag)
      arr[arr.length] = node;
  return arr;
}

function recurse_guts(node, tag, arr)
{
  for (node = node.firstChild; node; node = node.nextSibling)
    {
      if (node.tagName == tag)
        arr[arr.length] = node;
      if (node.firstChild)
        recurse_guts(node, tag, arr);
    }
}

// As node_getElementsByTagName, but recurses children
function recurse_getElementsByTagName(node, tag)
{
  var arr = new Array;
  tag = tag.toUpperCase();
  recurse_guts(node, tag, arr);
  return arr;
}

function morelinks()
{
  var lk = 0, a, table, tds, td, lks, txt, deleted_edits = 0;
  try
    {
      table = document.getElementById('topbar').getElementsByTagName('table')[0];
      tds = table.getElementsByTagName('td');
      td = tds[1];
      lks = td.getElementsByTagName('a');
    }
  catch (a)
    {
      return;
    }

  // Add comment link to top, and replace Main Page with New pages
  for (a = 0; a < lks.length; ++a)
    {
      txt = lks[a].childNodes[0].data;
      if (txt == 'Main Page')
        {
          lks[a].childNodes[0].data = 'New pages';
          lks[a].setAttribute('href', '/w/index.php?title=Special:Newpages&limit=500');
        }
      else if (txt == 'Edit this page')
        {
          txt = lks[a].getAttribute('href');
          lk = lks[a + 1];
          addexplicitlink(txt + '&section=new', 'Comment', td, lk);
          pipe(td, 0, lk);
          addexplicitlink(txt + '&fakeaction=nulledit', 'null', td, lk);
          pipe(td, 0, lk);
        }
      else if (txt == 'Page history')
        {
          // Rename to 'History', add a link to Special:Undelete/pagename after it.
          lks[a].childNodes[0].data = 'History';
          txt = lks[a].getAttribute('href').replace(/&action=history$/, '').replace(/title=/, 'title=Special:Undelete/');
          addexplicitlink(txt + '&fakeaction=show_most_recent', '(show)', td, lks[a].nextSibling);
          pipe(td, ' ', lks[a].nextSibling);
          deleted_edits = addexplicitlink(txt, 'deleted');
          td.insertBefore(deleted_edits, lks[a].nextSibling);
          pipe(td, 0, lks[a].nextSibling);
          ++a;
        }
    }

  td = td.getElementsByTagName('p')[0];
  if (!td)
    return;

  var wlh = -1;
  // Handy links to reload user js and css
  if (document.title.indexOf('User:Cryptic/standard') >= 0)
    {
      pipe(td.parentNode, 0, td);
      addexplicitlink('/w/index.php?title=User:Cryptic/standard.js&action=raw&ctype=text/javascript', 'js', td.parentNode, td);
      pipe(td.parentNode, 0, td);
      addexplicitlink('/w/index.php?title=User:Cryptic/standard.css&action=raw&ctype=text/css', 'css', td.parentNode, td);
    }
  else if (document.title.indexOf('Category:') == 0 || document.title.indexOf('Image:') == 0 || (wlh = new String(document.location).indexOf('Special:Whatlinkshere')) >= 0)
    {
      pipe(td.parentNode, 0, td);
      add_id_link('javascript:link_ul_edit(true)', 'null', 'link_ul_null_edit', td.parentNode, td);
      add_id_link('javascript:link_ul_edit(false)', 'edit', 'link_ul_edit', td.parentNode, td);
      if (wlh >= 0)
        {
          var h = document.getElementsByTagName('H1')[0];
          h.parentNode.insertBefore(makebutton('Fix double redirects', 'javascript:fix_double_redirects()'), h.nextSibling);
          var title = document.getElementsByTagName('H1')[0].firstChild.data;
          set_cookie('last_whatlinkshere', title);
        }
    }

  // Remove second line, preserving 'Current revision' and 'n deleted edits' (on the first line) and 'You have new messages' (replacing (Talk) in upper right) if present
  while (td.hasChildNodes())
    {
      lk = td.firstChild;
      if (lk.nodeName == 'A' && lk.firstChild.data == 'Current revision')
        {
          a = tds[1].getElementsByTagName('p')[0];
          pipe(tds[1], 0, a);
          addexplicitlink(lk.href, 'Current', tds[1], a);
        }
      else if (lk.nodeName == 'STRONG' && lk.firstChild.data == 'You have ')
        {
          lks = tds[2].getElementsByTagName('a');
          for (a = 0; a < lks.length; ++a)
            if (lks[a].firstChild.data == 'Talk')
              {
                lks[a].firstChild.data = 'New Messages';
                lks[a].setAttribute('style', 'font-style: italic;');
                lks[a].setAttribute('href', '/w/index.php?title=User_talk:Cryptic&action=history');
              }
        }
      else if (lk.nodeType == 3 /*Node.TEXT_NODE*/ && (lk.data == ' | View ' || lk.data == ' | View or restore '))
        {
          if (deleted_edits)
            deleted_edits.firstChild.data = lk.nextSibling.firstChild.data;
          else
            {
              a = tds[1].getElementsByTagName('p')[0];
              pipe(tds[1], 0, a);
              tds[1].insertBefore(lk.nextSibling, a);
            }
        }
      td.removeChild(td.firstChild);
    }

  // Replace them
  addlink('Special:Watchlist', 'Watchlist', td);
  pipe(td);
  addlink('Special:Randompage', 'Random', td);
  pipe(td);
  addexplicitlink('/w/index.php?title=Special:Contributions&hideminor=0&target=Cryptic&limit=500&offset=0', 'Contribs', td);
  pipe(td, '/');
  addexplicitlink('/w/index.php?title=Special%3ALog&type=&user=Cryptic&page=', 'Log', td);
  pipe(td);
  addlink('Special:Specialpages', 'Special', td);

  try
    {
      var title = /^http:\/\/en\.wikipedia\.org\/(wiki\/|w\/index\.php\?title=)([^&?#]*)/.exec(decodeURI(location.href))[2].split(' ').join('_');

      if (title.indexOf('Special:') != 0)
        {
          pipe(td);
          addexplicitlink('/w/index.php?title=Special:Log&page=' + title, 'Logs', td);
          if (title.indexOf('User:') == 0 || title.indexOf('User_talk:') == 0)
            {
              var user = /^(User|User_talk):([^&?\/#]*)/.exec(title)[2];
              pipe(td);
              addexplicitlink('/w/index.php?title=Special:Log&user=' + user, 'Actions', td);
              pipe(td);
              addexplicitlink('/w/index.php?title=Special:Blockip&ip=' + user, 'Block', td);
              pipe(td, '/');
              addexplicitlink('/w/index.php?title=Special:Log&type=block&page=User:' + user, 'Log', td);
            }
        }
    }
  catch (a) {}

  var title = document.getElementsByTagName('H1')[0].firstChild.data;
  if (title.indexOf('Wikipedia:Articles for deletion/') == 0)
    {
      try
        {
          var as = recurse_getElementsByTagName(document.getElementById('article'), 'A');
          for (var i = 0; i < as.length; ++i)
            if (as[i].href)
              as[i].onclick = 'set_cookie_no_escape(\'last_afd\', \'' + escape(title) + '\')';
        }
      catch (title) {}
    }

  if ((/&action=edit/.test(window.location.href) || /&action=submit/.test(window.location.href))
      && document.title.indexOf('View and restore deleted pages') != 0)
    {
      // hide the 'Save page' button if I haven't previewed yet
      document.editform.wpSave.onclick = 'force_preview()';

      pipe(td);
      addexplicitlink('javascript:replace()', 'Replace', td);
      pipe(td);

      if (document.title.indexOf('Editing User talk:') == 0)
        {
          addexplicitlink('javascript:user_talk_template(\'test\', \'your test\')', 'Test', td);
          pipe(td);
          addexplicitlink('javascript:user_talk_template(\'test2\', \'{{test2}}\')', '2', td);
          pipe(td, '/');
          addexplicitlink('javascript:user_talk_template(\'test2a\', \'{{test2a}}\')', 'a', td);
          pipe(td);
          addexplicitlink('javascript:user_talk_template(\'test3\', \'{{test3}}\')', '3', td);
          pipe(td);
          addexplicitlink('javascript:user_talk_template(\'test4\', \'{{test4}}\')', '4', td);
          pipe(td);
          addexplicitlink('javascript:user_talk_template(\'test5\', \'{{test5}}\')', '5', td);
          //pipe(td);
          //addexplicitlink('javascript:user_talk_template(\'nothanks|\' + prompt(\'Copyvio at?\'), \'no thanks\')', 'Nothanks', td);
        }
      else if (document.title.indexOf('Editing Talk:') == 0)
        addexplicitlink('javascript:oldafdfull()', 'Oldafdfull', td);
      else if (document.title.indexOf('Editing Wikipedia:Transwiki log') == 0)
        addexplicitlink('javascript:transwiki_log()', 'Log entry', td);
      else if (document.title.indexOf('Editing Wikipedia:Votes for deletion/') == 0
               || document.title.indexOf('Editing Wikipedia:Pages for deletion/') == 0
               || document.title.indexOf('Editing Wikipedia:Articles for deletion/') == 0)
        {
          addexplicitlink('javascript:header_xfd(\'===\')', 'Header', td);
          pipe(td);
          addexplicitlink('javascript:close_xfd(\'afd\')', 'Close', td);
        }
      else if (document.title.indexOf('Editing Wikipedia:Miscellany for deletion/') == 0)
        {
          addexplicitlink('javascript:header_xfd(\'====\')', 'Header', td);
          pipe(td);
          addexplicitlink('javascript:close_xfd(\'mfd\')', 'Close', td);
        }
      else if (document.title.indexOf('Editing Wikipedia:Templates for deletion/Log/') == 0
               && new String(document.location.href).indexOf('&section=') >= 0)
        addexplicitlink('javascript:close_xfd(\'tfd\')', 'Close', td);
      else if (document.title.indexOf('Editing Wikipedia:Redirects for deletion') == 0)
        addexplicitlink('javascript:close_xfd(\'rfd\')', 'Close', td);
      else if (document.title.indexOf('Editing Image:') == 0)
        {
          addexplicitlink('javascript:template(\'no source|month={{subst:CURRENTMONTHNAME}}|day={{subst:CURRENTDAY}}|year={{subst:CURRENTYEAR}}\')', 'no source', td);
          pipe(td);
          addexplicitlink('javascript:template(\'no license|month={{subst:CURRENTMONTHNAME}}|day={{subst:CURRENTDAY}}|year={{subst:CURRENTYEAR}}\')', 'no license', td);
          pipe(td);
          addexplicitlink('javascript:template(\'orphaned fairuse not replaced|~~~~~|month={{subst:CURRENTMONTHNAME}}|day={{subst:CURRENTDAY}}|year={{subst:CURRENTYEAR}}\')', 'or-fu', td);
        }
      else
        {
          addexplicitlink('javascript:template(\'cleanup-date|{{subst:CURRENTMONTHNAME}} {{subst:CURRENTYEAR}}\')', 'cleanup', td);
          //pipe(td);
          //addexplicitlink('javascript:transwiki_to()', 'TranswikiTo', td);
          pipe(td);
          var preset_search = get_cookie('preset_search');
          var preset_replace = get_cookie('preset_replace');
          var preset_summary = get_cookie('preset_summary');
          if (preset_search && preset_summary)
            {
              addexplicitlink('javascript:preset_search_n_replace()', 's/' + preset_search + '/' + preset_replace + '/g', td);
              pipe(td, ' ');
              addexplicitlink('javascript:set_preset_search_n_replace()', '(change)', td);
            }
          else
            addexplicitlink('javascript:set_preset_search_n_replace()', 'set preset search/replace', td);

          var last_whatlinkshere = get_cookie('last_whatlinkshere');
          var last_afd = get_cookie('last_afd');
          if (last_whatlinkshere && last_afd)
            {
              pipe(td);
              addexplicitlink('javascript:unlk_per_afd()', 'unlk [[' + last_whatlinkshere + ']]', td);
            }
        }

      var action = '';
      var target = '';
      var user = '';
      var date = '';
      var revertee = '';
      if (location.search)
        {
          var l = location.search.substring(1).split('&');
          for (var i = 0; i < l.length; ++i)
            {
              var eq = l[i].indexOf('=') + 1;
              var name = l[i].substring(0, eq - 1);
              if (name == 'fakeaction')
                action = l[i].substring(eq);
              else if (name == 'faketarget')
                target = unescape(l[i].substring(eq)).replace(/_/g, ' ');
              else if (name == 'fakedate')
                date = unescape(l[i].substring(eq));
              else if (name == 'fakeuser')
                user = unescape(l[i].substring(eq));
              else if (name == 'fakerevertee')
                revertee = unescape(l[i].substring(eq));
            }
        }

      if (action == 'vfdlist')
        {
          document.editform.wpTextbox1.value += '{{Wikipedia:Articles for deletion/' + target + '}}\n';
          document.editform.wpSummary.value = '[[' + target + ']]';
        }
      else if (action == 'vfdsub')
        {
          if (document.editform.wpTextbox1.value.length > 0)
            {
              target = document.editform.action;
              target = unescape(target.substring(target.indexOf('title=') + 6, target.lastIndexOf('&action=submit'))).replace(/_/g, ' ');
              window.alert('There is an old afd at the default location already.\n\n' +
                           'Please either move it out of the way (and update existing links to it), or file the afd by hand in another location (such as [[' +
                           target + ' (2)]]).');
            }
          else
            document.editform.wpTextbox1.value += '===[[' + target + ']]===\n';
        }
      else if (action == 'nulledit')
        {
          var f = document.editform;
          //f.wpWatchthis.checked = false;
          f.wpMinoredit.checked = true;
          f.wpSummary.value = 'null edit';
          f.wpSave.onclick = '';
          f.wpSave.click();
        }
      else if (action == 'revert')
        {
          if (target == 'edits' && revertee == '')
            target = '';
          else
            target += ' ';

          var f = document.editform;
          if (revertee != '')
            f.wpSummary.value = 'rv ' + target + 'by [[Special:Contributions/' + revertee + '|' + revertee + ']] back to ' + date + ' edit by [[User:' + user + '|' + user + ']]';
          else
            f.wpSummary.value = 'rv ' + target + 'back to ' + date + ' edit by [[User:' + user + '|' + user + ']]';
          f.wpMinoredit.checked = true;

          if (target != 'edits ' && target != '')
            f.wpSave.click();
        }
      else if (action == 'fix_dbl_redir')
        {
          document.editform.wpTextbox1.value = document.editform.wpTextbox1.value.replace(/\[\[[^\]]+\]\]/, '[[' + target + ']]');
          document.editform.wpSummary.value = 'dbl redir';
          document.editform.wpMinoredit.checked = true;
          document.editform.wpDiff.click();
        }
      else
        {
          pipe(td);
          addexplicitlink('javascript:vfd()', 'Afd', td);
          pipe(td);
          addexplicitlink('javascript:prod()', 'Prod', td);
        }
    }

  // Interwiki links
  td = tds[2];
  a = td.firstChild;
  lk = new String(document.location).replace(/en.wikipedia/, 'source').replace(/Special:Whatlinkshere&target=/, '');
  interwiki(lk, td, a, 'en.wikipedia', 'W');
  interwiki(lk, td, a, 'en.wiktionary', 'd');
  interwiki(lk, td, a, 'en.wikinews', 'n');
  interwiki(lk, td, a, 'en.wikibooks', 'b');
  interwiki(lk, td, a, 'wikisource', 's');
  interwiki(lk, td, a, 'commons.wikimedia', 'c');
  interwiki(lk, td, a, 'meta.wikimedia', 'm');
  interwiki(lk, td, a, 'en.wikiquote', 'q');
}

function force_preview()
{
  if ((/&action=edit/.test(window.location.href)
       && !confirm('Are you sure you want to submit without previewing?'))
      || (window.location.href.match(/\?title=User:([^?&\/#]*)/)
          && RegExp.$1 != 'Cryptic'
          && !confirm('Hey, clueless!\n\nYou\'re editing someone else\'s user page, not their talk page.  You sure?')))
    {
      document.editform.wpSave.value = document.editform.wpPreview.value;
      document.editform.wpSave.name = 'wpPreview';
    }
}

// Change section links in vfd log pages to edit the entire subpage, instead of its section
function vfdsectionlinks(thispage)
{
  var divs = document.getElementsByTagName('div');
  var a;
  var url;
  var pos;
  for (var x = 0; x < divs.length; ++x)
    if (divs[x].className == 'editsection')
      {
        a = divs[x].getElementsByTagName('a')[0];
        url = a.getAttribute('href');
        pos = url.indexOf('action=edit&section=');
        if (pos != -1)
          {
            url = url.substring(0, pos + 11);
            if (url.indexOf(thispage) < 0)
              a.setAttribute('href', url);
          }
      }
}

function resize_editbox(delta)
{
  var tb = document.editform.wpTextbox1;
  if (delta == 1)
    switch (tb.rows)
      { // Pretty ad-hoc, but so what?
        case 5: tb.rows = 10; break;
        case 10: tb.rows = 15; break;
        case 15: tb.rows = 20; break;
        case 20: tb.rows = 25; break;
        case 25: tb.rows = 35; break;
        case 35: tb.rows = 50; break;
      }
  else if (delta == -1)
    switch (tb.rows)
      {
        case 10: tb.rows = 5; break;
        case 15: tb.rows = 10; break;
        case 20: tb.rows = 15; break;
        case 25: tb.rows = 20; break;
        case 35: tb.rows = 25; break;
        case 50: tb.rows = 35; break;
      }
  else
    {
      var div = document.createElement('div');
      div.setAttribute('style', 'text-align:center; float:right;');
      div.appendChild(makebutton('-', 'resize_editbox(-1)'));
      div.appendChild(document.createElement('br'));
      div.appendChild(makebutton('+', 'resize_editbox(1)'));
      var art = document.getElementById('article');
      if (!art)
        art = document.getElementById('bodyContent');
      art.insertBefore(div, art.firstChild);
    }
}

function cesarb_fixDiffOverflowTableCell(cell)
{
  var div = document.createElement('div');
  div.style.overflow = 'auto';
  cell.insertBefore(div, cell.firstChild);

  while (div.nextSibling)
    div.appendChild(div.nextSibling);
}

function cesarb_fixDiffOverflowTable(table)
{
  var cells = table.getElementsByTagName('td');

  for (var i = 0; i < cells.length; i++)
    {
      var cell = cells[i];
      var classes = cell.className.split(' ');

      for (var j = 0; j < classes.length; j++)
        if (classes[j] == 'diff-context' || classes[j] == 'diff-addedline' || classes[j] == 'diff-deletedline' || classes[j] == 'diff-otitle' || classes[j] == 'diff-ntitle')
          {
            cesarb_fixDiffOverflowTableCell(cell);
            break;
          }
    }
}

function cesarb_fixDiffOverflowLoadListener(evt)
{
  var tables = document.getElementsByTagName('table');

loop:
  for (var i = 0; i < tables.length; i++)
    {
      var table = tables[i];
      var classes = table.className.split(' ');

      for (var j = 0; j < classes.length; j++)
        if (classes[j] == 'diff')
          {
            cesarb_fixDiffOverflowTable(table);
            break loop;
          }
    }
}

function toggle_undelete(init)
{
  var f = document.getElementById('undelete');
  if (f)
    {
      if (init)
        {
          var h2 = f.getElementsByTagName('h2')[0];
          if (h2)
            f.insertBefore(makebutton('Invert', 'toggle_undelete(0)'), h2);
        }
      else
        {
          var inputs = f.getElementsByTagName('input');
          var i;
          for (i = 0; i < inputs.length; ++i)
            if (inputs[i].type == 'checkbox')
              inputs[i].checked = !inputs[i].checked;
        }
    }
}

function undelete_page_stuff()
{
  toggle_undelete(1);
  if (location.search)
    {
      var l = location.search.substring(1).split('&');
      for (var i = 0; i < l.length; ++i)
        {
          var eq = l[i].indexOf('=') + 1;
          var name = l[i].substring(0, eq - 1);
          if (name == 'fakeaction')
            {
              var a;
              name = l[i].substring(eq);
              //try
                {
                  if (name == 'show_most_recent')
                    {
                      a = node_getElementsByTagName(node_getElementsByTagName(document.getElementById('undelete'), 'UL')[1].firstChild, 'A')[0];
                      window.location.href = a.href + '&fakeaction=show_preview';
                    }
                  else if (name == 'show_preview')
                    {
                      var forms = document.getElementsByTagName('FORM');
                    loop:
                      for (var j = 0; j < forms.length; ++j)
                        if (forms[j].action.indexOf('Undelete') >= 0)
                          {
                            var inputs = node_getElementsByTagName(forms[j], 'INPUT');
                            for (var k = 0; k < inputs.length; ++k)
                              if (inputs[k].type == 'submit')
                                {
                                  inputs[k].click();
                                  break loop;
                                }
                          }
                    }
                }
                //catch (a) {}
              return;
            }
        }
    }
}

function delete_button(csd, txt, crit, display_orig)
{
  var f = document.getElementById('deleteconfirm');
  if (f)
    {
      if (display_orig == -1)
        {
          var pgname = document.getElementById('article').getElementsByTagName('h1')[0].nextSibling.firstChild.data;
          pgname = pgname.replace(/^\(Deleting \"/g, '');
          pgname = strip_namespace(pgname.replace(new RegExp('"\\)$', 'g'), ''));
          var table = f.getElementsByTagName('table')[0];
          var tbody = table.getElementsByTagName('tbody')[0];
          var box = tbody.getElementsByTagName('tr')[0];
          var tr = document.createElement('tr');
          var td = document.createElement('td');
          tr.appendChild(td);
          td = document.createElement('td');

          var criterion = document.createElement('span');
          criterion.id = 'criterion';
          f.appendChild(criterion);

          var orig_reason = document.createElement('span');
          orig_reason.id = 'orig_reason';
          orig_reason.style.display = 'none';
          orig_reason.appendChild(document.createTextNode(f.wpReason.value));
          f.appendChild(orig_reason);

          td.appendChild(makebutton('Default',          'delete_button(\'default\', \'\', \'\', 1)'));
          td.appendChild(makebutton('Copyvio',          'delete_button(\'\', \'Copyvio; listed on [[WP:CP]] since \', \'\', 0)'));
          td.appendChild(makebutton('RFD',              'delete_button(\'\', \'Listed on [[WP:RFD]] since ; \', \'\', 1)'));

          td.appendChild(document.createElement('br'));

          td.appendChild(makebutton('U1:subpage',       'delete_button(\'U1\', \'owner request\', \'Personal subpages, upon request by their owner.\', 1)'));
          td.appendChild(makebutton('U2:user/talk',     'delete_button(\'U2\', \'owner request\', \'User and talk pages on request of the user, where there is no significant abuse, and no administrative need to retain the page. A redirect (to the users new name, or to Wikipedia:Missing Wikipedians) should be created to avoid red links and confusion.\', 1)'));
          td.appendChild(makebutton('U3:ip talk',       'delete_button(\'U3\', \'talk page of ip; no longer relevant\', \'User talk pages of non-logged in users where the message is no longer relevant (This is to avoid confusing new users who happen to edit with that same IP address).\', 1)'));

          td.appendChild(makebutton('C1:empty',         'delete_button(\'C1\', \'empty 72 hours, no content other than parent categories\', \'Empty categories (no articles or subcategories for at least 72 hours) whose only content has consisted of links to parent categories.  Does NOT apply to categories listed on WP:CFD.\', 1)'));
          td.appendChild(makebutton('C2:rename',        'delete_button(\'C2\', \'empty, speedy rename\', \'Empty categories (no articles or subcategories) that have qualified for speedy renaming.  Must have been listed at Wikipedia:Categories_for_deletion#Speedy_renaming for a minimum of 48 hours.\', 1)'));
          td.appendChild(makebutton('C3:template',      'delete_button(\'C3\', \'populated solely by [[Template:]]\', \'If a category is solely populated from a template (e.g. Category:Wikipedia cleanup from {{cleanup}}) and the template is deleted per deletion policy, the category can also be deleted without further discussion.\', 1)'));

          td.appendChild(document.createElement('br'));

          td.appendChild(makebutton('I1:redundant',     'delete_button(\'I1\', \'redundant copy of [[:Image:]]\', \'An image which is a redundant (all pixels the same or scaled-down) copy of something else on Wikipedia and as long as all inward links have been changed to the image being retained.  Does not include images saved in a different file format or moved to Commons.\', 1)'));
          td.appendChild(makebutton('I2:corrupt',       'delete_button(\'I2\', \'corrupt or empty\', \'A corrupt or empty image.\', 1)'));
          td.appendChild(makebutton('I3:non-com/permis','delete_button(\'I3\', \'noncommercial/permission-only image\', \'Images licensed as for non-commercial use only or used with permission which were uploaded on or after May 19, 2005.\', 1)'));
          td.appendChild(makebutton('I4:source/license','delete_button(\'I4\', \'no source/unknown license\', \'Images in category Images with unknown source or Images with unknown copyright status which have been tagged with a template that places them in the category for more than 7 days, regardless of when uploaded.\', 1)'));
          td.appendChild(makebutton('I5:or-fu',         'delete_button(\'I5\', \'orphan fair use\', \'Copyrighted images uploaded without permission of the copyright holder, or under a license which does not permit commercial use, which are not used in any article, and which has been tagged with a template which places them in Category:Orphaned fairuse images for more than seven days (so-called orphaned fair use images). Reasonable exceptions may be made for images uploaded for an upcoming article. The templates {{or-fu-nr}} and {{or-fu-re}} place an image in this category.\', 1)'));

          td.appendChild(makebutton('R1:broken',        'delete_button(\'R1\', \'non-existent target\', \'They refer to non-existent pages.  Before deleting such a redirect, its a good idea to check to see if the redirect can be made useful by changing its target.\', 1)'));
          td.appendChild(makebutton('R2:userspace',     'delete_button(\'R2\', \'redirect to user: space\', \'They redirect from the main article space to the User: space.\', 1)'));
          td.appendChild(makebutton('R3:for move',      'delete_button(\'R3\', \'for page move\', \'Consensus is that it should be removed to make way for a non-controversial page move.\', 1)'));
          td.appendChild(makebutton('R4:typo',          'delete_button(\'R4\', \'typo\', \'Were created very recently as a result of a typo (during a page move or as a proactive measure).  This does not include common misspellings or misnomers, or plurals where the singular is appropriate, as redirects from those are considered useful.\', 1)'));

          td.appendChild(document.createElement('br'));

          td.appendChild(makebutton('A1:empty',         'delete_button(\'A1\', \'insufficient context\', \'Very short articles providing little or no context (e.g., He is a funny man that has created Factory and the Hacienda. And, by the way, his wife is great.). Limited content is not in itself a reason to delete if there is enough context to allow expansion.\', 1)'));
          td.appendChild(makebutton('A2:foreign',       'delete_button(\'A2\', \'foreign language article existing on another Wikimedia project\', \'Foreign language articles that already exist on another Wikimedia project, as a result of having been copied and pasted into Wikipedia after their creation elsewhere, or as a result of having been moved via the transwiki system.\', 1)'));
          td.appendChild(makebutton('A3:ext.lk',        'delete_button(\'A3\', \'zero content\', \'Any article whose contents consist only of an external link, See also section, book reference, category tag, template tag, interwiki link, or rephrasing of the title.\', 1)'));
          td.appendChild(makebutton('A4:correspond',    'delete_button(\'A3\', \'attempt to correspond\', \'Any article which consists only of attempts to correspond with the person or group named by its title.\', 1)'));
          td.appendChild(makebutton('A5:transwiki',     'delete_button(\'A5\', \'transwiki complete\', \'Any article that has been discussed at Articles for Deletion (or Miscellany for deletion), where the outcome was to transwiki, and where the transwikification has been properly performed and the author information recorded.\', 1)'));
          td.appendChild(makebutton('A6:attack',        'delete_button(\'A6\', \'article serves no purpose but to disparage its subject\', \'Articles which serve no purpose but to disparage their subject (insult pages, e.g., OMFG! Joe Random is a l0ser n00bface lolol!!!11).\', 0)'));
          td.appendChild(makebutton('A7:nnbio',         'delete_button(\'A7\', \'nnbio\', \'An article about a real person that does not assert that persons importance or significance. If the assertion is disputed or controversial, it should be taken to AFD instead. For details, see Wikipedia:Deletion of vanity articles.\', 1)'));
          td.appendChild(makebutton('A8:copyvio',       'delete_button(\'A8\', \'copyvio from \', \'An article that is a blatant copyright infringement and meets these parameters: Material is unquestionably copied from the website of a commercial content provider (e.g. encyclopedia, news service) and; The article and its entire history contains only copyright violation material, excluding tags, templates, and minor edits and; Uploader makes no assertion of permission or fair use, and none seems likely and; The material is identified within 48 hours of upload and is almost or totally un-wikified (to diminish mirror problem).  Notification: When tagging a page for deletion under this criterion, a user should notify the pages creator using wording similar to {{Nothanks-sd}} or an equivalent message. Before deleting any page under this criterion, an admin should verify that the page creator has been notifed - if not, the admin should do so. If the creator was not logged in and did not use a consistent IP address, such notification is unneeded. \', 0)'));

          td.appendChild(document.createElement('br'));

          td.appendChild(makebutton('G1:nonsense',      'delete_button(\'G1\', \'patent nonsense\', \'No meaningful content or history, text unsalvageably incoherent (e.g., random characters). This does not include: copyvios, bad writing, partisan screeds, religious excogitations, immature material, flame bait, obscene remarks, vandalism (although pure vandalism is speediable under CSD G3), badly translated material, hoaxes, or fancruft, unless the material is actually unsalvageably incoherent. Please see patent nonsense.\', 1)'));
          td.appendChild(makebutton('G2:test',          'delete_button(\'G2\', \'test page\', \'Test pages (e.g., Can I really create a page here?).\', 1)'));
          td.appendChild(makebutton('G3:vandalism',     'delete_button(\'G3\', \'vandalism\', \'Pure vandalism (see also dealing with vandalism). This includes redirects created during cleanup of page move vandalism.\', 0)'));
          td.appendChild(makebutton('G4:again',         'delete_button(\'G4\', \'repost of deleted content ([[Wikipedia:Articles for deletion/' + pgname + ']])\', \'A substantially identical copy, by any title, of a page that was deleted according to the deletion policy. Note that: Administrators faced with a recreation of previously speedily deleted content must determine that it did in fact meet a criterion for speedy deletion and had been appropriately deleted before they delete it again; and, This does not apply to content in userspace or to content undeleted according to the undeletion policy.\', 0)'));
          td.appendChild(makebutton('G5:banned',        'delete_button(\'G5\', \'created by banned [[User:]]\', \'Contributions made by a banned user after they were banned, unless the user has been unbanned. This is slightly controversial!\', 1)'));
          td.appendChild(makebutton('G6:history merge', 'delete_button(\'G6\', \'history merge\', \'Temporarily deleting a page in order to merge page histories after a cut and paste move.\', 0)'));
          td.appendChild(makebutton('G7:request',       'delete_button(\'G7\', \'author request\', \'Any page which is requested for deletion by the original author, provided the author reasonably explains that it was created by mistake, and the page was edited only by its author.\', 0)'));
          td.appendChild(makebutton('G8:orphan talk',   'delete_button(\'G8\', \'talk page of deleted page\', \'Talk pages of already deleted pages unless they contain records of the deletion discussion and are linked from Wikipedia:Archived delete debates (this doesnt apply if the deletion discussion is logged elsewhere, like an AfD sub-page or other log).\', 0)'));

          tr.appendChild(td);
          tbody.insertBefore(tr, box);
        }
      else
        {
          var criterion = document.getElementById('criterion');
          if (criterion)
            {
              while (criterion.hasChildNodes())
                criterion.removeChild(criterion.firstChild);
              if (crit)
                pipe(criterion, crit);

              var orig_reason = document.getElementById('orig_reason').firstChild.data;
              if (csd == 'default')
                f.wpReason.value = orig_reason;
              else
                {
                  var v = '';
                  if (csd != '')
                    v = '[[WP:CSD#' + csd + '|' + csd + ']]: ';
                  if (!display_orig)
                    orig_reason = '';
                  if (txt != '' && orig_reason != '')
                    txt += '; ';
                  f.wpReason.value = v + txt + orig_reason;
                }
            }
        }
    }
}

function openahah(kk)
{
  var as = document.getElementsByTagName('a');
  var j = 0, k = 0;
  ++kk;
  for (var n = 0; n < as.length; ++n)
    if (as[n].innerHTML == 'hist' && kk - k++ <= 20)
      {
        if (k <= kk)
          {
            as[n].setAttribute('class', as[n].getAttribute('class') + ' modified');
            window.open(as[n].href, '_blank');
          }
        else
          break;
      }
}

function addahah()
{
  var as = document.getElementsByTagName('a');
  var k = 0;
  for (var n = 0; n < as.length; ++n)
    {
      if (as[n].innerHTML == 'diff')
        as[n].href = as[n].href.replace(/&curid=[0-9]+/, '');
      else if (as[n].innerHTML == 'hist')
        {
          addexplicitlink('javascript:openahah(' + (k++) + ')', 'ahah', as[n].parentNode, as[n].nextSibling);
          pipe(as[n].parentNode, ') (', as[n].nextSibling);
        }
    }
}

function fix_relatedchanges()
{
  var uls = document.getElementsByTagName('ul');
  var entries = new Object;
  for (var i = 0; i < uls.length; ++i)
    if (uls[i].className && uls[i].className.indexOf('special') >= 0)
      {
        var ul = uls[i];
        var li = ul.getElementsByTagName('li');
        for (var j = 0; j < li.length; ++j)
          {
            var a = li[j].getElementsByTagName('a');
            if (a[0].firstChild.data == 'diff')
              if (entries[a[2].href] == 'y')
                li[j].style.display = 'none';
              else
                {
                  a[0].href = a[0].href.replace(/&curid=[0-9]+/, '');
                  entries[a[2].href] = 'y';
                }
          }
      }
}

var spoiler_num = 0;

function spoiler_toggle(num)
{
  var contents = document.getElementById('spoilercontents_' + num);
  var lk = document.getElementById('spoilerlk_' + num);
  if (!contents || !lk)
    return;
  if (contents.style.display == 'none')
    {
      contents.style.display = '';
      lk.replaceChild(document.createTextNode('hide'), lk.firstChild);
    }
  else
    {
      contents.style.display = 'none';
      lk.replaceChild(document.createTextNode('show'), lk.firstChild);
    }
}

function setup_spoilers()
{
  var divs = document.getElementsByTagName('div');
  var hide_initially = hide_spoilers_initially
                       && !/(\?title=|\/wiki\/)(Talk|User|Wikipedia|Image|MediaWiki|Template|Help|Category|Portal)(_talk)?:/.test(window.location.href);

  for (var i = 0; i < divs.length; ++i)
    {
      var node = divs[i];
      if (node.id != 'spoiler' || (node.className && node.className.indexOf('endspoiler') >= 0))
        continue;

      ++spoiler_num;

      pipe(node, ' ['); 
      add_id_link('javascript:spoiler_toggle(' + spoiler_num + ')', hide_initially ? 'show' : 'hide', 'spoilerlk_' + spoiler_num, node);
      pipe(node, ']'); 

      var contents = document.createElement('div');
      contents.className = 'spoilercontents';
      contents.id = 'spoilercontents_' + spoiler_num;
      if (hide_initially)
        contents.style.display = 'none';

      var depth = 0;
      while (depth >= 0)
        {
          var n = node.nextSibling;
          if (!n)
            break;
          if (n.id == 'spoiler')
            {
              if (n.className && n.className.indexOf('endspoiler') >= 0)
                {
                  if (--depth < 0 && !hide_endspoiler_tag)
                    break;
                }
              else
                ++depth;
            }
          n.parentNode.removeChild(n);
          contents.appendChild(n);
        }

        if (node.nextSibling)
          node.parentNode.insertBefore(contents, node.nextSibling);
        else
          node.parentNode.appendChild(contents);
    }
}

function old_revision_to_diffs()
{
  var node = document.getElementById('contentSub');     // monobook-like skins

  if (!node)    // classic-like skins
    {
      var h1s = document.getElementsByTagName('h1');
      for (var i = 0; i < h1s.length; ++i)
        if (h1s[i].className && h1s[i].className.indexOf('pagetitle') >= 0)
          {
            node = h1s[i].nextSibling;
            break;
          }
    }

  try
    {
      if (node
          && node.firstChild
          && node.firstChild.nodeType == 3 /*Node.TEXT_NODE*/
          && node.firstChild.data.indexOf('Revision as of') >= 0)
        {
          var as = node_getElementsByTagName(node, 'A');
          if (as[0].firstChild.data == 'view current revision')
            {
              addexplicitlink(as[1].href.replace(/&direction=prev&oldid=/, '&diff=prev&oldid='), '(diff) ', node, as[1]);
              addexplicitlink(as[2].href.replace(/&direction=next&oldid=/, '&diff=next&oldid='), ' (diff)', node);
            }
        }
    }
  catch (node) {}
}

// Changes <span id='block_this_addr'>[[User:123.45.67.89|123.45.67.89]]</span> into <span id='block_this_addr'>[[Special:Blockip/123.45.67.89|Block target IP 123.45.67.89]]</span>
function fix_proxy_block_link()
{
  var span = document.getElementById('block_this_addr');
  if (!span)
    return;
  var a = span.firstChild;
  var ip = a.firstChild.data;
  a.href = 'http://en.wikipedia.org/wiki/Special:Blockip/' + ip;
  a.className = ''; // Get rid of the ugly redlink
  pipe(a, 'Block target IP ', a.firstChild);
}

function descendent_ul(node, ancestor)
{
  return (node.parentNode.tagName == 'LI'
          && (node.parentNode.parentNode == ancestor
              || (node.parentNode.parentNode.tagName == 'UL' && descendent_ul(node.parentNode.parentNode, ancestor))));
}

function fix_double_redirects()
{
  var a, i, li, uls = document.getElementsByTagName('UL'), title = escape(document.getElementsByTagName('H1')[0].firstChild.data);
  for (i = 1; i < uls.length; ++i)
    if (descendent_ul(uls[i], uls[0]))
      for (li = uls[i].firstChild; li; li = li.nextSibling)
        if (li.tagName == 'LI'
            && (a = li.firstChild).tagName == 'A'
            && a.href.indexOf('&redirect=no') >= 0)
          window.open(a.href + '&action=edit&fakeaction=fix_dbl_redir&faketarget=' + title, '_blank');
}

function top_edit_lk()
{
  var divs = document.getElementsByTagName('DIV');
  for (var i = 0; i < divs.length; ++i)
    if (divs[i].className.indexOf('editsection') >= 0)
      {
        var div = document.createElement('DIV');
        div.className = divs[i].className;
        div.setAttribute('style', divs[i].getAttribute('style'));
        //document.location.href.match(/^(http:\/\/[^/]+/w)(iki/|/index\.php\?title=)([^&?]+)/);
        document.location.href.match(new RegExp('^(http://[^/]+/w)(iki/|/index\\.php\\?title=)([^&?]+)', ''));
        var title = RegExp.$3;
        div.innerHTML = divs[i].innerHTML.replace(/&action=edit&section=[0-9]+/, '&action=edit&section=0');
        title = document.getElementsByTagName('H1')[0];
        title.parentNode.insertBefore(div, title.nextSibling);
        return;
      }
}

function fix_lks_to_afd()
{
  // Make sure all links to afd are of the /w/index.php form, not /wiki/
  var as = document.getElementsByTagName('A');
  var afdre = new RegExp('^http://en.wikipedia.org/wiki/Wikipedia:Articles_for_deletion', '');
  for (var i = 0; i < as.length; ++i)
    if (as[i].href)
      as[i].href = new String(as[i].href).replace(afdre, 'http://en.wikipedia.org/w/index.php?title=Wikipedia:Articles_for_deletion');
}

function do_onload()
{
  if (new RegExp('^http://en.wikipedia.org/wiki/Wikipedia:Articles_for_deletion', '').test(window.location))
    {
      window.location = new String(window.location).replace(new RegExp('/wiki/', ''), '/w/index.php?title=');
      return;
    }
  fix_lks_to_afd();
  setup_spoilers();
  cesarb_fixDiffOverflowLoadListener();
  top_edit_lk();
  morelinks();
  if (document.title.indexOf('Editing ') == 0)
    {
      resize_editbox(0);
      document.editform.wpSummary.setAttribute('style', 'width:100%');
    }
  else if (document.title == 'My watchlist - Wikipedia, the free encyclopedia')
    addahah();
  else if (document.title == 'Related changes - Wikipedia, the free encyclopedia')
    fix_relatedchanges();
  else if (document.title.indexOf('Wikipedia:Articles for deletion/Log/2') != -1)
    vfdsectionlinks('Wikipedia:Articles for deletion/Log/2');
  else if (document.title.indexOf('Wikipedia:Featured picture candidates') != -1)
    vfdsectionlinks('/w/index.php?title=Wikipedia:Featured_picture_candidates&action=edit');
  else if (document.title == 'View and restore deleted pages - Wikipedia, the free encyclopedia')
    undelete_page_stuff(1);
  else if (document.title == 'Confirm delete - Wikipedia, the free encyclopedia')
    delete_button('', '', '', -1);
  else if (document.title == 'Block user - Wikipedia, the free encyclopedia' && !/action=success/.test(document.location))
    document.getElementById('blockip').wpBlock.parentNode.appendChild(makebutton('Log', 'javascript:window.location.href=\'http://en.wikipedia.org/w/index.php?title=Special:Log&type=block&page=User:\' + document.getElementById(\'blockip\').wpBlockAddress.value.split(\' \').join(\'_\');'));
  else if (document.title.indexOf('User:Cryptic/sandbox2') == 0)
    fix_proxy_block_link();
  add_revert_links_history();
  old_revision_to_diffs();
}

$(do_onload);
//</nowiki></pre>




// [[User:Lupin/popups.js]]

mw.loader.load(
             'https://en.wikipedia.org/w/index.php?title=User:Lupin/popups.js'
             + '&action=raw&ctype=text/javascript&dontcountme=s');