var U; 
var UTIL = U = new function() {
	var t=this;
	t.D = t.def = function(e) { return (typeof(e) != 'undefined'); }
	t.Try = function() { for (var fn,i = 0; ( fn = arguments[i] ); i++) try { return fn(); } catch(e) { } }
	
	t.forEach = function(a, fn, o) { for (var l=a.length,i = 0; i<l; i++) (o) ? fn.call(o, a[i]) : fn(a[i]); }
	t.from = function(a, f, fn, o) { for (var l=a.length,i = f; i<l; i++) (o) ? fn.call(o, a[i]) : fn(a[i]); }
	t.indexOf = function(a, v, f) { for (var i = (U.D(f)) ? f : 0,l = a.length; i < l; i++) if (a[i] == v) return i; return -1; }
	t.lastIndexOf = function(a, v, f) { for (var i = Math.min((U.D(f)) ? f : a.length, a.length - 1); i >= 0; i--) if (a[i] == v) return i; return -1;}
	t.every = function(a, fn, o) { for (var l=a.length,i = 0; i < l; i++) if ( !((o) ? fn.call(o, a[i]) : fn(a[i]) )) return false; return true; }
	t.some = function(a, fn, o) { for (var l=a.length,i = 0; i < l; i++) if ( (o) ? fn.call(o, a[i]) : fn(a[i]) ) return true; return false; }
	t.filter = function(a, fn, o) { for (var r = [],l=a.length,i = 0; i < l; i++) if ( (o) ? fn.call(o, a[i]) : fn(a[i]) ) r.push(a[i]); return r;	}
	t.map = function(a, fn, o) { for (var r = [],l=a.length,i = 0; i < l; i++) r.push ( (o) ? fn.call(o, a[i]) : fn(a[i]) ); return r; }
	t.contains = function(a, v) { return (U.indexOf(a, v) > -1); },
	t._bind = function(o, k, fn) { if (!o.prototype[k]) o.prototype[k] = function(b,c, d) { return fn(this, b, c, d) } }
	t.deleteItem = function(a, v) { var i; while ((i = a.indexOf(v)) >= 0) a.splice(i, 1); }
	t.swapItems = function(a, i, j) { var e = a[i]; a[i] = a[j]; a[j] = e; };
	t.moveItems = function(a, i, j, l) { l = l || 1; if (j > i) j -= l; var r = a.splice(i, l); r.unshift(j, 0); a.splice.apply(a, r); }
	t.copy = function(o) { var key,r = { }; for (key in o) r[key] = o[key]; return r; }
	t.shallow = function(a) { var i=a.length-1,r = []; if (i>=0) do { r.unshift(a[i]) } while (i--); return r; }
	
	t.forEach(['moveItems','deleteItem','forEach','from','indexOf','lastIndexOf','every','some','filter','map','contains'], function(k) {t._bind(Array, k, t[k]); });

	t.copy = function(o) {
		var result, k;
		
		if (U.isArray(o)) { result = [ ]; o.forEach(function(e) { result.push(U.copy(e)) }); }
		else if (U.isObject(o)) { result = { }; for (k in o) { result[k] = U.copy(o[k]); }; }
		else result = o;
	
		return result;
	}
	
	t.multiSplit = function(s) {
		if (!arguments[1]) return s;
		var a = s.split(arguments[1]);
		var e,i,d = [ '' ], r = [];
		for (i=2,e;(e=arguments[i]);i++) d.push(e);
		for (i=0;(i<a.length);i++) { 
			d[0] = a[i];
			r.push(t.multiSplit.apply(this, d));
		}
		return r;
	}
	
	t.isFunction = function(a) { return (typeof(a) == 'function'); }
	t.isObject = function(a) { return (a && typeof(a) == 'object') || U.isFunction(a); }
	t.isAlien = function(a) { return U.isObject(a) && typeof(a.constructor) != 'function'; }
	t.isArray = function(a) { return U.isObject(a) && a.constructor == Array; }

	t.FN = function(o, fn) { 
		for (var args=[], i=2, len=arguments.length; i<len; i++) args.push(arguments[i]);
		return function() { if (fn) return fn.apply(o, args);  }
	};
	
	t.entityEncoder1 = /%([0-9a-fA-F][0-9a-fA-F])/g;
	t.entityEncoder2 = /%u([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F])/g;
	t.entityDecoder1 = /&\#x([0-9a-fA-F][0-9a-fA-F][0-9a-fA-F][0-9a-fA-F]);/g;
	t.entityDecoder2 = /&\#x([0-9a-fA-F][0-9a-fA-F]);/g;
	t.encodeEntities = function(str) { str = str.toString(); return escape(str).replace(/%20/g, ' ').replace(t.entityEncoder2, '&\#x$1;').replace(t.entityEncoder1, '&\#x$1;');	}
	t.decodeEntities = function(str) { str = str.toString(); return unescape(str.replace(t.entityDecoder1, '%u$1').replace(t.entityDecoder2, '%$1')); }
	t.fromEntities = function(s) {  var t=document.createElement("textarea"); t.innerHTML=s.replace(/</g,"&lt;").replace(/>/g,"&gt;"); return t.value; }
	
	t.toInt = function(val, d) { d=d||0; val = parseInt(val, 10); return (isNaN(val))?d:val; }
	
	t.compare = function(s1, s2) { var key; for (key in s1) if (s1[key]!=s2[key]) return false; return true; }
	
	t.structMerge = function(e) {
		for (var key,i=1,e1;(e1=arguments[i]); i++) {
			for (key in e1) e[key] = U.D(e[key])?e[key]:e1[key];
		}
		return e;
	}
	t.toInt = function(i) {
		var r,type=typeof(i);
		switch(type) {
			case 'number'	: return Math.round(i);
			case 'string'	: return (isNaN(r=parseInt(i,10))?0:r);
		}
		return 0;
	}
	t.max = function(n) { for (var i=1;i<arguments.length;i++) n=Math.max(n,arguments[i]); return n; }
	
	t.colour = function(c) { c = c.toString(); while (c.length<6) c='0'+c; return c; }
}

var DOM = new function() {
	
	this.__trash = [ ];
	
	this.get = function(e) {
		if(typeof(e)!='string') return e;
		return U.Try(function() { return document.getElementById(e); }, function() { return document.all[e]; }, function() { return null; } );
	}
	
	this.structure = function(s, top, h) {
		if (U.isFunction(s)) return s();
		s.t = s.t || 'div';
		var key, item, index, ele = (s.f) ? s.f() : document.createElement(s.t);
		top = top || ele;
		
		if (h) h.appendChild(ele);
		
		if (s.r) top[s.r] = ele;
		if (s.a) for (key in s.a) ele.setAttribute(key, s.a[key]);
		if (s.e) { ele.ooCleanupQ = []; for (key in s.e) { ele.ooCleanupQ.push[key]; ele[key] = s.e[key]; } }
		if (U.D(s.x)) ele.appendChild(document.createTextNode(s.x));
		if (s.s) s.s.forEach(function(item) { ele.appendChild (DOM.structure(item, top)); }, this);
		if (s.sl) s.sl.forEach(function(item) { ele.appendChild (DOM.structure({ cn: item }, top)); }, this);
		if (s.y) for (key in s.y) ele.style[key] = s.y[key];
		if (s.tr) s[key] = top;
		if (s.d) DHTML.sizeTo(ele, s.d[0],s.d[1]);
		if (U.D(s.W)) DHTML.setWidth(ele, s.W);
		if (U.D(s.H)) DHTML.setHeight(ele, s.H);
		if (U.D(s.X)) DHTML.divX(ele, s.X);
		if (U.D(s.Y)) DHTML.divY(ele, s.Y);
		if (s.cn) ele.className = s.cn;
		if (U.D(s.id)) ele.id = s.id;
		if (s.c) { DHTML.bind.apply(DHTML, [ ele ].concat(s.c)); }			
		
		for (key in s) if (key.charAt(0)=='_') ele[key.substring(1)]=s[key];

		return ele;
	}

	this.div = function(cn, html, id, t) {
		t = t || 'div';
		var r = document.createElement(t);
		
		r.className = cn;
		if (id) r.id = id;
		if (html) r.innerHTML = html;
		
		return r;
	}
	
	this.getElements = function() { var result={}; U.forEach(arguments, function(a) { result[a] = DOM.get(a); } ); return result; },

	this.parentOf = function(o, p) {
		if (U.isArray(p)) return p.some(function(e) { return DOM.parentOf(o, e); });

		var parent = o;
		if (p == o) return true;
		
		while (parent = parent.parentNode) {
			if (p == parent) return true;
		}
		
		return false;
	}
	
	this.trash = function() {
		for (var i=0;i<arguments.length;i++) DOM.__trash.push(arguments[i]);
	}
	
	this.emptyTrash = function() {
		var e;
		if (!this.trashEle) this.trashEle = DOM.structure({ y: { top: '-100px', position: 'absolute', height: '1px', display: 'none' }, e: { stat: 'trashNode' } });
		
		while (this.__trash.length) {
			e=this.__trash.pop();
			if (e) {
				if (e.ooState=='active') OO.dispose(e);
				e.innerHTML = '';
				this.trashEle.appendChild(e);
			}
		}
		this.trashEle.innerHTML = '';

	}
}

AJAX = new function() {
	this.ajaxBase = '/_ajax';
	this.handlerURL = this.ajaxBase+'/core.cfm';
	this.popupURL = this.ajaxBase+'/popup.cfm';
	this.debugMode = true;
	this.queue = [ ];
	this._XHRS = {};
	this.reportWindow = null;
	this.xhrID = 1;
	this.responseId = 1;
	this._Complete = [];
	this.rTimeoutT = 15000;
	
	this.create = function(owner, handler) {
		return OO.create(AJAX.Request, owner, handler);
	}
	
	this.getXHR = function(type) {
		return AJAX.XMLHTTP();
		if (!this._XHRS[type]) this._XHRS[type] = AJAX.XMLHTTP();
		return this._XHRS[type];
	}
	
	this.XMLHTTP = (window.XMLHttpRequest) ? function() { return new XMLHttpRequest(); } : function() { try { return new ActiveXObject("Msxml2.XMLHTTP"); } catch(e) { return new ActiveXObject("Microsoft.XMLHTTP"); } }
	
	this.prepareSend = function(owner, action, params, timeout, alertFn) {
		if (!this.busy) { this.busy = true; return true; }
		this.queue.push({ sendType: 'ajax', owner: owner, action: action, params: params, timeout: timeout, alertFn: alertFn });

		return false;
	}
	
	this.preparePreload = function(owner, file, type, message, params) {
		if (!this.busy) { this.busy = true; return true; }
		this.queue.push({ sendType: 'preload', owner: owner, file: file, params: params, message: message, type: type });

		return false;
	}
	
	this.releaseSend = function() {
		var next = this.queue.shift();

		this.busy = false;
		if (next) switch (next.sendType) {
			case 'ajax'		:	next.owner.send(next.action, next.params, next.timeout, next.alertFn); break;
			case 'preload'	:	next.owner.preload(next.file, next.type, next.message, next.params); break;
		}
	}
	
	this.encodeParams = function(p) {
		var k,r = '',d='';
		for (k in p) {
			r += d+k+'='+escape(p[k]);
			d='&';
		}
		
		return r;
	}
	this.blankFN = function() {}
}

AJAX.xhr = function() {
	this.inherit(OO.Timer);
}
AJAX.xhr.prototype = { 
	initSelf: function(type) {
		this.XHR = AJAX.getXHR(type);
		this.busy = false;
		this.sbt = (new Date()).getTime();
		this.id = AJAX.xhrID++;
		this.responseId = 0;
	},
	
	setCallback: function(caller, fn) {
		this.caller = caller;
		this.callbackFN = fn;
	},
	
	send: function(url, params, async, extra, discardResponse) {
		var ps = '', d='';
		var OT = this;
		var action = 'none';
		var rId = AJAX.responseId++;
		var rsFN = 0;
		var t = new Date().getTime();
		
		if (params) {
			params._SBT = this.sbt;
			params._RQID = this.id;
			params._RSPNSID = rId;
			params._CMPLT = JSON.stringify(AJAX._Complete);
			action = params.action;
			ps = AJAX.encodeParams(params);
		}
		AJAX._Complete = [];

		this.handled = false;
		this._sentTimeoutMsg = false;

		rsFN = function() { if (OT.XHR.readyState==4) OT.returnCall(); };
		this._P = { url: url, ps: ps, rId: rId, action: action, rsFN: rsFN, discardResponse: discardResponse, extra: extra, params: params, t: t }
		
		this._chunkNo = 0;
		this.rawSend(url, ps, rsFN);
		
		this._action = action;
		this._chunkResponse = '';
		
		this.retryTime=4000;
		if (params) this.setTimeout('retryFN', this.retryTime, this.retryFN, false, 'Retry');
		if (!this.noTimeout) if (params) this.setTimeout('requestTimeoutFN', AJAX.rTimeoutT, this.requestTimeoutFN, 1, 0);
		
		this.busy = true;
		
		return true;
	},
	
	rawSend: function(url, ps, rsFN) {
		var xhr = this.XHR;
		
		this.XHR.open('POST', url, true);
		this.XHR.onreadystatechange = rsFN;
		this.XHR.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
		this.XHR.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
		this.XHR.setRequestHeader('Accept', 'application/json, text/javascript, text/plain, text/html, text/javascript, application/javascript');
		this.XHR.send(ps);
	},
	
	retryFN: function(noAbort, type, chunkNo) {
		chunkNo=chunkNo||0;
		if (this._P.rId<=this.completedId) { return; }
		this.ignoreResponse = true;
		if (!noAbort) {
			this.XHR.onreadystatechange = AJAX.blankFN;
			this.XHR.abort();
		}
		this.ignoreResponse = false;
			
		this.rawSend(this._P.url, this._P.ps+'&_RTRY=1&_CHNK='+this._chunkNo, this._P.rsFN);
		this.setTimeout('retryFN', this.retryTime, this.retryFN, false, 'Retry', chunkNo);
		this.retryTime+=3000;
	},
	
	
	sendFN: function(ps, params, extra, discardResponse, url, responseId) {
		this.XHR.send(ps);
		this.returnCall(params, extra, discardResponse, url, responseId)
	},
	
	returnCall: function() {
		var responseText,status = this.XHR.status,chunk,current,count;
		var t = new Date().getTime();
		
		try { var queue = AJAX.queue; } catch(e) { this.clearTimeout('retryFN'); return; }
		
		if (this.ignoreResponse) return;
		if (!this._P.discardResponse) responseText = this.XHR.responseText;
		if (responseText=='<<REJECT>>') { AJAX.log('Reject', this.id, this._P.rId, this._P.action); return; }
		this.clearTimeout('retryFN');
		if (responseText&&(responseText.indexOf('<<CHUNK')>=0)) {
			chunk = responseText.substr(0, 18).split(':');
			current = parseInt(chunk[1], 10);
			count = parseInt(chunk[2], 10);
			if (current>this._chunkNo)
				this._chunkResponse+=responseText.substr(18);
			
			if (current < count) {
				this._chunkNo++;
				this.clearTimeout('retryFN');
				this.retryFN(true, 'chunk', this._chunkNo);
				this.retryTime-=3000;
				return;
			} else {
				responseText = this._chunkResponse;
			}
		}
		AJAX._Complete.push({ i:this.id,r:this._P.rId,t:t });
		this.clearTimeout('requestTimeoutFN'); 
		
		if (this._P.rId<=this.completedId) { return; }
		this.completedId = this._P.rId;

		this.busy = false;
		this.handled = true;
		if (!this.sendResponse(this.caller, this.callbackFN, status, responseText, this._P.params, this._P.extra, this._P.url, this._P.rId));
	},
	
	sendResponse: function(caller, fn, status, responseText, params, extra, url, responseId) { 
		if (caller&&fn) fn.call(caller, status, responseText, params, extra, url, responseId);
		else if (fn) fn(status, responseText, params, extra, url, responseId);
	},
	
	disposeSelf: function() {
		this.XHR.onreadystatechange = function() {};
		this.XHR = null;
	}
}
AJAX.Request = function() {
	this.inherit(OO.Broadcaster);
	this.inherit(OO.Timer);
}
AJAX.Request.prototype = { 
	initSelf: function(owner, handler) {
		this.addListener(owner);
		this.handler = handler;
		this.syncXHR = OO.create(AJAX.xhr, 'sync');
		this.asyncXHR = OO.create(AJAX.xhr, 'async');
		this.preloadXHR = OO.create(AJAX.xhr, 'preload');
		
		this.syncXHR.setCallback(this, this.syncResponseFN);
		this.preloadXHR.setCallback(this, this.preloadResponseFN);
	},
		
	setHandler: function(handler) {
		this.handler = handler;
	},
	
	send: function(action, params, timeout, alertFn, errorMess) {
		var divider = '';

		if (!AJAX.prepareSend(this, action, params, timeout, alertFn)) {
			return;
		}
		params = params || {  };
		params = { handler: this.handler, action: action, data: encodeURIComponent(JSON.stringify(params)), SBSID: window.$SBSID };
		this.syncXHR.send(AJAX.handlerURL, params, true, { alertFn: alertFn, errorMess: errorMess });
	},
	
	preload: function(file, type, message, params) {
		var oThis = this;
		
		if (!AJAX.preparePreload(this, file, type, message, params)) return;
		
		this.preloadXHR.send(file, params, true, { type: type, message: message }, true);
		return;
	},
	
	sendAsync: function(action, params) {
		params = params || {  };
		params = { handler: this.handler, action: action, data: encodeURIComponent(JSON.stringify(params)), SBSID: window.$SBSID };
		
		this.asyncXHR.send(AJAX.handlerURL, params, true);
	},
	
	preloadResponseFN: function(status, r, p, e) {
		CM.delayedMessage(10, e.type, e.message, p);
		AJAX.releaseSend();
	},
	
	handleTimeout: function(action) {
		this.sendMessage('ajaxTimeout', action);
		AJAX.releaseSend();
	},
	
	syncResponseFN: function(status, response, p, e, url, reponseId) {
		var ok,data,t=this;
		var fn = function(item) { this._HM.t=item.type;this._HM.m=item.message; this.sendMessage(item.message, item.data);  }
		
		this._HM = { };
		
		if (status==200) {
			try {
				data = response.replace(/^[\n\r]+/, '');
				eval('data='+data);
				ok = true;
			} catch(e) {  }
		}
		
		if (ok) {
			data.data.messagequeue.forEach(fn, this);
		} else {
			if (mess = e.errorMess) {
				this.sendMessage(mess.message, mess.params);
			} else {
				this.sendMessage('ajaxFail'); 
				this.failureReport(url, response, p.data, p.action, p.handler, p._RQID, p._RSPNSID); 
			}
		}
		this.releaseSend();
		return;
	},
	
	releaseSend: function() { AJAX.releaseSend(); },
	
	defaultErrorHandler: function(error) {
		var errorText = error.getAttribute('errorText');
		alert('AJAX ERROR: \n' + errorText);
	},

	failureReport: function(url, responseText, data, action, handler, rId, responseId) {
		var d = new Date();
		var oThis = this;
		var newWindow = false;
		
		if (AJAX.errorHandler) AJAX.errorHandler(url, responseText, data, action, handler, rId, responseId);
	}
}

AJAX.sendDiscard = function(handler, action, params)

{
	var discardXHR = OO.create(AJAX.xhr, 'discard');
	
	params = params || {  };
	params = { handler: handler, action: action, data: encodeURIComponent(JSON.stringify(params)), SBSID: window.$SBSID };
	
	discardXHR.noTimeout=1;
	discardXHR.send(AJAX.handlerURL, params);
}

AJAX.asyncRequest = function(handler, action, params)

{
	var ajaxRequest = AJAX.XMLHTTP();
	var key, divider = '', paramsStr = '';
	
	AJAX._asyncRequests = AJAX._asyncRequests||[];
	params = params || { };
	params = { handler: handler, action: action, data: encodeURIComponent(JSON.stringify(params)), SBSID: window.$SBSID };
	for (key in params) { paramsStr += divider + key + '=' + escape(params[key]); divider = '&'; }
	
	AJAX._asyncRequests.push({ request: ajaxRequest, url: AJAX.handlerURL, handler: handler, action: action, data: params.data });
	ajaxRequest.onreadystatechange = AJAX.asyncOnReadyStateChange;
	ajaxRequest.open("POST", AJAX.handlerURL, true);
	ajaxRequest.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
	ajaxRequest.setRequestHeader('Charset', 'UTF-8');
	ajaxRequest.setRequestHeader('Connection', 'close');
	ajaxRequest.send(paramsStr);
}

AJAX.asyncOnReadyStateChange = function() {
	var ok = false;
	var current, i = 0;
	
	if (this.readyState!=4) return;
	if (this.status != 200) return;

	for (i in AJAX._asyncRequests) {
		current = AJAX._asyncRequests[i];
		if (current.request == this) {
			AJAX._asyncRequests.splice(i, 1);
			break;
		}
	}
	try { 
		eval('data = '+this.responseText.replace(/^[\n\r]+/, '')); ok = true;
	} catch(e) {
		//printfire('AJAX: Error decoding data');
	}
	if (ok) { 
		if(data.data.messagequeue)
			data.data.messagequeue.forEach(function(item) { try { $CM(item.message, item.data); } catch (e) { ERROR.handle(e); } }, this);
		else
			try { $CM(data.message, data.data); } catch (e) { ERROR.handle(e); }
	}
	if (!ok) {
		if (AJAX.errorHandler) AJAX.errorHandler(current.url, this.responseText, current.data, current.action, current.handler);
	}
}

AJAX.defaultErrorHandler = AJAX.errorHandler = function(url, responseText, data, action, handler, showWin) {
	showWin = showWin||confirm('AJAX SERVER ERROR:\nDo you want to display the error report?');
	if (showWin) {								
		var newWindow = true;
		AJAX.reportWindow = window.open(AJAX.popupURL+'?ajaxHandler='+escape(url),'_blank');
		
		AJAX.reportWindow.displayErrorText = responseText;
		AJAX.reportWindow.ajaxURL = url;
		AJAX.reportWindow.ajaxData = data;
		AJAX.reportWindow.ajaxAction = action;
		AJAX.reportWindow.ajaxHandler = handler;
		AJAX.reportWindow.SBSID = window.$SBSID;
		AJAX.reportWindow.focus(); 
		
		try { AJAX.reportWindow.displayError(); } catch(e) {}
	}
}

AJAX.Fetch = function(o, fn, url, data, params, type) {
	var request = AJAX.XMLHTTP();
	var paramsStr = '';
	
	type = (type == 'post') ? 'POST':'GET';
	params = params || { };
	
	for (key in params) {
		paramsStr += divider + key + '=' + escape(params[key]);
		divider = '&';
	}
	
	responseData = { o: o, fn: fn, data: data }
	request.onreadystatechange = U.FN(request, AJAX.FetchResponse, responseData);
	request.open(type, url, true);
	request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
	request.send('');
}

AJAX.FetchResponse = function(responseData) {
	if (responseData && (this.readyState==4)) responseData.fn.call(responseData.o, responseData.data);
}

AJAX.log = function(p) {
	//try { $CM('helper', 'log', p) } catch(e) { }
	//try { console.log(AJAX.toText(p)); } catch(e) {}
	//console.log.apply(console, arguments);
}

AJAX.toText = function(p) {
	var r='',t = typeof(p);
	
	switch(t) {
		case 'object'	:	if (U.isArray(p)) r=AJAX.arrayToText(p);
							else r = AJAX.objectToText(p);
							break;
		case 'string'	:	r = '"'+p+'"';
							break;
		case 'number'	:	r = ''+p;
							break;
		case 'boolean'	:	r = p.toString();
							break;
	}
	
	return r;
}

AJAX.arrayToText=function(t) {
	var r = '[', sep='';
	for (var i=0,e;i<t.length;i++) {
		r+=sep;
		r+=AJAX.toText(t[i]);
		sep=', ';
	}
	
	return r+']';
}

AJAX.objectToText=function(o) {
	var k,r = '{', sep='';
	for (k in o) {
		r+=sep;
		r+=k+': ';
		r+=AJAX.toText(o[k]);
		sep=', ';
	}
	
	return r+'}';
}

var EVT = new function() {
	this.nextIndex = 1;
	this.events = { };
	this.byId = { };
	this.overTypes = { mouseover: 'hover', mouseout: 'normal' };
	this._disabledEvents = [ ];
	this._locks = { };
	this.e = this._event;	
	this._event = this.e = function(e, o) {		
		if (!(e = e || window.event)) return;
		var r= {	type: e.type, target: e.target || e.srcElement, baseTarget: o,
					pageX: e.pageX || (e.clientX + document.body.scrollLeft), 
					pageY: e.pageY || (e.clientY + document.body.scrollTop),
					keyCode: e.keyCode || e.which, charCode: e.charCode, overType: this.overTypes[e.type],
					shiftKey: e.shiftKey, ctrlKey: e.ctrlKey, altKey: e.altKey, event: e }
		return r;
	}

	
	this.attach = function(o, types, fn, on)  {
		var i,item,evts,evt={};
		var id = this.nextIndex++;

		o._hasEVT=true;
		types = types.split(',');
		if (on) evt=on._EVT=on._EVT||{};
		item = this.byId[id] = { i: id, o: o, fn: fn, on: on, types: types }
		for (var i=0,type;(type=types[i]);i++) {
			this.events[type].push(item);
			evt[type]=evt[type]||[];
			evt[type].push(id);
		}
		return id;
	}

	this.removeEvents = function() {
		for (var i=0,id;(id=arguments[i]);i++) this.remove(id);
	}
	
	this.lock = function(o, events) {
		var i,e;
		events = events.split(',');
		for (i=0;(e=events[i]);i++) { this._locks[events[i]] = o; }
	}
	
	this.unlock = function(o, events) {
		var i, e;
		events = events.split(',');
		for (i=0;(e=events[i]);i++) { delete this._locks[events[i]]; }
	}
	
	this.createDisabledRegExp = function() {
		this._disabledRegExp = new RegExp('('+this._disabledEvents.join('|')+')');
	}
	
	this.remove = function(id)  {
		var type,i,item,a;
		var item = this.byId[id];
		if (!item) return;
		var on = (item.on && item.on._EVT)?item.on:{};
		
		for (i=0;(type=item.types[i]);i++) {
			this.events[type].deleteItem(item);
			try { if (on[type]) on[type].deleteItem(item.i); } catch(e) {}
		}
		delete this.byId[id];
	},
	
	this.removeObject = function(o)  {
		var type,id,item,a;
		for (id in this.byId) {
			item = this.byId[id];
			if (item.o==o) this.remove(id);
		}
	},

	this.killNextClick = function() { this.KNC=true; if (EVT.clickTimeout) clearTimeout(EVT.clickTimeout); }
	
	this.report = function(mess) {
		var reportDiv = DOM.get('mainContent');
		if (reportDiv) {
			reportDiv.innerHTML = mess+'<br>'+reportDiv.innerHTML;
		}		
	}
	
	this.delayedClick = function() {
		var e = EVT.cachedEvent;
		EVT.cachedEvent = null;
		
		if (!e) return;
		
		EVT._thisEvent = { type: e.type, shiftKey: e.shiftKey, altKey: e.altKey, keyCode: e.keyCode, charCode: e.charCode, pageX: e.pageX, pageY: e.pageY }; 
		if (e) EVT.handleEvent(e, true); 
	}
	
	this.handleEvent = function(e, postponed) {
		var type, o;
		

		EVT._thisEvent = { type: e.type, shiftKey: e.shiftKey, altKey: e.altKey, keyCode: e.keyCode, charCode: e.charCode, pageX: e.pageX, pageY: e.pageY }; 
		if (!postponed) {
			if (!(e=EVT.e(e))) return;
			if ((e.type=='mousedown')&&e.target&&e.target.parentNode&&((e.target.className.indexOf('cke_')>=0)||(e.target.parentNode.className.indexOf('cke_')>=0)))  return; //IE6 CKEditor Integration Fix
			if (e.pageX&&e.type.indexOf('mouse')!=-1) EVT._current = { type: e.type, shiftKey: e.shiftKey, altKey: e.altKey, keyCode: e.keyCode, pageX: e.pageX, pageY: e.pageY }
			t = e.target; 
			switch (e.type) {
				case 'click'	:	EVT.mouseDown=false; 
									if (!EVT.KNC) { EVT.cachedEvent = e; EVT.clickTimeout = setTimeout(EVT.delayedClick, 500); }
									EVT.KNC=EVT.mouseDown=false; 
									type='blockclick';
									break;
				case 'mousedown':	EVT.KNC=false; EVT.mouseDown=true; break;
				case 'mouseup'	:	EVT.mouseDown=false; break;
				case 'dblclick'	:	EVT.mouseDown=false; EVT.cachedEvent = null; clearTimeout(EVT.clickTimeout); break;
			}
		}
		else if (e.pageX) EVT._current = { type: e.type, shiftKey: e.shiftKey, altKey: e.altKey, keyCode: e.keyCode, charCode: e.charCode, pageX: e.pageX, pageY: e.pageY }
		var r,i,h,handlers=EVT.getHandlers(type||e.type, e.target);

		for (i=0;(h=handlers[i]);i++) {
			if (!(h = EVT.byId[h])) continue;
			
			if ((!(o=EVT._locks[e.type]))||(o==h.o)) { r = h.fn.call(h.o, e); }
			if (U.D(r)&&!r) { 
				if (e.type=='blockclick') {
					clearTimeout(EVT.clickTimeout);
					EVT.cachedEvent = null;
				}
				return EVT.stopAll(e); 
			}
		}
	}
	
	this.getHandlers = function(type, target) {
		var i,item,handlers = [], baseList = this.events[type];

		while (target) {
			if (target._EVT&&target._EVT[type]) handlers.push.apply(handlers, target._EVT[type]);
			try { target = target.parentNode; } catch(e) { break; };
		}
		for (i=baseList.length-1;(item=baseList[i]);i--) if (!item.on && handlers.indexOf(item.i)==-1) handlers.push(item.i);
		
		return handlers;
	}

	this.stopPropagation = function(e) { 
		if (e && e.event) try {
			e.event.cancelBubble = true;
			e.event.returnValue = false;
			if (e.event.stopPropagation) e.event.stopPropagation();
		} catch(e) { }
	}
	this.preventDefault = function(e) { if (e && e.event && e.event.preventDefault) e.event.preventDefault(); }
	this.stopAll = function(e) { this.stopPropagation(e); this.preventDefault(e); return false; }

	this.initDocEvent = function(type) { this.initEvent(type, document); }
	this.initBodyEvent = function(type) { this.initEvent(type, document.body); }
	this.initWinEvent = function(type) { this.initEvent(type, window); }
	this.initEvent = function(type, b) {
		this.events[type]=[];
		switch (this.eventType) {
			case 'add'		: b.addEventListener(type, EVT.handleEvent, false); break;
			case 'attach'	: b.attachEvent('on'+type, EVT.handleEvent); break;
		}
	}
	
	this.init = function() { 
		EVT.eventType = (document.body.addEventListener)?'add':'attach';
		'keypress,keydown,keyup'.split(',').forEach(EVT.initDocEvent, EVT);
		'mousedown,mouseup,mouseover,mouseout,click,dblclick,mousemove,change,scroll,resize'.split(',').forEach(EVT.initBodyEvent, EVT);
		EVT.events.blockclick=[];
	}
	gAddOnload(this.init);
}


var JSON;if(!JSON){JSON={};}
(function(){'use strict';function f(n){return n<10?'0'+n:n;}
if(typeof Date.prototype.toJSON!=='function'){Date.prototype.toJSON=function(key){return isFinite(this.valueOf())?this.getUTCFullYear()+'-'+
f(this.getUTCMonth()+1)+'-'+
f(this.getUTCDate())+'T'+
f(this.getUTCHours())+':'+
f(this.getUTCMinutes())+':'+
f(this.getUTCSeconds())+'Z':null;};String.prototype.toJSON=Number.prototype.toJSON=Boolean.prototype.toJSON=function(key){return this.valueOf();};}
var cx=/[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,escapable=/[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g,gap,indent,meta={'\b':'\\b','\t':'\\t','\n':'\\n','\f':'\\f','\r':'\\r','"':'\\"','\\':'\\\\'},rep;function quote(string){escapable.lastIndex=0;return escapable.test(string)?'"'+string.replace(escapable,function(a){var c=meta[a];return typeof c==='string'?c:'\\u'+('0000'+a.charCodeAt(0).toString(16)).slice(-4);})+'"':'"'+string+'"';}
function str(key,holder){var i,k,v,length,mind=gap,partial,value=holder[key];if(value&&typeof value==='object'&&typeof value.toJSON==='function'){value=value.toJSON(key);}
if(typeof rep==='function'){value=rep.call(holder,key,value);}
switch(typeof value){case'string':return quote(value);case'number':return isFinite(value)?String(value):'null';case'boolean':case'null':return String(value);case'object':if(!value){return'null';}
gap+=indent;partial=[];if(Object.prototype.toString.apply(value)==='[object Array]'){length=value.length;for(i=0;i<length;i+=1){partial[i]=str(i,value)||'null';}
v=partial.length===0?'[]':gap?'[\n'+gap+partial.join(',\n'+gap)+'\n'+mind+']':'['+partial.join(',')+']';gap=mind;return v;}
if(rep&&typeof rep==='object'){length=rep.length;for(i=0;i<length;i+=1){if(typeof rep[i]==='string'){k=rep[i];v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}else{for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=str(k,value);if(v){partial.push(quote(k)+(gap?': ':':')+v);}}}}
v=partial.length===0?'{}':gap?'{\n'+gap+partial.join(',\n'+gap)+'\n'+mind+'}':'{'+partial.join(',')+'}';gap=mind;return v;}}
if(typeof JSON.stringify!=='function'){JSON.stringify=function(value,replacer,space){var i;gap='';indent='';if(typeof space==='number'){for(i=0;i<space;i+=1){indent+=' ';}}else if(typeof space==='string'){indent=space;}
rep=replacer;if(replacer&&typeof replacer!=='function'&&(typeof replacer!=='object'||typeof replacer.length!=='number')){throw new Error('JSON.stringify');}
return str('',{'':value});};}
if(typeof JSON.parse!=='function'){JSON.parse=function(text,reviver){var j;function walk(holder,key){var k,v,value=holder[key];if(value&&typeof value==='object'){for(k in value){if(Object.prototype.hasOwnProperty.call(value,k)){v=walk(value,k);if(v!==undefined){value[k]=v;}else{delete value[k];}}}}
return reviver.call(holder,key,value);}
text=String(text);cx.lastIndex=0;if(cx.test(text)){text=text.replace(cx,function(a){return'\\u'+
('0000'+a.charCodeAt(0).toString(16)).slice(-4);});}
if(/^[\],:{}\s]*$/.test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g,'@').replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g,']').replace(/(?:^|:|,)(?:\s*\[)+/g,''))){j=eval('('+text+')');return typeof reviver==='function'?walk({'':j},''):j;}
throw new SyntaxError('JSON.parse');};}}());
