User:Omegatron/monobook.js/quarl.js

/* */ /* module.js */

// $Id: module.js 1367 2006-03-22 06:02:44Z quarl $

// module.js - dependency tracking

// quarl 2006-02-07 initial version

var $module = new Object;

// can be a URL prefix or a User:Wikipedia prefix $module.options = { // auto_load: "http://wikipedia.quarl.org/scripts/" auto_load: null };

var Module = $module.Module = function(name) { if (!(this instanceof $module.Module)) { return new $module.Module(name); }

if (typeof(name) != 'string') { alert("$module.Module: need name (error 7e05c98d-b55c-4e1f-a48a-170d7bcb63a8)"); return void(0); }

this.module = { name: name }; $module.provide(this.module.name, this); return this; }

$module.Module.prototype.depend = function { var l;   for (var i = 0; i < arguments.length; ++i) { if (!(l=$module.depend1(arguments[i], this))) return null; }   return l; }

$module.Module.prototype.inherit = function(parent) { // allow string name of parent, because the module might not yet be loaded // at this point var parent0 = parent; if (typeof(parent) == 'string') { parent = window[parent]; }   if (!parent) { alert($module.msgpfx(child) + "Can't inherit from " + parent0); return; }   for (var v in parent) { if (v == 'module') continue; if (typeof(this[v]) == 'undefined') child[v] = parent[v]; } }

$module.Module.prototype.alert = function(msg) { window.alert(this.module.name + ': ' + msg); }

// requires msg.js $module.Module.prototype.error = function(msg) { return $msg.error('(' + this.module.name + ') ' + msg); }

// requires msg.js $module.Module.prototype.warning = function(msg) { return $msg.warning('(' + this.module.name + ') ' + msg); }

// requires msg.js $module.Module.prototype.debug = function(msg) { return $msg.debug('(' + this.module.name + ') ' + msg); }

$module.modules = {};

$module.provide = function(s, t) { $module.modules[s] = (t || 1); }

$module.msgpfx = function(t) { return (t && t.module && t.module.name) ? ("$module (" + t.module.name + "): ") : "$module: "; }

$module.depend = function { var l;   for (var i = 0; i < arguments.length; ++i) { if (!(l=$module.depend1(arguments[i], null))) return null; }   return l; }

$module.depend1 = function(s, t) { var m = $module.modules[s]; if (!m) { if ($module.options.auto_load) { $module.loadScript($module._makeScriptUrl(s));

m = $module.modules[s]; if (!m) { alert($module.msgpfx(t) + "Error loading module '"+s+"'"); return false; }       } else { if (!$module.options.auto_load && s.match(/[.]css$/)) { // XXX TODO: check document.styleSheets return; }           alert($module.msgpfx(t) + "Error, depends on '"+s+"', but not yet loaded (error 05ceb474-86ec-49ac-833f-89a5d77130bc)"); }   }    return m; }

$module.loadScript = function(s) { if (s.match(/[.]js$/)) { document.write('');   } else if (s.match(/[.]css$/)) {        document.write('' + s + '";'); // TODO: use document.styleSheets; test with .href $module.modules[s] = 1; } else { alert("$module.loadScript: unknown type (error 32326eb9-095b-4f21-ba23-1bda4d6091fe)"); } }

$module._makeScriptUrl = function(t, ns) { ns = ns || $module.options.auto_load; if (ns.match(/^(http|ftp):/)) { return ns + '/' + t;   } else if (ns.match(/^\[\[(.*)\]\]$/)) { var page = RegExp.$1 + '/' + t;       if (ns.match(/[.]js$/)) { return ('/w/index.php?title=' + page +                   '&action=raw&ctype=text/javascript&dontcountme=s'); } else if (ns.match(/[.]css$/)) { return ('/w/index.php?title=' + page +                   '&action=raw&ctype=text/css&dontcountme=s'); } else { return ('/w/index.php?title=' + page); }   } else { alert("Unknown value for ns (error 01b7cf1a-f746-4c93-8992-b0542a2f54c3)"); return null; } }

/* datetime.js */ // $Id: datetime.js 1236 2006-02-24 11:35:23Z quarl $

// datetime.js - date/time utility functions

var $datetime = new Module('datetime.js');

// return N days ago (default today) $datetime.previousDay = function(days) { days = days || 0; var d = new Date; d.setDate(d.getDate - days); // automatically wraps as necessary return d; }

$datetime.L2 = function(x) { if (x < 0) return ""+x; if (x < 10) return "0"+x; return ""+x; }

$datetime.L3 = function(x) { if (x < 0) return ""+x; if (x < 10) return "00"+x; if (x < 100) return "0"+x; return ""+x; }

$datetime.datestampUTCISO = function(d) { d = d || new Date; return ("" +           d.getUTCFullYear + '-' +            $datetime.L2(d.getUTCMonth+1) + '-' +            $datetime.L2(d.getUTCDate)); }

$datetime.timestampUTCISO = function(d) { d = d || new Date; return ($datetime.L2(d.getUTCHours) + ':' +           $datetime.L2(d.getUTCMinutes)); }

$datetime.logtimestamp = function(d) { d = d || new Date;

return ($datetime.L2(d.getHours) + ':' +           $datetime.L2(d.getMinutes) + ':' +            $datetime.L2(d.getSeconds) + '.' +            $datetime.L3(d.getTime % 100)); }

$datetime.monthnames = [ "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December" ];

$datetime.datestampYYYYMonthD = function(d) { d = d || new Date; return ("" +           d.getUTCFullYear + ' ' +            $datetime.monthnames[d.getUTCMonth] + ' ' +            d.getUTCDate); }

$datetime.datestampMonthYYYY = function(d) { d = d || new Date; return ("" +           $datetime.monthnames[d.getUTCMonth] + ' ' +            d.getUTCFullYear); }

// from Lupin's popups $datetime.formatAge = function(age) { var addunit = function(num,str) { return  + num + ' ' + str + ((num!=1) ? 's' : ) ; }

// coerce into a number age = 0 + age; var a = age;

var seclen  = 1000; var minlen  = 60*seclen; var hourlen = 60*minlen; var daylen  = 24*hourlen; var weeklen = 7*daylen;

var numweeks = (a-a%weeklen)/weeklen; a = a-numweeks*weeklen; var sweeks = addunit(numweeks, 'week'); var numdays = (a-a%daylen)/daylen;   a = a-numdays*daylen;   var sdays  = addunit(numdays,  'day'); var numhours = (a-a%hourlen)/hourlen; a = a-numhours*hourlen; var shours = addunit(numhours, 'hour'); var nummins = (a-a%minlen)/minlen;   a = a-nummins*minlen;   var smins  = addunit(nummins,  'minute'); var numsecs = (a-a%seclen)/seclen;   a = a-numsecs*seclen;   var ssecs  = addunit(numsecs,  'second');

if (age > 4*weeklen) { return sweeks; } if (age > weeklen)  { return sweeks + ' ' + sdays; } if (age > daylen)   { return sdays  + ' ' + shours; } if (age > 6*hourlen) { return shours; } if (age > hourlen)  { return shours + ' ' + smins; } if (age > 10*minlen) { return smins; } if (age > minlen)   { return smins  + ' ' + ssecs; } return ssecs; }

/* msg.js */

// $Id: msg.js 1267 2006-02-25 08:30:54Z quarl $

// error, warning, debug functions

// quarl 2006-02-20 initial version

var $msg = new Module('msg.js'); $msg.depend('msg.css'); $msg.depend('datetime.js');

$msg.options = { // debug log is only pruned if it grows larger than this. debuglogsize: 500 };

$msg.alert_disabled = false; $msg.debuglog = [];

$msg.alert = function(msg) { $msg.debug(msg); if ($msg.alert_disabled) return void(0); msg += "\nPress CANCEL to disable alerts for this page (they will still be visible in the debug log)"; if (!window.confirm(msg)) { $msg.alert_disabled = true; }   return void(0); }

$msg.error = function(msg) { $msg.alert(msg); // dummy try/catch to automatically interrupt if running under debugger // (kind of like a built-in breakpoint) try { throw 0; } catch(e) {}; return void(0); }

$msg.warning = function(msg) { $msg.alert(msg); return void(0); }

$msg.debug = function(msg) { msg = '[' + $datetime.logtimestamp + '] ' + msg;

$msg.debuglog.push(msg);

// if it's way over budget, delete until we're at budget if ($msg.debuglog.length > $msg.options.debuglogsize * 1.5) { $msg.debuglog.splice(0, $msg.debuglog.length-$msg.options.debuglogsize); } }

$msg.debug("-- Initializing Wikipedia Power Toolkit --");

/* util.js */

// $Id: util.js 1351 2006-03-08 22:24:43Z quarl $

// util.js - miscellaneous utility functions for Wikipedia user scripts

// quarl 2006-01-09 initial version

// NON-NAMESPACED FUNCTION NAMES ARE DEPRECATED

var $util = new Module('util.js'); $util.depend('msg.js');

///////////////////////////////////////////////////////////// // MISCELLANEOUS FUNCTIONS

// $util.defineClass = function(constructor, functions) { //    var c = constructor; //    c.prototype = functions; //    return c; // }

$util.merge = function(o, params) { if (!params) return o;   for (var p in params) { o[p] = params[p]; }   return o; }

$util.copyArray = function(a, i) { var r = []; i = i || 0; for (i < a.length; i++) { r.push(a[i]); }   return r; }

$util.assocArray = function(x) { for (var i in x) { x[ x[i] ] = 1; }   return x; }

// flatten an array $util.flatten = function(list, start) { var ret=[]; if (typeof start == 'undefined') start=0; for (var i=start; i<list.length; ++i) { if (typeof list[i] == typeof []) { return ret.concat($util.flatten(list[i])).concat($util.flatten(list, i+1)); }       else ret.push(list[i]); }   return ret; };

$util.bindThis = function(this_, method) { return function { return method.apply(this_, arguments); }; }

$util.callHooks = function(callbacks) { var args = $util.copyArray(arguments, 1); for (var i in callbacks) { var callback = callbacks[i]; callback.apply(callback, args); } }

$util.hookEventObj = function(obj, hookName, hookFunct) { if (!obj) return;

if (obj.addEventListener) obj.addEventListener(hookName, hookFunct, false); else if (obj.attachEvent) obj.attachEvent("on" + hookName, hookFunct); }

// wikibits.js:addOnloadHook does almost exactly what we want. Its primary // feature is it runs at the end of loading rather than after loading, so the // user does not see the page before running the hooks. // // The disadvantage is its buggy behavior if any of the hooks thrown an // exception: the entire list of hooks is re-run, producing poor results like // multiple tabs.

$util._onloadFunctions = [];

$util._runOnloadHooks = function { $util.debug("Running onload hooks..."); if ($util._onloadFunctions == null) return; // Using a while loop in this manner ensures that if we queue up more // hooks during _runOnloadHooks, they get queued at the end, and also if   // we raise an exception for some reason, we don't re-run the entire list. while ($util._onloadFunctions.length) { try { $util._onloadFunctions[0] ; } catch(e) { var s = $util._onloadFunctions[0].toString; $util.error("_runOnloadHooks: Error in onload hook '"+$util.strAbbrev(s,297)+"': " + e); }       $util._onloadFunctions.shift; }   $util._onloadFunctions = null; $util.debug("Running onload hooks... done."); }

// This is more robust than wikibits.js's addOnloadHook. That version uses an // array of fuctions; if there is an error, the hook functions sometimes get // re-run. $util.addOnloadHook = function(f) { if (!f) { $util.error("$util.addOnloadHook: no function given! (error 0a0fb885-97fb-4089-b7c5-90f0be7d5abc)"); return; }

if ($util._onloadFunctions == null) { // we've already finished _runOnloadHooks, so just run f now. // TODO: any advantage to doing setTimeout(f, 0) here? f; } else { $util._onloadFunctions.push(f); // $util.hookEventObj(window, "load", f); }

// setTimeout is NOT a good alternative to addEventListener. The reason // is that timeout functions are called too soon: since the tag // is before the main body content, we don't yet see that content at time // of setTimeout.

// setTimeout(f, 0); };

// use wikibits.js's onload hook system to invoke ours. addOnloadHook($util._runOnloadHooks);

$util.addOnunloadHook = function(f) { $util.hookEventObj(window, 'unload', f); }

// conditional func eval $util.funkyval = function(x) { if (typeof(x) == 'function') { x = x; }   return x; }

///////////////////////////////////////////////////////////// // STRING UTILITY FUNCTIONS

$util.trimSpaces = function(s) { if (!s) return s;   s = s.replace(/^\s+/,''); s = s.replace(/\s+$/,''); return s; }

$util.trimLines = function(s) { return s.replace(/^\n+/, ).replace(/\n+$/, ); }

$util.removeAnchor = function(s) { return s.replace(/(?:#|%23).*/, ''); }

$util.reverseString = function(s) { var ret = ''; for (var i = s.length-1; i >= 0; --i) { ret += s[i]; }   return ret; }

$util.strAbbrev = function(s, n) { if (!s) return s;   if (s.length <= n) return s;    return s.substr(0, n-3) + '...'; }

$util.wordCount = function(t) { return t.split(/\s+/).length; }

$util.stringQuoteEscape = function(str) { if (!str) return str; return "'" + str.replace(/\'/g, '\\\).replace(/\%27/g, '\\\) + "'"; }

$util.reEscape = function(str) { return str.replace(RegExp('([-.\\+?*^${}\\[\\]])', 'g'), '\\$1'); };

// wiki article name escaping $util.wpaEscape = function(s) { if (!s) return s;   // encodeURIComponent is better than 'escape' for unicode chars; // it also escapes '+'. // Don't escape ':' return encodeURIComponent(s.replace(/ /g,'_')).replace(/%3A/g,':').replace(/%2F/g,'/'); }

$util.wpaDecode = function(s) { return decodeURIComponent(s).replace(/_/g,' '); }

// from Scriptaculous $util.escapeHTML = function(s) { var div = document.createElement('div'); var text = document.createTextNode(s); div.appendChild(text); return div.innerHTML; };

// from Scriptaculous $util.unescapeHTML = function { var div = document.createElement('div'); div.innerHTML = this.stripTags; return div.childNodes[0] ? div.childNodes[0].nodeValue : ''; };

$util.urlGetPath = function(s) { return s.replace(/^http:\/\/[^\/]+/, ''); }

// from Lupin's popups: // String.prototype.parenSplit should do what ECMAscript says // String.prototype.split does, interspersing paren matches between // the split elements

if (String('abc'.split(/(b)/))!='a,b,c') { // broken String.split, e.g. konq, IE   String.prototype.parenSplit=function (re) { var m=re.exec(this); if (!m) return [this]; // without the following loop, we have // 'ab'.parenSplit(/a|(b)/) != 'ab'.split(/a|(b)/) for(var i=0; i "Hello, my name is Quarl" $util.printf = function(fmt) { var r = ''; var s = fmt.split('%s'); for (var i = 1; i < s.length; ++i) { r += s[i-1]; r += (i < arguments.length) ? arguments[i] : '%s'; }   r += s[s.length-1]; return r; };

// e.g. $util.printf("$1, my name is $2", "Hello", "Quarl") //               => "Hello, my name is Quarl" $util.pprintf = function(fmt) { // start at last argument in case we have more than 9 arguments for (var i = arguments.length; i >= 1; --i) { fmt = fmt.replace(new RegExp('\\$' + i,'g'), arguments[i]); }   return fmt; };

// similar to pprintf; takes an array which is the result of a String.match. // Starts at $0 instead of $1. // e.g. $util.mprintf("$1, my name is $2", 'Hello Quarl'.match(/(.+) (.+)/)) //                => "Hello, my name is Quarl" // Useful when String.replace cannot be used. $util.mprintf = function(fmt, m) { for (var i = m.length; i >= 0; --i) { fmt = fmt.replace(new RegExp('\\$' + i,'g'), m[i]); }   return fmt; }

$util.capitalizeFirstChar = function(s) { if (!s) return s;   return s[0].toUpperCase + s.substr(1); };

$util.describeCharCount = function(s) { if (s == null) return '(null)'; return "[" + s.length + " chars]"; }

// replaces all occurrences of RE with REPL, returning {str:str, count:count} $util.reReplaceAll = function(str, re, repl) {   re = new RegExp(re); var m;   var result = ''; var count = 0; while ( (m=str.match(re)) ) { str = RegExp.rightContext; result += RegExp.leftContext; result += m[0].replace(re, repl); ++count; }   result += str; return { str: result, count: count }; };

$util.regexpNotGlobal = function(re) { var opts = ''; if (re.ignoreCase) opts += 'i'; if (re.multiline) opts += 'm'; return new RegExp(re.source, opts); }

// like regular String.replace, but takes a lambda for replacement func String.prototype.replacef = function(re, func) { if (!(re instanceof RegExp)) re = new RegExp(re); str = this; var m;   var result = ''; if (re.global) { re = $util.regexpNotGlobal(re); while ( (m=str.match(re)) ) { str = RegExp.rightContext; result += RegExp.leftContext; result += func(m); }       result += str; return result; } else { if ( (m=str.match(re)) ) { str = RegExp.rightContext; result += RegExp.leftContext; result += func(m); result += str; return result; } else { return str; }   } };

//////////////////////////////////////////////////////////// // DOM UTILITY FUNCTIONS $util.getElementsByClass = function(searchClass, node, tag) { var classElements = []; if (node == null) node = document; if (tag == null) tag = '*'; var els = node.getElementsByTagName(tag); var elsLen = els.length; var pattern = new RegExp("(^|\\s)"+searchClass+"(\\s|$)"); for (var i = 0; i < elsLen; i++) { if (pattern.test(els[i].className) ) { classElements.push(els[i]); }   }    return classElements; }

$util.findDescendantById = function(node, id) { if (node.id == id) { return node; } for (var i = node.firstChild; i != null; i=i.nextSibling) { var c = $util.findDescendantById(i,id); if (c != null) return c;   } return null; }

$util.isDescendent = function(node, ancestorNode, cachePropertyName) { if (typeof node[cachePropertyName] != 'undefined') { return node[cachePropertyName]; }

if (node == ancestorNode) { return node[cachePropertyName] = true; }

if (!node.parentNode) { return node[cachePropertyName] = false; }

return node[cachePropertyName] = $util.isDescendent(       node.parentNode, ancestorNode, cachePropertyName); };

$util.addClass = function(node, cls) { node.className += ' '+cls; }

$util.removeClass = function(node, cls) { node.className = node.className.replace(       new RegExp("(^|\\s)"+cls+"(\\s|$)",'g'), ' '); }

$util.addNodeBefore = function(node, newnode) { node.parentNode.insertBefore(newnode, node); return newnode; }

$util.addNodeAfter = function(node, newnode) { if (node.nextSibling) { node.parentNode.insertBefore(newnode, node.nextSibling); } else { node.parentNode.appendChild(newnode); }   return newnode; }

// return nodes in [node_start, node_end) $util.getNodesInRange = function(node_start, node_end) {   var nodes = [];    while (node_start != node_end) {        nodes.push(node_start);        node_start = node_start.nextSibling;        if (!node_start) return null; // didn't reach node_end!    }    return nodes; }

$util.removeNodesInRange = function(node_start, node_end) { if (!node_end) { $util.error("## removeNodesInRange: node_end==null"); return null; }   if (!$util.getNodesInRange(node_start, node_end)) { $util.error("## removeNodesInRange: range does not terminate"); return null; }   var parent = node_start.parentNode; var count = 0; while (node_start != node_end) { ++count; var n = node_start.nextSibling; // save before it gets clobbered parent.removeChild(node_start); node_start = n;       if (!node_start) return null; }   return count; }

$util.createHref = function(href, title, inner) { var a = document.createElement('a'); a.href = href; a.title = title; a.innerHTML = inner; return a; }

$util.findHref = function(href) { href = $util.wpaEscape($util.wpaDecode(href)); var links=document.links; for(i=0;i<links.length;++i) { // unescape and reescape to ensure canonical escaping if ($util.wpaEscape($util.wpaDecode(links[i].href)) == href) return links[i]; }   return null; }

// insert a new node as parent of node $util.insertNode = function(node, newNode) { if (!node) return null;

node.parentNode.replaceChild(newNode, node); newNode.appendChild(node); return newNode; }

$util.appendChildren = function(node, newNodes) { for (var i in newNodes) { node.appendChild(newNodes[i]); } }

// add a span around a node if there isn't one. $util.ensureSpan = function(node) { if (node.parentNode.nodeName == 'SPAN') { return node.parentNode; }   return $util.insertNode(node, document.createElement('span')); }

//////////////////////////////////////////////////////////// // STYLESHEET FUNCTIONS $util.addStylesheetRule = function(tag, style) { var ss = document.styleSheets[0]; if (ss.insertRule) { ss.insertRule(tag + '{' + style + '}', ss.cssRules.length); } else if (ss.addRule) { ss.addRule(tag, style); } }

//////////////////////////////////////////////////////////// // AJAX FUNCTIONS

// cross-platform $util.HTTPClient = function { 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; }

$util.asyncDownloadXML = function(url, callback, props) { var req = $util.HTTPClient; if (!req) return null; // add optional arguments if (props) { for (var k in props) { req[k] = props[k]; }   }

var args = $util.copyArray(arguments, 2);

req.open("GET", url, true); // TODO: another way to parse XML is to create a div and then set its // innerHTML to the responseText -- this may be more reliable than // overrideMimeType. req.overrideMimeType('text/xml'); if (callback) { // using onload instead of onreadystatechange allows multiple asynchronous requests // TODO: since we now have access to 'req' as a variable, we could change back. // Is there any advantage to using onreadystatechange? req.onload = function(event) { var req = event.target; args[0] = req; if (req.readyState == 4) callback.apply(event, args); };   }    req.send(null); return req; }

// doesn't try to parse as XML $util.asyncDownloadText = function(url, callback, props) { var req = $util.HTTPClient; if (!req) return null; // add optional arguments if (props) { for (var k in props) { req[k] = props[k]; }   }

var args = $util.copyArray(arguments, 2);

req.open("GET", url, true); req.overrideMimeType('text/plain'); req.onload = function(event) { var req = event.target; args[0] = req; if (req.readyState == 4) callback.apply(event, args); };   req.send(null); return req; }

$util.buildParams = function(paramArray) { var params = ''; for (k in paramArray) { v = paramArray[k]; // if v is a Boolean then the form was a checkbox. // unchecked checkboxes should not add any input fields. if (v == false) continue; if (v == true) v = 'on'; params += '&' + k + '=' + encodeURIComponent(v); }   params = params.replace(/^&/,''); return params; }

$util.addFormHiddenParams = function(newform, d) { for (var k in d) { v = d[k]; // if v is a Boolean then the form was a checkbox. // unchecked checkboxes should not add any input fields. if (v == false) continue; if (v == true) v = 'on'; var t = document.createElement('input'); t.type = 'hidden'; t.name = k;       t.value = d[k]; newform.appendChild(t); }   return newform; }

$util.asyncPostXML = function(url, parameters, callback, props) { var req = $util.HTTPClient; if (!req) return null; if (typeof parameters != 'string') parameters = $util.buildParams(parameters); // add optional arguments if (props) { for (var k in props) { req[k] = props[k]; }   }

var args = $util.copyArray(arguments, 2);

req.open("POST", url, true); req.overrideMimeType('text/xml'); req.setRequestHeader("Content-type", "application/x-www-form-urlencoded"); req.setRequestHeader("Content-length", parameters.length); req.setRequestHeader("Connection", "close"); req.onload = function(event) { var req = event.target; args[0] = req; if (req.readyState == 4) callback.apply(event, args); };   req.send(parameters); return req; }

// Temporarily replace the content of statusNode with a non-clicakble, bolded string // that shows we're doing something. statusNode should be the node that completely wraps // an  element that was just clicked (e.g. a ) $util.buttonShowStatus = function(statusNode, statusText) { if (!statusNode) return;

if (!statusText) { // use  tag to keep padding/margin/color/etc. statusText = ''+statusNode.textContent+'...'; }

// Note: saving innerHTML doesn't work if we've messed with the document // tree.

// statusNode.savedContent = statusNode.innerHTML; // statusNode.innerHTML = statusText;

// save content (but don't clobber it if we're called again before buttonRestoreStatus) if (!statusNode.savedContent) { statusNode.savedContent = $util.copyArray(statusNode.childNodes); }   statusNode.innerHTML = statusText; }

$util.buttonRestoreStatus = function(statusNode, tempStatusText) { if (tempStatusText) { // temporarily show a string indicating success, and after a while, reset. $util.buttonShowStatus(statusNode, tempStatusText); setTimeout(function { $util.buttonRestoreStatus(statusNode); }, 10000); return; }

if (statusNode && statusNode.savedContent) { // statusNode.innerHTML = statusNode.savedContent; statusNode.innerHTML = ''; $util.appendChildren(statusNode, statusNode.savedContent); } }

//////////////////////////////////////////////////////////// // UI FUNCTIONS

$util.eventLeftButtonP = function(e) { if (typeof(e.which) != 'undefined') return e.which == 1;   // Mozilla if (typeof(e.button) != 'undefined') return (e.button | 1); // IE   return null; }

/* wikiwidget.js */

// $Id: wikiwidget.js 1351 2006-03-08 22:24:43Z quarl $

// originally based on // http://en.wikipedia.org/wiki/Wikipedia:WikiProject_User_scripts/Scripts/Add_LI_link

var $wikiwidget = new Module('wikiwidget.js'); $wikiwidget.depend('wikiwidget.css'); $wikiwidget.depend('util.js');

$wikiwidget.getPortlet0 = function(n) { return document.getElementById(n).getElementsByTagName('ul')[0]; }

// this is monobook-specific $wikiwidget.portlet_names = { 'Personal':'p-personal', 'Actions': 'p-cactions', 'Navigation': 'p-navigation', 'Toolbox': 'p-tb' // 'Search': 'p-search' };

$wikiwidget._load = function { $wikiwidget.portlets = {}; for (var n in $wikiwidget.portlet_names) { $wikiwidget.portlets[n] = $wikiwidget.getPortlet0($wikiwidget.portlet_names[n]); } }

$wikiwidget.getPortlet = function(n) { if (!$wikiwidget.portlets) { $wikiwidget.error("## getPortlet: not yet initialized?! (error 0b8ab92b-8f67-425b-b1eb-2485aa8265af)"); return null; }   return $wikiwidget.portlets[n]; }

// add a node at a location. If it's a regular node, then append to location // as parent. If it's {after:node}, then insert after node. $wikiwidget._fancyAdd = function(location, newNode) { if (typeof(location) == 'function') { location = location; }   if (location['portlet']) { var portlet = $wikiwidget.getPortlet(location['portlet']); portlet.appendChild(newNode); } else if (location['after']) { var after = location['after']; if (typeof(after) == 'string') { after = document.getElementById(after); }       if (!after) { $wikiwidget.error("couldn't get location to add after (error 6e8df341-9ee6-4ada-9d44-42a8e600d87c)"); return; }       if (after.nextSibling) { after.parentNode.insertBefore(newNode, after.nextSibling); } else { after.parentNode.appendChild(newNode); }   } else if (location && location.appendChild) { location.appendChild(newNode); } else { $wikiwidget.error("must specify location to add (error bb4c83cf-8ab6-4cc3-a2c0-f9fc53f66dbb)"); } }

var WikiWidget = $wikiwidget.WikiWidget = function(params) { $util.merge(this, params); this.add = $util.bindThis(this, this.add_); }

$wikiwidget.WikiWidget.prototype.add_ = function(location) { $wikiwidget.debug("WikiWidget.add: " +                     {id:this.id, entry:this.entry, name:this.name,                              url:this.url, title:this.title}.toSource); location = location || this.default_location; var li = this.li = document.createElement('li'); if (this.id) li.id = this.id; if (this.className) li.className = this.className;

if (typeof(this.entry) == 'string') { li.innerHTML = this.entry; } else if (this.entry) { li.appendChild(this.entry); } else if (this.name) { var na = document.createElement('a'); if (this.url) { na.href = this.url; }       if (this.onclick) { na.onclick = this.onclick; if (!na.href) { na.href = "javascript:void 0"; }       }        na.appendChild(document.createTextNode(this.name)); li.appendChild(na); } else { $wikiwidget.error("WikiWidget.add: invalid WikiWidget (error aed67c57-3bba-47e0-9b7f-e8d420c7eeea)"); }

$wikiwidget._fancyAdd(location, li);

if (this.id && (this.key || this.title) && window.ta) { ta[this.id] = [(this.key||), (this.title||)]; $wikiwidget._scheduleAkeytt; }   return li; }

$wikiwidget.WikiWidget.prototype.showStatus = function(statusText) { $util.buttonShowStatus(this.li, statusText); }

$wikiwidget.WikiWidget.prototype.hideStatus = function(statusText) { $util.buttonHideStatus(this.li, statusText); }

// Re-render the title and access keys. Since we add many tabs onLoad, don't // call akeytt a unnecessarily -- just call it once after we're done loading. $wikiwidget._scheduled_akeytt = false; $wikiwidget._scheduleAkeytt = function { if (!$wikiwidget._scheduled_akeytt) { $wikiwidget._scheduled_akeytt = true; setTimeout(function { akeytt; $wikiwidget._scheduled_akeytt = false; }, 0); } }

$wikiwidget._toggleMenu = function { var mn = this.nextSibling; if (!mn || typeof(mn.displayState) != 'boolean') { $wikiwidget.error("## invalid target for $wikiwidget._toggleMenu (error f66282ae-0762-4c90-8b5d-f095909cb786)"); return; }

if ( (mn.displayState = !mn.displayState) ) { // new state: display mn.className += ' sticky'; } else { // new state: hide mn.className = mn.className.replace(/(^| )sticky/, ''); } }

$wikiwidget.addTabMenu = function(name, id) {   var parent = $wikiwidget.getPortletTabActions;

var na = document.createElement('a'); na.href = 'javascript:void(0)'; na.appendChild(document.createTextNode(name)); na.onclick = $wikiwidget._toggleMenu;

var mn = document.createElement('ul'); mn.displayState = false;

var li = document.createElement('li'); li.id = id; li.className = 'tabmenu'; li.appendChild(na); li.appendChild(mn); parent.appendChild(li); return mn; }

// deprecated: $wikiwidget.addLiLinkX = function(location, entry, id, title, key){ new $wikiwidget.WikiWidget({entry: entry, id: id, title: title, key: key}).add(location); }

// deprecated: $wikiwidget.addLiLink = function(location, url, name, id, title, key) { new $wikiwidget.WikiWidget({url: url, name: name, id: id, title: title, key: key}).add(location); }

// deprecated: $wikiwidget.getPortletPersonal = function { return $wikiwidget.getPortlet('Personal'); } // deprecated: $wikiwidget.getPortletTabActions = function { return $wikiwidget.getPortlet('Actions'); } // deprecated: $wikiwidget.getPortletNavigation = function { return $wikiwidget.getPortlet('Navigation'); } // deprecated: $wikiwidget.getPortletToolbox = function { return $wikiwidget.getPortlet('Toolbox'); }

// deprecated: $wikiwidget.addTab = function(url, name, id, title, key) { return new $wikiwidget.WikiWidget({url: url, name: name, id: id, title: title, key: key}).add({portlet:'Actions'}); }

// deprecated: $wikiwidget.addToolboxLink = function(url, name, id, title, key) { return new $wikiwidget.WikiWidget({url: url, name: name, id: id, title: title, key: key}).add({portlet:'Toolbox'}); }

// deprecated: $wikiwidget.addNavigationLink = function(url, name, id, title, key) { return new $wikiwidget.WikiWidget({url: url, name: name, id: id, title: title, key: key}).add({portlet:'Navigation'}); }

$util.addOnloadHook($wikiwidget._load);

/* wikins.js */

// -*- coding:utf-8 -*- // $Id: wikins.js 1241 2006-02-24 11:57:26Z quarl $

// define internationalized namespace strings

// $wikins.namespaceTalk maps English non-Talk namespace to Talk namespace // $wikins.namespaceNoTalk maps English Talk namespace to non-Talk namespace

// $wikins.namespaces maps local names to English // $wikins.namespaceNames maps English to local names

// $wikins.User_talk == $wikins.namespaceNames['User talk']

// e.g. on de.wikipedia.org:

// $wikins.User_talk == 'Benutzerseite Diskussion' // $wikins.namespaceNames['User talk'] == 'Benutzerseite Diskussion' // $wikins.namespaces['Benutzerseite Diskussion'] == 'User talk'

// originally from Lupin's popups

var $wikins = new Module('wikins.js');

$wikins.namespacesEnglish = ["Media", "Special", "Talk", "User", "User talk", "Wikipedia", "Wikipedia talk", "Image", "Image talk", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk", "Portal", "Portal talk"];

$wikins.namespaceTalk = { ""         : "Talk", "User"     : "User talk", "Wikipedia" : "Wikipedia talk", "Image"    : "Image talk", "MediaWiki" : "MediaWiki talk", "Template" : "Template talk", "Help"     : "Help talk", "Category" : "Category talk", "Portal"   : "Portal talk" };

$wikins.namespaceNoTalk = { "Talk"          : "", "User talk"     : "User", "Wikipedia talk" : "Wikipedia", "Image talk"    : "Image", "MediaWiki talk" : "MediaWiki", "Template talk" : "Template", "Help talk"     : "Help", "Category talk" : "Category", "Portal talk"   : "Portal" };

$wikins.getNS = function(lang) { switch(lang) { case "en": return $wikins.namespacesEnglish; case "af": return ["Media", "Spesiaal", "Bespreking", "Gebruiker", "Gebruikerbespreking", "Wikipedia", "Wikipediabespreking", "Beeld", "Beeldbespreking", "MediaWiki", "MediaWikibespreking", "Sjabloon", "Sjabloonbespreking", "Hulp", "Hulpbespreking", "Kategorie", "Kategoriebespreking"]; case "als": return ["Media", "Spezial", "Diskussion", "Benutzer", "Benutzer Diskussion", "Wikipedia", "Wikipedia Diskussion", "Bild", "Bild Diskussion", "MediaWiki", "MediaWiki Diskussion", "Vorlage", "Vorlage Diskussion", "Hilfe", "Hilfe Diskussion", "Kategorie", "Kategorie Diskussion"]; case "ar": return ["Ù…Ù„Ù", "Ø®Ø§Øµ", "Ù†Ù‚Ø§Ø´", "Ù…Ø³ØªØ®Ø¯Ù…", "Ù†Ù‚Ø§Ø´ Ø§Ù„Ù…Ø³ØªØ®Ø¯Ù…", "ÙˆÙŠÙƒÙŠØ¨ÙŠØ¯ÙŠØ§", "Ù†Ù‚Ø§Ø´ ÙˆÙŠÙƒÙŠØ¨ÙŠØ¯ÙŠØ§", "ØµÙˆØ±Ø©", "Ù†Ù‚Ø§Ø´ Ø§Ù„ØµÙˆØ±Ø©", "Ù…ÙŠØ¯ÙŠØ§ÙˆÙŠÙƒÙŠ", "Ù†Ù‚Ø§Ø´ Ù…ÙŠØ¯ÙŠØ§ÙˆÙŠÙƒÙŠ", "Template", "Ù†Ù‚Ø§Ø´ Template", "Ù…Ø³Ø§Ø¹Ø¯Ø©", "Ù†Ù‚Ø§Ø´ Ø§Ù„Ù…Ø³Ø§Ø¹Ø¯Ø©", "ØªØµÙ†ÙŠÙ", "Ù†Ù‚Ø§Ø´ Ø§Ù„ØªØµÙ†ÙŠÙ"]; case "ast": return ["Media", "Especial", "DiscusiÃ³n", "Usuariu", "Usuariu discusiÃ³n", "Uiquipedia", "Uiquipedia discusiÃ³n", "Imaxen", "Imaxen discusiÃ³n", "MediaWiki", "MediaWiki discusiÃ³n", "Plantilla", "Plantilla discusiÃ³n", "Ayuda", "Ayuda discusiÃ³n", "CategorÃ­a", "CategorÃ­a discusiÃ³n"]; case "be": return ["ÐœÑÐ´Ñ‹Ñ", "Ð¡Ð¿ÑÑ†Ñ‹ÑÐ»ÑŒÐ½Ñ‹Ñ", "ÐÐ±Ð¼ÐµÑ€ÐºÐ°Ð²Ð°Ð½ÑŒÐ½Ðµ", "Ð£Ð´Ð·ÐµÐ»ÑŒÐ½Ñ–Ðº", "Ð“ÑƒÑ‚Ð°Ñ€ÐºÑ– ÑžÐ´Ð·ÐµÐ»ÑŒÐ½Ñ–ÐºÐ°", "Ð’Ñ–ÐºÑ–Ð¿ÑÐ´Ñ‹Ñ", "ÐÐ±Ð¼ÐµÑ€ÐºÐ°Ð²Ð°Ð½ÑŒÐ½Ðµ Ð’Ñ–ÐºÑ–Ð¿ÑÐ´Ñ‹Ñ", "Ð’Ñ‹ÑÐ²Ð°", "ÐÐ±Ð¼ÐµÑ€ÐºÐ°Ð²Ð°Ð½ÑŒÐ½Ðµ Ð²Ñ‹ÑÐ²Ñ‹", "MediaWiki", "ÐÐ±Ð¼ÐµÑ€ÐºÐ°Ð²Ð°Ð½ÑŒÐ½Ðµ MediaWiki", "Ð¨Ð°Ð±Ð»Ñ‘Ð½", "ÐÐ±Ð¼ÐµÑ€ÐºÐ°Ð²Ð°Ð½ÑŒÐ½Ðµ ÑˆÐ°Ð±Ð»Ñ‘Ð½Ñƒ", "Ð”Ð°Ð¿Ð°Ð¼Ð¾Ð³Ð°", "ÐÐ±Ð¼ÐµÑ€ÐºÐ°Ð²Ð°Ð½ÑŒÐ½Ðµ Ð´Ð°Ð¿Ð°Ð¼Ð¾Ð³Ñ–", "ÐšÐ°Ñ‚ÑÐ³Ð¾Ñ€Ñ‹Ñ", "ÐÐ±Ð¼ÐµÑ€ÐºÐ°Ð²Ð°Ð½ÑŒÐ½Ðµ ÐºÐ°Ñ‚ÑÐ³Ð¾Ñ€Ñ‹Ñ–"]; case "bg": return ["ÐœÐµÐ´Ð¸Ñ", "Ð¡Ð¿ÐµÑ†Ð¸Ð°Ð»Ð½Ð¸", "Ð‘ÐµÑÐµÐ´Ð°", "ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ»", "ÐŸÐ¾Ñ‚Ñ€ÐµÐ±Ð¸Ñ‚ÐµÐ» Ð±ÐµÑÐµÐ´Ð°", "Ð£Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ", "Ð£Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ Ð±ÐµÑÐµÐ´Ð°", "ÐšÐ°Ñ€Ñ‚Ð¸Ð½ÐºÐ°", "ÐšÐ°Ñ€Ñ‚Ð¸Ð½ÐºÐ° Ð±ÐµÑÐµÐ´Ð°", "ÐœÐµÐ´Ð¸ÑÐ£Ð¸ÐºÐ¸", "ÐœÐµÐ´Ð¸ÑÐ£Ð¸ÐºÐ¸ Ð±ÐµÑÐµÐ´Ð°", "Ð¨Ð°Ð±Ð»Ð¾Ð½", "Ð¨Ð°Ð±Ð»Ð¾Ð½ Ð±ÐµÑÐµÐ´Ð°", "ÐŸÐ¾Ð¼Ð¾Ñ‰", "ÐŸÐ¾Ð¼Ð¾Ñ‰ Ð±ÐµÑÐµÐ´Ð°", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ Ð±ÐµÑÐµÐ´Ð°"]; case "bm": return ["Media", "Special", "Discuter", "Utilisateur", "Discussion Utilisateur", "Wikipedia", "Discussion Wikipedia", "Image", "Discussion Image", "MediaWiki", "Discussion MediaWiki", "ModÃ¨le", "Discussion ModÃ¨le", "Aide", "Discussion Aide", "CatÃ©gorie", "Discussion CatÃ©gorie"]; case "bn": return ["à¦¬à¦¿à¦¶à§‡à¦·", "à¦†à¦²à¦¾à¦ª", "à¦¬à§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€", "à¦¬à§à¦¯à¦¬à¦¹à¦¾à¦°à¦•à¦¾à¦°à§€ à¦†à¦²à¦¾à¦ª", "à¦‰à¦‡à¦•à¦¿à¦ªà§‡à¦¡à¦¿à¦¯à¦¼à¦¾", "à¦‰à¦‡à¦•à¦¿à¦ªà§‡à¦¡à¦¿à¦¯à¦¼à¦¾ à¦†à¦²à¦¾à¦ª", "à¦šà¦¿à¦¤à§à¦°", "à¦šà¦¿à¦¤à§à¦° à¦†à¦²à¦¾à¦ª", "MediaWik i à¦†à¦²à¦¾à¦ª", "Media", "MediaWiki", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "br": return ["Media", "Dibar", "Kaozeal", "Implijer", "Kaozeadenn Implijer", "Wikipedia", "Kaozeadenn Wikipedia", "Skeudenn", "Kaozeadenn Skeudenn", "MediaWiki", "Kaozeadenn MediaWiki", "Patrom", "Kaozeadenn Patrom", "Skoazell", "Kaozeadenn Skoazell", "Rummad", "Kaozeadenn Rummad"]; case "ca": return ["Media", "Especial", "DiscussiÃ³", "Usuari", "Usuari DiscussiÃ³", "ViquipÃ¨dia", "ViquipÃ¨dia DiscussiÃ³", "Imatge", "Imatge DiscussiÃ³", "MediaWiki", "MediaWiki DiscussiÃ³", "Template", "Template DiscussiÃ³", "Ajuda", "Ajuda DiscussiÃ³", "Categoria", "Categoria DiscussiÃ³"]; case "cs": return ["MÃ©dia", "SpeciÃ¡lnÃ­", "Diskuse", "Wikipedista", "Wikipedista diskuse", "Wikipedie", "Wikipedie diskuse", "Soubor", "Soubor diskuse", "MediaWiki", "MediaWiki diskuse", "Å ablona", "Å ablona diskuse", "NÃ¡povÄ›da", "NÃ¡povÄ›da diskuse", "Kategorie", "Kategorie diskuse"]; case "csb": return ["Media", "SpecjalnÃ´", "DiskÃ¹sÃ«jÃ´", "BrÃ«kÃ²wnik", "DiskÃ¹sÃ«jÃ´ brÃ«kÃ²wnika", "Wiki", "DiskÃ¹sÃ«jÃ´ Wiki", "Ã’brÃ´zk", "DiskÃ¹sÃ«jÃ´ Ã²brÃ´zkÃ³w", "MediaWiki", "DiskÃ¹sÃ«jÃ´ MediaWiki", "SzablÃ³na", "DiskÃ¹sÃ«jÃ´ SzablÃ³nÃ«", "PÃ²mÃ²c", "DiskÃ¹sÃ«jÃ´ PÃ²mÃ²cÃ«", "KategÃ²rÃ«jÃ´", "DiskÃ¹sÃ«jÃ´ KategÃ²rÃ«ji"]; case "cv": return ["ÐœÐµÐ´Ð¸Ð°", "Ð¯Ñ‚Ð°Ñ€Ð»Äƒ", "Ð¡Ó³Ñ‚ÑÐµ ÑÐ²Ð°ÑÑÐ¸", "Ð¥ÑƒÑ‚ÑˆÄƒÐ½Ð°ÐºÐ°Ð½", "Ð¥ÑƒÑ‚ÑˆÄƒÐ½Ð°ÐºÐ°Ð½ÄƒÐ½ ÐºÐ°Ð½Ð°ÑˆÐ»Ñƒ ÑÑ‚Ñ€Ð°Ð½Ð¸Ñ†Ð¸", "Wikipedia", "0", "Ó²ÐºÐµÑ€Ñ‡Ä•Ðº", "Ó²ÐºÐµÑ€Ñ‡Ä•ÐºÐµ ÑÓ³Ñ‚ÑÐµ ÑÐ²Ð¼Ð°Ð»Ð»Ð¸", "MediaWiki", "MediaWiki ÑÓ³Ñ‚ÑÐµ ÑÐ²Ð¼Ð°Ð»Ð»Ð¸", "Ð¨Ð°Ð±Ð»Ð¾Ð½", "Ð¨Ð°Ð±Ð»Ð¾Ð½Ð° ÑÓ³Ñ‚ÑÐµ ÑÐ²Ð¼Ð°Ð»Ð»Ð¸", "ÐŸÑƒÐ»ÄƒÑˆÑƒ", "ÐŸÑƒÐ»ÄƒÑˆÄƒÐ²Ð° ÑÓ³Ñ‚ÑÐµ ÑÐ²Ð¼Ð°Ð»Ð»Ð¸", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð½Ðµ ÑÓ³Ñ‚ÑÐµ ÑÐ²Ð¼Ð°Ð»Ð»Ð¸"]; case "cy": return ["Media", "Arbennig", "Sgwrs", "Defnyddiwr", "Sgwrs Defnyddiwr", "Wicipedia", "Sgwrs Wicipedia", "Delwedd", "Sgwrs Delwedd", "MediaWiki", "Sgwrs MediaWiki", "Nodyn", "Sgwrs Nodyn", "Help", "Help talk", "Category", "Category talk"]; case "da": return ["Media", "Speciel", "Diskussion", "Bruger", "Bruger diskussion", "Wikipedia", "Wikipedia diskussion", "Billede", "Billede diskussion", "MediaWiki", "MediaWiki diskussion", "Skabelon", "Skabelon diskussion", "HjÃ¦lp", "HjÃ¦lp diskussion", "Kategori", "Kategori diskussion"]; case "de": return ["Media", "Spezial", "Diskussion", "Benutzer", "Benutzer Diskussion", "Wikipedia", "Wikipedia Diskussion", "Bild", "Bild Diskussion", "MediaWiki", "MediaWiki Diskussion", "Vorlage", "Vorlage Diskussion", "Hilfe", "Hilfe Diskussion", "Kategorie", "Kategorie Diskussion", "Portal", "Portal Diskussion"]; case "el": return ["ÎœÎ­ÏƒÎ¿Î½", "Î•Î¹Î´Î¹ÎºÏŒ", "Î£Ï…Î¶Î®Ï„Î·ÏƒÎ·", "Î§ÏÎ®ÏƒÏ„Î·Ï‚", "Î£Ï…Î¶Î®Ï„Î·ÏƒÎ· Ï‡ÏÎ®ÏƒÏ„Î·", "Î’Î¹ÎºÎ¹Ï€Î±Î¯Î´ÎµÎ¹Î±", "Î’Î¹ÎºÎ¹Ï€Î±Î¯Î´ÎµÎ¹Î± ÏƒÏ…Î¶Î®Ï„Î·ÏƒÎ·", "Î•Î¹ÎºÏŒÎ½Î±", "Î£Ï…Î¶Î®Ï„Î·ÏƒÎ· ÎµÎ¹ÎºÏŒÎ½Î±Ï‚", "MediaWiki", "MediaWiki talk", "Î ÏÏŒÏ„Ï…Ï€Î¿", "Î£Ï…Î¶Î®Ï„Î·ÏƒÎ· Ï€ÏÎ¿Ï„ÏÏ€Î¿Ï…", "Î’Î¿Î®Î¸ÎµÎ¹Î±", "Î£Ï…Î¶Î®Ï„Î·ÏƒÎ· Î²Î¿Î®Î¸ÎµÎ¹Î±Ï‚", "ÎšÎ±Ï„Î·Î³Î¿ÏÎ¯Î±", "Î£Ï…Î¶Î®Ï„Î·ÏƒÎ· ÎºÎ±Ï„Î·Î³Î¿ÏÎ¯Î±Ï‚"]; case "eo": return ["Media", "Speciala", "Diskuto", "Vikipediisto", "Vikipediista diskuto", "Vikipedio", "Vikipedio diskuto", "Dosiero", "Dosiera diskuto", "MediaWiki", "MediaWiki diskuto", "Åœablono", "Åœablona diskuto", "Helpo", "Helpa diskuto", "Kategorio", "Kategoria diskuto"]; case "es": return ["Media", "Especial", "DiscusiÃ³n", "Usuario", "Usuario DiscusiÃ³n", "Wikipedia", "Wikipedia DiscusiÃ³n", "Imagen", "Imagen DiscusiÃ³n", "MediaWiki", "MediaWiki DiscusiÃ³n", "Plantilla", "Plantilla DiscusiÃ³n", "Ayuda", "Ayuda DiscusiÃ³n", "CategorÃ­a", "CategorÃ­a DiscusiÃ³n"]; case "et": return ["Meedia", "Eri", "Arutelu", "Kasutaja", "Kasutaja arutelu", "Vikipeedia", "Vikipeedia arutelu", "Pilt", "Pildi arutelu", "MediaWiki", "MediaWiki arutelu", "Mall", "Malli arutelu", "Juhend", "Juhendi arutelu", "Kategooria", "Kategooria arutelu"]; case "eu": return ["Media", "Aparteko", "Eztabaida", "Lankide", "Lankide eztabaida", "Wikipedia", "Wikipedia eztabaida", "Irudi", "Irudi eztabaida", "MediaWiki", "MediaWiki eztabaida", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "fa": return ["Ù…Ø¯ÛŒØ§", "ÙˆÛŒÚ˜Ù‡", "Ø¨Ø­Ø«", "Ú©Ø§Ø±Ø¨Ø±", "Ø¨Ø­Ø« Ú©Ø§Ø±Ø¨Ø±", "ÙˆÛŒÚ©ÛŒâ€ŒÙ¾Ø¯ÛŒØ§", "Ø¨Ø­Ø« ÙˆÛŒÚ©ÛŒâ€ŒÙ¾Ø¯ÛŒØ§", "ØªØµÙˆÛŒØ±", "Ø¨Ø­Ø« ØªØµÙˆÛŒØ±", "Ù…Ø¯ÛŒØ§ÙˆÛŒÚ©ÛŒ", "Ø¨Ø­Ø« Ù…Ø¯ÛŒØ§ÙˆÛŒÚ©ÛŒ", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "fi": return ["Media", "Toiminnot", "Keskustelu", "KÃ¤yttÃ¤jÃ¤", "Keskustelu kÃ¤yttÃ¤jÃ¤stÃ¤", "Wikipedia", "Keskustelu Wikipediasta", "Kuva", "Keskustelu kuvasta", "MediaWiki", "MediaWiki talk", "Malline", "Keskustelu mallineesta", "Ohje", "Keskustelu ohjeesta", "Luokka", "Keskustelu luokasta"]; case "fo": return ["MiÃ°il", "Serstakur", "Kjak", "BrÃºkari", "BrÃºkari kjak", "Wikipedia", "Wikipedia kjak", "Mynd", "Mynd kjak", "MidiaWiki", "MidiaWiki kjak", "Fyrimynd", "Fyrimynd kjak", "HjÃ¡lp", "HjÃ¡lp kjak", "BÃ³lkur", "BÃ³lkur kjak"]; case "fr": return ["Media", "Special", "Discuter", "Utilisateur", "Discussion Utilisateur", "WikipÃ©dia", "Discussion WikipÃ©dia", "Image", "Discussion Image", "MediaWiki", "Discussion MediaWiki", "ModÃ¨le", "Discussion ModÃ¨le", "Aide", "Discussion Aide", "CatÃ©gorie", "Discussion CatÃ©gorie", "Portail", "Discussion Portail"]; case "fur": return ["Media", "SpeciÃ¢l", "Discussion", "Utent", "Discussion utent", "Vichipedie", "Discussion Vichipedie", "Figure", "Discussion figure", "MediaWiki", "Discussion MediaWiki", "Model", "Discussion model", "Jutori", "Discussion jutori", "Categorie", "Discussion categorie"]; case "fy": return ["Media", "Wiki", "Oerlis", "Meidogger", "Meidogger oerlis", "Wikipedy", "Wikipedy oerlis", "Ofbyld", "Ofbyld oerlis", "MediaWiki", "MediaWiki oerlis", "Berjocht", "Berjocht oerlis", "Hulp", "Hulp oerlis", "Kategory", "Kategory oerlis"]; case "ga": return ["MeÃ¡n", "Speisialta", "PlÃ©", "ÃšsÃ¡ideoir", "PlÃ© ÃºsÃ¡ideora", "VicipÃ©id", "PlÃ© VicipÃ©ide", "ÃomhÃ¡", "PlÃ© Ã­omhÃ¡", "MediaWiki", "PlÃ© MediaWiki", "TeimplÃ©ad", "PlÃ© teimplÃ©id", "Cabhair", "PlÃ© cabhrach", "CatagÃ³ir", "PlÃ© catagÃ³ire"]; case "gu": return ["Media", "Special", "Talk", "User", "User talk", "àªµàª¿àª•àª¿àªªà«€àª¡àª¿àª¯àª¾", "àªµàª¿àª•àª¿àªªà«€àª¡àª¿àª¯àª¾ talk", "Image", "Image talk", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "he": return ["Media", "×ž×™×•×—×“", "×©×™×—×”", "×ž×©×ª×ž×©", "×©×™×—×ª ×ž×©×ª×ž×©", "×•×™×§×™×¤×“×™×”", "×©×™×—×ª ×•×™×§×™×¤×“×™×”", "×ª×ž×•× ×”", "×©×™×—×ª ×ª×ž×•× ×”", "MediaWiki", "×©×™×—×ª MediaWiki", "×ª×‘× ×™×ª", "×©×™×—×ª ×ª×‘× ×™×ª", "×¢×–×¨×”", "×©×™×—×ª ×¢×–×¨×”", "×§×˜×’×•×¨×™×”", "×©×™×—×ª ×§×˜×’×•×¨×™×”"]; case "hi": return ["Media", "à¤µà¤¿à¤¶à¥‡à¤·", "à¤µà¤¾à¤°à¥à¤¤à¤¾", "à¤¸à¤¦à¤¸à¥à¤¯", "à¤¸à¤¦à¤¸à¥à¤¯ à¤µà¤¾à¤°à¥à¤¤à¤¾", "à¤µà¤¿à¤•à¤¿à¤ªà¥€à¤¡à¤¿à¤¯à¤¾", "à¤µà¤¿à¤•à¤¿à¤ªà¥€à¤¡à¤¿à¤¯à¤¾ à¤µà¤¾à¤°à¥à¤¤à¤¾", "à¤šà¤¿à¤¤à¥à¤°", "à¤šà¤¿à¤¤à¥à¤° à¤µà¤¾à¤°à¥à¤¤à¤¾", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "à¤¶à¥à¤°à¥‡à¤£à¥€", "à¤¶à¥à¤°à¥‡à¤£à¥€ à¤µà¤¾à¤°à¥à¤¤à¤¾", "Help", "Help talk"]; case "hr": return ["Mediji", "Posebno", "Razgovor", "Suradnik", "Razgovor sa suradnikom", "Wikipedia", "Razgovor Wikipedia", "Slika", "Razgovor o slici", "MediaWiki", "MediaWiki razgovor", "PredloÅ¾ak", "Razgovor o predloÅ¡ku", "PomoÄ‡", "Razgovor o pomoÄ‡i", "Kategorija", "Razgovor o kategoriji"]; case "hu": return ["MÃ©dia", "SpeciÃ¡lis", "Vita", "User", "User vita", "WikipÃ©dia", "WikipÃ©dia vita", "KÃ©p", "KÃ©p vita", "MediaWiki", "MediaWiki vita", "Sablon", "Sablon vita", "SegÃ­tsÃ©g", "SegÃ­tsÃ©g vita", "KategÃ³ria", "KategÃ³ria vita"]; case "ia": return ["Media", "Special", "Discussion", "Usator", "Discussion Usator", "Wikipedia", "Discussion Wikipedia", "Imagine", "Discussion Imagine", "MediaWiki", "Discussion MediaWiki", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "id": return ["Media", "Istimewa", "Bicara", "Pengguna", "Bicara Pengguna", "Wikipedia", "Pembicaraan Wikipedia", "Gambar", "Pembicaraan Gambar", "MediaWiki", "Pembicaraan MediaWiki", "Templat", "Pembicaraan Templat", "Bantuan", "Pembicaraan Bantuan", "Kategori", "Pembicaraan Kategori"]; case "is": return ["MiÃ°ill", "KerfissÃ­Ã°a", "Spjall", "Notandi", "Notandaspjall", "Wikipedia", "Wikipediaspjall", "Mynd", "Myndaspjall", "Melding", "Meldingarspjall", "SniÃ°", "SniÃ°aspjall", "HjÃ¡lp", "HjÃ¡lparspjall", "Flokkur", "Flokkaspjall"]; case "it": return ["Media", "Speciale", "Discussione", "Utente", "Discussioni utente", "Wikipedia", "Discussioni Wikipedia", "Immagine", "Discussioni immagine", "MediaWiki", "Discussioni MediaWiki", "Template", "Discussioni template", "Aiuto", "Discussioni aiuto", "Categoria", "Discussioni categoria"]; case "ja": return ["Media", "ç‰¹åˆ¥", "ãƒŽãƒ¼ãƒˆ", "åˆ©ç”¨è€…", "åˆ©ç”¨è€…â€ä¼šè©±", "Wikipedia", "Wikipediaâ€ãƒŽãƒ¼ãƒˆ", "ç”»åƒ", "ç”»åƒâ€ãƒŽãƒ¼ãƒˆ", "MediaWiki", "MediaWikiâ€ãƒŽãƒ¼ãƒˆ", "Template", "Templateâ€ãƒŽãƒ¼ãƒˆ", "Help", "Helpâ€ãƒŽãƒ¼ãƒˆ", "Category", "Categoryâ€ãƒŽãƒ¼ãƒˆ"]; case "ka": return ["áƒ›áƒ”áƒ“áƒ˜áƒ", "áƒ¡áƒžáƒ”áƒªáƒ˜áƒáƒšáƒ£áƒ áƒ˜", "áƒ’áƒáƒœáƒ®áƒ˜áƒšáƒ•áƒ", "áƒ›áƒáƒ›áƒ®áƒ›áƒáƒ áƒ”áƒ‘áƒ”áƒšáƒ˜", "áƒ›áƒáƒ›áƒ®áƒ›áƒáƒ áƒ”áƒ‘áƒ”áƒšáƒ˜ áƒ’áƒáƒœáƒ®áƒ˜áƒšáƒ•áƒ", "áƒ•áƒ˜áƒ™áƒ˜áƒžáƒ”áƒ“áƒ˜áƒ", "áƒ•áƒ˜áƒ™áƒ˜áƒžáƒ”áƒ“áƒ˜áƒ áƒ’áƒáƒœáƒ®áƒ˜áƒšáƒ•áƒ", "áƒ¡áƒ£áƒ áƒáƒ—áƒ˜", "áƒ¡áƒ£áƒ áƒáƒ—áƒ˜ áƒ’áƒáƒœáƒ®áƒ˜áƒšáƒ•áƒ", "áƒ›áƒ”áƒ“áƒ˜áƒáƒ•áƒ˜áƒ™áƒ˜", "áƒ›áƒ”áƒ“áƒ˜áƒáƒ•áƒ˜áƒ™áƒ˜ áƒ’áƒáƒœáƒ®áƒ˜áƒšáƒ•áƒ", "áƒ—áƒáƒ áƒ’áƒ˜", "áƒ—áƒáƒ áƒ’áƒ˜ áƒ’áƒáƒœáƒ®áƒ˜áƒšáƒ•áƒ", "áƒ“áƒáƒ®áƒ›áƒáƒ áƒ”áƒ‘áƒ", "áƒ“áƒáƒ®áƒ›áƒáƒ áƒ”áƒ‘áƒ áƒ’áƒáƒœáƒ®áƒ˜áƒšáƒ•áƒ", "áƒ™áƒáƒ¢áƒ”áƒ’áƒáƒ áƒ˜áƒ", "áƒ™áƒáƒ¢áƒ”áƒ’áƒáƒ áƒ˜áƒ áƒ’áƒáƒœáƒ®áƒ˜áƒšáƒ•áƒ"]; case "ko": return ["Media", "íŠ¹ìˆ˜ê¸°ëŠ¥", "í† ë¡ ", "ì‚¬ìš©ìž", "ì‚¬ìš©ìží† ë¡ ", "ìœ„í‚¤ë°±ê³¼", "ìœ„í‚¤ë°±ê³¼í† ë¡ ", "ê·¸ë¦¼", "ê·¸ë¦¼í† ë¡ ", "ë¶„ë¥˜", "ë¶„ë¥˜í† ë¡ ", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk"]; case "ku": return ["Medya", "Taybet", "NÃ®qaÅŸ", "BikarhÃªner", "BikarhÃªner nÃ®qaÅŸ", "WÃ®kÃ®pediya", "WÃ®kÃ®pediya nÃ®qaÅŸ", "WÃªne", "WÃªne nÃ®qaÅŸ", "MediaWiki", "MediaWiki nÃ®qaÅŸ", "Åžablon", "Åžablon nÃ®qaÅŸ", "AlÃ®karÃ®", "AlÃ®karÃ® nÃ®qaÅŸ", "KategorÃ®", "KategorÃ® nÃ®qaÅŸ"]; case "la": return ["Specialis", "Disputatio", "Usor", "Disputatio Usoris", "Vicipaedia", "Disputatio Vicipaediae", "Imago", "Disputatio Imaginis", "MediaWiki", "Disputatio MediaWiki", "Formula", "Disputatio Formulae", "Auxilium", "Disputatio Auxilii", "Categoria", "Disputatio Categoriae", "Media"]; case "li": return ["Media", "Speciaal", "Euverlik", "Gebroeker", "Euverlik gebroeker", "Wikipedia", "Euverlik Wikipedia", "Aafbeilding", "Euverlik afbeelding", "MediaWiki", "Euverlik MediaWiki", "Sjabloon", "Euverlik sjabloon", "Help", "Euverlik help", "Kategorie", "Euverlik kategorie"]; case "lt": return ["Medija", "Specialus", "Aptarimas", "Naudotojas", "Naudotojo aptarimas", "Wikipedia", "Wikipedia aptarimas", "Vaizdas", "Vaizdo aptarimas", "MediaWiki", "MediaWiki aptarimas", "Å ablonas", "Å ablono aptarimas", "Pagalba", "Pagalbos aptarimas", "Kategorija", "Kategorijos aptarimas"]; case "mk": return ["ÐœÐµÐ´Ð¸Ñ˜Ð°", "Ð¡Ð¿ÐµÑ†Ð¸Ñ˜Ð°Ð»Ð½Ð¸", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€", "ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº", "ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€", "Wikipedia", "Wikipedia Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€", "Ð¡Ð»Ð¸ÐºÐ°", "Ð¡Ð»Ð¸ÐºÐ° Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€", "ÐœÐµÐ´Ð¸Ñ˜Ð°Ð’Ð¸ÐºÐ¸", "ÐœÐµÐ´Ð¸Ñ˜Ð°Ð’Ð¸ÐºÐ¸ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€", "Ð¨Ð°Ð±Ð»Ð¾Ð½", "Ð¨Ð°Ð±Ð»Ð¾Ð½ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€", "ÐŸÐ¾Ð¼Ð¾Ñˆ", "ÐŸÐ¾Ð¼Ð¾Ñˆ Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð° Ñ€Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€"]; case "ms": return ["Media", "Istimewa", "Perbualan", "Pengguna", "Perbualan Pengguna", "Wikipedia", "Perbualan Wikipedia", "Imej", "Imej Perbualan", "MediaWiki", "MediaWiki Perbualan", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "mt": return ["Media", "Special", "Talk", "User", "User talk", "Wikipedija", "Wikipedija talk", "Image", "Image talk", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "nap": return ["Media", "Speciale", "Discussione", "Utente", "Discussioni utente", "Wikipedia", "Discussioni Wikipedia", "Immagine", "Discussioni immagine", "MediaWiki", "Discussioni MediaWiki", "Template", "Discussioni template", "Aiuto", "Discussioni aiuto", "Categoria", "Discussioni categoria"]; case "nds": return ["Media", "Spezial", "Diskuschoon", "Bruker", "Bruker Diskuschoon", "Wikipedia", "Wikipedia Diskuschoon", "Bild", "Bild Diskuschoon", "MediaWiki", "MediaWiki Diskuschoon", "VÃ¶rlaag", "VÃ¶rlaag Diskuschoon", "HÃ¼lp", "HÃ¼lp Diskuschoon", "Kategorie", "Kategorie Diskuschoon"]; case "nl": return ["Media", "Speciaal", "Overleg", "Gebruiker", "Overleg gebruiker", "Wikipedia", "Overleg Wikipedia", "Afbeelding", "Overleg afbeelding", "MediaWiki", "Overleg MediaWiki", "Sjabloon", "Overleg sjabloon", "Help", "Overleg help", "Categorie", "Overleg categorie"]; case "nn": return ["Filpeikar", "Spesial", "Diskusjon", "Brukar", "Brukardiskusjon", "Wikipedia", "Wikipedia-diskusjon", "Fil", "Fildiskusjon", "MediaWiki", "MediaWiki-diskusjon", "Mal", "Maldiskusjon", "Hjelp", "Hjelpdiskusjon", "Kategori", "Kategoridiskusjon"]; case "no": return ["Medium", "Spesial", "Diskusjon", "Bruker", "Brukerdiskusjon", "Wikipedia", "Wikipedia-diskusjon", "Bilde", "Bildediskusjon", "MediaWiki", "MediaWiki-diskusjon", "Mal", "Maldiskusjon", "Hjelp", "Hjelpdiskusjon", "Kategori", "Kategoridiskusjon"]; case "nv": return ["Media", "Special", "Naaltsoos baa yinÃ­sht'Ä¯Ì", "Choinish'Ä¯Ä¯hÃ­", "Choinish'Ä¯Ä¯hÃ­ baa yinÃ­sht'Ä¯Ì", "WikiibÃ­Ã­diiya", "WikiibÃ­Ã­diiya baa yinÃ­sht'Ä¯Ì", "E'elyaaÃ­gÃ­Ã­", "E'elyaaÃ­gÃ­Ã­ baa yinÃ­sht'Ä¯Ì", "MediaWiki", "MediaWiki baa yinÃ­sht'Ä¯Ì", "Template", "Template talk", "AnÃ¡'Ã¡lwo'", "AnÃ¡'Ã¡lwo' baa yinÃ­sht'Ä¯Ì", "T'Ã¡Ã¡Å‚Ã¡hÃ¡gi Ã¡t'Ã©ego", "T'Ã¡Ã¡Å‚Ã¡hÃ¡gi Ã¡t'Ã©ego baa yinÃ­sht'Ä¯Ì"]; case "oc": return ["Especial", "Discutir", "Utilisator", "Discutida Utilisator", "OiquipediÃ ", "Discutida OiquipediÃ ", "Image", "Discutida Image", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Media", "Help", "Help talk", "Category", "Category talk"]; case "os": return ["Media", "Ð¡Ã¦Ñ€Ð¼Ð°Ð³Ð¾Ð½Ð´", "Ð”Ð¸ÑÐºÑƒÑÑÐ¸", "ÐÑ€Ñ…Ð°Ð¹Ã¦Ð³", "ÐÑ€Ñ…Ð°Ð¹Ã¦Ð´Ð¶Ñ‹ Ð´Ð¸ÑÐºÑƒÑÑÐ¸", "Wikipedia", "0", "ÐÑ‹Ð²", "ÐÑ‹Ð²Ñ‹ Ñ‚Ñ‹Ñ…Ñ…Ã¦Ð¹ Ð´Ð¸ÑÐºÑƒÑÑÐ¸", "MediaWiki", "Ð”Ð¸ÑÐºÑƒÑÑÐ¸ MediaWiki", "Ð¨Ð°Ð±Ð»Ð¾Ð½", "Ð¨Ð°Ð±Ð»Ð¾Ð½Ñ‹ Ñ‚Ñ‹Ñ…Ñ…Ã¦Ð¹ Ð´Ð¸ÑÐºÑƒÑÑÐ¸", "Ã†Ñ…Ñ…ÑƒÑ‹Ñ", "Ã†Ñ…Ñ…ÑƒÑ‹ÑÑ‹ Ñ‚Ñ‹Ñ…Ñ…Ã¦Ð¹ Ð´Ð¸ÑÐºÑƒÑÑÐ¸", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¹Ñ‹ Ñ‚Ñ‹Ñ…Ñ…Ã¦Ð¹ Ð´Ð¸ÑÐºÑƒÑÑÐ¸"]; case "pa": return ["à¨®à©€à¨¡à©€à¨†", "à¨–à¨¾à¨¸", "à¨šà¨°à¨šà¨¾", "à¨®à©ˆà¨‚à¨¬à¨°", "à¨®à©ˆà¨‚à¨¬à¨° à¨šà¨°à¨šà¨¾", "Wikipedia", "Wikipedia à¨šà¨°à¨šà¨¾", "à¨¤à¨¸à¨µà©€à¨°", "à¨¤à¨¸à¨µà©€à¨° à¨šà¨°à¨šà¨¾", "à¨®à©€à¨¡à©€à¨†à¨µà¨¿à¨•à¨¿", "à¨®à©€à¨¡à©€à¨†à¨µà¨¿à¨•à¨¿ à¨šà¨°à¨šà¨¾", "à¨¨à¨®à©‚à¨¨à¨¾", "à¨¨à¨®à©‚à¨¨à¨¾ à¨šà¨°à¨šà¨¾", "à¨®à¨¦à¨¦", "à¨®à¨¦à¨¦ à¨šà¨°à¨šà¨¾", "à¨¸à¨¼à©à¨°à©‡à¨£à©€", "à¨¸à¨¼à©à¨°à©‡à¨£à©€ à¨šà¨°à¨šà¨¾"]; case "pl": return ["Media", "Specjalna", "Dyskusja", "Wikipedysta", "Dyskusja Wikipedysty", "Wikipedia", "Dyskusja Wikipedii", "Grafika", "Dyskusja grafiki", "MediaWiki", "Dyskusja MediaWiki", "Szablon", "Dyskusja szablonu", "Pomoc", "Dyskusja pomocy", "Kategoria", "Dyskusja kategorii", "Portal", "Dyskusja portalu"]; case "pt": return ["Media", "Especial", "DiscussÃ£o", "UsuÃ¡rio", "UsuÃ¡rio DiscussÃ£o", "Wikipedia", "Wikipedia DiscussÃ£o", "Imagem", "Imagem DiscussÃ£o", "MediaWiki", "MediaWiki DiscussÃ£o", "PredefiniÃ§Ã£o", "PredefiniÃ§Ã£o DiscussÃ£o", "Ajuda", "Ajuda DiscussÃ£o", "Categoria", "Categoria DiscussÃ£o"]; case "ro": return ["Media", "Special", "DiscuÅ£ie", "Utilizator", "DiscuÅ£ie Utilizator", "Wikipedia", "DiscuÅ£ie Wikipedia", "Imagine", "DiscuÅ£ie Imagine", "MediaWiki", "DiscuÅ£ie MediaWiki", "Format", "DiscuÅ£ie Format", "Ajutor", "DiscuÅ£ie Ajutor", "Categorie", "DiscuÅ£ie Categorie"]; case "ru": return ["ÐœÐµÐ´Ð¸Ð°", "Ð¡Ð»ÑƒÐ¶ÐµÐ±Ð½Ð°Ñ", "ÐžÐ±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ðµ", "Ð£Ñ‡Ð°ÑÑ‚Ð½Ð¸Ðº", "ÐžÐ±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ðµ ÑƒÑ‡Ð°ÑÑ‚Ð½Ð¸ÐºÐ°", "Ð’Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ", "ÐžÐ±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ðµ Ð’Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ð¸", "Ð˜Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ðµ", "ÐžÐ±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ðµ Ð¸Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð¸Ñ", "MediaWiki", "ÐžÐ±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ðµ MediaWiki", "Ð¨Ð°Ð±Ð»Ð¾Ð½", "ÐžÐ±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ðµ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð°", "Ð¡Ð¿Ñ€Ð°Ð²ÐºÐ°", "ÐžÐ±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ðµ ÑÐ¿Ñ€Ð°Ð²ÐºÐ¸", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ", "ÐžÐ±ÑÑƒÐ¶Ð´ÐµÐ½Ð¸Ðµ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ð¸"]; case "sc": return ["Speciale", "ContiÃ¨ndha", "Utente", "Utente discussioni", "Wikipedia", "Wikipedia discussioni", "ImmÃ gini", "ImmÃ gini contiÃ¨ndha", "Media", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "sk": return ["MÃ©diÃ¡", "Å peciÃ¡lne", "Diskusia", "Redaktor", "Diskusia s redaktorom", "WikipÃ©dia", "Diskusia k WikipÃ©dii", "ObrÃ¡zok", "Diskusia k obrÃ¡zku", "MediaWiki", "Diskusia k MediaWiki", "Å ablÃ³na", "Diskusia k Å¡ablÃ³ne", "Pomoc", "Diskusia k pomoci", "KategÃ³ria", "Diskusia ku kategÃ³rii"]; case "sl": return ["Media", "Posebno", "Pogovor", "Uporabnik", "UporabniÅ¡ki pogovor", "Wikipedija", "Pogovor k Wikipediji", "Slika", "Pogovor k sliki", "MediaWiki", "MediaWiki talk", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "sq": return ["Media", "Speciale", "Diskutim", "PÃ«rdoruesi", "PÃ«rdoruesi diskutim", "Wikipedia", "Wikipedia diskutim", "Figura", "Figura diskutim", "MediaWiki", "MediaWiki diskutim", "Stampa", "Stampa diskutim", "NdihmÃ«", "NdihmÃ« diskutim", "Category", "Category talk"]; case "sr": return ["Media", "ÐŸÐ¾ÑÐµÐ±Ð½Ð¾", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€", "ÐšÐ¾Ñ€Ð¸ÑÐ½Ð¸Ðº", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€ ÑÐ° ÐºÐ¾Ñ€Ð¸ÑÐ½Ð¸ÐºÐ¾Ð¼", "Ð’Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ˜Ð°", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€ Ð¾ Ð’Ð¸ÐºÐ¸Ð¿ÐµÐ´Ð¸Ñ˜Ð¸", "Ð¡Ð»Ð¸ÐºÐ°", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€ Ð¾ ÑÐ»Ð¸Ñ†Ð¸", "ÐœÐµÐ´Ð¸Ñ˜Ð°Ð’Ð¸ÐºÐ¸", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€ Ð¾ ÐœÐµÐ´Ð¸Ñ˜Ð°Ð’Ð¸ÐºÐ¸Ñ˜Ñƒ", "Ð¨Ð°Ð±Ð»Ð¾Ð½", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€ Ð¾ ÑˆÐ°Ð±Ð»Ð¾Ð½Ñƒ", "ÐŸÐ¾Ð¼Ð¾Ñ›", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€ Ð¾ Ð¿Ð¾Ð¼Ð¾Ñ›Ð¸", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð°", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€ Ð¾ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ð¸Ñ˜Ð¸", "ÐŸÐ¾Ñ€Ñ‚Ð°Ð»", "Ð Ð°Ð·Ð³Ð¾Ð²Ð¾Ñ€ Ð¾ Ð¿Ð¾Ñ€Ñ‚Ð°Ð»Ñƒ"]; case "sv": return ["Media", "Special", "Diskussion", "AnvÃ¤ndare", "AnvÃ¤ndardiskussion", "Wikipedia", "Wikipediadiskussion", "Bild", "Bilddiskussion", "MediaWiki", "MediaWiki diskussion", "Mall", "Malldiskussion", "HjÃ¤lp", "HjÃ¤lp diskussion", "Kategori", "Kategoridiskussion"]; case "ta": return ["à®Šà®Ÿà®•à®®à¯", "à®šà®¿à®±à®ªà¯à®ªà¯", "à®ªà¯‡à®šà¯à®šà¯", "à®ªà®¯à®©à®°à¯", "à®ªà®¯à®©à®°à¯ à®ªà¯‡à®šà¯à®šà¯", "Wikipedia", "Wikipedia à®ªà¯‡à®šà¯à®šà¯", "à®ªà®Ÿà®¿à®®à®®à¯", "à®ªà®Ÿà®¿à®®à®ªà¯ à®ªà¯‡à®šà¯à®šà¯", "à®®à¯€à®Ÿà®¿à®¯à®¾à®µà®¿à®•à¯à®•à®¿", "à®®à¯€à®Ÿà®¿à®¯à®¾à®µà®¿à®•à¯à®•à®¿ à®ªà¯‡à®šà¯à®šà¯", "à®µà®¾à®°à¯à®ªà¯à®ªà¯à®°à¯", "à®µà®¾à®°à¯à®ªà¯à®ªà¯à®°à¯ à®ªà¯‡à®šà¯à®šà¯", "à®‰à®¤à®µà®¿", "à®‰à®¤à®µà®¿ à®ªà¯‡à®šà¯à®šà¯", "à®ªà®•à¯à®ªà¯à®ªà¯", "à®ªà®•à¯à®ªà¯à®ªà¯ à®ªà¯‡à®šà¯à®šà¯"]; case "th": return ["Media", "à¸žà¸´à¹€à¸¨à¸©", "à¸žà¸¹à¸”à¸„à¸¸à¸¢", "à¸œà¸¹à¹‰à¹ƒà¸Šà¹‰", "à¸„à¸¸à¸¢à¹€à¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸œà¸¹à¹‰à¹ƒà¸Šà¹‰", "Wikipedia", "Wikipedia talk", "à¸ à¸²à¸ž", "à¸„à¸¸à¸¢à¹€à¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸šà¸ à¸²à¸ž", "MediaWiki", "à¸„à¸¸à¸¢à¹€à¸à¸µà¹ˆà¸¢à¸§à¸à¸±à¸š MediaWiki", "Template", "Template talk", "Help", "Help talk", "Category", "Category talk"]; case "tlh": return ["Doch", "le'", "ja'chuq", "lo'wI'", "lo'wI' ja'chuq", "wIqIpe'DIya", "wIqIpe'DIya ja'chuq", "nagh beQ", "nagh beQ ja'chuq", "MediaWiki", "MediaWiki ja'chuq", "chen'ay'", "chen'ay' ja'chuq", "QaH", "QaH ja'chuq", "Segh", "Segh ja'chuq"]; case "tr": return ["Media", "Ã–zel", "TartÄ±ÅŸma", "KullanÄ±cÄ±", "KullanÄ±cÄ± mesaj", "Vikipedi", "Vikipedi tartÄ±ÅŸma", "Resim", "Resim tartÄ±ÅŸma", "MedyaViki", "MedyaViki tartÄ±ÅŸma", "Åžablon", "Åžablon tartÄ±ÅŸma", "YardÄ±m", "YardÄ±m tartÄ±ÅŸma", "Kategori", "Kategori tartÄ±ÅŸma"]; case "tt": return ["Media", "Maxsus", "BÃ¤xÃ¤s", "Ã„ÄŸzÃ¤", "Ã„ÄŸzÃ¤ bÃ¤xÃ¤se", "Wikipedia", "Wikipedia bÃ¤xÃ¤se", "RÃ¤sem", "RÃ¤sem bÃ¤xÃ¤se", "MediaWiki", "MediaWiki bÃ¤xÃ¤se", "ÃœrnÃ¤k", "ÃœrnÃ¤k bÃ¤xÃ¤se", "YÃ¤rdÃ¤m", "YÃ¤rdÃ¤m bÃ¤xÃ¤se", "TÃ¶rkem", "TÃ¶rkem bÃ¤xÃ¤se"]; case "uk": return ["ÐœÐµÐ´Ñ–Ð°", "Ð¡Ð¿ÐµÑ†Ñ–Ð°Ð»ÑŒÐ½Ñ–", "ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ", "ÐšÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡", "ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ¾Ñ€Ð¸ÑÑ‚ÑƒÐ²Ð°Ñ‡Ð°", "Wikipedia", "ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Wikipedia", "Ð—Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ", "ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð·Ð¾Ð±Ñ€Ð°Ð¶ÐµÐ½Ð½Ñ", "MediaWiki", "ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ MediaWiki", "Ð¨Ð°Ð±Ð»Ð¾Ð½", "ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ñƒ", "Ð”Ð¾Ð²Ñ–Ð´ÐºÐ°", "ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð´Ð¾Ð²Ñ–Ð´ÐºÐ¸", "ÐšÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ", "ÐžÐ±Ð³Ð¾Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ ÐºÐ°Ñ‚ÐµÐ³Ð¾Ñ€Ñ–Ñ—"]; case "vi": return ["PhÆ°Æ¡ng tiá»‡n", "Äáº·c biá»‡t", "Tháº£o luáº­n", "ThÃ nh viÃªn", "Tháº£o luáº­n ThÃ nh viÃªn", "Wikipedia", "Tháº£o luáº­n Wikipedia", "HÃ¬nh", "Tháº£o luáº­n HÃ¬nh", "MediaWiki", "Tháº£o luáº­n MediaWiki", "TiÃªu báº£n", "Tháº£o luáº­n TiÃªu báº£n", "Trá»£ giÃºp", "Tháº£o luáº­n Trá»£ giÃºp", "Thá»ƒ loáº¡i", "Tháº£o luáº­n Thá»ƒ loáº¡i"]; case "wa": return ["Media", "SipeciÃ¥s", "Copene", "Uzeu", "Uzeu copene", "Wikipedia", "Wikipedia copene", "ImÃ¥dje", "ImÃ¥dje copene", "MediaWiki", "MediaWiki copene", "Modele", "Modele copene", "Aidance", "Aidance copene", "Categoreye", "Categoreye copene"]; }   return null; }

$wikins.createMap = function(k,v) { var r = {"" : ""}; for (var i = 0; i < k.length; ++i) { r[k[i]] = v[i]; }   return r; }

$wikins.init = function { // This works only on Wikimedia-style URLs. Failsafe is English. var lang = window.location.host.split('.')[0]; var ns = $wikins.getNS(lang) || $wikins.namespacesEnglish;

$wikins.namespaces = $wikins.createMap(       ns, $wikins.namespacesEnglish); $wikins.namespaceNames = $wikins.createMap(       $wikins.namespacesEnglish, ns);

for (var k in $wikins.namespaceNames) { $wikins[k.replace(/ /g,'_')] = $wikins.namespaceNames[k]; } }

$wikins.nsjoin = function(ns, article) { if (ns == "") return article; else return ns + ':' + article; }

// TODO: this only applies for Wikimedia servers $wikins.interwiki = 'ab|aa|af|ak|sq|als|am|ang|ar|an|arc|hy|roa-rup|as|ast|av|ay|az|bm|ba|eu|be|bn|bh|bi|bs|br|bg|my|ca|ch|ce|chr|chy|ny|zh|zh-tw|zh-cn|cho|cv|kw|co|cr|hr|cs|da|dv|nl|dz|en|eo|et|ee|fo|fj|fi|fr|fy|ff|gl|ka|de|got|el|kl|gn|gu|ht|ha|haw|he|hz|hi|ho|hu|is|io|ig|id|ia|ie|iu|ik|ga|it|ja|jv|kn|kr|csb|ks|kk|km|ki|rw|rn|tlh|kv|kg|ko|kj|ku|ky|lo|la|lv|li|ln|lt|jbo|nds|lg|lb|mk|mg|ms|ml|mt|gv|mi|minnan|mr|mh|zh-min-nan|mo|mn|mus|nah|na|nv|ne|se|no|nn|oc|or|om|pi|fa|pl|pt|pa|ps|qu|ro|rm|ru|sm|sg|sa|sc|gd|sr|sh|st|tn|sn|scn|simple|sd|si|sk|sl|so|st|es|su|sw|ss|sv|tl|ty|tg|ta|tt|te|th|bo|ti|tpi|to|tokipona|ts|tum|tr|tk|tw|uk|ur|ug|uz|ve|vi|vo|wa|cy|wo|xh|ii|yi|yo|za|zu';

$wikins.init;

/* wikipage.js */

// $Id: wikipage.js 1361 2006-03-16 08:45:20Z quarl $

// wikipage.js - "WikiPage" class for page name, etc. functionality //  Has i18n support.

// Suppose we are editing Template talk:Foo bar 'blah'. //  wikiDoc.editingP:             true; //  ...

// wikiPage is a pre-initialized global variable using the current page's canonical URL. // It uses the "Retrieved from" page hyperlink which is robust against redirections, editing, special characters, special pages. // //  wikiPage.url:         "http://en.wikipedia.org/wiki/Template_talk:Foo_bar_%27blah%27" //  wikiPage.qurl:        "http://en.wikipedia.org/w/index.php?title=Template_talk:Foo_bar_%27blah%27" //  wikiPage.page:        "Template talk:Foo bar 'blah'" //  wikiPage.article:     "Foo bar 'blah'" //  wikiPage.namespace:   "Template talk" // always the English version //  wikiPage.namespaceNT: "Template" //  wikiPage.talkP:       true //  wikiPage.nsTemplateP: true //  wikiPage.nsMainP:     false //  wikiPage.nsUserP:     false //  wikiPage.nsCategoryP: false //  wikiPage.nsSpecialP:  false //  wikiPage.nsProjectP:  false    // (namespace "Wikipedia")

// To create new WikiPage object from a URL: //  var wp = new WikiPage("http://en.wikipedia.org/wiki/Article_Name"); // To create a new WikiPage object from a page name: //  var wp = new WikiPage(null, 'Article Name');

// TODO: generalize code to other languages

var $wikipage = new Module('wikipage.js'); $wikipage.depend('util.js', 'wikins.js');

var WikiPage = $wikipage.WikiPage = function(url, page, doc, usafe) { if (!(this instanceof WikiPage)) { var wp= new WikiPage(url, page, doc, usafe); if (wp.failed) return null; return wp; }   this.doc = doc; var extraParams; if (url) { url = "" + url; if (url.match( '^(?:http://'+WikiPage.server+')?/wiki/')) { this.pageQuoted = RegExp.rightContext; } else if (url.match( '^(?:http://'+WikiPage.server+')?/w/index\\.php\\?title=([^&=+]+)(.*)')) { this.pageQuoted = RegExp.$1; extraParams = RegExp.$2; } else { if (usafe) { this.failed=1; return null; } return $wikipage.error("Couldn't parse page name from url '"+url+"' (error 3a9483df-fc14-419f-8b0b-6e00bb4a6d12)"); }       this.pageQuoted = $util.removeAnchor(this.pageQuoted); try { this.page = $util.wpaDecode(this.pageQuoted); } catch (e) { if (usafe) { this.failed=1; return null; } return $wikipage.error($util.pprintf("Couldn't decode page name '$1': $2", this.pageQuoted, e)); }   } else if (page) { this.page = $util.removeAnchor(page.replace(/_/g, ' ')); this.pageQuoted = $util.wpaEscape(page); } else { return $wikipage.error("must specify url or page (12af0703-eeba-4d70-87dd-06e10c26dbf8)"); }

// this is the requested oldid for the page, if present this.oldid = extraParams && extraParams.match(/&oldid=([0-9]+)/) && RegExp.$1; // XXX TODO this doesn't work right now for window.wikiPage because we use // canonical URL, not window.location // maybe we should create another class that wraps WikiPage

this.url = 'http://'+WikiPage.server+'/wiki/' + this.pageQuoted; this.qurl = 'http://'+WikiPage.server+'/w/index.php?title=' + this.pageQuoted;

if (this.oldid) { this.qurl += '&oldid=' + this.oldid; }

// Get term on the left of ":". Not any string is a namespace though, only certain hardcoded ones! if (this.page.match(/:/) &&       (this.namespace = $wikins.namespaces[RegExp.leftContext])) {       // this.namespace contains the ENGLISH version of the namespace this.article = RegExp.rightContext; } else { this.namespace = ''; // (main) this.article = this.page; }

if ($wikins.namespaceNoTalk[this.namespace] != null) { this.talkP = true; this.editableP = true; this.namespaceNT = $wikins.namespaceNoTalk[this.namespace]; this.namespaceT = this.namespace; } else if ($wikins.namespaceTalk[this.namespace]) { this.talkP = false; this.editableP = true; this.namespaceNT = this.namespace; this.namespaceT = $wikins.namespaceTalk[this.namespace]; } else { // this should be a namespace with no corresponding Talk namespace, // i.e. Media or Special this.talkP = false; this.editableP = false; this.namespaceNT = this.namespace; this.namespaceT = null; }

if (this.article.match(/\//)) { this.superarticle = RegExp.leftContext; this.subarticle = RegExp.rightContext; } else { this.superarticle = this.article; this.subarticle = ''; }

this.nsMainP = (this.namespaceNT == ''); this.nsMediaP = (this.namespaceNT == 'Media'); this.nsSpecialP = (this.namespaceNT == 'Special'); this.nsUserP = (this.namespaceNT == 'User'); this.nsPortalP = (this.namespaceNT == 'Portal'); this.nsImageP = (this.namespaceNT == 'Image'); this.nsMediaWikiP = (this.namespaceNT == 'MediaWiki'); this.nsTemplateP = (this.namespaceNT == 'Template'); this.nsHelpP = (this.namespaceNT == 'Help'); this.nsCategoryP = (this.namespaceNT == 'Category'); this.nsProjectP = (this.namespaceNT == 'Wikipedia');

// remember, this.namespace is in English, but WikiPage argument is the // localized wikimarkup name this.talkPage = function { if (this.talkP) { return this; } if (this.namespaceT == null) return null; var ns = $wikins.namespaceNames[this.namespaceT]; return new WikiPage(null, $wikins.nsjoin(ns, this.article)); }

this.notalkPage = function { if (!this.talkP) { return this; } var ns = $wikins.namespaceNames[this.namespaceNT]; return new WikiPage(null, $wikins.nsjoin(ns, this.article)); }

this.sandboxP    = Boolean(this.page.match(/sandbox$/i));

this.setDoc = function(doc) { var wd = new WikiDocument(doc, this);

if (wd.editingP) { this.editDoc = wd; } else { this.viewDoc = wd; }

this.wd = wd; }

if (doc) { // Note that a WikiPage may have more than one associated WikiDocument, // e.g. one from viewing and one from editing this.setDoc(doc); }

this.relevantUser = $wikipage.getRelevantUser0(this, extraParams); // TODO: if relevantUser was from extraParams, we need to fixup // page/pageQuoted

return this; }

WikiPage.prototype.toString = function { return 'WikiPage(null,' + $util.stringQuoteEscape(this.page) + ')'; }

/* Retrieved from "http://en.wikipedia.org/wiki/Albert_Einstein"

$wikipage.getCanonPageURL0 = function { // for 'Special' pages, use location.href, because the "retrieved from" // note doesn't include the sub-page or target if (window.location.pathname.match('^/wiki/' + $wikins.Special + ':') ||       window.location.href.match('/w/index\\.php\\?title=' + $wikins.Special + ':')) {       return window.location.href; } else { return $wikipage.getCanonPageURL1; } }

// the "retrieved from" text contains the canonical article URL (even if we're // looking at an edit or history page) $wikipage.getCanonPageURL1 = function { return $util.getElementsByClass("printfooter", null, 'div')[0].getElementsByTagName('a')[0].href; }

var WikiDocument = $wikipage.WikiDocument = function(doc, wp) { this.doc = doc; this.wp = wp;

this.username    = $wikipage.getUsername0(doc);

// Note: can't use "doc.editform" or "doc.forms.editform", because 'doc' // might actually be an XMLDocument (not HTMLDocument), if this is the // result of an XMLHTTPRequest. this.editForm    = doc.getElementById('editform'); this.editingP    = Boolean(this.editForm); this.editingNewP = Boolean(doc.getElementById('newarticletext')); // obsolete method: document.title.match(/^Editing /) this.protectedP  = Boolean(doc.getElementById("ca-viewsource")); this.newSectionP = this.editForm && (this.editForm.wpSection.value == "new"); this.movePageP   = Boolean(doc.getElementById("movepage")); this.previewP    = Boolean(doc.getElementById("wikiPreview")); this.historyP    = Boolean(doc.getElementById("pagehistory")); this.permalinkP  = Boolean(doc.getElementById("t-ispermalink"));

// this is the revision id for this document, which always exists for // saved pages, even if we're looking at a 'latest version' URL. this.oldid       = $wikipage.getOldid0(doc, this.permalinkP); }

$wikipage.getUsername0 = function(doc) { // read username from pt-userpage link. // Quarl return doc.getElementById('pt-userpage').getElementsByTagName('a')[0].text; }

$wikipage.getUsernameFromLink = function(link) { return link && (new WikiPage(link)).relevantUser; }

$wikipage.getRelevantUser0 = function(wp, extraParams) { if (wp.nsUserP) return wp.superarticle; if (wp.nsSpecialP) { if (wp.superarticle == 'Contributions' ||           wp.superarticle == 'Emailuser' ||            wp.superarticle == 'Blockip'            ) {           // e.g. /w/index.php?title=Special:Contributions&target=foo if (extraParams && extraParams.match(/&target=([^&=+]+)/)) { var u = RegExp.$1; } else { var u = wp.subarticle; }

// Special:Contributions/newbies is a magic username if (u == 'newbies') return null; return u;       } // TODO: return current user if Watchlist? // TODO: /w/index.php?title=Special:Log&user=Quarl }

return null;

// if (doc && wp.page == 'Special:Contributions') { //    var cdiv = doc.getElementById('contentSub'); //    if (cdiv.textContent == "For newbies") return null; //    return $wikipage.getUsernameFromLink(cdiv.getElementsByTagName('a')[0]); // } }

// Get the oldid ("permalink") for the current page. // Note that we can't get oldid for editing pages, special pages, etc. $wikipage.getOldid0 = function(doc, perm) { var tagid = perm ? 'ca-edit' : 't-permalink'; var tag = doc.getElementById(tagid); if (!tag) return null; var href = tag.getElementsByTagName("a")[0].href; if (!href) return null; href.match(/&oldid=([0-9]+)/); return RegExp.$1; }

$wikipage.getQueryVars0 = function{ var res = []; var queryStr = window.location.search.substring(1); if (queryStr) { var pairs = queryStr.split("&"); for(var i=0; i < pairs.length; i++){ var pair = pairs[i].split("="); res[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]); }   }    // default nulls to avoid 'undefined property' warnings for commonly // checked properties if (!res.fakeaction) res.fakeaction = null; return res; }

$wikipage.getDbName0 = function(server) { // dbnames for all Wikimedia Foundation servers: switch(server) { case 'commons.wikimedia.org': return 'commonswiki'; case 'meta.wikimedia.org': return 'metawiki'; case 'species.wikipedia.org': return 'specieswiki'; case 'wikimediafoundation.org': return 'foundationwiki'; }   if (server.match(/^([a-z][a-z])[.]wikipedia[.]org$/)) { return RegExp.$1 + 'wiki'; }   if (server.match(/^([a-z][a-z])[.]wikisource[.]org$/)) { return RegExp.$1 + 'wikisource'; }   if (server.match(/^([a-z][a-z])[.]wikibooks[.]org$/)) { return RegExp.$1 + 'wikibooks'; }   if (server.match(/^([a-z][a-z])[.]wiktionary[.]org$/)) { return RegExp.$1 + 'wiktionary'; }   if (server.match(/^([a-z][a-z])[.]wikinews[.]org$/)) { return RegExp.$1 + 'wikinews'; }   if (server.match(/^([a-z][a-z])[.]wikiquote[.]org$/)) { return RegExp.$1 + 'wikiquote'; }   $wikipage.error("unknown server, couldn't figure out dbname (error 3b448857-7545-4187-8959-d80b1cd8149b)"); return 'enwiki'; }

$wikipage.load = function { WikiPage.server = window.location.host || 'en.wikipedia.org'; WikiPage.wikimediaWikiP = Boolean(WikiPage.server.match(/wiki([pm]edia|source|books)\.org|wiktionary\.org/));

WikiPage.dbname = $wikipage.getDbName0(WikiPage.server);

window.wikiPage = new WikiPage($wikipage.getCanonPageURL0, null, document); window.wikiDoc = wikiPage.wd;

WikiDocument.queryVars = $wikipage.getQueryVars0;

$wikipage.debug("load: wikiPage=" + wikiPage); }

$util.addOnloadHook($wikipage.load);

// obsolete method 1: // function getPname0 { //    var z=document.getElementById("content").childNodes; //    for (var n=0;n<z.length;n++) { //        if (z[n].className=="firstHeading") return z[n].textContent; //    } // }

// function getPname1 { //    var t = getPname0; //    t = t.replace(/^Editing /,''); //    t = t.replace(/ \(section\)$/,'');

//    return t; // }

// obsolete method 2: //   document.title.substr(0, document.title.lastIndexOf(' - Wikipedia, the free'));

/* wikiedit.js */

// $Id: wikiedit.js 1351 2006-03-08 22:24:43Z quarl $

// wikiedit.js - functions for automatically editing pages

// synposis: //    function beginEdit { //        wikiPage.getEditorAsync(myPage_edit, data1, data2); //    } //     function myPage_edit(editor, data1, data2) { //        editor.wpTextbox1 += data1; //        editor.wpSummary += data2; //        editor.submit; //

// WikiEditor is a class that facilitates editing and submitting Wikipedia edit forms. // // use wp.getEditorAsync to use the current edit form if available, else download one. //    - inside the callback, "this" is equivalent to "editor" // // available properties: //    wpTextbox1 //    wpSummary //    wpMinoredit //    wpWatchthis // // available functions: //    submitDirect: submit form directly via document.form.submit //    submitHidden: create a new hidden form, attach to document, and submit //    submit: submitDirect if possible, else submitHidden //    submitAsync: asynchronously submit a form via XMLHTTPRequest, and callback result //    updateForm: update what the user sees and prepare for submitting //    refuseCreate: if wpTextbox1 is empty, alert and return 'True' //

// WikiEditor.addSubmitHook adds a hook that's called from all form // submissions (including asynchronous ones). For example usage see // autoreplace.js. //    WikiEditor.addSubmitHook(function(editor, button) { ... });

// quarl 2006-01-23 initial version

var $wikiedit = new Module('wikiedit.js'); $wikiedit.depend('util.js', 'wikipage.js'); // recommends: smartsubmit.js

// WikiEditor class // // A WikiEditor doubles as an associative array of the edit properties - // i.e. editor.wpTextbox1 contains the edit text. var WikiEditor = $wikiedit.WikiEditor = function (wd) { if (!(this instanceof WikiEditor)) return new WikiEditor(wd); window.wikiEditor = this;

if (!(wd instanceof WikiDocument)) { return $wikiedit.error("WikiEditor: need a WikiDocument (error 22a8bb3a-80e9-4df4-87c1-8c100b6aebbf)"); } this.wd = wd; this.wp = wd.wp; this.form = WikiEditor.getEditForm(wd.doc); if (!this.form) { return $wikiedit.error("WikiEditor: no form! (error d49dfc77-752c-4064-a5c8-503b635fdc7b)"); }

// The HTML default maxlength is 200, but the MediaWiki server actually // accepts up to 250 chars! this.form.wpSummary.setAttribute('maxlength', 250);

this.refuseCreate = function { if (!this.wpTextbox1) { alert("Error! Page is empty; refusing to create."); return true; } else { return false; }   }

this.getFormParams = function(button) { button = WikiEditor._checkButton(button); d = {}; WikiEditor.updateFields(d, this, WikiEditor.wpFormFields); d[button] = this.form[button]; return d;   }

this.updateThis = function { WikiEditor.updateFields(this, this.form, WikiEditor.wpFormFields); }

this.updateForm = function { WikiEditor.updateFields(this.form, this, WikiEditor.wpFormFields); }

// Direct submission, should only be used when the form is part of the // currently-viewed HTML page. Navigates to result page. this.submitDirect = function(button) { button = WikiEditor._checkButton(button); this.updateForm; // Click the appropriate button. // Note that this generates an onClick event, which in turn calls the // runPreSubmitHooks function. this.form[button].click; }

// Adds a hidden form to the current page and submits it, navigating to   // the result page. this.submitHidden = function(button) { button = WikiEditor._checkButton(button); this.runPreSubmitHooks(this, button); var newform = document.createElement('form'); $util.addFormHiddenParams(newform, this.getFormParams(button)); newform.name = this.form.name; newform.method = this.form.method; newform.id = this.form.id; newform.action = this.form.action; document.getElementById('bodyContent').appendChild(newform); newform.submit; }

// Asynchronously submit the form and call CALLBACK. this.submitAsync = function(button, callback) { button = WikiEditor._checkButton(button); var cb; if (callback) { var thisE = this; var args = $util.copyArray(arguments); args.shift; args[0] = null; cb = function(req) { args[0] = req; callback.apply(thisE, args); }; } else { cb = function(req) { /* dummy */ }; }       var data = this.getFormParams(button); this.runPreSubmitHooks(data, button); $util.asyncPostXML(this.form.action, data, cb); }

// copy input fields from form into this object for easy access (we'll copy back later) this.updateThis; this.wpTextbox1_orig = this.form.wpTextbox1_orig;

// If this form is the current document's form, we can submit directly. // Else we must use the hidden submit method. if (this.form == document.editform) { this.submit = this.submitDirect; } else { this.submit = this.submitHidden; }

return this; }

WikiEditor.getEditForm = function(doc) { if (!doc) doc = document; // Note: can't use "doc.editform", because 'doc' might actually be an XMLDocument (not HTMLDocument), if this is the result of an XMLHTTPRequest. return doc.getElementById('editform'); }

WikiEditor.wpFormFields = $util.assocArray( [   'wpSection', 'wpStarttime', 'wpEdittime', 'wpScrolltop',    'wpTextbox1', 'wpSummary', 'wpMinoredit', 'wpWatchthis',    'wpEditToken' ] ); WikiEditor.wpButtons = $util.assocArray( [ 'wpSave', 'wpPreview', 'wpDiff' ] );

WikiEditor._checkButton = function(button) { if (!button) return 'wpSave';                  // default if (typeof button != 'string' || WikiEditor.wpButtons[button] != 1) { $wikiedit.error("## WikiEditor._checkButton: invalid button '"+button+"' (error 1a0655e7-ac83-4f15-8447-694b16a834ed)"); return 'wpPreview'; }   return button; }

WikiEditor.updateFields = function(target, source, fields) { var targetFormP = Boolean(target.nodeName); var sourceFormP = Boolean(source.nodeName); for (var i in fields) { var f = fields[i]; var v;       if (sourceFormP && source[f]) { if (source[f].type == "checkbox") { v = source[f].checked; } else { v = source[f].value; }       } else { v = source[f]; }       if (targetFormP) { if (target[f].type == "checkbox") { target[f].checked = v;           } else { // don't set it if unchanged, to avoid focus/selection change if (target[f].value != v) target[f].value = v;           } } else { target[f] = v;       } } }

// Get an editor for this WikiPage -- it needs to have an editDoc already (as // an editing window.wikiPage would have); else need to use getEditorAsync. // Usually it's easier to just always use getEditorAsync. WikiPage.prototype.getEditor = function { if (!this.editor) { if (!this.editDoc) { return $wikiedit.error("WikiPage.getEditor: no editDoc - use getEditorAsync (error 9f4a2c95-b3e0-437e-972d-88290a5bd7ee)"); }       this.editor = WikiEditor(this.editDoc); }   return this.editor; }

// If already editing the target page, return a WikiEditor now. // Else, download the edit form first. // Call-back with new WikiEditor instance. WikiPage.prototype.getEditorAsync = function(callback) { var wp = this; var args = $util.copyArray(arguments); // copy arguments because we need it in 'cb' below

// already cached if (wp.editor) { args[0] = wp.editor; callback.apply(wp.editor, args); return; }

// do we already have an edit document? (window.wikiPage.editDoc would be   // initialized to 'WikiDocument(document)' as appropriate). if (wp.editDoc) { wp.editor = WikiEditor(wp.editDoc); args[0] = wp.editor; callback.apply(wp.editor, args); return; }

// need to download a new edit document. var cb = function(req) { if (req.status != 200) { $wikiedit.error("getEditorAsync: Error downloading edit page!"); return; }

wp.setDoc(req.responseXML); wp.editor = WikiEditor(wp.editDoc); args[0] = wp.editor; callback.apply(wp.editor, args); return; };   $util.asyncDownloadXML(wp.qurl + '&action=edit', cb); }

WikiEditor.pre_submit_hooks = [];

// add a submit hook to all forms (including asynchronous ones). // Submit hooks are called with arguments (editor, form, button) //  Note that the form argument may not be the same as editor.form or //   document.form, if the submit is via submitHidden or submitAsync! WikiEditor.addPreSubmitHook = function(func) { WikiEditor.pre_submit_hooks.push(func); }

WikiEditor.prototype.runPreSubmitHooks = function(data, button) { // 'data' should be a hash array and could be either a WikiEditor // instance, or a separate object for (var i in WikiEditor.pre_submit_hooks) { WikiEditor.pre_submit_hooks[i](this, data, button); } }

WikiEditor.onClickSubmitHook = function(button) { var editor = wikiPage.getEditor; if (editor.form[button].preventPreSumitHook) return; editor.updateThis; editor.runPreSubmitHooks(editor, button); // submit hooks may have changed data. editor.updateForm; }

document.write(''+              '  ');

WikiEditor.load = function { if (document.forms.editform) { // save original version of edit box. // write this to a hidden field (in a separate form) so that we       // don't lose this data on forward/back. var w = document.getElementById('wikiedit_wpTextbox1_orig'); if (w.value) { document.forms.editform.wpTextbox1_orig = w.value; } else { document.forms.editform.wpTextbox1_orig = w.value = document.forms.editform.wpTextbox1.value; }

// $util.hookEventObj(document.forms.editform, 'submit', WikiEditor.onClickSubmitHook);

// add submit hooks $util.hookEventObj(document.editform.wpSave, 'click', function { WikiEditor.onClickSubmitHook('wpSave'); }); $util.hookEventObj(document.editform.wpDiff, 'click', function { WikiEditor.onClickSubmitHook('wpDiff'); }); $util.hookEventObj(document.editform.wpPreview, 'click', function { WikiEditor.onClickSubmitHook('wpPreview'); }); } }

$util.addOnloadHook(WikiEditor.load);

/* diff.js */

// $Id: diff.js 1259 2006-02-25 08:07:15Z quarl $

// diff.js - utility functions for doing diffs

// quarl 2006-01-29 initial version

/* * $diff is based on http://ejohn.org/projects/javascript-diff-algorithm/ *  Copyright John Resig */

var $diff = new Module('diff.js'); $diff.depend('util.js');

$diff.options = { // if more than this many words of changes, use overflow string summary_maxwords: 40, summary_overflow: "$1 words changed" };

$diff.diff = function(o, n) { var ns = {}; var os = {};

for ( var i = 0; i < n.length; i++ ) { // note we have to check that it is in fact an object with "rows", in       // case ns[i] happens to match a javascript member function of class // Array, e.g. "some"! if ( ns[ n[i] ] == null || !ns[n[i]].rows ) ns[ n[i] ] = { rows: new Array, o: null }; ns[ n[i] ].rows.push( i ); }

for ( var i = 0; i < o.length; i++ ) { if ( os[ o[i] ] == null || !os[o[i]].rows ) os[ o[i] ] = { rows: new Array, n: null }; os[ o[i] ].rows.push( i ); }

for ( var i in ns ) { if ( ns[i].rows.length == 1 && typeof(os[i]) != "undefined" && os[i].rows.length == 1 ) { n[ ns[i].rows[0] ] = { text: n[ ns[i].rows[0] ], row: os[i].rows[0] }; o[ os[i].rows[0] ] = { text: o[ os[i].rows[0] ], row: ns[i].rows[0] }; }   }

for ( var i = 0; i < n.length - 1; i++ ) { if ( n[i].text != null && n[i+1].text == null &&            0 <= n[i].row+1 && n[i].row+1 < o.length &&             o[ n[i].row + 1 ].text == null &&             n[i+1] == o[ n[i].row + 1 ] ) {           n[i+1] = { text: n[i+1], row: n[i].row + 1 }; o[n[i].row+1] = { text: o[n[i].row+1], row: i + 1 }; }   }

for ( var i = n.length - 1; i > 0; i-- ) { if ( n[i].text != null && n[i-1].text == null &&            0 <= n[i].row-1 && n[i].row-1 < o.length &&             o[ n[i].row - 1 ].text == null &&             n[i-1] == o[ n[i].row - 1 ] ) {           n[i-1] = { text: n[i-1], row: n[i].row - 1 }; o[n[i].row-1] = { text: o[n[i].row-1], row: i - 1 }; }   }

return { o: o, n: n }; }

$diff._split = function(s) { //return $util.trimSpaces(s).split(/(?:\s|[.,;\'\"`])+/);   return s.split(/\s+/); }

$diff.aggregate = function(words) { var phrases = new Array; var cur = null; var wordcount = 0;

// start at virtual index -1 to check for removed words at beginning of   // text for ( var i = -1; i < words.n.length; i++ ) { if ( i!=-1 && words.n[i].text == null ) { if (!cur) { cur = { o: "", n: "" }; phrases.push(cur); }           cur.n += " " + words.n[i]; wordcount ++; } else { var pre = ""; var j = i==-1 ? 0 : words.n[i].row + 1; while ( j < words.o.length && words.o[j].text == null ) { pre += " " + words.o[j]; j++; wordcount ++; }           if (pre) { if (!cur) { cur = { o: "", n: "" }; phrases.push(cur); }               cur.o += pre; }           if (pre && words.n[i+1] && words.n[i+1].text == null) { // If there's an addition following, treat this as part of the // same change. } else { cur = null; }       }    }

for (var i in phrases) { phrases[i].n = $util.trimSpaces(phrases[i].n); phrases[i].o = $util.trimSpaces(phrases[i].o); }

return { phrases: phrases, wordcount: wordcount }; }

$diff.wikiQuote = function(s) { if (!s) return s;   if (s.match(/^\{\{.*\}\}$/)) return s;    s = s.replace(/\"/g, "'");    return '"'+s+'"'; }

// trim the equal chars from the front and back of o,n at a word boundary $diff.stringTrim = function(o, n) { var r = $diff.stringTrim0($util.reverseString(o), $util.reverseString(n)); return $diff.stringTrim0($util.reverseString(r.o), $util.reverseString(r.n)); }

$diff.stringTrim0 = function(o, n) { var i = 0; while (i < o.length && i < n.length && o[i] == n[i]) { ++i; }

// find index of last non-word character var prefix = o.substr(0, i);

// if prefix ends with word characters and suffix starts with non-word, // then erase entire prefix if (prefix.match(/\w$/) &&       !o.substr(i, 1).match(/^\w/) && !n.substr(i, 1).match(/^\w/)) {       o = o.substr(i); n = n.substr(i); } else if (prefix.match(/.*\W/)) { i = RegExp.lastMatch.length; o = o.substr(i); n = n.substr(i); } else { // keep entire prefix }   return { o: o, n: n }; }

$diff._wikiQuoteWords = function(s) {   var words = $diff._split(s); if (words.length > $diff.options.summary_maxwords) { return $util.pprintf('($1 words)', words.length); } else { return $diff.wikiQuote(words.join(' ')); } }

$diff.diffSummary = function(o, n) { o = $util.trimSpaces(o); n = $util.trimSpaces(n); if (o == n) return ""; if (!o) { return "new: +" + $diff._wikiQuoteWords(n); }   if (!n) { return "blank: -" + $diff._wikiQuoteWords(o); }   var words = $diff.diff( $diff._split(o), $diff._split(n) ); var r = $diff.aggregate(words); if (!r.wordcount) return ""; if (r.wordcount > $diff.options.summary_maxwords) { return $util.pprintf($diff.options.summary_overflow, r.wordcount); }

var phrases = r.phrases; var str = []; for (var i in phrases) { var r = $diff.stringTrim(phrases[i].o, phrases[i].n); var ro = $diff.wikiQuote(r.o), rn = $diff.wikiQuote(r.n); if (ro && rn) { str.push(ro + ' â†’ ' + rn); } else if (ro) { str.push('-' + ro); } else if (rn) { str.push('+' + rn); } else { // alert("## internal error 15e1b13f-bae3-4399-86c5-721786822fa2"); }   }

return str.join(", "); }

/* shortcuts.js */

// $Id: shortcuts.js 938 2006-02-22 06:30:21Z quarl $

// shortcuts.js - shortcut utilities

// Defines the Shortcuts class. //  Input is an associative array like this: // /*  s = Shortcuts({                    'x1'   : 'str 1',                    'x2 '  : 'str 2', // the space after x2 prevents msg from displaying this entry                    'x3,x4': 'str 34' // x3 and x4 are aliases; msg only displays x3                });

var $shortcuts = new Module('shortcuts.js');

var Shortcuts = $shortcuts.Shortcuts = function(input) { if (!(this instanceof Shortcuts)) return new Shortcuts(input);

this.shortcuts = {}; for (k in input) { var keys = k.toUpperCase.split(','); this.shortcuts[keys[0]] = input[k]; for (var i=1; i < keys.length; ++i) { this.shortcuts[keys[i]] = input[k] + ' '; }   }

return this; }

Shortcuts.prototype.msg = function { var msg = 'Shortcuts available:\n'; for (var key in this.shortcuts) { if (this.shortcuts[key].match(/ $/)) continue; msg += key + ': ' + this.shortcuts[key] + '\n'; }   return msg; }

Shortcuts.prototype.subst = function(word) { return $util.trimSpaces(this.shortcuts[word.toUpperCase]) || word; }

Shortcuts.prototype.substP = function(word) { return Boolean(this.shortcuts[word.toUpperCase]); }

// replace the first word (doesn't require uppercase) Shortcuts.prototype.substFirstWord = function(msg) { if (!msg) return msg; if (msg.match(/^([a-zA-Z]+)(.*)$/)) { return this.subst(RegExp.$1) + RegExp.$2; }   return msg; }

// replace all UPPERCASE words Shortcuts.prototype.substUppercaseWords = function(msg) { if (!msg) return msg; var ret = ''; var m;   while (msg && (m = msg.match(/^(.*?)\b([A-Z]+)\b(.*)$/)) ) { ret += m[1] + this.subst(m[2]); msg = m[3]; }

ret += msg; return ret; }

// replace all words (ignoring case) Shortcuts.prototype.substWords = function(msg) { if (!msg) return msg; var ret = ''; var m;   while (msg && (m = msg.match(/^(.*?)\b([A-Za-z]+)\b(.*)$/)) ) { ret += m[1] + this.subst(m[2]); msg = m[3]; }

ret += msg; return ret; }

/* diffsince.js */

// $Id: diffsince.js 1351 2006-03-08 22:24:43Z quarl $

// diffsince.js - utility functions for doing a "diff since I last edited"

// Synopsis: //   url = diffsince.makeUrl(wikiPage); //   href = '<a onclick="javascript:diffsince.diffThis" href="'+url+'">diff since</a>';

// Or: //   url = diffsince.makeUrl(wp); //   href = '<a onclick="javascript:diffsince.diffPageAsync(wp)" href="'+url+'">diff since</a>';

// Navigating to the value of makeUrl will open a history page, parse it, and // jump to the appropriate diff.

// The diffPageAsync function asynchronously downloads the history page and // then navigates to the diff. It is appropriate as an onClick handler.

// The diffThis function does the diff directly if already looking at a // history page, else calls diffPageAsync(wikiPage).

// diffPageAsync and diffThis take status_node and status_text parameters for // showing progress.

// quarl 2006-01-16 (asynchronous code originally written in show_diff_since.js) // quarl 2006-02-03 factored as library

var $diffsince = new Module('diffsince.js'); $diffsince.depend('wikipage.js', 'util.js');

$diffsince.options = { history_limit: [200] };

// return a URL that points to a "fakeaction" page for doing a diff. $diffsince.makeUrl = function(wp) { return wp.qurl + '&fakeaction=diffsince&action=history&limit='+$diffsince.options.history_limit[0]; }

$diffsince._load = function { if (WikiDocument.queryVars.fakeaction == 'diffsince') { $diffsince._parseHistory(document); } }

$diffsince.diffPageAsync = function(wp, statusNode, statusText) { var url = wp.qurl + '&action=history&limit='+$diffsince.options.history_limit[0]; var req = new XMLHttpRequest;

// change the button to show the user we're doing something and // prevent another click $util.buttonShowStatus(statusNode, statusText); // (statusNode, statusText are optional)

$util.asyncDownloadXML(url, $diffsince._handleHistoryPage,                          { statusNode: statusNode }); return false; }

$diffsince.diffThis = function(statusNode, statusText) { if (wikiDoc.historyP) { // already looking at a history page $diffsince._parseHistory(document); } else { // not yet a history page -- asynchronously download it first $diffsince.diffPageAsync(wikiPage, statusNode, statusText); }   return false; }

$diffsince._handleHistoryPage = function(req) { // restore button in case this fails, so user can click again $util.buttonRestoreStatus(req.statusNode);

if (req.status == 200) { $diffsince._parseHistory(req.responseXML); } else { $diffsince.error("Error downloading history page! (error cafe5f9c-5d9d-4f91-ba31-35c68c401c4f)"); } }

$diffsince._parseHistory = function(doc) { if (!doc) { return $diffsince.error("no doc?! (error 771d4660-0109-4e56-9cd7-70fc583fd4b5)"); } var hists = doc.getElementById("pagehistory").childNodes; if (!hists) { return $diffsince.error("Couldn't parse history from page (error db3ebe3e-cc2f-48ab-9c18-d348f92b0d91)"); } for (n=0;n<hists.length;n++) { if (hists[n].getElementsByTagName &&           hists[n].getElementsByTagName("span")[0].textContent==wikiDoc.username) {           document.location = hists[n].childNodes[1].href; return void(0); }   }

alert("diffsince: Couldn't find your entry in the history page; you haven't edited recently!"); // TODO: retry with a larger limit return void(0); }

$util.addOnloadHook($diffsince._load);

/* wikiwatch.js */

// $Id: wikiwatch.js 1351 2006-03-08 22:24:43Z quarl $

// wikiwatch.js - utility functions for manipulating watchlist

// quarl 2006-01-09 (initial asynchronous implementation at unwatch.js) // quarl 2006-02-03 factored out to utility library

var $wikiwatch = new Module('wikiwatch.js'); $wikiwatch.depend('wikipage.js', 'util.js');

$wikiwatch.unwatchAsync = function(wp, callback, statusNode, statusText) { $wikiwatch.wuwatchAsync(false, wp, callback, statusNode, statusText); }

$wikiwatch.watchAsync = function(wp, callback, statusNode, statusText) { $wikiwatch.wuwatchAsync(true, wp, callback, statusNode, statusText); }

$wikiwatch.makeUrl = function(wp, wuwp) { if (wuwp) { return wp.qurl + '&action=watch'; } else { return wp.qurl + '&action=unwatch'; } }

// wuwp true: watch // wuwp false: unwatch $wikiwatch.wuwatchAsync = function(wuwp, wp, callback, statusNode, statusText) { var h1expect = wuwp ? 'Added to watchlist' : 'Removed from watchlist';

wp = wp.notalkPage; $util.buttonShowStatus(statusNode, statusText); var cb = function(req) { $util.buttonRestoreStatus(statusNode); var m;       if ((req.status == 200) &&            (req.responseXML.getElementById('content').getElementsByTagName('h1')[0].textContent == h1expect)) {           if (callback) { callback(wp, wuwp); }       } else { $wikiwatch.error("$wikiwatch.wuwatchAsync "+(wuwp?'watch':'unwatch')+" '"+wp.page+"' failed!"); }   };    $util.asyncDownloadXML($wikiwatch.makeUrl(wp, wuwp), cb); }

/* watchlist.js */

// $Id: watchlist.js 1351 2006-03-08 22:24:43Z quarl $

// watchlist.js - adds buttons to watchlist: "unwatch", "diff // since"

// UNWATCH button asynchronously unwatches and crosses the entry off the // watchlist. // // DIFF SINCE button shows differences since last edited.

// USAGE: //  $module.depend('watchlist.js'); //  $watchlist.widgetLoad;

// quarl 2006-01-09 added asynchronous feature. // quarl 2006-02-03 factored; added diff since.

// originally based on http://en.wikipedia.org/wiki/User:Omegatron/monobook.js // see also http://en.wikipedia.org/wiki/User:Matthewmayer/monobook.js

// see also Bug 424 http://bugzilla.wikipedia.org/show_bug.cgi?id=424

var $watchlist = new Module('watchlist.js'); $watchlist.depend('wikipage.js', 'util.js', 'wikiwatch.js', 'diffsince.js');

$watchlist.options = { enabled: true, textlink_diffsince: 'since', textlink_unwatch: 'unwatch', textlink_watch: 'watch' };

$watchlist.wp = {};

$watchlist.wuwatchAsync = function(wp) { if (!wp) { return $watchlist.error("internal error 72192d74-ab57-4a98-917f-8c6ca03b0559"); }

var updateWuwLink = function(wpX, nextWuwAction) { if (!wpX) return; // don't use just "$util.findHref(wpX.url)", because if the target is       // a User or User talk page, we don't want to accidentally match the // contributor link. if (!$watchlist._addremoveStrikeThrough(nextWuwAction, wpX.targetLink)) { $watchlist.error("$watchlist.wuwatchAsync: Couldn't annotate link for '" + wpX.page + "'"); }

wpX.nextWuwAction = nextWuwAction; wpX.unwatchLink.innerHTML = (           nextWuwAction ? $watchlist.options.textlink_watch : $watchlist.options.textlink_unwatch); wpX.unwatchLink.href = $wikiwatch.makeUrl(wp, nextWuwAction); }

var lookupWp = function(wp) { return wp && $watchlist.wp[wp.page]; }

var cb = function { // note: wp.talkPage can be null for certain non-talkable pages var wpNT = lookupWp(wp.notalkPage); var wpT = lookupWp(wp.talkPage); if (!wpT && !wpNT) { $watchlist.error("wuwatchAsync: neither talkPage nor notalkPage found (error 16e495b9-d198-4b80-8e9d-ba4088b77a98)"); return; }       var nextWuwAction = !wp.nextWuwAction; updateWuwLink(wpT, nextWuwAction); updateWuwLink(wpNT, nextWuwAction); }

$wikiwatch.wuwatchAsync(wp.nextWuwAction, wp, cb, wp.unwatchSpan); return false; }

$watchlist.diffSince = function(wp) { if (!wp) { return $watchlist.error("## internal error 72192d74-ab57-4a98-917f-8c6ca03b0559"); } return $diffsince.diffPageAsync(wp, wp.diffsinceSpan); }

$watchlist._addremoveStrikeThrough = function(addp, node) { // return node && $util.insertNode(node, document.createElement('s')); if (!node) return 0;

if (addp) { $util.addClass($util.ensureSpan(node), 'history-deleted'); } else { $util.removeClass($util.ensureSpan(node), 'history-deleted'); }   return 1; }

$watchlist.widgetLoad = function {   $util.addOnloadHook(function {            if (wikiPage.page.match(/^Special:Watchlist/)) $watchlist._annotatePage;        }); }

$watchlist._annotatePage = function { // everything disabled? if (!$watchlist.options.enabled) return; $watchlist.debug("Annotating watchlist with unwatch & since links");

var annotateLine = function(histLink, targetLink) { // note: 'wp' is needed by the onclick closure below -- do not just // put this inside the 'for' loop! var wp = new WikiPage(histLink.href); wp.targetLink = targetLink; $watchlist.wp[wp.page] = wp;

wp.nextWuwAction = 0; wp.unwatchSpan = document.createElement('span'); wp.unwatchLink = document.createElement('a'); wp.unwatchLink.innerHTML = $watchlist.options.textlink_unwatch; wp.unwatchLink.href = $wikiwatch.makeUrl(wp, 0); wp.unwatchLink.onclick = function { return $watchlist.wuwatchAsync(wp) }; wp.unwatchSpan.appendChild(wp.unwatchLink); $util.addNodeAfter(histLink, wp.unwatchSpan); $util.addNodeAfter(histLink, document.createTextNode('; '));

wp.diffsinceSpan = document.createElement('span'); var diffsinceLink = document.createElement('a'); diffsinceLink.innerHTML = $watchlist.options.textlink_diffsince; diffsinceLink.href = $diffsince.makeUrl(wp); diffsinceLink.onclick = function { return $watchlist.diffSince(wp) }; wp.diffsinceSpan.appendChild(diffsinceLink); $util.addNodeBefore(histLink, wp.diffsinceSpan); $util.addNodeBefore(histLink, document.createTextNode('; ')); }

var links = $util.copyArray(document.getElementById('bodyContent').getElementsByTagName('a')); var targetLink; for (i in links) { var link = links[i]; if (!link.href) continue; if (link.href.match(/^http:\/\/(?:[^\/]+?)\/wiki\//)) { targetLink = link; continue; }       if (link.href.match(/&action=history$/)) { if (link.id == 'newmessages-hist') continue; annotateLine(link, targetLink); }   } }

/* watchbutton.js */

// $Id: watchbutton.js 612 2006-02-17 03:12:55Z quarl $

// watchbutton.js - change standard watch/unwatch tab to be // asynchronous.

// USAGE: //  $module.depend('watchbutton.js'); //  $watchbutton.widgetLoad;

// quarl 2006-02-03 initial version

var $watchbutton = new Module('watchbutton.js'); $watchbutton.depend('wikiwatch.js', 'util.js');

$watchbutton.options = { enabled: true };

$watchbutton.toggleAsync = function { $wikiwatch.wuwatchAsync(! $watchbutton.currentlyWatched, wikiPage,                           $watchbutton._wuwSuccess, $watchbutton.tab); return false; }

$watchbutton._wuwSuccess = function { $watchbutton.currentlyWatched = !$watchbutton.currentlyWatched; if ($watchbutton.currentlyWatched) { $watchbutton.link.innerHTML = 'Unwatch'; $watchbutton.link.href = wikiPage.qurl + '&action=unwatch'; $watchbutton.link.title = 'Remove this page from your watchlist'; } else { $watchbutton.link.innerHTML = 'Watch'; $watchbutton.link.href = wikiPage.qurl + '&action=watch'; $watchbutton.link.title = 'Add this page to your watchlist'; } }

$watchbutton.widgetLoad_ = function {   if (!$watchbutton.options.enabled) return;

if (($watchbutton.tab = document.getElementById('ca-unwatch'))) { $watchbutton.currentlyWatched = true; } else if (($watchbutton.tab = document.getElementById('ca-watch'))) { $watchbutton.currentlyWatched = false; } else { // couldn't find watch/unwatch button. return; }

$watchbutton.link = $watchbutton.tab.getElementsByTagName('a')[0]; $watchbutton.link.onclick = $watchbutton.toggleAsync;

}

$watchbutton.widgetLoad = function { $util.addOnloadHook($watchbutton.widgetLoad_); }

/* autofocus.js */

// $Id: autofocus.js 441 2006-02-14 11:21:27Z quarl $

// autofocus.js - Auto-focus the cursor to appropriate edit fields.

// Edit page: focus the main edit area. // Move page: focus the new page title.

// usage: //    $module.depend('autofocus.js'); //    $autofocus.enable;

// quarl 2006-01-03 initial version

var $autofocus = new Module('autofocus.js'); $autofocus.depend('wikipage.js');

$autofocus.run = function { if (wikiDoc.editingP && !wikiDoc.previewP) { if (wikiDoc.newSectionP) { document.forms.editform.wpSummary.focus; } else { document.forms.editform.wpTextbox1.focus; }       return; }

if (wikiDoc.movePageP) { document.forms.movepage.wpNewTitle.focus; return; } }

$autofocus.enable = function { $util.addOnloadHook($autofocus.run); }

/* autosummary.js */

// $Id: autosummary.js 1257 2006-02-25 08:05:33Z quarl $

// autosummary.js - automatically fill in edit summary based on diff; short cuts

// quarl 2006-01-26 added shortcuts // quarl 2006-01-30 auto diff

// TODO: add a checkbox for "auto" next to summary, to disable auto diff

var $autosummary = new Module('autosummary.js'); $autosummary.depend('wikipage.js', 'wikiedit.js', 'util.js', 'diff.js', 'shortcuts.js'); // recommends: smartsubmit.js

// see also: Edit_summary_legend $autosummary.shortcuts = Shortcuts({ // 'ed' : 'editing', // 'edit'  'cped,cpediting,cpyed,copyed,copyedit' : 'copy-editing',  'mn ' : 'minor',  'mnf ' : 'minor fixes',  'fmt' : 'formatting',  'mfmt ' : 'minor formatting',  'rv' : 'reverting',  'rvv' : 'reverting vandalism',  'gr' : 'grammar',  'sp' : 'spelling',  'rd ' : 'redirect',  'cmt' : 'commenting',  'cla' : 'clarifying',  'xl,xlink' : 'external link',  'sa' : 'see also',  'cap' : 'capitalization',  'catz' : 'categorizing',  'cl,cu' : 'cleaning up',  'newart,creat' : 'creating new article',  'dab,disamb,disam,disambig' : 'disambiguating',  'rddab' : 'replacing redirect with disambiguation page',  //'st' : 'see Talk page',  // 'style' : 'style',  'punc,punct,pnct' : 'punctuation',  'wfy,wkfy' : 'wikifying' });

$autosummary.options = { prompt : 'Enter edit summary.',

// whether to query even when filled via auto diff query: true,

// whether to default edit summary to diff (not needed if   // $autosummary.auto_diff is enabled) diff: true,

// whether to automatically prepend "(auto diff)" to edit summary while // editing. Use number of seconds for update interval (in sec), or false // to disable. auto_diff: 1.5,

// whether to automatically select text after the /* section */ and Â« diff // Â» auto_select: true,

// whether shortcut expansion is enabled shortcuts_enabled: false };

$autosummary.load = function {   if (!wikiDoc.editingP) return; if (wikiDoc.newSectionP) return;

if ($autosummary.options.auto_diff) { $autosummary._autoDiffSetup; }

if ($autosummary.options.auto_select) { $util.hookEventObj(document.editform.wpSummary, 'focus', $autosummary._focusSummaryEvent); }

$util.hookEventObj(document.editform.wpSave, 'click', $autosummary._preSubmitEvent); }

$autosummary._autoDiffSetup = function { $util.hookEventObj(document.editform.wpTextbox1, 'blur', $autosummary._updateAutoDiff); $autosummary.intervalHandle = setInterval($autosummary._updateAutoDiff,                                             1000*$autosummary.options.auto_diff); }

$autosummary._textFilter = function(s) { // ignore signature when diffing return s.replace(/~/g,).replace(/<span class=[\'\"]user-sig.*?<\/span>/g, ); }

$autosummary._diffStrings = function(s1,s2) { return $diff.diffSummary($autosummary._textFilter(s1), $autosummary._textFilter(s2)); }

$autosummary.diffTextbox = function { var editor = wikiPage.getEditor; return $autosummary._diffStrings(editor.wpTextbox1_orig, editor.wpTextbox1); }

// update the edit summary with diff $autosummary._updateAutoDiff = function { var editor = wikiPage.getEditor; editor.updateThis;

if (editor.wpTextbox1_prev == editor.wpTextbox1) { // no change since last update return; }   editor.wpTextbox1_prev = editor.wpTextbox1;

var s = $autosummary.diffTextbox; if (s) { if (wikiDoc.editingNewP) { // add "Creating page" since edit summary survives page moves s = s.replace(/^new /,                         $util.pprintf("Creating $1 ", wikiPage.page)); }

s = "Â«" + s + "Â» "; }

if (editor.wpSummary.match(/\Â«/)) { editor.wpSummary = editor.wpSummary.replace(/Â«.*?Â» */, s); } else if (s && !$autosummary._pruneSection(editor.wpSummary)) { editor.wpSummary = $util.trimSpaces(editor.wpSummary); if (editor.wpSummary) editor.wpSummary += ' '; editor.wpSummary += s;   }

editor.updateForm; }

$autosummary._preSubmitEvent = function(event) {   if ($autosummary.options.auto_diff) $autosummary._updateAutoDiff; var editor = wikiPage.getEditor; editor.updateThis; var r = $autosummary._edit(editor); editor.updateForm;

if (!r) { event.preventDefault; event.stopPropagation; } }

// auto focus $autosummary._focusSummaryEvent = function(event) { var sumField = document.editform.wpSummary; if (sumField.value.match(/^(?:\/\*.*?\*\/)?\s*(?:Â«(?:.*)Â»)? ?/)) {       var n = RegExp.lastMatch.length; var m = sumField.value.length; // apparently you can't setSelectionRange in an onFocus handler, but // you can set a timer to do it 0 seconds from now. setTimeout(function { sumField.setSelectionRange(n, m) }, 0); } }

$autosummary._pruneSection = function(s) { return $util.trimSpaces(s.replace(/^\/\\*.*?\\*\//,'')); }

$autosummary._edit = function(editor) {   if (editor.wpTextbox1_orig == editor.wpTextbox1) { // no change return true; }

var auto = false;

if (!editor.wpSummary.match(/REDIRECT/i) &&       editor.wpTextbox1.match(/^#REDIRECT/i)) {       // it's a redirect. Annotate with REDIRECT. if ($autosummary.options.auto_diff) { // don't need auto diff // editor.wpSummary = editor.wpSummary.replace(/^ã€ˆ.*?ã€‰ */, ''); }       editor.wpSummary += editor.wpTextbox1; auto = true; } else if ($autosummary._pruneSection(editor.wpSummary)) { // non-negligible summary exists; continue with submission if ($autosummary.options.shortcuts_enabled) { editor.wpSummary = $autosummary.shortcuts.substWords(editor.wpSummary); }       return true; } else if ($autosummary.options.diff) { // if we get here then we're not using auto diff, or user manually // removed it       var s = $autosummary.diffTextbox; if (s) { editor.wpSummary += s;           auto = true; }   }

if (!auto || $autosummary.options.query) { var pr = $autosummary.options.prompt; if ($autosummary.options.shortcuts_enabled) { pr += ' ' + $autosummary.shortcuts.msg; }

var r = window.prompt(pr, editor.wpSummary); if(r == null) { return false; } // cancel if ($autosummary.options.shortcuts_enabled) { editor.wpSummary = $autosummary.shortcuts.substWords(r); }   }

return true; }

$util.addOnloadHook($autosummary.load);

/* smartsubmit.js */

// $Id: smartsubmit.js 915 2006-02-22 06:07:39Z quarl $

// smartsubmit.js - smarter diff/preview buttons

// Instead of navigating to a new page, the "Show preview" and "Show //  changes" buttons download the target asynchronously and update the current // page. // // Advantages: // - Can continue editing without losing changes // - Can use up to 250 characters in edit summary (normally, preview/diff //    would cut to 200 characters) // - enhances auto_summary.js: the auto diff is based on the "previous" //   version of the page, but normally pressing preview/diff would cause the //   preview version to be "previous", as there is no way to save the //   original text // - enhances $autoreplace.js (including advanced_sig.js): replacements not //   substituted in the edit box on preview/diff // - don't lose cursor position in text box

// Side effects: // - Since the browser doesn't navigate the window to a new location, it //    doesn't register as a history event (i.e. "back" goes to the page //    visited before any initial editing)

// quarl 2006-02-02 initial version

var $smartsubmit = new Module('smartsubmit.js'); $smartsubmit.depend('wikiedit.js', 'util.js'); // enhances: wikiedit.js, $autoreplace.js, auto_summary.js

$smartsubmit.options = { enabled: true, focus_after_download: true };

$smartsubmit.load = function { if (!$smartsubmit.options.enabled) return;

if (!wikiDoc.editingP) return;

if (!$smartsubmit.annotatePageInit) return;

document.editform.wpDiff.preventPreSumitHook = true; $util.hookEventObj(document.editform.wpDiff, 'click',                     function(event){$smartsubmit.click(event,'wpDiff');}); document.editform.wpPreview.preventPreSumitHook = true; $util.hookEventObj(document.editform.wpPreview, 'click',                     function(event){$smartsubmit.click(event,'wpPreview');}); }

// returns true value on success $smartsubmit.annotatePageInit = function { var divLoc = document.getElementById('jump-to-nav'); if (!divLoc) { return $smartsubmit.error("couldn't get 'jump-to-nav' (error 1639a197-bdd2-4e9d-9777-9c8a5987fe2c)"); }   $smartsubmit.div = document.createElement('div'); $smartsubmit.div.id = 'smartsubmit-preview'; $util.addNodeAfter(divLoc, $smartsubmit.div);

// create an empty <a> so that we can focus on it   $smartsubmit.focusloc = document.createElement('a'); $smartsubmit.focusloc.id = 'smartsubmit-focusloc'; $util.addNodeAfter(divLoc, $smartsubmit.focusloc);

return true; }

$smartsubmit.focusPreview = function { $smartsubmit.focusloc.focus; }

// The user clicked wpDiff or wpPreview. Instead of submitting, we're going // to make a new asynchronous request, download the data, insert into the // current page. $smartsubmit.click = function(event, button) { if (!$smartsubmit.options.enabled) { return true; }

// don't allow multiple concurrent clicks document.editform[button].disabled = true; $smartsubmit.div.innerHTML = 'Submitting...';

wikiPage.getEditor.submitAsync(button, $smartsubmit.updatePage, button);

event.preventDefault; event.stopPropagation; return false; }

$smartsubmit.updatePage = function(req, button) { if (button == 'wpDiff') { var divId = 'wikiDiff'; } else if (button == 'wpPreview') { var divId = 'wikiPreview'; } else { $smartsubmit.error("internal error dcd4ab5a-4e10-4576-9cd5-874d589455da"); return; }

var editor = this; // re-enable button document.editform[button].disabled = false; if (req.status != 200) { $smartsubmit.error("downloading page failed! (error af129b48-ac16-4459-bf8c-86ed9e38d8f0)"); $smartsubmit.options.enabled = false; wikiPage.getEditor.submit(button); return; }

var newDoc = req.responseXML;

var newDiv = newDoc.getElementById(divId);

if (!newDiv) { $smartsubmit.warning("Couldn't get "+divId+" from downloaded document (error e3f57370-85c8-4ab6-8430-00d6441b828b)"); // fall back: disable and do normal submit $smartsubmit.options.enabled = false; wikiPage.getEditor.submit(button); return; }

// clear and add newDiv $smartsubmit.div.innerHTML = ''; $smartsubmit.div.appendChild(newDiv);

if ($smartsubmit.options.focus_after_download) { $smartsubmit.focusPreview; } }

$util.addOnloadHook($smartsubmit.load);

/* newmessages.js */

// $Id: newmessages.js 1356 2006-03-11 21:03:42Z quarl $

// newmessages.js // - annotate the "You have new messages" alert to add "diff since" and "hist" //  links. // - tag fake "new messages" boxes as such // - touch talk on diff

// quarl 2006-01-16 initial version

var $newmessages = new Module('newmessages.js'); $newmessages.depend('wikipage.js', 'diffsince.js', 'util.js');

$newmessages.options = { // whether to add "since" and "hist" buttons to new messages boxes add_since_hist: true,

// whether fake "New messages" boxes should be marked as such tag_fake: true,

// whether to access the regular talk page when viewing diff of   // User_talk:Username so that Mediawiki registers message reads touch_talk_on_diff: true };

$newmessages.load = function { $newmessages.wpTalk = new WikiPage(null,'User talk:' + wikiDoc.username);

if ($newmessages.options.touch_talk_on_diff &&       wikiPage.page == $newmessages.wpTalk.page &&        WikiDocument.queryVars['diff']) {       $newmessages.touchTalk; }

var boxes = $util.getElementsByClass(       'usermessage', document.getElementById('bodyContent'),'div');

var seenreal = 0, seenfake = 0;

for (var i in boxes) { var box = boxes[i];

// People love to create lookalikes as a practical joke. The easiest // way to tell is that real talk message boxes are before the <div // id="jump-to-nav"> tag.

if (box.textContent.match(/^You have new messages \((?:diff|changes|last change)\)\.$/) &&           box.nextSibling.nextSibling.id == 'jump-to-nav') {           if (seenreal++) continue;               // at most one real $newmessages.annotateRealMessageBox(box); continue; }

if (box.textContent.match(/You have new messages/)) { // only bother tagging at most one fake box if (seenfake++) continue; $newmessages.annotateFakeMessageBox(box); }   } }

$newmessages.annotateRealMessageBox = function(talkmessagebox) {   if (!$newmessages.options.add_since_hist) return; var histUrl = $newmessages.wpTalk.qurl + '&action=history'; var diffSinceUrl = $diffsince.makeUrl($newmessages.wpTalk);

talkmessagebox.className += ' plainlinks';

var t = (' ( ' + '<a onclick="javascript:return $newmessages.diffSince" href="'+diffSinceUrl+'">' + 'diff since</a> )' +            ' (<a id="newmessages-hist" href="'+histUrl+'">history</a>)');

// insert before final period talkmessagebox.innerHTML = talkmessagebox.innerHTML.replace(/(?=[.]$)/, t); }

// People like to write a message box on their user/talk pages that look like // you have new messages. It's fun for a while but it gets old... $newmessages.annotateFakeMessageBox = function(talkmessagebox) {   if (!$newmessages.options.tag_fake) return; var sp = document.createElement('span'); sp.style.color = 'red'; sp.innerHTML = '(FAKE)';

talkmessagebox.insertBefore(sp, talkmessagebox.firstChild); }

$newmessages.diffSince = function { return $diffsince.diffPageAsync($newmessages.wpTalk,                           document.getElementById('newmessages-diffsince'),                            'diff since...'); };

// touch the talk page to register timestamp with Mediawiki. Idea by // User:Omegatron $newmessages.touchTalk = function { $newmessages.debug("Touching " + $newmessages.wpTalk.url); $util.asyncDownloadXML($newmessages.wpTalk.url, null); }

$util.addOnloadHook($newmessages.load);

/* tabsince.js */

// $Id: tabsince.js 1314 2006-02-27 11:12:21Z quarl $

// tabsince.js - add 'since' tab to show change since I last edited

// Left-click navigates asynchronously; new tab/window works as well.

// USAGE: //  $module.depend('tabsince.js'); //  $tabsince.widgetLoad;

// quarl 2006-01-16 rewritten to asynchronously download history page

var $tabsince = new Module('tabsince.js'); $tabsince.depend('wikipage.js', 'wikiwidget.js', 'diffsince.js');

$tabsince.load = function { if (wikiPage.nsSpecialP) return; $tabsince.widget = new WikiWidget({       default_location: {portlet: 'Actions'},        url: $diffsince.makeUrl(wikiPage),        onclick: $tabsince.run,        name: "Since",        id: "ca-since",        title: "Show changes since I last edited"}); }

$tabsince.run = function { return $diffsince.diffThis($tabsince.tab); }

$tabsince.widgetLoad = function(location) { $util.addOnloadHook(function {           if ($tabsince.widget) $tabsince.widget.add(location);        }); }

$util.addOnloadHook($tabsince.load);

/* */