function makeReqObj()
{
	if (window.XMLHttpRequest) return new XMLHttpRequest();
	else return new ActiveXObject("Microsoft.XMLHTTP");
}

function deserialise(text)
{
	return !(/[^,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]/.test(
	       text.replace(/"(\\.|[^"\\])*"/g, ''))) &&
	       eval('(' + text + ')');
}

// for debugging
function dump(obj)
{
	var s = "";
	for (var a in obj) s += a + ": " + obj[a] + ",";
	alert("{" + s + "}");
}

// Assigns event handlers and unhooks them on unload
var handle = function() {
	var events = [];
	window.onunload = function() {
		for (var i in events)
			events[i][0][events[i][1]] = null;
		events = null;
	}
	return function(target, event, func) {
		target[event] = func;
		events[events.length] = [target, event];
	}
}();

function addonload(f) {
	var x = window.onload;
	if (x) window.onload = function() { x(); f(); }
	else handle(window, "onload", f);
}

function absLocate(obj)
{
	var left = 0, top = 0;
	do
	{
		left += obj.offsetLeft;
		top += obj.offsetTop;
	}
	while (obj = obj.offsetParent);
	return [left, top];
}

function isAncestorOrSelfOf(x, y)
{
	while (y)
	{
		if (x == y) return true;
		y = y.parentNode;
	}
	return false;
}

function showTempMessageAt(obj, message)
{
	var xy = absLocate(obj);
	var div = document.body.appendChild(document.createElement("div"));
	div.appendChild(document.createTextNode(message));
	div.className = "popup-msg";
	div.style.position = "absolute";
	div.style.left = (xy[0] + obj.offsetWidth) + "px";
	div.style.top = xy[1] + "px";
	
	window.setTimeout(function() { document.body.removeChild(div); }, 3000);
}
function mousePos(e)
{
	if (e.pageX || e.pageY) return [e.pageX, e.pageY];
	return [e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft,
	        e.clientY + document.body.scrollTop + document.documentElement.scrollTop];
}
function addClass(obj, className)
{
	obj.className += " " + className;
}
function delClass(obj, className)
{
	obj.className = obj.className.replace(new RegExp("\\b"+className.replace("-", "\\-")+" ?"), "");
}
function disableTextSelection()
{
	document.documentElement.ondrag = function () { return false; };
	document.documentElement.onselectstart = function () { return false; };
	addClass(document.documentElement, "no-select");
}
function enableTextSelection()
{
	document.documentElement.ondrag = null;
	document.documentElement.onselectstart = null;
	delClass(document.documentElement, "no-select");
}

