<?xml version="1.0"?>
<?xml-stylesheet type="text/css" href="http://72.14.177.54/skins/common/feed.css?207"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/">
	<channel>
		<title>EditThis.info - User contributions [en]</title>
		<link>http://72.14.177.54/wiki/Special:Contributions/Canderous</link>
		<description>From EditThis.info</description>
		<language>en</language>
		<generator>MediaWiki 1.15.1</generator>
		<lastBuildDate>Tue, 20 Oct 2026 08:35:02 GMT</lastBuildDate>
		<item>
			<title>User:Canderous/Tool2/code.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/Tool2/code.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 22:50:02 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/Tool2/code.js</comments>		</item>
		<item>
			<title>User:Canderous/Tool2/code.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/Tool2/code.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;// see http://paperlined.org/apps/wikipedia/Tool2/ for instructions on adding this to your monobook.js&lt;br /&gt;
&lt;br /&gt;
// To run this tool on other servers:&lt;br /&gt;
//	1. copy this script to the target server (this is required because of javascript cross-site security restrictions)&lt;br /&gt;
&lt;br /&gt;
//	2. update the following URL&lt;br /&gt;
//		for example: &amp;quot;User:Interiot/Tool2/code.js&amp;quot;&lt;br /&gt;
var tool2_url = &amp;quot;User:Canderous/Tool2/code.js&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//	3. update this namespace list, extracted from something like http://en.wikiquote.org/wiki/Special:Export//&lt;br /&gt;
//			These *should not* have colons after them.&lt;br /&gt;
var namespaces = [&lt;br /&gt;
&amp;quot;Talk&amp;quot;,&lt;br /&gt;
&amp;quot;User&amp;quot;,&lt;br /&gt;
&amp;quot;User talk&amp;quot;,&lt;br /&gt;
&amp;quot;Editthis&amp;quot;,&lt;br /&gt;
&amp;quot;Editthis talk&amp;quot;,&lt;br /&gt;
&amp;quot;Image&amp;quot;,&lt;br /&gt;
&amp;quot;Image talk&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki talk&amp;quot;,&lt;br /&gt;
&amp;quot;Template&amp;quot;,&lt;br /&gt;
&amp;quot;Template talk&amp;quot;,&lt;br /&gt;
&amp;quot;Help&amp;quot;,&lt;br /&gt;
&amp;quot;Help talk&amp;quot;,&lt;br /&gt;
&amp;quot;Category&amp;quot;,&lt;br /&gt;
&amp;quot;Category talk&amp;quot;,&lt;br /&gt;
		// 3b. these two project project entries are not added by Special:Export, and might or might not need to be updated&lt;br /&gt;
&amp;quot;Wikipedia&amp;quot;,&lt;br /&gt;
&amp;quot;Wikipedia talk&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
namespaces[100] = &amp;quot;Portal&amp;quot;;&lt;br /&gt;
namespaces[101] = &amp;quot;Portal talk&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//	4. update this date-parser to match the format and language of your specific wiki.  Feel free to contact Interiot regarding this, if you can't find another&lt;br /&gt;
//		copy of this script that uses the same language.&lt;br /&gt;
// input: a text string from Special:Contributions.    output: a javascript Date object&lt;br /&gt;
// documentation:  http://www.quirksmode.org/js/introdate.html#parse, http://www.elated.com/tutorials/programming/javascript/dates/&lt;br /&gt;
function date_parse(text) {&lt;br /&gt;
	var matches = text.match(/^([0-9:]+), +([0-9]+) +([a-z]+) +([0-9]+)$/i);&lt;br /&gt;
	if (!matches) {&lt;br /&gt;
		//dump_text(&amp;quot;XXX&amp;quot;);			// for debugging&lt;br /&gt;
		return matches;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	parseme = matches[3] + &amp;quot;, &amp;quot; + matches[2] + &amp;quot; &amp;quot;  + matches[4] + &amp;quot; &amp;quot; + matches[1] + &amp;quot;:00&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	//dump_text(parseme);				// for debugging&lt;br /&gt;
&lt;br /&gt;
	var dt = new Date();&lt;br /&gt;
	dt.setTime( Date.parse(parseme));&lt;br /&gt;
&lt;br /&gt;
	//dump_text(dt.toLocaleString());		// for debugging&lt;br /&gt;
&lt;br /&gt;
	return dt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ end of server-specific configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
//	- the current document.location method doesn't work when the page is accessed sans-mod_rewrite&lt;br /&gt;
//	- test with non-ASCII characters&lt;br /&gt;
//		- non-ascii usernames&lt;br /&gt;
//		- ??&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var prefix = &amp;quot;&amp;quot;;&lt;br /&gt;
var params = parse_params();&lt;br /&gt;
&lt;br /&gt;
addOnloadFunction(function() {&lt;br /&gt;
  var path_len = document.location.pathname.length;&lt;br /&gt;
  // trigger once we view the right page&lt;br /&gt;
  if (document.location.pathname.substring(path_len - tool2_url.length, path_len) == tool2_url) {&lt;br /&gt;
    // get the prefix (needs to be fixed to work sans-mod_rewrite&lt;br /&gt;
    prefix = document.location.protocol + &amp;quot;//&amp;quot; + document.location.host + &amp;quot;/&amp;quot;&lt;br /&gt;
            + document.location.pathname.substring(1, path_len - tool2_url.length);&lt;br /&gt;
&lt;br /&gt;
    // blank the inner contents of the page&lt;br /&gt;
    var bodyContent = document.getElementById(&amp;quot;bodyContent&amp;quot;);&lt;br /&gt;
    while (bodyContent.childNodes.length &amp;gt; 0) bodyContent.removeChild(bodyContent.lastChild);&lt;br /&gt;
&lt;br /&gt;
    if (document.location.search.length == 0) {&lt;br /&gt;
      generate_input_form(bodyContent);&lt;br /&gt;
    } else {&lt;br /&gt;
      generate_main_report(bodyContent);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function generate_input_form(bodyContent) {&lt;br /&gt;
  if (navigator.userAgent.toLowerCase().indexOf('msie')+1)&lt;br /&gt;
  {&lt;br /&gt;
  bodyContent.innerHTML = &amp;quot;This counter does not currently work in Internet Explorer.  Please &amp;lt;a href='http://www.getfirefox.com'&amp;gt;get Firefox&amp;lt;/a&amp;gt; or use &amp;lt;a href='http://en.wikipedia.org/wiki/Wikipedia:WikiProject_edit_counters/Flcelloguy%27s_Tool'&amp;gt;Flcelloguy's Tool&amp;lt;/a&amp;gt; instead.&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
  bodyContent.innerHTML =&lt;br /&gt;
            &amp;quot;&amp;lt;form&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Username &amp;lt;td&amp;gt;&amp;lt;input maxlength=128 name=username value='' id=username title='username'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;             &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;         &amp;lt;td&amp;gt;&amp;lt;input type=submit value='Submit'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;&amp;lt;/table&amp;gt;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  var form = bodyContent.getElementsByTagName(&amp;quot;form&amp;quot;)[0];&lt;br /&gt;
  form.method = &amp;quot;get&amp;quot;;&lt;br /&gt;
  form.action = document.location;&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&amp;quot;username&amp;quot;).focus();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function generate_main_report() {&lt;br /&gt;
  fetch_data(params[&amp;quot;username&amp;quot;].replace(/\\+/g, &amp;quot; &amp;quot;),&lt;br /&gt;
		&amp;quot;&amp;quot;, output_main_report, 0, []);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function add_stats_row(left_col, right_col) {&lt;br /&gt;
		var row = document.createElement(&amp;quot;tr&amp;quot;);&lt;br /&gt;
		var left = document.createElement(&amp;quot;td&amp;quot;);&lt;br /&gt;
		var right = document.createElement(&amp;quot;td&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
		document.getElementById(&amp;quot;basic_stats&amp;quot;).appendChild(row);&lt;br /&gt;
		row.appendChild(left);&lt;br /&gt;
		row.appendChild(right);&lt;br /&gt;
		//left.innerHTML = left_col;&lt;br /&gt;
		left.appendChild( document.createTextNode(left_col) );&lt;br /&gt;
		right.appendChild( document.createTextNode(right_col) );&lt;br /&gt;
		return row;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
function output_main_report(history) {&lt;br /&gt;
	// -- generate summary statistics&lt;br /&gt;
	var unique_articles = new Array();&lt;br /&gt;
	var namespace_numedits = new Array();&lt;br /&gt;
	for (var i=0; i&amp;lt;namespaces.length; i++) {&lt;br /&gt;
		namespace_numedits[ namespaces[i] ] = 0;&lt;br /&gt;
	}&lt;br /&gt;
	namespace_numedits[&amp;quot;&amp;quot;] = 0;&lt;br /&gt;
	for (var i=0; i&amp;lt;history.length; i++) {&lt;br /&gt;
		var h = history[i];&lt;br /&gt;
		unique_articles[  h[&amp;quot;title&amp;quot;] ]++;&lt;br /&gt;
		namespace_numedits[  h[&amp;quot;namespace&amp;quot;] ]++;&lt;br /&gt;
	}&lt;br /&gt;
	var unique_articles_keys = keys(unique_articles);&lt;br /&gt;
&lt;br /&gt;
	// -- output report&lt;br /&gt;
	var table = document.createElement(&amp;quot;table&amp;quot;);&lt;br /&gt;
	table.id = &amp;quot;basic_stats&amp;quot;;&lt;br /&gt;
	document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(table);&lt;br /&gt;
&lt;br /&gt;
	add_stats_row(&amp;quot;Username&amp;quot;, params[&amp;quot;username&amp;quot;].replace(/\\+/g, &amp;quot; &amp;quot;));&lt;br /&gt;
	add_stats_row(&amp;quot;Total edits&amp;quot;, history.length);&lt;br /&gt;
	add_stats_row(&amp;quot;Distinct pages edited&amp;quot;, unique_articles_keys.length);&lt;br /&gt;
	add_stats_row(&amp;quot;Average edits/page&amp;quot;, new Number(history.length / unique_articles_keys.length).toFixed(3));&lt;br /&gt;
	add_stats_row(&amp;quot;First edit&amp;quot;, history[ history.length-1 ][&amp;quot;date_text&amp;quot;] );&lt;br /&gt;
&lt;br /&gt;
	// add a blank row&lt;br /&gt;
	add_stats_row(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;).childNodes[0].style.height = &amp;quot;1em&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	add_stats_row(&amp;quot;(main)&amp;quot;, namespace_numedits[&amp;quot;&amp;quot;]);&lt;br /&gt;
	for (var i=0; i&amp;lt;namespaces.length; i++) {&lt;br /&gt;
		var nmspc = namespaces[i];&lt;br /&gt;
		if (namespace_numedits[nmspc]) {&lt;br /&gt;
			add_stats_row(nmspc, namespace_numedits[nmspc]);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== HTML-scraping backend =========================================&lt;br /&gt;
&lt;br /&gt;
function add_loading_notice() {&lt;br /&gt;
	if (document.getElementById(&amp;quot;loading_notice&amp;quot;))&lt;br /&gt;
		return;&lt;br /&gt;
	var loading = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
	loading.id = &amp;quot;loading_notice&amp;quot;;&lt;br /&gt;
	loading.innerHTML = &amp;quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Retrieving data&amp;lt;blink&amp;gt;...&amp;lt;/blink&amp;gt;&amp;quot;;&lt;br /&gt;
	document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(loading);&lt;br /&gt;
}&lt;br /&gt;
function remove_loading_notice() {&lt;br /&gt;
	var loading = document.getElementById(&amp;quot;loading_notice&amp;quot;);&lt;br /&gt;
	if (!loading) return;&lt;br /&gt;
	loading.parentNode.removeChild(loading);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var offset_regexp = /href=&amp;quot;[^&amp;quot;]+:Contributions[^&amp;quot;]+offset=(\\d+)/gi;&lt;br /&gt;
function fetch_data(username, end_date, handler, offset, page_list) {&lt;br /&gt;
	add_loading_notice();&lt;br /&gt;
	var url = prefix + &amp;quot;Special:Contributions/&amp;quot; + username + &amp;quot;?offset=&amp;quot; + offset + &amp;quot;&amp;amp;limit=5000&amp;quot;;&lt;br /&gt;
	loadXMLDoc(url, &lt;br /&gt;
		function (request) {&lt;br /&gt;
			var next_offset = 0;&lt;br /&gt;
			if (request.readyState != 4)   return;&lt;br /&gt;
			if (request.status == 200) {&lt;br /&gt;
				page_list.push(request.responseText);&lt;br /&gt;
				//dump_text(request.responseText);&lt;br /&gt;
&lt;br /&gt;
				// see if there's another pageful to get&lt;br /&gt;
				var matches = map( function(p){&lt;br /&gt;
						return p.match( /(\\d+)$/ )[0];&lt;br /&gt;
					}, request.responseText.match( offset_regexp ) );&lt;br /&gt;
				for (var i=0; i&amp;lt;matches.length; i++) {&lt;br /&gt;
					var v = matches[i] * 1;&lt;br /&gt;
					if (v != 0 &amp;amp;&amp;amp; (offset == 0 || v &amp;lt; offset)) {&lt;br /&gt;
						next_offset = v;&lt;br /&gt;
						break;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//next_offset = 0;			// for testing only, retrieve just the first page of results&lt;br /&gt;
&lt;br /&gt;
			if (next_offset == 0) {&lt;br /&gt;
				parse_data(page_list, handler);&lt;br /&gt;
			} else {&lt;br /&gt;
				// tail recurse&lt;br /&gt;
				fetch_data(username, end_date, handler, next_offset, page_list);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// input: a list of strings, each string containing the HTML from a single page&lt;br /&gt;
// output: a list, where each individual entry is a specific edit from history&lt;br /&gt;
function parse_data(page_list, handler) {&lt;br /&gt;
	//var total_len = 0;&lt;br /&gt;
	//for (var i=0; i&amp;lt;page_list.length; i++) total_len += page_list[i].length;&lt;br /&gt;
	//alert(&amp;quot;parsing &amp;quot; + page_list.length + &amp;quot; pages comprising &amp;quot; + total_len + &amp;quot; total bytes&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	var last_history_ent = [];&lt;br /&gt;
	last_history_ent[&amp;quot;title&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
	last_history_ent[&amp;quot;oldid&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	var edit_history = new Array();&lt;br /&gt;
	for (var pagecnt=0; pagecnt&amp;lt;page_list.length; pagecnt++) {&lt;br /&gt;
		var matches = page_list[pagecnt].match( /^&amp;lt;li&amp;gt;[^(]+\\(&amp;lt;a href=&amp;quot;[^&amp;quot;]+action=history.*/gim );&lt;br /&gt;
		//dump_lines(matches);&lt;br /&gt;
		for (var matchcnt=0; matchcnt&amp;lt;matches.length; matchcnt++) {&lt;br /&gt;
			var history_text = matches[matchcnt];&lt;br /&gt;
&lt;br /&gt;
			var history_entry = new Array();&lt;br /&gt;
			history_entry[&amp;quot;date_text&amp;quot;] = history_text.match( /^&amp;lt;li&amp;gt;([^(&amp;lt;]+)/i )[1]&lt;br /&gt;
					.replace( / +$/, &amp;quot;&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;date&amp;quot;] = date_parse( history_entry[&amp;quot;date_text&amp;quot;] );&lt;br /&gt;
			history_entry[&amp;quot;title&amp;quot;] = history_text.match( /title=&amp;quot;([^&amp;quot;]+)&amp;quot;/i )[1]&lt;br /&gt;
					.replace( /&amp;amp;quot;/g, &amp;quot;\\&amp;quot;&amp;quot;)&lt;br /&gt;
					.replace( /&amp;amp;amp;/g, &amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
			var find_comment = history_text.replace(/&amp;lt;span class=&amp;quot;autocomment&amp;quot;&amp;gt;.*?&amp;lt;\\/span&amp;gt; ?/, &amp;quot;&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;comment&amp;quot;] = ifmatch(find_comment.match( /&amp;lt;span class='comment'&amp;gt;(.*?)&amp;lt;\\/span&amp;gt;/ ))&lt;br /&gt;
					.replace(/^\\((.*)\\)$/, &amp;quot;$1&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;minor&amp;quot;] = /&amp;lt;span class=&amp;quot;minor&amp;quot;/.test(history_text);&lt;br /&gt;
			history_entry[&amp;quot;oldid&amp;quot;] = ifmatch(history_text.match(/oldid=([0-9]+)/i));&lt;br /&gt;
&lt;br /&gt;
			history_entry[&amp;quot;namespace&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
			for (var nmspc_ctr=0; nmspc_ctr&amp;lt;namespaces.length; nmspc_ctr++) {&lt;br /&gt;
				var nmspc = namespaces[nmspc_ctr] + &amp;quot;:&amp;quot;;&lt;br /&gt;
				if (history_entry[&amp;quot;title&amp;quot;].substring(0, nmspc.length) == nmspc) {&lt;br /&gt;
					history_entry[&amp;quot;namespace&amp;quot;] = namespaces[nmspc_ctr];&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//dump_object(history_entry);&lt;br /&gt;
&lt;br /&gt;
			if (history_entry[&amp;quot;title&amp;quot;] != last_history_ent[&amp;quot;title&amp;quot;] || history_entry[&amp;quot;oldid&amp;quot;] != last_history_ent[&amp;quot;oldid&amp;quot;])&lt;br /&gt;
				edit_history.push(history_entry);&lt;br /&gt;
			last_history_ent = history_entry;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	remove_loading_notice();&lt;br /&gt;
&lt;br /&gt;
	handler(edit_history);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== test/debug functions =========================================&lt;br /&gt;
&lt;br /&gt;
function dump_text(text) {&lt;br /&gt;
  //alert(&amp;quot;dump_text, with text of size &amp;quot; + text.length);&lt;br /&gt;
&lt;br /&gt;
  var pre = document.createElement(&amp;quot;pre&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  var div = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
  div.style.width = &amp;quot;60em&amp;quot;;&lt;br /&gt;
  div.style.maxHeight = &amp;quot;40em&amp;quot;;&lt;br /&gt;
  div.style.overflow = &amp;quot;auto&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  pre.appendChild(document.createTextNode(text));&lt;br /&gt;
  div.appendChild(pre);&lt;br /&gt;
  document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(div);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function dump_lines(ary) {&lt;br /&gt;
  dump_text(&amp;quot;--&amp;gt; &amp;quot; + ary.join(&amp;quot;\&lt;br /&gt;
--&amp;gt; &amp;quot;));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function dump_object(obj) {&lt;br /&gt;
	var toString = &amp;quot;&amp;quot;;&lt;br /&gt;
	for (var prop in obj) {&lt;br /&gt;
		toString += prop + &amp;quot;: &amp;quot; + obj[prop] + &amp;quot;\&lt;br /&gt;
&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
	dump_text(toString);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== utility functions =========================================&lt;br /&gt;
&lt;br /&gt;
function addOnloadFunction(f) {&lt;br /&gt;
  if (window.addEventListener) window.addEventListener(&amp;quot;load&amp;quot;,f,false);&lt;br /&gt;
  else if (window.attachEvent) window.attachEvent(&amp;quot;onload&amp;quot;,f);&lt;br /&gt;
  else {&lt;br /&gt;
    var oldOnload='_old_onload_'+addOnloadFunction.uid;&lt;br /&gt;
    addOnloadFunction[oldOnload] = window.onload ? window.onload : function () {};&lt;br /&gt;
    window.onload = function() { addOnloadFunction[oldOnload]();  f(); }&lt;br /&gt;
    ++addOnloadFunction.uid;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function parse_params() {&lt;br /&gt;
  var pairs = document.location.search.substring(1).split(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
  var ret = [];&lt;br /&gt;
  for (var i=0; i &amp;lt; pairs.length; i++) {&lt;br /&gt;
    var values = pairs[i].split(&amp;quot;=&amp;quot;);&lt;br /&gt;
    ret[values[0]] = unescape(values[1]);&lt;br /&gt;
  }&lt;br /&gt;
  return ret; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function loadXMLDoc(url, handler)&lt;br /&gt;
{&lt;br /&gt;
    // branch for native XMLHttpRequest object&lt;br /&gt;
    if (window.XMLHttpRequest) {&lt;br /&gt;
        req = new XMLHttpRequest();&lt;br /&gt;
	req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
        req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
        req.send(null);&lt;br /&gt;
    // branch for IE/Windows ActiveX version&lt;br /&gt;
    } else if (window.ActiveXObject) {&lt;br /&gt;
        req = new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);&lt;br /&gt;
        if (req) {&lt;br /&gt;
            req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
            req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
            req.send();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#map&lt;br /&gt;
function map (handler, list) {&lt;br /&gt;
  var ret = new Array();&lt;br /&gt;
  for (var i=0; i&amp;lt;list.length; i++) {&lt;br /&gt;
    ret[i] = handler( list[i] );&lt;br /&gt;
    // ret.push( handler( list[i] ) );&lt;br /&gt;
  }&lt;br /&gt;
  return ret;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#keys&lt;br /&gt;
function keys (obj) {&lt;br /&gt;
	var ret = new Array();&lt;br /&gt;
	for (var key in obj) {&lt;br /&gt;
		ret.push(key);&lt;br /&gt;
	}&lt;br /&gt;
	return ret;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function ifmatch(ary) {&lt;br /&gt;
	if (ary &amp;amp;&amp;amp; ary.length &amp;gt;= 2) {&lt;br /&gt;
		return ary[1];&lt;br /&gt;
	} else {&lt;br /&gt;
		return &amp;quot;&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 21:01:03 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/Tool2/code.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;//Interiot's javascript edit counter&lt;br /&gt;
if (document.title.indexOf('User:Canderous/editcount.js') != -1) {&lt;br /&gt;
  document.write('&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;' &lt;br /&gt;
    + 'http://www.editthis.info/wiki/User:Canderous/editcount.js' &lt;br /&gt;
    + '&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;amp;dontcountme=s&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;'); }&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:23:53 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;//Interiot's javascript edit counter&lt;br /&gt;
if (document.title.indexOf('User:Canderous/editcount.js') != -1) {&lt;br /&gt;
  document.write('&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;' &lt;br /&gt;
    + 'http://www.editthis.info/wiki/User:Canderous/editcount.js'&lt;br /&gt;
    + '&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;amp;dontcountme=s&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;'); }&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:19:51 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;//Interiot's javascript edit counter&lt;br /&gt;
if (document.title.indexOf('User:Interiot/Tool2/code.js') != -1) {&lt;br /&gt;
  document.write('&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;' &lt;br /&gt;
    + 'http://www.editthis.info/wiki/User:Canderous/editcount.js'&lt;br /&gt;
    + '&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;amp;dontcountme=s&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;'); }&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:17:59 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;//Interiot's javascript edit counter&lt;br /&gt;
if (document.title.indexOf('User:Interiot/Tool2/code.js') != -1) {&lt;br /&gt;
  document.write('&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;' &lt;br /&gt;
    + 'http://en.wikipedia.org/w/index.php?title=User:Interiot/Tool2/code.js' &lt;br /&gt;
    + '&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;amp;dontcountme=s&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;'); }&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:17:24 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;//Interiot's javascript edit counter if (document.title.indexOf('User:Canderous/editcount.js') != -1) {&lt;br /&gt;
&lt;br /&gt;
 document.write('&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;' &lt;br /&gt;
   + 'http://www.editthis.info/wiki/User:Canderous/editcount.js' &lt;br /&gt;
   + '&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;amp;dontcountme=s&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;'); }&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:16:39 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>User:Canderous/editcount.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/editcount.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;// see http://paperlined.org/apps/wikipedia/Tool2/ for instructions on adding this to your monobook.js&lt;br /&gt;
&lt;br /&gt;
// To run this tool on other servers:&lt;br /&gt;
//  1. copy this script to the target server (this is required because of javascript cross-site security restrictions)&lt;br /&gt;
&lt;br /&gt;
//  2. update the following URL&lt;br /&gt;
//      for example: &amp;quot;User:Interiot/Tool2/code.js&amp;quot;&lt;br /&gt;
var tool2_url = &amp;quot;User:Canderous/editcount.js&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//  3. update this namespace list, extracted from something like http://en.wikiquote.org/wiki/Special:Export//&lt;br /&gt;
var namespaces = [&lt;br /&gt;
&amp;quot;Talk&amp;quot;,&lt;br /&gt;
&amp;quot;User&amp;quot;,&lt;br /&gt;
&amp;quot;User talk&amp;quot;,&lt;br /&gt;
&amp;quot;Editthis&amp;quot;,&lt;br /&gt;
&amp;quot;Editthis talk&amp;quot;,&lt;br /&gt;
&amp;quot;Image&amp;quot;,&lt;br /&gt;
&amp;quot;Image talk&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki talk&amp;quot;,&lt;br /&gt;
&amp;quot;Template&amp;quot;,&lt;br /&gt;
&amp;quot;Template talk&amp;quot;,&lt;br /&gt;
&amp;quot;Help&amp;quot;,&lt;br /&gt;
&amp;quot;Help talk&amp;quot;,&lt;br /&gt;
&amp;quot;Category&amp;quot;,&lt;br /&gt;
&amp;quot;Category talk&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
//  - the current document.location method doesn't work when the page is accessed sans-mod_rewrite&lt;br /&gt;
//  - test with non-ASCII characters&lt;br /&gt;
//      - non-ascii usernames&lt;br /&gt;
//      - ??&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var prefix = &amp;quot;&amp;quot;;&lt;br /&gt;
var params = parse_params();&lt;br /&gt;
&lt;br /&gt;
addOnloadFunction(function() {&lt;br /&gt;
  var path_len = document.location.pathname.length;&lt;br /&gt;
  // trigger once we view the right page&lt;br /&gt;
  if (document.location.pathname.substring(path_len - tool2_url.length, path_len) == tool2_url) {&lt;br /&gt;
    // get the prefix (needs to be fixed to work sans-mod_rewrite&lt;br /&gt;
    prefix = document.location.protocol + &amp;quot;//&amp;quot; + document.location.host + &amp;quot;/&amp;quot;&lt;br /&gt;
            + document.location.pathname.substring(1, path_len - tool2_url.length);&lt;br /&gt;
&lt;br /&gt;
    // blank the inner contents of the page&lt;br /&gt;
    var bodyContent = document.getElementById(&amp;quot;bodyContent&amp;quot;);&lt;br /&gt;
    while (bodyContent.childNodes.length &amp;gt; 0) bodyContent.removeChild(bodyContent.lastChild);&lt;br /&gt;
&lt;br /&gt;
    if (document.location.search.length == 0) {&lt;br /&gt;
      generate_input_form(bodyContent);&lt;br /&gt;
    } else {&lt;br /&gt;
      generate_main_report(bodyContent);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function generate_input_form(bodyContent) {&lt;br /&gt;
  bodyContent.innerHTML =&lt;br /&gt;
            &amp;quot;&amp;lt;form&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Username &amp;lt;td&amp;gt;&amp;lt;input maxlength=128 name=username value='' title='username'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;             &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;         &amp;lt;td&amp;gt;&amp;lt;input type=submit value='Submit'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;&amp;lt;/table&amp;gt;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  var form = bodyContent.getElementsByTagName(&amp;quot;form&amp;quot;)[0];&lt;br /&gt;
  form.method = &amp;quot;get&amp;quot;;&lt;br /&gt;
  form.action = document.location;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function generate_main_report() {&lt;br /&gt;
  fetch_data(params[&amp;quot;username&amp;quot;], &amp;quot;&amp;quot;, output_main_report, 0, []);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function output_main_report(data) {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var offset_regexp = /href=&amp;quot;[^&amp;quot;]+:Contributions[^&amp;quot;]+offset=(\\d+)/gi;&lt;br /&gt;
function fetch_data(username, end_date, handler, offset, page_list) {&lt;br /&gt;
    var url = prefix + &amp;quot;Special:Contributions/&amp;quot; + username + &amp;quot;?offset=&amp;quot; + offset + &amp;quot;&amp;amp;limit=500&amp;quot;;&lt;br /&gt;
    loadXMLDoc(url, &lt;br /&gt;
        function (request) {&lt;br /&gt;
            var next_offset = 0;&lt;br /&gt;
            if (request.readyState != 4)   return;&lt;br /&gt;
            if (request.status == 200) {&lt;br /&gt;
                page_list.push(request.responseText);&lt;br /&gt;
                //dump_text(request.responseText);&lt;br /&gt;
&lt;br /&gt;
                // see if there's another pageful to get&lt;br /&gt;
                var matches = map( function(p){&lt;br /&gt;
                        return p.match( /(\\d+)$/ )[0];&lt;br /&gt;
                    }, request.responseText.match( offset_regexp ) );&lt;br /&gt;
                for (var i=0; i&amp;lt;matches.length; i++) {&lt;br /&gt;
                    var v = matches[i] * 1;&lt;br /&gt;
                    if (v != 0 &amp;amp;&amp;amp; (offset == 0 || v &amp;lt; offset)) {&lt;br /&gt;
                        next_offset = v;&lt;br /&gt;
                        break;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (next_offset == 0) {&lt;br /&gt;
                parse_data(page_list, handler);&lt;br /&gt;
            } else {&lt;br /&gt;
                // tail recurse&lt;br /&gt;
                fetch_data(username, end_date, handler, next_offset, page_list);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function parse_data(page_list, handler) {&lt;br /&gt;
    //var total_len = 0;&lt;br /&gt;
    //for (var i=0; i&amp;lt;page_list.length; i++) total_len += page_list[i].length;&lt;br /&gt;
    //alert(&amp;quot;parsing &amp;quot; + page_list.length + &amp;quot; pages comprising &amp;quot; + total_len + &amp;quot; total bytes&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== test/debug functions =========================================&lt;br /&gt;
&lt;br /&gt;
function dump_text(text) {&lt;br /&gt;
  //alert(&amp;quot;dump_text, with text of size &amp;quot; + text.length);&lt;br /&gt;
&lt;br /&gt;
  var pre = document.createElement(&amp;quot;pre&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  var div = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
  div.style.width = &amp;quot;60em&amp;quot;;&lt;br /&gt;
  div.style.maxHeight = &amp;quot;40em&amp;quot;;&lt;br /&gt;
  div.style.overflow = &amp;quot;auto&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  pre.appendChild(document.createTextNode(text));&lt;br /&gt;
  div.appendChild(pre);&lt;br /&gt;
  document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(div);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function dump_lines(ary) {&lt;br /&gt;
  dump_text(ary.join(&amp;quot;\&lt;br /&gt;
&amp;quot;));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== utility functions =========================================&lt;br /&gt;
&lt;br /&gt;
function addOnloadFunction(f) {&lt;br /&gt;
  if (window.addEventListener) window.addEventListener(&amp;quot;load&amp;quot;,f,false);&lt;br /&gt;
  else if (window.attachEvent) window.attachEvent(&amp;quot;onload&amp;quot;,f);&lt;br /&gt;
  else {&lt;br /&gt;
    var oldOnload='_old_onload_'+addOnloadFunction.uid;&lt;br /&gt;
    addOnloadFunction[oldOnload] = window.onload ? window.onload : function () {};&lt;br /&gt;
    window.onload = function() { addOnloadFunction[oldOnload]();  f(); }&lt;br /&gt;
    ++addOnloadFunction.uid;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function parse_params() {&lt;br /&gt;
  var pairs = document.location.search.substring(1).split(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
  var ret = [];&lt;br /&gt;
  for (var i=0; i &amp;lt; pairs.length; i++) {&lt;br /&gt;
    var values = pairs[i].split(&amp;quot;=&amp;quot;);&lt;br /&gt;
    ret[values[0]] = unescape(values[1]);&lt;br /&gt;
  }&lt;br /&gt;
  return ret; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function loadXMLDoc(url, handler)&lt;br /&gt;
{&lt;br /&gt;
    // branch for native XMLHttpRequest object&lt;br /&gt;
    if (window.XMLHttpRequest) {&lt;br /&gt;
        req = new XMLHttpRequest();&lt;br /&gt;
    req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
        req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
        req.send(null);&lt;br /&gt;
    // branch for IE/Windows ActiveX version&lt;br /&gt;
    } else if (window.ActiveXObject) {&lt;br /&gt;
        req = new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);&lt;br /&gt;
        if (req) {&lt;br /&gt;
            req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
            req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
            req.send();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#map&lt;br /&gt;
function map (handler, list) {&lt;br /&gt;
  var ret = new Array();&lt;br /&gt;
  for (var i=0; i&amp;lt;list.length; i++) {&lt;br /&gt;
    ret[i] = handler( list[i] );&lt;br /&gt;
    // ret.push( handler( list[i] ) );&lt;br /&gt;
  }&lt;br /&gt;
  return ret;&lt;br /&gt;
}&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:11:41 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/editcount.js</comments>		</item>
		<item>
			<title>User:Canderous/editcount.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/editcount.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;// see http://paperlined.org/apps/wikipedia/Tool2/ for instructions on adding this to your monobook.js&lt;br /&gt;
&lt;br /&gt;
// To run this tool on other servers:&lt;br /&gt;
//  1. copy this script to the target server (this is required because of javascript cross-site security restrictions)&lt;br /&gt;
&lt;br /&gt;
//  2. update the following URL&lt;br /&gt;
//      for example: &amp;quot;User:Interiot/Tool2/code.js&amp;quot;&lt;br /&gt;
var tool2_url = &amp;quot;User:Interiot/Tool2/code.js&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//  3. update this namespace list, extracted from something like http://en.wikiquote.org/wiki/Special:Export//&lt;br /&gt;
var namespaces = [&lt;br /&gt;
&amp;quot;Talk&amp;quot;,&lt;br /&gt;
&amp;quot;User&amp;quot;,&lt;br /&gt;
&amp;quot;User talk&amp;quot;,&lt;br /&gt;
&amp;quot;Wikiquote&amp;quot;,&lt;br /&gt;
&amp;quot;Wikiquote talk&amp;quot;,&lt;br /&gt;
&amp;quot;Image&amp;quot;,&lt;br /&gt;
&amp;quot;Image talk&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki talk&amp;quot;,&lt;br /&gt;
&amp;quot;Template&amp;quot;,&lt;br /&gt;
&amp;quot;Template talk&amp;quot;,&lt;br /&gt;
&amp;quot;Help&amp;quot;,&lt;br /&gt;
&amp;quot;Help talk&amp;quot;,&lt;br /&gt;
&amp;quot;Category&amp;quot;,&lt;br /&gt;
&amp;quot;Category talk&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
//  - the current document.location method doesn't work when the page is accessed sans-mod_rewrite&lt;br /&gt;
//  - test with non-ASCII characters&lt;br /&gt;
//      - non-ascii usernames&lt;br /&gt;
//      - ??&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var prefix = &amp;quot;&amp;quot;;&lt;br /&gt;
var params = parse_params();&lt;br /&gt;
&lt;br /&gt;
addOnloadFunction(function() {&lt;br /&gt;
  var path_len = document.location.pathname.length;&lt;br /&gt;
  // trigger once we view the right page&lt;br /&gt;
  if (document.location.pathname.substring(path_len - tool2_url.length, path_len) == tool2_url) {&lt;br /&gt;
    // get the prefix (needs to be fixed to work sans-mod_rewrite&lt;br /&gt;
    prefix = document.location.protocol + &amp;quot;//&amp;quot; + document.location.host + &amp;quot;/&amp;quot;&lt;br /&gt;
            + document.location.pathname.substring(1, path_len - tool2_url.length);&lt;br /&gt;
&lt;br /&gt;
    // blank the inner contents of the page&lt;br /&gt;
    var bodyContent = document.getElementById(&amp;quot;bodyContent&amp;quot;);&lt;br /&gt;
    while (bodyContent.childNodes.length &amp;gt; 0) bodyContent.removeChild(bodyContent.lastChild);&lt;br /&gt;
&lt;br /&gt;
    if (document.location.search.length == 0) {&lt;br /&gt;
      generate_input_form(bodyContent);&lt;br /&gt;
    } else {&lt;br /&gt;
      generate_main_report(bodyContent);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function generate_input_form(bodyContent) {&lt;br /&gt;
  bodyContent.innerHTML =&lt;br /&gt;
            &amp;quot;&amp;lt;form&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Username &amp;lt;td&amp;gt;&amp;lt;input maxlength=128 name=username value='' title='username'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;             &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;         &amp;lt;td&amp;gt;&amp;lt;input type=submit value='Submit'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;&amp;lt;/table&amp;gt;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  var form = bodyContent.getElementsByTagName(&amp;quot;form&amp;quot;)[0];&lt;br /&gt;
  form.method = &amp;quot;get&amp;quot;;&lt;br /&gt;
  form.action = document.location;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function generate_main_report() {&lt;br /&gt;
  fetch_data(params[&amp;quot;username&amp;quot;], &amp;quot;&amp;quot;, output_main_report, 0, []);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function output_main_report(data) {&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var offset_regexp = /href=&amp;quot;[^&amp;quot;]+:Contributions[^&amp;quot;]+offset=(\\d+)/gi;&lt;br /&gt;
function fetch_data(username, end_date, handler, offset, page_list) {&lt;br /&gt;
    var url = prefix + &amp;quot;Special:Contributions/&amp;quot; + username + &amp;quot;?offset=&amp;quot; + offset + &amp;quot;&amp;amp;limit=500&amp;quot;;&lt;br /&gt;
    loadXMLDoc(url, &lt;br /&gt;
        function (request) {&lt;br /&gt;
            var next_offset = 0;&lt;br /&gt;
            if (request.readyState != 4)   return;&lt;br /&gt;
            if (request.status == 200) {&lt;br /&gt;
                page_list.push(request.responseText);&lt;br /&gt;
                //dump_text(request.responseText);&lt;br /&gt;
&lt;br /&gt;
                // see if there's another pageful to get&lt;br /&gt;
                var matches = map( function(p){&lt;br /&gt;
                        return p.match( /(\\d+)$/ )[0];&lt;br /&gt;
                    }, request.responseText.match( offset_regexp ) );&lt;br /&gt;
                for (var i=0; i&amp;lt;matches.length; i++) {&lt;br /&gt;
                    var v = matches[i] * 1;&lt;br /&gt;
                    if (v != 0 &amp;amp;&amp;amp; (offset == 0 || v &amp;lt; offset)) {&lt;br /&gt;
                        next_offset = v;&lt;br /&gt;
                        break;&lt;br /&gt;
                    }&lt;br /&gt;
                }&lt;br /&gt;
            }&lt;br /&gt;
&lt;br /&gt;
            if (next_offset == 0) {&lt;br /&gt;
                parse_data(page_list, handler);&lt;br /&gt;
            } else {&lt;br /&gt;
                // tail recurse&lt;br /&gt;
                fetch_data(username, end_date, handler, next_offset, page_list);&lt;br /&gt;
            }&lt;br /&gt;
        });&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function parse_data(page_list, handler) {&lt;br /&gt;
    //var total_len = 0;&lt;br /&gt;
    //for (var i=0; i&amp;lt;page_list.length; i++) total_len += page_list[i].length;&lt;br /&gt;
    //alert(&amp;quot;parsing &amp;quot; + page_list.length + &amp;quot; pages comprising &amp;quot; + total_len + &amp;quot; total bytes&amp;quot;);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== test/debug functions =========================================&lt;br /&gt;
&lt;br /&gt;
function dump_text(text) {&lt;br /&gt;
  //alert(&amp;quot;dump_text, with text of size &amp;quot; + text.length);&lt;br /&gt;
&lt;br /&gt;
  var pre = document.createElement(&amp;quot;pre&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  var div = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
  div.style.width = &amp;quot;60em&amp;quot;;&lt;br /&gt;
  div.style.maxHeight = &amp;quot;40em&amp;quot;;&lt;br /&gt;
  div.style.overflow = &amp;quot;auto&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  pre.appendChild(document.createTextNode(text));&lt;br /&gt;
  div.appendChild(pre);&lt;br /&gt;
  document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(div);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function dump_lines(ary) {&lt;br /&gt;
  dump_text(ary.join(&amp;quot;\&lt;br /&gt;
&amp;quot;));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== utility functions =========================================&lt;br /&gt;
&lt;br /&gt;
function addOnloadFunction(f) {&lt;br /&gt;
  if (window.addEventListener) window.addEventListener(&amp;quot;load&amp;quot;,f,false);&lt;br /&gt;
  else if (window.attachEvent) window.attachEvent(&amp;quot;onload&amp;quot;,f);&lt;br /&gt;
  else {&lt;br /&gt;
    var oldOnload='_old_onload_'+addOnloadFunction.uid;&lt;br /&gt;
    addOnloadFunction[oldOnload] = window.onload ? window.onload : function () {};&lt;br /&gt;
    window.onload = function() { addOnloadFunction[oldOnload]();  f(); }&lt;br /&gt;
    ++addOnloadFunction.uid;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function parse_params() {&lt;br /&gt;
  var pairs = document.location.search.substring(1).split(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
  var ret = [];&lt;br /&gt;
  for (var i=0; i &amp;lt; pairs.length; i++) {&lt;br /&gt;
    var values = pairs[i].split(&amp;quot;=&amp;quot;);&lt;br /&gt;
    ret[values[0]] = unescape(values[1]);&lt;br /&gt;
  }&lt;br /&gt;
  return ret; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function loadXMLDoc(url, handler)&lt;br /&gt;
{&lt;br /&gt;
    // branch for native XMLHttpRequest object&lt;br /&gt;
    if (window.XMLHttpRequest) {&lt;br /&gt;
        req = new XMLHttpRequest();&lt;br /&gt;
    req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
        req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
        req.send(null);&lt;br /&gt;
    // branch for IE/Windows ActiveX version&lt;br /&gt;
    } else if (window.ActiveXObject) {&lt;br /&gt;
        req = new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);&lt;br /&gt;
        if (req) {&lt;br /&gt;
            req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
            req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
            req.send();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#map&lt;br /&gt;
function map (handler, list) {&lt;br /&gt;
  var ret = new Array();&lt;br /&gt;
  for (var i=0; i&amp;lt;list.length; i++) {&lt;br /&gt;
    ret[i] = handler( list[i] );&lt;br /&gt;
    // ret.push( handler( list[i] ) );&lt;br /&gt;
  }&lt;br /&gt;
  return ret;&lt;br /&gt;
}&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:10:20 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/editcount.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:07:55 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>User:Canderous/editcount.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/editcount.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 20:07:38 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/editcount.js</comments>		</item>
		<item>
			<title>User:Canderous/editcount.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/editcount.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;// see http://paperlined.org/apps/wikipedia/Tool2/ for instructions on adding this to your monobook.js&lt;br /&gt;
&lt;br /&gt;
// To run this tool on other servers:&lt;br /&gt;
//	1. copy this script to the target server (this is required because of javascript cross-site security restrictions)&lt;br /&gt;
&lt;br /&gt;
//	2. update the following URL&lt;br /&gt;
//		for example: &amp;quot;User:Canderous/editcount.js&amp;quot;&lt;br /&gt;
var tool2_url = &amp;quot;User:Canderous/editcount.js&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//	3. update this namespace list, extracted from something like http://en.wikiquote.org/wiki/Special:Export//&lt;br /&gt;
//			These *should not* have colons after them.&lt;br /&gt;
var namespaces = [&lt;br /&gt;
&amp;quot;Talk&amp;quot;,&lt;br /&gt;
&amp;quot;User&amp;quot;,&lt;br /&gt;
&amp;quot;User talk&amp;quot;,&lt;br /&gt;
&amp;quot;Wikiquote&amp;quot;,&lt;br /&gt;
&amp;quot;Wikiquote talk&amp;quot;,&lt;br /&gt;
&amp;quot;Image&amp;quot;,&lt;br /&gt;
&amp;quot;Image talk&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki talk&amp;quot;,&lt;br /&gt;
&amp;quot;Template&amp;quot;,&lt;br /&gt;
&amp;quot;Template talk&amp;quot;,&lt;br /&gt;
&amp;quot;Help&amp;quot;,&lt;br /&gt;
&amp;quot;Help talk&amp;quot;,&lt;br /&gt;
&amp;quot;Category&amp;quot;,&lt;br /&gt;
&amp;quot;Category talk&amp;quot;,&lt;br /&gt;
		// 3b. these two project project entries are not added by Special:Export, and might or might not need to be updated&lt;br /&gt;
&amp;quot;Editthis&amp;quot;,&lt;br /&gt;
&amp;quot;Editthis talk&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
namespaces[100] = &amp;quot;Portal&amp;quot;;&lt;br /&gt;
namespaces[101] = &amp;quot;Portal talk&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//	4. update this date-parser to match the format and language of your specific wiki.  Feel free to contact Interiot regarding this, if you can't find another&lt;br /&gt;
//		copy of this script that uses the same language.&lt;br /&gt;
// input: a text string from Special:Contributions.    output: a javascript Date object&lt;br /&gt;
// documentation:  http://www.quirksmode.org/js/introdate.html#parse, http://www.elated.com/tutorials/programming/javascript/dates/&lt;br /&gt;
function date_parse(text) {&lt;br /&gt;
	var matches = text.match(/^([0-9:]+), +([0-9]+) +([a-z]+) +([0-9]+)$/i);&lt;br /&gt;
	if (!matches) {&lt;br /&gt;
		//dump_text(&amp;quot;XXX&amp;quot;);			// for debugging&lt;br /&gt;
		return matches;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	parseme = matches[3] + &amp;quot;, &amp;quot; + matches[2] + &amp;quot; &amp;quot;  + matches[4] + &amp;quot; &amp;quot; + matches[1] + &amp;quot;:00&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	//dump_text(parseme);				// for debugging&lt;br /&gt;
&lt;br /&gt;
	var dt = new Date();&lt;br /&gt;
	dt.setTime( Date.parse(parseme));&lt;br /&gt;
&lt;br /&gt;
	//dump_text(dt.toLocaleString());		// for debugging&lt;br /&gt;
&lt;br /&gt;
	return dt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ end of server-specific configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
//	- the current document.location method doesn't work when the page is accessed sans-mod_rewrite&lt;br /&gt;
//	- test with non-ASCII characters&lt;br /&gt;
//		- non-ascii usernames&lt;br /&gt;
//		- ??&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var prefix = &amp;quot;&amp;quot;;&lt;br /&gt;
var params = parse_params();&lt;br /&gt;
&lt;br /&gt;
addOnloadFunction(function() {&lt;br /&gt;
  var path_len = document.location.pathname.length;&lt;br /&gt;
  // trigger once we view the right page&lt;br /&gt;
  if (document.location.pathname.substring(path_len - tool2_url.length, path_len) == tool2_url) {&lt;br /&gt;
    // get the prefix (needs to be fixed to work sans-mod_rewrite&lt;br /&gt;
    prefix = document.location.protocol + &amp;quot;//&amp;quot; + document.location.host + &amp;quot;/&amp;quot;&lt;br /&gt;
            + document.location.pathname.substring(1, path_len - tool2_url.length);&lt;br /&gt;
&lt;br /&gt;
    // blank the inner contents of the page&lt;br /&gt;
    var bodyContent = document.getElementById(&amp;quot;bodyContent&amp;quot;);&lt;br /&gt;
    while (bodyContent.childNodes.length &amp;gt; 0) bodyContent.removeChild(bodyContent.lastChild);&lt;br /&gt;
&lt;br /&gt;
    if (document.location.search.length == 0) {&lt;br /&gt;
      generate_input_form(bodyContent);&lt;br /&gt;
    } else {&lt;br /&gt;
      generate_main_report(bodyContent);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function generate_input_form(bodyContent) {&lt;br /&gt;
  if (navigator.userAgent.toLowerCase().indexOf('msie')+1)&lt;br /&gt;
  {&lt;br /&gt;
  bodyContent.innerHTML = &amp;quot;This counter does not currently work in Internet Explorer.  Please &amp;lt;a href='http://www.getfirefox.com'&amp;gt;get Firefox&amp;lt;/a&amp;gt; or use &amp;lt;a href='http://en.wikipedia.org/wiki/Wikipedia:WikiProject_edit_counters/Flcelloguy%27s_Tool'&amp;gt;Flcelloguy's Tool&amp;lt;/a&amp;gt; instead.&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
  bodyContent.innerHTML =&lt;br /&gt;
            &amp;quot;&amp;lt;form&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Username &amp;lt;td&amp;gt;&amp;lt;input maxlength=128 name=username value='' id=username title='username'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;             &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;         &amp;lt;td&amp;gt;&amp;lt;input type=submit value='Submit'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;&amp;lt;/table&amp;gt;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  var form = bodyContent.getElementsByTagName(&amp;quot;form&amp;quot;)[0];&lt;br /&gt;
  form.method = &amp;quot;get&amp;quot;;&lt;br /&gt;
  form.action = document.location;&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&amp;quot;username&amp;quot;).focus();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function generate_main_report() {&lt;br /&gt;
  fetch_data(params[&amp;quot;username&amp;quot;].replace(/\\+/g, &amp;quot; &amp;quot;),&lt;br /&gt;
		&amp;quot;&amp;quot;, output_main_report, 0, []);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function add_stats_row(left_col, right_col) {&lt;br /&gt;
		var row = document.createElement(&amp;quot;tr&amp;quot;);&lt;br /&gt;
		var left = document.createElement(&amp;quot;td&amp;quot;);&lt;br /&gt;
		var right = document.createElement(&amp;quot;td&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
		document.getElementById(&amp;quot;basic_stats&amp;quot;).appendChild(row);&lt;br /&gt;
		row.appendChild(left);&lt;br /&gt;
		row.appendChild(right);&lt;br /&gt;
		//left.innerHTML = left_col;&lt;br /&gt;
		left.appendChild( document.createTextNode(left_col) );&lt;br /&gt;
		right.appendChild( document.createTextNode(right_col) );&lt;br /&gt;
		return row;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
function output_main_report(history) {&lt;br /&gt;
	// -- generate summary statistics&lt;br /&gt;
	var unique_articles = new Array();&lt;br /&gt;
	var namespace_numedits = new Array();&lt;br /&gt;
	for (var i=0; i&amp;lt;namespaces.length; i++) {&lt;br /&gt;
		namespace_numedits[ namespaces[i] ] = 0;&lt;br /&gt;
	}&lt;br /&gt;
	namespace_numedits[&amp;quot;&amp;quot;] = 0;&lt;br /&gt;
	for (var i=0; i&amp;lt;history.length; i++) {&lt;br /&gt;
		var h = history[i];&lt;br /&gt;
		unique_articles[  h[&amp;quot;title&amp;quot;] ]++;&lt;br /&gt;
		namespace_numedits[  h[&amp;quot;namespace&amp;quot;] ]++;&lt;br /&gt;
	}&lt;br /&gt;
	var unique_articles_keys = keys(unique_articles);&lt;br /&gt;
&lt;br /&gt;
	// -- output report&lt;br /&gt;
	var table = document.createElement(&amp;quot;table&amp;quot;);&lt;br /&gt;
	table.id = &amp;quot;basic_stats&amp;quot;;&lt;br /&gt;
	document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(table);&lt;br /&gt;
&lt;br /&gt;
	add_stats_row(&amp;quot;Username&amp;quot;, params[&amp;quot;username&amp;quot;].replace(/\\+/g, &amp;quot; &amp;quot;));&lt;br /&gt;
	add_stats_row(&amp;quot;Total edits&amp;quot;, history.length);&lt;br /&gt;
	add_stats_row(&amp;quot;Distinct pages edited&amp;quot;, unique_articles_keys.length);&lt;br /&gt;
	add_stats_row(&amp;quot;Average edits/page&amp;quot;, new Number(history.length / unique_articles_keys.length).toFixed(3));&lt;br /&gt;
	add_stats_row(&amp;quot;First edit&amp;quot;, history[ history.length-1 ][&amp;quot;date_text&amp;quot;] );&lt;br /&gt;
&lt;br /&gt;
	// add a blank row&lt;br /&gt;
	add_stats_row(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;).childNodes[0].style.height = &amp;quot;1em&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	add_stats_row(&amp;quot;(main)&amp;quot;, namespace_numedits[&amp;quot;&amp;quot;]);&lt;br /&gt;
	for (var i=0; i&amp;lt;namespaces.length; i++) {&lt;br /&gt;
		var nmspc = namespaces[i];&lt;br /&gt;
		if (namespace_numedits[nmspc]) {&lt;br /&gt;
			add_stats_row(nmspc, namespace_numedits[nmspc]);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== HTML-scraping backend =========================================&lt;br /&gt;
&lt;br /&gt;
function add_loading_notice() {&lt;br /&gt;
	if (document.getElementById(&amp;quot;loading_notice&amp;quot;))&lt;br /&gt;
		return;&lt;br /&gt;
	var loading = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
	loading.id = &amp;quot;loading_notice&amp;quot;;&lt;br /&gt;
	loading.innerHTML = &amp;quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Retrieving data&amp;lt;blink&amp;gt;...&amp;lt;/blink&amp;gt;&amp;quot;;&lt;br /&gt;
	document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(loading);&lt;br /&gt;
}&lt;br /&gt;
function remove_loading_notice() {&lt;br /&gt;
	var loading = document.getElementById(&amp;quot;loading_notice&amp;quot;);&lt;br /&gt;
	if (!loading) return;&lt;br /&gt;
	loading.parentNode.removeChild(loading);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var offset_regexp = /href=&amp;quot;[^&amp;quot;]+:Contributions[^&amp;quot;]+offset=(\\d+)/gi;&lt;br /&gt;
function fetch_data(username, end_date, handler, offset, page_list) {&lt;br /&gt;
	add_loading_notice();&lt;br /&gt;
	var url = prefix + &amp;quot;Special:Contributions/&amp;quot; + username + &amp;quot;?offset=&amp;quot; + offset + &amp;quot;&amp;amp;limit=5000&amp;quot;;&lt;br /&gt;
	loadXMLDoc(url, &lt;br /&gt;
		function (request) {&lt;br /&gt;
			var next_offset = 0;&lt;br /&gt;
			if (request.readyState != 4)   return;&lt;br /&gt;
			if (request.status == 200) {&lt;br /&gt;
				page_list.push(request.responseText);&lt;br /&gt;
				//dump_text(request.responseText);&lt;br /&gt;
&lt;br /&gt;
				// see if there's another pageful to get&lt;br /&gt;
				var matches = map( function(p){&lt;br /&gt;
						return p.match( /(\\d+)$/ )[0];&lt;br /&gt;
					}, request.responseText.match( offset_regexp ) );&lt;br /&gt;
				for (var i=0; i&amp;lt;matches.length; i++) {&lt;br /&gt;
					var v = matches[i] * 1;&lt;br /&gt;
					if (v != 0 &amp;amp;&amp;amp; (offset == 0 || v &amp;lt; offset)) {&lt;br /&gt;
						next_offset = v;&lt;br /&gt;
						break;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//next_offset = 0;			// for testing only, retrieve just the first page of results&lt;br /&gt;
&lt;br /&gt;
			if (next_offset == 0) {&lt;br /&gt;
				parse_data(page_list, handler);&lt;br /&gt;
			} else {&lt;br /&gt;
				// tail recurse&lt;br /&gt;
				fetch_data(username, end_date, handler, next_offset, page_list);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// input: a list of strings, each string containing the HTML from a single page&lt;br /&gt;
// output: a list, where each individual entry is a specific edit from history&lt;br /&gt;
function parse_data(page_list, handler) {&lt;br /&gt;
	//var total_len = 0;&lt;br /&gt;
	//for (var i=0; i&amp;lt;page_list.length; i++) total_len += page_list[i].length;&lt;br /&gt;
	//alert(&amp;quot;parsing &amp;quot; + page_list.length + &amp;quot; pages comprising &amp;quot; + total_len + &amp;quot; total bytes&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	var last_history_ent = [];&lt;br /&gt;
	last_history_ent[&amp;quot;title&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
	last_history_ent[&amp;quot;oldid&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	var edit_history = new Array();&lt;br /&gt;
	for (var pagecnt=0; pagecnt&amp;lt;page_list.length; pagecnt++) {&lt;br /&gt;
		var matches = page_list[pagecnt].match( /^&amp;lt;li&amp;gt;[^(]+\\(&amp;lt;a href=&amp;quot;[^&amp;quot;]+action=history.*/gim );&lt;br /&gt;
		//dump_lines(matches);&lt;br /&gt;
		for (var matchcnt=0; matchcnt&amp;lt;matches.length; matchcnt++) {&lt;br /&gt;
			var history_text = matches[matchcnt];&lt;br /&gt;
&lt;br /&gt;
			var history_entry = new Array();&lt;br /&gt;
			history_entry[&amp;quot;date_text&amp;quot;] = history_text.match( /^&amp;lt;li&amp;gt;([^(&amp;lt;]+)/i )[1]&lt;br /&gt;
					.replace( / +$/, &amp;quot;&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;date&amp;quot;] = date_parse( history_entry[&amp;quot;date_text&amp;quot;] );&lt;br /&gt;
			history_entry[&amp;quot;title&amp;quot;] = history_text.match( /title=&amp;quot;([^&amp;quot;]+)&amp;quot;/i )[1]&lt;br /&gt;
					.replace( /&amp;amp;quot;/g, &amp;quot;\\&amp;quot;&amp;quot;)&lt;br /&gt;
					.replace( /&amp;amp;amp;/g, &amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
			var find_comment = history_text.replace(/&amp;lt;span class=&amp;quot;autocomment&amp;quot;&amp;gt;.*?&amp;lt;\\/span&amp;gt; ?/, &amp;quot;&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;comment&amp;quot;] = ifmatch(find_comment.match( /&amp;lt;span class='comment'&amp;gt;(.*?)&amp;lt;\\/span&amp;gt;/ ))&lt;br /&gt;
					.replace(/^\\((.*)\\)$/, &amp;quot;$1&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;minor&amp;quot;] = /&amp;lt;span class=&amp;quot;minor&amp;quot;/.test(history_text);&lt;br /&gt;
			history_entry[&amp;quot;oldid&amp;quot;] = ifmatch(history_text.match(/oldid=([0-9]+)/i));&lt;br /&gt;
&lt;br /&gt;
			history_entry[&amp;quot;namespace&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
			for (var nmspc_ctr=0; nmspc_ctr&amp;lt;namespaces.length; nmspc_ctr++) {&lt;br /&gt;
				var nmspc = namespaces[nmspc_ctr] + &amp;quot;:&amp;quot;;&lt;br /&gt;
				if (history_entry[&amp;quot;title&amp;quot;].substring(0, nmspc.length) == nmspc) {&lt;br /&gt;
					history_entry[&amp;quot;namespace&amp;quot;] = namespaces[nmspc_ctr];&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//dump_object(history_entry);&lt;br /&gt;
&lt;br /&gt;
			if (history_entry[&amp;quot;title&amp;quot;] != last_history_ent[&amp;quot;title&amp;quot;] || history_entry[&amp;quot;oldid&amp;quot;] != last_history_ent[&amp;quot;oldid&amp;quot;])&lt;br /&gt;
				edit_history.push(history_entry);&lt;br /&gt;
			last_history_ent = history_entry;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	remove_loading_notice();&lt;br /&gt;
&lt;br /&gt;
	handler(edit_history);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== test/debug functions =========================================&lt;br /&gt;
&lt;br /&gt;
function dump_text(text) {&lt;br /&gt;
  //alert(&amp;quot;dump_text, with text of size &amp;quot; + text.length);&lt;br /&gt;
&lt;br /&gt;
  var pre = document.createElement(&amp;quot;pre&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  var div = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
  div.style.width = &amp;quot;60em&amp;quot;;&lt;br /&gt;
  div.style.maxHeight = &amp;quot;40em&amp;quot;;&lt;br /&gt;
  div.style.overflow = &amp;quot;auto&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  pre.appendChild(document.createTextNode(text));&lt;br /&gt;
  div.appendChild(pre);&lt;br /&gt;
  document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(div);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function dump_lines(ary) {&lt;br /&gt;
  dump_text(&amp;quot;--&amp;gt; &amp;quot; + ary.join(&amp;quot;\&lt;br /&gt;
--&amp;gt; &amp;quot;));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function dump_object(obj) {&lt;br /&gt;
	var toString = &amp;quot;&amp;quot;;&lt;br /&gt;
	for (var prop in obj) {&lt;br /&gt;
		toString += prop + &amp;quot;: &amp;quot; + obj[prop] + &amp;quot;\&lt;br /&gt;
&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
	dump_text(toString);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== utility functions =========================================&lt;br /&gt;
&lt;br /&gt;
function addOnloadFunction(f) {&lt;br /&gt;
  if (window.addEventListener) window.addEventListener(&amp;quot;load&amp;quot;,f,false);&lt;br /&gt;
  else if (window.attachEvent) window.attachEvent(&amp;quot;onload&amp;quot;,f);&lt;br /&gt;
  else {&lt;br /&gt;
    var oldOnload='_old_onload_'+addOnloadFunction.uid;&lt;br /&gt;
    addOnloadFunction[oldOnload] = window.onload ? window.onload : function () {};&lt;br /&gt;
    window.onload = function() { addOnloadFunction[oldOnload]();  f(); }&lt;br /&gt;
    ++addOnloadFunction.uid;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function parse_params() {&lt;br /&gt;
  var pairs = document.location.search.substring(1).split(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
  var ret = [];&lt;br /&gt;
  for (var i=0; i &amp;lt; pairs.length; i++) {&lt;br /&gt;
    var values = pairs[i].split(&amp;quot;=&amp;quot;);&lt;br /&gt;
    ret[values[0]] = unescape(values[1]);&lt;br /&gt;
  }&lt;br /&gt;
  return ret; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function loadXMLDoc(url, handler)&lt;br /&gt;
{&lt;br /&gt;
    // branch for native XMLHttpRequest object&lt;br /&gt;
    if (window.XMLHttpRequest) {&lt;br /&gt;
        req = new XMLHttpRequest();&lt;br /&gt;
	req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
        req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
        req.send(null);&lt;br /&gt;
    // branch for IE/Windows ActiveX version&lt;br /&gt;
    } else if (window.ActiveXObject) {&lt;br /&gt;
        req = new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);&lt;br /&gt;
        if (req) {&lt;br /&gt;
            req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
            req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
            req.send();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#map&lt;br /&gt;
function map (handler, list) {&lt;br /&gt;
  var ret = new Array();&lt;br /&gt;
  for (var i=0; i&amp;lt;list.length; i++) {&lt;br /&gt;
    ret[i] = handler( list[i] );&lt;br /&gt;
    // ret.push( handler( list[i] ) );&lt;br /&gt;
  }&lt;br /&gt;
  return ret;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#keys&lt;br /&gt;
function keys (obj) {&lt;br /&gt;
	var ret = new Array();&lt;br /&gt;
	for (var key in obj) {&lt;br /&gt;
		ret.push(key);&lt;br /&gt;
	}&lt;br /&gt;
	return ret;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function ifmatch(ary) {&lt;br /&gt;
	if (ary &amp;amp;&amp;amp; ary.length &amp;gt;= 2) {&lt;br /&gt;
		return ary[1];&lt;br /&gt;
	} else {&lt;br /&gt;
		return &amp;quot;&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 18:29:37 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/editcount.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;//Interiot's javascript edit counter&lt;br /&gt;
if (document.title.indexOf('User:Canderous/editcount.js') != -1) {&lt;br /&gt;
  document.write('&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;' &lt;br /&gt;
    + 'http://www.editthis.info/wiki/User:Canderous/editcount.js' &lt;br /&gt;
    + '&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;amp;dontcountme=s&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;'); }&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 18:19:48 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;//Interiot's javascript edit counter&lt;br /&gt;
if (document.title.indexOf('User:Canderous/editcount.js') != -1) {&lt;br /&gt;
  document.write('&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;' &lt;br /&gt;
    + 'http://en.wikipedia.org/w/index.php?title=User:Canderous/editcount.js' &lt;br /&gt;
    + '&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;amp;dontcountme=s&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;'); }&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 18:13:05 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>User:Canderous/editcount.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/editcount.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;// see http://paperlined.org/apps/wikipedia/Tool2/ for instructions on adding this to your monobook.js&lt;br /&gt;
&lt;br /&gt;
// To run this tool on other servers:&lt;br /&gt;
//	1. copy this script to the target server (this is required because of javascript cross-site security restrictions)&lt;br /&gt;
&lt;br /&gt;
//	2. update the following URL&lt;br /&gt;
//		for example: &amp;quot;User:Interiot/Tool2/code.js&amp;quot;&lt;br /&gt;
var tool2_url = &amp;quot;User:Interiot/Tool2/code.js&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//	3. update this namespace list, extracted from something like http://en.wikiquote.org/wiki/Special:Export//&lt;br /&gt;
//			These *should not* have colons after them.&lt;br /&gt;
var namespaces = [&lt;br /&gt;
&amp;quot;Talk&amp;quot;,&lt;br /&gt;
&amp;quot;User&amp;quot;,&lt;br /&gt;
&amp;quot;User talk&amp;quot;,&lt;br /&gt;
&amp;quot;Wikiquote&amp;quot;,&lt;br /&gt;
&amp;quot;Wikiquote talk&amp;quot;,&lt;br /&gt;
&amp;quot;Image&amp;quot;,&lt;br /&gt;
&amp;quot;Image talk&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki&amp;quot;,&lt;br /&gt;
&amp;quot;MediaWiki talk&amp;quot;,&lt;br /&gt;
&amp;quot;Template&amp;quot;,&lt;br /&gt;
&amp;quot;Template talk&amp;quot;,&lt;br /&gt;
&amp;quot;Help&amp;quot;,&lt;br /&gt;
&amp;quot;Help talk&amp;quot;,&lt;br /&gt;
&amp;quot;Category&amp;quot;,&lt;br /&gt;
&amp;quot;Category talk&amp;quot;,&lt;br /&gt;
		// 3b. these two project project entries are not added by Special:Export, and might or might not need to be updated&lt;br /&gt;
&amp;quot;Wikipedia&amp;quot;,&lt;br /&gt;
&amp;quot;Wikipedia talk&amp;quot;&lt;br /&gt;
];&lt;br /&gt;
&lt;br /&gt;
namespaces[100] = &amp;quot;Portal&amp;quot;;&lt;br /&gt;
namespaces[101] = &amp;quot;Portal talk&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
//	4. update this date-parser to match the format and language of your specific wiki.  Feel free to contact Interiot regarding this, if you can't find another&lt;br /&gt;
//		copy of this script that uses the same language.&lt;br /&gt;
// input: a text string from Special:Contributions.    output: a javascript Date object&lt;br /&gt;
// documentation:  http://www.quirksmode.org/js/introdate.html#parse, http://www.elated.com/tutorials/programming/javascript/dates/&lt;br /&gt;
function date_parse(text) {&lt;br /&gt;
	var matches = text.match(/^([0-9:]+), +([0-9]+) +([a-z]+) +([0-9]+)$/i);&lt;br /&gt;
	if (!matches) {&lt;br /&gt;
		//dump_text(&amp;quot;XXX&amp;quot;);			// for debugging&lt;br /&gt;
		return matches;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	parseme = matches[3] + &amp;quot;, &amp;quot; + matches[2] + &amp;quot; &amp;quot;  + matches[4] + &amp;quot; &amp;quot; + matches[1] + &amp;quot;:00&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	//dump_text(parseme);				// for debugging&lt;br /&gt;
&lt;br /&gt;
	var dt = new Date();&lt;br /&gt;
	dt.setTime( Date.parse(parseme));&lt;br /&gt;
&lt;br /&gt;
	//dump_text(dt.toLocaleString());		// for debugging&lt;br /&gt;
&lt;br /&gt;
	return dt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ end of server-specific configuration ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// TODO:&lt;br /&gt;
//	- the current document.location method doesn't work when the page is accessed sans-mod_rewrite&lt;br /&gt;
//	- test with non-ASCII characters&lt;br /&gt;
//		- non-ascii usernames&lt;br /&gt;
//		- ??&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
var prefix = &amp;quot;&amp;quot;;&lt;br /&gt;
var params = parse_params();&lt;br /&gt;
&lt;br /&gt;
addOnloadFunction(function() {&lt;br /&gt;
  var path_len = document.location.pathname.length;&lt;br /&gt;
  // trigger once we view the right page&lt;br /&gt;
  if (document.location.pathname.substring(path_len - tool2_url.length, path_len) == tool2_url) {&lt;br /&gt;
    // get the prefix (needs to be fixed to work sans-mod_rewrite&lt;br /&gt;
    prefix = document.location.protocol + &amp;quot;//&amp;quot; + document.location.host + &amp;quot;/&amp;quot;&lt;br /&gt;
            + document.location.pathname.substring(1, path_len - tool2_url.length);&lt;br /&gt;
&lt;br /&gt;
    // blank the inner contents of the page&lt;br /&gt;
    var bodyContent = document.getElementById(&amp;quot;bodyContent&amp;quot;);&lt;br /&gt;
    while (bodyContent.childNodes.length &amp;gt; 0) bodyContent.removeChild(bodyContent.lastChild);&lt;br /&gt;
&lt;br /&gt;
    if (document.location.search.length == 0) {&lt;br /&gt;
      generate_input_form(bodyContent);&lt;br /&gt;
    } else {&lt;br /&gt;
      generate_main_report(bodyContent);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
});&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function generate_input_form(bodyContent) {&lt;br /&gt;
  if (navigator.userAgent.toLowerCase().indexOf('msie')+1)&lt;br /&gt;
  {&lt;br /&gt;
  bodyContent.innerHTML = &amp;quot;This counter does not currently work in Internet Explorer.  Please &amp;lt;a href='http://www.getfirefox.com'&amp;gt;get Firefox&amp;lt;/a&amp;gt; or use &amp;lt;a href='http://en.wikipedia.org/wiki/Wikipedia:WikiProject_edit_counters/Flcelloguy%27s_Tool'&amp;gt;Flcelloguy's Tool&amp;lt;/a&amp;gt; instead.&amp;quot;;&lt;br /&gt;
  }&lt;br /&gt;
  else&lt;br /&gt;
  {&lt;br /&gt;
  bodyContent.innerHTML =&lt;br /&gt;
            &amp;quot;&amp;lt;form&amp;gt;&amp;lt;table&amp;gt;&amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;Username &amp;lt;td&amp;gt;&amp;lt;input maxlength=128 name=username value='' id=username title='username'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;             &amp;lt;tr&amp;gt;&amp;lt;td&amp;gt;         &amp;lt;td&amp;gt;&amp;lt;input type=submit value='Submit'&amp;gt;&amp;quot; +&lt;br /&gt;
            &amp;quot;&amp;lt;/table&amp;gt;&amp;lt;/form&amp;gt;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  var form = bodyContent.getElementsByTagName(&amp;quot;form&amp;quot;)[0];&lt;br /&gt;
  form.method = &amp;quot;get&amp;quot;;&lt;br /&gt;
  form.action = document.location;&lt;br /&gt;
&lt;br /&gt;
  document.getElementById(&amp;quot;username&amp;quot;).focus();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function generate_main_report() {&lt;br /&gt;
  fetch_data(params[&amp;quot;username&amp;quot;].replace(/\\+/g, &amp;quot; &amp;quot;),&lt;br /&gt;
		&amp;quot;&amp;quot;, output_main_report, 0, []);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
	function add_stats_row(left_col, right_col) {&lt;br /&gt;
		var row = document.createElement(&amp;quot;tr&amp;quot;);&lt;br /&gt;
		var left = document.createElement(&amp;quot;td&amp;quot;);&lt;br /&gt;
		var right = document.createElement(&amp;quot;td&amp;quot;);&lt;br /&gt;
	&lt;br /&gt;
		document.getElementById(&amp;quot;basic_stats&amp;quot;).appendChild(row);&lt;br /&gt;
		row.appendChild(left);&lt;br /&gt;
		row.appendChild(right);&lt;br /&gt;
		//left.innerHTML = left_col;&lt;br /&gt;
		left.appendChild( document.createTextNode(left_col) );&lt;br /&gt;
		right.appendChild( document.createTextNode(right_col) );&lt;br /&gt;
		return row;&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
function output_main_report(history) {&lt;br /&gt;
	// -- generate summary statistics&lt;br /&gt;
	var unique_articles = new Array();&lt;br /&gt;
	var namespace_numedits = new Array();&lt;br /&gt;
	for (var i=0; i&amp;lt;namespaces.length; i++) {&lt;br /&gt;
		namespace_numedits[ namespaces[i] ] = 0;&lt;br /&gt;
	}&lt;br /&gt;
	namespace_numedits[&amp;quot;&amp;quot;] = 0;&lt;br /&gt;
	for (var i=0; i&amp;lt;history.length; i++) {&lt;br /&gt;
		var h = history[i];&lt;br /&gt;
		unique_articles[  h[&amp;quot;title&amp;quot;] ]++;&lt;br /&gt;
		namespace_numedits[  h[&amp;quot;namespace&amp;quot;] ]++;&lt;br /&gt;
	}&lt;br /&gt;
	var unique_articles_keys = keys(unique_articles);&lt;br /&gt;
&lt;br /&gt;
	// -- output report&lt;br /&gt;
	var table = document.createElement(&amp;quot;table&amp;quot;);&lt;br /&gt;
	table.id = &amp;quot;basic_stats&amp;quot;;&lt;br /&gt;
	document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(table);&lt;br /&gt;
&lt;br /&gt;
	add_stats_row(&amp;quot;Username&amp;quot;, params[&amp;quot;username&amp;quot;].replace(/\\+/g, &amp;quot; &amp;quot;));&lt;br /&gt;
	add_stats_row(&amp;quot;Total edits&amp;quot;, history.length);&lt;br /&gt;
	add_stats_row(&amp;quot;Distinct pages edited&amp;quot;, unique_articles_keys.length);&lt;br /&gt;
	add_stats_row(&amp;quot;Average edits/page&amp;quot;, new Number(history.length / unique_articles_keys.length).toFixed(3));&lt;br /&gt;
	add_stats_row(&amp;quot;First edit&amp;quot;, history[ history.length-1 ][&amp;quot;date_text&amp;quot;] );&lt;br /&gt;
&lt;br /&gt;
	// add a blank row&lt;br /&gt;
	add_stats_row(&amp;quot;&amp;quot;, &amp;quot;&amp;quot;).childNodes[0].style.height = &amp;quot;1em&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	add_stats_row(&amp;quot;(main)&amp;quot;, namespace_numedits[&amp;quot;&amp;quot;]);&lt;br /&gt;
	for (var i=0; i&amp;lt;namespaces.length; i++) {&lt;br /&gt;
		var nmspc = namespaces[i];&lt;br /&gt;
		if (namespace_numedits[nmspc]) {&lt;br /&gt;
			add_stats_row(nmspc, namespace_numedits[nmspc]);&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== HTML-scraping backend =========================================&lt;br /&gt;
&lt;br /&gt;
function add_loading_notice() {&lt;br /&gt;
	if (document.getElementById(&amp;quot;loading_notice&amp;quot;))&lt;br /&gt;
		return;&lt;br /&gt;
	var loading = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
	loading.id = &amp;quot;loading_notice&amp;quot;;&lt;br /&gt;
	loading.innerHTML = &amp;quot;&amp;lt;br&amp;gt;&amp;lt;br&amp;gt;Retrieving data&amp;lt;blink&amp;gt;...&amp;lt;/blink&amp;gt;&amp;quot;;&lt;br /&gt;
	document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(loading);&lt;br /&gt;
}&lt;br /&gt;
function remove_loading_notice() {&lt;br /&gt;
	var loading = document.getElementById(&amp;quot;loading_notice&amp;quot;);&lt;br /&gt;
	if (!loading) return;&lt;br /&gt;
	loading.parentNode.removeChild(loading);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
var offset_regexp = /href=&amp;quot;[^&amp;quot;]+:Contributions[^&amp;quot;]+offset=(\\d+)/gi;&lt;br /&gt;
function fetch_data(username, end_date, handler, offset, page_list) {&lt;br /&gt;
	add_loading_notice();&lt;br /&gt;
	var url = prefix + &amp;quot;Special:Contributions/&amp;quot; + username + &amp;quot;?offset=&amp;quot; + offset + &amp;quot;&amp;amp;limit=5000&amp;quot;;&lt;br /&gt;
	loadXMLDoc(url, &lt;br /&gt;
		function (request) {&lt;br /&gt;
			var next_offset = 0;&lt;br /&gt;
			if (request.readyState != 4)   return;&lt;br /&gt;
			if (request.status == 200) {&lt;br /&gt;
				page_list.push(request.responseText);&lt;br /&gt;
				//dump_text(request.responseText);&lt;br /&gt;
&lt;br /&gt;
				// see if there's another pageful to get&lt;br /&gt;
				var matches = map( function(p){&lt;br /&gt;
						return p.match( /(\\d+)$/ )[0];&lt;br /&gt;
					}, request.responseText.match( offset_regexp ) );&lt;br /&gt;
				for (var i=0; i&amp;lt;matches.length; i++) {&lt;br /&gt;
					var v = matches[i] * 1;&lt;br /&gt;
					if (v != 0 &amp;amp;&amp;amp; (offset == 0 || v &amp;lt; offset)) {&lt;br /&gt;
						next_offset = v;&lt;br /&gt;
						break;&lt;br /&gt;
					}&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//next_offset = 0;			// for testing only, retrieve just the first page of results&lt;br /&gt;
&lt;br /&gt;
			if (next_offset == 0) {&lt;br /&gt;
				parse_data(page_list, handler);&lt;br /&gt;
			} else {&lt;br /&gt;
				// tail recurse&lt;br /&gt;
				fetch_data(username, end_date, handler, next_offset, page_list);&lt;br /&gt;
			}&lt;br /&gt;
		});&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// input: a list of strings, each string containing the HTML from a single page&lt;br /&gt;
// output: a list, where each individual entry is a specific edit from history&lt;br /&gt;
function parse_data(page_list, handler) {&lt;br /&gt;
	//var total_len = 0;&lt;br /&gt;
	//for (var i=0; i&amp;lt;page_list.length; i++) total_len += page_list[i].length;&lt;br /&gt;
	//alert(&amp;quot;parsing &amp;quot; + page_list.length + &amp;quot; pages comprising &amp;quot; + total_len + &amp;quot; total bytes&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
	var last_history_ent = [];&lt;br /&gt;
	last_history_ent[&amp;quot;title&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
	last_history_ent[&amp;quot;oldid&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
	var edit_history = new Array();&lt;br /&gt;
	for (var pagecnt=0; pagecnt&amp;lt;page_list.length; pagecnt++) {&lt;br /&gt;
		var matches = page_list[pagecnt].match( /^&amp;lt;li&amp;gt;[^(]+\\(&amp;lt;a href=&amp;quot;[^&amp;quot;]+action=history.*/gim );&lt;br /&gt;
		//dump_lines(matches);&lt;br /&gt;
		for (var matchcnt=0; matchcnt&amp;lt;matches.length; matchcnt++) {&lt;br /&gt;
			var history_text = matches[matchcnt];&lt;br /&gt;
&lt;br /&gt;
			var history_entry = new Array();&lt;br /&gt;
			history_entry[&amp;quot;date_text&amp;quot;] = history_text.match( /^&amp;lt;li&amp;gt;([^(&amp;lt;]+)/i )[1]&lt;br /&gt;
					.replace( / +$/, &amp;quot;&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;date&amp;quot;] = date_parse( history_entry[&amp;quot;date_text&amp;quot;] );&lt;br /&gt;
			history_entry[&amp;quot;title&amp;quot;] = history_text.match( /title=&amp;quot;([^&amp;quot;]+)&amp;quot;/i )[1]&lt;br /&gt;
					.replace( /&amp;amp;quot;/g, &amp;quot;\\&amp;quot;&amp;quot;)&lt;br /&gt;
					.replace( /&amp;amp;amp;/g, &amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
			var find_comment = history_text.replace(/&amp;lt;span class=&amp;quot;autocomment&amp;quot;&amp;gt;.*?&amp;lt;\\/span&amp;gt; ?/, &amp;quot;&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;comment&amp;quot;] = ifmatch(find_comment.match( /&amp;lt;span class='comment'&amp;gt;(.*?)&amp;lt;\\/span&amp;gt;/ ))&lt;br /&gt;
					.replace(/^\\((.*)\\)$/, &amp;quot;$1&amp;quot;);&lt;br /&gt;
			history_entry[&amp;quot;minor&amp;quot;] = /&amp;lt;span class=&amp;quot;minor&amp;quot;/.test(history_text);&lt;br /&gt;
			history_entry[&amp;quot;oldid&amp;quot;] = ifmatch(history_text.match(/oldid=([0-9]+)/i));&lt;br /&gt;
&lt;br /&gt;
			history_entry[&amp;quot;namespace&amp;quot;] = &amp;quot;&amp;quot;;&lt;br /&gt;
			for (var nmspc_ctr=0; nmspc_ctr&amp;lt;namespaces.length; nmspc_ctr++) {&lt;br /&gt;
				var nmspc = namespaces[nmspc_ctr] + &amp;quot;:&amp;quot;;&lt;br /&gt;
				if (history_entry[&amp;quot;title&amp;quot;].substring(0, nmspc.length) == nmspc) {&lt;br /&gt;
					history_entry[&amp;quot;namespace&amp;quot;] = namespaces[nmspc_ctr];&lt;br /&gt;
					break;&lt;br /&gt;
				}&lt;br /&gt;
			}&lt;br /&gt;
&lt;br /&gt;
			//dump_object(history_entry);&lt;br /&gt;
&lt;br /&gt;
			if (history_entry[&amp;quot;title&amp;quot;] != last_history_ent[&amp;quot;title&amp;quot;] || history_entry[&amp;quot;oldid&amp;quot;] != last_history_ent[&amp;quot;oldid&amp;quot;])&lt;br /&gt;
				edit_history.push(history_entry);&lt;br /&gt;
			last_history_ent = history_entry;&lt;br /&gt;
		}&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	remove_loading_notice();&lt;br /&gt;
&lt;br /&gt;
	handler(edit_history);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== test/debug functions =========================================&lt;br /&gt;
&lt;br /&gt;
function dump_text(text) {&lt;br /&gt;
  //alert(&amp;quot;dump_text, with text of size &amp;quot; + text.length);&lt;br /&gt;
&lt;br /&gt;
  var pre = document.createElement(&amp;quot;pre&amp;quot;);&lt;br /&gt;
&lt;br /&gt;
  var div = document.createElement(&amp;quot;div&amp;quot;);&lt;br /&gt;
  div.style.width = &amp;quot;60em&amp;quot;;&lt;br /&gt;
  div.style.maxHeight = &amp;quot;40em&amp;quot;;&lt;br /&gt;
  div.style.overflow = &amp;quot;auto&amp;quot;;&lt;br /&gt;
&lt;br /&gt;
  pre.appendChild(document.createTextNode(text));&lt;br /&gt;
  div.appendChild(pre);&lt;br /&gt;
  document.getElementById(&amp;quot;bodyContent&amp;quot;).appendChild(div);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function dump_lines(ary) {&lt;br /&gt;
  dump_text(&amp;quot;--&amp;gt; &amp;quot; + ary.join(&amp;quot;\&lt;br /&gt;
--&amp;gt; &amp;quot;));&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function dump_object(obj) {&lt;br /&gt;
	var toString = &amp;quot;&amp;quot;;&lt;br /&gt;
	for (var prop in obj) {&lt;br /&gt;
		toString += prop + &amp;quot;: &amp;quot; + obj[prop] + &amp;quot;\&lt;br /&gt;
&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
	dump_text(toString);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// ===================================== utility functions =========================================&lt;br /&gt;
&lt;br /&gt;
function addOnloadFunction(f) {&lt;br /&gt;
  if (window.addEventListener) window.addEventListener(&amp;quot;load&amp;quot;,f,false);&lt;br /&gt;
  else if (window.attachEvent) window.attachEvent(&amp;quot;onload&amp;quot;,f);&lt;br /&gt;
  else {&lt;br /&gt;
    var oldOnload='_old_onload_'+addOnloadFunction.uid;&lt;br /&gt;
    addOnloadFunction[oldOnload] = window.onload ? window.onload : function () {};&lt;br /&gt;
    window.onload = function() { addOnloadFunction[oldOnload]();  f(); }&lt;br /&gt;
    ++addOnloadFunction.uid;&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function parse_params() {&lt;br /&gt;
  var pairs = document.location.search.substring(1).split(&amp;quot;&amp;amp;&amp;quot;);&lt;br /&gt;
  var ret = [];&lt;br /&gt;
  for (var i=0; i &amp;lt; pairs.length; i++) {&lt;br /&gt;
    var values = pairs[i].split(&amp;quot;=&amp;quot;);&lt;br /&gt;
    ret[values[0]] = unescape(values[1]);&lt;br /&gt;
  }&lt;br /&gt;
  return ret; &lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function loadXMLDoc(url, handler)&lt;br /&gt;
{&lt;br /&gt;
    // branch for native XMLHttpRequest object&lt;br /&gt;
    if (window.XMLHttpRequest) {&lt;br /&gt;
        req = new XMLHttpRequest();&lt;br /&gt;
	req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
        req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
        req.send(null);&lt;br /&gt;
    // branch for IE/Windows ActiveX version&lt;br /&gt;
    } else if (window.ActiveXObject) {&lt;br /&gt;
        req = new ActiveXObject(&amp;quot;Microsoft.XMLHTTP&amp;quot;);&lt;br /&gt;
        if (req) {&lt;br /&gt;
            req.onreadystatechange = function () {handler(req)};&lt;br /&gt;
            req.open(&amp;quot;GET&amp;quot;, url, true);&lt;br /&gt;
            req.send();&lt;br /&gt;
        }&lt;br /&gt;
    }&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#map&lt;br /&gt;
function map (handler, list) {&lt;br /&gt;
  var ret = new Array();&lt;br /&gt;
  for (var i=0; i&amp;lt;list.length; i++) {&lt;br /&gt;
    ret[i] = handler( list[i] );&lt;br /&gt;
    // ret.push( handler( list[i] ) );&lt;br /&gt;
  }&lt;br /&gt;
  return ret;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
// see http://search.cpan.org/dist/perl/pod/perlfunc.pod#keys&lt;br /&gt;
function keys (obj) {&lt;br /&gt;
	var ret = new Array();&lt;br /&gt;
	for (var key in obj) {&lt;br /&gt;
		ret.push(key);&lt;br /&gt;
	}&lt;br /&gt;
	return ret;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
function ifmatch(ary) {&lt;br /&gt;
	if (ary &amp;amp;&amp;amp; ary.length &amp;gt;= 2) {&lt;br /&gt;
		return ary[1];&lt;br /&gt;
	} else {&lt;br /&gt;
		return &amp;quot;&amp;quot;;&lt;br /&gt;
	}&lt;br /&gt;
}&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 18:11:54 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/editcount.js</comments>		</item>
		<item>
			<title>User:Canderous/monobook.js</title>
			<link>http://72.14.177.54/wiki/User:Canderous/monobook.js</link>
			<description>&lt;p&gt;Canderous:&amp;#32;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;//Interiot's javascript edit counter&lt;br /&gt;
if (document.title.indexOf('User:Interiot/Tool2/code.js') != -1) {&lt;br /&gt;
  document.write('&amp;lt;script type=&amp;quot;text/javascript&amp;quot; src=&amp;quot;' &lt;br /&gt;
    + 'http://en.wikipedia.org/w/index.php?title=User:Interiot/Tool2/code.js' &lt;br /&gt;
    + '&amp;amp;action=raw&amp;amp;ctype=text/javascript&amp;amp;dontcountme=s&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;'); }&lt;/div&gt;</description>
			<pubDate>Thu, 08 Mar 2007 18:09:56 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/User_talk:Canderous/monobook.js</comments>		</item>
		<item>
			<title>Main Page</title>
			<link>http://72.14.177.54/wiki/Main_Page</link>
			<description>&lt;p&gt;Canderous:&amp;#32;...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;__NOTOC__&lt;br /&gt;
&amp;lt;div style=&amp;quot;float:right&amp;quot;&amp;gt;[http://digg.com/submit?phase=2&amp;amp;url=http%3A%2F%2Fwww.editthis.info%2Fwiki%2FMain_Page Digg This] - [http://del.icio.us/post?url=http://www.editthis.info/ Add to de.licio.us]&lt;br /&gt;
&amp;lt;/div&amp;gt;&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
Note: for the Main Page talk, see [[Main Page talk]]. This is done to prevent automated spamming from clogging up relevant pages.&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| style=&amp;quot;border: 1px solid #dddddd; color:#000; background-color=#eeeeee&amp;quot; &amp;quot;valign=&amp;quot;top&amp;quot;| &lt;br /&gt;
'''Wiki''' (n) - A collaborative site where users can edit content and have fun.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{| width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| style=&amp;quot;border: 1px solid #dddddd; color:#000; background-color=#eeeeee&amp;quot; &amp;quot;valign=&amp;quot;top&amp;quot;| &lt;br /&gt;
'''EditThis.info''' (n) - A site where you can create a wiki in seconds for free.&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
{|width=&amp;quot;90%&amp;quot; align=&amp;quot;center&amp;quot; style=&amp;quot;padding: .4em .9em .9em; border: 1px solid #6066ff; color: #000; background-color: #F0f3ff;&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
[[image:Static_Page.gif|style=&amp;quot;float:left&amp;quot;]]'''Create a single wiki page'''&lt;br /&gt;
&amp;lt;htmlinc&amp;gt;add_page&amp;lt;/htmlinc&amp;gt;&lt;br /&gt;
|valign=top width=&amp;quot;50%&amp;quot;|&lt;br /&gt;
[[image:Multiple_Pages.gif]]'''Create a wiki site'''&amp;lt;htmlinc&amp;gt;add_wiki&amp;lt;/htmlinc&amp;gt;&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Current WOTM}}&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Tools &amp;amp; Top Wikis ==&lt;br /&gt;
{| width=&amp;quot;100%&amp;quot;&lt;br /&gt;
| valign=&amp;quot;top&amp;quot; width=&amp;quot;50%&amp;quot;| &lt;br /&gt;
{{Top Wikis}}&lt;br /&gt;
|  valign=&amp;quot;top&amp;quot;| &lt;br /&gt;
{{Tools}}&lt;br /&gt;
|}&lt;br /&gt;
[[Category:Categories]]&lt;/div&gt;</description>
			<pubDate>Fri, 16 Feb 2007 07:51:37 GMT</pubDate>			<dc:creator>Canderous</dc:creator>			<comments>http://72.14.177.54/wiki/Talk:Main_Page</comments>		</item>
	</channel>
</rss>