window.FD = new Object();

function FDBrowser() {
	this.Name = navigator.appName; this.Version = navigator.appVersion; this.VersionNr = parseInt(this.Version);

	this.win = navigator.userAgent.search('Windows') > 0;
	this.linux = navigator.userAgent.search('Linux') > 0;
	this.mac = navigator.userAgent.search('Macintosh') > 0 || navigator.userAgent.search('Mac_') > 0;
	this.WebKit = navigator.userAgent.indexOf('AppleWebKit/') > -1;

	this.opera = navigator.userAgent.search('Opera') >= 0;
	this.gecko = navigator.userAgent.search('Gecko/') > 0;
	this.ns = navigator.userAgent.search('Netscape') > 0;
	this.ns4 = false; this.ns6 = false; this.ns7 = false; this.ns8 = false;
	if (this.ns) {
		this.VersionNr = parseFloat(navigator.userAgent.match(/Netscape(\d)?\/(.*)/)[2]);
		this.ns4 = parseInt(this.Version) == 4;
		this.ns6 = navigator.userAgent.search('Netscape6') > 0;
		this.ns7 = navigator.userAgent.search('Netscape/7') > 0;
		this.ns8 = navigator.userAgent.search('Netscape/8') > 0;
	}

	this.ie = (this.Name == "Microsoft Internet Explorer"); this.ie4 = false; this.ie5 = false; this.ie6 = false; this.ie7 = false;
	if (this.ie) {
		this.VersionNr = parseFloat(this.Version.match(/MSIE (\d+.\d+)/)[1]);
		this.ie4 = this.Version.search('MSIE 4') > 0;
		this.ie5 = this.Version.search('MSIE 5') > 0;
		this.ie6 = this.Version.search('MSIE 6') > 0;
		this.ie7 = this.Version.search('MSIE 7') > 0;
		this.ie8 = this.Version.search('MSIE 8') > 0;
	}

	this.safari = navigator.userAgent.search('Safari') > 0;
	if (this.safari)
		this.VersionNr = parseFloat(this.Version.match(/Safari\/(\d+.\d+)/)[1]);
	this.camino = navigator.userAgent.search('Camino') > 0;
	if (this.camino)
		this.VersionNr = parseFloat(navigator.userAgent.match(/Camino\/(.*)/)[1]);
	this.firefox = navigator.userAgent.search('Firefox') > 0;
	if (this.firefox)
		this.VersionNr = parseFloat(navigator.userAgent.match(/Firefox\/(.*)/)[1]);

	this.W3C = document.getElementById ? true : false;

	this.isComp = function(npLvl) {
		var lComp = false;
		if (npLvl > 0) {
			lComp = (this.gecko && (!this.ns || this.VersionNr >= 7));
			if (!lComp && this.win) lComp = (this.ie && this.VersionNr >= 5.5);
		}
		return lComp;
	}
}
var Browser = FD.Browser = new FDBrowser();

//--> Extened prototypes and objects
Object.extend = function(destination, source) {
	for (var property in source)
		destination[property] = source[property];
	return destination;
};

Object.extend(Boolean, {
	create: function(bool) {
		switch (typeof bool) {
			case 'string':
				return inList(bool.toLowerCase(), 'true', '.t.', '1');
			case 'number':
				return bool > 0;
			case 'boolean':
				return bool;
		}
		return false;
	}
});
Object.extend(String, {
	create: function(str) {
		return (typeof str == 'string' ? str : (str ? new String(str) : ''));
	},
	stripHTML: function(str) {
		var re = /<\S[^><]*>/g;
		return (str.replace(re, "").replace(/&[^&;]{1,8};/ig, ""));
	},
	stripScript: function(str) {
		var re = /<script[^>]*>([\\S\\s]*?)<\/script>/img;
		return (str.replace(re, ""));
	}
});
Object.extend(String.prototype, {
	left: function(length) {
		return this.substr(0,length);
	},
	right: function(length) {
		return this.substr(Math.max(this.length-length,0));
	},
	trim: function() {
		return this.ltrim().rtrim();
	},
	rtrim: function() {
		return this.replace(/\s+$/, '');
	},
	ltrim: function() {
		return this.replace(/^\s+/, '');
	},
	truncate: function(length, truncation) {
		length = length || 30;
		truncation = typeof truncation == 'undefined' ? '...' : truncation;
		return this.length > length ?
			this.slice(0, length - truncation.length) + truncation : String(this);
	},
	times: function(count) {
		return count < 1 ? '' : new Array(count + 1).join(this);
	},
	padl: function(size, pad) {
		pad = (typeof pad == 'undefined' ? ' ' : pad);
		return pad.times(size - this.length) + this;
	},
	padr: function(size, pad) {
		pad = (typeof pad == 'undefined' ? ' ' : pad);
		return this + pad.times(size - this.length);
	},
	int: function() {
		var retval = parseInt(this);
		return ((this.length == 0 || isNaN(retval)) ? 0 : retval);
	},
	float: function() {
		var str = this.replaceAll(',', '.');
		var pos = 0, chr = (str.length == 0 ? '' : str.charAt(pos)), next = '';
		while (pos < str.length && ((isNaN(chr) || chr.empty()) && ((chr != '-' && chr != '.') || (pos < str.length - 1 && (isNaN((next = str.charAt(pos + 1))) || next.empty()))))) {
			pos++; chr = str.charAt(pos); next = '';
		}
		var retval = parseFloat(str.substr(pos));
		return ((str.length == 0 || isNaN(retval)) ? 0 : retval);
	},
	array: function(chr, type) {
		var arr = this.split(chr);
		if (type && type.list('int', 'float')) {
			for (var i = arr.length - 1; i >= 0; i--) {
				if (arr[i].empty()) arr.splice(i, 1);
				else arr[i] = (type == 'int' ? arr[i].int() : arr[i].float());
			}
		}
		return arr;
	},
	stringToRegExp: function() {
		if (!String._regexp1) String._regexp1 = new RegExp('([\\\(\\\[\\\{])', 'gm');
		if (!String._regexp2) String._regexp2 = new RegExp('([\\\)\\\]\\\}\\\?])', 'gm');
		str = this.replace(String._regexp1, '\\\$1');
		return str.replace(String._regexp2, '\\\$1');
	},
	replaceAll: function(what, withwhat, icase) {
		var re = new RegExp(what, (icase ? "i" : "") + "gm");
		return this.replace(re, withwhat);
	},
	empty: function(nolength) {
		if (nolength && this.length == 0) return false;
		return !(/[^\s]/.test(this));
	},
	occurs: function(str) {
		var re = new RegExp(str, "igm"), occurs = this.match(re);
		return (occurs ? occurs.length : 0);
	},
	list: function() {
		for (var i = 0; i < arguments.length; i++) {
			if (this == arguments[i]) return true;
		}
		return false;
	},
	stripHTML: function() {
		var re = /<\S[^><]*>/g;
		return (this.replace(re, "").replace(/&[^&;]{1,8};/ig, ""));
	},
	stripScript: function() {
		var re = /<script[^>]*>([\\S\\s]*?)<\/script>/img;
		return (this.replace(re, ""));
	}
});

Object.extend(Number, {
	int: function(val) {
		var retval = parseInt(val);
		return (isNaN(retval) ? 0 : retval);
	},
	float: function(val) {
		var retval = parseFloat(val);
		return (isNaN(retval) ? 0 : retval);
	},
	correct: function() {
		return this.float(correctNumber.apply(this, arguments)[0]);
	}
});
Object.extend(Number.prototype, {
	between: function(low, high) {
		return (this >= low && this <= high);
	}
});

Object.extend(Function, {
	exist: function(func) {
		try { return typeof eval(func) != 'undefined' && this.is(eval(func)); }
		catch (e) { return false; }
	}
});
Object.extend(Function.prototype, {
	bind: function() {
		if (arguments.length < 2 && arguments[0] == 'undefined') return this;
			var __method = this, args = $A(arguments.length == 1 ? arguments[0] : arguments), object = (typeof args[0] == 'object' ? args.shift() : this);
			return function() {
			return __method.apply(object, args); //.concat($A(arguments))
		}
	},
	bindAsEventListener: function() {
		var __method = this, args = $A(arguments), object = args.shift();
		return function(event) {
			return __method.apply(object, [event || window.event].concat(args));
		}
	},
	delay: function() {
		var __method = this, args = $A(arguments), object = (typeof args[0] == 'object' ? args.shift() : this), timeout = args.shift();
		return window.setTimeout(function() {
			return __method.apply(object, args);
		}, timeout);
	}
});

Object.extend(Math, {
	log10: function(num) {
		return this.log(num) / this.log(10);
	},
	median: function(array) {
		if (array.length == 0) return 0;
		array.sort(function(a, B) { return (a - B); });
		if (array.length % 2 > 0) { // odd
			return array[Math.floor(array.length / 2)];
		} else {
			var mid = array.length / 2;
			return (array[mid - 1] + array[mid]) / 2;
		}
	}
});
Object.extend(Array.prototype, {
	insert: function() {
		var arg = arguments.length < 2 ? arguments[0] : arguments;
		if (arg[0] < this.length) {
			var temp = this.splice(arg[0], this.length - arg[0]);
			this.add(1, arg);
			this.add(0, temp);
		} else {
			this.add(1, arg);
		}
	},
	add: function(start, items, index) {
		for (var i = start; i < items.length; i++) {
			if (index) items[i].index = this.length;
			this.push(items[i]);
		}
	},
	search: function(search) {
		for (var i = 0; i < this.length; i++) {
			if (this[i] == search) return i;
		}
		return -1;
	},
	seek: function(search) {
		for (var i = 0; i < this.length; i++) {
			if (this[i] == search) return true;
		}
		return false;
	},
	remove: function(index) {
		this.splice(index, 1);
	},
	trim: function() {
		for (var i = 0; i < this.length; i++) {
			this[i] = String(this[i]).trim();
		}
		return this;
	}
});
if (!Array.prototype.push) {
	Array.prototype.push = function() {
		for (var i = 0; i < arguments.length; i++)
			this[this.length] = arguments[i];
		return this.length;
	}
}

function $A(iterable) {
	if (!iterable) return [];
	if (iterable.toArray) return iterable.toArray();
	var length = iterable.length || 0, results = new Array(length);
	while (length--) results[length] = iterable[length];
	return results;
}

if (Browser.WebKit) {
	$A = function(iterable) {
		if (!iterable) return [];
		if (!(Function.is(iterable) && iterable == '[object NodeList]') &&
			iterable.toArray) return iterable.toArray();
		var length = iterable.length || 0, results = new Array(length);
		while (length--) results[length] = iterable[length];
		return results;
	};
}
RegExp.prototype.execAll = function(str) {
	var result = [], arr;
	while ((arr = this.exec(str)) != null) {
		result.push(arr[1]);
	}
	return (result.length > 0 ? result : null);
}

function FDKeyArray(items, decode) {
	var ret = new Array();
	ret.parent_push = ret.push;
	ret.push = function() {
		if (arguments.length == 2 && typeof arguments[0] == 'string') {
			this.set(arguments[0], arguments[1]);
		} else {
			for (var i = 0; i < arguments.length; i++) {
				if (Array.is(arguments[i])) {
					this.set(arguments[i][0], arguments[i][1]);
				} else {
					this.set(arguments[i], '');
				}
			}
		}
	}
	ret.concat = function(items) {
		this.push(items);
	}
	ret.merge = function(items) {
		if (items.length == 0) return;
		if (Array.is(items[0])) { // consider all items to be an array
			this.add(items);
		} else { // flat array with key,value,key,value pairs
			for (var i = 0; i < items.length; i += 2) {
				this.set(items[i], items[i + 1]);
			}
		}
	}
	ret.add = function(items, decode) {
		var i, item;
		for (i = 0; i < items.length; i++) {
			item = items[i];
			if (typeof item == 'string') {
				item = item.split('=');
				if (typeof item[0] == 'undefined') item[0] = '';
				if (typeof item[1] == 'undefined' || item[1] == 'undefined') item[1] = '';
				else item[1] = (decode ? URLDecode(item[1]) : item[1]); //( decode ? ( typeof decodeURIComponent != 'undefined' ? decodeURIComponent(item[1]) : URLDecode(item[1]) ) : item[1] ) ;
			}
			this.push(item);
		}
	}
	ret.get = function(name, alt, type, decode) {
		name = name.toLowerCase();
		var val = '', f = false;
		for (var i = 0; i < this.length; i++) {
			if (this[i][0].toLowerCase() == name) { f = true; val = this[i][1]; break; }
		}
		if (!f && arguments.length > 1 && alt != null) return alt;
		if (decode) {
			val = (typeof decodeURIComponent != 'undefined' ? decodeURIComponent(val) : URLDecode(val));
		}
		if (arguments.length < 3 || type == null) return val;
		type = type.toLowerCase();
		if (inList(type, 'integer', 'i')) {
			return Number.int(val);
		} else if (inList(type, 'boolean', 'l')) {
			return inList(val.toLowerCase(), 'true', '1', '.t.');
		} else if (inList(type, 'float', 'f', 'n')) {
			return Number.float(val);
		}
		return val;
	}
	ret.exist = function(name) {
		name = name.toLowerCase();
		for (var i = 0; i < this.length; i++) {
			if (this[i][0].toLowerCase() == name) return true;
		}
		return false;
	}
	ret.set = function(name, value) {
		var index = -1;
		if (name == '') return index;
		name = name.toLowerCase();
		value = (typeof value == 'string' ? value : String(value));
		for (var i = 0; i < this.length; i++) {
			if (this[i][0].toLowerCase() == name) { index = i; break; }
		}
		if (index == -1) {
			index = this.length;
			this[index] = new Array(name, value);
		} else
			this[index][1] = value;
		return index;
	}
	ret.remove = function(name) {
		for (var i = 0; i < this.length; i++) {
			if (this[i][0].toLowerCase() == name) { this.splice(i, 1); break; }
		}
	}
	ret.parent_tostring = ret.toString;
	ret.toString = function(bookmark) {
		var string = '', append = '', bm = '';
		for (var i = 0; i < this.length; i++) {
			if (this[i].length > 0) {
				if (this[i][0].charAt(0) != '#') {
					if (this[i][0].length == '' || this[i][1].length == '') {
						append += (append.length > 0 ? '&' : '') + this[i][0] + URLEncode(this[i][1]);
					} else {
						string += (string.length > 0 ? '&' : '') + this[i][0] + '=' + URLEncode(this[i][1]);
					}
				} else {
					bm = this[i][0];
				}
			}
		}
		return string + (string.length > 0 && append.length > 0 ? '&' : '') + append + (bookmark ? bm : '');
	}
	if (items) ret.add(items, decode);
	return ret;
}

function FDExecArray() {
	var ret = new Array();
	ret.Add = function(obj) {
		var i = arraySearch(this, obj.name);
		if (i < 0) {
			i = this.length;
			this.push(obj.name);
		} else
			this[i] = obj.name;
		obj.index = i; this[obj.name] = obj;
	}
	ret.Remove = function(name) {
		var i = arraySearch(this, name), item = null;
		if (i >= 0) {
			item = this[name];
			this[name] = null;
			this.splice(i, 1);
		}
		return item;
	}
	return ret;
}
function FDObjectArray() {
	var ret = new Array();
	if (arguments.length > 0) ret.add(0, arguments, true);
	ret.search = function() {
		var prop = (arguments.length > 1 ? arguments[0] : (typeof arguments[0] == 'string' ? 'name' : 'id'));
		var search = (arguments.length > 1 ? arguments[1] : arguments[0]);
		for (var i = 0; i < this.length; i++) {
			if (this[i][prop] == search) return this[i];
		}
		return null;
	}
	ret.first = function() {
		return (this.length > 0 ? this[0] : null);
	}
	ret.last = function() {
		return (this.length > 0 ? this[this.length - 1] : null);
	}
	ret.next = function(current) {
		if (!current || current.index >= this.length - 1 || current.index < 0) return null;
		return (this[current.index + 1]);
	}
	ret.prev = function(current) {
		if (!current || current.index > this.length - 1 || current.index <= 0) return null;
		return this[current.index - 1];
	}
	ret.parent_push = ret.push;
	ret.push = function() {
		var item, i;
		for (i = 0; i < arguments.length; i++) {
			arguments[i].index = this.length;
			this.parent_push(arguments[i]);
		}
	}
	ret.parent_insert = ret.insert;
	ret.insert = function() {
		this.parent_insert(arguments);
		this.reindex(arguments.length > 0 ? arguments[0] + 1 : 0);
	}
	ret.parent_add = ret.add;
	ret.add = function(start, items, index) {
		this.parent_add(start, items, true);
	}
	ret.remove = function(index) {
		this.splice(index, 1);
		this.reindex(index);
	}
	ret.reindex = function(start) {
		for (var i = start || 0; i < this.length; i++) {
			this[i].index = i;
		}
	}
	return ret;
}

function FDAjaxArray() {
	var ret = new FDObjectArray();
	ret.firstChild = null;
	if (arguments.length > 0) ret.add(0, arguments, true);
	ret.push = function() {
		for (var i = 0; i < arguments.length; i++) {
			this.parent_push(arguments[i]);
		}
		this.reindex();
	}
	ret.add = function(start, items, index) {
		this.parent_add(start, items, true);
		this.reindex();
	}
	ret.remove = function(index) {
		this.firstChild = null;
		this[index].nextSibling = null;
		this.splice(index, 1);
		this.reindex(index);
	}
	ret.reindex = function(start) {
		this.firstChild = (this.length > 0 ? this[0] : null);
		for (var i = start || 0; i < this.length; i++) {
			this[i].index = i;
			this[i].nodeType = 1; // ELEMENT_NODE
			this[i].nextSibling = null;
			this[i].getAttribute = FDAjaxArray_getAttribute;
			if (i > 0) this[i - 1].nextSibling = this[i];
		}
	}
	ret.selectSingleNode = function(nodeName) {
		return this.search('nodeName', nodeName);
	}
	return ret;
}
FDAjaxArray_getAttribute = function(name) {
	return (typeof this[name] != 'undefined' ? this[name] : null);
}

function FDFieldArray() {
	var ret = FDObjectArray();
	if (arguments.length > 0) ret.add(0, arguments, true);
	ret.get = function() {
		var prop = (typeof arguments[0] == 'string' ? 'name' : 'id'), search = arguments[0];
		var ret = (typeof arguments[0] == 'string' ? 'id' : 'name');
		for (var i = 0; i < this.length; i++) {
			if (this[i][prop] == search) return this[i][ret];
		}
		return null;
	}
	ret.value = function() {
		var name = arguments[0], retval = '';
		if (typeof name == 'number') name = this.get(name);
		var el = $(name);
		if (!el) return retval;
		if (typeof el.tagName == 'undefined' && typeof el[0] != 'undefined') { // radio/checkbox list
			if (arguments.length > 1 && arguments[1] != null) {
				retval = isSelectedOption(null, el, arguments[1]);
			} else {
				retval = new Array();
				for (var i = 0; i < el.length; i++) {
					if (el[i].checked) retval.push(el[i].value);
				}
			}
		} else if (el.tagName.toLowerCase() == 'input' && /^(radio|checkbox)$/.test((el.type ? el.type.toLowerCase() : ''))) { // single checkbox/radio
			retval = el.checked;
		} else if (typeof el.value != 'undefined') {
			retval = el.value;
		}
		if (arguments.length > 2) {
			var fld = this.search(name);
			switch (fld.type) {
				case 15:
				case 2:
					retval = Number.correct(retval.substr(0, el.maxlength), Number.int(el.getAttribute('fd:decimals')), true);
					break;
				case 3:
					if (retval == '') retval = null;
					else {
						retval = FD.Date.Parse(retval);
						if (retval.Error) retval = null;
					}
					break;
			}
		}

		return retval;
	}
		
	return ret;
}

//<-- Extended prototypes and objects

FD.Lock = {
	_locked: 0, _queue: '', _tmr: 0,
	Set: function() {
		this._locked++;
	},
	Release: function(all) {
		if (all) { this._locked = 0; }
		else this._locked--;
		if (this._locked < 0) this._locked = 0;
		if (this._locked == 0 && this._queue) {
			FD.Lock.ExecQueue.delay(FD.Lock, 500);
		}
	},
	ExecQueue: function() {
		if (typeof this._queue == 'object') this._queue();
		else eval(this._queue);
		this._queue = '';
	},
	Cancel: function(all) {
		if (all) this._locked = 0;
		else this._locked--;
		if (this._locked < 0) this._locked = 0;
		this._queue = '';
	},
	Check: function(queue) {
		//		alert('check: ' + this._locked + ', ' + queue);
		if (!this._locked) return true;
		if (queue) this._queue = queue;
		return false;
	}
}

FD.Error = {
	reportPlain: function(msg, url, line) {
		var texts = FD.Texts.Error;
		var message = (texts ? texts.get('CLIENT_ERROR_INFO') + '\r\n\r\n' : '') + (line && texts ? texts.get('CLIENT_ERROR_LINE') + line + '\r\n' : '') + (texts ? texts.get('CLIENT_ERROR_MSG') : '') + msg;
		alert(message);
		return true;
	},
	reportFlash: function(e, msg, id) {
		var attrib = aFields.search(id);
		if (attrib) {
			alert(msg + (e ? '\r\n\r\n' + (typeof e.message != 'undefined' ? e.message : e) : ''));
			FD.Utils.Blink.Start(attrib);
		}
	},
	reportCalc: function(e, id) {
		this.reportFlash(e, FD.Texts.Error.get('SCRIPT_ERROR_CALC'), id);
	},
	reportDep: function(e, id) {
		this.reportFlash(e, FD.Texts.Error.get('SCRIPT_ERROR_DEP'), id);
	},
	Queue: {
		prev_onerror: null, Items: null, Message: '', AttribID: 0,
		Start: function(msg) {
			this.Message = msg;
			this.AttribID = 0;
			if (!this.prev_onerror) this.prev_onerror = window.onerror;
			window.onerror = FD.Error.Queue.Add;
		},
		Stop: function() {
			if (this.prev_onerror) window.onerror = this.prev_onerror;
			prev_onerror = null;
		},
		Add: function(msg, url, line) {
			var queue = FD.Error.Queue;
			if (!queue.Items) {
				queue.Items = new Array();
				FDEvents.AttachEvent('AfterLoad', queue.Report);
			}
			queue.Items.push({ msg: queue.Message, line: line, id: queue.AttribID });
			return true;
		},
		Report: function() {
			var queue = FD.Error.Queue, attrib;
			for (var i = 0; i < queue.Items.length; i++) {
				if (queue.Items[i].id > 0)
					FD.Error.reportFlash(null, queue.Items[i].msg, queue.Items[i].id);
				else
					FD.Error.reportPlain(queue.Items[i].msg, '', queue.Items[i].line);
			}
			queue.Clear();
		},
		Clear: function() {
			this.Stop();
			this.Items = null;
			this.Message = '';
			this.AttribID = 0;
		}
	}
}

FD.Stack = {
	Items: new Array(), _cl: 0, _loop: 0,
	Get: function(func) {
		if (!func) func = FD.Stack.Get.caller;
		items = new Array();
		var name, loop = 0;
		while (func && loop < 1000) {
			loop++;
			name = this.getFunctionName(func);
			items.push(name || 'unknown');
			func = func.caller || null;
		}
		this.Items = items.reverse();
		return this.Items;
	},
	Format: function(join, func) {
		func = func || FD.Stack.Format.caller;
		this.Get(func);
		var stack = [];
		if (!join) join = '\r\n';
		for (var i = 0; i < this.Items.length; i++) {
			stack.push((i + 1) + ': ' + this.Items[i]);
		}
		return stack.join(join);
	},
	getFunctionName: function(func) {
		//DEBUG.trace('getFunctionName', func + ', '+typeof func);
		try {
			if (typeof func == 'function') {
				if (func.name) return '(func) ' + func.name;
				var name = new RegExp("function ([^\(\)]*)").exec(func);
				if (name && name[1].replace(/\s/ig, '') != '') return '(func) ' + name[1];
				name = null;
			} else if (func && func.callee) {
				var name = new RegExp("function ([^\(\)]*)").exec(func.callee);
				if (name) return '(callee) ' + name[1];
			}
			if (func && !name && (name = ('(scope) ' + this.findName(window, func)))) return name;
		} catch (e) { return 'error finding function name (' + (e.description || e) + ')'; }
		return '';
	},
	findName: function(scope, search, recur, lvl) {
		var i, j, k, posible = [], exclude = 'top,window,parent,frames,self,navigator';
		if (!recur) { this._cl++; this._loop = 0; lvl = 0; }
		if (this._loop < 1000) {
			lvl++;
			for (var i in scope) {
				if (scope[i] == search) posible.push(i);
				try {
					if (lvl <= 10 && exclude.search(i.toLowerCase()) < 0 && typeof scope[i] == 'object' && scope[i] && typeof scope[i].nodeType == 'undefined' && (typeof scope[i]._cl == 'undefined' || scope[i]._cl != this._cl || i == 'Stack')) {
						scope[i]._cl = this._cl;
						if ((j = this.findName(scope[i], search, true, lvl)) && j.length > 0) {
							for (k = 0; k < j.length; k++) j[k] = i + '.' + j[k];
							posible.push(j.join(', '));
						}
					}
				} catch (e) { };
			}
		}
		return (!recur ? posible.join(', ') : posible);
	},
	CalledFrom: function() {
		var func = FD.Stack.CalledFrom.caller;
		return (func && func.caller ? this.findName(window, func.caller) : '');
	}
}

var FDUtils = FD.Utils = {
	doFile: function(cel, action, noev) {
		var el = $('hd' + cel);
		if (!el) return;
		if (action == 3 && el.prevValue && el.prevValue == '0') action = 1;
		else el.prevValue = el.value;
		if (action > 0) el.value = (action == 1 ? 0 : 1);
		setDisplay(document, 'tbl' + cel, parseInt(el.value) == 1);
		setDisplay(document, cel, parseInt(el.value) == 0);
		if (!noev && typeof ev != 'undefined' && FD.Form.isLoading) ev(cel);
	},
	setCounter: function(id, max) {
		layerWrite(document, 'cnt' + id, '(' + $(id).value.length + (max ? '/' + max : '') + ' ' + FD.Texts.get('CHARACTER_COUNT') + ')');
	},
	checkLabel: function(el) {
		if (!el.tagName || el.tagName.toUpperCase() != 'LABEL' || !el.htmlFor) return el;
		return $(el.htmlFor);
	},
	Random: function() {
		return Math.round(Math.random() * 100000);
	},
	RegExp: function(exp, clean) {
		var re = /(\*|\+|\$|\(|\)|\.|\[|\]|\?|\\|\/|\^|\{|\}|\|)/g; // escape the special characters
		exp = exp.replace(re, '\\$1');
		return (clean ? exp : new RegExp(exp));
	},
	Blink: {
		tmr: 0, items: new FDObjectArray(), el1: null, el2: null, show: true,
		isBlinking: function(attrib) {
			return this.items.search('id', attrib.id);
		},
		Start: function(attrib) {
			var item = this.items.search('id', attrib.id);
			if (item) return true;
			item = { id: attrib.id, el1: $('tdQA' + attrib.id) };
			if (!item.el1) {
				item.el1 = $('tdA' + attrib.id);
				item.el2 = $('tdQ' + attrib.id);
			}
			this.items.push(item);
			this.Exec();
		},
		Exec: function() {
			window.clearTimeout(this.tmr);
			this.tmr = window.setTimeout('FD.Utils.Blink.Exec();', (this.show ? 1300 : 400));
			for (var i = 0; i < this.items.length; i++) {
				this.Show(this.items[i], this.show);
			}
			this.show = !this.show;
		},
		Show: function(item, show) {
			show = (arguments.length == 1 ? item.el1.style.visibility == 'hidden' : show);
			show = (show ? '' : 'hidden');
			if (item.el1) item.el1.style.visibility = show;
			if (item.el2) item.el2.style.visibility = show;
		},
		Stop: function(id) {
			if (this.tmr) window.clearTimeout(this.tmr);
			if (id) {
				var item = this.items.search('id', id);
				if (item) {
					this.items.remove(item.index);
					this.Show(item, true);
				}
				item = null;
			} else {
				for (var i = 0; i < this.items.length; i++) this.Show(this.items[i], true);
				this.items = new FDObjectArray();
			}
			if (this.items.length == 0 && this.tmr) window.clearTimeout(this.tmr);
			else if (this.items.length > 0) this.tmr = window.setTimeout('FD.Utils.Blink.Exec();', (this.show ? 1300 : 400));
		}
	}
}

FD.Script = new Object();
FD.Script.loadFile = function(filePath, onload, check_version) {
	if (check_version) filePath += '?' + this.getVersion(check_version);
	// Dynamically load the file (it can be a CSS or a JS)

	var e = document.createElement("script");
	e.type = "text/javascript";

	// Add the new object to the HEAD.
	document.getElementsByTagName("head")[0].appendChild(e);

	// Start downloading it.
	// Gecko fires the "onload" event and IE fires "onreadystatechange"
	if (onload) {
		e.onload = onload;
		if (FD.Browser.ie) {
			e.onreadystatechange = function() {
				if (this.readyState == 'complete') this.tmr = setTimeout(this.onload, 2000);
				if (this.readyState == 'loaded') {
					if (this.tmr > 0) clearTimeout(this.tmr);
					this.onload();
				}
			};
		}
	}
	e.src = filePath;
}
FD.Script.getVersion = function(scriptname) {
	var scripts = document.getElementsByTagName("script"), version = '';
	for (var i = 0; i < scripts.length; i++) {
		if (scripts[i].src.search(scriptname) > -1) {
			var match = /\?(.*)?/.exec(scripts[i].src);
			if (match) version = match[1];
			return version;
		}
	}
	return version;
}
FD.Script.getObject = function(scriptname) {
	var scripts = document.getElementsByTagName("script");
	for (var i = 0; i < scripts.length; i++) {
		if (scripts[i].src.search(scriptname) > -1) {
			return scripts[i];
		}
	}
	return null;
}
FD.Script.isLoaded = function(scriptname) {
	return (this.getObject(scriptname) ? true : false);
}

FD.Form = new Object();
var lLoading = FD.Form.isLoading = true;
FD.Form._loading_call_count = 0;
FD.Form.Info = { id: 0, id_visitor: 0, action: 0, lang: 0 };
FD.Form.Init = function() {
	window.focus();
	this.State.Enable(true);
	addEventHandler(window, 'onbeforeunload', FD.Form.OnClose);
	addEventHandler(window, 'onbeforeunload', writeSend);
	if (!FD.Browser.mac && !FD.Browser.opera && FD.Browser.ie && typeof document.getElementsByTagName != 'undefined') {
		var coll = document.getElementsByTagName('A'), el, match;
		for (var i = 0; i < coll.length; i++) {
			el = coll[i];
			if ((match = el.href.match(/(javascript\:)(.*)/)) != null && match[2].search(/void\(/) < 0) {
				el.fdFunc = unescape(match[2]);
				el.onmouseup = function() { eval(this.fdFunc); };
				el.href = (Browser.ie6 ? '#' : 'javascript:void(0)');
			}
		}
	}
	this.Params.Init();
	if (this.Params.Exist('logout')) {
		window.noForce = this.Params.Get('logout', 'true') == 'false';
	}
	this.Data.Fill();
	if ((this.Info.action <= 100 || this.Params.Get('r') == '') || this.Params.Exist('test')) this.Hidden.Hide();

	if (typeof CustomOnLoad != 'undefined') FDEvents.AttachEvent('AfterLoad', CustomOnLoad);
}
FD.Form.setLoading = function(loading, reset) {
	if (reset) this._loading_call_count = 0;
	else this._loading_call_count += (loading ? 1 : -1);
	if (this._loading_call_count > 0 && !loading) loading = true;
	this.isLoading = lLoading = loading;
}
FD.Form.Params = new Object();
FD.Form.Params._vars = null;
FD.Form.Params.Init = function() {
	if (this._vars) return; // already inited
	this._vars = getLocationVars(document.location.href, true);
	if (this._vars.exist('noinputnote')) setDisplay(document, 'trInputNote', false);
	if (this._vars.exist('nobutton')) setDisplay(document, 'trButtons', false);
}
FD.Form.Params.Get = function(name, alt, type) {
	if (!this._vars) this.Init();
	return this._vars.get(name, (arguments.length > 1 ? alt : null), (arguments.length > 2 ? type : null));
	//var val = this._vars.get(name, type);
	//return (val || arguments.length <= 1 ? val : alt);
}
FD.Form.Params.Exist = function(name) {
	if (!this._vars) this.Init();
	return this._vars.exist(name); // arraySearch( this._vars, name, 0 ) >= 0 ;
}
FD.Form.Params.Remove = function(name) {
	if (!this._vars) this.Init();
	this._vars[1].remove(name);
}
FD.Form.Action = new Object();
FD.Form.Action.Get = function(param, alt, type) {
	var vars = getLocationVars(document.builder.action);
	return vars.get(param, (arguments.length > 1 ? alt : null), (arguments.length > 2 ? type : null));
}
FD.Form.Action.Set = function(vars) {
	document.builder.action = setLocationVars(document.builder.action, vars);
}
FD.Form.Hidden = new Array();
FD.Form.Hidden._current = false;
FD.Form.Hidden._exec = false;
FD.Form.Hidden.Set = function(val) {
	var attrib, i, el;
	this._exec = true;
	this._current = val;
	for (i = 0; i < this.length; i++) {
		attrib = aFields.search(this[i]);
		FD.Form.setDisp(attrib.id, attrib.disp, val);
	}
	this._exec = false;
}
FD.Form.Hidden.Check = function(id) { return (!this._exec && this._current && this.search(id) >= 0); }
FD.Form.Hidden.Show = function() { this.Set(false); }
FD.Form.Hidden.Hide = function() { this.Set(true); }
FD.Form.Hidden.Toggle = function() { this.Set(!this._current); }

FD.Form.Data = new Object();
FD.Form.Data.Mode = 0; // 0 = array, 1 = ajax
FD.Form.Data.Values = FDAjaxArray();
FD.Form.Data.Fill = function(node) {

	FDEvents.FireEvent('BeforeDataFill');

	var child = (node ? node.firstChild : this.Values.firstChild), els, el, val, vals, type, i, option, alt;
	while (child) {
		if (child.nodeType == 1 /* ELEMENT_NODE */) {
			els = document.getElementsByName(child.nodeName);
			el = [];
			if (els) {
				for (i = 0; i < els.length; i++) {
					if (inList(els[i].tagName.toLowerCase(), 'input', 'textarea', 'select')) {
						el.push(els[i]);
					}
				}
				els = null;
			}
			if (el.length > 0) {
				type = Number.int(child.getAttribute('type'));
				val = child.firstChild ? child.firstChild.nodeValue : '';
				if (el.length == 1) {
					tagname = el[0].tagName.toLowerCase();
					if (tagname == 'select') {
						el[0].selectedIndex = -1;
						if (type == 20 /* USERLIST */) {
							el[0].length = 0;
							for (i = 0; i < val.length; i++) {
								option = addOption(null, el[0], unescape(val[i][0]), unescape(val[i][1]));
								if (val[i][2]) option.selected = true;
							}
						} else {
							val = unescape(this.getNodeValue(val, 'values'));
							for (i = 0; i < el[0].length; i++) {
								if (el[0].options[i].value == val || el[0].options[i].text.toLowerCase() == val.toLowerCase()) {
									el[0].selectedIndex = i;
									break;
								}
							}
						}
					} else if (tagname == 'input' && /^(radio|checkbox)$/.test((el[0].type ? el[0].type.toLowerCase() : ''))) {
						if (typeof val == 'object') {
							val = this.getNodeValue(val, 'values');
							el[0].checked = el[0].value == unescape(val);
						} else {
							el[0].checked = (val == 1 || this.stringToValue(val, 'boolean'));
						}
					} else if (type == 17 /* FILE */) {
						el = $('td' + child.nodeName);
						el.innerHTML = unescape(val);
						FD.Utils.doFile(child.nodeName, 2);
					} else if (type == 11 /* TEXTAREA */ && FD.Browser.safari && FD.Browser.VersionNr < 522 && typeof el[0].innerHTML != 'undefined') {
						el[0].innerHTML = unescape(val);
					} else {
						el[0].value = unescape(val);
					}
				} else { // it's an checkbox- or radiogroup
					vals = ',' + unescape(this.getNodeValue(val, 'values', '')) + ',';
					for (i = 0; i < el.length; i++) {
						if (typeof el[i].value == 'undefined') continue;
						el[i].checked = vals.search(FD.Utils.RegExp(',' + el[i].value + ',')) >= 0; //new RegExp(','+escape(el[i].value)+',').test(vals) ;
					}
					alt = unescape(this.getNodeValue(val, 'alt', ''));
					if (alt) {
						$('alt' + child.nodeName).value = alt;
						el[el.length - 1].checked = true;
						FD.Alt.Check(child.nodeName);
					}
				}
				/*} else if ( type == 22 fckeditor  ) {
				val = child.firstChild ? child.firstChild.nodeValue : '' ;
				fdEdts[ child.nodeName ].SetData( val ) ; */
			}
		}
		child = child.nextSibling;
	}
}
FD.Form.Data.getValue = function(nodeName) {
	var value = [], node;

	node = this.Values.selectSingleNode(nodeName);
	if (node) {
		els = document.getElementsByName(node.nodeName);
		el = [];
		if (els) {
			for (i = 0; i < els.length; i++) {
				if (inList(els[i].tagName.toLowerCase(), 'input', 'textarea', 'select')) {
					el.push(els[i]);
				}
			}
			els = null;
		}
		if (el.length > 0) {
			type = Number.int(node.getAttribute('type'));
			val = node.firstChild ? node.firstChild.nodeValue : '';
			if (el.length == 1) {
				tagname = el[0].tagName.toLowerCase();
				if (tagname == 'select') {
					if (type == 20 /* USERLIST */) {
						for (i = 0; i < val.length; i++) {
							if (val[i][2]) {
								value.push(unescape(val[i][0]));
								break;
							}
						}
					} else {
						val = unescape(this.getNodeValue(val, 'values'));
						value.push(val);
					}
				} else if (tagname == 'input' && /^(radio|checkbox)$/.test((el[0].type ? el[0].type.toLowerCase() : ''))) {
					if (typeof val == 'object') {
						val = this.getNodeValue(val, 'values');
						value.push(el[0].value == unescape(val));
					} else {
						value.push((val == 1 || this.stringToValue(val, 'boolean')));
					}
				} else {
					value.push(unescape(val));
				}
			} else { // it's an checkbox- or radiogroup
				vals = ',' + unescape(this.getNodeValue(val, 'values', '')) + ',';
				for (i = 0; i < el.length; i++) {
					if (typeof el[i].value == 'undefined') continue;
					if (vals.search(FD.Utils.RegExp(',' + el[i].value + ',')) >= 0) {
						value.push(el[i].value);
					}
				}
				alt = unescape(this.getNodeValue(val, 'alt', ''));
				if (alt) {
					value.push(alt);
				}
			}
		}
	}

	return value;
}
FD.Form.Data.getNodeValue = function(node, nodeName, alt) {
	if (this.Mode) return AJAX.getNodeValue(node, nodeName, alt);
	return (node && typeof node[nodeName] != 'undefined' ? node[nodeName] : (alt ? alt : ''));
}
FD.Form.Data.stringToValue = function(str, datatype) {
	switch (datatype) {
		case 'string': return str; break;
		case 'boolean': return (str == '1' || str.toLowerCase() == 'on' || str.toLowerCase() == '.t.' ? 1 : 0); break;
		case 'number': return parseFloat(str); break;
	}
	return str;
}
FD.Form.forceLogout = function() {
	if ((typeof window.noForce != 'undefined' && window.noForce) || FD.Form.Info.action > 100) return;
	var oWnd = OpenWindow(top, '', 200, 100, 'no', 'no');
	if (Object.is(oWnd)) {
		oWnd.document.write(unescape('%3Chtml%3E%3Chead%3E%3Ctitle%3E' + FD.Texts.get('FORCED_LOG_OUT') + '%3C/title%3E%3C/head%3E%3Cbody bgcolor=%22LightGrey%22 style=%22margin:0px%22%3E%3Ctable cellspacing=%220%22 cellpadding=%220%22 width=%22100%%22 height=%22100%22%3E%3Ctr%3E%3Ctd style=%22font-family: arial, verdana;font-size:10pt%22%3E%3Cimg border=%220%22 src="' + FD.Form.Info.label + 'images/key.gif" align=%22absmiddle%22%3E&nbsp;' + FD.Texts.get('FORCED_LOG_OUT') + '%3C/td%3E%3C/tr%3E%3C/table%3E%3C/body%3E%3C/html%3E'));
		oWnd.document.close();
		oWnd.setTimeout("document.location = '?lang=" + FD.Form.Info.lang + "&action=100&nextstep=65&close=true'", 10);
	} else {
		document.location = '?lang=' + FD.Form.Info.lang + '&action=100&nextstep=65';
	}
}
FD.Form.OnClose = function(e) {
	var self = FD.Form;
	if (FDEvents.FireEvent('OnClose')) {
		var msg = self.State.Check(e);
		if (msg != '') return msg;
	}
}
FD.Form.State = { isChanged: false, isStatic: false, Active: true, _text: '' };
FD.Form.State.setText = function(text) {
	this._text = text;
}
FD.Form.State.Enable = function(init) {
	window.isChanged = this.isChanged;
	//alert(window.noState);
	if (!init || typeof window.noState == 'undefined') {
		window.noState = !(this.Active = true);
	}
	if (!this.isStatic) {
		addEventHandler(document, 'onkeydown', FD.Form.State.Change);
		addEventHandler(document, 'onclick', FD.Form.State.Change);
	}
}
FD.Form.State.Static = function() {
	this.isStatic = true;
	this.Enable();
}
FD.Form.State.Disable = function() {
	var self = FD.Form.State;
	window.noState = !(self.Active = false);
	self.Stop();
}
FD.Form.State.Change = function(e, lpForce) {
	e = e || window.event;
	if (e && e.keyCode == 116) FD.Form.State.Disable();
	if (FD.Form.State.isChanged) return;
	if (e) {
		var el = checkEvent(e);
		if (!el || typeof el.tagName == 'undefined') return;
		if (e.type == 'click') {
			if (el.tagName == 'SELECT') {
				if (typeof el.oldValue == 'undefined') {
					el.oldValue = el.value;
					return;
				} else if (el.oldValue == el.value) return;
				el.oldValue = el.value;
			} else {
				el = FD.Utils.checkLabel(el);
				if (!el || el.tagName != 'INPUT' || !inList(el.type, 'checkbox', 'radio')) return;
			}
		}
		if (e.type == 'keydown' && (!inList(el.tagName, 'INPUT', 'TEXTAREA', 'SELECT') || (inList(e.keyCode, 9, 16, 17, 18, 33, 34, 35, 36, 37, 39) || inBetween(e.keyCode, 112, 123)))) return;
	}
	if (FDEvents.FireEvent('OnStateChange', e)) {
		FD.Form.State.isChanged = window.isChanged = true;
		FD.Form.State.Stop();
	}
}
FD.Form.State.Stop = function() {
	removeEventHandler(document, 'onkeydown', FD.Form.State.Change);
	removeEventHandler(document, 'onclick', FD.Form.State.Change);
}
FD.Form.State.Check = function(e) {
	var self = FD.Form.State;
	if (!window.Submitted && (self.isChanged || window.isChanged || self.isStatic)) {
		if (!FD.Form.Info.soc) {
			if (self.Active && !window.noState) {
				e.returnValue = e.message = (self._text ? self._text : FD.Texts.get('ALERT_CANCEL_FORM'));
			}
			return e.message;
		} else {
			FD.Form.silentSubmit();
		}
	}
	return '';
}

FD.Form.silentSubmit = function() {
	if (FD.Form.Params.Exist('r')) return true; // no submit when a form is edited or inserted from the results summary
	try { if (typeof AJAX == 'undefined' || !AJAX.checkEnabled()) return true; } catch (e) { return true; }
	FDEvents.FireEvent('AfterSubmitForm', { action: 0 });
	var url = document.builder.action;
	var data = {
		url: url + '&xml=true',
		async: false,
		verb: 'POST',
		content: AJAX.Utils.collectFormData(document.builder)
	};
	var req = AJAX.sendRequest(data);
	if (req.status == 200) {
		try {
			var oData = req.responseXML, node = oData.selectNodes('//result').item(0);
		} catch (e) { return true; }
		if (Number.int(AJAX.getNodeValue(node, 'code', '')) == 0) {
			node = node.selectSingleNode('value/form');
			document.builder.txtUPD.value = AJAX.getNodeValue(node, 'upd');
			var id = Number.int(AJAX.getNodeValue(node, 'id'));
			if (id > 0) document.builder.action = setLocationVars(url, ['id_form_visitor', id]);
			//alert(document.builder.action);
		}
	}
}

FD.Form.setDisp = function(npEl, npType, lpRule, npPage, cpIdent) {
	if (npType == 0) {
		var attrib = aFields.search(npEl);
		npType = attrib.disp;
	}
	if (FD.Form.Hidden.Check(npEl)) return;
	var cEl = 'tdA' + npEl, oEl = $(cEl), nOpt = 1;
	if (oEl) setDisplay(null, oEl, !lpRule);
	else {
		while ((oEl = getElement(document, 'tdA' + npEl + 'cell' + nOpt))) {
			cEl = 'tdA' + npEl + 'cell' + nOpt;
			setDisplay(null, oEl, !lpRule);
			nOpt++;
		}
	}
	if (npType == 1 || npType == 2) {
		setDisplay(document, 'tdQ' + npEl, !lpRule);
		cEl = 'tdQ' + npEl;
	}
	if (npType == 2) {
		setDisplay(document, 'tdQA' + npEl, !lpRule);
		cEl = 'tdQA' + npEl;
	}
	if (this.Info.qno && npType < 3) setDisplay(document, 'tdN' + npEl, !lpRule);
	this.checkRowDisplay(cEl);
}
FD.Form.checkRowDisplay = function(vpEl) {
	var oEl = getElement(document, vpEl);
	if (oEl) {
		var nLvl = Number.int(oEl.getAttribute('fd:lvl'));
		oEl = oEl.parentNode;
		while (nLvl > 0 && oEl && oEl.parentNode) {
			oEl = oEl.parentNode;
			if (oEl.tagName && oEl.tagName == 'TR') nLvl--;
		}
		if (oEl) setRowDisplay(oEl);
	}
}

FD.Alt = new Object();
FD.Alt.Items = new Array();
FD.Alt.isEventSet = false;
FD.Alt.Add = function(name) {
	this.Items.push(name);
	var el = getElement(document, name);
	if (typeof el[0] == 'undefined')
		el.onclick = function() { FD.Alt.Check(this.name); };
	else {
		for (var i = 0; i < el.length; i++) {
			if (el[i].onclick) el[i].prevOnClick = el[i].onclick;
			el[i].onclick = function(e) { FD.Alt.Check(this.name); if (this.prevOnClick) this.prevOnClick(e); };
		}
	}
	if (!this.isEventSet) {
		this.isEventSet = true;
		FDEvents.AttachEvent('AfterLoad', function() { FD.Alt.Init(); });
	}
}
FD.Alt.Check = function(name) {
	var el = getElement(document, name);
	setDisabled(document, "alt" + name, !(typeof el[0] != 'undefined' ? el[el.length - 1].checked : el.checked), true);
}
FD.Alt.Init = function() {
	for (var i = 0; i < this.Items.length; i++) {
		this.Check(this.Items[i]);
	}
}

FD.Debug = new Object();
FD.Debug.trace = FD.Debug.deprecated = FD.Debug.reportError = function() { ; };

FD.Security = new Object();

/* This function/object checks for Internet Security software */
FD.Security.checkIS = function(opWND) {

	var obj = { IS: false, Continue: true };

	opWND = (typeof opWND == 'object' ? opWND : window);
	var cOnError = new String(opWND.onerror), cOpen = new String(opWND.open);
	if (typeof opWND.onerror != 'undefined' && cOnError.search('native') <= -1 && cOnError.search('fdOnError') <= -1 && cOnError.search('FD.') <= -1) {
		obj.IS = true;
		opWND.onerror = null;
	}
	if (opWND.open && ((!FD.Browser.safari && cOpen.search('native') <= -1) || (FD.Browser.safari && cOpen != '[function]'))) {
		obj.IS = true;
		if (opWND.SymRealWinOpen)
			opWND.open = opWND.SymRealWinOpen;
		else
			obj.Continue = false;
	}

	return obj;
}

function FD_Texts(texts) {
	if (texts) this.set(texts);
}
FD_Texts.prototype.set = function(texts) {
	for (var key in texts) {
		this[key] = texts[key];
	}
}
FD_Texts.prototype.get = function(key, alt) {
	return unescape((this[key] ? this[key] : (alt ? alt : '')));
}
FD_Texts.prototype.create = function(sub, texts) {
	if (this[sub]) this[sub].set(texts);
	else this[sub] = new FD_Texts(texts);
}

try {
	if (top.FD && typeof top.FD.Texts != 'undefined')
		FD.Texts = top.FD.Texts;
	else if (top.opener && typeof top.opener.top.FD != 'undefined' && typeof top.opener.top.FD.Texts != 'undefined')
		FD.Texts = top.opener.top.FD.Texts;
	else
		throw "Create your own Texts object!";
} catch (e) {
	FD.Texts = new FD_Texts();
}

function checkMain(params) {
	if (document.location.search.search('newwindow') == -1) {
		if (self.name != 'frmMain') {
			cLoc = '/?'
			var cLang = (getLocationVar(document.location.href, 'lang') || params.lang);
			if (cLang) cLoc += 'lang=' + cLang + '&';
			var nId_Aff = (Number.int(getLocationVar(document.location.href, 'id_aff')) || params.id_aff);
			if (nId_Aff) cLoc += 'id_aff=' + nId_Aff + '&';
			var cKeyword = (getLocationVar(document.location.href, 'keyword') || params.keyword);
			if (cKeyword) cLoc += 'keyword=' + cKeyword + '&';
			var cHRef = document.location.href;
			if (params.url_params) cHRef = setLocationVars(cHRef, params.url_params);
			top.location = cLoc + 'frmMain=' + URLEncode(cHRef);
		} else {
			switch (params.type) {
				case 'menu':
					this.menuItem = params.item;
					if (parent.frames[1].menuSelect)
						parent.frames[1].menuSelect(this.menuItem);
					break;
				case 'landing':
					top.setLandingOption(document.location.href, params.text);
					break;
			}
		}
	}
}
function Register(lang, id_aff) {
	document.location = '/?action=2&nextstep=1&lang=' + (lang || getLang()) + (id_aff ? '&id_aff=' + id_aff : '');
}
function getLang() {
	var nLang = Number.int(getLocationVar(document.location.href, 'lang'));
	if (nLang == 0) {
		var aHost = document.location.hostname.split('.');
		switch (aHost[aHost.length - 1]) {
			case 'nl': nLang = 1; break;
			case 'com': nLang = 2; break;
			case 'co.uk': nLang = 2; break;
			case 'de': nLang = 4; break;
			case 'net': nLang = 1; break;
		}
	}
	return nLang;
}

function setStatus(cpStatus, opWnd) {
	var lGlobal = false;
	try { lGlobal = (Object.is(top.Global)); } catch (e) { }
	opWnd = opWnd || window;
	opWnd.status = ((lGlobal) ? top.Global.Status : '') + ((typeof cpStatus == 'string' && cpStatus != '') ? ((lGlobal) ? ': ' : '') + cpStatus : '');
	return true;
}

function addActionVar(opForm, cpVar, lpReplace) {
	var aAction = opForm.action.split('?');
	var cAction = aAction[0] + ((lpReplace || aAction.length == 1) ? '?' : aAction[1] + '&') + cpVar;
	opForm.action = cAction;
}

FD.Cookie = new Object();
FD.Cookie.getAll = function(cookies) {
	return FDKeyArray((cookies ? cookies : document.cookie).split('; '), true);
}
FD.Cookie.Get = function(cookie, cookies) {
	cookies = FD.Cookie.getAll((arguments.length > 1 ? cookies : null));
	return cookies.get(cookie, false);
}
FD.Cookie.Exist = function(cookie, cookies) {
	cookies = FD.Cookie.getAll((arguments.length > 1 ? cookies : null));
	return cookies.exist(cookie);
}
FD.Cookie.Set = function(cookie, value, expireDays) {
	var val = '';
	if (typeof value == 'object') {
		for (var key in value) {
			val += ("&" + key + "=" + escape(value[key]));
		}
		val = val.substr(1);
	} else {
		val = value;
	}
	cookie = cookie + "=" + escape(val);
	if (arguments.length > 2) {
		var exdate = new Date();
		exdate.setDate(exdate.getDate() + expireDays);
		cookie += ";expires=" + exdate.toGMTString();
	}
	document.cookie = cookie;
}
FD.Cookie.Delete = function(cookie) {
	if (this.Exist(cookie)) {
		document.cookie = cookie + "=; expires=Thu, 01-Jan-70 00:00:01 GMT";
	}
}

function getCookies(cookies) {
	FD.Debug.deprecated(getCookies, 'deprecated! use FD.Cookie.getAll instead');
	return FD.Cookie.getAll((arguments.length > 0 ? cookies : null));
}
function getCookie(cookies, cookie) {
	FD.Debug.deprecated(getCookie, 'deprecated! use FD.Cookie.Get instead');
	return FD.Cookie.Get(cookie, cookies);
}

function getLocationVars(location, decode) {
	// de pagina en de parameters scheiden
	var loc = location.split('?'), bookmark = '';
	decode = decode || false;
	// de parameters scheiden
	if (loc.length > 1) {
		var bm = loc[1].search('#');
		if (bm >= 0) {
			bookmark = loc[1].substr(bm);
			loc[1] = loc[1].substr(0, bm);
		}
		loc[1] = FDKeyArray(loc[1].split('&'), decode);
	} else
		loc[1] = FDKeyArray();

	if (bookmark.length > 0)
		loc[1][loc[1].length] = new Array(bookmark);

	loc.get = function(name, alt, type) {
		return this[1].get(name, alt, type);
	}
	loc.exist = function(name) {
		return this[1].exist(name);
	}
	loc.set = function(name, value) {
		return this[1].set(name, value);
	}
	return loc;
}

function getLocationVar(location, qvar) {
	var vars = (Array.is(location) ? location : getLocationVars(location, true));
	return vars.get(qvar, false);
}

function setLocationVars(location, vars, nobookmark) {
	// de pagina en de parameters scheiden
	var loc = (Array.is(location) ? location : getLocationVars(location, true));

	// zoeken en vervangen/toevoegen van de meegegeven parameter/waarde array
	if (vars) loc[1].merge(vars);
	
	// de locatiestring weer opbouwen
	location = loc[0] + '?' + loc[1].toString(!nobookmark);

	return (location);
}

function delLocationVars(location, vars) {
	// de pagina en de parameters scheiden; de parameters scheiden
	var loc = location.split('?'), qvars = (loc.length > 1) ? loc[1].split('&') : new Array();

	// de parameters en de waarden scheiden
	var i, nIndex = -1;
	for (i = 0; i < qvars.length; i++)
		qvars[i] = qvars[i].split('=');

	// de locatiestring weer opbouwen
	location = loc[0] + '?';
	for (i = 0; i < qvars.length; i++) {
		if (arraySearch(vars, qvars[i][0], 0) == -1) {
			location = location + ((i > 0) ? '&' : '') +
				qvars[i][0] + ((qvars[i][0].length > 0) ? '=' : '') + qvars[i][1];
		}
	}
	return location;
}

function arraySearch(apArray, vpSearchFor, npColumn, npColumns, npStart) {
	if (apArray.length == 0) return -1;
	npColumn = (typeof npColumn == 'undefined') ? 0 : npColumn;
	npColumns = (typeof npColumns == 'undefined') ? 1 : npColumns;
	npStart = (typeof npStart == 'undefined') ? 0 : npStart;
	var i = 0, l2d = (Object.is(apArray[0]) && typeof apArray[0][0] != 'undefined');
	if (l2d) {
		for (i = npStart; i < apArray.length; i++) {
			if ((typeof apArray[i][npColumn] == 'string' && apArray[i][npColumn].toUpperCase() == String(vpSearchFor).toUpperCase()) || apArray[i][npColumn] == vpSearchFor)
				return i;
		}
	} else {
		for (i = npStart + npColumn; i < apArray.length; i = i + npColumns) {
			if ((typeof apArray[i] == 'string' && apArray[i].toUpperCase() == String(vpSearchFor).toUpperCase()) || apArray[i] == vpSearchFor)
				return i;
		}
	}
	return -1;
}

function arrayDelete(apArray, npIndexFrom, npIndexTo) {
	if (npIndexFrom < 0) return apArray;
	npIndexTo = npIndexFrom + (typeof npIndexTo == 'undefined' ? 1 : npIndexTo);
	var aTemp = null;
	if (apArray.length == 1 && npIndexFrom == 0)
		aTemp = new Array();
	else {
		if (npIndexFrom > 0)
			aTemp = apArray.slice(0, npIndexFrom);
		if (npIndexFrom >= 0 && npIndexFrom < apArray.length - 1)
			aTemp = (aTemp != null ? aTemp.concat(apArray.slice(npIndexTo)) : apArray.slice(npIndexTo));
	}

	return (aTemp);
}

function arrayMove(apArray, npFrom, npTo) {
	if (npFrom == npTo) return apArray;

	var vElement = apArray[npFrom], i = 0;
	if (npFrom < npTo) {
		for (i = npFrom; i < npTo; i++)
			apArray[i] = apArray[i + 1];
	} else {
		for (i = npFrom; i > npTo; i--)
			apArray[i] = apArray[i - 1];
	}
	apArray[npTo] = vElement;

	return apArray;
}

function arraySort(apArray, npColl) {
	var i = 0, j = 0, nIndex = 0, lColl = typeof (npColl) == 'number';
	for (i = 0; i < apArray.length; i++) {
		nIndex = i;
		for (j = i; j < apArray.length - 1; j++) {
			if (lColl) {
				if (apArray[j + 1][npColl] < apArray[nIndex][npColl]) nIndex = j + 1;
			} else if (apArray[j + 1] < apArray[nIndex]) nIndex = j + 1;
		}
		arrayMove(apArray, nIndex, i);
	}

	return apArray;
}

function URLEncode(cpString, cpSAFECHARS, lpUrl) {
	// The Javascript escape and unescape functions do not correspond
	// with what browsers actually do...
	var SAFECHARS = "0123456789" + 				// Numeric
					"ABCDEFGHIJKLMNOPQRSTUVWXYZ" + // Alphabetic
					"abcdefghijklmnopqrstuvwxyz" +
					"-_.!~*'()" + (cpSAFECHARS || ''); // RFC2396 Mark characters
	var HEX = "0123456789ABCDEF";

	var cEncoded = "";
	for (var i = 0; i < cpString.length; i++) {
		var ch = cpString.charAt(i);
		if (ch == " ") {
			cEncoded += (lpUrl ? "%20" : "+"); 			// x-www-urlencoded, rather than %20
		} else if (SAFECHARS.indexOf(ch) != -1) {
			cEncoded += ch;
		} else {
			var charCode = ch.charCodeAt(0);
			cEncoded += "%";
			cEncoded += HEX.charAt((charCode >> 4) & 0xF);
			cEncoded += HEX.charAt(charCode & 0xF);
		}
	} // for

	return cEncoded;
}
if (typeof encodeURIComponent == 'undefined') var encodeURIComponent = URLEncode;
function URLEncodeFull(cpString) {
	var aUrl = cpString.match(/(http(s?)\:\/\/)?([^\?]+)(\?(.*))?/); // MSIE 5.0 compatible
	// ((?:http(?:s?))\:\/\/)?([^\?]+)(?:\?(.*))? // MSIE 5.5+ compatible
	if (aUrl) return ((aUrl[1] ? aUrl[1] : '') + URLEncode(aUrl[3], '/%', true) + (aUrl[5] && aUrl[5].length > 0 ? '?' + URLEncode(aUrl[5], '&=') : ''));
	else return ('');
}
function URLDecode(cpString) {
	// Replace + with ' '
	// Replace %xx with equivalent character
	var cDecoded = "", i = 0;
	while (i < cpString.length) {
		var ch = cpString.charAt(i);
		if (ch == "+") {
			cDecoded += " ";
			i++;
		} else if (ch == "%" && cpString.charAt(i + 1) != "%") {
			cDecoded += unescape(cpString.substr(i, 3));
			i += 3;
		} else {
			cDecoded += ch;
			i++;
		}
	} // while
	if (i < cpString.length) {
		cDecoded += cpString.substr(i, cpString.length - i);
	}

	return unescape(cDecoded);
}
if (typeof decodeURIComponent == 'undefined') var decodeURIComponent = URLDecode;

function OpenWindow(opWindow, cpPage, npWidth, npHeight, cpScroll, cpStatus, cpToolbar, cpName, opParentProp, lpDialog, vpArg) {
	var lParent = (typeof opParentProp == 'object'), cScroll = (cpScroll ? cpScroll : 'yes');
	var cStatus = (cpStatus ? cpStatus : 'yes'), cToolbar = (cpToolbar ? cpToolbar : 'no');
	var nAvailWidth = 0, nAvailHeight = 0; //, oDim = new getWindowDim( window, true );
	//if( window.screen ){
	nAvailWidth = window.screen.availWidth;
	nAvailHeight = window.screen.availHeight - (Browser.ie ? 60 : 56);
	//}
	var nWidth = 0, nHeight = 0, nTop = 0, nLeft = 0;
	npWidth = (typeof npWidth == 'undefined' ? (lParent ? 0 : nAvailWidth) : (npWidth > nAvailWidth ? nAvailWidth : npWidth));
	npHeight = (typeof npHeight == 'undefined' ? (lParent ? 0 : nAvailHeight) : ((npHeight + 32) >= nAvailHeight ? nAvailHeight - 50 : npHeight));
	lpDialog = lpDialog && Browser.ie;
	if (lParent) {
		var oWnd = opParentProp.Window;
		oDim = new getWindowDim(oWnd, true);
		nWidth = oDim.outerWidth, nHeight = oDim.outerHeight, nTop = oDim.Top, nLeft = oDim.Left;

		nWidth = nWidth - opParentProp.offsetWidth - 12 - (Browser.ie ? 6 : 0); //scrollbar;  && cScroll != 'yes'
		nHeight = nHeight - opParentProp.offsetHeight - 26 - (cStatus == 'yes' ? 37 : 0);
		nTop = nTop + (opParentProp.offsetHeight / 2);
		nLeft = nLeft + (opParentProp.offsetWidth / 2);
	}
	nWidth = Math.max(nWidth, npWidth);
	nHeight = Math.max(nHeight, npHeight);

	if (!lParent || (nLeft + nWidth > nAvailWidth))
		nLeft = (nAvailWidth / 2) - ((nWidth + (cScroll == 'yes' ? 8 : 0)) / 2);
	if (!lParent || (nTop + nHeight > nAvailHeight))
		nTop = (nAvailHeight / 2) - (nHeight / 2) - 25;
	if (nTop < 0) nTop = 0;
	var oFromWindow = ((Object.is(opWindow)) ? opWindow : window), oWindow = null, vReturn;
	if (lpDialog)
		vReturn = oFromWindow.showModalDialog(cpPage, (vpArg ? vpArg : window), 'dialogWidth:' + nWidth + 'px;dialogHeight:' + nHeight + 'px;center:yes;scroll:' + cScroll + ';status:' + cStatus);
	else
		oWindow = oFromWindow.open(cpPage, (cpName ? cpName : ''), 'toolbar=' + cToolbar + ',directories=no,menubar=no,status=' + cStatus + ',resizable=yes,scrollbars=' + cScroll + ',top=' + nTop + ',left=' + nLeft + ',width=' + nWidth + ',height=' + nHeight);

	return (lpDialog ? vReturn : (Object.is(oWindow, 'document') ? oWindow : null));
}

function maximizeWindow(npMaxWidth, npMaxHeight) {
	var nAvailWidth = window.screen.availWidth, nAvailHeight = window.screen.availHeight;
	var nWidth = (npMaxWidth > nAvailWidth) ? nAvailWidth : npMaxWidth;
	var nHeight = ((npMaxHeight + 32) >= nAvailHeight) ? nAvailHeight - 50 : npMaxHeight;
	var nLeft = (nAvailWidth / 2) - (nWidth / 2);
	var nTop = (nAvailHeight / 2) - (nHeight / 2) - 25;
	if (nTop < 0) nTop = 0;
	window.moveTo(nLeft, nTop);
	window.resizeTo(nWidth, nHeight);
}

function centerWindow(opWnd) {
	var oDim = new getWindowDim(opWnd, true);
	var nTop = Math.max((oDim.availHeight / 2) - (oDim.outerHeight / 2) - (Browser.ie ? 25 : 0), 0);
	var nLeft = Math.max((oDim.availWidth / 2) - (oDim.outerWidth / 2), 0);
	opWnd.moveTo(nLeft, nTop);
	//	oDim = new getWindowDim( opWnd, true );
	//	alert(oDim.availWidth+ '; '+nTop+', ' + nLeft+'; '+oDim.Top+', '+oDim.Left + ', ' + oDim.outerWidth+', ' + opWnd.scrollbars);
}

function getWindowDim(opWnd, lpCreated) {
	if (!lpCreated) return (new getWindowDim(opWnd, true));

	this.outerWidth = 0, this.outerHeight = 0, this.clientWidth = 0, this.clientHeight = 0, this.scrollTop = 0, this.scrollLeft = 0;
	this.Top = 0, this.Left = 0, this.availWidth = opWnd.screen.availWidth, this.availHeight = opWnd.screen.availHeight;
	with (this) {
		if (Browser.gecko || Browser.safari) {
			availHeight = availHeight - 56;
			Top = opWnd.screenY;
			Left = opWnd.screenX;
			outerWidth = opWnd.outerWidth;
			outerHeight = opWnd.outerHeight + 2;
			clientWidth = opWnd.innerWidth;
			clientHeight = opWnd.innerHeight;
			scrollTop = opWnd.pageYOffset;
			scrollLeft = opWnd.pageXOffset;
		} else if (Browser.ie) {
			availHeight = availHeight - 60;
			Top = opWnd.screenTop;
			Left = opWnd.screenLeft;
			if (opWnd.document.body) {
				outerWidth = opWnd.document.body.offsetWidth + 6; // -6 voor de scrollbar
				outerHeight = opWnd.document.body.offsetHeight;
				clientWidth = opWnd.document.body.clientWidth;
				clientHeight = opWnd.document.body.clientHeight;
				scrollTop = opWnd.document.body.scrollTop;
				scrollLeft = opWnd.document.body.scrollLeft;
			}
		}
	}
}

function Select(opDoc, vpEl, lpNoError) {
	var oEl = getElement(opDoc, vpEl);
	if (typeof oEl[0] != 'undefined' && (typeof oEl.tagName == 'undefined' || oEl.tagName != 'SELECT')) oEl = oElement[0];
	if (typeof oEl.type != 'undefined' && oEl.type == 'hidden') return;
	if ((typeof oEl.disabled == 'undefined' || !oEl.disabled) && (typeof oEl.readOnly == 'undefined' || !oEl.readOnly)) {
		if (Browser.W3C) {
			try {
				if (typeof oEl.focus != 'undefined') oEl.focus();
				if (typeof oEl.select != 'undefined') oEl.select();
			} catch (e) { }
		} else {
			if (typeof oEl.focus != 'undefined') oEl.focus();
			if (typeof oEl.select != 'undefined') oEl.select();
		}
	}
}

function SwapImage(opDocument, cpImgName, cpImg, cpImgDir) {
	opDocument.images[cpImgName].src = (typeof cpImgDir != 'undefined' ? cpImgDir : 'images/') + cpImg;
}

// deprecated; use isEmpty instead
function CheckEmpty(str, lpNoLength) {
	return String.create(str).empty(lpNoLength);
}
var __tmp = {
	isObject: function(vpEl, cpTest) {
		return (vpEl != null && (typeof vpEl == 'object' || typeof vpEl == 'function') && (typeof cpTest == 'undefined' || (eval('typeof vpEl.' + cpTest) != 'undefined' && eval('typeof vpEl.' + cpTest) != 'unknown')));
	},
	isString: function(a) {
		return (typeof a == 'string');
	},
	isNumber: function(a) {
		return (typeof a == 'number' && !isNaN(a));
	},
	isArray: function(a) {
		return (typeof a == 'object' && String(a.constructor).trim() == String(Array).trim());
	},
	isCollection: function(a) {
		return ((typeof a == 'object' || (Browser.safari && typeof a == 'function')) && typeof a[0] != 'undefined');
	},
	isFunction: function(a) {
		return (typeof a == 'function');
	},
	isEmpty: function(str, nolength) {
		if (typeof str == 'undefined' || str == null) return true;
		return str.empty(nolength);
	},
	isEmptyVal: function(opDoc, vpEl) {
		var el = getElement(opDoc, vpEl);
		if (!Object.is(el)) return true;
		if (typeof el.tagName == 'undefined' && typeof el[0] != 'undefined')
			return getSelectedOption(null, el, 2) == -1;
		else return String.create(el.value).empty();
	},
	inList: function() {
		var value = arguments[0];
		for (var i = 1; i < arguments.length; i++) {
			if (value == arguments[i]) return true;
		}
		return false;
	},
	inBetween: function(npTestVal, npLowVal, npHighVal) {
		return (npTestVal >= npLowVal && npTestVal <= npHighVal);
	}
};
Object.extend(window, __tmp);
Object.extend(FDUtils, __tmp);

// isDate was already in use by a client, so we called it FD_isDate. thats wy the isDate is not initially included in the FDUtils
function FD_isDate(a) {
	return (Object.is(a) && a.constructor == Date);
}

Date.is = FD_isDate;
Object.is = __tmp.isObject;
String.is = __tmp.isString;
Number.is = __tmp.isNumber;
Array.is = __tmp.isArray;
Function.is = __tmp.isFunction;
Math.between = __tmp.inBetween;


/**
*
*  Javascript sprintf
*  http://www.webtoolkit.info/
*
*
**/
sprintfWrapper = {

	init: function() {

		if (typeof arguments == "undefined") { return null; }
		if (arguments.length < 1) { return null; }
		if (typeof arguments[0] != "string") { return null; }
		if (typeof RegExp == "undefined") { return null; }

		var string = arguments[0];
		var exp = new RegExp(/(%([%]|(\-)?(\+|\x20)?(0)?(\d+)?(\.(\d)?)?([bcdfosxX])))/g);
		var matches = new Array(), strings = new Array();
		var convCount = 0, stringPosStart = 0, stringPosEnd = 0, matchPosEnd = 0, newString = '', match = null;

		while (match = exp.exec(string)) {
			if (match[9]) { convCount += 1; }

			stringPosStart = matchPosEnd;
			stringPosEnd = exp.lastIndex - match[0].length;
			strings[strings.length] = string.substring(stringPosStart, stringPosEnd);

			matchPosEnd = exp.lastIndex;
			matches[matches.length] = { match: match[0], left: match[3] ? true : false, sign: match[4] || '', pad: match[5] || ' ', min: match[6] || 0, precision: match[8], code: match[9] || '%', negative: parseInt(arguments[convCount]) < 0 ? true : false, argument: String(arguments[convCount]) };
		}
		strings[strings.length] = string.substring(matchPosEnd);

		if (matches.length == 0) { return string; }
		if ((arguments.length - 1) < convCount) { return null; }

		var code = null;
		var match = null;
		var i = null;

		for (i = 0; i < matches.length; i++) {

			if (matches[i].code == '%') { substitution = '%' }
			else if (matches[i].code == 'b') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(2));
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'c') {
				matches[i].argument = String(String.fromCharCode(parseInt(Math.abs(parseInt(matches[i].argument)))));
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'd') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'f') {
				matches[i].argument = String(Math.abs(parseFloat(matches[i].argument)).toFixed(matches[i].precision ? matches[i].precision : 6));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'o') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(8));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 's') {
				matches[i].argument = matches[i].argument.substring(0, matches[i].precision ? matches[i].precision : matches[i].argument.length)
				substitution = sprintfWrapper.convert(matches[i], true);
			}
			else if (matches[i].code == 'x') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
				substitution = sprintfWrapper.convert(matches[i]);
			}
			else if (matches[i].code == 'X') {
				matches[i].argument = String(Math.abs(parseInt(matches[i].argument)).toString(16));
				substitution = sprintfWrapper.convert(matches[i]).toUpperCase();
			}
			else {
				substitution = matches[i].match;
			}

			newString += strings[i];
			newString += substitution;

		}
		newString += strings[i];

		return newString;

	},

	convert: function(match, nosign) {
		if (nosign) { match.sign = ''; }
		else { match.sign = match.negative ? '-' : match.sign; }
		var l = match.min - match.argument.length + 1 - match.sign.length;
		var pad = new Array(l < 0 ? 0 : l).join(match.pad);
		if (!match.left) {
			if (match.pad == "0" || nosign) { return match.sign + pad + match.argument; }
			else { return pad + match.sign + match.argument; }
		} else {
			if (match.pad == "0" || nosign) { return match.sign + match.argument + pad.replace(/0/g, ' '); }
			else { return match.sign + match.argument + pad; }
		}
	}
}

String.sprintf = sprintfWrapper.init;


function getElement(doc, vel) {
	var el = null;
	if (Object.is(vel)) return vel;
	if (!Object.is(doc)) return el;

	if (Browser.W3C) {
		if (typeof doc.getElementsByName == 'function') {
			el = doc.getElementsByName(vel);
			if ((Browser.ie && Browser.VersionNr >= 7) || Browser.opera) {
				el = $.correct(el, vel);
			}
		}
		if (!Object.is(el) || el.length == 0) {
			el = (typeof doc.getElementById == 'function' ? doc.getElementById(vel) : null);
		} else if (el.length == 1) {
			el = el[0];
		}
	}

	if (Object.is(el)) return el;

	if (typeof doc.forms != 'undefined' && doc.forms.length > 0)
		el = doc.forms[0].elements[vel];

	if (Object.is(el)) return el;
	if (Browser.ie) el = doc.all[vel];
	return el;
}
function $(id) {
	var el = null;
	if (document.getElementsByName) {
		el = document.getElementsByName(id);
		if ((Browser.ie && Browser.VersionNr >= 7) || Browser.opera) { // there is a terrible bug in IE8 also returning elements with a matching ID without a matching Name. Because of the browser compatibility feature of IE8 this is also applicable for the IE7 useragent string
			el = $.correct(el, id);
		}
	}
	if (!Object.is(el) || el.length == 0)
		el = (document.getElementById ? document.getElementById(id) : null);
	else if (el.length == 1)
		el = el[0];
	return el;
}
$.correct = function(arr, id) {
	arr = $A(arr);
	for (var i = arr.length - 1; i >= 0; i--) {
		if (typeof arr[i].name == 'undefined' || arr[i].name != id) {
			arr.splice(i, 1);
		}
	}
	return arr;
}

function getElementByIndex(from, npIndex) {
	var el = null;
	if (Browser.W3C) {
		if (from.all)
			el = from.all[npIndex];
		else if (from.elements)
			el = from.elements[npIndex];
	}
	if (Browser.ns) {
		if (from.elements)
			el = from.elements[npIndex];
		else if (from.forms && from.forms.length > 0 && npIndex <= from.forms[0].elements.length)
			el = from.forms[0].elements[npIndex];
	}
	return el;
}

function focusElement(from, vel) {
	try {
		if (from.forms && from.forms.length == 0) return;
	} catch (e) { return; }
	var el, i, lFocus = false;
	if (typeof vel == 'string')
		el = getElement(from, vel);
	else if (typeof vel == 'number') {
		var nel = (vel < 0 ? 0 : vel), l;
		el = getElementByIndex(from, nel);
		while (Object.is(el)) {
			//alert(oEl.name);
			if (typeof el[0] != 'undefined' && (typeof el.tagName == 'undefined' || el.tagName != 'SELECT')) {
				while (i < el.length && !l)
					l = checkFocus(el[i], vel);
				if (l) break;
			} else {
				if (checkFocus(el, vel)) break;
			}
			nel++;
			el = getElementByIndex(from, nel);
		}
	} else
		el = vel;
	if (Object.is(el)) {
		if (typeof el[0] != 'undefined' && (typeof el.tagName == 'undefined' || el.tagName != 'SELECT')) {
			while (i < el.length && !(lFocus = focusElement(from, el[i]))) i++;
		} else if (typeof el.focus != 'undefined') {
			l = !el.disabled && (!el.style || (el.style.display != 'hide' && el.style.visibility != 'hidden'));
			if (l) {
				if (Browser.ns && Browser.VersionNr < 5) {
					el.focus();
					lFocus = true;
				} else {
					eval(
						"try{" +
							"el.focus(); lFocus = true;" +
						"}catch(e){ lFocus = false; }"
					);
				}
			}
		}
	}
	return (lFocus);
}
function checkFocus(el, nel) {
	var l = !el.disabled && (!el.style || (el.style.display != 'hide' && el.style.visibility != 'hidden'));
	if (nel < 0 && (typeof el.value != 'undefined' || typeof el.checked != 'undefined') && l) return true;
	if (nel >= 0 && typeof el.focus != 'undefined' && l) return true;
	return false;
}

function setDisabled(doc, vpObject, lpDisabled, lpAdvanced, lpDontEmptyValue, cpBgColor, lpNoEvents) {
	doc = doc || document;
	if (typeof cpBgColor != 'string') cpBgColor = '#E1E1E1';
	if (Array.is(vpObject)) {
		for (var i = 0; i < vpObject.length; i++)
			setDisabled(doc, vpObject[i], lpDisabled, lpAdvanced, lpDontEmptyValue, cpBgColor);
		return;
	}
	var oEl = getElement(doc, vpObject), lArray = (oEl && typeof oEl[0] != 'undefined');
	if (Object.is(oEl)) {
		if (lArray && (typeof oEl.tagName == 'undefined' || oEl.tagName != 'SELECT')) {
			for (var i = 0; i < oEl.length; i++) {
				if (typeof oEl[i].disabled != 'undefined' && oEl[i].disabled != lpDisabled) {
					oEl[i].disabled = lpDisabled;
					if (typeof oEl[i].type != 'undefined' && (oEl[i].type == 'checkbox' || oEl[i].type == 'radio')) {
						if (!lpDontEmptyValue) {
							if (lpDisabled) {
								oEl[i].oldValue = oEl[i].checked;
								oEl[i].checked = false;
							} else
								oEl[i].checked = oEl[i].oldValue;
							if (oEl[i].onclick && !lpNoEvents)
								fireEvent(oEl[i], 'onclick');

						}
						if (i == oEl.length - 1)
							setDisabled(document, 'alt' + oEl[i].name, lpDisabled || !oEl[i].checked, true);
					}
					//if( lpAdvanced )
					//	setDisabledStyle( oEl[ i ], lpDisabled, cpBgColor );
				}
			}
		} else {
			if ((oEl.disabled != lpDisabled || typeof oEl.disabled == 'undefined') && (typeof oEl.disabled != 'undefined' || lpDisabled)) {
				oEl.disabled = lpDisabled;
				if (typeof oEl.tagName != 'undefined') {
					if (oEl.tagName == 'IMG' || oEl.tagName == 'TD') {
						var cClass = oEl.getAttribute('fdClassD');
						if (cClass) {
							if (lpDisabled) {
								oEl.oldClass = oEl.className;
								oEl.className = cClass;
								oEl.focus = '0';
							} else {
								if (oEl.getAttribute('fdClass'))
									oEl.className = oEl.getAttribute('fdClass');
								else
									oEl.className = oEl.oldClass;
							}
						} else {
							var oDiv = getElement(doc || document, '__div_' + oEl.id);
							if (!oDiv) {
								oDiv = doc.createElement('DIV');
								oDiv.style.cssText = 'background:white;filter:gray() alpha(opacity=10);opacity:.4;-moz-opacity:.4;';
								oDiv.id = '__div_' + oEl.id; oDiv.style.display = 'none'; oDiv.style.position = 'absolute';
								//oDiv.style.backgroundColor = 'red';
								doc.body.insertBefore(oDiv, doc.body.firstChild); //.appendChild( oDiv );
							}
							oDiv.style.top = getY(oEl) + 1; oDiv.style.left = getX(oEl) + 1;
							if (oEl.offsetWidth > 2) {
								oDiv.style.width = oEl.offsetWidth - 2; oDiv.style.height = oEl.offsetHeight - 2;
							}
							oDiv.style.zIndex = 999;
							oDiv.style.display = (lpDisabled ? '' : 'none');
						}
						if (lpDisabled) {
							oEl.oldClick = oEl.onclick; oEl.oldMouseOver = oEl.onmouseover; oEl.oldMouseOut = oEl.onmouseout;
							oEl.onclick = null; oEl.onmouseover = null, oEl.onmouseout = null;
						} else {
							oEl.onclick = oEl.oldClick; oEl.onmouseover = oEl.oldMouseOver; oEl.onmouseout = oEl.oldMouseOut;
							oEl.oldClick = null; oEl.oldMouseOver = null; oEl.oldMouseOut = null;
						}
					} else if (!lpDontEmptyValue) {
						if (oEl.tagName == 'SELECT') {
							if (lpDisabled) {
								oEl.oldValue = oEl.selectedIndex;
								oEl.selectedIndex = -1;
							} else if (typeof oEl.oldValue != 'undefined')
								oEl.selectedIndex = oEl.oldValue;
							if (lpNoEvents)
								fireEvent(oEl, 'onchange');
						} else if ((oEl.tagName == 'INPUT' && oEl.type == 'text') || oEl.tagName == 'TEXTAREA') {
							if (lpDisabled) {
								oEl.oldValue = oEl.value;
								oEl.value = '';
							} else if (typeof oEl.oldValue != 'undefined')
								oEl.value = oEl.oldValue;
							if (!lpNoEvents)
								fireEvent(oEl, 'onchange');
						} else if (oEl.tagName == 'INPUT' && (oEl.type == 'checkbox' || oEl.type == 'radio')) {
							if (lpDisabled) {
								oEl.oldValue = oEl.checked;
								oEl.checked = false;
							} else if (typeof oEl.oldValue != 'undefined')
								oEl.checked = oEl.oldValue;
							if (!lpNoEvents)
								fireEvent(oEl, 'onclick');
						}
					}
				}
				if (lpAdvanced)
					setDisabledStyle(oEl, lpDisabled, cpBgColor);
				if (oEl.tagName && oEl.tagName == 'INPUT' && oEl.type == 'file')
					FD.Utils.doFile(oEl.id, (lpDisabled ? 1 : 3), true);
			}
		}
	}
}
function setDisabledStyle(opEl, lpDisabled, cpBgColor) {
	if (!opEl.style) return;
	if (typeof opEl.styleInit == 'undefined' && opEl.style.cssText != null)
		opEl.styleInit = opEl.style.cssText.replace(/visibility:[^;]*;{0,1}/i, "");
	if (!lpDisabled && String.is(opEl.styleReadonly))
		opEl.style.cssText = opEl.styleReadonly;
	else if (!Browser.opera && !lpDisabled && String.is(opEl.styleInit)) {
		opEl.style.cssText = opEl.styleInit;
		if (opEl.style.display == 'none') opEl.style.display = '';
	} else {
		if (!Browser.gecko || typeof opEl.tagName == 'undefined' || opEl.tagName != 'SELECT') {
			setBorderStyle(opEl, (lpDisabled ? 'solid' : ''));
			setBorderWidth(opEl, (lpDisabled ? '2px' : ''));
			setBorderColor(opEl, (lpDisabled ? 'silver' : ''));
			setBackgroundColor(opEl, (lpDisabled ? cpBgColor : ''));
		}
	}
	opEl.styleDisabled = (lpDisabled ? opEl.style.cssText : null);
}

function setReadonly(opDoc, vpObject, lpReadonly, lpAdvanced, cpBgColor, lpKeepSize) {
	var oEl = getElement(opDoc, vpObject);
	if (!Object.is(oEl)) return;
	var lArray = typeof oEl[0] != 'undefined';
	if (Object.is(oEl) && (lArray || typeof oEl.readOnly != 'undefined')) {
		if (lArray && (typeof oEl.tagName == 'undefined' || oEl.tagName != 'SELECT')) {
			var i, lRadio, nChk = -1;
			lRadio = typeof oEl[0].type != 'undefined' && oEl[0].type == 'radio';
			if (lRadio) {
				for (i = 0; i < oEl.length; i++) {
					if (oEl[i].checked) {
						nChk = i; break;
					}
				}
			}
			for (i = 0; i < oEl.length; i++) {
				if (oEl[i].readOnly != lpReadonly) {
					if (lpReadonly) {
						oEl[i].oldClick = oEl[i].onclick;
						oEl[i].oldValue = (lRadio ? nChk : oEl[i].checked);
						if (lRadio)
							oEl[i].onclick = function() {
								if (this.oldValue > -1) getElement(document, this.name)[this.oldValue].checked = true;
								else this.checked = false;
							}
						else
							oEl[i].onclick = function() { this.checked = this.oldValue; }
					} else {
						oEl[i].onclick = oEl[i].oldClick;
						oEl[i].oldClick = null;
					}
				}
				oEl[i].oldValue = (lRadio ? nChk : oEl[i].checked);
				oEl[i].readOnly = lpReadonly;
				oEl[i].unselectable = (lpReadonly ? 'on' : 'off');
				if (lpAdvanced)
					setReadonlyStyle(oEl, lpReadonly, cpBgColor);
			}
		} else {
			if (oEl.readOnly != lpReadonly && typeof oEl.tagName != 'undefined') {
				if (oEl.tagName == 'INPUT' && oEl.type == 'checkbox') {
					oEl.oldValue = oEl.checked;
					if (lpReadonly) {
						oEl.oldClick = oEl.onclick;
						oEl.onclick = function() { this.checked = this.oldValue; }
					} else {
						oEl.onclick = oEl.oldClick;
						oEl.oldClick = null;
					}
				} else if (oEl.tagName == 'SELECT') {
					oEl.oldValue = oEl.value;
					if (lpReadonly) {
						oEl.oldChange = oEl.onchange;
						oEl.onchange = function() { this.value = this.oldValue; }
					} else if (oEl.oldChange) {
						oEl.onchange = oEl.oldChange;
						oEl.oldChange = null;
					}
				}
			}
			oEl.readOnly = lpReadonly;
			if (lpAdvanced) {
				if (lpKeepSize) {
					oReadonlyElements[oEl.id] = (lpReadonly ? oEl : null);
					oEl.orgValue = oEl.value;
					oEl.value = '';
				}
				setReadonlyStyle(oEl, lpReadonly, cpBgColor);
				if (lpKeepSize)
					window.setTimeout('resetReadonlyVal( "' + oEl.id + '" )', 0);
			}
		}
	}
}
var oReadonlyElements = { afterload: false };
function resetReadonlyVal(cpId) {
	oReadonlyElements[cpId].value = oReadonlyElements[cpId].orgValue;
	fireEvent(oReadonlyElements[cpId], 'onchange');
	oReadonlyElements[cpId] = null;
}
function setReadonlyStyle(opEl, lpReadonly, cpBgColor) {
	if (!opEl.style) return;
	if (typeof opEl.styleInit == 'undefined')
		opEl.styleInit = opEl.style.cssText;
	if (!lpReadonly && String.is(opEl.styleDisabled))
		opEl.style.cssText = opEl.styleDisabled;
	else if (!lpReadonly && String.is(opEl.styleInit))
		opEl.style.cssText = opEl.styleInit;
	else {
		opEl.style.paddingBottom = (lpReadonly ? (Browser.ie ? '3px' : '2px') : '');
		//opEl.style.paddingLeft = ( lpReadonly ? '3px' : '' );
		setBorderStyle(opEl, (lpReadonly ? 'none' : ''));
		opEl.style.borderBottom = (lpReadonly ? '1px silver dotted' : '');
		if (typeof cpBgColor == 'string') setBackgroundColor(opEl, (lpReadonly ? cpBgColor : ''));
	}
	opEl.styleReadonly = (lpReadonly ? opEl.style.cssText : null);
}
/*
var oResizeElements = { elements: new Array(), listen: false };
oResizeElements.addElement = function(id){
if( arraySearch(this.elements,id) == -1 )
this.elements[ this.elements.length ] = id;
if( !this.listen ){
alert('setevent');
addEventHandler(window,'onresize',resizeElements);
this.listen = true;
}
}
oResizeElements.resizeElements = function(){
alert('resize: '+this.elements.length);
var i, oEl;
for( i = 0; i < this.elements.length; i++ ){
oEl = getElement( document, this.elements[ i ] );
alert(this.elements[ i ]+', '+oEl);
if( oEl && oEl.style ){
alert(oEl.id + ', ' + oEl.offsetHeight+', '+oEl.style.border);
if( oEl.style.height == '' && oEl.offsetHeight > 0 ) oEl.style.height = oEl.offsetHeight + ( oEl.style.border == 'none' ? 3 : 0 );
if( oEl.style.width == '' && oEl.offsetWidth > 0 ) oEl.style.width = oEl.offsetWidth;
}
}
}
function resizeElements(){ oResizeElements.resizeElements(); }
*/

// deprecated; use getSelectedOption instead;
function getCheckedRadio(opDoc, vpObject, vpExpr) {
	return getSelectedOption(opDoc, vpObject, vpExpr);
}
function getSelectedOption(opDoc, vpObject, vpExpr) {
	var oEl = getElement(opDoc, vpObject), vRetVal = null, i = -1;
	if (Object.is(oEl)) {
		if (typeof oEl[0] != 'undefined') {
			for (i = 0; i < oEl.length; i++) {
				if (oEl[i].checked) {
					vRetVal = oEl[i];
					break;
				}
			}
		} else if (oEl.checked) {
			vRetVal = oEl; i = 0;
		}
	}
	if (vpExpr == 2)
		vRetVal = (vRetVal != null ? i : -1);
	else if (vpExpr)
		vRetVal = (vRetVal != null ? vRetVal.value : '');

	return vRetVal;
}

function isSelectedOption(opDoc, vpEl, vpOption) {
	var oEl = getElement(opDoc, vpEl), lSel = false, i;
	if (oEl) {
		var t = 1;
		if (isCollection(oEl)) {
			if (typeof (vpOption) == 'number')
				lSel = inBetween(vpOption, 0, oEl.length - 1) && oEl[vpOption].checked;
			else {
				for (i = 0; i < oEl.length; i++) {
					if (oEl[i].value == vpOption) {
						lSel = oEl[i].checked;
						break;
					}
				}
			}
		} else if (typeof (oEl.tagName) != 'undefined' && oEl.tagName == 'INPUT' && typeof (oEl.checked) != 'undefined') {
			if (typeof (vpOption) == 'Number')
				lSel = vpOption == 0 && oEl.checked;
			else
				lSel = oEl.value == vpOption && oEl.checked;
		}
	}
	return lSel;
}

function setCheckedRadio(opDoc, vpEl, vpVal) {
	setSelectedOption(opDoc, vpEl, vpVal);
}
function setSelectedOption(opDoc, vpEl, vpVal) {
	var oEl = getElement(opDoc, vpEl);
	if (oEl) {
		for (i = 0; i < oEl.length; i++) {
			if (oEl[i].value == vpVal)
				oEl[i].checked = true;
		}
	}
}

function removeOptions(opDoc, vpEl) {
	var oEl = getElement(opDoc, vpEl), i = 0;
	for (i = oEl.options.length - 1; i >= 0; i--) {
		if (Browser.ie || Browser.W3C) oEl.remove(i);
		else {
			oEl.options[i].value = '';
			oEl.options[i].text = '';
		}
	}
}
function removeOption(opDoc, vpEl, npIndex) {
	var oEl = getElement(opDoc, vpEl);
	if (Browser.ie || Browser.W3C) {
		oEl.remove(npIndex);
		/* Mozilla workaround
		Remove an option before the selected option.
		The value and selectedIndex do change.
		Firefox probably keeps track of the previous value to see if a change has occured.
		Presumably this tracking value does not change automatically. Below the workaround.
		*/
		var i = oEl.selectedIndex;
		oEl.selectedIndex = -1, oEl.selectedIndex = i;
	} else {
		oEl.options[i].value = '';
		oEl.options[i].text = '';
	}
}

function copyOptions(opFrom, opTo, empty, value) {
	if (empty) opTo.length = 0;
	for (var i = 0; i < opFrom.options.length; i++)
		addOption(null, opTo, opFrom.options[i].value, opFrom.options[i].text);
	if (arguments.length >= 4) opTo.value = value;
	else opTo.selectedIndex = 0;
}

function addOptions(apFrom, opTo, lp2D) {
	var nCnt = (lp2D ? 2 : 1);
	for (var i = 0; i < apFrom.length; i += nCnt)
		addOption(null, opTo, unescape(apFrom[i]), unescape(apFrom[i + (nCnt - 1)]));
}

function addOption(opDoc, vpEl, vpValue, cpText) {
	opDoc = opDoc || document;
	var oEl = getElement(opDoc, vpEl), oOption = null
	if (Browser.ie || Browser.W3C) {
		oOption = opDoc.createElement('OPTION');
		oOption.value = vpValue;
		oOption.text = cpText;
		if (Browser.ie)
			oEl.add(oOption);
		else if (Browser.W3C)
			oEl.add(oOption, null);
	} else {
		oEl.options.length++;
		oOption = oElement.options[oEl.options.length - 1];
		oOption.value = vpValue;
		oOption.text = cpText;
	}
	return oOption;
}

function searchOption(opDoc, vpEl, vpValue, cpText) {
	var oEl = getElement(opDoc, vpEl);
	var lValue = typeof vpValue != 'boolean', lText = typeof cpText != 'undefined';
	var lFoundV = false, lFoundT = false;
	if (oEl.options) {
		for (var i = 0; i < oEl.options.length; i++) {
			lFoundV = (lValue && oEl.options[i].value == vpValue);
			lFoundT = (lText && oEl.options[i].text == cpText);
			if ((lValue && lFoundV && !lText) || (lText && lFoundT && !lValue) || (lValue && lText && lFoundV && lFoundT))
				return i;
		}
	} else {
		var lLen = oEl.length;
		for (var i = 0; i < (lLen ? oEl.length : 1); i++) {
			if ((lLen ? oEl[i] : oEl).value.toLowerCase() == vpValue.toLowerCase())
				return i;
		}
	}
	return -1;
}

function sortOptions(opDoc, vpElement) {
	var oEl = getElement(opDoc, vpElement), cValue = oEl.value;
	var nLength = oEl.options.length;
	nIndex = 0;
	var aSort = new Array(nLength);
	var aValues = new Array(nLength * 2);
	for (i = 0; i < nLength; i++) {
		aSort[i] = oEl.options[i].text.toLowerCase();
		aValues[nIndex] = oEl.options[i].text;
		aValues[nIndex + 1] = oEl.options[i].value;
		nIndex = nIndex + 2;
	}
	aSort.sort();
	nIndex = 0;
	for (i = 0; i < nLength; i++) {
		for (j = 0; j < nLength * 2; j = j + 2) {
			if (aValues[j] != null && aValues[j].toLowerCase() == aSort[i]) {
				oEl.options[nIndex].text = aValues[j];
				oEl.options[nIndex].value = aValues[j + 1];
				aValues[j] = null;
				break;
			}
		}
		nIndex++;
	}
	aSort = null;
	aValues = null;
	oEl.value = cValue;
}

function setBorderStyle(opEl, cpStyle) {
	if (Object.is(opEl) && (this.Browser.ie || this.Browser.W3C)) {
		if (typeof opEl.style != 'undefined') {
			with (opEl.style) {
				borderTopStyle = cpStyle;
				borderBottomStyle = cpStyle;
				borderLeftStyle = cpStyle;
				borderRightStyle = cpStyle;
			}
		}
	}
}

function setBorder(opEl, cpBorder) {
	if (Object.is(opEl) && (this.Browser.ie || this.Browser.W3C)) {
		if (typeof opEl.style != 'undefined')
			opEl.style.border = cpBorder;
	}
}
function setBorderColor(opEl, cpColor) {
	if (Object.is(opEl) && (this.Browser.ie || this.Browser.W3C)) {
		if (typeof opEl.style != 'undefined') {
			with (opEl.style) {
				borderTopColor = cpColor;
				borderBottomColor = cpColor;
				borderLeftColor = cpColor;
				borderRightColor = cpColor;
			}
		}
	}
}
function setBackgroundColor(opEl, cpColor) {
	if (Object.is(opEl) && (this.Browser.ie || this.Browser.W3C)) {
		if (typeof opEl.style != 'undefined') {
			opEl.style.backgroundColor = cpColor;
		}
	}
}
function setBorderWidth(opEl, vpWidth) {
	if (Object.is(opEl) && (this.Browser.ie || this.Browser.W3C)) {
		if (typeof opEl.style != 'undefined') {
			vpWith = vpWidth + (typeof vpWidth == 'number' ? 'px' : '');
			with (opEl.style) {
				borderTopWidth = vpWidth;
				borderBottomWidth = vpWidth;
				borderLeftWidth = vpWidth;
				borderRightWidth = vpWidth;
			}
		}
	}
}

function setVisibility(opDoc, vpEl, lpVisible) {
	var oEl = getElement(opDoc, vpEl);
	if (!Object.is(oEl)) return;
	if (this.Browser.ie || this.Browser.W3C) {
		var cValue = lpVisible ? 'visible' : 'hidden';
		oEl.style.visibility = cValue;
	}
	if (this.Browser.ns4) {
		var cValue = lpVisible ? 'show' : 'hide';
		oEl.visibility = cValue;
	}
}

function setDisplay(opDoc, vpEl, vpDisplay) {
	var oEl = getElement(opDoc, vpEl);
	if (!Object.is(oEl) || typeof oEl.style == 'undefined') return;
	if (this.Browser.ie || this.Browser.W3C) {
		var cValue = (typeof (vpDisplay) == 'string' ? vpDisplay : (vpDisplay ? '' : 'none'));
		oEl.style.display = cValue;
	}
	return (oEl);
}

function setOpacity(opDoc, vpEl, npOpacity) {
	npOpacity = (npOpacity == 100) ? 99.999 : npOpacity;
	var oEl = getElement(opDoc, vpEl);
	if (typeof oEl.style == 'undefined') return;
	if (typeof oEl.style.filter != 'undefined') // IE/Win
		oEl.style.filter = (npOpacity == 99.999 ? "" : "alpha(opacity:" + npOpacity + ")");
	else if (typeof oEl.style.MozOpacity != 'undefined')// Older Mozilla and Firefox
		oEl.style.MozOpacity = npOpacity / 100;
	else if (typeof oEl.style.opacity != 'undefined') // Safari 1.2, newer Firefox and Mozilla, CSS3
		oEl.style.opacity = npOpacity / 100;
	else if (typeof oEl.style.KHTMLOpacity != 'undefined') // Safari&lt;1.2, Konqueror
		oEl.style.KHTMLOpacity = npOpacity / 100;
}
function getOpacity(opDoc, vpEl) {
	var oEl = getElement(opDoc, vpEl), nOpacity = 100;
	if (typeof oEl.style == 'undefined') return (nOpacity);
	if (oEl.style.filter) {
		var cFilter = oEl.style.filter, nPos = cFilter.search(/opacity:/);
		if (nPos > -1) {
			cFilter = cFilter.substr(nPos + 8);
			nOpacity = Number.float(cFilter.substr(0, cFilter.search(/\)/)));
		}
	} else if (oEl.style.MozOpacity)
		nOpacity = oEl.style.MozOpacity * 100;
	else if (oEl.style.opacity)
		nOpacity = oEl.style.opacity * 100;
	else if (oEl.style.KHTMLOpacity)
		nOpacity = oEl.style.KHTMLOpacity * 100;
	if (nOpacity == 99.999) nOpacity = 100;
	return (nOpacity);
}


function layerMove(opDoc, vpEl, npX, npY) {
	var oEl = getElement(opDoc, vpEl);
	if (!Object.is(oEl)) return;
	if (this.Browser.ie || this.Browser.W3C)
		oEl = oEl.style;
	oEl.left = npX;
	oEl.top = npY;
}
// deprecated; use layerMove instead
function moveLayer(opDoc, vpEl, npX, npY) {
	top.status = 'Function moveLayer is deprecated. Please, use layerMove instead.';
	layerMove(opDoc, vpEl, npX, npY);
}

function layerWrite(opDoc, vpEl, cpHTML) {
	var oEl = getElement(opDoc, vpEl);
	if (!Object.is(oEl)) return;
	if (typeof oEl[0] == 'object') {
		for (var i = 0; i < oEl.length; i++)
			layerWrite(null, oEl[i], cpHTML);
	} else {
		if (this.Browser.ns4 && Object.is(oEl, 'write')) {
			oEl.document.write(cpHTML);
			oEl.document.close();
		}
		if ((this.Browser.ie || this.Browser.W3C) && Object.is(oEl, 'innerHTML'))
			oEl.innerHTML = cpHTML;
	}
}
// deprecated; use layerWrite instead
function WriteToLayer(opDocument, vpElement, cpHTML) {
	top.status = 'Function WriteToLayer is deprecated. Please, use layerWrite instead.';
	layerWrite(opDocument, vpElement, cpHTML);
}

function maxLength(e, npMax, lpChk) {
	var el = null;
	if (lpChk) el = e;
	else el = checkEvent(e);
	if (!Object.is(el)) return;
	if (el.value.length >= npMax && (lpChk || !inList(e.keyCode, 8, 9, 16, 17, 18, 35, 36, 37, 38, 39, 40, 46))) {
		if (!lpChk) {
			if (Browser.ie) e.returnValue = false;
			else if (typeof e.preventDefault != 'undefined') e.preventDefault();
			else el.value = el.value.substr(0, npMax - 1);
		} else if (el.value.length > npMax) {
			el.value = el.value.substr(0, npMax - 1).rtrim();
			fireEvent(el, 'onkeyup');
		}
	}
}

function onPaste(npCurr, npMax) {
	var cClip, nClipLength, nAvailLength, lReturn;

	lReturn = true;
	cClip = window.clipboardData.getData("Text");
	nClipLength = cClip.length;
	nAvailLength = npMax - npCurr;

	if (nAvailLength > 0) {
		if (nAvailLength > nClipLength) {
			cClip = cClip.substr(0, nAvailLength);
			window.clipboardData.setData("Text", cClip);
		}
	} else
		lReturn = false;

	return lReturn;
}


var aCharCodes = new Array(32, 33, 35, 36, 37, 38, 40, 41, 43, 45, 46, 64, 94, 95, 255);
//32 = ' '
function FillArray(apCharCodes, npStart, npEnd) {
	var aRestCodes = new Array(npEnd - npStart + 1), i = 0, j = 0;
	for (i = npStart; i <= npEnd; i++) { aRestCodes[j] = i; j++; }
	return (apCharCodes = apCharCodes.concat(aRestCodes));
}

aCharCodes = FillArray(aCharCodes, 48, 57);
aCharCodes = FillArray(aCharCodes, 97, 122);
aCharCodes = FillArray(aCharCodes, 224, 229);
aCharCodes = FillArray(aCharCodes, 231, 246);
aCharCodes = FillArray(aCharCodes, 248, 253);

function CheckChars(cpString, npOptions, apCharCodes) {
	var cString = cpString.toLowerCase(), lFound = false, i, j, k, nCharCode;
	if (typeof apCharCodes == 'string') {
		apCharCodes = apCharCodes.split(',');
		for (i = 0; i < apCharCodes.length; i++) apCharCodes[i] = parseInt(apCharCodes[i]);
	}
	if (typeof apCharCodes == 'undefined' || !Object.is(apCharCodes)) apCharCodes = aCharCodes;
	for (i = 0; i < cString.length; i++) {

		if (i == 0 && ((npOptions & 1 && cString.charAt(0) == ' ') || (npOptions & 2 && !isNaN(cString.charAt(0)))))
			return 0;

		nCharCode = cString.charCodeAt(i); lFound = false;
		for (j = 0; j < apCharCodes.length; j++) {
			if (apCharCodes[j] == nCharCode) { lFound = true; break; }
		}
		if (!lFound) { return i; }
	}
	return -1;
}

FD.Date = new Object();
FD.Date.getCentury = function(year) {
	year = Number.float(year);
	var date = new Date(), rollover = parseInt(String(date.getFullYear() + 50).substr(2, 2));
	var current = parseInt(String(date.getFullYear()).substr(0, 2));
	if (year >= rollover) return (current - 1);
	return current;
}
FD.Date.Validate = function(vpDates, cpFormat, npRange) {
	// checks if date passed is in valid cpFormat format
	if (Object.is(vpDates)) var oStripDate = vpDates;
	else {
		if (vpDates.length == 0) return 0;
		var aDates = vpDates.split(','), oStripDate = this.Parse(aDates[0], cpFormat, true);
	}

	if (oStripDate.Error) return -1

	if (oStripDate.Time)
		var dDate = new Date(oStripDate.Year, oStripDate.Month - 1, oStripDate.Day, oStripDate.Hours, oStripDate.Minutes, oStripDate.Seconds);
	else
		var dDate = new Date(oStripDate.Year, oStripDate.Month - 1, oStripDate.Day);

	if ((oStripDate.Year == dDate.getFullYear()) && (oStripDate.Month - 1 == dDate.getMonth()) && (oStripDate.Day == dDate.getDate()) && (!oStripDate.Time || (oStripDate.Hours == dDate.getHours() && oStripDate.Minutes == dDate.getMinutes() && oStripDate.Seconds == dDate.getSeconds()))) {
		var dCheckDate;
		if (aDates.length > 1) {
			oStripDate = this.Parse(aDates[1], cpFormat);
			if (oStripDate.Time)
				dCheckDate = new Date(oStripDate.Year, oStripDate.Month - 1, oStripDate.Day, oStripDate.Hours, oStripDate.Minutes, oStripDate.Seconds);
			else
				dCheckDate = new Date(oStripDate.Year, oStripDate.Month - 1, oStripDate.Day);
		} else {
			dCheckDate = new Date();
			dCheckDate = new Date(dCheckDate.getFullYear(), dCheckDate.getMonth(), dCheckDate.getDate());
		}

		if (npRange == 1 && dDate > dCheckDate) return -2;
		if (npRange == 2 && dDate < dCheckDate) return -3;
		if (npRange == 3 && dDate >= dCheckDate) return -4;
		if (npRange == 4 && dDate <= dCheckDate) return -5;
		if (npRange == 5 && dDate <= dCheckDate && dDate >= dCheckDate) return -6;
		return 0;
	} else {
		//return 'valid format but an invalid date';
		return -1;
	}
}

function isValidDate(vpDates, cpFormat, npRange) {
	FD.Debug.deprecated(isValidDate, 'deprecated! use FD.Date.Validate instead');
	return FD.Date.Validate(vpDates, cpFormat, npRange);
}

FD.Date.Parse = function(cpDate, cpFormat, strict) {
	var nSepPos, cTmp, cChar, nLen, i;
	if (!cpFormat) cpFormat = FD.Texts.get('DATE_FORMAT');
	var obj = {
		Error: false, Date: null, Format: cpFormat, Separator: FD.Date.getSeparator(cpFormat), Time: cpDate.search(' ') > 0,
		Day: 0, Month: 0, Year: 0, Hours: 0, Minutes: 0, Seconds: 0, hasSeconds: false, Julian: 0, format: []
	};
	obj.toString = function() {
		var str = '';
		if (this.Error) return str;
		for (var i = 0; i < format.length; i++) {
			if (/d|t|g|j/.test(format[i]) && format[i].length <= 2) {
				str += this.Separator + String.create(this.Day).padl(2, '0');
			} else if (/m/.test(format[i])) {
				str += this.Separator + String.create(this.Month).padl(2, '0');
			} else {
				str += this.Separator + this.Year;
			}
		}
		if (this.Time) {
			str += ' ' + String.create(this.Hours).padl(2, '0') + ':' + String.create(this.Minutes).padl(2, '0') + (this.hasSeconds ? ':' + String.create(this.Seconds).padl(2, '0') : '');
		}
		str = str.substr(1);
		return str;
	}

	var sep = FD.Date.getSeparator(cpDate);
	if (sep != '' && sep != obj.Separator) {
		cpDate = cpDate.replace(new RegExp((sep == '.' ? '\\.' : sep), 'g'), obj.Separator);
	}
	var format = obj.format = cpFormat.split(obj.Separator), rg = '';
	for (i = 0; i < format.length; i++) {
		rg += (/d|t|g|j|m/.test(format[i]) && format[i].length <= 2 ? '(\\d{1,2})' : '(\\d{2,4})') + (i < 2 ? obj.Separator + (!strict ? '?' : '') : '');
	}
	var date = new RegExp(rg + ' ?(\\d{1,2})?:?(\\d{2})?:?(\\d{2})?').exec(cpDate);
	//alert(date);
	obj.Error = date == null;
	if (!obj.Error) {
		for (i = 0; i < format.length; i++) {
			if (/d|t|g|j/.test(format[i]) && format[i].length <= 2) {
				obj.Day = Number.float(date[i + 1]);
			} else if (/m/.test(format[i])) {
				obj.Month = Number.float(date[i + 1]);
			} else {
				obj.Year = Number.float((date[i + 1].length == 2 && !strict ? this.getCentury(date[i + 1]) : '') + date[i + 1]);
			}
			if (!strict && obj.Month > 12 && obj.Day <= 12) { // day and month are switched
				var tmp = obj.Day;
				obj.Day = obj.Month;
				obj.Month = tmp;
			}
			obj.Error = obj.Day <= 0 || obj.Month <= 0 || obj.Year <= 0 || String(obj.Year).length < 4;
		}
		if (obj.Time) {
			obj.Hours = Number.float(date[4]);
			obj.Minutes = Number.float(date[5]);
			obj.hasSeconds = typeof date[6] != 'undefined' && date[6] != '';
			obj.Seconds = Number.float(date[6]);
		}
		if (!obj.Error) {
			if (obj.Time)
				obj.Date = new Date(obj.Year, obj.Month - 1, obj.Day, obj.Hours, obj.Minutes, obj.Seconds);
			else
				obj.Date = new Date(obj.Year, obj.Month - 1, obj.Day);

			obj.Error = obj.Date == null;
			if (!obj.Error && !strict) {
				obj.Day = obj.Date.getDate();
				obj.Month = obj.Date.getMonth() + 1;
				obj.Year = obj.Date.getFullYear();
				obj.Hours = obj.Date.getHours();
				obj.Minutes = obj.Date.getMinutes();
				obj.Seconds = obj.Date.getSeconds();
			}
			obj.Julian = FD.Date.toJulian(obj.Date);
		}
	}

	return obj;
}

FD.Date.getSeparator = function(format) {
	var sep = '-/.';
	for (var i = 0; i < format.length; i++) {
		if (sep.search(format.charAt(i)) > -1)
			return format.charAt(i);
	}
	return '';
}
function getDateSeparator(cpFormat) {
	FD.Debug.deprecated(getDateSeparator, 'deprecated! use FD.Date.getSeparator instead');
	return FD.Date.getSeparator(cpFormat);
}


function stripDate(cpDate, cpFormat) {
	FD.Debug.deprecated(stripDate, 'deprecated! use FD.Date.Parse instead');
	var obj = FD.Date.Parse(cpDate, cpFormat);
	for (var prop in obj) this[prop] = obj[prop];
}

//-------
// convert calendar to Julian date
// (Julian day number algorithm adopted from Press et al.)
//-------
FD.Date.toJulian = function() {

	var y, m, d, h, mn, s;

	if (arguments.length == 0) return 0;
	if (typeof arguments[0] == 'object' && !Date.is(arguments[0])) arguments = arguments[0]; // called from deprecated function
	if (Date.is(arguments[0])) {
		y = arguments[0].getFullYear();
		m = arguments[0].getMonth() + 1;
		d = arguments[0].getDate() + 1;
		h = arguments[0].getHours();
		mn = arguments[0].getMinutes();
		s = arguments[0].getSeconds();
	} else {
		y = arguments[0];
		m = arguments[1];
		d = arguments[2];
		h = arguments[3];
		mn = arguments[4];
		s = arguments[5];
	}

	var jy, ja, jm, era; 		//scratch

	if (y < 0) {
		era = "BCE";
		y = -y;
	}

	if (y == 0) {
		return 0;
	}
	if (y == 1582 && m == 10 && d > 4 && d < 15) {
		// "The dates 5 through 14 October, 1582, do not exist in the Gregorian system!";
		return 0;
	}

	//	if( y < 0 )  ++y;
	if (era == "BCE") y = -y + 1;
	if (m > 2) {
		jy = y;
		jm = m + 1;
	} else {
		jy = y - 1;
		jm = m + 13;
	}

	var intgr = Math.floor(Math.floor(365.25 * jy) + Math.floor(30.6001 * jm) + d + 1720995);

	//check for switch to Gregorian calendar
	var gregcal = 15 + 31 * (10 + 12 * 1582);
	if (d + 31 * (m + 12 * y) >= gregcal) {
		ja = Math.floor(0.01 * jy);
		intgr += 2 - ja + Math.floor(0.25 * ja);
	}

	//correct for half-day offset
	var dayfrac = h / 24.0 - 0.5;
	if (dayfrac < 0.0) {
		dayfrac += 1.0;
		--intgr;
	}

	//now set the fraction of a day
	var frac = dayfrac + (mn + s / 60.0) / 60.0 / 24.0;

	//round to nearest second
	var jd0 = (intgr + frac) * 100000;
	var jd = Math.floor(jd0);
	if (jd0 - jd > 0.5) ++jd;

	return jd / 100000;
}
function getDateToJulian() {
	FD.Debug.deprecated(getDateToJulian, 'deprecated! use FD.Date.toJulian instead');
	return FD.Date.toJulian(arguments);
}

//-------
// convert Julian date to calendar date
// (algorithm adopted from Press et al.)
//-------
FD.Date.fromJulian = function(jd) {

	var j1, j2, j3, j4, j5; 		//scratch

	//
	// get the date from the Julian day number
	//
	var intgr = Math.floor(jd);
	var frac = jd - intgr;
	var gregjd = 2299161;
	if (intgr >= gregjd) {				//Gregorian calendar correction
		var tmp = Math.floor(((intgr - 1867216) - 0.25) / 36524.25);
		j1 = intgr + 1 + tmp - Math.floor(0.25 * tmp);
	} else
		j1 = intgr;

	//correction for half day offset
	var dayfrac = frac + 0.5;
	if (dayfrac >= 1.0) {
		dayfrac -= 1.0;
		++j1;
	}

	j2 = j1 + 1524;
	j3 = Math.floor(6680.0 + ((j2 - 2439870) - 122.1) / 365.25);
	j4 = Math.floor(j3 * 365.25);
	j5 = Math.floor((j2 - j4) / 30.6001);

	var d = Math.floor(j2 - j4 - Math.floor(j5 * 30.6001));
	var m = Math.floor(j5 - 1);
	if (m > 12) m -= 12;
	var y = Math.floor(j3 - 4715);
	if (m > 2) --y;
	if (y <= 0) --y;

	//
	// get time of day from day fraction
	//
	var hr = Math.floor(dayfrac * 24.0);
	var mn = Math.floor((dayfrac * 24.0 - hr) * 60.0);
	f = ((dayfrac * 24.0 - hr) * 60.0 - mn) * 60.0;
	var sc = Math.floor(f);
	f -= sc;
	if (f > 0.5) ++sc;

	if (y < 0) { // BCE
		y = -y;
	}

	return (new Date(y, m - 1, d - 1, hr, mn, sc));

}
function getJulianToDate(jd) {
	FD.Debug.deprecated(getJulianToDate, 'deprecated! use FD.Date.fromJulian instead');
	return FD.Date.fromJulian(jd);
}

FD.Date.goMonth = function(dpDate, npMonth) {
	var date, month;
	if (arguments.length == 3) {
		date = this.Parse(arguments[0], arguments[1]).Date;
		month = arguments[2];
	} else {
		date = arguments[0];
		month = arguments[1];
	}
	if (typeof date != 'object') date = new Date();
	var prev_month = date.getMonth();
	date.setMonth(prev_month + month);
	// for instance: 31-01-2009 + 1 month = 03-03-2009
	if (date.getMonth() > prev_month + month) {
		// set the date back to the last day of the previous month
		date.setDate(0);
	}
	return date;
}

FD.Date.getLastDayOfMonth = function(dpDate) {
	if (typeof dpDate != 'object') dpDate = new Date();
	dpDate.setMonth(dpDate.getMonth() + 1);
	dpDate.setDate(1);
	dpDate.setDate(dpDate.getDate() - 1);
	return dpDate.getDate();
}
function getLastDayOfMonth(dpDate) {
	FD.Debug.deprecated(getLastDayOfMonth, 'deprecated! use FD.Date.getLastDayOfMonth instead');
	return FD.Date.getLastDayOfMonth(dpDate);
}

FD.Date._y2k = function(number) { return (number < 1000) ? number + 1900 : number; }
FD.Date.getWeek = function(year, month, day, iso) {
	var when = new Date(year, month, day);
	var newYear = new Date(year, 0, 1);
	var modDay = newYear.getDay();
	if (modDay == 0) modDay = 6; else modDay--;

	var daynum = ((Date.UTC(this._y2k(year), when.getMonth(), when.getDate(), 0, 0, 0) -
					Date.UTC(this._y2k(year), 0, 1, 0, 0, 0)) / 1000 / 60 / 60 / 24) + 1;

	if (iso && modDay < 4) {
		var weeknum = Math.floor((daynum + modDay - 1) / 7) + 1;
	} else {
		var weeknum = Math.floor((daynum + modDay - 1) / 7);
		if (weeknum == 0) {
			year--;
			var prevNewYear = new Date(year, 0, 1), prevmodDay;
			if (iso) {
				prevmodDay = prevNewYear.getDay();
				if (prevmodDay == 0) prevmodDay = 6; else prevmodDay--;
				if (prevmodDay < 4) weeknum = 53; else weeknum = 52;
			} else {
				prevmodDay = 7 + 1 - prevNewYear.getDay();
				if (prevmodDay == 2 || prevmodDay == 8) weeknum = 53; else weeknum = 52;
			}
		}
	}

	return weeknum;
}
function getWeek(year, month, day, iso) {
	FD.Debug.deprecated(getWeek, 'deprecated! use FD.Date.getWeek instead');
	return FD.Date.getWeek(year, month, day, iso);
}

FD.Date.toWeek = function(dpDate, iso) {
	dpDate = dpDate || new Date();
	return this.getWeek(dpDate.getFullYear(), dpDate.getMonth(), dpDate.getDate(), iso);
}
function getDateToWeek(dpDate, iso) {
	FD.Debug.deprecated(getDateToWeek, 'deprecated! use FD.Date.toWeek instead');
	return FD.Date.toWeek(dpDate, iso);
}

FD.Date.fromWeek = function(npWeek, npDOW, npYear) {
	npDOW = npDOW || 0;
	var dDate = new Date();
	npYear = npYear || dDate.getFullYear();
	var DOb = new Date(npYear, 0, 4);
	var D = DOb.getDay(); if (D == 0) D = 7;
	var Off = -(D - npDOW);
	DOb.setDate(DOb.getDate() + Off + 7 * (npWeek - 1))
	return DOb;
}
function getWeekToDate(npWeek, npDOW, npYear) {
	FD.Debug.deprecated(getWeekToDate, 'deprecated! use FD.Date.fromWeek instead');
	return FD.Date.fromWeek(npWeek, npDOW, npYear);
}

FD.Date.Format = function(date, format) {
	var aDate = [], cSep = this.getSeparator(format), cChar, nLen;
	for (var i = 1; i <= 3; i++) {
		cChar = format.charAt(0);
		nLen = format.search((cSep == '.' ? '\\.' : cSep));
		if (nLen < 0) nLen = format.length;
		if (cChar.match(/d|t|g|j/) != null && nLen <= 2)
			aDate.push(padOut(date.getDate()));
		else if (cChar == 'm' && nLen == 2)
			aDate.push(padOut(date.getMonth() - 0 + 1));
		else if (cChar.match(/j|y|a/) != null)
			aDate.push(date.getFullYear());

		//if (i < 3) cDate += cSep;
		format = format.substring(nLen + 1);
	}
	return aDate.join(cSep);
}
function formatDate(dpDate, cpFormat) {
	FD.Debug.deprecated(formatDate, 'deprecated! use FD.Date.Format instead');
	return FD.Date.Format(dpDate, cpFormat);
}

FD.Date.isWeekDay = function() {
	if (arguments.length <= 1 || arguments[0] == '') return true;
	var date = this.Parse(arguments[0]);
	if (date.Error || !date.Date) return false;
	var day = date.Date.getDay();
	for (var i = 1; i < arguments.length; i++) {
		if (day == arguments[i]) return true;
	}
	return false;
}

FD.Time = new Object();
FD.Time.Parse = function(time, inclSeconds) {
	var obj = { Error: false, Hours: 0, Minutes: 0, Seconds: 0, hasSeconds: false, inclSeconds: inclSeconds, Separator: FD.Time.getSeparator(time) };
	if (obj.Separator == '') {
		var tmp = time;
		if (tmp.length >= 5) { // seconds included
			obj.hasSeconds = true;
			obj.Seconds = Number.float(tmp.right(2));
			tmp = tmp.substr(0, tmp.length - 2);
		}
		obj.Minutes = Number.float(tmp.right(2));
		tmp = tmp.substr(0, tmp.length - 2);
		obj.Hours = Number.float(tmp);
	} else {
		time = new RegExp('^(\\d{1,2})+' + obj.Separator + '?(\\d{1,2})?' + obj.Separator + '?(\\d{1,2})? ?([ap]m)?').exec(time.toLowerCase());
		obj.Error = time == null;
		if (!obj.Error) {
			obj.Hours = Number.float(time[1]);
			if (time[4] == 'pm') obj.Hours = obj.Hours + 12;
			obj.Minutes = Number.float(time[2]);
			obj.hasSeconds = time[3] != '';
			obj.Seconds = Number.float(time[3]);
		}
	}
	obj.Error = !obj.Hours.between(0, 23) || !obj.Minutes.between(0, 59) || !obj.Seconds.between(0, 59);

	obj.toString = function() {
		var str = '';
		if (this.Error) return str;
		str += String.create(this.Hours).padl(2, '0');
		str += ':' + String.create(this.Minutes).padl(2, '0');
		if (this.inclSeconds) {
			str += ':' + String.create(this.Seconds).padl(2, '0');
		}
		return str;
	}
	return obj;
}
FD.Time.getSeparator = function(time) {
	var sep = ':-/.';
	for (var i = 0; i < time.length; i++) {
		if (sep.search(time.charAt(i)) > -1)
			return time.charAt(i);
	}
	return '';
}

FD.Calendar = new Object();
FD.Calendar._element = null;
FD.Calendar._format = '';
FD.Calendar._lang = 0;
FD.Calendar._time = false;
FD.Calendar._window = null;
FD.Calendar.Param = null;
FD.Calendar.setProp = function(prop) {
	if (prop.format) this._format = prop.format;
	if (prop.lang) this._lang = prop.lang;
	if (prop.time) this._time = prop.time;
}
FD.Calendar.Set = function(param) {
	var oWnd = ((typeof window.FD != 'undefined') ? window : top);
	var param = param || this.Param, el = param.element;
	if (Object.is(el) && !el.disabled && (!el.readOnly || el.getAttribute('selectOnly'))) {
		el.value = '' + FD.Date.Format(new Date(param.year, param.month, param.day), param.format) + (param.time && param.hasTime ? ' ' + param.hours + ':' + param.minutes : '');
		fireEvent(el, 'onchange');
		if (typeof el.onblur == 'function')
			fireEvent(el, 'onblur');
		if (typeof changeState == 'function')
			changeState();
	}
	param.window.close();
	param = param.window = this.Param = null;
}
FD.Calendar.Get = function(vpEl, cpType, cpFormat) {
	if (this._lang == 0 && typeof FD != 'undefined') {
		this._lang = FD.Texts.lang;
		this._format = FD.Texts.get('DATE_FORMAT');
	}
	var today = new Date(), param = this.Param = new Object();
	param.element = $(vpEl);
	param.element.oldValue = param.element.value;
	param.format = cpFormat || this._format;
	if (param.element.value.length > 0) {
		var oDate = new FD.Date.Parse(param.element.value, param.format);
		param.day = param.orgday = parseFloat(oDate.Day); param.month = param.orgmonth = (oDate.Month > 0 ? oDate.Month - 1 : today.getMonth()); param.year = param.orgyear = (oDate.Year >= 1900 ? oDate.Year : today.getFullYear());
		param.hasTime = oDate.Time, param.time = this._time = (cpType && cpType == 'T');
		if (this._time) {
			param.hours = oDate.Hours || 0;
			param.minutes = oDate.Minutes || 0;
		}
	} else {
		param.day = param.orgday = today.getDate(); param.month = param.orgmonth = today.getMonth(); param.year = param.orgyear = today.getFullYear();
		param.hasTime = false, param.time = this._time = (cpType && cpType == 'T');
		if (this._time) {
			param.hours = 0; param.minutes = 0;
		}
	}
	param.window = OpenWindow(window, '/util.asp?lang=' + this._lang + '&expr1=1&expr2=UTIL&' + FD.Script.getVersion('fd_general'), 330, 240 + (this._time ? 110 : 0), 'no', 'no', 'no');
	if (param.window.opener == null) param.window.opener = window;
}
function getDate(vpElement, cpType, cpFormat) {
	FD.Debug.deprecated(getDate, 'deprecated! FD.Calendar.Get instead');
	FD.Calendar.Get(vpElement, cpType, cpFormat);
}
function getDate_event(e) {
	FD.Debug.deprecated(getDate_event, 'deprecated! FD.Calendar.Get instead');
	var el = checkEvent(e);
	FD.Calendar.Get(el);
}

function padOut(npNumber) { return (npNumber < 10) ? '0' + npNumber : npNumber; }

function splitChar(cpString, lpEscaped) {
	return (
		(
			cpString.search((!lpEscaped ? unescape('%0D%0A') : '%0D%0A')) >= 0 ?
			'%0D%0A' :
			(
				cpString.search((!lpEscaped ? unescape('%0D') : '%0D')) >= 0 ?
				'%0D' :
				'%0A'
			)
		)
	);
}

//-- This script and many more are available free online at -->
//-- The JavaScript Source!! http://javascript.internet.com -->
function emailCheck(emailStr) {
	if (emailStr.length == 0) return 0;
	emailStr = String.create(emailStr).rtrim();
	var nPos = CheckChars(emailStr, 1, new String(aCharCodes) + ',39');
	if (nPos >= 0) return nPos + 1;

	var emailPat = /^(.+)@(.+)$/
	var specialChars = "\\(\\)<>@,;:\\\\\\\"\\.\\[\\]"
	var validChars = "\[^\\s" + specialChars + "\]"
	var quotedUser = "(\"[^\"]*\")"
	var ipDomainPat = /^\[(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\]$/
	var atom = validChars + '+'
	var word = "(" + atom + "|" + quotedUser + ")"
	var userPat = new RegExp("^" + word + "(\\." + word + ")*$")
	var domainPat = new RegExp("^" + atom + "(\\." + atom + ")*$")

	var matchArray = emailStr.match(emailPat)
	if (matchArray == null)
		return -1

	var user = matchArray[1], domain = matchArray[2];
	// See if "user" is valid 
	if (user.match(userPat) == null)
		return -2

	var IPArray = domain.match(ipDomainPat)
	if (IPArray != null) {
		for (var i = 1; i <= 4; i++) {
			if (IPArray[i] > 255) {
				//alert("Destination IP address is invalid!")
				return -3
			}
		}
		return 0
	}

	// Domain is symbolic name
	var domainArray = domain.match(domainPat)
	if (domainArray == null)
		return -4

	var atomPat = new RegExp(atom, "g"), domArr = domain.match(atomPat), len = domArr.length;
	if (domArr[domArr.length - 1].length < 2)
		return -5

	// Make sure there's a host name preceding the domain.
	if (len < 2)
		return -6

	// If we've gotten this far, everything's valid!
	return 0;
}

function rgb2Hex(rgb) {
	var aRGB = rgb.split(','), num, hex = '#', base, rem, val;
	if (aRGB.length != 3) return '';
	for (var i = 0; i < 3; i++) {
		num = parseInt(aRGB[i]);
		if (isNaN(num) || num < 0 || num > 255) return '';
		base = num / 16;
		rem = num % 16;
		val = (makeHex(base - (rem / 16)) + makeHex(rem)).toString();
		if (val.length < 2) val = '0' + val;
		hex += val;
	}
	return (hex);
}
function makeHex(x) {
	if ((x >= 0) && (x <= 9))
		return x;
	else {
		switch (x) {
			case 10: return "A";
			case 11: return "B";
			case 12: return "C";
			case 13: return "D";
			case 14: return "E";
			case 15: return "F";
		}
	}
}

function checkColor(cpColorString) {
	var rgb = /\d{3},\d{3},\d{3}/, hex = /^#([0-9a-f]{1,2}){3}$/i;
	return rgb.test(cpColorString) || hex.test(cpColorString);
}

// deprecated
function colorCheck(cpColorString) {
	return checkColor(cpColorString);
}

function checkUrl(cpUrl) {
	var cUrl = cpUrl.toLowerCase()
	if (cUrl.search('http://') == -1 && cUrl.search('https://') == -1 && cUrl.substr(0, 1) != '#')
		cpUrl = 'http://' + cpUrl;
	return cpUrl;
}

function checkCSS(cpUrl, lpRetVal) {
	var cUrl = cpUrl.toLowerCase(), lRetVal = cUrl.match(/(.+\/){1}.+(\.css|\.asp|\.php)/) != null;
	return (lpRetVal ? (lRetVal ? cpUrl : '') : lRetVal);
}

function emptyStr(str) {
	FD.Debug.deprecated(emptyStr, 'deprecated! use String.empty');
	return String.create(str).empty();
}

function emptyNum(npNumber) {
	return parseFloat(npNumber) == 0;
}

function allTrim(str, lpCRLF) {
	FD.Debug.deprecated(allTrim, 'deprecated! use String.trim instead');
	return String.create(str).trim();
}

function rTrim(str, lpCRLF) {
	FD.Debug.deprecated(rTrim, 'deprecated! use String.rtrim instead');
	return String.create(str).rtrim();
}

function lTrim(str, lpCRLF) {
	FD.Debug.deprecated(lTrim, 'deprecated! use String.ltrim instead');
	return String.create(str).ltrim();
}

function padL(str, len, chr) {
	FD.Debug.deprecated(padL, 'deprecated! use String.padl instead');
	return String.create(str).padl(len, chr);
}
function padR(str, len, chr) {
	FD.Debug.deprecated(padR, 'deprecated! use String.padr instead');
	return String.create(str).padr(len, chr);
}

function parseIntEx(str) {
	FD.Debug.deprecated(parseIntEx, 'deprecated! use Number.int or String.int instead');
	return String.create(str).int();
}

function parseFloatEx(str) {
	FD.Debug.deprecated(parseFloatEx, 'deprecated! use Number.float or String.float instead');
	return String.create(str).float();
}

function correctNumber(number, range, decimals, min, max, allowEmpty, onchange) {
	number = String.create(number).replaceAll(',', '.');

	if (number.match(/[^0-9.-]/) || (allowEmpty && number.length == 0)) {
		return ['', '', '', true];
	}

	var num = number.split('.');
	if (typeof range == 'number' && range >= 0 && decimals && (num.length > 1 && num[1].length > 0)) {
		number = String.create(Math.round(parseFloat(number) * Math.pow(10, range)) / Math.pow(10, range));
		num = number.split('.');
	}

	num[0] = String.create(num[0]).trim();
	num[2] = isNaN(num[0]) && num[0] != '-'; // it could be empty or it contains text; something is wrong!
	num[3] = (num[0].length > 0 && num[2]); // it clearly contains text
	num[0] = String.create((num[2] || num[0].length == 0) ? '0' : num[0]); // make sure it contains something of a number
	num[1] = (num.length > 1 && !String.create(num[1]).empty()) ? String.create(num[1]).trim() : ''; // make sure the decimal array index is a string
	num[2] = (num[2] || isNaN(num[1]) || (range <= 0 && num[1].length > 0)); // something is wrong with the decimals
	num[3] = (num[3] || (num[1].length > 0 && isNaN(num[1]))); // the decimals part contains text; that's wrong!
	num[1] = (isNaN(num[1]) ? '0' : num[1]); // make sure again the decimal part contains a number string

	if (typeof range == 'number' && range > 0) {
		var index = (decimals ? 1 : 0);
		num[2] = (num[2] || num[index].length > range);
		if (num[1].length > range) {
			num[1] = num[1].substr(0, range);
		}

		if (!onchange) {
			while (num[index].length < range) {
				if (decimals) num[index] = num[index] + '0';
				else num[index] = '0' + num[index];
			}
		}
	}

	corrected = new Array('' /* completed corrected string */, num[0] /* absolute part */, num[1] /* decimal part */, num[2] /* error flag */);
	corrected[0] = (num[3] ? '' : (num[0] + ((decimals && num[1].length > 0 || (onchange && decimals && number.search(/\./) >= 0)) ? ('.' + num[1]) : '')));
	if (corrected[0].length > 20) {
		corrected[3] = true;
		corrected[0] = '';
	}
	if (typeof min == 'number' && parseFloat(corrected[0]) < min)
		corrected[0] = (allowEmpty ? '' : min);
	if (typeof max == 'number' && parseFloat(corrected[0]) > max)
		corrected[0] = (allowEmpty ? '' : max);

	return corrected;
}
function checkNumber(e, type) {
	var lSpecChars = (arguments.length == 0 || (type & 2) == 2);
	if ((!lSpecChars || checkDecimalMark(e)) && !keyCodeIsNumChar(e.keyCode, (arguments.length == 0 || (type & 1) == 1), lSpecChars)) {
		if (Browser.ie) e.returnValue = false;
		else if (typeof e.preventDefault != 'undefined')
			e.preventDefault();
		else if (typeof e.target != 'undefined')
			e.target.value = correctNumber(e.target.value, 0, true);
	}
}
function keyCodeIsNumChar(keyCode, lpControlChars, lpSpecChars) {
	return ((keyCode.between(48, 57) || keyCode.between(96, 105) || (lpSpecChars && inList(keyCode, 189, 190, 110))) || (lpControlChars && inList(keyCode, 8, 9, 16, 17, 18, 35, 36, 37, 38, 39, 40, 46)));
}
function keyCodeIsControlChar(e) {
	return (inList(e.keyCode, 8, 9, 16, 17, 18, 35, 36, 37, 38, 39, 40, 46));
}
function checkDecimalMark(e) {
	var lRetVal = true;
	if (e.keyCode == 188 && typeof e.shiftKey != 'undefined' && !e.shiftKey) {
		lRetVal = false;
		if (Browser.ie) {
			document.selection.createRange().text = '.';
			e.returnValue = false;
		} else if (typeof e.preventDefault != 'undefined')
			e.preventDefault();
	}
	return (lRetVal);
}

function replaceAll(str, what, withwhat, icase) {
	FD.Debug.deprecated(replaceAll, 'deprecated! use String.replaceAll instead');
	return String.create(str).replaceAll(what, withwhat, icase);

	var re = new RegExp(cpWhat, (lpICase ? "i" : "") + "g");
	if (cpString)
		return cpString.replace(re, cpWith);
	else
		return '';
}

function stripHTML(str) {
	FD.Debug.deprecated(stripHTML, 'deprecated! use String.stripHTML instead');
	return str.stripHTML();
}

//--> http://www.faqts.com/knowledge_base/view.phtml/aid/13562
function setSelectionRange(el, selectionStart, selectionEnd) {
	if (el.setSelectionRange) {
		el.focus();
		el.setSelectionRange(selectionStart, selectionEnd);
	} else if (el.createTextRange) {
		var range = el.createTextRange();
		range.collapse(true);
		range.moveEnd('character', selectionEnd);
		range.moveStart('character', selectionStart);
		range.select();
	}
}
function setCaretToEnd(el) {
	setSelectionRange(el, input.value.length, input.value.length);
}
function setCaretToBegin(el) {
	setSelectionRange(el, 0, 0);
}
function setCaretToPos(el, pos) {
	setSelectionRange(el, pos, pos);
}
function selectString(el, string) {
	string = string.replaceAll('\\(', '\\\(').replaceAll('\\)', '\\\)');
	var match = new RegExp(string, "i").exec(el.value);
	if (match) {
		setSelectionRange(el, match.index, match.index + match[0].length);
	}
}
//<--

function getAttribute(el, prop) {
	var val = null;
	try {
		val = el.getAttribute(prop);
	} catch (e) { };
	return val;
}
function removeAttribute(el, prop) {
	if (el.removeAttribute) {
		if (Browser.ie)
			el.removeAttribute(prop, 0);
		else
			el.removeAttribute(prop);
	} else if (el.removeProperty)
		el.removeProperty(prop);
}
function setAttribute(el, prop, value) {
	if (el.setAttribute) {
		if (Browser.ie)
			el.setAttribute(prop, value, 0);
		else
			el.setAttribute(prop, value);
	} else if (el.setProperty)
		el.setProperty(prop, value, "");
}

function setRowDisplay(opEl, lpRec) {
	if (!Object.is(opEl) || typeof opEl.tagName == 'undefined' || !inList(opEl.tagName, 'TABLE', 'TR')) return;
	var i, lDisp = true, oCell, nIndex = (Browser.ie ? 0 : 1);
	if (opEl.tagName == 'TABLE') {
		for (i = 0; i < opEl.rows.length; i++) {
			lDisp = setRowDisplay(opEl.rows[i], true);
			if (lDisp) break;
		}
	} else {
		for (i = 0; i < opEl.cells.length; i++) {
			oCell = opEl.cells[i];
			lDisp = oCell.style.display != 'none';
			if (lDisp && oCell.childNodes.length > nIndex && oCell.childNodes[nIndex].nodeType == 1 && oCell.childNodes[nIndex].tagName == 'TABLE')
				lDisp = setRowDisplay(oCell.childNodes[nIndex], true);
			if (lDisp) break;
		}
		if (!lpRec)
			opEl.style.display = (lDisp ? '' : 'none');
	}
	return lDisp;
}

function toggleOption(e, vpEl, npIndex) {
	if (checkEvent(e).tagName != 'INPUT') {
		var oEl = getElement(document, vpEl);
		if (typeof npIndex != 'undefined' && oEl.length > 1) oEl = oEl[npIndex];
		if ((typeof oEl.disabled == 'undefined' || !oEl.disabled) && (typeof oEl.readOnly == 'undefined' || !oEl.readOnly)) {
			oEl.checked = (oEl.type == 'radio' ? true : !oEl.checked);
			if (oEl.onclick) oEl.onclick(e);
		}
	}
}
// short function call to toggleOption
function to(e, vpEl, npIndex) {
	toggleOption(e, vpEl, npIndex);
}

function getElementByTagName(opFrom, cpTagName) {
	var oEl = null, oChild;
	if (typeof opFrom.tagName != 'undefined' && opFrom.tagName == cpTagName) return opFrom;
	if (typeof opFrom.childNodes == 'undefined') return null;
	for (var i = 0; i < opFrom.childNodes.length; i++) {
		oEl = getElementByTagName(opFrom.childNodes[i], cpTagName);
		if (oEl) return oEl;
	}
	return oEl;
}

function preloadImage(cpImage, apArray) {
	var oImg;
	try {
		oImg = new Image();
	} catch (e) {
		oImg = document.createElement('IMG');
	}
	oImg.src = cpImage;
	if (typeof apArray == 'undefined') {
		if (typeof window.preloadImg == 'undefined') window.preloadImg = new Array(oImg);
		else window.preloadImg.push(oImg);
	} else
		apArray.push(oImg);

	return oImg;
}

function getIDoc(opDoc, cpFrm) {
	var oDoc = null;
	opDoc = opDoc || document;
	if (Browser.ie) oDoc = opDoc.frames(cpFrm).document;
	else oDoc = getElement(opDoc, cpFrm).contentDocument;
	return oDoc;
}

function hideControl(cpTagName, opTopControl) {
	if (FD.Browser.gecko || (FD.Browser.ie && FD.Browser.VersionNr >= 7)) return;
	var x = getX(opTopControl), y = getY(opTopControl), w = opTopControl.offsetWidth, h = opTopControl.offsetHeight, i, obj;
	var list = (opTopControl.ownerDocument ? opTopControl.ownerDocument : document).getElementsByTagName(cpTagName);
	for (i = 0; i < list.length; i++) {
		obj = list[i];
		if (!obj || !obj.offsetParent) continue;
		var ox = getX(obj), oy = getY(obj), ow = obj.offsetWidth, oh = obj.offsetHeight;
		if (ox > (x + w) || (ox + ow) < x) continue;
		if (oy > (y + h) || (oy + oh) < y) continue;
		if (obj.style.visibility == "hidden") continue;
		if (!opTopControl.fdOverlap) opTopControl.fdOverlap = new Array();
		opTopControl.fdOverlap[opTopControl.fdOverlap.length] = obj;
		obj.style.visibility = "hidden";
	}
}
function showControl(opTopControl) {
	if (opTopControl.fdOverlap) {
		var i;
		for (i = 0; i < opTopControl.fdOverlap.length; i++)
			opTopControl.fdOverlap[i].style.visibility = "";
	}
	opTopControl.fdOverlap = null;
}
function getX(obj, excl) {
	var x = 0;
	do {
		x += obj.offsetLeft;
		if (!Browser.ie) {
			if (!excl && (!Browser.gecko || Browser.VersionNr >= 2) && obj.parentNode && obj.parentNode.scrollLeft) x -= obj.parentNode.scrollLeft;
		} else {
			if (obj.parentNode && obj.parentNode.currentStyle && obj.parentNode.currentStyle.borderWidth) x += String.create(obj.parentNode.currentStyle.borderWidth).float();
		}
		if (!excl && obj.scrollLeft) x -= obj.scrollLeft;
		obj = obj.offsetParent;
	} while (obj);
	return x;
}
function getY(obj, excl) {
	var y = 0;
	do {
		y += obj.offsetTop;
		if (!Browser.ie) {
			if (!excl && (!Browser.gecko || Browser.VersionNr >= 2) && obj.parentNode && obj.parentNode.scrollTop) y -= obj.parentNode.scrollTop;
		} else {
			if (obj.parentNode && obj.parentNode.currentStyle && obj.parentNode.currentStyle.borderWidth) y += String.create(obj.parentNode.currentStyle.borderWidth).float();
		}
		if (!excl && obj.scrollTop) y -= obj.scrollTop;
		obj = obj.offsetParent;
	} while (obj);
	return y;
}

// Events object which handles custom events
var FDEvents = new objFDEvents();

function objFDEvents(eventsOwner) {
	this.Owner = eventsOwner || window;
	this.Events = new Object();
}
objFDEvents.prototype.AttachEvent = function(eventName, functionPointer, index) {
	if (!this.Events[eventName]) this.Events[eventName] = new Array();
	var eventArray = this.Events[eventName];
	if (typeof index == 'number' && index < eventArray.length) {
		for (var i = eventArray.length - 1; i >= index; i--)
			eventArray[i + 1] = eventArray[i];
	} else
		index = eventArray.length;

	eventArray[index] = functionPointer;
}
objFDEvents.prototype.FireEvent = function(eventName, params, stop) {
	var bReturnValue = true, bRetVal = true;
	var oCalls = this.Events[eventName];
	if (oCalls) {
		var oArg = { Owner: this.Owner, eventName: eventName, params: params, returnValue: true, stopEvent: false };
		for (var i = 0; i < oCalls.length; i++) {
			if (oCalls[i]) {
				try {
					bRetVal = oCalls[i](oArg);
					bReturnValue = (typeof bRetVal == 'boolean' ? bRetVal : oArg.returnValue) && bReturnValue;
				} catch (e) { oCalls.remove(i); i--; }
				if ((!bReturnValue && stop) || oArg.stopEvent) break;
			}
		}
	}

	return bReturnValue;
}
objFDEvents.prototype.Clear = function(event) {
	if (arguments.length == 0) {
		this.Events = new Object();
	} else {
		this.Events[event] = null;
	}
}

function fireEvent(opEl, cpName, opEvent, lpCreate) {
	if (cpName == 'onresize') {
		try { window.resizeBy(0, 1); window.resizeBy(0, -1); } catch (e) { }
	} else {
		if (Browser.ie) {
			if (Browser.VersionNr >= 5.5) {
				if (lpCreate) {
					opEvent = document.createEventObject();
					opEvent.fdElement = opEl;
					opEvent.type = cpName.substr(2);
				} else {
					opEl.fireEvent(cpName, (opEvent ? opEvent : null));
				}
			} else
				opEvent = fireEventFD(opEl, cpName, opEvent, lpCreate);
		} else if (Browser.W3C) {
			if (!opEvent) opEvent = opEl.ownerDocument.createEvent((Browser.safari ? "UIEvents" : "Events"));
			opEvent.initEvent(cpName.substr(2), true, false);
			if (lpCreate)
				opEvent.fdElement = opEl;
			else
				opEl.dispatchEvent(opEvent);
		} else
			opEvent = fireEventFD(opEl, cpName, opEvent, lpCreate);
	}
	return (opEvent);
}
function fireEventFD(opEl, cpName, opEvent, lpCreate) {
	opEvent = new Object();
	opEvent.srcElement = opEl;
	opEvent.fdElement = opEl;
	opEvent.type = cpName.substr(2);
	if (!lpCreate) {
		window.fdEvent = opEvent;
		if (eval('opEl.' + cpName))
			eval('opEl.' + cpName + '();');
	}
	return (opEvent);
}
function cloneEvent(e) {
	if (!e) e = window.fdEvent || window.event;
	var clone = new Object();
	clone.fdElement = clone.srcElement = clone.target = (Browser.ie ? e.srcElement : e.target);
	clone.type = e.type;
	clone.ctrlKey = e.ctrlKey;
	clone.shiftKey = e.shiftKey;
	clone.clientX = e.clientX;
	clone.clientY = e.clientY;
	return (clone);
}
function checkEvent(e) {
	if (!e) e = window.fdEvent || window.event;
	window.fdEvent = null;
	var el = null;
	if (e) {
		if (e.fdElement)
			el = e.fdElement;
		else if (Browser.ie) {
			el = e.srcElement;
		} else
			el = e.target;
	}
	return (el);
}
function cancelEvent(e) {
	if (!e) return;
	stopEvent(e);
	if (Browser.ie) e.returnValue = false;
	else if (typeof e.preventDefault != 'undefined')
		e.preventDefault();
}
function stopEvent(e) {
	if (!e) return;
	try {
		if (Browser.ie) e.cancelBubble = true;
		else if (typeof e.stopPropagation != 'undefined')
			e.stopPropagation();
	} catch (e) { };
}
function addEventHandler(opEl, cpType, ppListener, useCapture) {
	if (opEl.addEventListener)
		opEl.addEventListener(cpType.substr(2), ppListener, useCapture);
	else if (opEl.attachEvent)
		opEl.attachEvent(cpType, ppListener);
}
function removeEventHandler(opEl, cpType, ppListener, useCapture) {
	try {
		if (opEl.removeEventListener)
			opEl.removeEventListener(cpType.substr(2), ppListener, useCapture);
		else if (opEl.detachEvent)
			opEl.detachEvent(cpType, ppListener);
	} catch (e) { };
}


function loadFile(filePath, onload) {

	// Dynamically load the file (it can be a CSS or a JS)
	var e;

	// If it is a CSS
	if (filePath.lastIndexOf('.css') > 0) {
		e = document.createElement('LINK');
		e.rel = 'stylesheet';
		e.type = 'text/css';
	}
	// It it is a JS
	else {
		e = document.createElement("script");
		e.type = "text/javascript";
	}

	// Add the new object to the HEAD.
	document.getElementsByTagName("head")[0].appendChild(e);

	// Start downloading it.
	if (e.tagName == 'LINK') {
		e.href = filePath;
	} else {
		// Gecko fires the "onload" event and IE fires "onreadystatechange"
		if (onload) e.onload = e.onreadystatechange = onload;
		e.src = filePath;
	}
}

/**
* Netscape compatible WaitForDelay function.
* You can use it as an alternative to Thread.Sleep() in any major programming language
* that support it while JavaScript it self doesn't have any built-in function to do such a thing.
* parameters:
*  (Number) delay in millisecond
*/
function nsWaitForDelay(delay) {
	/**
	* Just uncomment this code if you're building an extention for <strong class="highlight">Firefox</strong>.
	* Since FF3, we'll have to ask for user permission to execute XPCOM objects.
	*/
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");

	// Get the current thread.
	var thread = Components.classes["@mozilla.org/thread-manager;1"].getService(Components.interfaces.nsIThreadManager).currentThread;

	// Create an inner property to be used later as a notifier.
	this.delayed = true;

	/* Call JavaScript setTimeout function
	* to execute this.delayed = false
	* after it finish.
	*/
	setTimeout("this.delayed = false;", delay);

	/**
	* Keep looping until this.delayed = false
	*/
	while (this.delayed) {
		/**
		* This code will not freeze your browser as it's documented in here:
		* https://developer.mozilla.org/en/Code_snippets/Threads#Waiting_for_a_background_task_to_complete
		*/
		thread.processNextEvent(true);
	}
}
