Jump to content

User:Zhaofeng Li/vada/vadaprocess.js

From Wikipedia, the free encyclopedia
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
/* <nowiki> */
var vada={};
vada.settings={};
vada.settings.summarytag=" ([[WP:Vada|Vada]])";

vada.api=function(query){
var xhr=new XMLHttpRequest();//no JQuery $.ajaxSettings.xhr();
xhr.open("POST","//en.wikipedia.org/w/api.php?format=json",false);
xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
query=vada.api._kwarg_to_poststring(query);
xhr.send(query);
return JSON.parse(xhr.responseText);
}

vada.api._kwarg_to_querystring=function(kwarg){
var ret = "?";
for(var i in kwarg){
ret+=i+"="+encodeURIComponent(kwarg[i])+"&";
}
return ret;
}
vada.api._kwarg_to_poststring=function(kwarg){
	ret=vada.api._kwarg_to_querystring(kwarg);
	return ret.slice(1,ret.length-1);
}
vada.api._kwarg_to_formdata=function(kwarg){
var ret=new FormData();
for(var i in kwarg){
ret.append(i,kwarg[i]);
}
return ret;
}

vada.api.recentchanges=[];
vada.api.getNewChanges=function(){
	if(vada.api.rcstart===undefined)vada.api.getrcstart();
	query={};
	query["action"]="query";
	query["list"]="recentchanges";
	query["rcprop"]="user|userid|comment|parsedcomment|flags|timestamp|title|ids|sizes|redirect|loginfo|tags|sha1";
	query["rclimit"]=500;
	query["rcdir"]="newer";
	query["rcstart"]=vada.api.rcstart;
	var data=vada.api(query);
	for(var i=1;i<data.query.recentchanges.length;i++){
		var rc=(data.query.recentchanges[i].type=="edit" || data.query.recentchanges[i].type=="new")?
			new vada.Revision(data.query.recentchanges[i].revid):{};
		rc.title=data.query.recentchanges[i]["title"];
		rc.page=new vada.Page(data.query.recentchanges[i].title);
		rc.revid=data.query.recentchanges[i]["revid"];
		rc.revision=new vada.Revision(rc.revid);
		rc.parent=new vada.Revision(data.query.recentchanges[i]["old_revid"]);
		rc.user=new vada.User(data.query.recentchanges[i]["user"]);
		rc.userid=data.query.recentchanges[i]["userid"];
		rc.parent.size=data.query.recentchanges[i]["oldlen"];
		rc.size=data.query.recentchanges[i]["newlen"];
		rc.timestamp=data.query.recentchanges[i]["timestamp"];
		rc.comment=data.query.recentchanges[i]["comment"];
		rc.parsedcomment=data.query.recentchanges[i]["parsedcomment"];
		rc.tags=data.query.recentchanges[i]["tags"];
		rc.sha1=data.query.recentchanges[i]["sha1"];
		rc.minor=data.query.recentchanges[i]["minor"]!=undefined;
		rc.bot=data.query.recentchanges[i]["bot"]!=undefined;
		switch(data.query.recentchanges[i].type){
			case "edit":
			case "new":
				rc.page._revisions["cur"]=rc;
				vada.events.trigger("rc.new"+(data.query.recentchanges[i].type=="edit"?"edit":"page"),{rc:rc});//old
				vada.events.trigger("rc."+data.query.recentchanges[i].type,{rc:rc});
				break;
			case "log":
				rc.logid=data.query.recentchanges[i].logid;
				rc.logtype=data.query.recentchanges[i].logtype;
				rc.logaction=data.query.recentchanges[i].logaction;
				switch(rc.logtype){
					case "delete":
						break;
					case "pagetriage-curation":
						break;
					case "pagetriage-deletion":
						break;
					case "block":
						break;
					case "move":
						rc.move=data.query.recentchanges[i].move;
						break;
					case "newusers":
						break;
					case "upload":
						rc.sha1=data.query.recentchanges[i].img_sha1;
						break;
					case "abusefilter":
						break;
					case "protect":
						break;
					case "eparticle":
						break;
					case "stable":
						break;
					default:
						if(typeof console!="undefined")console.log("Unsupported rc.log type: "+rc.logtype);//TODO Are these properly supported?
						break;
				}
				vada.events.trigger("rc.log."+rc.logtype+"."+rc.logaction,{rc:rc});
				vada.events.trigger("rc.log."+rc.logtype,{rc:rc});
				vada.events.trigger("rc.log",{rc:rc});
				break;
			case "external":
				vada.events.trigger("rc.external",{rc:rc});
				break;
			default:
				if(typeof console!="undefined")console.log("Unsupported rc type: "+data.query.recentchanges[i].type);
				break;
		}
		vada.events.trigger("rc",{rc:rc});
		vada.api.recentchanges.push(rc);
	}
	if((rc||{timestamp:false}).timestamp){
		vada.api.rcstart=rc.timestamp;
	}else if(data.query.recentchanges[data.query.recentchanges.length-1]["timestamp"]){
		vada.api.rcstart=data.query.recentchanges[data.query.recentchanges.length-1]["timestamp"];
	}
}
vada.api.getrcstart=function(){
	query={};
	query["action"]="query";
	query["list"]="recentchanges";
	query["rclimit"]=1;
	var data=vada.api(query);
	vada.api.rcstart=data.query.recentchanges[0].timestamp;
}
vada.api._edittoken=function(params){
	vada.api.edittoken=params.token;
}

vada.rctimer=setInterval(vada.api.getNewChanges,5000);

vada.events={};
vada.events._listeners={};
vada.events.addListener=function(event,callback){
	if(!vada.events._listeners.hasOwnProperty(event))
		vada.events._listeners[event]=[];
	vada.events._listeners[event].push(callback);
}
vada.events.removeListener=function(event,callback){
	var i=vada.events._listeners[event].indexOf(callback);
	if(i>-1)
		vada.events._listeners[event].splice(i,1);
}
vada.events.trigger=function(event,params){
	if(typeof event=="object"){//called from GUI thread
		params=event;
		event=event.event;
	}
	if(!vada.events._listeners.hasOwnProperty(event))
		return;
	for(var i=0;i<vada.events._listeners[event].length;i++){
		vada.events._listeners[event][i](params);
	}
}

vada.dom={};
vada.dom.call=function(func,params){
	self.postMessage(JSON.stringify({"func":func,"params":params}));
}
self.onmessage=function(msg){
	//if(typeof console!="undefined")console.log(msg.data);
	//debugger;
	data=JSON.parse(msg.data);
	if((dot=data.func.indexOf("."))>=0){
		var func=vada[data.func.substr(0,dot)];
		data.func=data.func.slice(dot+1);
		while((dot=data.func.indexOf("."))+1){
			func=func[data.func.substr(0,dot)];
			data.func=data.func.slice(dot+1);
		}
		func=func[data.func];
	} else {
		var func=vada[data.func];
	}
	func(data.params);
}
vada.plugins={};
vada.loadPlugin=function(plugin){
	vada.plugins[plugin.plugin.about.namespace]=plugin.plugin;
	importScripts("/w/index.php?title="+plugin.plugin.about.userscript+"&action=raw&ctype=text/javascript");
}

vada.dom.queue=[];
vada.dom.queue.redraw=function(){
	var list=[];
	for(var i=0;i<vada.dom.queue.length;i++){
		var itm=vada.dom.queue[i];
		list.push(itm.toDOM());
	}
	vada.dom.call("dom.queue.redraw",{"elements":list});	
}
vada.dom.queue.next=function(){
	if(vada.dom.queue[0]){
		if(vada.dom.queue[0] instanceof vada.Page){
			vada.Page.click({title:vada.dom.queue[0].title});
		}else if(vada.dom.queue[0] instanceof vada.Revision){
			vada.Revision.click({revid:vada.dom.queue[0].revid});
		}
	}
}
vada.dom.queue.remove=function(page){
	vada.dom.queue.splice(vada.dom.queue.indexOf(new vada.Page(page)),1);
	vada.dom.queue.redraw();
}
vada.dom.queue.removenext=function(page){
	vada.dom.queue.remove(page);
	return vada.dom.queue.next();
}
vada.dom.queue._builders={};
vada.dom.queue.builders=[];
vada.dom.queue.Builder=function(name){
	this.name=name;
	this.text="Builder";
	this.input=false;
	this.action=new Function();
	vada.dom.queue._builders[name]=this;
}
vada.dom.queue.builders.redraw=function(){
	var list=[];
	for(var i=0;i<vada.dom.queue.builders.length;i++){
		var itm=vada.dom.queue.builders[i];
		var item={};
		item.text=itm.text;
		item.input=itm.input;
		item.callback="dom.queue._builders."+itm.name+".action";
		list.push(item);
	}
	vada.dom.call("dom.queue.builder.redraw",{"elements":list});
}
vada.dom.queue.builders.show=function(){
	vada.dom.queue.builders.toggle(true);
}
vada.dom.queue.builders.hide=function(){
	vada.dom.queue.builders.toggle(false);
}
vada.dom.queue.builders.toggle=function(val){
	vada.dom.queue.builders._visible=(val===undefined?!vada.dom.queue.builders._visible:val);
	vada.dom.call("dom.queue.builder.visible",{visible:vada.dom.queue.builders._visible});
}
vada.dom.queue.builders._visible=false;
vada.dom.queue.builder={};

vada.dom.queue.builder.pagea=new vada.dom.queue.Builder("pagea");
vada.dom.queue.builder.pagea.text="Page Append";
vada.dom.queue.builder.pagea.input="Title";
vada.dom.queue.builder.pagea.action=function(params){
	vada.dom.queue.push(new vada.Page(params.input));
	vada.dom.queue.redraw();
}
vada.dom.queue.builders.push(vada.dom.queue.builder.pagea);

vada.dom.queue.builder.pagep=new vada.dom.queue.Builder("pagep");
vada.dom.queue.builder.pagep.text="Page Prepend";
vada.dom.queue.builder.pagep.input="Title";
vada.dom.queue.builder.pagep.action=function(params){
	vada.dom.queue.unshift(new vada.Page(params.input));
	vada.dom.queue.redraw();
}
vada.dom.queue.builders.push(vada.dom.queue.builder.pagep);

vada.dom.queue.builder.revisiona=new vada.dom.queue.Builder("revisiona");
vada.dom.queue.builder.revisiona.text="Revision Append";
vada.dom.queue.builder.revisiona.input="ID";
vada.dom.queue.builder.revisiona.action=function(params){
	vada.dom.queue.push(new vada.Revision(params.input));
	vada.dom.queue.redraw();
}
vada.dom.queue.builders.push(vada.dom.queue.builder.revisiona);

vada.dom.queue.builder.revisionp=new vada.dom.queue.Builder("revisionp");
vada.dom.queue.builder.revisionp.text="Revision Prepend";
vada.dom.queue.builder.revisionp.input="ID";
vada.dom.queue.builder.revisionp.action=function(params){
	vada.dom.queue.unshift(new vada.Revision(params.input));
	vada.dom.queue.redraw();
}
vada.dom.queue.builders.push(vada.dom.queue.builder.revisionp);

vada.dom.queue.builder.category=new vada.dom.queue.Builder("category");
vada.dom.queue.builder.category.text="Category";
vada.dom.queue.builder.category.input="Category";
vada.dom.queue.builder.category.action=function(params){
	var query={};
	query.action="query";
	query.list="categorymembers";
	var t=vada.normalise(params.input);
	query.cmtitle=t.substr(0,9)=="Category:"?t:"Category:"+t;
	query.cmlimit=500;
	if(params.continue)query.cmcontinue=params.continue;
	var data=vada.api(query);
	var cm=data.query.categorymembers;
	for(var i=0;i<cm.length;i++){
		vada.dom.queue.push(new vada.Page(cm[i].title));
	}
	vada.dom.queue.redraw();
	if(data["query-continue"]){
		params.continue=data["query-continue"].categorymembers.cmcontinue;
		vada.dom.queue.builder.category.action(params);
	}
}
vada.dom.queue.builders.push(vada.dom.queue.builder.category);

vada.dom.queue.builder.wikilinks=new vada.dom.queue.Builder("wikilinks");
vada.dom.queue.builder.wikilinks.text="Links on page";
vada.dom.queue.builder.wikilinks.input="Page";
vada.dom.queue.builder.wikilinks.action=function(params){
	var query={};
	query.action="query";
	query.prop="links";
	query.titles=vada.normalise(params.input);
	query.pllimit=500;
	var data=vada.api(query);
	for(var pageid in data.query.pages)break; 
	var pl=data.query.pages[pageid].links;
	for(var i=0;i<pl.length;i++){
		vada.dom.queue.push(new vada.Page(pl[i].title));
	}
	vada.dom.queue.redraw();
}
vada.dom.queue.builders.push(vada.dom.queue.builder.wikilinks);

vada.dom.queue.builder.whatlinkshere=new vada.dom.queue.Builder("whatlinkshere");
vada.dom.queue.builder.whatlinkshere.text="What links here";
vada.dom.queue.builder.whatlinkshere.input="Page";
vada.dom.queue.builder.whatlinkshere.action=function(params){
	var query={};
	query.action="query";
	query.list="backlinks";
	query.bltitle=vada.normalise(params.input);
	query.bllimit=500;
	if(params.continue)query.blcontinue=params.continue;
	var data=vada.api(query);
	var bl=data.query.backlinks;
	for(var i=0;i<bl.length;i++){
		vada.dom.queue.push(new vada.Page(bl[i].title));
	}
	vada.dom.queue.redraw();
	if(data["query-continue"]){
		params.continue=data["query-continue"].backlinks.blcontinue;
		vada.dom.queue.builder.category.action(params);
	}
}
vada.dom.queue.builders.push(vada.dom.queue.builder.whatlinkshere);

vada.dom.queue.builder.catscan=new vada.dom.queue.Builder("catscan");
vada.dom.queue.builder.catscan.text="Catscan";
vada.dom.queue.builder.catscan.input="Catscan URL";
vada.dom.queue.builder.catscan.action=function(params){
	var kwargs=params.input.split("?")[1].split("&");
	var dict={};
	for(var i in kwargs)dict[kwargs[i].split("=")[0]]=kwargs[i].split("=")[1];
	dict.format="json";
	dict.doit="1";
	var query="";
	for(var i in dict)query+=i+"="+dict[i]+"&";
	var xhr=new XMLHttpRequest();
	xhr.open("post","//tools.wmflabs.org/catscan2/catscan2.php",false);
	xhr.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
	xhr.send(query);
	var data=JSON.parse(xhr.responseText);
	for(var i in data["*"][0]["*"]){
		var itm=data["*"][0]["*"][i]["a"];
		vada.dom.queue.push(new vada.Page((itm.namespace?vada.normalise.id_to_namespace[itm.namespace]+":":"")+itm.title));
	}
	vada.dom.queue.redraw();
}
vada.dom.queue.builders.push(vada.dom.queue.builder.catscan);

vada.dom.queue.builders.redraw();

vada.dom.queue.filters={};

vada.dom.queue.filters.trimtop=function(params){
	for(var i=0;i<params.value;i++)vada.dom.queue.shift();
	vada.dom.queue.redraw();
}
vada.dom.queue.filters.trimbottom=function(params){
	for(var i=0;i<params.value;i++)vada.dom.queue.pop();
	vada.dom.queue.redraw();
}
vada.dom.queue.filters.regexremove=function(params){
	var re=new RegExp(params.re,params.case?"i":"");
	for(var i=0;i<vada.dom.queue.length;i++)
		if(vada.dom.queue[i].title.match(re)!==null){
			vada.dom.queue.splice(i,1);
			i--;
		}
	vada.dom.queue.redraw();
}
vada.dom.queue.filters.regexonly=function(params){
	var re=new RegExp(params.re,params.case?"i":"");
	for(var i=0;i<vada.dom.queue.length;i++)
		if(vada.dom.queue[i].title.match(re)===null){
			vada.dom.queue.splice(i,1);
			i--;
		}
	vada.dom.queue.redraw();
}
vada.dom.queue.filters.sortab=function(params){
	vada.dom.queue.sort(function (a, b) {
		if (a.title > b.title)
			return 1;
		if (a.title < b.title)
			return -1;
		return 0;
	});
	vada.dom.queue.redraw();
}

//load(page)
//load(revision)
//load(leftRevision,rightRevision)
//load(page,newText)
//load(revision,newText)
vada.dom.load=function(a,b){
	if(typeof b=="string"){
		if(a instanceof vada.Page){
			var lrv=a.getLatestRevision();
			var history=a;
		}
		else if(a instanceof vada.Revision){
			var lrv=a;
			var history=a.page;
		}
		var rrv=b,title=a.title,user=lrv.user.name,contributions=lrv.user;
	}else{
		if(a instanceof vada.Page){
			var rrv=a.getLatestRevision();
			var history=a;
			var lrv=rrv.parent,user=rrv.user.name,contributions=rrv.user;
		}
		else if(a instanceof vada.Revision){
			var history=a.page;
			if(b instanceof vada.Revision){
				var lrv=a,rrv=b,user=b.user.name,contributions=b.user;
			}else{
				var rrv=a,lrv=rrv.parent,user=rrv.user.name,contributions=rrv.user;
			}
		}
		var title=rrv.title;
	}
		vada.dom._diff.loadLeftRevision(lrv);
		vada.dom._diff.loadRightRevision(rrv);
		vada.dom.call("dom.diff.redraw",{});
		vada.dom.editbox.visible(typeof b=="string");
		vada.dom.page(title);
		vada.dom.user(user);
		vada.dom._history(history);
		vada.dom._contributions(contributions);
}
vada.dom._diff={};
vada.dom.diff=vada.dom._diff;
vada.dom._diff.loadLeftRevision=function(rev){
	vada.dom._diff.leftRevision=rev;
	var params={};
	params["revid"]=rev.revid;
	params["text"]=rev.text;
	params["header"]="<div>Revision as of "+rev.timestamp+"</div><div>"+rev.user.name+"</div><div style='font-style:italic;'>("+rev.parsedcomment+")</div>";
	vada.dom.call("dom.diff.loadleft",params);
}
//loadRightRevision(revision)
//loadRightRevision(newText)
vada.dom._diff.loadRightRevision=function(a){
	vada.dom._diff.rightRevision=a;
	var params={};
	if(typeof a=="string"){
		params["revid"]=0;
		params["text"]=a;
		params["header"]="<div>&nbsp;</div><div>Proposed changes</div><div>&nbsp;</div>";
	}else{
		params["revid"]=a.revid;
		params["text"]=a.text;
		params["header"]="<div>Revision as of "+a.timestamp+"</div><div>"+a.user.name+"</div><div style='font-style:italic;'>("+a.parsedcomment+")</div>";
	}
	vada.dom.call("dom.diff.loadright",params);
}
vada.dom.page=function(page){
	vada.dom.page.page=page;
	vada.dom.call("dom.page",{page:page});
}
vada.dom.user=function(user){
	vada.dom.user.user=user;
	vada.dom.call("dom.user",{user:user});
}
vada.dom.extraInfo=function(html){
	vada.dom.extraInfo.text=html;
	vada.dom.call("dom.setExtraInfo",{text:html});
}
vada.dom._history=function(page){
	vada.dom._history.page=page;
	var history=page.getHistory();
	var ret=[];
	var isprev=false,isnew=false;
	for(var i=Math.min(10,history.length)-1;i>=0;i--){
		var current=history[i];
		if(current.revid==0){
			isnew=true;
			history.pop();
			continue;
		}
		var hs={};
		hs['sizediff']=current.size-(history[i+1]?(history[i+1].revid==0?0:history[i+1].size):0);
		classes=["blob"];
		//if(whitelist.indexOf(hs.user)!=-1)
		//	classes.push("blob-wl");
		if(/rv\b|rvv\b|revert|undid/i.exec(current.comment)!=null)
			classes.push("blob-revert");
		for(var j=Math.min(10,history.length)-1;j>i;j--)
			if(current.sha1==history[j].sha1 && current.user.name!=history[j].user.name){
				classes[classes.length]="blob-revert";
				for(var k=i+1;k<j;k++){
					if(current.sha1==history[k].sha1 || current.user.name==history[k].user.name)break;
					history[k].user.reverted=true;
				}
			}
		if(current.user.isAnonymous())
			classes[classes.length]="blob-anon";
		if(/<a href=\"\/wiki\/Wikipedia:AES\" class=\"mw-redirect\" title=\"Wikipedia:AES\">\u2190<\/a>Replaced content/.exec(current.parsedcomment) || false)
			classes[classes.length]="blob-replaced";
		if(/<a href=\"\/wiki\/Wikipedia:AES\" class=\"mw-redirect\" title=\"Wikipedia:AES\">\u2190<\/a>Blanked the page/.exec(current.parsedcomment) || false)
			classes.push("blob-blanked");
		if(current.tags.length)
			classes.push("blob-tag");
		if(current.user.reverted||false)
			classes.push("blob-reverted");
		if(current.user.inCache("warnlevel") && current.user.warnlevel||false)
			classes.push("blob-warn"+current.user.warnlevel);
		if(current.user.reported)
			classes.push("blob-reported");
		if(current.user.inCache("blocked") && current.user.blocked)
			classes.push("blob-blocked");
		if((history[i+1]||{revid:0}).revid!=0 && current.user==(history[i+1]||{user:null}).user)
			classes.push("hs-before");
		if(current.user==(history[i-1]||{user:null}).user)
			classes.push("hs-after");
		if(isprev==true){
			classes.push("hs-prev");
			isprev=false;
		}
		if(current==(vada.dom._diff.rightRevision||0)){
			classes.push("hs-current");
			isprev=true;
		}
		if(isnew==true){
			classes.push("blob-new");
			isnew=false;
		}
		hs.callback="dom._history.click";
		hs.params={revid:history.revid};
		hs.user=current.user.name;
		hs.timestamp=current.timestamp;
		hs.sizediff=(hs.sizediff<0?'':"+")+hs.sizediff;
		hs.tags=current.tags.join(" | ");
		hs.comment=current.comment;
		hs.classes=classes.join(" ");
		ret.push(hs);
	}
	vada.dom.call("dom.history",{history:ret});
}
vada.dom._history.click=function(params){
	vada.events.trigger("history.selected",new vada.Revision(params.revid));
}
vada.dom._contributions=function(user){
	vada.dom._contributions.user=user;
	var contribs=user.getContributions();
	var ret=[]
	for(var i=0;i<contribs.length;i++){
		var current=contribs[i];
		var classes=["blob"];
		if(current.user.isAnonymous())
			classes.push("blob-anon");
		//if(whitelist.indexOf(current.user)!=-1)
		//	classes.push("blob-wl");
		if(current.parentid==0)
			classes.push("blob-new");
		if(current.user.inCache("warnlevel") && current.user.warnlevel||false)
			classes.push("blob-warn"+current.user.warnlevel);
		if(/<a href=\"\/wiki\/Wikipedia:AES\" class=\"mw-redirect\" title=\"Wikipedia:AES\">\u2190<\/a>Replaced content/.exec(current.comment) || false)
			classes[classes.length]="blob-replaced";
		if(/<a href=\"\/wiki\/Wikipedia:AES\" class=\"mw-redirect\" title=\"Wikipedia:AES\">\u2190<\/a>Blanked the page/.exec(current.comment) || false)
			classes.push("blob-blanked");
		if(current.user.reported)
			classes.push("blob-reported");
		if(current.user.inCache("blocked") && current.user.blocked)
			classes.push("blob-blocked");
		if(current.tags.length)
			classes.push("blob-tag");
		if(current.user.reverted||false)
			classes.push("blob-reverted");
		if(/rv\b|rvv\b|revert|undid/i.exec(current.comment)!=null)
			classes.push("blob-revert");
		//if(genwarn.exec(current.comment)!=null)
		//	classes.push("blob-warning");
		if(current.title=="Wikipedia:Administrator intervention against vandalism")
			classes.push("blob-report");
		/*with({c:current}){
			item.click(function(){
				loadrev({diff:c["diff"],user:contribs["user"],title:c['title']});
			});
		}*/
		ct={};
		ct.classes=classes.join(" ");
		ct.title=current.title;
		ct.timestamp=current.timestamp;
		ct.sizediff=current.sizediff;
		ct.tags=current.tags.join(" | ");
		ct.comment=current.comment;
		ret.push(ct);
	}
	vada.dom.call("dom.contributions",{contributions:ret.reverse()});
}
vada.dom.editbox={};
vada.dom.editbox.visible=function(vis){
	vada.dom.call("dom.editbox.visible",{visible:vis});
}
vada.dom.editbox.value="";
vada.dom.editbox.change=function(params){
	vada.dom.editbox.value=params.text;
}
vada.dom.editbox.setText=function(text){
	vada.dom.call("dom.editbox.setText",{text:text});
}
vada.dom.summarybox={};
vada.dom.summarybox.value="";
vada.dom.summarybox.change=function(params){
	vada.dom.summarybox.value=params.text;
}
vada.dom.summarybox.setText=function(text){
	vada.dom.call("dom.summarybox.setText",{text:text});
}
vada.dom.minorbox={};
vada.dom.minorbox.value=false;
vada.dom.minorbox.change=function(params){
	vada.dom.minorbox.value=params.text;
}
vada.dom.minorbox.setChecked=function(checked){
	vada.dom.call("dom.minorbox.set",{checked:checked});
}
vada.dom.minorbox.check=function(){
	vada.dom.call("dom.minorbox.set",{checked:true});
}
vada.dom.minorbox.uncheck=function(checked){
	vada.dom.call("dom.minorbox.set",{checked:false});
}
vada.dom.menu=[];
vada.dom.menu._buttons={};
vada.dom.menu.Button=function(name){
	this.name=name;
	this.text="Button";
	this.image=null;
	this.shortcut="";
	this.click=Function();
	this.children=[];
	vada.dom.menu._buttons[name]=this;
}
vada.dom.menu.Button.prototype.toDOM=function(){
	var ret={};
	ret.name=this.name;
	ret.text=this.text;
	ret.image=this.image;
	ret.shortcut=this.shortcut;
	ret.callback="dom.menu._buttons."+this.name+".click";
	ret.params={};
	ret.children=[];
	for(var i=0;i<this.children.length;i++){
		ret.children.push(this.children[i].toDOM());
	}
	return ret;
}
vada.dom.menu.redraw=function(){
	var menu=[];
	for(var i=0;i<vada.dom.menu.length;i++){
		menu.push(vada.dom.menu[i].toDOM());
	}
	vada.dom.call("dom.menu.redraw",{menu:menu});
}
vada.dom.menu.new=function(menu){
	while(vada.dom.menu.pop()){}
	vada.dom.menu.push(vada.dom.menu.buttons.vada);
	menu.forEach(function(m){vada.dom.menu.push(m);});
	vada.dom.menu.redraw();
}
vada.dom.menu.buttons={};

vada.dom.menu.buttons.vada=new vada.dom.menu.Button("vada");
vada.dom.menu.buttons.vada.text="Vada";
vada.dom.menu.buttons.vada.image="//tools.wmflabs.org/cluestuff/vada/vadalogos0.png";

vada.dom.menu.buttons.innocent=new vada.dom.menu.Button("innocent");
vada.dom.menu.buttons.innocent.text="Innocent/next";
vada.dom.menu.buttons.innocent.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/sight-and-next.png";
vada.dom.menu.buttons.innocent.shortcut="i";
vada.dom.menu.buttons.innocent.click=function(){
	vada.events.trigger("innocent.click",{});
}

vada.dom.menu.buttons.nextq=new vada.dom.menu.Button("nextq");
vada.dom.menu.buttons.nextq.text="Next";
vada.dom.menu.buttons.nextq.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/diff-next.png";
vada.dom.menu.buttons.nextq.shortcut=" ";
vada.dom.menu.buttons.nextq.click=function(){
	vada.dom.call("dom.queue.next",{});
}

vada.dom.menu.buttons.save=new vada.dom.menu.Button("save");
vada.dom.menu.buttons.save.text="Save";
vada.dom.menu.buttons.save.image="//upload.wikimedia.org/wikipedia/commons/0/0c/Media-floppy.svg";
vada.dom.menu.buttons.save.click=function(){
	//vada.dom._diff.leftRevision.page.text=vada.dom._diff.rightRevision.text||vada.dom._diff.rightRevision;
	//vada.dom._diff.leftRevision.page.save(vada.dom.menu.buttons.save.summary,vada.dom.menu.buttons.save.minor);
	vada.dom._diff.leftRevision.page.text=vada.dom.editbox.value;
	vada.dom._diff.leftRevision.page.save(vada.dom.summarybox.value,vada.dom.minorbox.checked);
	vada.events.trigger("save.click",{});
}
//vada.dom.menu.buttons.save.summary="";
//vada.dom.menu.buttons.save.minor=false;

vada.dom.menu.buttons.revertwarn=new vada.dom.menu.Button("revertwarn");
vada.dom.menu.buttons.revertwarn.text="Revert and Warn";
vada.dom.menu.buttons.revertwarn.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/diff-revert-warn.png";
	
vada.dom.menu.buttons.vandalism=new vada.dom.menu.Button("vandalism");
vada.dom.menu.buttons.vandalism.text="Vandalism";
vada.dom.menu.buttons.vandalism.click=function(){
	vada._revertWarn("Vandalism","Huggle/warn-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.vandalism);

vada.dom.menu.buttons.duc=new vada.dom.menu.Button("duc");
vada.dom.menu.buttons.duc.text="Dubious Unsourced Content";
vada.dom.menu.buttons.duc.click=function(){
	vada._revertWarn("Dubious unsourced content","Huggle/warn-unsor-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.duc);

vada.dom.menu.buttons.roc=new vada.dom.menu.Button("roc");
vada.dom.menu.buttons.roc.text="Removal of Content";
vada.dom.menu.buttons.roc.click=function(){
	vada._revertWarn("Unexplained removal of content","Huggle/warn-delete-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.roc);

vada.dom.menu.buttons.test=new vada.dom.menu.Button("test");
vada.dom.menu.buttons.test.text="Edit Test";
vada.dom.menu.buttons.test.click=function(){
	vada._revertWarn("Edit test","Huggle/warn-test-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.test);

vada.dom.menu.buttons.blanking=new vada.dom.menu.Button("blanking");
vada.dom.menu.buttons.blanking.text="Blanking Pages";
vada.dom.menu.buttons.blanking.click=function(){
	vada._revertWarn("Blanking","Huggle/warn-blank-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.blanking);

// vada.dom.menu.buttons.udc=new vada.dom.menu.Button("udc");
// vada.dom.menu.buttons.udc.text="Unexplained Data Change";
// //vada.dom.menu.buttons.udc.click=//TODO make template?
// vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.udc);

vada.dom.menu.buttons.biased=new vada.dom.menu.Button("biased");
vada.dom.menu.buttons.biased.text="Biased Content";
vada.dom.menu.buttons.biased.click=function(){
	vada._revertWarn("Biased","Huggle/warn-npov-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.biased);

// vada.dom.menu.buttons.notenglish=new vada.dom.menu.Button("notenglish");
// vada.dom.menu.buttons.notenglish.text="Not English";
// //vada.dom.menu.buttons.notenglish.click=//TODO template?
// vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.notenglish);

vada.dom.menu.buttons.advert=new vada.dom.menu.Button("advert");
vada.dom.menu.buttons.advert.text="Advert";
vada.dom.menu.buttons.advert.click=function(){
	vada._revertWarn("Advertising","uw-advert",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.advert);

vada.dom.menu.buttons.spam=new vada.dom.menu.Button("spam");
vada.dom.menu.buttons.spam.text="Spamlinks";
vada.dom.menu.buttons.spam.click=function(){
	vada._revertWarn("Spam","Huggle/warn-spam-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.spam);

vada.dom.menu.buttons.fe=new vada.dom.menu.Button("fe");
vada.dom.menu.buttons.fe.text="Factual Errors";
vada.dom.menu.buttons.fe.click=function(){
	vada._revertWarn("Factual errors","Huggle/warn-error-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.fe);

vada.dom.menu.buttons.or=new vada.dom.menu.Button("or");
vada.dom.menu.buttons.or.text="Original Research";
vada.dom.menu.buttons.or.click=function(){
	vada._revertWarn("Original research","uw-nor",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.or);

vada.dom.menu.buttons.notlist=new vada.dom.menu.Button("notlist");
vada.dom.menu.buttons.notlist.text="Not Notable for List";
vada.dom.menu.buttons.notlist.click=function(){
	(function(l,r){
		var reason="Not notable for list";
		l.page.text=l.text;
		var rev=l.page.save("Reverted edits by [[Special:Contributions/"+r.user.name+"|"+r.user.name+"]]  ([[User talk:"+r.user.name+"|talk]]): "+reason,true);
		if(rev.revid)r.user.warn("{{subst:"+"uw-badlistentry|"+l.page.title+"}} ~~"+"~~","Warning: "+reason+" on [["+l.page.title+"]]",r,l);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.notlist);

vada.dom.menu.buttons.removespeedy=new vada.dom.menu.Button("removespeedy");
vada.dom.menu.buttons.removespeedy.text="Removing Speedy Deletion Templates";
vada.dom.menu.buttons.removespeedy.click=function(){
	vada._revertWarn("Removing speedy deletion templates","Huggle/warn-speedy-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.revertwarn.children.push(vada.dom.menu.buttons.removespeedy);

vada.dom.menu.buttons.revert=new vada.dom.menu.Button("revert");
vada.dom.menu.buttons.revert.text="Revert";
vada.dom.menu.buttons.revert.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/diff-revert.png";
vada.dom.menu.buttons.revert.click=function(){
	vada.dom._diff.leftRevision.page.text=vada.dom._diff.leftRevision.text;
	vada.dom._diff.leftRevision.page.save("Reverted edits by [[Special:Contributions/"+vada.dom._diff.rightRevision.user.name+"|"+vada.dom._diff.rightRevision.user.name+"]]  ([[User talk:"+vada.dom._diff.rightRevision.user.name+"|talk]])",true);
}

vada.dom.menu.buttons.uroc=new vada.dom.menu.Button("uroc");
vada.dom.menu.buttons.uroc.text="Unexplained Removal of Content";
vada.dom.menu.buttons.uroc.click=function(){
	(function(l,r){
		l.page.text=l.text;
		l.page.save("Reverted edits by [[Special:Contributions/"+r.user.name+"|"+r.user.name+"]]  ([[User talk:"+r.user.name+"|talk]]): Unexplained removal of content",true);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.revert.children.push(vada.dom.menu.buttons.uroc);

vada.dom.menu.buttons.unsourced=new vada.dom.menu.Button("unsourced");
vada.dom.menu.buttons.unsourced.text="Dubious Unsourced Content";
vada.dom.menu.buttons.unsourced.click=function(){
	(function(l,r){
		l.page.text=l.text;
		l.page.save("Reverted edits by [[Special:Contributions/"+r.user.name+"|"+r.user.name+"]]  ([[User talk:"+r.user.name+"|talk]]): Dubious unsourced content",true);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.revert.children.push(vada.dom.menu.buttons.unsourced);

vada.dom.menu.buttons.agf=new vada.dom.menu.Button("agf");
vada.dom.menu.buttons.agf.text="Assume Good Faith";
vada.dom.menu.buttons.agf.click=function(){
	(function(l,r){
		l.page.text=l.text;
		l.page.save("Reverted [[WP:AGF|good faith]] edits by [[Special:Contributions/"+r.user.name+"|"+r.user.name+"]]  ([[User talk:"+r.user.name+"|talk]])",true);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.revert.children.push(vada.dom.menu.buttons.agf);

vada.dom.menu.buttons.bb=new vada.dom.menu.Button("bb");
vada.dom.menu.buttons.bb.text="Better Before";
vada.dom.menu.buttons.bb.click=function(){
	(function(l,r){
		l.page.text=l.text;
		l.page.save("Reverted edits by [[Special:Contributions/"+r.user.name+"|"+r.user.name+"]]  ([[User talk:"+r.user.name+"|talk]]): Article was better before the edits",true);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.revert.children.push(vada.dom.menu.buttons.bb);

vada.dom.menu.buttons.template=new vada.dom.menu.Button("template");
vada.dom.menu.buttons.template.text="Template User";
vada.dom.menu.buttons.template.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/user-talk.png";

vada.dom.menu.buttons.coi=new vada.dom.menu.Button("coi");
vada.dom.menu.buttons.coi.text="Conflict of Interest";
vada.dom.menu.buttons.coi.click=function(){
	(function(l,r){
		r.user.warn("{{subst:"+"uw-coi|"+r.page.title+"}} ~~"+"~~","Warning: Conflict of interest on [["+r.page.title+"]]",r,l);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.template.children.push(vada.dom.menu.buttons.coi);

vada.dom.menu.buttons.summary=new vada.dom.menu.Button("summary");
vada.dom.menu.buttons.summary.text="Edit Summary";
vada.dom.menu.buttons.summary.click=function(){
	(function(l,r){
		r.user.warn("{{subst:"+"uw-editsummary|"+r.page.title+"}} ~~"+"~~","Note: No edit summary on [["+r.page.title+"]]",r,l);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.template.children.push(vada.dom.menu.buttons.summary);

vada.dom.menu.buttons.selfrevert=new vada.dom.menu.Button("selfrevert");
vada.dom.menu.buttons.selfrevert.text="Self Reverting";
vada.dom.menu.buttons.selfrevert.click=function(){
	(function(l,r){
		r.user.warn("{{subst:"+"uw-selfrevert|"+r.page.title+"}} ~~"+"~~","Warning: Self reverting on [["+r.page.title+"]]",r,l);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.template.children.push(vada.dom.menu.buttons.selfrevert);

vada.dom.menu.buttons.warn=new vada.dom.menu.Button("warn");
vada.dom.menu.buttons.warn.text="Warn";
vada.dom.menu.buttons.warn.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/user-warn.png";

vada.dom.menu.buttons.rvandalism=new vada.dom.menu.Button("rvandalism");
vada.dom.menu.buttons.rvandalism.text="Vandalism";
vada.dom.menu.buttons.rvandalism.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Vandalism","Huggle/warn-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.rvandalism);

vada.dom.menu.buttons.rduc=new vada.dom.menu.Button("rduc");
vada.dom.menu.buttons.rduc.text="Dubious Unsourced Content";
vada.dom.menu.buttons.rduc.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Dubious unsourced content","Huggle/warn-unsor-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.rduc);

vada.dom.menu.buttons.rroc=new vada.dom.menu.Button("rroc");
vada.dom.menu.buttons.rroc.text="Removal of Content";
vada.dom.menu.buttons.rroc.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Unexplained removal of content","Huggle/warn-delete-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.roc);

vada.dom.menu.buttons.rtest=new vada.dom.menu.Button("rtest");
vada.dom.menu.buttons.rtest.text="Edit Test";
vada.dom.menu.buttons.rtest.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Edit test","Huggle/warn-test-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.rtest);

vada.dom.menu.buttons.rblanking=new vada.dom.menu.Button("rblanking");
vada.dom.menu.buttons.rblanking.text="Blanking Pages";
vada.dom.menu.buttons.rblanking.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Blanking","Huggle/warn-blank-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.rblanking);

// vada.dom.menu.buttons.rudc=new vada.dom.menu.Button("rudc");
// vada.dom.menu.buttons.rudc.text="Unexplained Data Change";
// //vada.dom.menu.buttons.rudc.click=//TODO make template?
// vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.rudc);

vada.dom.menu.buttons.rbiased=new vada.dom.menu.Button("rbiased");
vada.dom.menu.buttons.rbiased.text="Biased Content";
vada.dom.menu.buttons.rbiased.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Biased","Huggle/warn-npov-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.rbiased);

// vada.dom.menu.buttons.notenglish=new vada.dom.menu.Button("rnotenglish");
// vada.dom.menu.buttons.notenglish.text="Not English";
// //vada.dom.menu.buttons.notenglish.click=//TODO template?
// vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.notenglish);

vada.dom.menu.buttons.radvert=new vada.dom.menu.Button("advert");
vada.dom.menu.buttons.radvert.text="Advert";
vada.dom.menu.buttons.radvert.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Advertising","uw-advert",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.advert);

vada.dom.menu.buttons.rspam=new vada.dom.menu.Button("rspam");
vada.dom.menu.buttons.rspam.text="Spamlinks";
vada.dom.menu.buttons.rspam.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Spam","Huggle/warn-spam-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.rspam);

vada.dom.menu.buttons.rfe=new vada.dom.menu.Button("rfe");
vada.dom.menu.buttons.rfe.text="Factual Errors";
vada.dom.menu.buttons.rfe.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Factual errors","Huggle/warn-error-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.rfe);

vada.dom.menu.buttons.ror=new vada.dom.menu.Button("ror");
vada.dom.menu.buttons.ror.text="Original Research";
vada.dom.menu.buttons.ror.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Original research","uw-nor",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.or);

vada.dom.menu.buttons.rnotlist=new vada.dom.menu.Button("rnotlist");
vada.dom.menu.buttons.rnotlist.text="Not Notable for List";
vada.dom.menu.buttons.rnotlist.click=function(){
	(function(l,r){
		var reason="Not notable for list";
		l.page.text=l.text;
		var rev=l.page.save("Reverted edits by [[Special:Contributions/"+r.user.name+"|"+r.user.name+"]]  ([[User talk:"+r.user.name+"|talk]]): "+reason,true);
		if(rev.revid)r.user.warn("{{subst:"+"uw-badlistentry|"+l.page.title+"}} ~~"+"~~","Warning: "+reason+" on [["+l.page.title+"]]",r,l);
	})(vada.dom._diff.leftRevision,vada.dom._diff.rightRevision);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.notlist);

vada.dom.menu.buttons.rremovespeedy=new vada.dom.menu.Button("rremovespeedy");
vada.dom.menu.buttons.rremovespeedy.text="Removing Speedy Deletion Templates";
vada.dom.menu.buttons.rremovespeedy.click=function(){
	(function(reason,template,l,r,link){r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?("~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);})("Removing speedy deletion templates","Huggle/warn-speedy-",vada.dom._diff.leftRevision,vada.dom._diff.rightRevision,true);
}
vada.dom.menu.buttons.warn.children.push(vada.dom.menu.buttons.removespeedy);

vada.dom.menu.buttons.thank=new vada.dom.menu.Button("thank");
vada.dom.menu.buttons.thank.text="Thank";
vada.dom.menu.buttons.thank.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/user-welcome.png";
vada.dom.menu.buttons.thank.click=function(){
	vada.api({action:"thank",rev:vada.dom._diff.rightRevision.revid,token:vada.api.edittoken,source:"Vada"});
}

vada.dom.menu.buttons.previous=new vada.dom.menu.Button("previous");
vada.dom.menu.buttons.previous.text="Previous";
vada.dom.menu.buttons.previous.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/browser-prev.png";
vada.dom.menu.buttons.previous.shortcut="z";
vada.dom.menu.buttons.previous.click=function(){
	vada.events.trigger("previous.click",{});
}

vada.dom.menu.buttons.next=new vada.dom.menu.Button("next");
vada.dom.menu.buttons.next.text="Next";
vada.dom.menu.buttons.next.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/browser-next.png";
vada.dom.menu.buttons.next.shortcut="x";
vada.dom.menu.buttons.next.click=function(){
	vada.events.trigger("next.click",{});
}

vada.dom.menu.buttons.tagdelete=new vada.dom.menu.Button("tagdelete");
vada.dom.menu.buttons.tagdelete.text="Tag for Deletion";
vada.dom.menu.buttons.tagdelete.image="//raw.githubusercontent.com/huggle/huggle3-qt-lx/master/huggle/Resources/page-delete.png";

vada.dom.menu.buttons.tagdelete.makeButton=function(o){
    var tag=o.code.toLowerCase();
vada.dom.menu.buttons.tagdelete[tag]=new vada.dom.menu.Button(tag);
vada.dom.menu.buttons.tagdelete[tag].text=o.code+": "+o.text;
vada.dom.menu.buttons.tagdelete[tag].click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;
             vada.dom.queue.next();
             p.text="{{db-"+tag+"}}\n"+p.text;
             p.save("Tagging page for [[WP:SD#"+o.code+"|speedy deletion ("+o.code+")]]");
             if(!("nowarn" in o)){
               tp.text=tp.text+"\n\n{{subst"+":db-"+tag+"-notice|"+p.title+"|header=1}} ~~"+"~~";
               tp.save("Notification: Speedy deletion of [["+p.title+"]]");
             }
}
return vada.dom.menu.buttons.tagdelete[tag];
}

vada.dom.menu.buttons.tagdelete.general=new vada.dom.menu.Button("tagdeletegeneral");
vada.dom.menu.buttons.tagdelete.general.text="General Deletion";
vada.dom.menu.buttons.tagdelete.children.push(vada.dom.menu.buttons.tagdelete.general)

vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G1", text: "Patent nonsense"}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G2", text: "Test page"}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G3", text: "Vandalism"}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G4", text: "Recreation of deleted content"}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G5", text: "Created by banned user", nowarn: true}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G6", text: "Maintenance", nowarn: true}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G7", text: "Blanked or requested by author", nowarn: true}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G8", text: "Orphaned talk page", nowarn: true}));

vada.dom.menu.buttons.tagdelete.g10=new vada.dom.menu.Button("g10");
vada.dom.menu.buttons.tagdelete.g10.text="G10: Attack page";
vada.dom.menu.buttons.tagdelete.g10.click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;;
             vada.dom.queue.next();
             p.text="{{db-g10}}";
             p.save("Tagging page for [[WP:SD#G10|speedy deletion (G10)]]");
             tp.text=tp.text+"\n\n{{subst"+":db-attack-notice|"+p.title+"|header=1}} ~~"+"~~";
             tp.save("Notification: Speedy deletion of [["+p.title+"]]");
}
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.g10);

vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G11", text: "Unambgious spam or promotional content"}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G12", text: "Copyright infringment"}));
vada.dom.menu.buttons.tagdelete.general.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "G13", text: "Abandoned articles for creation submissions"}));

vada.dom.menu.buttons.tagdelete.article=new vada.dom.menu.Button("tagdeletearticle");
vada.dom.menu.buttons.tagdelete.article.text="Article Deletion";
vada.dom.menu.buttons.tagdelete.children.push(vada.dom.menu.buttons.tagdelete.article)

vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "A1", text: "Article provides no context"}));
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "A2", text: "Wrong project"}));
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "A3", text: "No content"}));
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "A5", text: "Transwikied article"}));
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "A7", text: "Importance/significance not asserted"}));

vada.dom.menu.buttons.tagdelete.article.a7a=new vada.dom.menu.Button("a7a");
vada.dom.menu.buttons.tagdelete.article.a7a.text="A7a: - Band";
vada.dom.menu.buttons.tagdelete.article.a7a.click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;
             vada.dom.queue.next();
             p.text="{{db-band}}\n"+p.text;
             p.save("Tagging page for [[WP:SD#A7|speedy deletion (A7)]]");
             tp.text=tp.text+"\n\n{{subst"+":db-band-notice|"+p.title+"|header=1}} ~~"+"~~";
             tp.save("Notification: Speedy deletion of [["+p.title+"]]");
}
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.article.a7a);

vada.dom.menu.buttons.tagdelete.article.a7b=new vada.dom.menu.Button("a7b");
vada.dom.menu.buttons.tagdelete.article.a7b.text="A7b: - Biography";
vada.dom.menu.buttons.tagdelete.article.a7b.click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;
             vada.dom.queue.next();
             p.text="{{db-person}}\n"+p.text;
             p.save("Tagging page for [[WP:SD#A7|speedy deletion (A7)]]");
             tp.text=tp.text+"\n\n{{subst"+":db-person-notice|"+p.title+"|header=1}} ~~"+"~~";
             tp.save("Notification: Speedy deletion of [["+p.title+"]]");
}
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.article.a7b);

vada.dom.menu.buttons.tagdelete.article.a7c=new vada.dom.menu.Button("a7c");
vada.dom.menu.buttons.tagdelete.article.a7c.text="A7c: - Club or group of people";
vada.dom.menu.buttons.tagdelete.article.a7c.click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;
             vada.dom.queue.next();
             p.text="{{db-club}}\n"+p.text;
             p.save("Tagging page for [[WP:SD#A7|speedy deletion (A7)]]");
             tp.text=tp.text+"\n\n{{subst"+":db-club-notice|"+p.title+"|header=1}} ~~"+"~~";
             tp.save("Notification: Speedy deletion of [["+p.title+"]]");
}
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.article.a7c);

vada.dom.menu.buttons.tagdelete.article.a7d=new vada.dom.menu.Button("a7d");
vada.dom.menu.buttons.tagdelete.article.a7d.text="A7d: - Company or organisation";
vada.dom.menu.buttons.tagdelete.article.a7d.click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;
             vada.dom.queue.next();
             p.text="{{db-inc}}\n"+p.text;
             p.save("Tagging page for [[WP:SD#A7|speedy deletion (A7)]]");
             tp.text=tp.text+"\n\n{{subst"+":db-inc-notice|"+p.title+"|header=1}} ~~"+"~~";
             tp.save("Notification: Speedy deletion of [["+p.title+"]]");
}
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.article.a7d);

vada.dom.menu.buttons.tagdelete.article.a7e=new vada.dom.menu.Button("a7e");
vada.dom.menu.buttons.tagdelete.article.a7e.text="A7e: - Website";
vada.dom.menu.buttons.tagdelete.article.a7e.click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;
             vada.dom.queue.next();
             p.text="{{db-web}}\n"+p.text;
             p.save("Tagging page for [[WP:SD#A7|speedy deletion (A7)]]");
             tp.text=tp.text+"\n\n{{subst"+":db-web-notice|"+p.title+"|header=1}} ~~"+"~~";
             tp.save("Notification: Speedy deletion of [["+p.title+"]]");
}
vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.article.a7e);

vada.dom.menu.buttons.tagdelete.article.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "A9", text: "Song/music lacking artist article and assertation of notability"}));

vada.dom.menu.buttons.tagdelete.file=new vada.dom.menu.Button("tagdeletefile");
vada.dom.menu.buttons.tagdelete.file.text="File Deletion";
vada.dom.menu.buttons.tagdelete.children.push(vada.dom.menu.buttons.tagdelete.file)

vada.dom.menu.buttons.tagdelete.file.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "F1", text: "Redundant image"}));
vada.dom.menu.buttons.tagdelete.file.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "F2", text: "Corrupt or empty image"}));

vada.dom.menu.buttons.tagdelete.f2b=new vada.dom.menu.Button("f2b");
vada.dom.menu.buttons.tagdelete.f2b.text="F2b: Local description for file at Commons";
vada.dom.menu.buttons.tagdelete.f2b.click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;
             vada.dom.queue.next();
             p.text="{{Db-fpcfail}}\n"+p.text;
             p.save("Tagging page for [[WP:SD#F2|speedy deletion (F2)]]");
             tp.text=tp.text+"\n\n{{subst"+":Db-noimage-notice|"+p.title+"|header=1}} ~~"+"~~";
             tp.save("Notification: Speedy deletion of [["+p.title+"]]");
}
vada.dom.menu.buttons.tagdelete.file.children.push(vada.dom.menu.buttons.tagdelete.f2b);

vada.dom.menu.buttons.tagdelete.file.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "F3", text: "Improper licence"}));

vada.dom.menu.buttons.tagdelete.f4=new vada.dom.menu.Button("f2b");
vada.dom.menu.buttons.tagdelete.f4.text="F4: Missing source or licensing detail";
vada.dom.menu.buttons.tagdelete.f4.click=function(){
             var r=vada.dom._diff.leftRevision, p=r.page, data=vada.api({action:"query",prop:"revisions",titles:p.title,rvprop:"user",rvdir:"newer",rvlimit:"1"});
             for(var pageid in data.query.pages)break;
             var tp=new vada.User(data.query.pages[pageid].revisions[0].user).talkpage;
             vada.dom.queue.next();
             p.text="{{subst"+":nld}}\n"+p.text;
             p.save("Tagging page for [[WP:SD#F4|speedy deletion (F2)]]");
             tp.text=tp.text+"\n\n{{subst"+":di-no license-notice|"+p.title+"|1=Di-no license}} ~~"+"~~";
             tp.save("Notification: Speedy deletion of [["+p.title+"]]");
}
vada.dom.menu.buttons.tagdelete.file.children.push(vada.dom.menu.buttons.tagdelete.f4);

vada.dom.menu.buttons.tagdelete.file.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "F9", text: "Copyright infringement"}));
vada.dom.menu.buttons.tagdelete.file.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "F10", text: "Useless file"}));

vada.dom.menu.buttons.tagdelete.redirect=new vada.dom.menu.Button("tagdeleteredirect");
vada.dom.menu.buttons.tagdelete.redirect.text="Redirect Deletion";
vada.dom.menu.buttons.tagdelete.children.push(vada.dom.menu.buttons.tagdelete.redirect)

vada.dom.menu.buttons.tagdelete.redirect.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "R1", text: "Redirect to nonexistent page", nowarn: true}));
vada.dom.menu.buttons.tagdelete.redirect.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "R2", text: "Cross-namespace redirect"}));
vada.dom.menu.buttons.tagdelete.redirect.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "R3", text: "Implausible redirect"}));

vada.dom.menu.buttons.tagdelete.user=new vada.dom.menu.Button("tagdeleteuser");
vada.dom.menu.buttons.tagdelete.user.text="User Deletion";
vada.dom.menu.buttons.tagdelete.children.push(vada.dom.menu.buttons.tagdelete.user)

vada.dom.menu.buttons.tagdelete.user.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "U1", text: "Requested by user", nowarn: true}));
vada.dom.menu.buttons.tagdelete.user.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "U2", text: "Nonexistent user", nowarn: true}));
vada.dom.menu.buttons.tagdelete.user.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "U3", text: "Non-free image gallery"}));

vada.dom.menu.buttons.tagdelete.template=new vada.dom.menu.Button("tagdeletetemplate");
vada.dom.menu.buttons.tagdelete.template.text="Template Deletion";
vada.dom.menu.buttons.tagdelete.children.push(vada.dom.menu.buttons.tagdelete.template)

vada.dom.menu.buttons.tagdelete.template.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "T2", text: "Policy misrepresentation"}));

vada.dom.menu.buttons.tagdelete.portal=new vada.dom.menu.Button("tagdeleteportal");
vada.dom.menu.buttons.tagdelete.portal.text="Portal Deletion";
vada.dom.menu.buttons.tagdelete.children.push(vada.dom.menu.buttons.tagdelete.portal)

vada.dom.menu.buttons.tagdelete.portal.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "P1", text: "Portal that would be deleted as an article", nowarn: true}));
vada.dom.menu.buttons.tagdelete.portal.children.push(vada.dom.menu.buttons.tagdelete.makeButton({code: "P2", text: "Underpopulated portal", nowarn: true}));

vada.Page=function(title){
	if(vada.normalise(title) in vada.Page._pagejar)return vada.Page._pagejar[vada.normalise(title)];
	this._title=vada.normalise(title);
	this._revisions={};
	vada.Page._pagejar[this.title]=this;
};
vada.Page._pagejar={};
vada.Page.click=function(params){
	vada.events.trigger("queue.page.selected",new vada.Page(params.title));
}
vada.Page.prototype={
	getLatestRevision:function(){
		if("cur" in this._revisions)return this._revisions["cur"];
		var rev=new vada.Revision(this.title);
		this._revisions["cur"]=rev;
		return rev;
	},
	get title(){
		return this._title;
	},
	get text(){
		return (this._text==undefined)?this.getLatestRevision().text:this._text;
	},
	set text(txt){
		this._text=txt;
	},
	get namespace(){
		var ns={"Talk":1,"User":2,"User talk":3,"Wikipedia":4,"Wikipedia talk":5,"File":6,"File talk":7,"MediaWiki":8,"MediaWiki talk":9,"Template":10,"Template talk":11,"Help":12,"Help talk":13,"Category":14,"Category talk":15,"Portal":100,"Portal talk":101,"Book":108,"Book talk":109,"Draft":118,"Draft talk":119,"Education Program":446,"Education Program talk":447,"TimedText":710,"TimedText talk":711,"Module":828,"Module talk":829,"Special":-1,"Media":-2};
		return ns[this.title.substr(0,this.title.indexOf(":"))] || 0;
	},
	save:function(summary,minor){
		if(this._text==undefined) throw({toString:function(){return "NothingToSave";},message:"No text was set to be saved"});
		var query={};
		query["action"]="edit";
		query["title"]=this.title;
		try{
			if("cur" in this._revisions)query["basetimestamp"]=this._revisions["cur"].timestamp;
		}catch(err){
			if(err!="PageDoesNotExist")throw err;
		}
		query["text"]=this._text;
		query["summary"]=summary+vada.settings.summarytag;
		if(minor){
			query["minor"]="";
		}else{
			query["notminor"]="";
		}
		query["token"]=vada.api.edittoken;
		var data=vada.api(query);
		if(data.error){
			switch(data.error.code){
				case "badtoken":
					vada.api.edittoken=vada.api({action:"tokens"}).tokens.edittoken;//TODO error handle
					this.save(summary,minor);
					break;
				default:
					throw {e:"Unspecified error saving page",d:data};//TODO error handling
			}
		}
		var rev=new vada.Revision(data.edit.newrevid);
		this.addrevision(rev);
		this._text=undefined;
		return rev;
		
	},
	addrevision:function(rev){
		this._revisions[rev.revid]=rev;
	},
	getHistory:function(){
		vada._getRevisions(this.title,11);
		var ret=[this.getLatestRevision()];
		for(var i=0;i<Math.min(10,Object.keys(this._revisions).length-1);i++){
			ret.push(ret[ret.length-1].parent);
		}
		return ret;
	},
	toDOM:function(){
		var item={};
		item.text=this.title;
		item.classes="";
		item.data={};
		item.style="";
		item.callback="Page.click";
		item.params={title:this.title};
		return item;
	},
}
vada.normalise=function(text){
	text=text.replace(/_/g," ");
	for(var a in vada.normalise.aliases){
		if(text.charAt(a.length)==":" && text.substr(0,a.length).toUpperCase()==a.toUpperCase()){
			text=vada.normalise.aliases[a]+text.substr(a.length);break;
		}
	}
	var ns="",title=text;
	for(var i=0;i<vada.normalise.namespaces.length;i++){
		if(text.charAt(vada.normalise.namespaces[i].length)==":" && text.substr(0,vada.normalise.namespaces[i].length).toLowerCase()==vada.normalise.namespaces[i].toLowerCase()){
			ns=vada.normalise.namespaces[i];
			title=text.substr(vada.normalise.namespaces[i].length+1);
		}
	}
	title=(title.charAt(0).toUpperCase()+title.substr(1));
	text=(ns?ns+":":"")+title;
	return text;
}
vada.normalise.namespaces=["Talk","User","User talk","Wikipedia","Wikipedia talk","File","File talk","MediaWiki","MediaWiki talk","Template","Template talk","Help","Help talk","Category","Category talk","Portal","Portal talk","Book","Book talk","Draft","Draft talk","Education Program","Education Program talk","TimedText","TimedText talk","Module","Module talk","Special","Media"];
vada.normalise.aliases={"WP":"Wikipedia","WT":"Wikipedia talk","Image":"File","Image talk":"File talk","Project":"Wikipedia","Project talk":"Wikipedia talk"};
vada.normalise.id_to_namespace={1:"Talk",2:"User",3:"User talk",4:"Wikipedia",5:"Wikipedia talk",6:"File",7:"File talk",8:"MediaWiki",9:"MediaWiki talk",10:"Template",11:"Template talk",12:"Help",13:"Help talk",14:"Category",15:"Category talk",100:"Portal",101:"Portal talk",108:"Book",109:"Book talk",118:"Draft",119:"Draft talk",446:"Education Program",447:"Education Program talk",710:"TimedText",711:"TimedText talk",828:"Module",829:"Module talk","-1":"Special","-2":"Media"};
vada.normalize=vada.normalise; //for those who spell it wrong

vada._revisionjar={};
vada.Revision=function(revid){
	if(revid in vada._revisionjar)return vada._revisionjar[revid];
	this._revid=revid;
	vada._revisionjar[revid]=this;
}
vada.Revision.click=function(params){
	vada.events.trigger("queue.revision.selected",new vada.Revision(params.revid));
}
vada.Revision.prototype={
	set title(val){
		this._title=val;
		this.page=new vada.Page(val);
	},
	set text(val){
		this._text=val;
	},
	set page(val){
		this._page=val;
	},
	set comment(val){
		this._comment=val;
	},
	set minor(val){
		this._minor=val;
	},
	set parentid(val){
		this._parentid=val;
	},
	set parent(val){
		this._parent=val;
	},
	set parsedcomment(val){
		this._parsedcomment=val;
	},
	set sha1(val){
		this._sha1=val;
	},
	set size(val){
		this._size=val;
	},
	set tags(val){
		this._tags=val;
	},
	set timestamp(val){
		this._timestamp=val;
	},
	set user(val){
		this._user=val;
	},
	set userid(val){
		this._userid=val;
	},
	get revid(){
		if((typeof this._revid)=="string")
			this._fetch();
		return this._revid;
	},
	get text(){
		if(this._text==undefined)
			this._fetch();
		return this._text;
	},
	get title(){
		if(!this._title)
			this._fetch();
		return this._title;
	},
	get page(){
		if(!this._page)
			this._fetch();
		return this._page;
	},
	get comment(){
		if(this._comment==undefined)
			this._fetch();
		return this._comment;
	},
	get minor(){
		if(this._minor==undefined)
			this._fetch();
		return this._minor;
	},
	get parentid(){
		if(this._parentid==undefined)
			this._fetch();
		return this._parentid;
	},
	get parent(){
		if(!this._parent)
			this._fetch();
		return this._parent;
	},
	get parsedcomment(){
		if(this._parsedcomment==undefined)
			this._fetch();
		return this._parsedcomment;
	},
	get sha1(){
		if(!this._sha1)
			this._fetch();
		return this._sha1;
	},
	get size(){
		if(this._size==undefined)
			this._fetch();
		return this._size;
	},
	get tags(){
		if(!this._tags)
			this._fetch();
		return this._tags;
	},
	get timestamp(){
		if(!this._timestamp)
			this._fetch();
		return this._timestamp;
	},
	get user(){
		if(!this._user)
			this._fetch();
		return this._user;
	},
	get userid(){
		if(!this._userid)
			this._fetch();
		return this._userid;
	},
	get child(){
		var getchild=(function(r){for(i in r.page._revisions){
			if(r.revid==r.page._revisions[i].parent.revid){
				return r.page._revisions[i];
			}
		}
		return undefined;
		});
		var ret=getchild(this);
		if(ret)return ret;
		vada._getRevisions(this.title,500);
		return getchild(this);
	},
	_fetch: function(){
		var query={};
		query["action"]="query";
		query["prop"]="revisions";
		if(isNaN(parseFloat(this._revid)) || !isFinite(this._revid)){//if(isNaN(parseInt(this._revid))){ //assume revid is a page title? If so, get latest revision
			query["titles"]=this._revid;
		}else{
			query["revids"]=this._revid;
		}
		query["rvprop"]="ids|flags|timestamp|user|userid|size|sha1|comment|parsedcomment|content|tags";
		var data=vada.api(query);
		if(data.query.badrevids)throw({toString:function(){return "BadRevId";},message:"Revision does not exist"});
		if(data.query.pages["-1"])throw({toString:function(){return "PageDoesNotExist";},message:"Page does not exist"});//TODO revision/page
		for(var pageid in data.query.pages)break; //get pageid
		var revision=data.query.pages[pageid].revisions[0];
		this.title=data.query.pages[pageid].title;
		this.page=new vada.Page(data.query.pages[pageid].title);
		this._revid=revision.revid;
		this.text=revision.texthidden==""?null:revision["*"];
		this.comment=revision.commenthidden==""?null:revision.comment;
		this.minor=(revision.minor!="");
		this.parentid=revision.parentid;
		this.parent=new vada.Revision(revision.parentid);
		this.parsedcomment=revision.commenthidden==""?null:revision.parsedcomment;
		this.sha1=revision.sha1hidden==""?null:revision.sha1;
		this.size=revision.size;
		this.tags=revision.tags;
		this.timestamp=revision.timestamp;
		this.user=revision.userhidden==""?null:new vada.User(revision.user);
		this.userid=revision.userid;
	},
	toDOM:function(){
		var item={};
		item.text="Rev "+this.revid;
		item.classes="";
		item.data={};
		item.style="";
		item.callback="Revision.click";
		item.params={revid:this.revid};
		return item;
	}
}
vada._getRevisions=function(title,n){
	var query={};
	query["action"]="query";
	query["prop"]="revisions";
	query["titles"]=title;
	query["rvlimit"]=n||2;
	query["rvprop"]="ids|flags|timestamp|user|userid|size|sha1|comment|parsedcomment|content|tags";
	var data=vada.api(query);
	if(data.query.pages["-1"])throw({toString:function(){return "PageDoesNotExist";},message:"Page does not exist"});//TODO revision/page
	for(var pageid in data.query.pages)break; //get pageid
	for(var i in data.query.pages[pageid].revisions){
		var revision=data.query.pages[pageid].revisions[i];
		var rev=new vada.Revision(revision.revid);
		rev.title=data.query.pages[pageid].title;
		rev.page=new vada.Page(rev.title);
		rev.text=revision.texthidden==""?null:revision["*"];
		rev.comment=revision.commenthidden==""?null:revision.comment;
		rev.minor=(revision.minor!="");
		rev.parentid=revision.parentid;
		rev.parent=new vada.Revision(revision.parentid);
		rev.parsedcomment=revision.commenthidden==""?null:revision.parsedcomment;
		rev.sha1=revision.sha1hidden==""?null:revision.sha1;
		rev.size=revision.size;
		rev.tags=revision.tags;
		rev.timestamp=revision.timestamp;
		rev.user=revision.userhidden==""?null:new vada.User(revision.user);
		rev.userid=revision.userid;
		(new vada.Page(rev.title)).addrevision(rev);
	}
}

vada._userjar=[];
vada.User=function(name){
	var findname=vada._getuserby("name",name);
	if(findname)return findname;
	this._name=name;
	vada._userjar.push(this);
}
vada._getuserby=function(by,v){
	v=vada.normalise(v);
	for(user in vada._userjar){
		if(vada._userjar[user][by]==v)return vada._userjar[user];
	}
}
vada.User.prototype={
	_fetch: function(){
		var query={};
		query["action"]="query";
		query["list"]="users";
		query["ususers"]=this._name;
		query["usprop"]="blockinfo|groups|implicitgroups|rights|editcount|registration|emailable|gender";
		var data=vada.api(query);
		var user=data.query.users[0];
		if(user.missing!==undefined)throw({toString:function(){return "UserDoesNotExist";},message:"User does not exist"});
		if(user.blockid!==undefined){
			this._blocked=true;
			this._blockid=user.blockid;
			this._blockedby=user.blockedby;
			this._blockedbyid=user.blockedbyid;
			this._blockedreason=user.blockedreason;
			this._blockedexpiry=user.blockedexpiry;
		}else{
			this._blocked=false;
		}
		this._userid=user.userid;
		this._editcount=user.editcount;
		this._registration=user.registration;
		this._groups=user.groups;
		this._implicitgroups=user.implicitgroups;
		this._rights=user.rights;
		this._emailable=(user.emailable===undefined)?false:true;
	},
	get blocked(){if(this._blocked==undefined)this._fetch();return this._blocked==true;},
	get blockid(){if(!this._blockid)this._fetch();return this._blockid;},
	get blockedby(){if(!this._blockedby)this._fetch();return this._blockedby;},
	get blockedbyid(){if(!this._blockedbyid)this._fetch();return this._blockedbyid;},
	get blockedreason(){if(!this._blockedreason)this._fetch();return this._blockedreason;},
	get blockedexpiry(){if(!this._blockedexpiry)this._fetch();return this._blockedexpiry;},
	get userid(){if(!this._userid)this._fetch();return this._userid;},
	get editcount(){if(this._editcount==undefined)this._fetch();return this._editcount;},
	get registration(){if(!this._registration)this._fetch();return this._registration;},
	get groups(){if(!this._groups)this._fetch();return this._groups;},
	get implicitgroups(){if(!this._implicitgroups)this._fetch();return this._implicitgroups;},
	get rights(){if(!this._rights)this._fetch();return this._rights;},
	get emailable(){if(this._emailable==undefined)this._fetch();return this._emailable;},
	get name(){return this._name;},
	get page(){return new vada.Page("User:"+this.name);},
	get talkpage(){return new vada.Page("User talk:"+this.name);},
	getContributions:function(){
		//TODO generalise function
		var query={},ret=[];
		query["action"]="query";
		query["list"]="usercontribs";
		query["ucuser"]=this.name;
		query["uclimit"]=10;
		query["ucprop"]="ids|flags|timestamp|title|size|sizediff|comment|parsedcomment|tags";
		var data=vada.api(query);
		for(var i in data.query.usercontribs){
			var revision=data.query.usercontribs[i];
			var rev=new vada.Revision(revision.revid);
			rev.title=revision.title;
			rev.comment=revision.comment;
			rev.minor=(revision.minor!="");
			rev.parentid=revision.parentid;
			rev.parent=new vada.Revision(revision.parentid);
			rev.parsedcomment=revision.parsedcomment;
			rev.size=revision.size;
			rev.sizediff=revision.sizediff;
			rev.tags=revision.tags;
			rev.timestamp=revision.timestamp;
			rev.user=this;
			(new vada.Page(rev.title)).addrevision(rev);
			ret.push(rev);
		}
		return ret;
	},
	set warnlevel(val){
		this._warnlevel=val;
	},
	get warnlevel(){
		if(this._warnlevel==undefined)
			this.getWarns();
		return this._warnlevel || 0;
	},
	set warns(val){
		this._warns=val;
	},
	get warns(){
		if(this._warns==undefined)
			this.getWarns();
		return this._warns || [];
	},
	getWarns:function(){
		try{
			var text=this.talkpage.text;
		}catch(err){
			if(err=="PageDoesNotExist"){
				this.warnlevel=0;
				this.warns=[];
				return;
			}
		}
		var re=new RegExp("==\\s?"+["January","February","March","April","May","June","July","August","September","October","November","December"][(new Date).getMonth()]+" "+(new Date).getUTCFullYear()+"\\s?==");
		var needle=re.exec(text);
		if(needle==null)return 0;
		var sectionstart=text.search(needle[0]);
		var sectionend=text.substr(sectionstart+needle[0].length).search("\n==")+sectionstart+needle[0].length;
		var section=(sectionend!=sectionstart+needle[0].length-1)?
			text.substr(sectionstart,sectionend-sectionstart):
			text.substr(sectionstart);
		this._warnlevel=(function(section){
			var r=/<!-- Template:uw-.+?(\d?)[^\d]*? -->/g;
			var warn=0;
			while(m=r.exec(section)){if(warn<m[1])warn=m[1];}
			return warn;
		})(section);
		this._warns=(function(section){
			var r=/<!-- Template:uw-((?!(cluebot)).+?) -->/g;
			var warns=[];
			while(m=r.exec(section)){warns.push(m[1]);}
			return warns;
		})(section);
	},
	warn:function(warning,summary,rrev,lrev){
		if(this.warnlevel==4||this.reported){
			if(rrev==undefined)return;
			if(this.reported){
				var p=new vada.Page("Wikipedia:Administrator intervention against vandalism");
				var newText=p.text;
				var reportS=newText.search(new RegExp("{{"+(this.isAnonymous()?"IPvandal":"Vandal")+"\\|"+this.name+"}}","i"));
				if(reportS==-1){
					if(typeof console!="undefined")console.log("Can't find vandalism report for User:"+this.name);
					return;
				}
				var report="\n:: Another unconstructive edit on [{{subst:"+"fullurl:"+rrev.title+"|diff="+rrev.revid+((lrev==undefined)?"":("&oldid="+lrev.revid))+"}} "+rrev.title+"]. ~~"+"~~";
				var reportE=newText.substr(reportS).search("\n*")+reportS;
				if(reportE==reportS){
					newText=newText+report;
				}else{
					newText=newText.substr(0,reportE)+report+"\n"+newText.substr(reportE);
				}
				p.text=newText;
				return p.save("Adding to report on [[Special:Contributions/"+this.name+"|"+this.name+"]]");
			}
			var report="* {{"+(this.isAnonymous()?"IPvandal":"Vandal")+"|"+this.name+"}} [[WP:Vada|Automatically]] reporting for unconstructive edits after final warning, including on [{{subst:"+"fullurl:"+rrev.title+"|diff="+rrev.revid+((lrev==undefined)?"":("&oldid="+lrev.revid))+"}} "+rrev.title+"]. ~~"+"~~";
			var p=new vada.Page("Wikipedia:Administrator intervention against vandalism");
			var newText=p.text;
			newText+="\n"+report;
			p.text=newText;
			return p.save("Reporting [[Special:Contributions/"+this.name+"|"+this.name+"]]");
		}
		if(rrev!=undefined){
			try{
				var lastEdit=rrev.user.getContributions()[0];
				if(lastEdit.timestamp<rrev.user.talkpage.getLatestRevision().timestamp){
					if(typeof console!="undefined")console.log("Not warning "+rrev.user.name+" - User has not edited since last tpedit");
					return;
				}
			}catch(e){
				if(e.toString()!="PageDoesNotExist")throw(e);
			}
		}
		warning=warning.replace("{{{warnlevel}}}",parseInt(this.warnlevel)+1);
		summary=summary.replace("{{{warnlevel}}}",parseInt(this.warnlevel)+1);
		var p=new vada.Page("User talk:"+this.name);
		var text="";
		try{
			text=p.text;
		}catch(err){
			if(err!="PageDoesNotExist")throw err;
		}
		var re=new RegExp("==\\s?"+["January","February","March","April","May","June","July","August","September","October","November","December"][(new Date).getMonth()]+" "+(new Date).getUTCFullYear()+"\\s?==");
		var needle=re.exec(text);
		var newtext="";
		if(needle==null){
			newtext=text+"\n\n== "+["January","February","March","April","May","June","July","August","September","October","November","December"][(new Date).getMonth()]+" "+(new Date).getUTCFullYear()+" ==\n"+warning;
		}else{
			var sectionstart=text.search(needle[0]);
			var sectionend=text.substr(sectionstart+needle[0].length).search("\n==")+sectionstart+needle[0].length;
			if(sectionend==sectionstart+needle[0].length-1){
				newtext=text+"\n\n"+warning;
			}else{
				newtext=text.substr(0,sectionend)+"\n"+warning+"\n"+text.substr(sectionend);
			}
		}
		p.text=newtext;
		return p.save(summary);//TODO error handling
	},
	get reported(){
		return this.name in vada.User.reports;
	},
	set reported(val){
		if(val&&!(this.name in vada.User.reports))vada.User.reports[this.name]="";
		if(!val&&(this.name in vada.User.reports))delete(vada.User.reports[this.name]);
	},
	inCache:function(key){
		return this["_"+key]!=undefined;
	},
	isAnonymous:function(){
		return /^(?::(?::|(?::[0-9A-Fa-f]{1,4}){1,7})|[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){0,6}::|[0-9A-Fa-f]{1,4}(?::[0-9A-Fa-f]{1,4}){7})|(((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]))$/.test(this.name);
	},
}
vada.User.reports={};
vada.User.fetchReports=function(){
	var t=new vada.Page("Wikipedia:Administrator intervention against vandalism").text;
	vada.User.reports={};
	var r=/\{\{(?:IPv|V)andal\|(.+?)\}\}/gi;
	while(m=r.exec(t)){vada.User.reports[m[1]]="";}
}
vada._revertWarn=function(reason,template,l,r,link){
	vada.dom.queue.next();
	l.page.text=l.text;
	var rev=l.page.save("Reverted edits by [[Special:Contributions/"+r.user.name+"|"+r.user.name+"]]  ([[User talk:"+r.user.name+"|talk]]): "+reason,true);
	if(rev.revid)r.user.warn("{{subst:"+template+"{{{warnlevel}}}|"+l.page.title+((link==true)?("|{{subst:"+"fullurl:"+l.page.title+"|diff="+r.revid+"&oldid="+l.revid+"}}"):"")+"}}"+((link!=true)?(" ~~"+"~~"):""),"Level {{{warnlevel}}} warning: "+reason+" on [["+l.page.title+"]]",r,l);
}
vada.heartbeat={};
vada.heartbeat.ping=function(params){
	vada.dom.call("heartbeat.pong",{});
}

vada.events.addListener("load",function(){
	vada.dom.menu.push(vada.dom.menu.buttons.vada);
	vada.dom.menu.redraw();
	vada.User.fetchReports();
});

vada.events.addListener("rc.newedit",function(evt){
	var rc=evt.rc;
	var genwarn=/warning|general note|caution/i;
	if(genwarn.test(rc.comment)){
		if(rc.page.namespace==3){
			new vada.User(rc.title.substr(10)).getWarns();
		}
	}
	if(rc.title=="Wikipedia:Administrator intervention against vandalism"){
		vada.User.fetchReports();
	}
	if(vada.dom._history.page instanceof vada.Page && rc.title==vada.dom._history.page.title){
		vada.dom._history(vada.dom._history.page);
	}
	if(vada.dom._contributions.user instanceof vada.User && rc.user.name==vada.dom._contributions.user.name){
		vada.dom._contributions(vada.dom._contributions.user);
	}
});
//</nowiki>