function $include(file) {
	document.write('<script language="javascript" type="text/javascript" src="' + file + '"></script>');
}

function $css(file) {
	document.write('<link rel="stylesheet" type="text/css" href="' + file + '" />');
}

Function.empty = function () {};

var $Element = {
	Methods: {}
}

function $extend () {
	var args = arguments;
	if (!args[1]) {
		args = [this, args[0]];
	}
	for (var property in args[1]) {
		args[0][property] = args[1][property];
	}
	return args[0];
}

function $extendML () {
	var args = arguments;
	if (!args[1]) {
		args = [this, args[0]];
	}
	for (var prop in args[1]) {
		if (typeof args[1][prop] == "object") {
			if (!args[0][prop]) { args[0][prop] = {}; }
			$extendML(args[0][prop], args[1][prop]);
		} else {
			args[0][prop] = args[1][prop];
		}
	}
	return args[0];
}

function $() {
	if (arguments.length == 0)
		return false;
	var el = gEBI(arguments[0]);
	var i = 1;
	while (i < arguments.length) {
		if (arguments[i] == "parent") {
			el = el.parentNode;
			i++;
		} else if ((i + 1) == arguments.length) {
			return gEBTN(el, arguments[i++]);
		} else {
			el = gEBTN(el, arguments[i++], arguments[i++]);
		}
	}
	return $Element.update(el);
}

function gEBI(el) {
	if (typeof el == 'string')
		return document.getElementById(el);
	else
		return el;
}

function gEBTN () {
	if (arguments.length < 2) {
		return false;
	} else if (arguments.length == 2) {
		var els = [];
		var childs = gEBI(arguments[0]).childNodes;
		var mask = arguments[1].toUpperCase();
		for (var i = 0; i < childs.length; i++) {
			if (mask == "*") {
				if (childs[i].nodeType == 1) {
					els.push($Element.update(childs[i]));
				}
			} else if (mask == childs[i].nodeName) {
				els.push($Element.update(childs[i]));
			}
		}
		return els;
	} else {
		var childs = gEBI(arguments[0]).childNodes;
		var mask = arguments[1].toUpperCase();
		var num = arguments[2];
		var j = -1;
		for (var i = 0; i < childs.length; i++)
		{
			if (mask == "*") {
				if (childs[i].NodeType == 1) {
					j++;
				}
			} else if (mask == childs[i].nodeName) {
				j++;
			}
			if (j == num) {
				return childs[i];
			}
		}
	}
}

function $c() {
	if (arguments.length == 0)
		return false;
	var el = document.createElement(arguments[0]);
	if (arguments.length > 1) {
		var i, opts = arguments[1];
		$extendML(el, opts);
	}
	if (arguments.length > 2)
		el.innerHTML = arguments[2];
	return $Element.update(el);
}

function $isdef(a) { return !(typeof a == "undefined"); }

var $browser = new function() {
	this.dom = (document.getElementById ? true : false);
	this.opera = (window.opera ? true : false);
	this.webkit = (document.childNodes && !document.all && !navigator.taintEnabled);
	this.mac = (window.xpath ? true : false);
	this.gecko = (document.getBoxObjectFor != null);
	this.ie = (window.ActiveXObject ? true : false);
	this.ie7 = (this.ie && (window.XMLHttpRequest ? true : false));
	this.ie6 = (this.ie && !this.ie7)
}();

var $ajax = {
	init: function () {
			var res;
			try {
				if ($browser.ie) {
					if ($browser.ver >= 6) {
						res = new ActiveXObject("Microsoft.XMLHTTP");
					} else {
						res = new ActiveXObject("Msxml2.XMLHTTP");
					}
				} else {
					res = new XMLHttpRequest();
				}
			} catch (e) {
				return null;
			}
			return res;
		},
	request: function (obj) {
			try {
				if (typeof obj == "undefined")
					return;
				var url = obj.url ? obj.url : '';
				var req = $ajax.init();
				var data = obj.data ? $ajax.buildData(obj.data) : null;
				if (obj.onSuccess) {
					req.onreadystatechange = function () {
						if (req.readyState == 4) {
							if (req.status == 200) {
								obj.onSuccess($ajax.parseRespond($ajax.ruDecode(req.responseText)), req.responseText);
							}
						}
					}
				}
				var urlCache = '';
				var cache = typeof obj.cache != "undefined" ? obj.cache : false;
				if (!cache)
					url += (url.indexOf('?') == -1 ? '?' : '&') + 'rTime=' + $time();
				var method = obj.method ? obj.method.toUpperCase() : "POST";
				if (method == "GET") {
					url += (url.indexOf('?') == -1 ? '?' : '&') + data;
					data = null;
				}
				req.open(method, url, true);
				req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
				req.setRequestHeader("Content-length", data == null ? 0 : data.length);
				req.setRequestHeader("Connection", "close");
				req.send(data);
			} catch (e) { }
		},
	buildData: function (data) {
			var res = '';
			for (var k in data) {
				if (res.length > 0)
					res += '&';
				res += encodeURI(k) + '=' + encodeURI(data[k]);
			}
			return res;
		},
	parseRespond: function (a) {
			try {
				return (Function("return" + a))()
			} catch(e) {
				return null;
			}
		},
	ruDecode: function (a) {
			var tmp;
			var res = "";
			for (var i = 0; i < a.length; i++) {
				if (a.charAt(i) == '|')
				{
					tmp = a.charAt(++i);
					if (tmp == 'a')
						res += '¨';
					else if (tmp == 'b')
						res += '¸';
					else if (tmp == 'c')
						res += '|';
					else
						res += String.fromCharCode(tmp.charCodeAt(0) + 1007);
				}
				else
					res += a.charAt(i);
			}
			return res;
		},
	formRequest: function () {
			if (arguments.length == 0)
				return;
			var form = arguments[0];
			var id = 'ifrm' + $time('z');
			document.body.appendChild($c( 'div', {}, '<iframe style="display: none" src="about:blank" id="' + id + '" name="' + id + '" onload="loaded(\'' + id + '\');"></iframe>' ));
			var ifrm = $(id);
			form.target = id;
			if (arguments.length > 1)
			{
				var onsucc = arguments[1];
				ifrm.onload = function() {
					var ifrmdoc = window.frames[id].document;
					if (ifrmdoc.location.href != "about:blank") {
						onsucc($ajax.parseRespond($ajax.ruDecode(ifrmdoc.body.innerHTML)));
					}
				}
			}
			form.submit();
		}
}

function $time() {
	var sep = '.';
	if (arguments.length > 0)
		sep = arguments[0];
	var date = new Date();
	return date.getFullYear() + sep
		+ date.getMonth() + sep
		+ date.getDate() + sep
		+ date.getHours() + sep
		+ date.getMinutes() + sep
		+ date.getSeconds() + sep
		+ date.getMilliseconds();
}

function $uts() {
	var date = new Date();
	return date.getTime();
}

var $effect = {
	tick: 30, //($browser.ie ? 100 : 30),
	list: [],
	type: function (x) { return Math.sin((x - 0.5) * Math.PI) * 0.5 + 0.5; },
	create: function(f, t) {
		var id = $effect.list.length;
		var uts = $uts();
		if (arguments.length > 1) {
			return $effect.createComplex(id, f, false, uts, uts + t);
		}
		return $effect.createInterval(id, f, uts);
	},
	createComplex: function(id, f, r, sT, eT) {
		$effect.list[id] = {
			startTime: sT,
			endTime: eT,
			durTime: eT - sT,
			reversed: r,
			func: f,
			interval: function() {
				var uts = $uts();
				if ((uts  - sT) / (eT - sT) >= 1) {
					f(r ? 0 : 1);
					$effect.destroy(id);
				} else {
					f($effect.type(r ? 1 - (uts  - sT) / (eT - sT) : (uts  - sT) / (eT - sT)));
				}
			}
		}
		$effect.list[id].proc = setInterval($effect.list[id].interval, $effect.tick);
		return id;
	},
	createInterval: function(id, f, sT) {
		$effect.list[id] = {
			startTime: sT,
			lastTick: sT,
			func: f,
			interval: function() {
				var uts = $uts()
				f(uts - $effect.list[id].lastTick);
				$effect.list[id].lastTick = uts;
			}
		}
		$effect.list[id].proc = setInterval($effect.list[id].interval, $effect.tick);
	},
	reverse: function(id) {
		if ($effect.list[id].proc == false) {
			var uts = $uts();
			with ($effect.list[id]) {
				return $effect.createComplex(id, func, !reversed, uts, uts + durTime);
			}
		} else {
			$effect.destroy(id);
			var uts = $uts();
			with ($effect.list[id]) {
				return $effect.createComplex(id, func, !reversed, 2 * uts - endTime, 2 * uts - startTime);
			}
		}
	},
	pause: function(id) {
	},
	destroy: function(id) {
		clearInterval($effect.list[id].proc);
		$effect.list[id].proc = false;
	}
}

$extend(Math, {
	HEX: {0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9, 'a': 10, 'b': 11, 'c': 12, 'd': 13, 'e': 14, 'f': 15},
	DEC: ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'],
	hex2dec: function (str) {
		str = str.toLowerCase();
		var x = 0;
		var p = 1;
		for (var i = str.length - 1; i >= 0; i--) {
			x += Math.HEX[str.charAt(i)] * p;
			p *= 16;
		}
		return x;
	},
	dec2hex: function (x) {
		if (x <= 0)
			return '0';
		var str = '';
		while (x > 0) {
			str = Math.DEC[x % 16] + str;
			x = Math.floor(x / 16);
		}
		return str;
	}
});

var $color = {
	toRGB: function(str) {
		if (str.charAt(0) == "#") {
			str = str.slice(1);
		}
		var r, g, b;
		if (str.length == 3) {
			r = Math.hex2dec(str.charAt(0) + str.charAt(0));
			g = Math.hex2dec(str.charAt(1) + str.charAt(1));
			b = Math.hex2dec(str.charAt(2) + str.charAt(2));
		} else {
			r = Math.hex2dec(str.slice(0, 2));
			g = Math.hex2dec(str.slice(2, 4));
			b = Math.hex2dec(str.slice(4, 6));
		}
		return {'r': r, 'g': g, 'b': b};
	},
	toHEX: function(rgb) {
		if (arguments.length == 3) {
			rgb = this.RGB(arguments[0], arguments[1], arguments[2]);
		}
		var hr = Math.dec2hex(rgb.r), hg = Math.dec2hex(rgb.g), hb = Math.dec2hex(rgb.b)
		return '#' + (hr.length == 1 ? '0' : '') + hr + (hg.length == 1 ? '0' : '') + hg + (hb.length == 1 ? '0' : '') + hb;
	},
	RGB: function(r, g, b) {
		return {'r': r, 'g': g, 'b': b};
	},
	gradient: function(from, to, pos) {
		if (typeof from == "string" ) {
			from = $color.toRGB(from);
		}
		if (typeof to == "string" ) {
			to = $color.toRGB(to);
		}
		return {
			'r': Math.round(from.r + (to.r - from.r) * pos),
			'g': Math.round(from.g + (to.g - from.g) * pos),
			'b': Math.round(from.b + (to.b - from.b) * pos)
		};
	}
}

$extend($Element.Methods, {
	setOpacity: $browser.ie ? function (alpha) { this.style.filter = 'Alpha(Opacity=' + (alpha * 100) + ')'; } : function (alpha) { this.style.opacity = alpha; },
	addEffect: function (func, t) {
		var id;
		var obj = this
		if (typeof func == "function") {
			id = $effect.create(function(t) { func.apply(obj, [t]); } , t);
			this.idEffect = id;
			this.removeEffect = function () { $effect.destroy(id); }
			this.reverseEffect = function () { $effect.reverse(id); }
			this.isEffect = function() { return ($effect.list[id].interval != false); }
			return id;
		}
		if (typeof func == "string") {
			switch(func) {
				case "param": {
					var param = arguments[2], from = arguments[3], to = arguments[4], hz = arguments[5];
					return $Element.Methods.addEffect.apply(obj, [function(t) { this.style[param] = (from + (to - from) * t) + hz; }, t ]);
				}
				case ("height" || "width" || "left" || "right" || "top" || "bottom"): {
					if (arguments.length > 3) {
						var param = arguments[0], from = arguments[2], to = arguments[3], hz = "px";
						return $Element.Methods.addEffect.apply(this, ["param", t, param, from, to, hz]);
					} else {
						var param = arguments[0], from = parseInt(this.style[param]), to = arguments[2], hz = "px";
						return $Element.Methods.addEffect.apply(this, ["param", t, param, from, to, hz]);
					}
				}
			}
		}
	},
	replaceEffect: function () {
		if (this.isEffect) {
			this.removeEffect();
		}
		return $Element.Methods.addEffect.apply(this, arguments);
	},
	remove: function () {
		this.parentNode.removeChild(this);
	},
	appendChildFirst: function(e) {
		if (this.childNodes.length == 0) {
			this.appendChild(e)
		} else {
			this.insertBefore(e, this.childNodes[0]);
		}
	},
	getSize: function() {
		return {
			'scroll': {'x': this.scrollLeft, 'y': this.scrollTop},
			'size': {'x': this.offsetWidth, 'y': this.offsetHeight},
			'scrollSize': {'x': this.scrollWidth, 'y': this.scrollHeight},
			'offset': {'x': this.offsetLeft, 'y': this.offsetTop}
		};
	}
});

$Element.MethodsByTag = {};

$Element.MethodsByTag["select"] = {
	appendOption: function (opt, value) { this.appendChild(typeof opt == "object" ? opt : $c("option", {"value": value}, opt)); },
	clearOptions: function () { this.innerHTML = ''; },
	selectOption: ($browser.opera ? function(i) { var obj = this; setTimeout( function () { obj.selectedIndex = i; }, 0); } : function(i) { this.selectedIndex = i; })
};

$Element.update = function (el) {
	if (el.$updated) {
		return el;
	}
	for (i in $Element.Methods) {
		el[i] = methodize(el, $Element.Methods[i]);
	}
	var tag = el.nodeName.toLowerCase();
	if ($isdef($Element.MethodsByTag[tag])) {
		for (i in $Element.MethodsByTag[tag]) {
			el[i] = methodize(el, $Element.MethodsByTag[tag][i]);
		}
	}
	el.$updated = true;
	return el;
}

function methodize(el, f) {
	return function() { return f.apply(el, arguments); }
}

function $event(e) {
	var res = {};
	if (!$isdef(e)) {
		e = window.event;
	} else if (e.updatedEvent) {
		return e;
	}
	$extend(res, e);
	if (e.srcElement) { res.target = e.srcElement; }
	if (e.relatedTarget) { res.toElement = e.relatedTarget; }
	if (e.which) { res.keyCode = e.which; }
	res.updatedEvent = true;
	return res;
}