User:Huntster/popups.js

var popupVersion="Tue Jun 13 14:17:20 EDT 2006"; // STARTFILE: main.js // ********************************************************************** // **                                                                 ** // **             changes to this file affect many users. ** // **          please discuss on the talk page before editing         ** // **                                                                 ** // ********************************************************************** // **                                                                  ** // ** if you do edit this file, be sure that your editor recognizes it ** // ** as utf8, or the weird and wonderful characters in the namespaces ** // **  below will be completely broken. You can check with the show  ** // **           changes button before submitting the edit. ** // **                     test: مدیا מיוחד Мэдыя                      ** // **                                                                 ** // **********************************************************************

//////////////////////////////////////////////////////////////////// // Import stylesheet(s) //

if ( window.localCSS ) { document.write(''); } else { document.write(''); }

////////////////////////////////////////////////// // Globals //

// Trying to shove as many of these as possible into the pg (popup globals) object window.pg = { re: {},              // regexps ns: {},              // namespaces string: {},          // translatable strings wiki: {},            // local site info misc: {},            // YUCK PHOOEY option: {},          // options, see newOption etc optionDefault: {},   // default option values flag: {},            // misc flags cache: {},           // page and image cache structures: {},      // navlink structures timer: {},           // all sorts of timers (too damn many) counter: {},         // .. and all sorts of counters current: {},         // state info endoflist: null }; window.pop = {         // wrap various functions in here init: {}, util: {}, endoflist: null }; function popupsReady { if (!window.pg) { return false; } if (!pg.flag) { return false; } if (!pg.flag.finishedLoading) { return false; } return true; } //////////////////////////////////////////////////////////////////// // Run things ////////////////////////////////////////////////////////////////////

addOnloadHook(setupPopups);

/// Local Variables: /// /// mode:c /// /// End: /// // ENDFILE: main.js // STARTFILE: actions.js function setupTooltips(container, remove) { log('setupTooltips, container='+container+', remove='+remove); if (!container) { // // the main initial call if (getValueOf('popupOnEditSelection') && window.doSelectionPopup ) { try { document.editform.wpTextbox1.onmouseup=function { doSelectionPopup; }; } catch (neverMind) {} } // // article/content is a structure-dependent thing container = defaultPopupsContainer; }

if (!remove && container.ranSetupTooltipsAlready) { return; } container.ranSetupTooltipsAlready = !remove;

var anchors; anchors=container.getElementsByTagName('A'); setupTooltipsLoop(anchors, 0, 250, 100, remove); }

function defaultPopupsContainer { if (getValueOf('popupOnlyArticleLinks')) { return document.getElementById('article') || document.getElementById('content') || document; }   return  document; }

function setupTooltipsLoop(anchors,begin,howmany,sleep, remove) { log(simplePrintf('setupTooltipsLoop(%s,%s,%s,%s,%s)', arguments)); var finish=begin+howmany; var loopend = min(finish, anchors.length); var j=loopend - begin; log ('setupTooltips: anchors.length=' + anchors.length + ', begin=' + begin + ', howmany=' + howmany + ', loopend=' + loopend + ', remove=' + remove); var doTooltip= remove ? removeTooltip : addTooltip; // try a faster (?) loop construct if (j > 0) { do { var a=anchors[loopend - j]; if (!a || !a.href) { log('got null anchor at index ' + loopend - j); continue; }			doTooltip(a); } while (--j); }	if (finish < anchors.length) { pop.runOnce(function {setupTooltipsLoop(anchors,finish,howmany,sleep,remove);}, sleep); } else { // now eliminate popups from the TOC if ( !remove && ! getValueOf('popupTocLinks')) { var toc=document.getElementById('toc'); if (toc) { var tocLinks=toc.getElementsByTagName('A'); var tocLen = tocLinks.length; for (j=0; j<tocLen; ++j) { log ('killing popup for toclinks[' + j + ']'); doTooltip(tocLinks[j], true); }				// looks like we just killed any onclick stuff that used to be going on in the toc // life is hard }		}		pg.flag.finishedLoading=true; } }

function addTooltip(a) { if ( !isPopupLink(a) ) { return; } var remTitles = getValueOf('removeTitles'); a.onmouseover=mouseOverWikiLink; a.onmouseout= mouseOutWikiLink; a.onclick= killPopup; a.hasPopup = true; if (remTitles && typeof a.originalTitle=='undefined') { a.originalTitle=a.title; a.title=''; } }

// function removeTooltip(a) { if ( !a.hasPopup ) { return; } a.onmouseover = null; a.onmouseout = null; if (a.originalTitle) { a.title = a.originalTitle; } a.hasPopup=false; } //

function registerHooks(np) { var popupMaxWidth=getValueOf('popupMaxWidth');

if (typeof popupMaxWidth == 'number') { var setMaxWidth = function { np.mainDiv.style.maxWidth = popupMaxWidth + 'px'; np.maxWidth = popupMaxWidth;

// hack for IE			// see http://www.svendtofte.com/code/max_width_in_ie/ // use setExpression as documented here on msdn: http://tinyurl dot com/dqljn

if (np.mainDiv.style.setExpression) { np.mainDiv.style.setExpression('width', 'document.body.clientWidth > ' +							      popupMaxWidth + ' ? "' +popupMaxWidth + 'px": "auto"'); }		};		np.addHook(setMaxWidth, 'unhide', 'before'); } // if (window.addPopupShortcuts && window.rmPopupShortcuts) { np.addHook(addPopupShortcuts, 'unhide', 'after'); np.addHook(rmPopupShortcuts, 'hide', 'before'); } // }

function mouseOverWikiLink { if (!window.popupsReady || !window.popupsReady) { return; } return mouseOverWikiLink2(this); }

function footnoteTarget(a) { var aTitle=Title.fromAnchor(a); // We want ".3A" rather than "%3A" or "?" here, so use the anchor property directly var anch = aTitle.anchor; if ( ! /^(_note-|endnote)/.test(anch) ) { return false; }

var lTitle=Title.fromURL(location.href); if ( lTitle.toString(true) != aTitle.toString(true) ) { return false; }	var el=document.getElementById(anch); while ( el && typeof el.nodeName == 'string') { var nt = el.nodeName.toLowerCase; if ( nt == 'li' ) { return el; } else if ( nt == 'body' ) { return false; } else if ( el.parentNode ) { el=el.parentNode; } else { return false; } }	return false; }

function footnotePreview(x) { setPopupHTML(' ' + x.innerHTML, 'popupPreview', pg.idNumber,		getValueOf('popupSubpopups') ? function {		setupTooltips(document.getElementById('popupPreview' + pg.idNumber));	} : null); }

function mouseOverWikiLink2(a) { // FIXME: should not generate the HTML until the delay has elapsed, //       and then popup immediately. Can be a CPU hog otherwise.

//log('mouseOverWikiLink: a='+a+', pg.current.link='+pg.current.link);

// try not to duplicate effort if ( a==pg.current.link && a.navpopup && a.navpopup.isVisible ) { return; } pg.current.link=a;

if (getValueOf('simplePopups') && pg.option.popupStructure===null) { // reset *default value* of popupStructure //log ('simplePopups is true and no popupStructure selected. Defaulting to "original"'); setDefault('popupStructure', 'original'); }

var article=(new Title).fromAnchor(a); // set global variable (ugh) to hold article (wikipage) pg.current.article = article; var diff=null; var history=null; var params=parseParams(a.href); var oldid=(typeof params.oldid=='undefined' ? null : params.oldid); // if(getValueOf('popupPreviewDiffs') && window.loadDiff) { diff=params.diff; // alert(params.diff); }	if(getValueOf('popupPreviewHistory') && getValueOf('popupUseQueryInterface')) { history=(params.action=='history'); } // if (pg.timer.image !== null) { clearInterval(pg.timer.image); pg.timer.image=null; pg.counter.checkImages=0; }

if (!a.navpopup) { log ('mouseoverwikilink2: creating new Navpopup'); a.navpopup = new Navpopup; a.navpopup.fuzz=5; a.navpopup.delay=getValueOf('popupDelay')*1000; // increment global counter now a.navpopup.popupIdNumber = ++pg.idNumber; registerHooks(a.navpopup); pg.current.links.push(a); }	if (a.navpopup.pending===null || a.navpopup.pending!==0) { // either fresh popups or those with unfinshed business are redone from scratch log ('doing popup content from scratch; a.navpopup.pending='+a.navpopup.pending); a.navpopup.setInnerHTML(popupHTML(a)); fillEmptySpans; } else { log ('using existing popup content - just showing'); }	a.navpopup.showSoonIfStable(a.navpopup.delay);

getValueOf('popupInitialWidth');

if (typeof pg.timer.checkPopupPosition==typeof 1) { clearInterval(pg.timer.checkPopupPosition); } pg.timer.checkPopupPosition=setInterval(checkPopupPosition, 600);

// if (getValueOf('popupLiveOptions')) { setPopupHTML(popupLiveOptionsHTML, 'popupLiveOptions', pg.idNumber,			    function  { popupToggleShowOptions(true); } ); }	if (getValueOf('popupRedlinkRemoval') && a.className=='new') { setPopupHTML(' '+popupRedlinkHTML, 'popupRedlink', pg.idNumber); } //

if(getValueOf('simplePopups')) { return; }

if (a.navpopup.pending!==0 ) { a.navpopup.pending=0; log('running unsimplify block'); var previewImage=true; var x;		pg.misc.gImage=null; //alert(diff+'\n'+oldid); if (x=footnoteTarget(a)) { footnotePreview(x); // } else if ( diff || diff === 0 ) { //alert([article,oldid,diff]); loadDiff(article, oldid, diff, a.navpopup); } else if ( history && getValueOf('popupUseQueryInterface') ) { loadQueryPreview('history', article, a.navpopup); } else if ( pg.re.contribs.test(a.href) && getValueOf('popupUseQueryInterface')) { loadQueryPreview('contribs', article, a.navpopup); } else if ( // FIXME should be able to get all preview combinations with options			article.namespace==pg.ns.image &&			( getValueOf('imagePopupsForImages') || ! anchorContainsImage(a) )			) { if (getValueOf('popupUseQueryInterface') && getValueOf('popupImageLinks')) { loadQueryPreview('imagelinks', article, a.navpopup); }			startArticlePreview(article, oldid, a.navpopup); loadImages(article); // } else if (article.namespace == pg.ns.category &&			  getValueOf('popupCategoryMembers')) { getValueOf('popupUseQueryInterface') && loadQueryPreview('category', article, a.navpopup); startArticlePreview(article, oldid, a.navpopup); }		else if (!article.namespace!=pg.ns.image && previewImage ) { startArticlePreview(article, oldid, a.navpopup); }	} }

function pendingNavpopTask(navpop) { if (navpop && navpop.pending===null) { navpop.pending=0; } ++navpop.pending; }

function completedNavpopTask(navpop) { if (navpop && navpop.pending) { --navpop.pending; } }

function startArticlePreview(article, oldid, navpop) { navpop.redir=0; loadPreview(article, oldid, navpop); }

function loadPreview(article, oldid, navpop) { log('loadPreview(' + article + ', ' + oldid + ', ' + navpop + ')'); pendingNavpopTask(navpop); getWiki(article, insertPreview, oldid, navpop); }

function loadPreviewFromRedir(redirMatch, navpop) { // redirMatch is a regex match var target = new Title.fromWikiText(redirMatch[2]); var trailingRubbish=redirMatch[4]; navpop.redir++; // if (window.redirLink) { var warnRedir = redirLink(target); setPopupHTML(warnRedir, 'popupWarnRedir'); } // fillEmptySpans({redir: true, redirTarget: target}); return loadPreview(target, null, navpop); }

function insertPreview(download) { if (!download.owner) { return; } var wikiText=download.data; var navpop=download.owner; var redirMatch = pg.re.redirect.exec(wikiText); completedNavpopTask(navpop); var art=pg.current.article;

if (navpop.redir===0 && redirMatch) { pg.current.redirSource=pg.current.article; loadPreviewFromRedir(redirMatch, navpop); return; }

var redirSource=pg.current.redirSource||''; // if ( window.makeFixDabs ) { if (navpop.redir===0) { // not a redir, so we don't have to specify an oldTarget makeFixDabs(wikiText); } else { makeFixDabs(wikiText, redirSource); }	} //</NOLITE> navpop.redirSource=null; navpop.redir=0;

// if (getValueOf('popupSummaryData') && window.getPageInfo) { var pgInfo=getPageInfo(wikiText, download); setPopupTrailer(pgInfo); }

if (window.getValidImageFromWikiText) { var imagePage=getValidImageFromWikiText(wikiText); if(imagePage) { loadImages(Title.fromWikiText(imagePage)); }	} //</NOLITE>

if (getValueOf('popupPreviews')) { if (download && typeof download.data == typeof ''){ if (pg.current.article.namespace==pg.ns.template && getValueOf('popupPreviewRawTemplates')) { // FIXME compare/consolidate with diff escaping code for wikitext var h=' <tt>' + download.data.entify.split('\\n').join(' \\n') + '</tt>'; setPopupHTML(h, 'popupPreview'); }			else { // deal with tricksy anchors var anch=pg.current.article.anchorString; var d=anchorize(download.data, anch); var urlBase=joinPath([pg.wiki.articlebase, art.urlString]); var p=new Previewmaker(d.substring(0,10000), urlBase); p.showPreview; }		}	}

}

function anchorize(d, anch) { if (!anch) { return d; } var anchRe=RegExp('=+\\s*' + literalizeRegex(anch).replace(/[_ ]/g, '[_ ]') + '\\s*=+'); var match=d.match(anchRe); if(match && match.length > 0 && match[0]) { return d.substring(d.indexOf(match[0])); }

// now try to deal with == foo baz boom == -> #foo_baz_boom var lines=d.split('\n'); for (var i=0; i<lines.length; ++i) { lines[i]=lines[i].replace(RegExp('\\*?[|])?(.*?)[\\]]{2}', 'g'), '$2'); if (lines[i].match(anchRe)) { return d.split('\n').slice(i).join('\n').replace(RegExp('^[^=]*'), ''); }	}	return d; }

function killPopup { if (getValueOf('popupShortcutKeys') && window.rmPopupShortcuts) { rmPopupShortcuts; } if (!pg) { return; } pg.current.link && pg.current.link.navpopup && pg.current.link.navpopup.banish; pg.current.link=null; abortAllDownloads; window.stopImagesDownloading && stopImagesDownloading; if (pg.timer.checkPopupPosition !== null) { clearInterval(pg.timer.checkPopupPosition); pg.timer.checkPopupPosition=null; }	if (pg.timer.checkImages !== null) { clearInterval(pg.timer.checkImages); pg.timer.checkImages=null; } if (pg.timer.image !== null) { clearInterval(pg.timer.image); pg.timer.image=null; } return true; // preserve default action (eg from } // ENDFILE: actions.js // STARTFILE: domdrag.js /**  @fileoverview   The {@link Drag} object, which enables objects to be dragged around.

*************************************************  dom-drag.js   09.25.2001 www.youngpup.net **************************************************  10.28.2001 - fixed minor bug where events sometimes fired off the handle, not the root. *************************************************  Pared down, some hooks added by User:Lupin

Copyright Aaron Boodman. Saying stupid things daily since March 2001.

/**  Creates a new Drag object. This is used to make various DOM elements draggable. @constructor function Drag { /**	  Condition to determine whether or not to drag. This function should take one parameter, an Event. To disable this, set it to. @type Function */	this.startCondition = null; /**	  Hook to be run when the drag finishes. This is passed the final coordinates of the dragged object (two integers, x and y). To disables this, set it to. @type Function */	this.endHook = null; }

/**  Gets an event in a cross-browser manner. @param {Event} e  @private Drag.prototype.fixE = function(e) { if (typeof e == 'undefined') { e = window.event; } if (typeof e.layerX == 'undefined') { e.layerX = e.offsetX; } if (typeof e.layerY == 'undefined') { e.layerY = e.offsetY; } return e; }; /**  Initialises the Drag instance by telling it which object you want to be draggable, and what you want to drag it by. @param {DOMElement} o The "handle" by which  is dragged. @param {DOMElement} oRoot The object which moves when  is dragged, or   if omitted. Drag.prototype.init = function(o, oRoot) { var dragObj     = this; this.obj = o;	o.onmousedown   = function(e) { dragObj.start.apply( dragObj, [e]); }; o.dragging      = false; o.draggable     = true; o.hmode         = true; o.vmode         = true;

o.root = oRoot && oRoot !== null ? oRoot : o ;

if (isNaN(parseInt(o.root.style.left, 10))) { o.root.style.left  = "0px"; } if (isNaN(parseInt(o.root.style.top, 10))) { o.root.style.top    = "0px"; }

o.root.onthisStart = function{}; o.root.onthisEnd   = function{}; o.root.onthis      = function{}; };

/**  Starts the drag. @private @param {Event} e Drag.prototype.start = function(e) { var o = this.obj; // = this; e = this.fixE(e); if (this.startCondition && !this.startCondition(e)) { return; } var y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10); var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10); o.root.onthisStart(x, y);

o.lastMouseX   = e.clientX; o.lastMouseY   = e.clientY;

var dragObj     = this; o.onmousemoveDefault   = document.onmousemove; o.dragging             = true; document.onmousemove   = function(e) { dragObj.drag.apply( dragObj, [e] ); }; document.onmouseup     = function(e) { dragObj.end.apply( dragObj, [e] ); }; return false; }; /**  Does the drag. @param {Event} e  @private Drag.prototype.drag = function(e) { e = this.fixE(e); var o = this.obj;

var ey   = e.clientY; var ex   = e.clientX; var y = parseInt(o.vmode ? o.root.style.top : o.root.style.bottom, 10); var x = parseInt(o.hmode ? o.root.style.left : o.root.style.right, 10 ); var nx, ny;

nx = x + ((ex - o.lastMouseX) * (o.hmode ? 1 : -1));	ny = y + ((ey - o.lastMouseY) * (o.vmode ? 1 : -1));

this.obj.root.style[o.hmode ? "left" : "right"] = nx + "px"; this.obj.root.style[o.vmode ? "top" : "bottom"] = ny + "px"; this.obj.lastMouseX   = ex; this.obj.lastMouseY   = ey;

this.obj.root.onthis(nx, ny); return false; };

/**  Ends the drag. @private Drag.prototype.end = function { document.onmousemove=this.obj.onmousemoveDefault; document.onmouseup  = null; this.obj.dragging   = false; if (this.endHook) { this.endHook( parseInt(this.obj.root.style[this.obj.hmode ? "left" : "right"], 10),			     parseInt(this.obj.root.style[this.obj.vmode ? "top" : "bottom"], 10)); } }; // ENDFILE: domdrag.js // STARTFILE: liveoptions.js // ////////////////////////////////////////////////// // live options nonsense //

function popupToggleVar(varstring) { pg.option[varstring] = ! getValueOf(varstring); if (getValueOf('popupCookies')) { Cookie.create(pg.option[varstring], String(pg.option[varstring])); } }

function popupToggleShowOptions (dummy) { // just update state if dummy is true getValueOf('popupLiveOptionsExpanded'); if (!dummy) { pg.option.popupLiveOptionsExpanded=!pg.option.popupLiveOptionsExpanded; } setPopupHTML((pg.option.popupLiveOptionsExpanded) ? '&lt;&lt;' : '&gt;&gt;',		    'optionPopped'); var s=document.getElementById('popupOptionsDiv'); // if (!s) return; if (pg.option.popupLiveOptionsExpanded) { s.style.display='inline'; } else { s.style.display='none'; } }

function popupOptionsCheckboxHTML(varstring, label, title) { var html=' '; html += '<span title="'+title+'">'; html += '<input type="checkbox" id="'+varstring+'Checkbox" '; html += (window[varstring]) ? 'checked="checked" ' : ''; html += 'onClick="javascript:popupToggleVar(' + "'" + varstring + "'" +		')">' + label + ' '; return html; }

function popupLiveOptionsHTML { var html = ''; html += ' '; html += '<span title="' + popupString('Show/hide options') + '" '; html += 'style="border: thin dotted black; cursor: pointer" '; html += 'onClick="javascript:popupToggleShowOptions">'; html += 'Options <span id="optionPopped' + pg.idNumber + '"> '; html += ' '; html += ' '; html += popupOptionsCheckboxHTML('simplePopups', popupString('Simple popups'),					 popupString('Never download extra stuff for images/previews')); html += popupOptionsCheckboxHTML('popupNavLinks', popupString('Show navigation links'),					 popupString('Display navigation links at the top of the popup')); html += popupOptionsCheckboxHTML('popupImages', popupString('Show image previews'),					 popupString('Load images')); html += popupOptionsCheckboxHTML('popupSummaryData', popupString('Show summary data'),					 popupString('Show page summary data')); html += popupOptionsCheckboxHTML('popupPreviews', popupString('Show text previews'),					 popupString('Show previews'));

var extraOptions=[ 'imagePopupsForImages', 'popupAdminLinks', 'popupAppendRedirNavLinks', 'popupCookies', 'popupFixDabs', 'popupFixRedirs', 'popupHistoricalLinks', 'popupImagesFromThisWikiOnly', 'popupImagesToggleSize', 'popupLastEditLink', 'popupLiveOptions', 'popupLoadImagesSequentially', 'popupNeverGetThumbs', 'popupOnlyArticleLinks', 'popupPreviewKillTemplates', 'popupPreviewFirstParOnly', 'popupShortcutKeys', 'popupSimplifyMainLink', 'removeTitles' // no , ];	for (var i=0; i<extraOptions.length; ++i) { html += popupOptionsCheckboxHTML(extraOptions[i], extraOptions[i], popupString('Toggle this option')); }

html += ' '; return html; } //</NOLITE> // ENDFILE: liveoptions.js // STARTFILE: structures.js // pg.structures.original={}; pg.structures.original.popupLayout=function { return ['popupError', 'popupImage', 'popupTopLinks', 'popupTitle', 'popupData', 'popupOtherLinks', 'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'], 'popupMiscTools', ['popupRedlink', 'popupLiveOptions'], 'popupPrePreviewSep', 'popupPreview', 'popupPostPreview', 'popupFixDab']; }; pg.structures.original.popupRedirSpans=function { return ['popupRedir', 'popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks']; }; pg.structures.original.popupTitle=function (x) { log ('defaultstructure.popupTitle'); if (!getValueOf('popupNavLinks')) { return navlinkStringToHTML('< >',x.article,x.oldid); } return ''; }; pg.structures.original.popupTopLinks=function (x) { log ('defaultstructure.popupTopLinks'); if (getValueOf('popupNavLinks')) { return navLinksHTML(x.article, x.hint, x.oldid); } return ''; }; pg.structures.original.popupImage=function(x) { log ('original.popupImage, x.article='+x.article+', pg.idNumber='+pg.idNumber); return imageHTML(x.article); }; pg.structures.original.popupRedirTitle=pg.structures.original.popupTitle; pg.structures.original.popupRedirTopLinks=pg.structures.original.popupTopLinks;

function copyStructure(oldStructure, newStructure) { pg.structures[newStructure]={}; for (var prop in pg.structures[oldStructure]) { pg.structures[newStructure][prop]=pg.structures[oldStructure][prop]; } }

/** -- fancy -- **/ copyStructure('original', 'fancy'); pg.structures.fancy.popupTitle=function (x) { return navlinkStringToHTML('<font size=+0>< > ',x.article,x.oldid); }; pg.structures.fancy.popupTopLinks=function(x) { var hist='<<history|shortcut=h|hist>>|<<lastEdit|shortcut=/|last>>if(mainspace_en){|<<editors|shortcut=E|eds>>}'; var watch='<<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>>'; var move='<<move|shortcut=m|move>>'; return navlinkStringToHTML('if(talk){' +				  '<<edit|shortcut=e>>|<<new|shortcut=+|+>>*' + hist + '*' +				   '<<article|shortcut=a>>|<<editArticle|edit>>' + '*' + watch + '*' + move +				   '}else{<<edit|shortcut=e>>*' + hist +				   '*<<talk|shortcut=t|>>|<<editTalk|edit>>|<<newTalk|shortcut=+|new>>' +				   '*' + watch + '*' + move+'} ', x.article, x.oldid); }; pg.structures.fancy.popupOtherLinks=function(x) { var admin='<<unprotect|unprotectShort>>|<<protect|shortcut=p>>*<<undelete|undeleteShort>>|<<delete|shortcut=d|del>>'; var user='<<contribs|shortcut=c>>if(wikimedia){|<<count|shortcut=#|#>>}'; user+='if(ipuser){|< >}else{*<<email|shortcut=E|'+ popupString('email')+'>>}if(admin){*<<block|shortcut=b>>}';

var normal='<<whatLinksHere|shortcut=l|links here>>*<<relatedChanges|shortcut=r|related>>'; return navlinkStringToHTML(' if(user){' + user + '*}if(admin){'+admin+'if(user){ }else{*}}' + normal,				  x.article, x.oldid); }; pg.structures.fancy.popupRedirTitle=pg.structures.fancy.popupTitle; pg.structures.fancy.popupRedirTopLinks=pg.structures.fancy.popupTopLinks; pg.structures.fancy.popupRedirOtherLinks=pg.structures.fancy.popupOtherLinks;

/** -- fancy2 -- **/ // hack for User:MacGyverMagic copyStructure('fancy', 'fancy2'); pg.structures.fancy2.popupTopLinks=function(x) { // hack out the at the end and put one at the beginning return ' '+pg.structures.fancy.popupTopLinks(x).replace(RegExp(' $','i'),''); }; pg.structures.fancy2.popupLayout=function { // move toplinks to after the title return ['popupError', 'popupImage', 'popupTitle', 'popupData', 'popupTopLinks', 'popupOtherLinks', 'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'], 'popupMiscTools', ['popupRedlink', 'popupLiveOptions'], 'popupPrePreviewSep', 'popupPreview', 'popupPostPreview', 'popupFixDab']; };

/** -- menus -- **/ copyStructure('original', 'menus'); pg.structures.menus.popupLayout=function { return ['popupError', 'popupImage', 'popupTopLinks', 'popupTitle', 'popupOtherLinks', 'popupRedir', ['popupWarnRedir', 'popupRedirTopLinks', 'popupRedirTitle', 'popupRedirData', 'popupRedirOtherLinks'], 'popupData', 'popupMiscTools', ['popupRedlink', 'popupLiveOptions'], 'popupPrePreviewSep', 'popupPreview', 'popupPostPreview', 'popupFixDab']; }; function toggleSticky(uid) { var popDiv=document.getElementById('navpopup_maindiv'+uid); if (!popDiv) { return; } if (!popDiv.navpopup.sticky) { popDiv.navpopup.stick; } else { popDiv.navpopup.unstick; popDiv.navpopup.hide; } } pg.structures.menus.popupTopLinks = function (x, shorter) { // FIXME this stuff should be cached var s=[]; var dropdiv='<div class="popup_drop">'; var enddiv=' '; var endspan=' '; var hist='<<history|shortcut=h>>'; if (!shorter) { hist = ' ' + hist + '|<<historyfeed|rss>>if(mainspace_en){|<<editors|shortcut=E>>} '; } var lastedit='<<lastEdit|shortcut=/|show last edit>>'; var jsHistory='<<lastContrib|last set of edits>><<sinceMe|changes since mine>>'; var linkshere='<<whatLinksHere|shortcut=l|what links here>>'; var related='<<relatedChanges|shortcut=r|related changes>>'; var search=' <<search|shortcut=s>>if(wikimedia){|<<globalsearch|shortcut=g|global>>}' + '|<<google|shortcut=G|web>> '; var watch=' <<unwatch|unwatchShort>>|<<watch|shortcut=w|watchThingy>> '; var protect='<<unprotect|unprotectShort>>|<<protect|shortcut=p>>|<<protectlog|log>>'; var del='<<undelete|undeleteShort>>|<<delete|shortcut=d>>|<<deletelog|log>>'; var move='<<move|shortcut=m|move page>>'; var nullPurge=' <<nullEdit|shortcut=n|null edit>>|<<purge|shortcut=P>> '; var viewOptions=' <<view|shortcut=v>>|<<render|shortcut=S>>|< > '; var editRow='if(oldid){ <<edit|shortcut=e>>|<<editOld|shortcut=e|this revision>> ' + '<<revert|shortcut=v>>' + '}else{<<edit|shortcut=e>>}'; var newTopic='if(talk){<<new|shortcut=+|new topic>>}'; var protectDelete='if(admin){ ' + protect + ' ' + del + ' }';

if (getValueOf('popupActionsMenu')) { s.push( '< >*' + dropdiv + '<a href="#">'+popupString('actions') + '</a>'); } else { s.push( dropdiv + '< >'); }	s.push( ' ') s.push( editRow + newTopic + hist + lastedit ) if (!shorter) { s.push(jsHistory); } s.push( move + linkshere + related) if (!shorter) { s.push(nullPurge + search); } if (!shorter) { s.push(viewOptions); } s.push(' ' + watch + protectDelete); s.push(' ' +	      'if(talk){<<article|shortcut=a|view article>><<editArticle|edit article>>}' +	       'else{<<talk|shortcut=t|talk page>><<editTalk|edit talk>>' + 	       '<<newTalk|shortcut=+|new topic>>} ' + enddiv); // user menu starts here var email='<<email|shortcut=E|email user>>'; var contribs=	'if(wikimedia){ }<<contribs|shortcut=c|contributions>>' + 'if(wikimedia){|<<contribsTree|tree>> }';

s.push('if(user){*' + dropdiv + '<a href="#">'+popupString('user')+'</a>'); s.push(' '); + s.push(' <<userPage|shortcut=u|user page>>|<<userSpace|space>> '); s.push('<<userTalk|shortcut=t|user talk>><<editUserTalk|edit user talk>>' +	      '<<newUserTalk|shortcut=+|leave comment>>'); if(!shorter) { s.push( 'if(ipuser){< >}else{' + email + '}') } else { s.push( 'if(ipuser){}else{' + email + '}') } s.push(' ' + contribs + '<<userlog|shortcut=L|user log>>'); s.push('if(wikimedia){<<count|shortcut=#|edit counter>>}'); s.push('if(admin){ <<unblock|unblockShort>>|<<block|shortcut=b|block user>> }'); s.push('<<blocklog|shortcut=B|block log>>' + getValueOf('popupExtraUserMenu')); s.push(' ' + enddiv + '}');

// popups menu starts here if (getValueOf('popupSetupMenu')) { s.push('*' + dropdiv + '<a href="#">' + popupString('popupsMenu') + '</a> '); s.push('<<togglePreviews|toggle previews>>'); s.push('<<purgePopups|reset>>'); s.push('<<disablePopups|disable>>'); s.push(' '+enddiv); }	return navlinkStringToHTML(s.join(''), x.article, x.oldid); };

pg.structures.menus.popupRedirTitle=pg.structures.menus.popupTitle; pg.structures.menus.popupRedirTopLinks=pg.structures.menus.popupTopLinks;

copyStructure('menus', 'shortmenus'); pg.structures.shortmenus.popupTopLinks=function(x) { return pg.structures.menus.popupTopLinks(x,true); };

//</NOLITE> pg.structures.lite={}; pg.structures.lite.popupLayout=function { return ['popupTitle', 'popupPreview' ]; }; pg.structures.lite.popupTitle=function (x) { log ('structures.lite.popupTitle'); //return navlinkStringToHTML('< >',x.article,x.oldid); return ' <span class="popup_mainlink">' + x.article.toString + ' '; }; // ENDFILE: structures.js // STARTFILE: autoedit.js // function getParamValue(paramName, h) { if (typeof h == 'undefined' ) { h = document.location.href; } var cmdRe=RegExp('[&?]'+paramName+'=([^&]*)'); var m=cmdRe.exec(h); if (m) { try { return decodeURI(m[1]); } catch (someError) {} }	return null; }

function substitute(data,cmdBody) { // alert('sub\nfrom: '+cmdBody.from+'\nto: '+cmdBody.to+'\nflags: '+cmdBody.flags); var fromRe=RegExp(cmdBody.from, cmdBody.flags); return data.replace(fromRe, cmdBody.to); }

function execCmds(data, cmdList) { for (var i=0; i<cmdList.length; ++i) { data=cmdList[i].action(data, cmdList[i]); }	return data; }

function parseCmd(str) { // returns a list of commands if (!str.length) { return []; } var p=false; switch (str.charAt(0)) { case 's': p=parseSubstitute(str); break; default: return false; }	if (p) { return [p].concat(parseCmd(p.remainder)); } return false; }

function unEscape(str, sep) { return str.split('\\\\').join('\\').split('\\'+sep).join(sep).split('\\n').join('\n'); }

function parseSubstitute(str) { // takes a string like s/a/b/flags;othercmds and parses it

var from,to,flags,tmp;

if (str.length<4) { return false; } var sep=str.charAt(1); str=str.substring(2);

tmp=skipOver(str,sep); if (tmp) { from=tmp.segment; str=tmp.remainder; } else { return false; }

tmp=skipOver(str,sep); if (tmp) { to=tmp.segment; str=tmp.remainder; } else { return false; }

flags=''; if (str.length) { tmp=skipOver(str,';') || skipToEnd(str, ';'); if (tmp) {flags=tmp.segment; str=tmp.remainder; } }

return {action: substitute, from: from, to: to, flags: flags, remainder: str};

}

function skipOver(str,sep) { var endSegment=findNext(str,sep); if (endSegment<0) { return false; } var segment=unEscape(str.substring(0,endSegment), sep); return {segment: segment, remainder: str.substring(endSegment+1)}; }

function skipToEnd(str,sep) { return {segment: str, remainder: ''}; }

function findNext(str, ch) { for (var i=0; i<str.length; ++i) { if (str.charAt(i)=='\\') { i+=2; } if (str.charAt(i)==ch) { return i; } }	return -1; }

function setCheckbox(param, box) { var val=getParamValue(param); if (val!==null) { switch (val) { case '1': case 'yes': case 'true': box.checked=true; break; case '0': case 'no': case 'false': box.checked=false; }	} }

function autoEdit { if (!document.editform) { return false; } if (window.autoEdit.alreadyRan) { return false; } window.autoEdit.alreadyRan=true; var cmdString=getParamValue('autoedit'); if (cmdString) { try { var editbox=document.editform.wpTextbox1; } catch (dang) { return; } var cmdList=parseCmd(cmdString); var input=editbox.value; var output=execCmds(input, cmdList); editbox.value=output; }	setCheckbox('autominor', document.editform.wpMinoredit); setCheckbox('autowatch', document.editform.wpWatchthis); var rvid = getParamValue('autorv'); if (getValueOf('popupUseQueryInterface') && getParamValue('autorv')) { var url=pg.wiki.wikibase + '/query.php?format=json&what=revisions&revids='+rvid; startDownload(url, null, autoEdit2); } else { autoEdit2; } }

function autoEdit2(d) { var summary=getParamValue('autosummary'); var summaryprompt=getParamValue('autosummaryprompt'); var summarynotice=''; if (d && d.data && getParamValue('autorv')) { var s = getRvSummary(summary, d.data); if (s===false) { summaryprompt=true; summarynotice=popupString('Failed to get revision information, please edit manually.\n\n'); summary = simplePrintf(summary, [getParamValue('autorv'), '(unknown)', '(unknown)']); } else { summary = s; } }	if (summaryprompt) { var txt= summarynotice + popupString('Enter a non-empty edit summary or press cancel to abort'); var response=prompt(txt, summary); if (response) { summary=response; } else { return; } }	if (summary) { document.editform.wpSummary.value=summary; }

var btn=getParamValue('autoclick'); if (btn) { if (document.editform && document.editform[btn]) { var headings=document.getElementsByTagName('h1'); if (headings) { var div=document.createElement('div'); var button=document.editform[btn]; div.innerHTML='<font size=+1><b>' + tprintf('The %s button has been automatically clicked. Please wait for the next page to load.',					 [ button.value ]) + '</b> '; document.title='('+document.title+')'; headings[0].parentNode.insertBefore(div, headings[0]); button.click; }		} else { alert(tprintf('Could not find button %s. Please check the settings in your javascript file.', [ btn ])); }	} }

function getRvSummary(template, json) { var o=getJsObj(json); try { var edit = anyChild(o.pages).revisions[0]; } catch (badness) {return false;} var timestamp = edit.timestamp.split(/[A-Z]/g).join(' ').replace(/^ *| *$/g, ''); return simplePrintf(template, [edit.revid, timestamp, edit.user]); }

addOnloadHook(autoEdit); //</NOLITE> // ENDFILE: autoedit.js // STARTFILE: downloader.js /** @fileoverview {@link Downloader}, a xmlhttprequest wrapper, and helper functions.

/**  Creates a new Downloader @constructor @class The Downloader class. Create a new instance of this class to download stuff. @param {String} url The url to download. This can be omitted and supplied later. function Downloader(url) { // Source: http://jibbering.com/2002/4/httprequest.html /** xmlhttprequest object which we're wrapping */ this.http = false;

/*@cc_on @*/ /*@if (@_jscript_version >= 5) // JScript gives us Conditional compilation, // we can cope with old IE versions. // and security blocked creation of the objects. try { this.http = new ActiveXObject("Msxml2.XMLHTTP"); } catch (e) { try { this.http = new ActiveXObject("Microsoft.XMLHTTP"); } catch (E) { // this.http = false; }	}	@end @*/

if (! this.http && typeof XMLHttpRequest!='undefined') { this.http = new XMLHttpRequest; } /**	   The url to download @type String */	this.url = url; /**	   A universally unique ID number @type integer */	this.id=null; /**	   Modification date, to be culled from the incoming headers @type Date @private */	this.lastModified = null; /**	   What to do when the download completes successfully @type Function @private */	this.callbackFunction = null; /**	   What to do on failure @type Function @private */	this.onFailure = null; /**	   Flag set on  	    @type boolean */	this.aborted = false; /**	  HTTP method. See http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html for possibilities. @type String */	this.method='GET'; /**	   Async flag. @type boolean */	this.async=true; }

new Downloader;

/** Submits the http request. */ Downloader.prototype.send = function (x) { if (!this.http) { return null; } return this.http.send(x); }; /** Aborts the download, setting the  field to true. */ Downloader.prototype.abort = function { if (!this.http) { return null; } this.aborted=true; return this.http.abort; }; /** Returns the downloaded data. */ Downloader.prototype.getData = function {if (!this.http) { return null; } return this.http.responseText;}; /** Prepares the download. */ Downloader.prototype.setTarget = function { if (!this.http) { return null; } this.http.open(this.method, this.url, this.async); }; /** Gets the state of the download. */ Downloader.prototype.getReadyState=function {if (!this.http) { return null; } return this.http.readyState;};

pg.misc.downloadsInProgress = { };

/** Starts the download. Note that setTarget {@link Downloader#setTarget} must be run first Downloader.prototype.start=function { if (!this.http) { return; } pg.misc.downloadsInProgress[this.id] = this; this.http.send(null); };

/** Gets the 'Last-Modified' date from the download headers. Should be run after the download completes. Returns  on failure. @return {Date} Downloader.prototype.getLastModifiedDate=function { if(!this.http) { return null; } var lastmod=null; try { lastmod=this.http.getResponseHeader('Last-Modified'); } catch (err) {} if (lastmod) { return new Date(lastmod); } return null; };

/** Sets the callback function. @param {Function} f callback function, called as  on success Downloader.prototype.setCallback = function (f) { if(!this.http) { return; } this.http.onreadystatechange = f; };

Downloader.prototype.getStatus = function { if (!this.http) { return null; } return this.http.status; };

////////////////////////////////////////////////// // helper functions

/** Creates a new {@link Downloader} and prepares it for action. @param {String} url The url to download @param {integer} id The ID of the {@link Downloader} object @param {Function} callback The callback function invoked on success @return {String/Downloader} the {@link Downloader} object created, or 'ohdear' if an unsupported browser function newDownload(url, id, callback, onfailure) { var d=new Downloader(url); if (!d.http) { return 'ohdear'; } d.id=id; d.setTarget; if (!onfailure) { onfailure=2; }	var f = function { if (d.getReadyState == 4) { delete pg.misc.downloadsInProgress[this.id]; try { if ( d.getStatus == 200 ) { d.data=d.getData; d.lastModified=d.getLastModifiedDate; callback(d); } else if (typeof onfailure == typeof 1) { if (onfailure > 0) { // retry newDownload(url, id, callback, onfailure - 1); }				} else if (typeof onfailure == 'function') { onfailure(d,url,id,callback); }			} catch (somerr) { /* ignore it */ } }	};	d.setCallback(f); return d; } /** Simulates a download from cached data. The supplied data is put into a {@link Downloader} as if it had downloaded it. @param {String} url The url. @param {integer} id The ID. @param {Function} callback The callback, which is invoked immediately as , where  is the new {@link Downloader}. @param {String} data The (cached) data. @param {Date} lastModified The (cached) last modified date. function fakeDownload(url, id, callback, data, lastModified, owner) { var d=newDownload(url,callback); d.owner=owner; d.id=id; d.data=data; d.lastModified=lastModified; return callback(d); }

/**  Starts a download. @param {String} url The url to download @param {integer} id The ID of the {@link Downloader} object @param {Function} callback The callback function invoked on success @return {String/Downloader} the {@link Downloader} object created, or 'ohdear' if an unsupported browser function startDownload(url, id, callback) { var d=newDownload(url, id, callback); if (typeof d == typeof '' ) { return d; } d.start; return d; }

/**  Aborts all downloads which have been started. function abortAllDownloads { for ( var x in pg.misc.downloadsInProgress ) { try { pg.misc.downloadsInProgress[x].aborted=true; pg.misc.downloadsInProgress[x].abort; delete pg.misc.downloadsInProgress[x]; } catch (e) { } } } // ENDFILE: downloader.js // STARTFILE: livepreview.js // TODO: location is often not correct (eg relative links in previews)

/** * InstaView - a Mediawiki to HTML converter in JavaScript * Version 0.6.1 * Copyright (C) Pedro Fayolle 2005-2006 * http://en.wikipedia.org/wiki/User:Pilaf * Distributed under the BSD license * * Changelog: * * 0.6.1 * - Fixed problem caused by \r characters * - Improved inline formatting parser * * 0.6 * - Changed name to InstaView * - Some major code reorganizations and factored out some common functions * - Handled conversion of relative links (i.e. /foo) * - Fixed misrendering of adjacent definition list items * - Fixed bug in table headings handling * - Changed date format in signatures to reflect Mediawiki's * - Fixed handling of Image:... * - Updated MD5 function (hopefully it will work with UTF-8) * - Fixed bug in handling of links inside images * * To do: * - Better support for $$ * - Full support for * - Parser-based (as opposed to RegExp-based) inline wikicode handling (make it one-pass and bullet-proof) * - Support for templates (through AJAX) * - Support for coloured links (AJAX) */

var Insta = {}

function setupLivePreview {

// options Insta.conf = {	   baseUrl: '',

user: {}, wiki: { lang: pg.wiki.lang, interwiki: pg.wiki.interwiki, default_thumb_width: 180 },	   paths: { articles: '/' + joinPath([pg.wiki.prePath, pg.wiki.articlePath]) + '/', math: '/math/', // FIXME images: ( window.getImageUrlStart ? getImageUrlStart(pg.wiki.hostname) : ''), images_fallback: 'http://upload.wikimedia.org/wikipedia/commons/', magnify_icon: 'skins/common/images/magnify-clip.png' },	   locale: { user: pg.ns.user, image: pg.ns.image, category: pg.ns.category, // shouldn't be used in popup previews, i think months: ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'] }	}

// options with default values or backreferences with (Insta.conf) { user.name = user.name || 'Wikipedian' user.signature = +user.name+ //paths.images = 'http://upload.wikimedia.org/wikipedia/' + wiki.lang + '/' }   // define constants Insta.BLOCK_IMAGE = new RegExp('^\\[\\['+Insta.conf.locale.image+				      ':.*?\\|.*?(?:frame|thumbnail|thumb|none|right|left|center)', 'i'); }

Insta.dump = function(from, to) {	if (typeof from == 'string') from = document.getElementById(from) if (typeof to == 'string') to = document.getElementById(to) to.innerHTML = this.convert(from.value) }

Insta.convert = function(wiki) {	var 	ll = (typeof wiki == 'string')? wiki.replace(/\r/g,'').split(/\n/): wiki, // lines of wikicode o='',	// output p=0,	// para flag $r	// result of passing a regexp to $ // some shorthands function remain { return ll.length } function sh { return ll.shift } // shift function ps(s) { o+=s } // push function f // similar to C's printf, uses ? as placeholders, ?? to escape question marks {		var i=1,a=arguments,f=a[0],o='',c,p for (i<a.length; i++) if ((p=f.indexOf('?'))+1) { // allow character escaping i -= c=f.charAt(p+1)=='?'?1:0 o += f.substring(0,p)+(c?'?':a[i]) f=f.substr(p+1+c) } else break; return o+f }	function html_entities(s) { return s.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;") } function max(a,b) { return (a>b)?a:b } function min(a,b) { return (a<b)?a:b } // return the first non matching character position between two strings function str_imatch(a, b)	{ for (var i=0, l=min(a.length, b.length); i<l; i++) if (a.charAt(i)!=b.charAt(i)) break return i	} // compare current line against a string or regexp // if passed a string it will compare only the first string.length characters // if passed a regexp the result is stored in $r function $(c) { return (typeof c == 'string') ? (ll[0].substr(0,c.length)==c) : ($r = ll[0].match(c)) } function $$(c) { return ll[0]==c } // compare current line against a string function _(p) { return ll[0].charAt(p) } // return char at pos p	function endl(s) { ps(s); sh } function parse_list {		var prev=''; while (remain && $(/^([*#:;]+)(.*)$/)) { var l_match = $r sh var ipos = str_imatch(prev, l_match[1]) // close uncontinued lists for (var i=prev.length-1; i >= ipos; i--) { var pi = prev.charAt(i) if (pi=='*') ps('</ul>') else if (pi=='#') ps('</ol>') // close a dl only if the new item is not a dl item (:, ; or empty) else switch (l_match[1].charAt(i)) { case'':case'*':case'#': ps('</dl>') } }			// open new lists for (var i=ipos; i<l_match[1].length; i++) { var li = l_match[1].charAt(i) if (li=='*') ps('<ul>') else if (li=='#') ps('<ol>') // open a new dl only if the prev item is not a dl item (:, ; or empty) else switch(prev.charAt(i)) { case'':case'*':case'#': ps('<dl>') } }			switch (l_match[1].charAt(l_match[1].length-1)) { case '*': case '#': ps('<li>' + parse_inline_nowiki(l_match[2])); break case ';': ps('<dt>') var dt_match // handle ;dt :dd format if (dt_match = l_match[2].match(/(.*?)(:.*?)$/)) { ps(parse_inline_nowiki(dt_match[1])) ll.unshift(dt_match[2]) } else ps(parse_inline_nowiki(l_match[2])) break case ':': ps('<dd>' + parse_inline_nowiki(l_match[2])) }			prev=l_match[1] }		// close remaining lists for (var i=prev.length-1; i>=0; i--) ps(f('</?>', (prev.charAt(i)=='*')? 'ul': ((prev.charAt(i)=='#')? 'ol': 'dl'))) }	function parse_table {		endl(f(' '); return			case '-': endl(f('<tr ?>', $(/\|-*(.*)/)[1])); break			default: parse_table_data		}		else if ($('!')) parse_table_data		else sh	}	function parse_table_data	{		var td_line, match_i		// 1: "|+", '|' or '+'		// 2: ??		// 3: attributes ??		// TODO: finish commenting this regexp		var td_match = sh.match(/^(\|\+|\||!)((?:([^[|]*?)\|(?!\|))?(.*))$/)		if (td_match[1] == '|+') ps('<caption');		else ps('<t' + ((td_match[1]=='|')?'d':'h'))		if (typeof td_match[3] != 'undefined') {			ps(' ' + td_match[3])			match_i = 4		} else match_i = 2		ps('>')		if (td_match[1] != '|+') {			// use || or !! as a cell separator depending on context			// NOTE: when split is passed a regexp make sure to use non-capturing brackets			td_line = td_match[match_i].split((td_match[1] == '|')? '||': /(?:\|\||!!)/)			ps(parse_inline_nowiki(td_line.shift))			while (td_line.length) ll.unshift(td_match[1] + td_line.pop)		} else ps(td_match[match_i])		var tc = 0, td = []		for (remain; td.push(sh))		if ($('|')) {			if (!tc) break // we're at the outer-most level (no nested tables), skip to td parse			else if (_(1)=='}') tc--		}		else if (!tc && $('!')) break		else if ($('{|')) tc++		if (td.length) ps(Insta.convert(td))	}	function parse_pre	{		ps(' ')		do endl(parse_inline_nowiki(ll[0].substring(1)) + "\n"); while (remain && $(' '))		ps(' ')	}	function parse_block_image	{		ps(parse_image(sh))	}

function parse_image(str) { // // get what's in between "" var tag = str.substring(Insta.conf.locale.image.length + 3, str.length - 2); var width; var attr = [], filename, caption = ''; var thumb=0, frame=0, center=0; var align=''; if (tag.match(/\|/)) { // manage nested links var nesting = 0; var last_attr; for (var i = tag.length-1; i > 0; i--) { if (tag.charAt(i) == '|' && !nesting) { last_attr = tag.substr(i+1); tag = tag.substring(0, i); break; } else switch (tag.substr(i-1, 2)) { case ']]': nesting++; i--; break; case '[[':						nesting--;						i--;				}			}			attr = tag.split(/\s*\|\s*/);			attr.push(last_attr);			filename = attr.shift;			var w_match;			for (attr.length; attr.shift)			if (w_match = attr[0].match(/^(\d*)px$/)) width = w_match[1]			else switch(attr[0]) {				case 'thumb':				case 'thumbnail':					thumb=true;				case 'frame':					frame=true;					break;				case 'none':				case 'right':				case 'left':					center=false;					align=attr[0];					break;				case 'center':					center=true;					align='none';					break;				default:					if (attr.length == 1) caption = attr[0];			}		} else filename = tag;		var o=;		if (frame) {			if (align==) align = 'right';			o += f("<div class='thumb t?'>", align);			if (thumb) {				if (!width) width = Insta.conf.wiki.default_thumb_width;				o += f("<div style='width:?px;'>?", 2+width*1, make_image(filename, caption, width)) +					f(" <a href='?' class='internal' title='Enlarge'><img src='?'></a> ? ",						Insta.conf.paths.articles + Insta.conf.locale.image + ':' + filename,						Insta.conf.paths.magnify_icon,						parse_inline_nowiki(caption)					)			} else {				o += ' ' + make_image(filename, caption) + f(" ? ", parse_inline_nowiki(caption))			}			o += '  ';		} else if (align != ) {			o += f("<div class='float?'> ?  ", align, make_image(filename, caption, width));		} else {			return make_image(filename, caption, width);		}		return center? f(" ? ", o): o; //</NOLITE>	}	function parse_inline_nowiki(str)	{		var start, lastend=0		var substart=0, nestlev=0, open, close, subloop;		var html=;		while (-1 != (start = str.indexOf(' ', substart))) {			html += parse_inline_wiki(str.substring(lastend, start));			start += 8;			substart = start;			subloop = true;			do {				open = str.indexOf(' ', substart);				close = str.indexOf(' ', substart);				if (close<=open || open==-1) {					if (close==-1) {						return html + html_entities(str.substr(start));					}					substart = close+9;					if (nestlev) {						nestlev--;					} else {						lastend = substart;						html += html_entities(str.substring(start, lastend-9));						subloop = false;					}				} else {					substart = open+8;					nestlev++;				}			} while (subloop)		}		return html + parse_inline_wiki(str.substr(lastend));	}	function make_image(filename, caption, width)	{ //				// uppercase first letter in file name		filename = filename.charAt(0).toUpperCase + filename.substr(1);		// replace spaces with underscores		filename = filename.replace(/ /g, '_');		caption = strip_inline_wiki(caption);		var md5 = hex_md5(filename);		var source = md5.charAt(0) + '/' + md5.substr(0,2) + '/' + filename;		if (width) width = "width='" + width + "px'";		var img = f("<img onerror=\"this.onerror=null;this.src='?'\" src='?' ? ?>", Insta.conf.paths.images_fallback + source, Insta.conf.paths.images + source, (caption!=)? "alt='" + caption + "'" : , width);		return f("<a class='image' ? href='?'>?</a>", (caption!=)? "title='" + caption + "'" : , Insta.conf.paths.articles + Insta.conf.locale.image + ':' + filename, img); //</NOLITE>	}	function parse_inline_images(str)	{ //		var start, substart=0, nestlev=0;		var loop, close, open, wiki, html;		while (-1 != (start=str.indexOf(, substart))) {			if(str.substr(start+2).match(RegExp('^' + Insta.conf.locale.image + ':','i'))) {				loop=true;				substart=start;				do {					substart+=2;					close=str.indexOf(,substart);					open=str.indexOf('[[',substart);					if (close<=open||open==-1) {						if (close==-1) return str;						substart=close;						if (nestlev) {							nestlev--;						} else {							wiki=str.substring(start,close+2);							html=parse_image(wiki);							str=str.replace(wiki,html);							substart=start+html.length;							loop=false;						}					} else {						substart=open;						nestlev++;					}				} while (loop)			} else break;		} //</NOLITE>		return str;	}	// the output of this function doesn't respect the FILO structure of HTML	// but since most browsers can handle it I'll save myself the hassle	function parse_inline_formatting(str)	{		var em,st,i,li,o=;		while ((i=str.indexOf("",li))+1) {			o += str.substring(li,i);			li=i+2;			if (str.charAt(i+2)=="'") {				li++;				st=!st;				o+=st?' ':' ';			} else {				em=!em;				o+=em?' ':' ';			}		}		return o+str.substr(li);	}	function parse_inline_wiki(str)	{		var aux_match;		str = parse_inline_images(str);		str = parse_inline_formatting(str);		// math		while (aux_match = str.match(/<(?:)math>(.*?)<\/math>/i)) {			var math_md5 = hex_md5(aux_match[1]);			str = str.replace(aux_match[0], f("<img src='?.png'>", Insta.conf.paths.math+math_md5));		}		// Build a Mediawiki-formatted date string		var date = new Date;		var minutes = date.getUTCMinutes;		if (minutes < 10) minutes = '0' + minutes;		var date = f("?:?, ? ? ? (UTC)", date.getUTCHours, minutes, date.getUTCDate, Insta.conf.locale.months[date.getUTCMonth], date.getUTCFullYear);		// text formatting		return str.			// signatures			replace(/~{5}(?!~)/g, date).			replace(/~{4}(?!~)/g, Insta.conf.user.name+' '+date).			replace(/~{3}(?!~)/g, Insta.conf.user.name).			// Category:..., Image:..., etc...			replace(RegExp('\\[\\[:((?:'+Insta.conf.locale.category+'|'+Insta.conf.locale.image+'|'+Insta.conf.wiki.interwiki+'):.*?)\\]\\]','gi'), "<a href='"+Insta.conf.paths.articles+"$1'>$1</a>").			replace(RegExp('\\[\\[(?:'+Insta.conf.locale.category+'|'+Insta.conf.wiki.interwiki+'):.*?\\]\\]','gi'),'').			// /Relative links			replace(/\[\[(\/[^|]*?)\]\]/g, f("<a href='?$1'>$1</a>", Insta.conf.baseUrl)).			// Relative links			replace(/\[\[(\/.*?)\|(.+?)\]\]/g, f("<a href='?$1'>$2</a>", Insta.conf.baseUrl)).			// Common links			replace(/\[\[([^|]*?)\]\](\w*)/g, f("<a href='?$1'>$1$2</a>", Insta.conf.paths.articles)).			// Links			replace(/\[\[(.*?)\|([^\]]+?)\]\](\w*)/g, f("<a href='?$1'>$2$3</a>", Insta.conf.paths.articles)).			// Namespace			replace(/\[\[([^\]]*?:)?(.*?)( *\(.*?\))?\|\]\]/g, f("<a href='?$1$2$3'>$2</a>", Insta.conf.paths.articles)). // External links replace(/\[$$