Nota: dopo aver pubblicato, potrebbe essere necessario pulire la cache del proprio browser per vedere i cambiamenti.

  • Firefox / Safari: tieni premuto il tasto delle maiuscole Shift e fai clic su Ricarica, oppure premi Ctrl-F5 o Ctrl-R (⌘-R su Mac)
  • Google Chrome: premi Ctrl-Shift-R (⌘-Shift-R su un Mac)
  • Internet Explorer / Edge: tieni premuto il tasto Ctrl e fai clic su Aggiorna, oppure premi Ctrl-F5
  • Opera: premi Ctrl-F5.
// <pre><nowiki>

recent2={
  // Edit these to your liking.
  // Make sure there's a comma at the end of each line.
  badwordsUrl:          'Utente:Wim_b/badwords',
  filterPage:           'Utente:Wim_b/Filtra_le_ultime_modifiche',
  allRecentPage:        'Utente:Wim_b/Tutte_le_ultime_modifiche',
  recentIPPage:         'Utente:Wim_b/Ultime_modifiche_anonime',
  monitorWatchlistPage: 'Utente:Wim_b/Segui_gli_osservati_speciali',
  spelldictUrl:         'Utente:Wim_b/Lista_degli_errori_comuni/Formato_macchina',
  spelldictPage:        'Utente:Wim_b/Controllo_ortografico',
  safePages: '[Ww]ikizionario:([Ii]ntroduction|[Ss]andbox|[Tt]utorial[^/]*/sandbox)|[Tt]emplate:(X[1-9]|Template sandbox))',
    linkify:              true,
    updateSeconds:        30,
    ipUserRegex:          RegExp('(User:)?((25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])\\.){3}' +
                                                    '(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]|[0-9])'),
    outputSeparator:      '<hr>',
    templateNamespace:    'Template',
    namespaces:           { 'Media':1, "Special":1, "User":1, "User talk":1, "Wikizionario":1,
                                                    "Discussioni Wikizionario":1, "File":1, "Discussioni File":1, "MediaWiki":1,
                                                    "Discussioni MediaWiki":1, "Template":1, "Discussioni Template":1, "Aiuto":1,
                                                    "Discussioni Aiuto":1, "Categoria":1, "Discussioni categoria":1, "Appendice":1, "Discussioni Appendice":1 },
    apiAulimitUser:        500,
    apiAulimitSysop:       5000,
    backgroundWindowsMax:  10,
    dummy: null // leave this last one alone
};

recent2.download=function(bundle) {
    // mandatory: bundle.url
    // optional:  bundle.onSuccess (xmlhttprequest, bundle)
    // optional:  bundle.onFailure (xmlhttprequest, bundle)
    // optional:  bundle.otherStuff OK too, passed to onSuccess and onFailure

    var x = window.XMLHttpRequest ? new XMLHttpRequest()
        : window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP")
        : false;

    if (x) {
        x.onreadystatechange=function() {
            x.readyState==4 && recent2.downloadComplete(x,bundle);
        };
        x.open("GET",bundle.url,true);
        x.send(null);
    }
    return x;
}

recent2.downloadComplete=function(x,bundle) {
    x.status==200 && ( bundle.onSuccess && bundle.onSuccess(x,bundle) || true )
    || ( bundle.onFailure && bundle.onFailure(x,bundle) || alert(x.statusText));
};

if (! recent2.outputPosition) { recent2.outputPosition=''; }
window.gettingBadWords=false;
window.badWords=null;

// paths
if ( typeof(wgServer)!='string' ||
        typeof(wgArticlePath)!='string' ||
        typeof(wgScriptPath)!='string') {
    recent2.articlePath= 'http://' + document.location.hostname + '/wiki/';
    recent2.scriptPath= 'http://' + document.location.hostname + '/w/';
} else {
    recent2.articlePath=mw.config.get('wgServer')+mw.config.get('wgArticlePath').replace(/\$1/, '');
    recent2.scriptPath=mw.config.get('wgServer')+mw.config.get('wgScriptPath')+'/';
}

recent2.getBadWords=function() {
    window.gettingBadWords=true;
    recent2.download({ url: recent2.scriptPath + 'index.php?title=' +
    recent2.badwordsUrl + '&action=raw&ctype=text/css&max-age=7200', // reload every 2 h
    onSuccess: recent2.processBadWords,
    onFailure: function () { setTimeout(recent2.getBadWords, 15000); return true;}});
}

window.diffCellRe=RegExp("<td class=\\\"diff-marker\\\">\\+<\\/td>\\s*" +
            "<td\\b[^>]*>\\s*<div>\\s*(.*?)\\s*<\\/div>\\s*<\\/td>", 'gi');


// processBadWords: generate the badWords RegExp from
// the downloaded data.
// d is the xmlhttprequest object from the download
recent2.processBadWords=function(d) {
    var data=d.responseText.split('\n');
    var phrase=[];
    var string=[];
    for (var i=0; i<data.length; ++i) {
        var s=data[i];

        // ignore empty lines, whitespace-only lines and lines starting with '<'
        if (/^\s*$|^</.test(s)) { continue; }

        // lines beginning and ending with a (back-)slash (and possibly trailing
        // whitespace) are treated as regexps
        if (/^([\\\/]).*\1\s*$/.test(s)) {
            var isPhrase=(s.charAt(0)=='/');
            // remove slashes and trailing whitespace
            s=s.replace(/^([\\\/])|([\\\/]\s*$)/g, '');
            // escape opening parens: ( -> (?:
            s=s.replace(/\(?!\?/g, '(?:');
            // check that s represents a valid regexp
            try { var r=new RegExp(s); }
            catch (err) {
    var errDiv=newOutputDiv('recent2_error', recent2.outputPosition);
    errDiv.innerHTML='Warning: ignoring odd-looking regexp on line '+i
        +' of <a href="/wiki/' + recent2.badwordsUrl + '">badwords</a>:<pre>' + s + '</pre>';
    continue;
            }
            if (isPhrase) phrase.push(s); else string.push(s);
        } else {
            // treat this line as a non-regexp and escape it.
            phrase.push(s.replace(RegExp('([-|.()\\+:!,?*^${}\\[\\]])', 'g'), '\\$1'));
        }
    }
    //                      123                                3       2|4                        4|5         56                        67        71
    //                      (((    repeated char               )       )|(   ... | strings | ...  )|( border  )(   ... | phrases | ...  )( border ))
    window.badWords=RegExp("((([^\\-\\|\\{\\}\\].\\s'=wI:*#0-9a-f])\\3{2,})|(" + string.join('|') + ")|(^|[^/\\w])(" + phrase.join('|') + ")(?![/\\w]))", 'gi');
};

window.gettingWatchlist=false;
recent2.watchlist=null;

recent2.getWatchlist=function() {
    window.gettingWatchlist=true;
    recent2.download({url: recent2.articlePath + 'Special:Watchlist/raw',
    onSuccess: recent2.processWatchlist,
    onFailure: function () { setTimeout(getWatchlist, 15000); return true; }});
};

recent2.processWatchlist=function(req, bundle) {
    var watchlist={};
    var lines=req.responseText.split('\n');
    var inList=false;
    var article = '';
    for (var i=0; i < lines.length; ++i) {
        if (inList || lines[i].indexOf('<textarea id="titles"')== 0) {
            if (inList && lines[i].indexOf('</textarea>') == 0) {
                window.watchlist =  watchlist;
                return;
            }
            if (!inList) {
                inList = true;
                article = lines[i].replace (/^.*>/, '');
            } else {
                article=lines[i];
            }
            watchlist[article] = true;
        }
    }
};

window.gettingSpelldict=false;
window.spelldict=null;

recent2.getSpelldict=function() {
    window.gettingSpelldict=true;
    recent2.download({url: recent2.scriptPath + 'index.php?title=' + recent2.spelldictUrl + '&action=raw&ctype=text/css',
    onSuccess: recent2.processSpelldict,
    onFailure: function () { setTimeout(getSpelldict, 15000); return true; }});
};

recent2.processSpelldict=function(req, bundle) {
    var spelldict={};
    var lines=req.responseText.split('\n');
    var a=[];
    for (var i=0; i<lines.length; ++i) {
        var split=lines[i].split('->');
        if (split.length<2) { continue; }
        split[1]=split.slice(1).join('->').split(/, */);
        split[0]=split[0].toLowerCase().replace(/^\s*/, '');
        spelldict[split[0]]=split[1];
        a.push(split[0]);
    }
    window.spelldict=spelldict;
    window.spellRe=RegExp('\\b(' + a.join('|') + ')\\b', 'i');
};

recent2.feed=recent2.scriptPath + 'index.php?title=Special:Recentchanges&feed=rss&action=purge';

window.newOutputDiv=function(klass, position, immortal) {
    var h1=document.getElementsByTagName('h1')[0];
    var ret=document.createElement('div');
    if (klass) { ret.className=klass; }
    if (!position) { position='bottom'; }
    switch(position) {
    case 'top':
        h1.parentNode.insertBefore(ret, h1.nextSibling);
        break;
    case 'bottom':
        h1.parentNode.appendChild(ret);
        break;
    default:
        if (!newOutputDiv.alerted) {
            alert('Unknown position '+position+' in recent2.js, newOutputDiv');
            window.newOutputDiv.alerted=true;
        }
        return newOutputDiv(klass, 'bottom');
    }
    if (!immortal) { ret.id=newOutputDiv.uid++; }
    window.outputDivs.push(ret);
    return ret;
};
window.newOutputDiv.alerted=false;
window.newOutputDiv.uid=0;
window.outputDivs=[];

window.grabRecentChanges=function(feed) {
    if (! window.badWords && recent2.filter_badwords ) {
        if ( ! window.gettingBadWords ) { recent2.getBadWords(); }
        return setTimeout(function(){grabRecentChanges(feed);}, 500);
    }
    if (! window.watchlist && recent2.filter_watchlist) {
        if (! window.gettingWatchlist ) recent2.getWatchlist();
        return setTimeout(function(){grabRecentChanges(feed);}, 500);
    }
    if (! window.spelldict && recent2.filter_spelling) {
        if (! window.gettingSpelldict) recent2.getSpelldict();
        return setTimeout(function(){grabRecentChanges(feed);}, 500);
    }
    if (typeof(recent2.sysopRegExp) == 'undefined') {
        if (! recent2.gettingSysops) recent2.getSysops();
        return setTimeout(function(){grabRecentChanges(feed);}, 500);
    }

    var pos=recent2.outputPosition;
    if (pos=='top') {
        var output=newOutputDiv('recent2.lines', pos);
        var status=newOutputDiv('recent2.status', pos);
    } else {
        var status=newOutputDiv('recent2.status', pos);
        var output=newOutputDiv('recent2.lines', pos);
    }
    status.style.borderStyle='solid';
    status.style.borderColor='orange';
    status.innerHTML=greyFont+'(' + recent2.count + ') updating...</font>';

    // this abort stuff doesn't work properly for some reason...
    //recent2.lastFeedDownload && recent2.lastFeedDownload.abort(); // } catch (summatNasty) { /* do nothing */ }
    recent2.lastFeedDownload=recent2.download({url: feed,
    onSuccess: processRecentChanges,
    output: output, status: status, onFailure: feedFailed});
};

var greyFont='<font color="#777">';

window.feedFailed=function(x,bundle) {
    try { bundle.status.innerHTML+=greyFont+'failed: '+x.statusText + '</font>'; }
    catch (err) { bundle.status.innerHTML+=greyFont+'failed badly: '+err+'</font>'; }
    return true;
};

recent2.newWindows=true;

window.linkmaker=function(url, text) {
    var s='<a href="' + url + '"';
    recent2.newWindows && (s += ' target="_blank"');
    s += '>' + text + '</a>';
    return s;
};

recent2.delayedLines={};
recent2.delay=0;

window.processRecentChanges=function(req, bundle){
    recent2.initialId=processRecentChanges.id;
    recent2.latest=processRecentChanges.lastDate;
    var doc;
    if (doc=req.responseXML.documentElement) {
        if (recent2.items=doc.getElementsByTagName('item')) {
            if ((recent2.itemsCurrent=recent2.items.length) > 0) {
                recent2.bundleRef = bundle;
                processRecentChangesSingle(); // start processing one diff every 50 ms
                return;
            }
        }
    }
    processRecentChangesDisplay(bundle);
    return;
}

recent2.safePagesRe=new RegExp('^' + recent2.safePages + '$');
recent2.changeDelay=50; // delay between processing each diff, in ms

window.nextChangeSoon=function(rightNow) {
    setTimeout(processRecentChangesSingle, rightNow ? 0 : recent2.changeDelay);
};

// process single diff items delayed by a short timespan
window.processRecentChangesSingle=function(){
    recent2.itemsCurrent--;
    var i = recent2.itemsCurrent;
    var items = recent2.items;
    if (i < 0) { processRecentChangesDisplay(recent2.bundleRef); return; }

    var timestamp = Date.parse(getFirstTagContent(items[i],'pubDate'));
    if (timestamp <= processRecentChanges.lastDate) { nextChangeSoon(true); return; }
    recent2.latest = (timestamp > recent2.latest) ? timestamp : recent2.latest;

    var diffText=getFirstTagContent(items[i],'description').split('</tr>').join('</tr>\n');
    var editSummary=diffText.replace(RegExp('^<p>(.*?)</p>[\\s\\S]*'), '$1');
    var editor=getFirstTagContent(items[i], 'creator') || getFirstTagContent(items[i], 'dc:creator');

    if (recent2.ignore_my_edits && wgUserName==editor) { return; }

    // NB article is the link attribute - a fully qualified URL
    // strip out the &diff=...&oldid=...  bit to leave only ?title=...
    var article=getFirstTagContent(items[i], 'link').split('&')[0];
    if (recent2.delayedLines[article] && recent2.delayedLines[article].editor != editor) {
        delete recent2.delayedLines[article];
    }

    if (recent2.filter_anonsOnly && !recent2.ipUserRegex.test(editor)) { nextChangeSoon(true); return; }

    // articleTitle is the wgTitle thingy with spaces and all that
    var articleTitle=getFirstTagContent(items[i], 'title');
    //console.info('articleTitle=%s', articleTitle);

    if (recent2.ignore_safe_pages && recent2.safePagesRe.test(articleTitle)) {
        //console.warn('Ignoring safe page %s', article);
        nextChangeSoon(true); return;
    }

    if (recent2.hideNonArticles) {
        var namespace=articleTitle.replace(/:.*/, '');
        if (recent2.namespaces[namespace] &&
    ( ( recent2.showTemplates && namespace != recent2.templateNamespace ) ||
        ! recent2.showTemplates )) {
            nextChangeSoon(true); return;
        }
    }

    // perhaps ignore talk pages
    if (! recent2.show_talkpages && articleTitle
            && /^Talk:|^[^:]*?[_ ]talk:/.test(articleTitle)) {
        nextChangeSoon(true); return;
    }

    // perhaps restrict to watchlist articles
    if (recent2.filter_watchlist && articleTitle &&
            ! window.watchlist[articleTitle.replace(/^Talk:/, '').replace(/[ _]talk:/, ':')]) {
        nextChangeSoon(true); return;
    }

    // filter against badwords regexp
    if (recent2.filter_badwords) {
        var badMatch=null;
        var diffCell=null;
        var previousVandal= window.vandals[editor];
        var matchesRe='';
        var matchesPlain='';
        diffCellRe.lastIndex=0;
        while (diffCell=diffCellRe.exec(diffText)) {
            // get content of addition table cells, faster than direct fulltext search
            badWords.lastIndex=0;
            // .test() is meant to be faster than a full match
            if (badMatch=badWords.test(diffCell[1])) { break; }
        }
        if (badMatch===true || previousVandal) {
            badWords.lastIndex=0;
            var reMatch;
            while (diffCell && (reMatch=badWords.exec(diffCell[1]))) {
                var badWord=reMatch[2] || reMatch[4] || reMatch[6] || '';
                if (articleTitle.toLowerCase().indexOf(badWord.toLowerCase())<0) { // avoid legit article title occurrences
                    badWord=badWord.replace(/^\s+|\s+$/g, '');
                    if (badWord!='') {
                        matchesPlain+=badWord+', ';
                        badWord=badWord.replace(/([^\w ])/g, '\\$1');
                        matchesRe+=badWord+'|';
                    }
                }
            }
            matchesRe=matchesRe.replace(/\|$/, '');
            matchesPlain=matchesPlain.replace(/, $/, '');
            if (!previousVandal && matchesRe=='') { nextChangeSoon(); return; }
            // highlighting
            var highlighted=diffCell && diffCell[1];
            if (matchesRe) {
                highlighted=highlighted.replace(RegExp('('+matchesRe+')', 'g'),
                    '<span style="background-color: #FF6">$1</span>');
            }
            articleTitle=getFirstTagContent(items[i], 'title');
            // linkify
            highlighted=recent2.doLinkify(highlighted);
            diffText=recent2.doLinkify(diffText);

            if (previousVandal) {
                matchesPlain = '[Previously rolled back this editor] ' + matchesPlain;
            }

            recent2.delayedLines[article]={
                timestamp: timestamp, article:article, count:recent2.count, articleTitle:articleTitle,
                editor:editor, badWord:matchesPlain, badDiffFragment:highlighted, diff:diffText, summary:editSummary
            };
        }
    } else if (recent2.filter_spelling) {
        var splMatch=null;
        while (diffCell=diffCellRe.exec(diffText)) {
            if (splMatch=spellRe.test(diffCell[1])) { break; }
        }
        if (splMatch) {
            splMatch = diffCell[1].match(spellRe);
            var misspelling = splMatch[1]; //.replace(/^\s*/, '');
            var badWord = '<a href=\'javascript:recent2.correctSpelling("' + articleTitle.split("'").join("%27") +
                '","'+misspelling.split("'").join("%27")+'")\'>'+ misspelling + '</a>';
            diffText = diffText.replace(RegExp('('+misspelling+')', 'gi'),
                '<span style="background-color: #FF6">$1</span>');
            // linkify
            diffText=recent2.doLinkify(diffText);
            recent2.delayedLines[article] = {
                timestamp: timestamp, article:article, count:recent2.count, articleTitle:articleTitle,
                editor:editor, badWord:badWord, badDiffFragment:'', diff:diffText, summary: editSummary
            };
        }
    } else {
        var article=getFirstTagContent(items[i], 'link');
        var articleTitle=getFirstTagContent(items[i], 'title');
        if (recent2.CustomFilter &&
            ! recent2.CustomFilter({timestamp:timestamp, article:article, articleTitle:articleTitle,
            editor:editor, diff:diffText, summary:editSummary})) { nextChangeSoon(); return; }
            // linkify
            diffText=recent2.doLinkify(diffText);
            recent2.delayedLines[article]={
            timestamp: timestamp, article:article, count:recent2.count, articleTitle:articleTitle,
            editor:editor, diff:diffText, summary:editSummary
        };
    }
    // schedule next iteration
    nextChangeSoon();
    return;
}



window.processRecentChangesDisplay=function(bundle){
    var output=recent2.getDelayedLineOutput();
    //console.log(output);
    var outputString='';
    if (recent2.outputPosition=='top') {
        outputString=output.join(recent2.outputSeparator);
    }
    else {
        for (var i=output.length-1; i>=0; --i) {
            outputString+=output[i] + (i>0 ? recent2.outputSeparator : '') ;
        }
    }
    bundle.output.innerHTML+=outputString;
    if (recent2.wait_for_output) { recent2.pauseOutput(); }
    setTimeout(function() {recent2.doPopups(bundle.output)}, 300);
    // overlap better than missing some out, i think; FIXME do this properly
    processRecentChanges.lastDate=recent2.latest; // - 1;
    var statusTail=greyFont+'done up to ' + formatTime(recent2.latest) + '</font>';
    if (processRecentChanges.id > recent2.initialId) {
        statusTail+=' <a href="javascript:showHideDetailRange(' + recent2.initialId + ',' +
            processRecentChanges.id  + ')">toggle these details</a> |';
        if (recent2.autoexpand) {
            setTimeout( function() {
        /* document.title=initialId+' '+processRecentChanges.id; */
        showHideDetailRange(recent2.initialId, processRecentChanges.id); }, 250 );
        }
    }
    statusTail += ' <a href="javascript:deleteEarlierOutputDivs(' + bundle.status.id + ')">remove earlier output</a>';
    if (recent2.wait_for_output) {
        statusTail += ' | <a href="javascript:recent2.unpauseOutputOnce()">show new output</a>';
    }
    statusTail+='<br>';
    bundle.status.innerHTML+=statusTail;
    return;
}

// linkify and popupsify wikilinks
recent2.doLinkify=function(txt) {
    if (!txt || !recent2.linkify) { return txt; }

    var inheritColor='color:inherit;color:expression(parentElement.currentStyle.color)';
    var externalLinkStyle='text-decoration:none;'
    var internalLinkStyle='text-decoration:none;'

    externalLinkStyle=internalLinkStyle='text-decoration:none;border-bottom: 1px dotted;';

    txt=txt.replace(/((https?|ftp):(\/\/[^\[\]\{\}\(\)<>\s&=\?#%]+|<[^>]*>)+)/g, function (p,p1) {
        p1=p1.replace(/<[^>]*>/g, '');
        var url=encodeURI(p1);
        url=url.replace(/\"/g, '%22');
        url=url.replace(/\'/g, '%27');
        url=url.replace(/#/g, '%23');
        var ti=p1.replace(/\"/g, '&quot;');
        return('<a href="'+url+'" style="' + externalLinkStyle + inheritColor + '" title="'+ti+'">'+p+'</a>');
    });

    // BUG: doLinkify('[[123<span style="color:red">]] badword</span> blah blah')
    // gives '<a href=/wiki/123 ... >[[123<span style="color:red">]]</a> badword</span> blah blah'
    // and the browser closes the <span> inside the </a>, so the badword is not red!

    txt=txt.replace(/((\[\[)([^\|\[\]\{\}\n]*)([^\]\n]*)(]\]))/g, function (p,p1,p2,p3) {
        p3=p3.replace(/<[^>]*>/g, '');
        var url=encodeURI(p3);
        url=url.replace(/\"/g, '%22');
        url=url.replace(/\'/g, '%27');
        url=url.replace(/#/g, '%23');
        url=recent2.articlePath+url;
        var ti=p3.replace(/\"/g, '&quot;');
        return('<a href="'+url+'" style="' + internalLinkStyle + inheritColor + '" title="'+ti+'">'+p+'</a>');
    });
    return(txt);
}

processRecentChanges.lastDate=0;
processRecentChanges.id=0;

recent2.getDelayedLineOutput=function() {
    var ret=[];
    var id=processRecentChanges.id;
    for (var a in recent2.delayedLines) {
        if (recent2.delayedLines[a] && typeof recent2.delayedLines[a].count == typeof 1 &&
            recent2.count - recent2.delayedLines[a].count >= recent2.delay) {
            recent2.delayedLines[a].id=id++;
            var line=(recent2.doLine(recent2.delayedLines[a]));
            if (line) { ret.push(line); }
            delete recent2.delayedLines[a];
        }
    }
    processRecentChanges.id=id;
    return ret;
}

window.deleteEarlierOutputDivs=function(cur) {
    for(var i=0; i<outputDivs.length; ++i) {
        if (!outputDivs[i] || !outputDivs[i].id) continue;
        if (outputDivs[i].id >= 0 && outputDivs[i].id < cur) {
            // FIXME BUG: if we go from the bottom up, then we'll delete one too many or too few, or something :-)
            outputDivs[i].parentNode.removeChild(outputDivs[i]);
            outputDivs[i]=null;
        }
    }
    // scroll to the top if we're appending output to the bottom, to keep the div we've clicked visible after the deletions
    if (recent2.outputPosition!='top') document.location='#';
}

window.showHideDetailRange=function(start,end) {
    // use the first div to see if we should show or hide
    var div=document.getElementById('diff_div_' + start);
    if (!div) {alert('no such div: diff_div_' + start); return; }
    var state=false; // hide
    if (div.style.display=='none') state=true; // show
    for (var i=start; i<end; ++i) {
        showHideDetail(i, true, state);
    }
}

window.hideSysopEdits=function(hide) {
    var divs=document.getElementsByTagName('div');
    for (var i=0; i<divs.length; ++i) {
        if (divs[i].className=='sysop_edit_line') divs[i].style.display= ( hide ? 'none' : 'inline' );
    }
}

window.bundles={};

window.vandalColour = function(vandal) {
    var num=window.vandals[vandal];
    if (!num) return '';
    switch (num) {
    case 1: return '#DDFFDD';
    case 2: return '#BBFFBB';
    }
    var i= 9-(num - 3) *2;
    if (i < 0) i=0;
    return '#' + i + i + 'FF' + i + i;
}

window.clickDetails=function(action, max) {
    if(!action) action='show';
    if (!max) max = document.links.length;
    var count=0;
    for (var i=0; i<document.links.length && count < max; ++i) {
        if(document.links[i].innerHTML==action + ' details' && document.links[i].href.indexOf('javascript:') == 0) {
            ++count;
            eval(document.links[i].href.replace('javascript:', ''));
        }
    }
}


recent2.pendingLines=[];

recent2.unpauseOutputOnce=function() {
    //console.log('unpausing once');
    if (recent2.pausedOutput) {
        recent2.togglePausedOutput();
        recent2.togglePausedOutput();
    }
};

recent2.pauseOutput=function() {
    //console.log('pausing');
    if (!recent2.pausedOutput) { recent2.togglePausedOutput(); }
    //console.log(recent2.pausedOutput);
}

recent2.unpauseOutput=function() {
    //console.log('unpausing');
    if (recent2.pausedOutput) { recent2.togglePausedOutput(); }
    //console.log(recent2.pausedOutput);
}

recent2.togglePausedOutput=function() {
    if (!recent2.pausedOutput) { recent2.pausedOutput = true; return true; }
    else recent2.pausedOutput=false;
    var outputBuffer='';
    while (recent2.pendingLines.length) {
        outputBuffer+=recent2.doLine(recent2.pendingLines.pop());
        if (recent2.pendingLines.length) { outputBuffer+=recent2.outputSeparator; }
    }
    var pos=recent2.outputPosition;
    var output=newOutputDiv('recent2.lines', pos);
    output.innerHTML=outputBuffer;
    setTimeout(function() {recent2.doPopups(output)}, 300);
    return false;
}

recent2.togglePaused=function() {
    if(!recent2.paused) { recent2.paused=true; return true; }
    recent2.paused=false;
    loopRecentChanges(loopRecentChanges.url, loopRecentChanges.iterations);
    return false;
}

recent2.doLine=function(bundle) {
    if (recent2.pausedOutput) {
        recent2.pendingLines.push(bundle);
        return '';
    }
    //if (recent2.filter_spelling) { return recent2.doSpellLine(bundle); }
    var sysop = null;
    if (typeof(recent2.sysopRegExp != 'undefined')) {
        sysop=recent2.sysopRegExp.test(bundle.editor);
    }
    var lastDiffPage=bundle.article + '&diff=cur&oldid=prev';
    bundle.url=lastDiffPage;
    saveBundle(bundle);

    var div='';
    var group='';
    if (window.vandals[bundle.editor]) {
        if (window.vandals[bundle.editor] > 0) {
            div='<div style="background-color:' + vandalColour(bundle.editor) + '">';
        }
    }
    else if (sysop) {
        group = ' <i>(Admin)</i>';
        if (recent2.hide_sysop_edits) {
            div='<div class="sysop_edit_line" style="display: none;">';
        }
        else {
            div='<div class="sysop_edit_line">';
        }
    }
    return(
        div +
        '<li>' +
        '[<a href="javascript:showHideDetail(' + bundle.id + ')" id="showdiff_link_' + bundle.id + '">Show</a>] ' +
        formatTime(bundle.timestamp) + ' ' +
         //latest + ' ' + processRecentChanges.lastDate + ' ' +
  '(' + linkmaker(lastDiffPage, 'diff') + ')' +
  ' (' + linkmaker(bundle.article+'?action=history', 'cron') + ')' +
(isSysop() ?
  ' (' + linkmaker(bundle.article+'?action=delete', 'del') + ')' +
  ' (' + linkmaker(bundle.article+'?action=protect', 'prot') + ')' : '') +
  ' ' + linkmaker(bundle.article, bundle.articleTitle) +
  ( bundle.badWord ? ' contiene <b>' + bundle.badWord + '</b> . . ' : ' . . ') +
  linkmaker(wikiBase + 'Utente:' + bundle.editor,           bundle.editor)     + ' ('  +
  linkmaker(wikiBase + 'Discussioni utente:' + bundle.editor,             'discussioni')     + ' | ' +
  linkmaker(wikiBase + 'Discussioni utente:' + bundle.editor + '?action=edit' +
        '&autoedit=s#$#\\n{{Test|' + bundle.articleTitle +
        '}}~~' + '~~#&autosummary=Avviso%20test%20',
        ' test')     + ' | ' +
  linkmaker(wikiBase + 'Discussioni utente:' + bundle.editor + '?action=edit' +
        '&autoedit=s#$#\\n{{WNB|' + bundle.articleTitle +
        '}}~~' + '~~#&autosummary=Avviso%20WNB',
        ' WNB')     + ' | ' +
  linkmaker(wikiBase + 'Discussioni utente:' + bundle.editor + '?action=edit' +
        '&autoedit=s#$#\\n{{WNF|' + bundle.articleTitle +
        '}}~~' + '~~#&autosummary=Avviso%20WNF',
        ' WNF')     + ' | ' +
  linkmaker(wikiBase + 'Discussioni utente:' + bundle.editor + '?action=edit' +
        '&autoedit=s#$#\\n{{Spam|' + bundle.articleTitle +
        '}}~~' + '~~#&autosummary=Avviso%20spam',
        ' spam')     + ' | ' +
  linkmaker(wikiBase + 'Discussioni utente:' + bundle.editor + '?action=edit' +
        '&autoedit=s#$#\\n{{Vandalismo|' + bundle.articleTitle +
        '}}~~' + '~~#&autosummary=Avviso%20vandalismo%20',
        'vandalismo')     + ' | ' +
  linkmaker(wikiBase + 'Discussioni utente:' + bundle.editor + '?action=edit' +
        '&autoedit=s#$#\\n{{IP Vandalismo}}~~' + '~~#&autosummary=Avviso%20IP%20vandalismo%20',
        'IP')     + ' | ' +
  linkmaker(wikiBase + 'Speciale:Contributions/' + bundle.editor, 'contributi') + ' | ' +
  linkmaker(wikiBase + 'Speciale:Blockip/' + bundle.editor,       'blocca')    +  ') . . ' +
  ( bundle.summary ? '<i>('+bundle.summary+')</i> . . ' : '') +
    '<a href="javascript:showHideDetail(' + bundle.id + ')" id="showdiff_link_' + bundle.id + '">dettagli</a>' +
    ' . . [<a href="javascript:tryRollback(' + bundle.id + ')" class="recent2_rollback">rollback</a>]' +
  '<p><div id="diff_div_' + bundle.id + '" style="display: none">' +
  '</div></li>' +
  ( div ? '</div>' : '') ;
};

recent2.correctSpelling=function (article, badword) {
    var url=recent2.articlePath + article + '?action=edit&autoclick=wpDiff&autominor=true';
    var wl=badword.toLowerCase();
    var cor=spelldict[wl];
    if (!cor|| !cor.length) { alert('Could not find an entry for ' + wl); return; }
    if (cor.length > 1) {
        var q='Which correction should I use?\nPlease either type a number or another correction.\n';
        for (var i=0; i<cor.length; ++i) { q += '\n' + i + ': ' + cor[i]; }
        var ans=prompt(q);
        if (!ans) {return;}
        var num=parseInt(ans, 10);
        if (num > -1 && num < cor.length) { cor = cor[num]; }
        else { cor = ans; }
    } else {
        cor = cor[0];
    }
    cor=cor.replace(/^ *| *$/g, '');
    url += '&autosummary=Correcting%20spelling:%20' + wl + '->' + cor;
    url += '&autoedit=';
    c0=cor.charAt(0);
    wl0 = wl.charAt(0);
    b='\\b';
    url += ['s', b + wl + b, cor, 'g;'].join('#');
    wl=wl0.toUpperCase() + wl.substring(1);
    cor=c0.toUpperCase() + cor.substring(1);
    url += ['s', b + wl + b, cor, 'g;'].join('#');
    wl=wl.toUpperCase();
    cor=cor.toUpperCase();
    url += ['s', b + wl + b, cor, 'g;'].join('#');
    window.open(url);
};

window.saveBundle= function(bundle) {
    var z={};
    for (var prop in bundle) { z[prop]=bundle[prop]; }
    window.bundles[bundle.id]=z;
}

window.vandals={};

window.tryRollback=function(id) {
    if (recent2.non_admin_rollback) { recent2.tryNonAdminRollback(id); }
    else { recent2.tryAdminRollback(id); }
};

recent2.getBundleVandal=function(id) {
    var b=window.bundles[id];
    if (!b) {
        alert('No bundle! Please tell Lupin how to reproduce this error - it should not really happen.');
        return null;
    }
    var vandal=b.editor;
    if (window.vandals[vandal]==null) { window.vandals[vandal]=1; }
    else { window.vandals[vandal]++; }
    return b;
}

recent2.tryAdminRollback=function(id){
    var b=recent2.getBundleVandal(id);
    if (!b) { return; }
    var vandal=b.editor;
    var onSuccess=function (x, bundle) {
        var rollRe=RegExp('<a href="(/w/index.php[^"]*?action=rollback[^"]*?from=([^&]*)[^"]*?)".*?(<span class="comment">(.*?)</span>)?');
        // match[0]: useless
        // match[1]: url (escaped)
        // match[2]: last editor (escaped)
        // match[4]: last edit summary (wikiText - FIXME strip this to plain text)
        var match=rollRe.exec(x.responseText);
        if (!match) {
            alert('No rollback link found.' +
            '\nMaybe you should try the non-admin rollback by checking the checkbox above?\n' +
            'Alternatively, this may be a bug.');
            return;
        }
        var lastEditor=match[2].split('+').join(' ');
        var lastSummary=match[4] || '';
        if (lastEditor != vandal) {
            var summary=lastSummary.replace(RegExp('<[^>]*?>','g'),'');
            if (!summary) summary=lastSummary;
            alert( 'Could not rollback - someone else has edited since the vandal.\n\nPage: '+ b.articleTitle +
                '\nVandal: '+vandal+'\nLast editor: '+lastEditor+'\nEdit summary: '+summary);
            return;
        }
        var rollbackUrl=match[1].split('&amp;').join('&');
        recent2.openBackgroundWindow(rollbackUrl);
    }
    var onFailure = function(x,bundle) {
        alert('HTTP failed when trying to get rollback link in url\n' + bundle.url +
        '\n\nHTTP status text: ' + x.statusText);
        return true;
    }
    recent2.download({ url:b.url, onSuccess: onSuccess, id: b.id, onFailure:onFailure});
};

recent2.backgroundWindows = [];
recent2.openBackgroundWindow = function(url) {
    var newWindow = window.open(url);
    self.focus();
    recent2.backgroundWindows.push(newWindow);
    if (recent2.backgroundWindows.length > recent2.backgroundWindowsMax) {
        if (!recent2.backgroundWindows[0].closed) {
            recent2.backgroundWindows[0].close();
            recent2.backgroundWindows.shift();
        }
    }
    return;
}

recent2.tryNonAdminRollback=function(id) {
    var b=recent2.getBundleVandal(id);
    if (!b) { return; }
    var url=recent2.scriptPath + 'api.php?action=query&format=json&titles=' + b.articleTitle + '&prop=revisions&rvlimit=30';
    var onSuccess=function(x,y){ recent2.processHistoryQuery(x,y,b); }
    recent2.download({ url: url, onSuccess: onSuccess, id: b.id}); // fixme: onFailure
};

recent2.processHistoryQuery=function(x,downloadBundle, bundle) {
    var json=x.responseText;
    try {
        eval('var o='+json);
        var edits=recent2.anyChild(o.query.pages).revisions;

    }
    catch ( someError ) { alert('JSON business failed.\n\n' + json.substring(0,200)
        + '\n\nCannot rollback.'); return; }
    var i;
    for (i=0; i<edits.length; ++i) {
        if (edits[i]['user']!=bundle.editor) { break; }
    }
    if (i===0) {
        alert( 'Could not rollback - someone else has edited since the vandal.\n\nPage: ' +
        bundle.articleTitle +
            '\nVandal: '+bundle.editor+'\nLast editor: '+edits[0]['user']+
            '\nEdit summary: '+edits[0]['comment']);
        return;
    }
    if (i==edits.length) {
        alert(bundle.editor + ' seems to be the only editor to ' + bundle.articleTitle +
            '.\n\nRollback aborted.'); return;
    }
    var prevEditor=edits[i]['user'];
    var prevRev=edits[i]['revid'];
    var summary='Reverted edits by [[Special:Contributions/' + escape(bundle.editor) + '|' +
        escape(bundle.editor) + ']] to last version by ' + escape(prevEditor);
    summary=summary.split(' ').join('%20');
    var url=bundle.article + '&action=edit&autosummary=' + summary + '&oldid=' + prevRev +
        '&autoclick=wpSave&autominor=true&autowatch=false';
    recent2.openBackgroundWindow(url);
};

recent2.anyChild=function(obj) {
    for (var p in obj) {
        return obj[p];
    }
    return null;
};

recent2.doPopups=function(div) {
    if (typeof(window.setupTooltips)!='undefined') { setupTooltips(div); }
}

window.formatTime=function(timestamp) {
    var date=new Date(timestamp);
    var nums=[date.getHours(), date.getMinutes(), date.getSeconds()];
    for (var i=0; i<nums.length; ++i) if (nums[i]<10) nums[i]='0'+nums[i];
    return nums.join(':');
}

window.showHideDetail = function(id, force, state) {
    var div=document.getElementById('diff_div_' + id);
    var lk=document.getElementById('showdiff_link_' + id);
    if (!div) return;
    var bundle=window.bundles[id];
    if (!div.innerHTML) div.innerHTML= ( bundle.badDiffFragment ? bundle.badDiffFragment:'') + bundle.diff;
    if ((force && state==true) || (!force && div.style.display=='none')) { div.style.display='inline'; lk.innerHTML='Hide'; }
    else { div.style.display='none';   lk.innerHTML='Show'; }

}

window.getFirstTagContent=function(parent, tag) {
    var e=parent.getElementsByTagName(tag);
    if (e && (e=e[0]) ) {
        var ret = e.firstChild.nodeValue || e.nodeValue;
        if (typeof ret != typeof '') return '';
        return ret;
    }
};

recent2.newCell=function() {
    var numCols=3;

    var c=recent2.controls;
    if (!c) { return; }
    if (!c.cellCount) {
        // start a table
        c.cellCount = 0;
        c.table=document.createElement('table');
        c.appendChild(c.table);
        c.tbody=document.createElement('tbody');
        c.table.appendChild(c.tbody);
    }
    if (!(c.cellCount % numCols)) {
        // start a row
        c.curRow=document.createElement('tr');
        c.tbody.appendChild(c.curRow);
    }
    // start a cell
    c.curCell=document.createElement('td');
    c.curRow.appendChild(c.curCell);
    ++c.cellCount;
};

recent2.newCheckbox=function(label, state, action, internalName, append) {
    // checkbox
    recent2.newCell();
    var ret=document.createElement('input');
    ret.type='checkbox';
    ret.checked = state;
    ret.onclick = function() { recent2.setBoxCookies(); this.setVariables(); };
    ret.setVariables = action;
    recent2.controls.curCell.appendChild(ret);
    if (internalName) { recent2.controls[internalName]=ret; }
    // label
    var l=document.createElement('label');
    l.innerHTML=label;
    l.onclick=function(){ ret.click(); }
    // recent2.controls.appendChild(l);
    recent2.controls.curCell.appendChild(l);
    recent2.checkboxes.push(ret);
    return ret;
};

recent2.checkboxes=[];

recent2.setBoxCookies=function() {
    var n=1;
    var val=0;
    for (var i=0; i<recent2.checkboxes.length; ++i) {
        val += n * (recent2.checkboxes[i].checked ? 1 : 0);
        n = n << 1;
    }
    document.cookie = 'recent2_checkboxes='+val+"; expires=Tue, 31-Dec-2030 23:59:59 GMT; path=/";
};

recent2.setCheckboxValuesFromCookie=function() {
    var val=recent2.readCookie('recent2_checkboxes');
    if (!val) { return; }
    val=parseInt(val, 10);
    for (var i=0; i<recent2.checkboxes.length; ++i) {
        if ( recent2.checkboxes[i].checked != (val & 1) ) {
            recent2.checkboxes[i].checked= (val & 1);
            recent2.checkboxes[i].setVariables();
        }
        val = val >> 1;
    }
};

recent2.readCookie=function(name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for(var i=0;i < ca.length;i++) {
        var c = ca[i];
        while (c.charAt(0)==' ') { c = c.substring(1,c.length); }
        if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length,c.length); }
    }
    return null;
};

recent2.controlUI=function() {
    recent2.controls=newOutputDiv('recent2.controls', 'top', true);

// control presets, will be changed by saved cookie settings
    recent2.show_talkpages = true;
    recent2.hideNonArticles = false;
    recent2.showTemplates = false;
    recent2.autoexpand = false;
    recent2.delay_preset = false;
    recent2.non_admin_rollback = !recent2.userIsSysop;
    recent2.ignore_my_edits = false;
    recent2.ignore_safe_pages = false;
    recent2.hide_sysop_edits = false;

// create controls
    recent2.newCheckbox('Ignora le pagine di discussione', !recent2.show_talkpages,
            function() { recent2.show_talkpages=!this.checked; }, 'talk');
    recent2.newCheckbox('Ignora le pagine non appartenenti al namespace principale', recent2.hideNonArticles,
            function() { recent2.hideNonArticles = this.checked; }, 'hidenonarticles');
    recent2.newCheckbox('... eccetto il namespace Template', recent2.showTemplates,
            function() { recent2.showTemplates = this.checked; }, 'showtemplates');
    recent2.newCheckbox('Espandi automaticamente gli aggiornamenti', recent2.autoexpand,
            function() { recent2.autoexpand = this.checked; }, 'autoexpand');
    recent2.newCheckbox('Visualizza solo le modifiche immutate dopo 4 aggiornamenti', recent2.delay_preset,
            function() { recent2.delay = (this.checked) ? 4 : 0; }, 'delayby4');
    recent2.newCheckbox('Usa il rollback per i non amministratori', recent2.non_admin_rollback,
            function() { recent2.non_admin_rollback = this.checked; }, 'nonadminrollback');
    recent2.newCheckbox('Ignora i miei edit', recent2.ignore_my_edits,
            function() { recent2.ignore_my_edits = this.checked; }, 'ignoremyedits');
    recent2.newCheckbox('Ignora le pagine sicure', recent2.ignore_safe_pages,
            function() { recent2.ignore_safe_pages = this.checked; }, 'ignoresafepages');
    recent2.newCheckbox('Nascondi gli edit degli admin', recent2.hide_sysop_edits,
            function() { recent2.hide_sysop_edits = this.checked; hideSysopEdits(recent2.hide_sysop_edits); }, 'hidesysopedits');

    var b=document.createElement('input');
    b.type='button';
    b.value='interrompi aggiornamenti';
    b.onclick=function(){
        b.value=(recent2.paused)?'interrompi aggiornamenti':'riprendi aggiornamenti';
        recent2.togglePaused();
    }
    recent2.newCell();
    recent2.controls.curCell.appendChild(b);
    recent2.setCheckboxValuesFromCookie();
}

recent2.count=0;
window.loopRecentChanges=function(url, iterations) {
    if (!iterations) iterations=20;
    loopRecentChanges.iterations=iterations;
    loopRecentChanges.url=url;
    grabRecentChanges(url);
    setTimeout(function () {
        if (recent2.paused) {++recent2.count; return; }
        if (++recent2.count >= iterations && ! confirm('Vuoi continuare a controllare le ultime modifiche?') ) return;
        recent2.count %= iterations; loopRecentChanges(url, iterations);
    }, recent2.updateSeconds * 1000);
}

window.marvin=function() {

// check if user is a sysop
    recent2.userIsSysop = false;
    if (typeof(wgUserGroups) != 'undefined') {
        for (var i = 0; i < wgUserGroups.length; ++i) {
            if (wgUserGroups[i] == 'sysop') {
                recent2.userIsSysop = true;
                break;
            }
        }
    }

// set chunk size for sysop list
    if (recent2.userIsSysop) {
        recent2.apiAulimit = recent2.apiAulimitSysop;
    }
    else {
        recent2.apiAulimit = recent2.apiAulimitUser;
    }

// setup checkboxes
    recent2.controlUI();

// start fetching recent changes
    loopRecentChanges(recent2.feed, 200);
}

// get the full sysop list in chunks
recent2.getSysops = function(startUser) {
    recent2.gettingSysops = true;
    var param = '';
    if (typeof(startUser) == 'string') {
        param = '&aufrom=' + encodeURIComponent(startUser);
    }
    recent2.download({
        url: recent2.scriptPath + 'api.php?action=query&list=allusers&augroup=sysop&aulimit=' + recent2.apiAulimit + '&format=json' + param,
        onSuccess: recent2.processSysops,
        onFailure: function() { setTimeout(recent2.getSysopList, 15000); return true;}
    });
}

recent2.sysopList = '';
recent2.processSysops = function(s) {
    var json = s.responseText;
    try {
        eval('var o = ' + json);
        var users = o.query.allusers;
    }
    catch(someError) {
        alert('Could not process admin list.\n\n"' + json.substring(0, 400) + '"');
        return;
    }
    for (var i = 0; i < users.length; i++) {
        if (recent2.sysopList != '') {
            recent2.sysopList += '|';
        }
        recent2.sysopList += users[i].name.replace(/(\W)/g, '\\$1');
    }
    if (users.length < recent2.apiAulimit) {
        recent2.sysopRegExp = new RegExp(recent2.sysopList);
    }
    else {
        recent2.getSysops(users[recent2.apiAulimit - 1].name);
    }
    return;
}

// **************************************************
// Installation
// **************************************************

recent2.addlilink=function(tabs, url, name, id, title, key){
        var na = document.createElement('a');
        na.href = url;
        na.appendChild(document.createTextNode(name));
        var li = document.createElement('li');
        if(id) li.id = id;
        li.appendChild(na);
        tabs.appendChild(li);
        if(id) {
            if(key && title) ta[id] = [key, title];
            else if(key)     ta[id] = [key, ''];
            else if(title)   ta[id] = ['', title];
        }
        // re-render the title and accesskeys from existing code in wikibits.js
        akeytt();
        return li;
}

recent2.addToolboxLink=function(url, name, id){
        var tb = document.getElementById('p-tb').getElementsByTagName('ul')[0];
        recent2.addlilink(tb, url, name, id);
}

window.addMarvin=function() {
    recent2.addToolboxLink(recent2.articlePath + recent2.filterPage,
        'Filtra le ultime modifiche', 'toolbox_filter_changes');
    recent2.addToolboxLink(recent2.articlePath + recent2.allRecentPage,
        'Tutte le ultime modifiche', 'toolbox_all_changes');
    recent2.addToolboxLink(recent2.articlePath + recent2.recentIPPage,
        'Ultime modifiche anonime', 'toolbox_IP_edits');
    recent2.addToolboxLink(recent2.articlePath + recent2.monitorWatchlistPage,
        'Segui gli osservati speciali', 'toolbox_watchlist_edits');
    recent2.addToolboxLink(recent2.articlePath + recent2.spelldictPage,
        'Controllo ortografico', 'toolbox_spelling');
};

recent2.testPage = function (str) {
    return RegExp(str.split(/[_ ]/).join('[_ ]'), 'i').test(document.location.href);
};

window.maybeStart=function() {
    var loc=document.location.href;
    if (recent2.testPage(recent2.filterPage)) {
        recent2.filter_badwords=true;
    } else if (recent2.testPage(recent2.allRecentPage)) {
        recent2.filter_badwords=false;
    } else if (recent2.testPage(recent2.recentIPPage)) {
        recent2.filter_anonsOnly=true;
    } else if (recent2.testPage(recent2.monitorWatchlistPage)) {
        recent2.filter_watchlist=true;
    } else if (recent2.testPage(recent2.spelldictPage)) {
        recent2.filter_spelling=true;
    } else {
        return;
    }
    setTimeout(marvin, 1000);
}

// onload
$(maybeStart);
$(addMarvin);


//
// autoedit code, streamlined from User:Lupin/autoedit.js, added autowatch
// User:Lupin/autoedit.js is no longer needed
//

recent2.getParamValue = function(paramName) {
    var cmdRe = RegExp('[&?]' + paramName + '=([^&]*)');
    var h = document.location;
    var m;
    if (m = cmdRe.exec(h)) {
        try {
            return decodeURI(m[1]);
        } catch (someError) {}
    }
    return null;
};

recent2.substitute = function(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);
};

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

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

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


recent2.runJavascript = function(data, argWrapper) {
    // flags aren't used (yet)

    // from the user's viewpoint,
    // data is a special variable may appear inside code
    // and gets assigned the text in the edit box

    // alert('eval-ing ' + argWrapper.code);

    return eval(argWrapper.code);
};

recent2.parseJavascript = function(str) {
    // takes a string like j/code/;othercmds and parses it

    var tmp, code, flags;

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

    tmp = recent2.skipOver(str, sep);
    if (tmp) { code = tmp.segment.split('\n').join('\\n'); str = tmp.remainder; }
    else return false;

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

    return { action: recent2.runJavascript, code: code, flags: flags, remainder: str };
};

recent2.parseSubstitute = function(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 = recent2.skipOver(str, sep);
    if (tmp) { from = tmp.segment; str = tmp.remainder; }
    else return false;

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

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

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

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

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

recent2.findNext = function(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;
};

recent2.runOnLoad = function(f) {
    if (window.addEventListener) {
        window.addEventListener("load", f, false);
    }
    else if (window.attachEvent) {
        window.attachEvent("onload", f);
    }
    else {
        window._old_popup_autoedit_onload = window.onload;
        window.onload = function() {
            window._old_popup_autoedit_onload();
            f();
        }
    }
};

window.AVTAutoEdit = function() {

    if (typeof(window.autoEdit) != 'undefined') {
        if (window.autoEdit.alreadyRan) return false;
    }
    else {
        window.autoEdit = {};
    }
    window.autoEdit.alreadyRan = true;
    var cmdString = recent2.getParamValue('autoedit');
    if (cmdString) {
        try {
            var editbox = document.editform.wpTextbox1;
        } catch (dang) { return; }
        var cmdList = recent2.parseCmd(cmdString);
        var input = editbox.value;
        var output = recent2.execCmds(input, cmdList);
        editbox.value = output;
        // wikEd user script compatibility
        if (typeof(wikEdUseWikEd) != 'undefined') {
            if (wikEdUseWikEd == true) {
                WikEdUpdateFrame();
            }
        }
    }

    var summary = recent2.getParamValue('autosummary');
    if (summary) document.editform.wpSummary.value = summary;

    var minor = recent2.getParamValue('autominor');
    if (minor) {
        switch (minor) {
        case '1':
        case 'yes':
        case 'true':
            document.editform.wpMinoredit.checked = true;
            break;
        case '0':
        case 'no':
        case 'false':
            document.editform.wpMinoredit.checked = false;
        }
    }

    var watch = recent2.getParamValue('autowatch');
    if (watch) {
        switch (watch) {
        case '1':
        case 'yes':
        case 'true':
            document.editform.wpWatchthis.checked = true;
            break;
        case '0':
        case 'no':
        case 'false':
            document.editform.wpWatchthis.checked = false;
        }
    }

    var btn = recent2.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>The "' + button.value +
                    '" button has been automatically clicked.' +
                    ' Please wait for the next page to load.</b></font>';
                document.title = '(' + document.title + ')';
                headings[0].parentNode.insertBefore(div, headings[0]);
                button.click();
            }
        } else {
            alert('Anti-Vandal Tool\n\nautoclick: could not find button "' + btn + '".');
        }
    }
};

recent2.runOnLoad(AVTAutoEdit);

// </nowiki></pre>