var js = {
	bind: function(node, type, listener) {
		if(node[0]){js.each(node, function(elem){js.bind(elem, type, listener)});return}
        if(node.addEventListener) node.addEventListener(type, listener, false);
        //@cc_on if(node.attachEvent)node.attachEvent('on' + type, function() { listener.call(node); });
    },
	init_: [],
    DOMready: function() {
        if(!arguments.callee.done) {
            arguments.callee.done = true;
            if(this.timer) clearInterval(this.timer);
            for(i in this.init_) this.init_[i]();
            this.init_ = [];
        }
    },
	ready:function(f){this.init_.push(f);},
    check: function() {
        var d = document, listener = function() {
            js.DOMready();
        };
        if(d.addEventListener) d.addEventListener('DOMContentLoaded', listener, false);
        if(/KHT|WebK/i.test(navigator.userAgent)) js.timer = setInterval(function(){
            if(/load|comp/.test(d.readyState)) js.DOMready();
        }, 10);
        /*@cc_on d.write(unescape('%3CSCRIPT onreadystatechange="if(this.readyState==\'complete\') js.DOMready()" defer=defer src=\/\/:%3E%3C/SCRIPT%3E')); @*/
        window.onload = listener;
    },
	coords:function(obj){		
		var l = 0, t = 0, ob = obj;
		while(ob)with(ob){
			l += offsetLeft;
			t += offsetTop;
			ob = offsetParent;
		}
		return {left:l, top:t, bottom: obj.offsetHeight + t, right: obj.offsetWidth + l};
	},
	onload: function(elem, listener){
		/*@cc_on js.bind(elem, 'readystatechange', function(){if(/loaded|complete/.test(this.readyState))listener()});return; @*/
		js.bind(elem, 'load', listener);
	},
	loadScript:function(source){
		var flag = (source instanceof Array), src = flag ? source[0] : source, d = document, script = d.createElement('script'), clbk = arguments[1];
		script.src = src;
		if(flag && source['length'] > 1){
			source.splice(0,1);
			js.onload(script, function(){js.loadScript(source, clbk)});
		}else if(clbk){
			js.onload(script, clbk);
		}
		d.getElementsByTagName('head')[0].appendChild(script);
	},
	each:function(data, func){
		for(i = 0; i<data.length; i++)func(data[i], i);return data;
	},
	assoc:function(data, func){
		for(i in data)if(data[i])func(data[i], i);return data;
	},
	map:function(data, func){
		js.each(data, function(v, i){data[i] = func(v, i)}); return data
	},
	parent:function(elem){
		var tag = arguments[1], a = [];
		if(elem.length && !(elem instanceof String)){
			js.each(elem, function(v, i){
				a.push(js.parent(v, tag))
			});
			return a
		}
		do{
			elem = elem.parentNode;
		}while(tag ? elem && tag.toUpperCase() != elem.tagName.toUpperCase() : false);
		return elem;
	},
	toggle:function(elem){
		if(!elem)return false;
		var disp = elem.style.display;
		disp = disp == 'none' ? 'block' : 'none';
		elem.style.display = disp;
		return disp;
	},
	validate:function(frm, setup){
		var errFunc = arguments[2] || function(e){for(i in e)alert(i+':'+e[i])}, errs = {}, cnt = 0, stop = arguments[3], deferr = arguments[4], ip = function(c){
			return '(?:|(?:[0-9]{1,2}|[01][0-9]{2}|2[0-4][0-9]|25[0-5])(?:\.(?:[0-9]{1,2}|[01][0-9]{2}|2[0-4][0-9]|25[0-5])){'+c+'})'
		}, host = "[a-zA-Z0-9]+[a-zA-Z0-9-_]+(?:\.[a-zA-Z0-9]+[a-zA-Z0-9-_]+)*";
		js.assoc(setup, function(val, name){
			var flag = val instanceof Array, rule = flag ? val[0] : val, msg = deferr || (name + " filled incorrect"), errMsg = flag ? val[1] || msg : msg, ind = arguments[2];
			if(/\[\]/.test(name) && !ind){
				for(i = 0; i<frm[name].length; i++)
					arguments.callee.call(null, val, name, i+1);
					return
				}
			if(cnt && stop)return;
			if(!({"string":function(src){
						return {
							'email': /^(?:|[A-Za-z][A-Za-z0-9\.-_]*@[A-Za-z0-9\.-_\/]*\.[a-zA-Z]+)$/,
							'zip': /^(?:|\d{5})$/,
							'phone': /^(?:|\+?(\d{3})\s+\((\d{3})\)\s+(\d{3})-(\d{2})-(\d{2}))$/,
							'date': /^(?:|\d{2}\.\d{2}\.\d{4}(?:|\s+\d{2}:\d{2}:\d{2}))$/,
							'number': /^\d*$/,
							'letters': /^[A-Za-zÀ-ßà-ÿ¸¨]*$/,
							'webstr': /^(?:|[A-Za-zÀ-ßà-ÿ¸¨]+[A-Za-zÀ-ßà-ÿ0-9¸¨\._-]*)$/,
							'string': /^(?:|[A-Za-zÀ-ßà-ÿ0-9¸¨\._-]*)$/,
							'url': /^(?:|(\w+:\/\/|)([^\/:]+)(:\d*)?([^# ]*))$/,
							'ip': new RegExp('^'+ip(3)+'$'),
							'ipv6': new RegExp('^'+ip(3)+'$'),
							'host': new RegExp('^'+host+'$'),
							'server': new RegExp('^(?:'+host+'|'+ip(3)+')$'),
							'other': /.*/
						}[/email|zip|phone|date|number|letters|webstr|url|ip|ipv6|host|server|string/.exec(rule) || 'other'].test(src) && (/required/.test(rule) ? src : true) && ((/\d+/.exec(rule) || Infinity) >= src.length);
					},
					"function":rule,
					"object":function(src){return rule.test(src)}
				}[typeof rule])((ind ? frm[name][ind-1]:frm[name]).value)){ind ? ((errs[name] ? void(0):errs[name] = {}), errs[name][ind-1] = errMsg) : errs[name] = errMsg; cnt++}
		});
		if(cnt)errFunc(errs);
		return (cnt == 0);
	},
	json:function(data){return eval('('+data+')');},
	index:function(arr, elem){
		var i = -1;
		for(j = 0; j<arr.length; j++)
			if(arr[j] == elem)i = j;
		return i;
	},
	remove:function(elem){
		if(elem instanceof Array){
			js.each(elem, function(src){js.remove(src)});
			return
		}
		js.parent(elem).removeChild(elem);
	},
	create:function(tg, html){
		var el = document.createElement(tg);
		el.innerHTML = html;
		return el
	},
	htmldecode:function(text){
		js.assoc({"&":"&amp;", "<":"&lt;", ">":"&gt;", '"':"&quot;", " ":"&nbsp;", "©":"&copy;", "«":"&laquo;", "»":"&raquo;"}, function(val, name){
			text = text.replace(new RegExp(val, 'gi'), name)
		});
		return text;
	},
	clientSize:function(){
		var d = document;
		with(/CSS1/.test(d.compatMode) && !window.opera? d.documentElement : d.body)
			return {width:clientWidth, height:clientHeight}
	},
	pageSize:function(){
		with(document.body)
			return {
				width:Math.max(scrollWidth, offsetWidth),
				height:Math.max(scrollHeight, offsetHeight)
			}
	},
	scroll:function(){
		var d = document, db = d.body, de = d.documentElement, s = self;
		return {
			x:db?db.scrollLeft:s.pageXOffset || de.scrollLeft,
			y:db?db.scrollTop:s.pageYOffset || de.scrollTop
		}
	},
	center:function(){
		var scr = js.scroll(), cl = js.clientSize();
		return {x:scr.x + cl.width/2, y:scr.y + cl.height/2}
	}
};

js.assoc({next:'next', prev:'previous'}, function(val, ntn){
	js[ntn] = function(elem){
		var tag = arguments[1], flag = false;
		do{
			elem = elem[val+'Sibling'];
			flag = (tag ? tag.toUpperCase() != (elem['tagName'] || '').toUpperCase() : false);
		}while ((elem && elem.nodeType != 1) && flag);
		return (!flag) ? elem : false;
	};
});

js.assoc({show:'block', hide:'none'}, function(val, n){js[n] = function(d){d.style.display = val; return val}});

var ajax = {
	xhr:function(){
		try{return new XMLHttpRequest() || new ActiveXObject('Microsoft.XMLHTTP')}
		catch(e)
		{
			try {return new ActiveXObject('Msxml2.XMLHTTP')}
			catch(e){return null}
		}
	},
	query:function(url, ok){
		var req = this.xhr(), a = arguments, c_err = a[2] || function(){}, data = a[3], mtd = a[4]||(data?'POST':'GET');
		req.onreadystatechange =function(){
			if(req.readyState == 4 && ok)(/200|304/.test(req.status)?ok:c_err)(req);
		};
		req.open(mtd, url, true);
		if(mtd=='POST')req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
		req.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
		req.setRequestHeader("If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT");
		req.send(data);
	},
	load:function(url, elem){
		this.query(url, 
			function(req){elem.innerHTML = req.responseText}, 
			arguments[2],arguments[3]);
	},
	sendForm:function(frm, ok){
		var data = [];
		js.each(frm.elements, function(x){
			if(!(/check|file/.test(x.type) && !(x.checked)))data.push(x.name+'='+encodeURIComponent(x.value))
		});
		this.query(frm.action, ok, arguments[2], data.join('&'), frm.method.toUpperCase());
	},
	json:function(url, ok){
		this.query(url,
			function(req){ok(req, eval('('+req.responseText+')'))},
			arguments[2]);
	}
};
for(i in{'post':'','get':''})ajax[i] = function(url, data, ok){this.query(url, ok, arguments[3], data, i.toUpperCase())}

try{js.check()}catch(e){}
