﻿///compress=false
///cache=false
Array.prototype.forEach = function(a) { for (var i = 0; i < this.length; i++) a(this[i]); };
Array.prototype.find = function(m) { for (var i = 0; i < this.length; i++) if (m(this[i])) return this[i]; return null; };
Array.prototype.findAll = function(m) { var arr = []; for (var i = 0; i < this.length; i++) if (m(this[i])) arr.push(this[i]); return arr; };
Array.prototype.findLast = function(m) {	for (var i = this.length - 1; i >= 0; i--) if (m(this[i])) return this[i]; return null; };
Array.prototype.findIndex = function() { var a = $A(arguments); var d = a.pop(); var c = a.length > 1 ? a.pop() : this.length; var s = a.length > 0 ? a.pop() : 0; for(var i = s; i < s + c; i++) if (d(this[i])) return i;	return -1; };
Array.prototype.findLastIndex = function() { var a = $A(arguments); var m = a.pop(); var c = a.length > 1 ? a.pop() : this.length; var s = a.length > 0 ? a.pop() : this.length - 1; s = Math.min(this.length - 1, s); var e = Math.max(s - (c - 1), 0); for(var i = s; i >= e; i--) if (m(this[i]))	return i; return -1; };
Array.prototype.indexOf = function() { var argArr = $A(arguments); var count = argArr.length > 2 ? argArr.pop() : this.length; var start = argArr.length > 1 ? argArr.pop() : 0; var item = argArr.length > 0 ? argArr.pop() : null; count = Math.min(count, this.length - start); for (var i = start; i < count; i++) if (this[i] === item) return i; return -1; };
Array.prototype.trueForAll = function(match) { for (var i = 0; i < this.length; i++) if (!match(this[i])) return false; return true; };
Array.prototype.remove = function(item) { for(var i = 0; i < this.length; i++) if(this[i] === item) return this.removeAt(i); };
Array.prototype.removeAt = function(index) { var ret = this[index]; for(var i = index; i < this.length-1; i++) this[i] = this[i+1]; this.pop(); return ret; };
Array.prototype.removeAll = function(match) { var i1 = 0; while ((i1 < this.length) && !match(this[i1])) i1++; if (i1 >= this.length) return 0; var i2 = i1 + 1; while (i2 < this.length) { while ((i2 < this.length) && match(this[i2])) i2++; if (i2 < this.length) this[i1++] = this[i2++]; } this.clear(i1, this.length - i1); return this.length - i1; };
Array.prototype.clear = function() { var argArr = $A(arguments); var count = argArr.length > 1 ? argArr.pop() : null; var start = argArr.length > 0 ? argArr.pop() : 0;	if ($null(count)) count = this.length - start; var end = start + count;	while (start++ < end) this.pop(); };
Array.prototype.contains = function(item) { for(var i = 0; i < this.length; i++) if(this[i] === item) return true; return false; };
Array.prototype.exists = function(match) { for (var i = 0; i < this.length; i++) if (match(this[i])) return true; return false; };
Array.prototype.add = function(item) { this.push(item);};
Array.prototype.addRange = function(arr, ignoreDuplicates) { for (var i = 0; i < arr.length; i++) if (!ignoreDuplicates || (ignoreDuplicates && !this.contains(arr[i]))) this.push(arr[i]); };
Array.prototype.insert = function(index, item) { for(var i = this.length; i > index; i--) this[i] = this[i-1]; this[index] = item; };
Array.checkArray = function(arr) { if (!arr.push) return arr.split(sep); return arr; };
Array.prototype.push = function() { var n = this.length >>> 0; for (var i = 0; i < arguments.length; i++) { this[n] = arguments[i]; n = n + 1 >>> 0; } this.length = n; return n; };
Array.prototype.pop = function() { var n = this.length >>> 0, value; if (n) { value = this[--n]; delete this[n]; } this.length = n; return value; };
String.prototype.trim = function() { return this.replace(/^\s*|\s*$/g,""); };
String.prototype.startsWith = function(str, ignoreCase) { var thisStr = ignoreCase ? this.toLowerCase() : this; str = ignoreCase ? str.toLowerCase() : str; if (ignoreCase) return thisStr.startsWith(str, false); return this.length>=str.length && this.substring(0, str.length) == str; };
String.prototype.startsWithAny = function(arr, ignoreCase) { arr = Array.checkArray(arr); for (var i = 0; i < arr.length; i++) if (this.startsWith(arr[i], ignoreCase)) return true; return false; };
String.prototype.endsWith = function(str, ignoreCase) { var thisStr = ignoreCase ? this.toLowerCase() : this; str = ignoreCase ? str.toLowerCase() : str; if (ignoreCase) return thisStr.endsWith(str, false); return this.length>=str.length && this.substring(this.length-str.length) == str; };
String.prototype.endsWithAny = function(arr, ignoreCase) { arr = Array.checkArray(arr); for (var i = 0; i < arr.length; i++) if (this.endsWith(arr[i], ignoreCase)) return true; return false; };
String.prototype.contains = function(str, ignoreCase) { var thisStr = ignoreCase ? this.toLowerCase() : this; str = ignoreCase ? str.toLowerCase() : str; if (ignoreCase) return thisStr.contains(str, false); return this.indexOf(str) >= 0; };
String.prototype.containsAny = function(arr, ignoreCase) { arr = Array.checkArray(arr); for (var i = 0; i < arr.length; i++) if (this.contains(arr[i], ignoreCase)) return true; return false; };
String.prototype.insert = function(startIndex, str) { return this.substring(0, startIndex) + str + this.substring(startIndex); };
String.prototype.padLeft = function(totalWidth, paddingChar) { if(!paddingChar || paddingChar.length == 0) paddingChar = " "; var newStr = this; while(newStr.length < totalWidth) newStr = paddingChar+newStr; return newStr; };
String.prototype.padRight = function(totalWidth, paddingChar) { if(!paddingChar || paddingChar.length == 0) paddingChar = " "; var newStr = this; while(newStr.length < totalWidth) newStr += paddingChar; return newStr; };
String.prototype.compareTo = function(str) { for(var i = 0; i < str.length; i++){ var code1 = this.charCodeAt(i); var code2 = str.charCodeAt(i); return code1.compareTo(code2); } };
String.prototype.reverse = function() { var str = ""; for(var i = this.length-1; i > -1; i--) str += this.substring(i-1, i); return str; };
String.prototype.remove = function(start, length) { if (!$number(length)) length = this.length - start;	var ret = ""; if (start > 0) ret = this.substring(0, start); ret += this.substring(start + length); return ret; };
String.format = function(str) { for(var i = 1; i < arguments.length; str=str.replace(new RegExp("\{" + (i-1) + "\}", "g"), arguments[i++])); return str; };
String.join = function(array, seperator, startIndex, count) { if(!seperator) seperator = ""; if(!startIndex) startIndex = 0; if(!count) count = array.length; var str = ""; for(var i = startIndex; i < count; str+=((i==startIndex)?"":seperator)+array[i++].toString()); return str; };
String.concat = function() { var str = ""; for(var i = 0; i < arguments.length; str+=arguments[i++].toString()); return str; };
String.compare = function(strA, strB) { return strA.compareTo(strB); };
String.isNullOrEmpty = function(str, trim) { if($null(str)) return true; if(trim) return str.trim().length == 0; return str.length == 0; };
Number.prototype.compareTo = function(num) { if(this > num) return 1; if(num > this) return -1; return 0; };
Number.prototype.wrap = function(n, x) { if (this > x) return n; return this; };
Number.compare = function(numA, numB) { return numA.compareTo(numB); };

function $A(e) { var a = []; for (var i = 0; i < e.length;)	a.push(e[i++]); return a; };
function $a(e) { return $A(e); }
function $number(n) { if (typeof n === "string") return parseInt(n).toString() != "NaN"; return typeof n === "number"; };
function $null(o) { return typeof o === "undefined" || o == null; };
function $function(f) { return typeof f === "function" || typeof f === "object"; };
function $string(s) { return typeof s === "string"; };
function $array(a) { return $number(a["length"]) && $function(a["splice"]); };
function $boolean(b) { return typeof b === "boolean"; };
function $bool(b) { return typeof b === "boolean"; };
function $object(o) { return typeof o === "object"; };
function $element(e) { return $object(e) && $function(e["appendChild"]); };
function $ns(n) { return Ekina.__cNs(n); }
function $E(p, c, t) { if (!$string(t)) t = "div"; var e = document.createElement(t); if ($object(p) && $function(p.appendChild)) p.appendChild(e); if ($string(c))	e.className = c; return Ekina.DOM.setupElement(e); };
function $e(p, c, t) { return $E(p, c, t); };
function $P(e, r) {
	if (!r) r = document.documentElement;
	var pos = {x:0,y:0};
	
	while(e && e != r) { 
		pos.x += e.offsetLeft; 
		pos.y += e.offsetTop;
		e = e.offsetParent;
	}
	return pos;
};

function $p(e, r) { return $P(e, r); };
function $(e) { return Ekina.DOM.getElementByExpression(e); }
function $f(e, d) { return (($(e) || {}).value || d || ""); };

function $x(e, o) { for (var i in o) e[i] = o[i]; };

function $scroll() { var s = {x:0, y:0}; if (window.innerHeight && window.scrollMaxY) {	s.x = document.body.scrollWidth; s.y = window.innerHeight + window.scrollMaxY; } else if (document.body.scrollHeight > document.body.offsetHeight){ s.x = document.body.scrollWidth; s.y = document.body.scrollHeight; } else { s.x = document.body.offsetWidth; s.y = document.body.offsetHeight; } return s; };
function $page() { var s = $scroll(); var ws = $window(); return { width: Math.max(ws.width, s.x), height: Math.max(ws.height, s.y) }; };
function $window() { var w = {width:0, height:0}; if (self.innerHeight) { w.width = self.innerWidth; w.height = self.innerHeight; } else if (document.documentElement && document.documentElement.clientHeight) { w.width = document.documentElement.clientWidth; w.height = document.documentElement.clientHeight; } else if (document.body) { w.width = document.body.clientWidth; w.height = document.body.clientHeight; } return w; };
function $viewport() { var w = $window(); return {width: w.width, height: w.height, x: document.body.scrollLeft, y: document.body.scrollTop}; };
function $center() { var v = $viewport(); return {x: v.width / 2, y: v.height / 2}; };


var Ekina = {  };
Ekina.Browser = { ie:0, opera:0, gecko:0, safari:0, mobile: "" };
var ua=navigator.userAgent, m; if ((/KHTML/).test(ua)) Ekina.Browser.safari = 1; m = ua.match(/AppleWebKit\/([^\s]*)/); if (m && m[1]) { Ekina.Browser.safari = parseFloat(m[1]); if (/ Mobile\//.test(ua)) Ekina.Browser.mobile = "Apple"; else { m = ua.match(/NokiaN[^\/]*/); if (m) Ekina.Browser.mobile = m[0];}} if (!Ekina.Browser.safari) { m = ua.match(/Opera[\s\/]([^\s]*)/); if (m && m[1]) { Ekina.Browser.opera = parseFloat(m[1]); m = ua.match(/Opera Mini[^;]*/); if (m) Ekina.Browser.mobile = m[0]; } else { m = ua.match(/MSIE\s([^;]*)/); if (m && m[1]) Ekina.Browser.ie = parseFloat(m[1]); else { m = ua.match(/Gecko\/([^\s]*)/); if (m) { Ekina.Browser.gecko = 1; m = ua.match(/rv:([^\s\)]*)/); if (m && m[1]) { Ekina.Browser.gecko = parseFloat(m[1]); } } } } };
Ekina.DOM = { 
	isEkinaElement : function(el) { return $function(el.addClass) && $function(el.removeClass); },
	setupElements : function(arr) { 
	    var dom = Ekina.DOM; 
	    var ecm = dom.__ecm; 
	    for (var i = 0; i < arr.length; i++) 
	        arr[i] = dom.setupElement(arr[i]); 
	    for (var i in ecm)
	    if (!$null(ecm[i]))
	        arr[i] = ecm[i]; return arr; 
	},
	setupElement : function(el, d) {
	    if (!el) return el;
	    if ($function(el.addClass) && $function(el.removeClass))
	        return el;
	    var dom = Ekina.DOM;
	    var em = dom.__em;
	    if ($null(el)) return el;
	    if (!dom.isEkinaElement(el));
	    for (var i in em)
	        if (!$null(em[i]))
	            el[i] = em[i];
	    if ($bool(d) && d)
	        for (var i = 0; i < el.childNodes.length; i++)
	            this.setupElement(el.childNodes[i], true);
	    return el;
	},
	extendElement : function(n, f) { Ekina.DOM.__em[n] = f; },
	extendElementCollection : function(n, f) { Ekina.DOM.__ecm[n] = f; },
	__getPosition : function(e, r, rel) { if (!r) r = document.documentElement; var p = {x: 0, y: 0}; while(e && e != r) { p.x += e.offsetLeft; p.y += e.offsetTop; e = e.offsetParent; if (rel && e && e.style && e.style.position && e.style.position.containsAny(["absolute", "relative"])) break; } return p; },
	__getRelativeParent : function(e) { while(true) { if (!e.offsetParent || e.offsetParent == e) return Ekina.DOM.setupElement(e); if (e.offsetParent.style.position.containsAny(["absolute", "relative"])) return Ekina.DOM.setupElement(e.offsetParent); e = e.offsetParent; } return Ekina.DOM.setupElement(document.documentElement); },
	__computedStyle : function(e, s) { if (e.currentStyle) return e.currentStyle[s]; return document.defaultView.getComputedStyle(e, null).getPropertyValue(s); },
	__em : { 
		getPosition : function(r) { return Ekina.DOM.__getPosition(this, r, false); },
		getRelativePosition : function(r) { return Ekina.DOM.__getPosition(this, r, true); },
		getRelativeParent : function() { return Ekina.DOM.__getRelativeParent(this); },
		getSize : function() { return { width: this.offsetWidth, height: this.offsetHeight }; },
		appendTo : function(el) { var dom = Ekina.DOM; if ($string(el)) el = dom.getSingleElement(el); if ($null(el) || !$function(el.appendChild)) return null; el.appendChild(this); return this; },
		addClass : function(cls) { if (String.isNullOrEmpty(cls, true)) return; var current = this.className; var arr = current.split(" "); if (!arr.contains(cls)) arr.add(cls); this.className = String.join(arr, " "); return this; },
		removeClass : function(cls) { if (String.isNullOrEmpty(cls, true)) return; var current = this.className; var arr = current.split(" "); if (arr.contains(cls)) arr.remove(cls); this.className = String.join(arr, " "); return this; },
		css : function() { var dom = Ekina.DOM; if (arguments.length == 1){ if ($null(arguments[0])) return this; for (var i in arguments[0]) this.style[dom.makeJsStyle(i)] = arguments[0][i]; } else for (var i = 0; i < arguments.length; i+=2) this.style[dom.makeJsStyle(arguments[i])] = arguments[i+1]; return this; },
		attribute : function() { var dom = Ekina.DOM; if (arguments.length == 1){ if ($null(arguments[0])) return this; for (var i in arguments[0]) this[i] = arguments[0][i]; } else for (var i = 0; i < arguments.length; i+=2) this[arguments[i]] = arguments[i+1]; return this; },
		getBorderWidth : function() { var top = (Ekina.Browser.ie || Ekina.Browser.opera) ? "borderTopWidth" : "border-top-width"; var right = (Ekina.Browser.ie || Ekina.Browser.opera) ? "borderRightWidth" : "border-right-width"; var bottom = (Ekina.Browser.ie || Ekina.Browser.opera) ? "borderBottomWidth" : "border-bottom-width"; var left = (Ekina.Browser.ie || Ekina.Browser.opera) ? "borderLeftWidth" : "border-left-width"; return { top: parseInt(Ekina.DOM.__computedStyle(this, top)), right: parseInt(Ekina.DOM.__computedStyle(this, right)), bottom: parseInt(Ekina.DOM.__computedStyle(this, bottom)), left: parseInt(Ekina.DOM.__computedStyle(this, left)) }; },
		show : function() { this.css("display", "block"); },
		hide : function() { this.css("display", "none"); },
		toggleDisplay : function() { this.css("display", this.style.display=="none" ? "block" : "none"); },
		containsClass : function(c) { return Ekina.DOM.containsClass(this, c); }
	},
	__ecm : {
		addClass : function(cls) { this.forEach(function(el) { el.addClass(cls); }); return this; },
		removeClass : function(cls) { this.forEach(function(el) { el.removeClass(cls); }); return this; },
		css : function() { var args = $A(arguments); var argList = {}; if (args.length > 1) for (var i = 0; i < args.length; i++) argList[args[i]] = args[i+1]; else argList = args[0]; this.forEach(function(el) { el.css(argList); }); return this; },
		appendTo : function(parent) { this.forEach(function(el) { el.appendTo(parent); }); return this; },
		show : function() { this.forEach(function(el) { el.show(); }); return this },
		hide : function() { this.forEach(function(el) { el.hide(); }); return this }
	},
	getElementByExpression : function(expr) { var dom = Ekina.DOM; if (!$string(expr) || String.isNullOrEmpty(expr, true)) return null; var c = expr.substring(0, 1); switch (c) { case ".": expr = expr.replace(/\./g, ""); var els = dom.getElementsByClassName(expr, document.getElementsByTagName("body")[0]); if (els.length == 1) return dom.setupElement(els[0]); else return dom.setupElements(els); case "<": return dom.setupElement(dom.createElementFromHtmlFragment(expr), true); break; case "#": expr = expr.remove(0, 1); default: return dom.setupElement(document.getElementById(expr)); } },
	getElementsByClassName : function(c, e) { var dom = Ekina.DOM; var a = []; for (var i = 0; i < e.childNodes.length; i++) { if (dom.containsClass(e.childNodes[i], c)) a.add(e.childNodes[i]); a.addRange(dom.getElementsByClassName(c, e.childNodes[i])); } return a; },
	getSingleElement : function(e) { var es = $(e); if ($function(es.push)) return es[0]; return es; },
	containsClass : function(e, c) { if ($null(e)) return false; if (String.isNullOrEmpty(e.className, true)) return false; return e.className.split(" ").contains(c); },
	makeJsStyle : function(s) { return s.replace(/\-(.)/g, function(m) { return m.substring(1).toUpperCase(); }); },
	createElementFromHtmlFragment : function(html) { var d = $e(); d.innerHTML = html; if (d.childNodes.length == 0) return null; var n = d.childNodes[0]; delete d; return n; }
};

Ekina.UI = { 
	__lockLayer_zIndexCounter : 1000,
	createLockLayer : function(alpha, tint, clickHandler, showHandler, show, fadeTime) { var e = $("<div></div>").appendTo(document.body).css({ zIndex: Ekina.UI.__lockLayer_zIndexCounter, backgroundColor: tint || "black", position: "absolute", left: "0px", top: "0px", width: "0px", height: "0px" }); if (Ekina.Browser.ie) e.css("filter", "alpha(opacity=0)"); else e.css("opacity", "0"); $x(e, Ekina.UI.LockLayerImpl); e.alpha = alpha || e.alpha; if ($function(clickHandler)) e.onclick = clickHandler; Ekina.UI.__lockLayer_zIndexCounter += 1000; if (show) e.show(fadeTime, showHandler); return e; },
	LockLayerImpl : {
		alpha : 50,		
		show : function(fadeTime, showHandler) { this.visible = true; showHandler = showHandler || function(){}; this.showHandler = showHandler; var realThis = this; var p = $page(); this.css({ width: p.width + "px", height: p.height + "px" }); var dxAlpha = this.alpha; var mozAlpha = this.alpha / 100; if ($number(fadeTime)) { this.fadeIn(dxAlpha, fadeTime, function() { realThis.showHandler(); }); } else { if (Ekina.Browser.ie) this.css("filter", "alpha(opacity=" + dxAlpha + ")"); else this.css("opacity", mozAlpha); this.showHandler(); } this.oldResize = window.onresize; window.onresize = function() { var p = $page(); realThis.css({ width: p.width + "px", height: p.height + "px" }); if (realThis.oldResize) realThis.oldResize(); }; },			
		hide : function(fadeTime, hideHandler) { this.visible = false; hideHandler = hideHandler || function(){}; this.hideHandler = hideHandler; var realThis = this; if ($number(fadeTime)) { this.fadeOut(0, fadeTime, function() { realThis.css({ width: "0px", height: "0px" }); realThis.hideHandler(); }); } else { this.css({ width: "0px", height: "0px" }); if (Ekina.Browser.ie) this.css("filter", "alpha(opacity=0)"); else this.css("opacity", "0"); this.hideHandler(); } window.onresize = this.oldResize; },
		visible : false
	}
	
//	loadingImageSrc : "loading.gif",
//	__loadingImage_el : null,
//	showLoading : function(e) { e = e || document.body; if (Ekina.UI.__loadingImage_el) Ekina.UI.__loadingImage_el.parentNode.removeChild(Ekina.UI.__loadingImage_el); Ekina.UI.__loadingImage_el = $("<img />").appendTo(e);Ekina.UI.__loadingImage_el.onload = function() { var realThis = this; if (e == document.body) { var vp = $viewport(); Ekina.UI.__loadingImage_el.css({ position: "absolute", zIndex: "65535", left: (document.body.scrollLeft + ((vp.width / 2) - (realThis.width / 2))) + "px", top: (document.body.scrollTop + ((vp.height / 2) - (realThis.height / 2))) + "px" }); }else { Ekina.UI.__loadingImage_el.css({position: "absolute", zIndex: "65535", left: (e.offsetWidth / 2) + "px", top: (e.offsetHeight / 2) + "px" }); } this.onload = null; }; Ekina.UI.__loadingImage_el.src = Ekina.UI.loadingImageSrc },
//	hideLoading : function() { if (Ekina.UI.__loadingImage_el) Ekina.UI.__loadingImage_el.parentNode.removeChild(Ekina.UI.__loadingImage_el); Ekina.UI.__loadingImage_el = null;}
};

Ekina.Events = {
	__eventElements: {},
	register : function (element, eventName, handler) {
		if (!this.__eventElements[eventName])
			this.__eventElements[eventName] = [];
		this.__eventElements[eventName].push({element : element, handler : handler});
		eventName = this.__normalizeEvent(eventName);
		this.__registerEvent(element, eventName, handler);
	},
	unregister : function (element, eventName, handler) { eventName = this.__normalizeEvent(eventName); var evt = this.__findEventStruct(element, eventName, handler); if(evt == -1) return; this.__eventElements[eventName].splice(evt, 1); this.__unregisterEvent(element, eventName, handler); },
	normaliseMouseEvent : function(e) { e = e || window.event; var p = this.__getPageXY(e); return { target: this.__getTarget(e), x: p.x, y: p.y, buttons: this.__getButtons(e), relatedTarget: this.__getRelatedTarget(e) }; },
	normaliseKeyEvent: function(e) { e = e || window.event; var modifiers = this.__getModifiers(e); return { keyCode: e.keyCode || e.which, charCode: this.__getCharCode(e), alt: modifiers & this.ALTMASK, ctrl: modifiers & this.CTRLMASK, shift: modifiers & this.SHIFTMASK }; },
	__findEventStruct : function (element, eventName, handler) { var evt = this.__eventElements[eventName]; if (!evt) { this.__eventElements[eventName] = new Array(); return -1; } for (var i = 0; i < evt.length; i++) if (evt[i].element == element && evt[i].handler == handler) return i;	return -1; },
	__normalizeEvent : function (eventName) { eventName = eventName.toLowerCase(); if (document.addEventListener) return eventName.substring(0, 2) == "on" ? eventName.substring(2) : eventName; else if (document.attachEvent) return eventName.substring(0, 2) == "on" ? eventName : "on" + eventName; else alert("Cannot normalize event - unknown DOM");	return ""; },
	__registerEvent : function (element, eventName, handler) { if (element.addEventListener) element.addEventListener(eventName, handler, false); else if (element.attachEvent) element.attachEvent(eventName, handler); else alert("Error registering event - Cannot register event \"" + eventName + "\" for the passed element"); },
	__unregisterEvent : function (element, eventName, handler) { if (element.removeEventListener) element.removeEventListener(eventName, handler, false); else if (element.detachEvent) element.detachEvent(eventName, handler); else alert("Error unregistering event - Cannot unregister event \"" + eventName + "\" for the passed element"); },
	__resolveTextNode: function(n) { if (n && 3 == n.nodeType) { return n.parentNode; } else { return n; } },
    __getTarget: function(e, resolveTextNode) { return this.__resolveTextNode(e.target || e.srcElement); },
    __getRelatedTarget: function(e) { var t = e.relatedTarget; if (!t) { if (e.type == "mouseout") t = e.toElement; else if (e.type == "mouseover") t = e.fromElement; } return this.__resolveTextNode(t); },
    __getScroll: function() { var de = document.documentElement, db = document.body; if (de && (de.scrollTop || de.scrollLeft)) return [de.scrollTop, de.scrollLeft]; else if (db) return [db.scrollTop, db.scrollLeft]; else return [0, 0]; },
    __getPageXY: function(e) { var x = e.pageX; var y = e.pageY; var s = this.__getScroll(); if (!x && 0 !== x) { x = e.clientX || 0; if ( Ekina.Browser.ie ) x += s[0]; } if (!y && 0 !== y) { y = e.clientY || 0; if ( Ekina.Browser.ie ) y += s[1]; } return {x:x, y:y}; },
	__getButtons: function(e) { if (e.which) { return { left: e.which == 1,	middle: e.which == 2, right: e.which == 3 }; } else { return { left: e.button == 1, middle: e.button == 4, right: e.button == 2 }; } },
	ALTMASK: 1,
	CTRLMASK: 2,
	SHIFTMASK: 4,
	__getModifiers: function(e) { var ret = 0; if (e.altKey) ret |= this.ALTMASK; if (e.ctrlKey) ret |= this.CTRLMASK; if (e.shiftKey) ret |= this.SHIFTMASK; return ret; },
	__safariKeymap: { 63232: 38, 63233: 40, 63234: 37, 63235: 39, 63276: 33, 63277: 34, 25: 9 },
	__getCharCode: function(e) { var c = e.keyCode || e.charCode || 0; if (Ekina.Browser.safari && (c in this.__safariKeymap)) c = this.__safariKeymap[code]; return c; },
	fire: function(context, evt, args) {
		var evt = Ekina.Events.__eventElements[evt];
		if (evt)
			evt.forEach(function(e) {
				if (e.element == context)
					e.handler(args);
			});
	}
};

Ekina.ScriptLoader = {
	load: function(url, callback) { this.__queue.push({url:url,cb:callback}); this.__loadFromQueue(); },
	__createHttpObject: function(){var xmlhttp = false;try{xmlhttp = new ActiveXObject("Msxml2.XMLHTTP");}catch(ex1){try{xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");}catch(ex2){xmlhttp = false;}}if(!xmlhttp && typeof XMLHttpRequest!='undefined')xmlhttp = new XMLHttpRequest();return xmlhttp;},
	__queue: [],
	__http: null,
	__cb: null,
	__loadFromQueue: function() { if (this.__queue.length == 0) return; if (this.__http) return; var u = this.__queue.pop(); this.__cb = u.cb; this.__http = this.__createHttpObject(); this.__http.open("GET", u.url, true); this.__http.send(null); var _this = this; this.__timer = window.setInterval(function() {_this.__checkStatus();}, 100); },
	__timer: null,
	__checkStatus: function() { if(this.__http.readyState == 4){ window.clearInterval(this.__timer); this.__evaluateScript(this.__http.responseText); this.__http = null; if (this.__cb) this.__cb(); this.__cb = null; this.__loadFromQueue(); } },
	__evaluateScript: function(s) { try { eval(s); } catch (e) { alert("Failed to load script: " + e.message); alert(s); } }
};

Ekina.ScriptLoader.scriptLookup = [
	{sc:"Effects", fp:"Ekina.UI.Effects"},
	{sc:"Validation", fp:"Ekina.Validation"},
	{sc:"DragDrop", fp:"Ekina.UI.DragDrop"},
	{sc:"Dialogs", fp:"Ekina.UI.Dialogs"}
];

(Ekina.ScriptLoader.loadScripts = function() {
	var el = document.getElementsByTagName("script");

	if (!el) return;

	for (var i = 0; i < el.length; i++) {
		var e = el[i];
		var src = e.attributes["src"].value;
		if (!src.contains("?")) continue;
		var li = src.lastIndexOf("/");
		var path = "";
		if (li > -1) {
			path = src.substring(0, li + 1);
			src = src.substring(li + 1);
		}
		var qp = src.indexOf("?");
		var name = src.substring(0, qp);
		var q = src.substring(qp);
		if (q.length == 1) continue;
		q = q.substring(1);
		var ss = q.split("+");
		Ekina.ScriptLoader.loading = 0;
		var toLoad = [];
		ss.forEach(function(s) {
		
			var lu = Ekina.ScriptLoader.scriptLookup.find(function(ll) {
				return ll.sc.toLowerCase() == s.toLowerCase();
			});
			
			if (lu)
				s = lu.fp;
		
			if (!s.startsWith("Ekina."))
				s = "Ekina." + s;
			s = path + s + ".js";
			Ekina.ScriptLoader.loading++;
			toLoad.push(s);
		});
		
		toLoad.forEach(function(s) {
			Ekina.ScriptLoader.load(s, function() {
				Ekina.ScriptLoader.loading--;
				if (Ekina.ScriptLoader.loading == 0)
					Ekina.DOM.fireDomReady();
			});
		});
	}

	el = null;
})();

Ekina.DOM.fireDomReady = function() {
	if (!window.loaded || Ekina.ScriptLoader.loading) return;
	Ekina.Events.fire(window, 'ondomready', null);
};

(Ekina.DOM.init = function() {
	if (window.loaded){
		Ekina.DOM.fireDomReady();
		return;
	}
	var domReady = function(){
		if (window.loaded) return;
		window.loaded = true;
		window.timer = window.clearInterval(window.timer);
		Ekina.DOM.fireDomReady();
	};
	if (document.readyState && Ekina.Browser.safari){
		window.timer = window.setInterval(function() {
			if (['loaded','complete'].contains(document.readyState))
				domReady();
		}, 50);
	} else if (document.readyState && Ekina.Browser.ie){
		if (!$('ie_ready')){
			var src = (window.location.protocol == 'https:') ? '://0' : 'javascript:void(0)';
			document.write('<script id="ie_ready" defer src="' + src + '"><\/script>');
			$('ie_ready').onreadystatechange = function() {
				if (this.readyState == 'complete')
					domReady();
			};
		}
	} else {
		Ekina.Events.register(window, "load", domReady);
		Ekina.Events.register(window, "DOMContentLoaded", domReady);
	}
})();

window.ekinaLoaded = true;

