// objects
function ouf_cpyo(oto, ofr) { var i;for(i in ofr) oto[i]=ofr[i]; }
function ouf_inho(oto, ofr) { var i;for(i in ofr) if (typeof(oto[i]) == 'undefined') oto[i]=ofr[i]; }
function ouf_clno(o) { var n = new o.constructor(); ouf_cpyo(n, o); return n;}
function ouf_clnt(o) {
	var i, n;
	if (typeof(o)=='object' && o!=null) { n = new o.constructor(); for (i in o) n[i]=ouf_clnt(o[i]); return n; }
	else return o;
}
function ouf_trmL(s) { var n=-1;while (' \r\n\t'.indexOf(s.charAt(++n))>=0); return s.substr(n); }
function ouf_trmR(s) { var n=s.length;while (n-- && ' \r\n\t'.indexOf(s.charAt(n))>=0);return s.substr(0, n+1); }
function ouf_trm(s) { return ouf_trmL(ouf_trmR(s)); }
function ouf_ardel(a, n) {
	var i, l=a.length;
	for (i=n+1;i<l;i++) a[i-1]=a[i];
	if (n<l) a.length=l-1;
}
function ouf_ardel0(a) {
	var i, ii=0, d=0, l=a.length;
	for (i=0;i<l;i++) { if (a[i]!=null) { if (i!=ii) a[ii]=a[i]; ii++; } else d++; }
	a.length=l-d;
}

// DOM
function ouf_topos(e, b) {
	if (!b) b=e.ownerDocument?e.ownerDocument.body:e.document.body;
	var p = new Object(); p.x=p.y=0;
	if (e==b) return p;
	while (1) {
		p.x+=e.offsetLeft; p.y+=e.offsetTop;
		if ((e=e.offsetParent) != b && e) { if(e.clientLeft >= 0) p.x+=e.clientLeft, p.y+=e.clientTop; }
		else { return p; }
	}
}
function ouf_clear(e) { while (e.hasChildNodes()) e.removeChild(e.childNodes[0]); }
function ouf_contains(e, c) { for(var i=0;i<e.childNodes.length;i++) if(e.childNodes[i]==c || ouf_contains(e.childNodes[i], c)) return 1; return 0; }
function ouf_todomevt(elem, evt) {
	if (evt.e) return evt.e;
	var e = new Object();
	evt.e = e;
	// DHTML -> DOM2
	e.type = evt.type;
	e.target = evt.srcElement;
	e.currentTarget = elem;
	e.clientX = evt.clientX; e.clientY = evt.clientY;
	e.screenX = evt.screenX; e.screenY = evt.screenY;
	e.ctrlKey = evt.ctrlKey; e.altKey = evt.altKey; e.shiftKey = evt.shiftKey;
	e.relatedTarget = (evt.fromElement==evt.srcElement) ? evt.toElement : evt.fromElement;
	if (evt.button & 1) e.button = 0;
	else if (evt.button & 2) e.button = 3;
	else if (evt.button & 4) e.button = 2;
	return e;
}
function ouf_setevt(elem, type, f) { // must be f(evt)
	if (elem.addEventListener) elem.addEventListener(type, f, false);
	else elem["on" + type] = function() { f(ouf_todomevt(elem, event)); }
}

// decl
function DECL_CLASS(clsn, ancf) {
	if (!ancf) ancf = _CMetaCls;
	var p, cf = window[clsn];
	p = new ancf._protoc();
	ouf_cpyo(p, cf.prototype);
	cf.prototype = p;
	cf._clsf = p._clsf = cf;
	cf._cls_name = clsn;
	cf._ancf = ancf;
	cf._impl = new Array();
	cf._protoc = new Function('');
	cf._protoc.prototype = p;
}
function IMPL_CLASS(clsf, iclsf) {
	clsf._impl[clsf._impl.length] = iclsf;
	ouf_inho(clsf.prototype, iclsf.prototype);
}
function D_CONSTRUCTOR(clsf, cnf) {
	cnf.prototype = clsf.prototype;
	cnf._clsf = clsf;
}
function APPLY_CLS(obj, clsf) { ouf_inho(obj, clsf.prototype); }

// metaclass
function _CMetaCls() {}
_CMetaCls.prototype._baseinit = _ou_mc_baseinit;
function _ou_mc_baseinit() {
	var i, cf = _ou_mc_baseinit.caller._clsf;
	if (!cf) return;
	this._bm_ = cf._ancf, this._bm_();
	i = cf._impl.length;
	while (i--) this._bm_ = cf._impl[i], this._bm_();
	this.constructor = cf;
}
_CMetaCls.prototype._getbasem = function (idm) {
	return this._bm_ = this.constructor._ancf.prototype[idm];
}
_CMetaCls.prototype._isOfType = function (clsn) {
	var cf = this.constructor;
	while (cf) { if (cf._cls_name == clsn) return 1; cf = cf._ancf; }
	return 0;
}
_CMetaCls.prototype._clsf = _CMetaCls;
_CMetaCls._cls_name = "_CMetaCls";
_CMetaCls._ancf = null;
_CMetaCls._impl = new Array();
_CMetaCls._protoc = new Function('');
_CMetaCls._protoc.prototype = _CMetaCls.prototype;
_CMetaCls._clsf = _CMetaCls;

// attaching to ch-I
if (window['GI']) {
GI.ouf_cpyo=ouf_cpyo;
GI.ouf_inho=ouf_inho;
GI.ouf_clno=ouf_clno;
GI.ouf_clnt=ouf_clnt;
GI.ouf_trmL=ouf_trmL;
GI.ouf_trmR=ouf_trmR;
GI.ouf_trm=ouf_trm;
GI.ouf_ardel=ouf_ardel;
GI.ouf_ardel0=ouf_ardel0;
GI.ouf_topos=ouf_topos;
}
