 function asc_currency_selector_on_change(url)
 {
     sel = document.getElementById('currency_selector');
     currency_id = sel.options[sel.selectedIndex].value;
     url = url.replace('%currency_id_value%', currency_id);
     window.location = url;
 }

function asc_go(url)
{
    if (url == '') return false;
    location.href=url;
    return true;
}

function formatPrice(price, settings)
{
	var t = price.toFixed(settings.precision);

    t = t.split('.');
	var d = t[settings.precision == 0 ? 0 : 1].substr(0,settings.precision);
	
	var p;
	for (p = (t=t[0]).length; (p-=3)>=1;) {
		t = t.substr(0,p)+settings.thousands+t.substr(p);
	}

	var v = (settings.precision > 0)
        ? t+settings.decimal+d+Array((settings.precision+1)-d.length).join(0)
        : t;
    
    var format = price < 0 ? settings.negative : settings.positive;
    return format.replace('{s}', settings.symbol).replace('{v}', v);
}
/**
 * jCarousel - Riding carousels with jQuery
 *   http://sorgalla.com/jcarousel/
 *
 * Copyright (c) 2006 Jan Sorgalla (http://sorgalla.com)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * Built on top of the jQuery library
 *   http://jquery.com
 *
 * Inspired by the "Carousel Component" by Bill Scott
 *   http://billwscott.com/carousel/
 */
eval(function(p,a,c,k,e,r){e=function(c){return(c<a?'':e(parseInt(c/a)))+((c=c%a)>35?String.fromCharCode(c+29):c.toString(36))};if(!''.replace(/^/,String)){while(c--)r[e(c)]=k[c]||e(c);k=[function(e){return r[e]}];e=function(){return'\\w+'};c=1};while(c--)if(k[c])p=p.replace(new RegExp('\\b'+e(c)+'\\b','g'),k[c]);return p}('(9($){$.1s.A=9(o){z 4.14(9(){2H r(4,o)})};8 q={W:F,23:1,1G:1,u:7,15:3,16:7,1H:\'2I\',24:\'2J\',1i:0,B:7,1j:7,1I:7,25:7,26:7,27:7,28:7,29:7,2a:7,2b:7,1J:\'<N></N>\',1K:\'<N></N>\',2c:\'2d\',2e:\'2d\',1L:7,1M:7};$.A=9(e,o){4.5=$.17({},q,o||{});4.Q=F;4.D=7;4.H=7;4.t=7;4.R=7;4.S=7;4.O=!4.5.W?\'1N\':\'2f\';4.E=!4.5.W?\'2g\':\'2h\';8 a=\'\',1d=e.J.1d(\' \');1k(8 i=0;i<1d.K;i++){6(1d[i].2i(\'A-2j\')!=-1){$(e).1t(1d[i]);8 a=1d[i];1l}}6(e.2k==\'2K\'||e.2k==\'2L\'){4.t=$(e);4.D=4.t.18();6(4.D.1m(\'A-H\')){6(!4.D.18().1m(\'A-D\'))4.D=4.D.B(\'<N></N>\');4.D=4.D.18()}X 6(!4.D.1m(\'A-D\'))4.D=4.t.B(\'<N></N>\').18()}X{4.D=$(e);4.t=$(e).2M(\'>2l,>2m,N>2l,N>2m\')}6(a!=\'\'&&4.D.18()[0].J.2i(\'A-2j\')==-1)4.D.B(\'<N 2N=" \'+a+\'"></N>\');4.H=4.t.18();6(!4.H.K||!4.H.1m(\'A-H\'))4.H=4.t.B(\'<N></N>\').18();4.S=$(\'.A-11\',4.D);6(4.S.u()==0&&4.5.1K!=7)4.S=4.H.1u(4.5.1K).11();4.S.V(4.J(\'A-11\'));4.R=$(\'.A-19\',4.D);6(4.R.u()==0&&4.5.1J!=7)4.R=4.H.1u(4.5.1J).11();4.R.V(4.J(\'A-19\'));4.H.V(4.J(\'A-H\'));4.t.V(4.J(\'A-t\'));4.D.V(4.J(\'A-D\'));8 b=4.5.16!=7?1n.1O(4.1o()/4.5.16):7;8 c=4.t.2O(\'1v\');8 d=4;6(c.u()>0){8 f=0,i=4.5.1G;c.14(9(){d.1P(4,i++);f+=d.T(4,b)});4.t.y(4.O,f+\'U\');6(!o||o.u===L)4.5.u=c.u()}4.D.y(\'1w\',\'1x\');4.R.y(\'1w\',\'1x\');4.S.y(\'1w\',\'1x\');4.2n=9(){d.19()};4.2o=9(){d.11()};4.1Q=9(){d.2p()};6(4.5.1j!=7)4.5.1j(4,\'2q\');6($.2r.2s){4.1e(F,F);$(2t).1y(\'2P\',9(){d.1z()})}X 4.1z()};8 r=$.A;r.1s=r.2Q={A:\'0.2.3\'};r.1s.17=r.17=$.17;r.1s.17({1z:9(){4.C=7;4.G=7;4.Y=7;4.12=7;4.1a=F;4.1f=7;4.P=7;4.Z=F;6(4.Q)z;4.t.y(4.E,4.1A(4.5.1G)+\'U\');8 p=4.1A(4.5.23);4.Y=4.12=7;4.1p(p,F);$(2t).1R(\'2u\',4.1Q).1y(\'2u\',4.1Q)},2v:9(){4.t.2w();4.t.y(4.E,\'2R\');4.t.y(4.O,\'2S\');6(4.5.1j!=7)4.5.1j(4,\'2v\');4.1z()},2p:9(){6(4.P!=7&&4.Z)4.t.y(4.E,r.I(4.t.y(4.E))+4.P);4.P=7;4.Z=F;6(4.5.1I!=7)4.5.1I(4);6(4.5.16!=7){8 a=4;8 b=1n.1O(4.1o()/4.5.16),O=0,E=0;$(\'1v\',4.t).14(9(i){O+=a.T(4,b);6(i+1<a.C)E=O});4.t.y(4.O,O+\'U\');4.t.y(4.E,-E+\'U\')}4.15(4.C,F)},2T:9(){4.Q=1g;4.1e()},2U:9(){4.Q=F;4.1e()},u:9(s){6(s!=L){4.5.u=s;6(!4.Q)4.1e()}z 4.5.u},2V:9(i,a){6(a==L||!a)a=i;6(4.5.u!==7&&a>4.5.u)a=4.5.u;1k(8 j=i;j<=a;j++){8 e=4.M(j);6(!e.K||e.1m(\'A-1b-1B\'))z F}z 1g},M:9(i){z $(\'.A-1b-\'+i,4.t)},2x:9(i,s){8 e=4.M(i),1S=0,2x=0;6(e.K==0){8 c,e=4.1C(i),j=r.I(i);1q(c=4.M(--j)){6(j<=0||c.K){j<=0?4.t.2y(e):c.1T(e);1l}}}X 1S=4.T(e);e.1t(4.J(\'A-1b-1B\'));1U s==\'2W\'?e.2X(s):e.2w().2Y(s);8 a=4.5.16!=7?1n.1O(4.1o()/4.5.16):7;8 b=4.T(e,a)-1S;6(i>0&&i<4.C)4.t.y(4.E,r.I(4.t.y(4.E))-b+\'U\');4.t.y(4.O,r.I(4.t.y(4.O))+b+\'U\');z e},1V:9(i){8 e=4.M(i);6(!e.K||(i>=4.C&&i<=4.G))z;8 d=4.T(e);6(i<4.C)4.t.y(4.E,r.I(4.t.y(4.E))+d+\'U\');e.1V();4.t.y(4.O,r.I(4.t.y(4.O))-d+\'U\')},19:9(){4.1D();6(4.P!=7&&!4.Z)4.1W(F);X 4.15(((4.5.B==\'1X\'||4.5.B==\'G\')&&4.5.u!=7&&4.G==4.5.u)?1:4.C+4.5.15)},11:9(){4.1D();6(4.P!=7&&4.Z)4.1W(1g);X 4.15(((4.5.B==\'1X\'||4.5.B==\'C\')&&4.5.u!=7&&4.C==1)?4.5.u:4.C-4.5.15)},1W:9(b){6(4.Q||4.1a||!4.P)z;8 a=r.I(4.t.y(4.E));!b?a-=4.P:a+=4.P;4.Z=!b;4.Y=4.C;4.12=4.G;4.1p(a)},15:9(i,a){6(4.Q||4.1a)z;4.1p(4.1A(i),a)},1A:9(i){6(4.Q||4.1a)z;i=r.I(i);6(4.5.B!=\'1c\')i=i<1?1:(4.5.u&&i>4.5.u?4.5.u:i);8 a=4.C>i;8 b=r.I(4.t.y(4.E));8 f=4.5.B!=\'1c\'&&4.C<=1?1:4.C;8 c=a?4.M(f):4.M(4.G);8 j=a?f:f-1;8 e=7,l=0,p=F,d=0;1q(a?--j>=i:++j<i){e=4.M(j);p=!e.K;6(e.K==0){e=4.1C(j).V(4.J(\'A-1b-1B\'));c[a?\'1u\':\'1T\'](e)}c=e;d=4.T(e);6(p)l+=d;6(4.C!=7&&(4.5.B==\'1c\'||(j>=1&&(4.5.u==7||j<=4.5.u))))b=a?b+d:b-d}8 g=4.1o();8 h=[];8 k=0,j=i,v=0;8 c=4.M(i-1);1q(++k){e=4.M(j);p=!e.K;6(e.K==0){e=4.1C(j).V(4.J(\'A-1b-1B\'));c.K==0?4.t.2y(e):c[a?\'1u\':\'1T\'](e)}c=e;8 d=4.T(e);6(d==0){2Z(\'30: 31 1N/2f 32 1k 33. 34 35 36 37 38 39. 3a...\');z 0}6(4.5.B!=\'1c\'&&4.5.u!==7&&j>4.5.u)h.3b(e);X 6(p)l+=d;v+=d;6(v>=g)1l;j++}1k(8 x=0;x<h.K;x++)h[x].1V();6(l>0){4.t.y(4.O,4.T(4.t)+l+\'U\');6(a){b-=l;4.t.y(4.E,r.I(4.t.y(4.E))-l+\'U\')}}8 n=i+k-1;6(4.5.B!=\'1c\'&&4.5.u&&n>4.5.u)n=4.5.u;6(j>n){k=0,j=n,v=0;1q(++k){8 e=4.M(j--);6(!e.K)1l;v+=4.T(e);6(v>=g)1l}}8 o=n-k+1;6(4.5.B!=\'1c\'&&o<1)o=1;6(4.Z&&a){b+=4.P;4.Z=F}4.P=7;6(4.5.B!=\'1c\'&&n==4.5.u&&(n-k+1)>=1){8 m=r.10(4.M(n),!4.5.W?\'1r\':\'1Y\');6((v-m)>g)4.P=v-g-m}1q(i-->o)b+=4.T(4.M(i));4.Y=4.C;4.12=4.G;4.C=o;4.G=n;z b},1p:9(p,a){6(4.Q||4.1a)z;4.1a=1g;8 b=4;8 c=9(){b.1a=F;6(p==0)b.t.y(b.E,0);6(b.5.B==\'1X\'||b.5.B==\'G\'||b.5.u==7||b.G<b.5.u)b.2z();b.1e();b.1Z(\'2A\')};4.1Z(\'3c\');6(!4.5.1H||a==F){4.t.y(4.E,p+\'U\');c()}X{8 o=!4.5.W?{\'2g\':p}:{\'2h\':p};4.t.1p(o,4.5.1H,4.5.24,c)}},2z:9(s){6(s!=L)4.5.1i=s;6(4.5.1i==0)z 4.1D();6(4.1f!=7)z;8 a=4;4.1f=3d(9(){a.19()},4.5.1i*3e)},1D:9(){6(4.1f==7)z;3f(4.1f);4.1f=7},1e:9(n,p){6(n==L||n==7){8 n=!4.Q&&4.5.u!==0&&((4.5.B&&4.5.B!=\'C\')||4.5.u==7||4.G<4.5.u);6(!4.Q&&(!4.5.B||4.5.B==\'C\')&&4.5.u!=7&&4.G>=4.5.u)n=4.P!=7&&!4.Z}6(p==L||p==7){8 p=!4.Q&&4.5.u!==0&&((4.5.B&&4.5.B!=\'G\')||4.C>1);6(!4.Q&&(!4.5.B||4.5.B==\'G\')&&4.5.u!=7&&4.C==1)p=4.P!=7&&4.Z}8 a=4;4.R[n?\'1y\':\'1R\'](4.5.2c,4.2n)[n?\'1t\':\'V\'](4.J(\'A-19-1E\')).20(\'1E\',n?F:1g);4.S[p?\'1y\':\'1R\'](4.5.2e,4.2o)[p?\'1t\':\'V\'](4.J(\'A-11-1E\')).20(\'1E\',p?F:1g);6(4.R.K>0&&(4.R[0].1h==L||4.R[0].1h!=n)&&4.5.1L!=7){4.R.14(9(){a.5.1L(a,4,n)});4.R[0].1h=n}6(4.S.K>0&&(4.S[0].1h==L||4.S[0].1h!=p)&&4.5.1M!=7){4.S.14(9(){a.5.1M(a,4,p)});4.S[0].1h=p}},1Z:9(a){8 b=4.Y==7?\'2q\':(4.Y<4.C?\'19\':\'11\');4.13(\'25\',a,b);6(4.Y!==4.C){4.13(\'26\',a,b,4.C);4.13(\'27\',a,b,4.Y)}6(4.12!==4.G){4.13(\'28\',a,b,4.G);4.13(\'29\',a,b,4.12)}4.13(\'2a\',a,b,4.C,4.G,4.Y,4.12);4.13(\'2b\',a,b,4.Y,4.12,4.C,4.G)},13:9(a,b,c,d,e,f,g){6(4.5[a]==L||(1U 4.5[a]!=\'2B\'&&b!=\'2A\'))z;8 h=1U 4.5[a]==\'2B\'?4.5[a][b]:4.5[a];6(!$.3g(h))z;8 j=4;6(d===L)h(j,c,b);X 6(e===L)4.M(d).14(9(){h(j,4,d,c,b)});X{1k(8 i=d;i<=e;i++)6(i!==7&&!(i>=f&&i<=g))4.M(i).14(9(){h(j,4,i,c,b)})}},1C:9(i){z 4.1P(\'<1v></1v>\',i)},1P:9(e,i){8 a=$(e).V(4.J(\'A-1b\')).V(4.J(\'A-1b-\'+i));a.20(\'3h\',i);z a},J:9(c){z c+\' \'+c+(!4.5.W?\'-3i\':\'-W\')},T:9(e,d){8 a=e.2C!=L?e[0]:e;8 b=!4.5.W?a.1F+r.10(a,\'2D\')+r.10(a,\'1r\'):a.2E+r.10(a,\'2F\')+r.10(a,\'1Y\');6(d==L||b==d)z b;8 w=!4.5.W?d-r.10(a,\'2D\')-r.10(a,\'1r\'):d-r.10(a,\'2F\')-r.10(a,\'1Y\');$(a).y(4.O,w+\'U\');z 4.T(a)},1o:9(){z!4.5.W?4.H[0].1F-r.I(4.H.y(\'3j\'))-r.I(4.H.y(\'3k\')):4.H[0].2E-r.I(4.H.y(\'3l\'))-r.I(4.H.y(\'3m\'))},3n:9(i,s){6(s==L)s=4.5.u;z 1n.3o((((i-1)/s)-1n.3p((i-1)/s))*s)+1}});r.17({3q:9(d){z $.17(q,d||{})},10:9(e,p){6(!e)z 0;8 a=e.2C!=L?e[0]:e;6(p==\'1r\'&&$.2r.2s){8 b={\'1w\':\'1x\',\'3r\':\'3s\',\'1N\':\'1i\'},21,22;$.2G(a,b,9(){21=a.1F});b[\'1r\']=0;$.2G(a,b,9(){22=a.1F});z 22-21}z r.I($.y(a,p))},I:9(v){v=3t(v);z 3u(v)?0:v}})})(3v);',62,218,'||||this|options|if|null|var|function||||||||||||||||||||list|size||||css|return|jcarousel|wrap|first|container|lt|false|last|clip|intval|className|length|undefined|get|div|wh|tail|locked|buttonNext|buttonPrev|dimension|px|addClass|vertical|else|prevFirst|inTail|margin|prev|prevLast|callback|each|scroll|visible|extend|parent|next|animating|item|circular|split|buttons|timer|true|jcarouselstate|auto|initCallback|for|break|hasClass|Math|clipping|animate|while|marginRight|fn|removeClass|before|li|display|block|bind|setup|pos|placeholder|create|stopAuto|disabled|offsetWidth|offset|animation|reloadCallback|buttonNextHTML|buttonPrevHTML|buttonNextCallback|buttonPrevCallback|width|ceil|format|funcResize|unbind|old|after|typeof|remove|scrollTail|both|marginBottom|notify|attr|oWidth|oWidth2|start|easing|itemLoadCallback|itemFirstInCallback|itemFirstOutCallback|itemLastInCallback|itemLastOutCallback|itemVisibleInCallback|itemVisibleOutCallback|buttonNextEvent|click|buttonPrevEvent|height|left|top|indexOf|skin|nodeName|ul|ol|funcNext|funcPrev|reload|init|browser|safari|window|resize|reset|empty|add|prepend|startAuto|onAfterAnimation|object|jquery|marginLeft|offsetHeight|marginTop|swap|new|normal|swing|UL|OL|find|class|children|load|prototype|0px|10px|lock|unlock|has|string|html|append|alert|jCarousel|No|set|items|This|will|cause|an|infinite|loop|Aborting|push|onBeforeAnimation|setTimeout|1000|clearTimeout|isFunction|jcarouselindex|horizontal|borderLeftWidth|borderRightWidth|borderTopWidth|borderBottomWidth|index|round|floor|defaults|float|none|parseInt|isNaN|jQuery'.split('|'),0,{}))

function mycarousel_initCallback(A){jQuery(".jcarousel-control a").bind("click",function(){A.scroll(jQuery.jcarousel.intval(jQuery(this).text()));return false});jQuery(".jcarousel-scroll select").bind("change",function(){A.options.scroll=jQuery.jcarousel.intval(this.options[this.selectedIndex].value);return false});jQuery("#mycarousel-next").bind("click",function(){A.next();return false});jQuery("#mycarousel-prev").bind("click",function(){A.prev();return false})}jQuery(document).ready(function(){jQuery("#mycarousel").jcarousel({scroll:1,initCallback:mycarousel_initCallback,buttonNextHTML:"<div></div>",buttonPrevHTML:"<div></div>",visible:3})});
/*
 * jQuery UI 1.7.1
 *
 * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
 * Dual licensed under the MIT (MIT-LICENSE.txt)
 * and GPL (GPL-LICENSE.txt) licenses.
 *
 * http://docs.jquery.com/UI
 */
;jQuery.ui || (function($) {

var _remove = $.fn.remove,
	isFF2 = $.browser.mozilla && (parseFloat($.browser.version) < 1.9);

//Helper functions and ui object
$.ui = {
	version: "1.7.1",

	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
	plugin: {
		add: function(module, option, set) {
			var proto = $.ui[module].prototype;
			for(var i in set) {
				proto.plugins[i] = proto.plugins[i] || [];
				proto.plugins[i].push([option, set[i]]);
			}
		},
		call: function(instance, name, args) {
			var set = instance.plugins[name];
			if(!set || !instance.element[0].parentNode) { return; }

			for (var i = 0; i < set.length; i++) {
				if (instance.options[set[i][0]]) {
					set[i][1].apply(instance.element, args);
				}
			}
		}
	},

	contains: function(a, b) {
		return document.compareDocumentPosition
			? a.compareDocumentPosition(b) & 16
			: a !== b && a.contains(b);
	},

	hasScroll: function(el, a) {

		//If overflow is hidden, the element might have extra content, but the user wants to hide it
		if ($(el).css('overflow') == 'hidden') { return false; }

		var scroll = (a && a == 'left') ? 'scrollLeft' : 'scrollTop',
			has = false;

		if (el[scroll] > 0) { return true; }

		// : determine which cases actually cause this to happen
		// if the element doesn't have the scroll set, see if it's possible to
		// set the scroll
		el[scroll] = 1;
		has = (el[scroll] > 0);
		el[scroll] = 0;
		return has;
	},

	isOverAxis: function(x, reference, size) {
		//Determines when x coordinate is over "b" element axis
		return (x > reference) && (x < (reference + size));
	},

	isOver: function(y, x, top, left, height, width) {
		//Determines when x, y coordinates is over "b" element
		return $.ui.isOverAxis(y, top, height) && $.ui.isOverAxis(x, left, width);
	},

	keyCode: {
		BACKSPACE: 8,
		CAPS_LOCK: 20,
		COMMA: 188,
		CONTROL: 17,
		DELETE: 46,
		DOWN: 40,
		END: 35,
		ENTER: 13,
		ESCAPE: 27,
		HOME: 36,
		INSERT: 45,
		LEFT: 37,
		NUMPAD_ADD: 107,
		NUMPAD_DECIMAL: 110,
		NUMPAD_DIVIDE: 111,
		NUMPAD_ENTER: 108,
		NUMPAD_MULTIPLY: 106,
		NUMPAD_SUBTRACT: 109,
		PAGE_DOWN: 34,
		PAGE_UP: 33,
		PERIOD: 190,
		RIGHT: 39,
		SHIFT: 16,
		SPACE: 32,
		TAB: 9,
		UP: 38
	}
};

// WAI-ARIA normalization
if (isFF2) {
	var attr = $.attr,
		removeAttr = $.fn.removeAttr,
		ariaNS = "http://www.w3.org/2005/07/aaa",
		ariaState = /^aria-/,
		ariaRole = /^wairole:/;

	$.attr = function(elem, name, value) {
		var set = value !== undefined;

		return (name == 'role'
			? (set
				? attr.call(this, elem, name, "wairole:" + value)
				: (attr.apply(this, arguments) || "").replace(ariaRole, ""))
			: (ariaState.test(name)
				? (set
					? elem.setAttributeNS(ariaNS,
						name.replace(ariaState, "aaa:"), value)
					: attr.call(this, elem, name.replace(ariaState, "aaa:")))
				: attr.apply(this, arguments)));
	};

	$.fn.removeAttr = function(name) {
		return (ariaState.test(name)
			? this.each(function() {
				this.removeAttributeNS(ariaNS, name.replace(ariaState, ""));
			}) : removeAttr.call(this, name));
	};
}

//jQuery plugins
$.fn.extend({
	remove: function() {
		// Safari has a native remove event which actually removes DOM elements,
		// so we have to use triggerHandler instead of trigger (#3037).
		$("*", this).add(this).each(function() {
			$(this).triggerHandler("remove");
		});
		return _remove.apply(this, arguments );
	},

	enableSelection: function() {
		return this
			.attr('unselectable', 'off')
			.css('MozUserSelect', '')
			.unbind('selectstart.ui');
	},

	disableSelection: function() {
		return this
			.attr('unselectable', 'on')
			.css('MozUserSelect', 'none')
			.bind('selectstart.ui', function() { return false; });
	},

	scrollParent: function() {
		var scrollParent;
		if(($.browser.msie && (/(static|relative)/).test(this.css('position'))) || (/absolute/).test(this.css('position'))) {
			scrollParent = this.parents().filter(function() {
				return (/(relative|absolute|fixed)/).test($.curCSS(this,'position',1)) && (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
			}).eq(0);
		} else {
			scrollParent = this.parents().filter(function() {
				return (/(auto|scroll)/).test($.curCSS(this,'overflow',1)+$.curCSS(this,'overflow-y',1)+$.curCSS(this,'overflow-x',1));
			}).eq(0);
		}

		return (/fixed/).test(this.css('position')) || !scrollParent.length ? $(document) : scrollParent;
	}
});


//Additional selectors
$.extend($.expr[':'], {
	data: function(elem, i, match) {
		return !!$.data(elem, match[3]);
	},

	focusable: function(element) {
		var nodeName = element.nodeName.toLowerCase(),
			tabIndex = $.attr(element, 'tabindex');
		return (/input|select|textarea|button|object/.test(nodeName)
			? !element.disabled
			: 'a' == nodeName || 'area' == nodeName
				? element.href || !isNaN(tabIndex)
				: !isNaN(tabIndex))
			// the element and all of its ancestors must be visible
			// the browser may report that the area is hidden
			&& !$(element)['area' == nodeName ? 'parents' : 'closest'](':hidden').length;
	},

	tabbable: function(element) {
		var tabIndex = $.attr(element, 'tabindex');
		return (isNaN(tabIndex) || tabIndex >= 0) && $(element).is(':focusable');
	}
});


// $.widget is a factory to create jQuery plugins
// taking some boilerplate code out of the plugin code
function getter(namespace, plugin, method, args) {
	function getMethods(type) {
		var methods = $[namespace][plugin][type] || [];
		return (typeof methods == 'string' ? methods.split(/,?\s+/) : methods);
	}

	var methods = getMethods('getter');
	if (args.length == 1 && typeof args[0] == 'string') {
		methods = methods.concat(getMethods('getterSetter'));
	}
	return ($.inArray(method, methods) != -1);
}

$.widget = function(name, prototype) {
	var namespace = name.split(".")[0];
	name = name.split(".")[1];

	// create plugin method
	$.fn[name] = function(options) {
		var isMethodCall = (typeof options == 'string'),
			args = Array.prototype.slice.call(arguments, 1);

		// prevent calls to internal methods
		if (isMethodCall && options.substring(0, 1) == '_') {
			return this;
		}

		// handle getter methods
		if (isMethodCall && getter(namespace, name, options, args)) {
			var instance = $.data(this[0], name);
			return (instance ? instance[options].apply(instance, args)
				: undefined);
		}

		// handle initialization and non-getter methods
		return this.each(function() {
			var instance = $.data(this, name);

			// constructor
			(!instance && !isMethodCall &&
				$.data(this, name, new $[namespace][name](this, options))._init());

			// method call
			(instance && isMethodCall && $.isFunction(instance[options]) &&
				instance[options].apply(instance, args));
		});
	};

	// create widget constructor
	$[namespace] = $[namespace] || {};
	$[namespace][name] = function(element, options) {
		var self = this;

		this.namespace = namespace;
		this.widgetName = name;
		this.widgetEventPrefix = $[namespace][name].eventPrefix || name;
		this.widgetBaseClass = namespace + '-' + name;

		this.options = $.extend({},
			$.widget.defaults,
			$[namespace][name].defaults,
			$.metadata && $.metadata.get(element)[name],
			options);

		this.element = $(element)
			.bind('setData.' + name, function(event, key, value) {
				if (event.target == element) {
					return self._setData(key, value);
				}
			})
			.bind('getData.' + name, function(event, key) {
				if (event.target == element) {
					return self._getData(key);
				}
			})
			.bind('remove', function() {
				return self.destroy();
			});
	};

	// add widget prototype
	$[namespace][name].prototype = $.extend({}, $.widget.prototype, prototype);

	// : merge getter and getterSetter properties from widget prototype
	// and plugin prototype
	$[namespace][name].getterSetter = 'option';
};

$.widget.prototype = {
	_init: function() {},
	destroy: function() {
		this.element.removeData(this.widgetName)
			.removeClass(this.widgetBaseClass + '-disabled' + ' ' + this.namespace + '-state-disabled')
			.removeAttr('aria-disabled');
	},

	option: function(key, value) {
		var options = key,
			self = this;

		if (typeof key == "string") {
			if (value === undefined) {
				return this._getData(key);
			}
			options = {};
			options[key] = value;
		}

		$.each(options, function(key, value) {
			self._setData(key, value);
		});
	},
	_getData: function(key) {
		return this.options[key];
	},
	_setData: function(key, value) {
		this.options[key] = value;

		if (key == 'disabled') {
			this.element
				[value ? 'addClass' : 'removeClass'](
					this.widgetBaseClass + '-disabled' + ' ' +
					this.namespace + '-state-disabled')
				.attr("aria-disabled", value);
		}
	},

	enable: function() {
		this._setData('disabled', false);
	},
	disable: function() {
		this._setData('disabled', true);
	},

	_trigger: function(type, event, data) {
		var callback = this.options[type],
			eventName = (type == this.widgetEventPrefix
				? type : this.widgetEventPrefix + type);

		event = $.Event(event);
		event.type = eventName;

		// copy original event properties over to the new event
		// this would happen if we could call $.event.fix instead of $.Event
		// but we don't have a way to force an event to be fixed multiple times
		if (event.originalEvent) {
			for (var i = $.event.props.length, prop; i;) {
				prop = $.event.props[--i];
				event[prop] = event.originalEvent[prop];
			}
		}

		this.element.trigger(event, data);

		return !($.isFunction(callback) && callback.call(this.element[0], event, data) === false
			|| event.isDefaultPrevented());
	}
};

$.widget.defaults = {
	disabled: false
};


/** Mouse Interaction Plugin **/

$.ui.mouse = {
	_mouseInit: function() {
		var self = this;

		this.element
			.bind('mousedown.'+this.widgetName, function(event) {
				return self._mouseDown(event);
			})
			.bind('click.'+this.widgetName, function(event) {
				if(self._preventClickEvent) {
					self._preventClickEvent = false;
					event.stopImmediatePropagation();
					return false;
				}
			});

		// Prevent text selection in IE
		if ($.browser.msie) {
			this._mouseUnselectable = this.element.attr('unselectable');
			this.element.attr('unselectable', 'on');
		}

		this.started = false;
	},

	// : make sure destroying one instance of mouse doesn't mess with
	// other instances of mouse
	_mouseDestroy: function() {
		this.element.unbind('.'+this.widgetName);

		// Restore text selection in IE
		($.browser.msie
			&& this.element.attr('unselectable', this._mouseUnselectable));
	},

	_mouseDown: function(event) {
		// don't let more than one widget handle mouseStart
		// : figure out why we have to use originalEvent
		event.originalEvent = event.originalEvent || {};
		if (event.originalEvent.mouseHandled) { return; }

		// we may have missed mouseup (out of window)
		(this._mouseStarted && this._mouseUp(event));

		this._mouseDownEvent = event;

		var self = this,
			btnIsLeft = (event.which == 1),
			elIsCancel = (typeof this.options.cancel == "string" ? $(event.target).parents().add(event.target).filter(this.options.cancel).length : false);
		if (!btnIsLeft || elIsCancel || !this._mouseCapture(event)) {
			return true;
		}

		this.mouseDelayMet = !this.options.delay;
		if (!this.mouseDelayMet) {
			this._mouseDelayTimer = setTimeout(function() {
				self.mouseDelayMet = true;
			}, this.options.delay);
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted = (this._mouseStart(event) !== false);
			if (!this._mouseStarted) {
				event.preventDefault();
				return true;
			}
		}

		// these delegates are required to keep context
		this._mouseMoveDelegate = function(event) {
			return self._mouseMove(event);
		};
		this._mouseUpDelegate = function(event) {
			return self._mouseUp(event);
		};
		$(document)
			.bind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.bind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		// preventDefault() is used to prevent the selection of text here -
		// however, in Safari, this causes select boxes not to be selectable
		// anymore, so this fix is needed
		($.browser.safari || event.preventDefault());

		event.originalEvent.mouseHandled = true;
		return true;
	},

	_mouseMove: function(event) {
		// IE mouseup check - mouseup happened when mouse was out of window
		if ($.browser.msie && !event.button) {
			return this._mouseUp(event);
		}

		if (this._mouseStarted) {
			this._mouseDrag(event);
			return event.preventDefault();
		}

		if (this._mouseDistanceMet(event) && this._mouseDelayMet(event)) {
			this._mouseStarted =
				(this._mouseStart(this._mouseDownEvent, event) !== false);
			(this._mouseStarted ? this._mouseDrag(event) : this._mouseUp(event));
		}

		return !this._mouseStarted;
	},

	_mouseUp: function(event) {
		$(document)
			.unbind('mousemove.'+this.widgetName, this._mouseMoveDelegate)
			.unbind('mouseup.'+this.widgetName, this._mouseUpDelegate);

		if (this._mouseStarted) {
			this._mouseStarted = false;
			this._preventClickEvent = (event.target == this._mouseDownEvent.target);
			this._mouseStop(event);
		}

		return false;
	},

	_mouseDistanceMet: function(event) {
		return (Math.max(
				Math.abs(this._mouseDownEvent.pageX - event.pageX),
				Math.abs(this._mouseDownEvent.pageY - event.pageY)
			) >= this.options.distance
		);
	},

	_mouseDelayMet: function(event) {
		return this.mouseDelayMet;
	},

	// These are placeholder methods, to be overriden by extending plugin
	_mouseStart: function(event) {},
	_mouseDrag: function(event) {},
	_mouseStop: function(event) {},
	_mouseCapture: function(event) { return true; }
};

$.ui.mouse.defaults = {
	cancel: null,
	distance: 1,
	delay: 0
};

})(jQuery);

/**
 * Cookie plugin
 *
 * Copyright (c) 2006 Klaus Hartl (stilbuero.de)
 * Dual licensed under the MIT and GPL licenses:
 * http://www.opensource.org/licenses/mit-license.php
 * http://www.gnu.org/licenses/gpl.html
 *
 */

/**
 * Create a cookie with the given name and value and other optional parameters.
 *
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Set the value of a cookie.
 * @example $.cookie('the_cookie', 'the_value', { expires: 7, path: '/', domain: 'jquery.com', secure: true });
 * @desc Create a cookie with all available options.
 * @example $.cookie('the_cookie', 'the_value');
 * @desc Create a session cookie.
 * @example $.cookie('the_cookie', null);
 * @desc Delete a cookie by passing null as value. Keep in mind that you have to use the same path and domain
 *       used when the cookie was set.
 *
 * @param String name The name of the cookie.
 * @param String value The value of the cookie.
 * @param Object options An object literal containing key/value pairs to provide optional cookie attributes.
 * @option Number|Date expires Either an integer specifying the expiration date from now on in days or a Date object.
 *                             If a negative value is specified (e.g. a date in the past), the cookie will be deleted.
 *                             If set to null or omitted, the cookie will be a session cookie and will not be retained
 *                             when the the browser exits.
 * @option String path The value of the path atribute of the cookie (default: path of page that created the cookie).
 * @option String domain The value of the domain attribute of the cookie (default: domain of page that created the cookie).
 * @option Boolean secure If true, the secure attribute of the cookie will be set and the cookie transmission will
 *                        require a secure protocol (like HTTPS).
 * @type undefined
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */

/**
 * Get the value of a cookie with the given name.
 *
 * @example $.cookie('the_cookie');
 * @desc Get the value of a cookie.
 *
 * @param String name The name of the cookie.
 * @return The value of the cookie.
 * @type String
 *
 * @name $.cookie
 * @cat Plugins/Cookie
 * @author Klaus Hartl/klaus.hartl@stilbuero.de
 */
jQuery.cookie = function(name, value, options) {
    if (typeof value != 'undefined') { // name and value given, set cookie
        options = options || {};
        if (value === null) {
            value = '';
            options = $.extend({}, options); // clone object since it's unexpected behavior if the expired property were changed
            options.expires = -1;
        }
        var expires = '';
        if (options.expires && (typeof options.expires == 'number' || options.expires.toUTCString)) {
            var date;
            if (typeof options.expires == 'number') {
                date = new Date();
                date.setTime(date.getTime() + (options.expires * 24 * 60 * 60 * 1000));
            } else {
                date = options.expires;
            }
            expires = '; expires=' + date.toUTCString(); // use expires attribute, max-age is not supported by IE
        }
        // NOTE Needed to parenthesize options.path and options.domain
        // in the following expressions, otherwise they evaluate to undefined
        // in the packed version for some reason...
        var path = options.path ? '; path=' + (options.path) : '';
        var domain = options.domain ? '; domain=' + (options.domain) : '';
        var secure = options.secure ? '; secure' : '';
        document.cookie = [name, '=', encodeURIComponent(value), expires, path, domain, secure].join('');
    } else { // only name given, get cookie
        var cookieValue = null;
        if (document.cookie && document.cookie != '') {
            var cookies = document.cookie.split(';');
            for (var i = 0; i < cookies.length; i++) {
                var cookie = jQuery.trim(cookies[i]);
                // Does this cookie string begin with the name we want?
                if (cookie.substring(0, name.length + 1) == (name + '=')) {
                    cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                    break;
                }
            }
        }
        return cookieValue;
    }
};
/*************************************************************************
	jquery.dynatree.js
	Dynamic tree view control, with support for lazy loading of branches.

	Copyright (c) 2008-2009  Martin Wendt (http://wwWendt.de)
	Licensed under the MIT License (MIT-License.txt)

	A current version and some documentation is available at
		http://dynatree.googlecode.com/

	Let me know, if you find bugs or improvements (martin at domain wwWendt.de).

	$Version: 0.5.2$
	$Revision: 296, 2009-12-20 11:04:25$

 	@depends: jquery.js
 	@depends: ui.core.js
    @depends: jquery.cookie.js
*************************************************************************/


/*************************************************************************
 *	Debug functions
 */

var _canLog = true;

function _log(mode, msg) {
	/**
	 * Usage: logMsg("%o was toggled", this);
	 */
	if( !_canLog ) 
		return;
	// Remove first argument
	var args = Array.prototype.slice.apply(arguments, [1]); 
	// Prepend timestamp
	var dt = new Date();
	var tag = dt.getHours()+":"+dt.getMinutes()+":"+dt.getSeconds()+"."+dt.getMilliseconds();
	args[0] = tag + " - " + args[0];

	try {
		switch( mode ) {
		case "info":
			window.console.info.apply(window.console, args);
			break;
		case "warn":
			window.console.warn.apply(window.console, args);
			break;
		default:
			window.console.log.apply(window.console, args);
		}
	} catch(e) {
		if( !window.console )
			_canLog = false; // Permanently disable, when logging is not supported by the browser 
	}
}

function logMsg(msg) {
	Array.prototype.unshift.apply(arguments, ["debug"]);
	_log.apply(this, arguments);
}


// Forward declaration
var getDynaTreePersistData = undefined;



/*************************************************************************
 *	Constants
 */
var DTNodeStatus_Error   = -1;
var DTNodeStatus_Loading = 1;
var DTNodeStatus_Ok      = 0;


// Start of local namespace
;(function($) {

/*************************************************************************
 *	Common tool functions.
 */

var Class = {
	create: function() {
		return function() {
			this.initialize.apply(this, arguments);
		}
	}
}

/*************************************************************************
 *	Class DynaTreeNode
 */
var DynaTreeNode = Class.create();

DynaTreeNode.prototype = {
	initialize: function(parent, tree, data) {
		/**
		 * @constructor 
		 */
		this.parent = parent; 
		this.tree = tree;
		if ( typeof data == "string" ) 
			data = { title: data };
		if( data.key == undefined )
			data.key = "_" + tree._nodeCount++;
		this.data = $.extend({}, $.ui.dynatree.nodedatadefaults, data);
		this.div = null; // not yet created
		this.span = null; // not yet created
		this.childList = null; // no subnodes yet
//		this.isRead = false; // Lazy content not yet read
		this.isLoading = false; // Lazy content is being loaded
		this.hasSubSel = false;
	},

	toString: function() {
		return "dtnode<" + this.data.key + ">: '" + this.data.title + "'";
	},

	toDict: function(recursive, callback) {
		var dict = $.extend({}, this.data);
		dict.activate = ( this.tree.activeNode === this );
		dict.focus = ( this.tree.focusNode === this );
		dict.expand = this.bExpanded;
		dict.select = this.bSelected;
		if( callback )
			callback(dict);
		if( recursive && this.childList ) {
			dict.children = [];
			for(var i=0; i<this.childList.length; i++ )
				dict.children.push(this.childList[i].toDict(true, callback));
		} else {
			delete dict.children;
		}
		return dict;
	},

	_getInnerHtml: function() {
		var opts = this.tree.options;
		var cache = this.tree.cache;
		// parent connectors
		var rootParent = opts.rootVisible ? null : this.tree.tnRoot; 
		var bHideFirstExpander = (opts.rootVisible && opts.minExpandLevel>0) || opts.minExpandLevel>1;
		var bHideFirstConnector = opts.rootVisible || opts.minExpandLevel>0;

		var res = "";
		var p = this.parent;
		while( p ) {
			// Suppress first connector column, if visible top level is always expanded
			if ( bHideFirstConnector && p==rootParent  )
				break;
			res = ( p.isLastSibling() ? cache.tagEmpty : cache.tagVline) + res;
			p = p.parent;
		}

		// connector (expanded, expandable or simple)
		if( bHideFirstExpander && this.parent==rootParent ) {
			// skip connector
		} else if ( this.childList || this.data.isLazy ) {
   			res += cache.tagExpander;
		} else {
   			res += cache.tagConnector;
		}
		
		// Checkbox mode
		if( opts.checkbox && this.data.hideCheckbox!=true && !this.data.isStatusNode ) {
   			res += cache.tagCheckbox;
		}
		
		// folder or doctype icon
//   		if ( this.data.icon ) {
//    		res += "<img src='" + opts.imagePath + this.data.icon + "' alt='' />";
//   		} else if ( this.data.icon == false ) {
//        	// icon == false means 'no icon'
//		} else {
//        	// icon == null means 'default icon'
//   			res += cache.tagNodeIcon;
//		}

		// node name
	//	var tooltip = ( this.data && typeof this.data.tooltip == "string" ) ? " title='" + this.data.tooltip + "'" : "";
	//	res +=  "<a href='#' class='" + opts.classNames.title + "'" + tooltip + ">" + this.data.title + "</a>";
		res +=  this.data.title;
		return res;
	},

	_fixOrder: function() {
		/**
		 * Make sure, that <div> order matches childList order.
		 */
		var cl = this.childList; 
		if( !cl )
			return;
		var childDiv = this.div.firstChild.nextSibling;
		for(var i=0; i<cl.length-1; i++) {
			var childNode1 = cl[i]; 
			var childNode2 = childDiv.firstChild.dtnode;
			if( childNode1 !== childNode2 ) {
//
				this.tree.logDebug("_fixOrder: mismatch at index " + i + ": " + childNode1 + " != " + childNode2);
				this.div.insertBefore(childNode1.div, childNode2.div);
			} else {
				childDiv = childDiv.nextSibling;
			}
		}
	},
	
	render: function(bDeep, bHidden) {
		/**
		 * Create HTML markup for this node.
		 * 
		 * <div> // This div contains the node's span and list of child div's.
		 *   <span id='key'>S S S A</span> // Span contains graphic spans and title <a> tag 
		 *   <div>child1</div>
		 *   <div>child2</div>
		 * </div>
		 */
//		this.tree.logDebug("%o.render()", this);
		var opts = this.tree.options;
		var cn = opts.classNames;
		var isLastSib = this.isLastSibling();
		// --- 
		if( ! this.div ) {
			this.span = document.createElement("span");
			this.span.dtnode = this;
			if( this.data.key )
				this.span.id = this.tree.options.idPrefix + this.data.key;
			this.div  = document.createElement("div");
			this.div.appendChild(this.span);
			
			if ( this.parent ) {
				this.parent.div.appendChild(this.div);
			}

			if( this.parent==null && !this.tree.options.rootVisible )
				this.span.style.display = "none";
		}
		// set node connector images, links and text
		this.span.innerHTML = this._getInnerHtml();

		// hide this node, if parent is collapsed
		this.div.style.display = ( this.parent==null || this.parent.bExpanded ? "" : "none");

		// Set classes for current status
		var cnList = [];
		cnList.push( ( this.data.isFolder ) ? cn.folder : cn.document );
		if( this.bExpanded )
			cnList.push(cn.expanded);
		if( this.childList != null )
			cnList.push(cn.hasChildren);
		if( this.data.isLazy && this.childList==null )
			cnList.push(cn.lazy);
		if( isLastSib )
			cnList.push(cn.lastsib);
		if( this.bSelected )
			cnList.push(cn.selected);
		if( this.hasSubSel )
			cnList.push(cn.partsel);
		if( this.tree.activeNode === this )
			cnList.push(cn.active);
		if( this.data.addClass )
			cnList.push(this.data.addClass);
		// IE6 doesn't correctly evaluate multiple class names,
		// so we create combined class names that can be used in the CSS
		cnList.push(cn.combinedExpanderPrefix
				+ (this.bExpanded ? "e" : "c")
				+ (this.data.isLazy && this.childList==null ? "d" : "")
				+ (isLastSib ? "l" : "")
				);
		cnList.push(cn.combinedIconPrefix
				+ (this.bExpanded ? "e" : "c")
				+ (this.data.isFolder ? "f" : "")
				);
		this.span.className = cnList.join(" ");

		if( bDeep && this.childList && (bHidden || this.bExpanded) ) {
			for(var i=0; i<this.childList.length; i++) {
				this.childList[i].render(bDeep, bHidden)
			}
			this._fixOrder();
		}
	},

	hasChildren: function() {
		return this.childList != null;
	},

	isLastSibling: function() {
		var p = this.parent;
		if ( !p ) return true;
		return p.childList[p.childList.length-1] === this;
	},

	prevSibling: function() {
		if( !this.parent ) return null;
		var ac = this.parent.childList;
		for(var i=1; i<ac.length; i++) // start with 1, so prev(first) = null
			if( ac[i] === this )
				return ac[i-1];
		return null;
	},

	nextSibling: function() {
		if( !this.parent ) return null;
		var ac = this.parent.childList;
		for(var i=0; i<ac.length-1; i++) // up to length-2, so next(last) = null
			if( ac[i] === this )
				return ac[i+1];
		return null;
	},

	_setStatusNode: function(data) {
		// Create, modify or remove the status child node (pass 'null', to remove it).
		var firstChild = ( this.childList ? this.childList[0] : null );
		if( !data ) {
			if ( firstChild ) {
				this.div.removeChild(firstChild.div);
				if( this.childList.length == 1 )
					this.childList = null;
				else
					this.childList.shift();
			}
		} else if ( firstChild ) {
			data.isStatusNode = true;
			firstChild.data = data;
			firstChild.render(false, false);
		} else {
			data.isStatusNode = true;
			firstChild = this.addChild(data);
		}
	},

	setLazyNodeStatus: function(lts) {
		switch( lts ) {
			case DTNodeStatus_Ok:
				this._setStatusNode(null);
//				this.isRead = true;
				this.isLoading = false;
				this.render(false, false);
				if( this.tree.options.autoFocus ) {
					if( this === this.tree.tnRoot && !this.tree.options.rootVisible && this.childList ) {
						// special case: using ajaxInit
						this.childList[0].focus();
					} else {
						this.focus();
					}
				}
				break;
			case DTNodeStatus_Loading:
				this.isLoading = true;
				this._setStatusNode({
					title: this.tree.options.strings.loading,
					addClass: this.tree.options.classNames.nodeWait
				});
				break;
			case DTNodeStatus_Error:
				this.isLoading = false;
				this._setStatusNode({
					title: this.tree.options.strings.loadError,
					addClass: this.tree.options.classNames.nodeError
				});
				break;
			default:
				throw "Bad LazyNodeStatus: '" + lts + "'.";
		}
	},

	_parentList: function(includeRoot, includeSelf) {
		var l = [];
		var dtn = includeSelf ? this : this.parent;
		while( dtn ) {
			if( includeRoot || dtn.parent )
				l.unshift(dtn);
			dtn = dtn.parent;
		};
		return l;
	},

	getLevel: function() {
		var level = 0;
		var dtn = this.parent;
		while( dtn ) {
			level++;
			dtn = dtn.parent;
		};
		return level;
	},

	_getTypeForOuterNodeEvent: function(event) {
		/** Return the inner node span (title, checkbox or expander) if 
		 *  event.target points to the outer span.
		 *  This function should fix issue #93: 
		 *  FF2 ignores empty spans, when generating events (returning the parent instead).
		 */ 
		var cns = this.tree.options.classNames;
	    var target = event.target;
	    // Only process clicks on an outer node span (probably due to a FF2 event handling bug)
	    if( target.className.indexOf(cns.folder)<0 
	    	&& target.className.indexOf(cns.document)<0 ) {
	        return null
	    }
	    // Event coordinates, relative to outer node span:
	    var eventX = event.pageX - target.offsetLeft;
	    var eventY = event.pageY - target.offsetTop;
	    
	    for(var i=0; i<target.childNodes.length; i++) {
	        var cn = target.childNodes[i];
	        var x = cn.offsetLeft - target.offsetLeft;
	        var y = cn.offsetTop - target.offsetTop;
	        var nx = cn.clientWidth, ny = cn.clientHeight;
//	        alert (cn.className + ": " + x + ", " + y + ", s:" + nx + ", " + ny);
	        if( eventX>=x && eventX<=(x+nx) && eventY>=y && eventY<=(y+ny) ) {
//	            alert("HIT "+ cn.className);
	            if( cn.className==cns.title ) 
	            	return "title";
	            else if( cn.className==cns.expander ) 
	            	return "expander";
	            else if( cn.className==cns.checkbox ) 
	            	return "checkbox";
	            else if( cn.className==cns.nodeIcon ) 
	            	return "icon";
	        }
	    }
	    return "prefix";
	},

	getEventTargetType: function(event) {
		// Return the part of a node, that a click event occured on.
		// Note: there is no check, if the was fired on TIHS node. 
		var tcn = event && event.target ? event.target.className : "";
		var cns = this.tree.options.classNames;

		if( tcn == cns.title )
			return "title";
		else if( tcn==cns.expander )
			return "expander";
		else if( tcn==cns.checkbox )
			return "checkbox";
		else if( tcn==cns.nodeIcon )
			return "icon";
		else if( tcn==cns.empty || tcn==cns.vline || tcn==cns.connector )
			return "prefix";
		else if( tcn.indexOf(cns.folder)>=0 || tcn.indexOf(cns.document)>=0 )
			// FIX issue #93
			return this._getTypeForOuterNodeEvent(event);
		return null;
	},

	isVisible: function() {
		// Return true, if all parents are expanded.
		var parents = this._parentList(true, false);
		for(var i=0; i<parents.length; i++)
			if( ! parents[i].bExpanded ) return false;
		return true;
	},

	makeVisible: function() {
		// Make sure, all parents are expanded
		var parents = this._parentList(true, false);
		for(var i=0; i<parents.length; i++)
			parents[i]._expand(true);
	},

	focus: function() {
		// : check, if we already have focus
//		this.tree.logDebug("dtnode.focus(): %o", this);
		this.makeVisible();
		try {
			$(this.span).find(">a").focus();
		} catch(e) { }
	},

	_activate: function(flag, fireEvents) {
		// (De)Activate - but not focus - this node.
		this.tree.logDebug("dtnode._activate(%o, fireEvents=%o) - %o", flag, fireEvents, this);
		var opts = this.tree.options;
		if( this.data.isStatusNode )
			return;
		if ( fireEvents && opts.onQueryActivate && opts.onQueryActivate.call(this.span, flag, this) == false )
			return; // Callback returned false
		
		if( flag ) {
			// Activate
			if( this.tree.activeNode ) {
				if( this.tree.activeNode === this )
					return;
				this.tree.activeNode.deactivate();
			}
			if( opts.activeVisible )
				this.makeVisible();
			this.tree.activeNode = this;
	        if( opts.persist )
				$.cookie(opts.cookieId+"-active", this.data.key, opts.cookie);
	        this.tree.persistence.activeKey = this.data.key;
			$(this.span).addClass(opts.classNames.active);
			if ( fireEvents && opts.onActivate ) // Pass element as 'this' (jQuery convention)
				opts.onActivate.call(this.span, this);
		} else {
			// Deactivate
			if( this.tree.activeNode === this ) {
				var opts = this.tree.options;
				if ( opts.onQueryActivate && opts.onQueryActivate.call(this.span, false, this) == false )
					return; // Callback returned false
				$(this.span).removeClass(opts.classNames.active);
		        if( opts.persist ) {
		        	// Note: we don't pass null, but ''. So the cookie is not deleted.
		        	// If we pass null, we also have to pass a COPY of opts, because $cookie will override opts.expires (issue 84)
					$.cookie(opts.cookieId+"-active", "", opts.cookie);
		        }
		        this.tree.persistence.activeKey = null;
				this.tree.activeNode = null;
				if ( fireEvents && opts.onDeactivate )
					opts.onDeactivate.call(this.span, this);
			}
		}
	},

	activate: function() {
		// Select - but not focus - this node.
//		this.tree.logDebug("dtnode.activate(): %o", this);
		this._activate(true, true);
	},

	deactivate: function() {
//		this.tree.logDebug("dtnode.deactivate(): %o", this);
		this._activate(false, true);
	},

	isActive: function() {
		return (this.tree.activeNode === this);
	},
	
	_userActivate: function() {
		// Handle user click / [space] / [enter], according to clickFolderMode.
		var activate = true;
		var expand = false;
		if ( this.data.isFolder ) {
			switch( this.tree.options.clickFolderMode ) {
			case 2:
				activate = false;
				expand = true;
				break;
			case 3:
				activate = expand = true;
				break;
			}
		}
		if( this.parent == null && this.tree.options.minExpandLevel>0 ) {
			expand = false;
		}
		if( expand ) {
			this.toggleExpand();
			this.focus();
		} 
		if( activate ) {
			this.activate();
		}
	},

	_setSubSel: function(hasSubSel) {
		if( hasSubSel ) {
			this.hasSubSel = true;
			$(this.span).addClass(this.tree.options.classNames.partsel);
		} else {
			this.hasSubSel = false;
			$(this.span).removeClass(this.tree.options.classNames.partsel);
		}
	},

	_fixSelectionState: function() {
		// fix selection status, for multi-hier mode 
//		this.tree.logDebug("_fixSelectionState(%o) - %o", this.bSelected, this);
		if( this.bSelected ) {
			// Select all children
			this.visit(function(dtnode){
				dtnode.parent._setSubSel(true);
				dtnode._select(true, false, false);
			});
			// Select parents, if all children are selected
			var p = this.parent;
			while( p ) {
				p._setSubSel(true);
				var allChildsSelected = true;
				for(var i=0; i<p.childList.length;  i++) {
					var n = p.childList[i]; 
					if( !n.bSelected && !n.data.isStatusNode ) {
						allChildsSelected = false;
						break;
					}
				}
				if( allChildsSelected )
					p._select(true, false, false);
				p = p.parent;
			}
		} else {
			// Deselect all children
			this._setSubSel(false);
			this.visit(function(dtnode){
				dtnode._setSubSel(false);
				dtnode._select(false, false, false);
			});
			// Deselect parents, and recalc hasSubSel
			var p = this.parent;
			while( p ) {
				p._select(false, false, false);
				var isPartSel = false;
				for(var i=0; i<p.childList.length;  i++) {
					if( p.childList[i].bSelected || p.childList[i].hasSubSel ) {
						isPartSel = true;
						break;
					}
				}
				p._setSubSel(isPartSel);
				p = p.parent;
			}
		}
	},
	
	_select: function(sel, fireEvents, deep) {
		// Select - but not focus - this node.
//		this.tree.logDebug("dtnode._select(%o) - %o", sel, this);
		var opts = this.tree.options;
		if( this.data.isStatusNode )
			return;
		// 
		if( this.bSelected == sel ) {
//			this.tree.logDebug("dtnode._select(%o) IGNORED - %o", sel, this);
			return;
		}
		// Allow event listener to abort selection
		if ( fireEvents && opts.onQuerySelect && opts.onQuerySelect.call(this.span, sel, this) == false )
			return; // Callback returned false
		
		// Force single-selection
		if( opts.selectMode==1 && sel ) { 
			this.tree.visit(function(dtnode){
				if( dtnode.bSelected ) {
					// Deselect; assuming that in selectMode:1 there's max. one other selected node
					dtnode._select(false, false, false);
					return false;
				}
			});
		}

		this.bSelected = sel;
//        this.tree._changeNodeList("select", this, sel);
  
		if( sel ) {
			if( opts.persist )
				this.tree.persistence.addSelect(this.data.key);

			$(this.span).addClass(opts.classNames.selected);

			if( deep && opts.selectMode==3 )
				this._fixSelectionState();

			if ( fireEvents && opts.onSelect )
				opts.onSelect.call(this.span, true, this);

		} else {
			if( opts.persist )
				this.tree.persistence.clearSelect(this.data.key);
			
			$(this.span).removeClass(opts.classNames.selected);

	    	if( deep && opts.selectMode==3 )
				this._fixSelectionState();

	    	if ( fireEvents && opts.onSelect )
				opts.onSelect.call(this.span, false, this);
		}
	},

	select: function(sel) {
		// Select - but not focus - this node.
//		this.tree.logDebug("dtnode.select(%o) - %o", sel, this);
		if( this.data.unselectable )
			return this.bSelected;
		return this._select(sel!=false, true, true);
	},

	toggleSelect: function() {
//		this.tree.logDebug("dtnode.toggleSelect() - %o", this);
		return this.select(!this.bSelected);
	},

	isSelected: function() {
		return this.bSelected;
	},
	
	_loadContent: function() {
		try {
			var opts = this.tree.options;
			this.tree.logDebug("_loadContent: start - %o", this);
			this.setLazyNodeStatus(DTNodeStatus_Loading);
			if( true == opts.onLazyRead.call(this.span, this) ) {
				// If function returns 'true', we assume that the loading is done:
				this.setLazyNodeStatus(DTNodeStatus_Ok);
				// Otherwise (i.e. if the loading was started as an asynchronous process)
				// the onLazyRead(dtnode) handler is expected to call dtnode.setLazyNodeStatus(DTNodeStatus_Ok/_Error) when done.
				this.tree.logDebug("_loadContent: succeeded - %o", this);
			}
		} catch(e) {
			alert(e);
			this.setLazyNodeStatus(DTNodeStatus_Error);
		}
	},
	
	_expand: function(bExpand) {
//		this.tree.logDebug("dtnode._expand(%o) - %o", bExpand, this);
		if( this.bExpanded == bExpand ) {
//			this.tree.logDebug("dtnode._expand(%o) IGNORED - %o", bExpand, this);
			return;
		}
		var opts = this.tree.options;
		if( !bExpand && this.getLevel()<opts.minExpandLevel ) {
			this.tree.logDebug("dtnode._expand(%o) forced expand - %o", bExpand, this);
			return;
		}
		if ( opts.onQueryExpand && opts.onQueryExpand.call(this.span, bExpand, this) == false )
			return; // Callback returned false
		this.bExpanded = bExpand;

		// Persist expand state
		if( opts.persist ) {
	        if( bExpand )
				this.tree.persistence.addExpand(this.data.key);
			else 
				this.tree.persistence.clearExpand(this.data.key);
		}

		this.render(false);

        // Auto-collapse mode: collapse all siblings
		if( this.bExpanded && this.parent && opts.autoCollapse ) {
			var parents = this._parentList(false, true);
			for(var i=0; i<parents.length; i++)
				parents[i].collapseSiblings();
		}

		// If the currently active node is now hidden, deactivate it
		if( opts.activeVisible && this.tree.activeNode && ! this.tree.activeNode.isVisible() ) {
			this.tree.activeNode.deactivate();
		}
		// Expanding a lazy node: set 'loading...' and call callback
		if( bExpand && this.data.isLazy && this.childList==null && !this.isLoading ) {
			this._loadContent();
			return;
		}
//		this.tree.logDebug("_expand: start div toggle - %o", this);

		var fxDuration = opts.fx ? (opts.fx.duration || 200) : 0;
		if( this.childList ) {
			for(var i=0; i<this.childList.length; i++ ) {
				var $child = $(this.childList[i].div);
				if( fxDuration ) {
					// This is a toggle, so only do it, if not already rendered (in)visible (issue 98)
					if( bExpand != $child.is(':visible') )
						$child.animate(opts.fx, fxDuration);
				} else {
					if( bExpand )
						$child.show();
					else
						$child.hide(); // : this seems to be slow, when called the first time for an element
				}
			}
		}
		
/* issue 109: using selector filter is really SLOW.
		// issue 98: only toggle, if render hasn't set visibility already:
		var filter = ">DIV" + (bExpand ? ":hidden" : ":visible");
		
		if( opts.fx ) {
			var duration = opts.fx.duration || 200;
//			$(">DIV", this.div).animate(opts.fx, duration);
			$(filter, this.div).animate(opts.fx, duration);
		} else {
			$(filter, this.div).toggle();
//			var $d = $(">DIV", this.div);
//			this.tree.logDebug("_expand: got div, start toggle - %o", this);
//			$d.toggle();
		}
//*/
//		this.tree.logDebug("_expand: end div toggle - %o", this);

		if ( opts.onExpand )
			opts.onExpand.call(this.span, bExpand, this);
	},

	expand: function(flag) {
		if( !this.childList && !this.data.isLazy && flag )
			return; // Prevent expanding empty nodes
		if( this.parent == null && this.tree.options.minExpandLevel>0 && !flag )
			return; // Prevent collapsing the root
		this._expand(flag);
	},

	toggleExpand: function() {
		this.expand(!this.bExpanded);
	},

	collapseSiblings: function() {
		if( this.parent == null )
			return;
		var ac = this.parent.childList;
		for (var i=0; i<ac.length; i++) {
			if ( ac[i] !== this && ac[i].bExpanded )
				ac[i]._expand(false);
		}
	},

	onClick: function(event) {
//		this.tree.logDebug("dtnode.onClick(" + event.type + "): dtnode:" + this + ", button:" + event.button + ", which: " + event.which);
		var targetType = this.getEventTargetType(event);
		if( targetType == "expander" ) {
			// Clicking the expander icon always expands/collapses
			this.toggleExpand();
			this.focus(); // issue 95
		} else if( targetType == "checkbox" ) {
			// Clicking the checkbox always (de)selects
			this.toggleSelect();
			this.focus(); // issue 95
		} else {
			this._userActivate();
			// Chrome and Safari don't focus the a-tag on click
			this.span.getElementsByTagName("a")[0].focus();
		}
		// Make sure that clicks stop, otherwise <a href='#'> jumps to the top
		return true;
	},

	onDblClick: function(event) {
//		this.tree.logDebug("dtnode.onDblClick(" + event.type + "): dtnode:" + this + ", button:" + event.button + ", which: " + event.which);
	},

	onKeydown: function(event) {
//		this.tree.logDebug("dtnode.onKeydown(" + event.type + "): dtnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which);
		var handled = true;
//		alert("keyDown" + event.which);

		switch( event.which ) {
			// charCodes:
//			case 43: // '+'
			case 107: // '+'
			case 187: // '+' @ Chrome, Safari
				if( !this.bExpanded ) this.toggleExpand();
				break;
//			case 45: // '-'
			case 109: // '-'
			case 189: // '+' @ Chrome, Safari
				if( this.bExpanded ) this.toggleExpand();
				break;
			//~ case 42: // '*'
				//~ break;
			//~ case 47: // '/'
				//~ break;
			// case 13: // <enter>
				// <enter> on a focused <a> tag seems to generate a click-event. 
				// this._userActivate();
				// break;
			case 32: // <space>
				this._userActivate();
				break;
			case 8: // <backspace>
				if( this.parent )
					this.parent.focus();
				break;
			case 37: // <left>
				if( this.bExpanded ) {
					this.toggleExpand();
					this.focus();
				} else if( this.parent && (this.tree.options.rootVisible || this.parent.parent) ) {
					this.parent.focus();
				}
				break;
			case 39: // <right>
				if( !this.bExpanded && (this.childList || this.data.isLazy) ) {
					this.toggleExpand();
					this.focus();
				} else if( this.childList ) {
					this.childList[0].focus();
				}
				break;
			case 38: // <up>
				var sib = this.prevSibling();
				while( sib && sib.bExpanded && sib.childList )
					sib = sib.childList[sib.childList.length-1];
				if( !sib && this.parent && (this.tree.options.rootVisible || this.parent.parent) )
					sib = this.parent;
				if( sib ) sib.focus();
				break;
			case 40: // <down>
				var sib;
				if( this.bExpanded && this.childList ) {
					sib = this.childList[0];
				} else {
					var parents = this._parentList(false, true);
					for(var i=parents.length-1; i>=0; i--) {
						sib = parents[i].nextSibling();
						if( sib ) break;
					}
				}
				if( sib ) sib.focus();
				break;
			default:
				handled = false;
		}
		// Return false, if handled, to prevent default processing
		return !handled; 
	},

	onKeypress: function(event) {
		// onKeypress is only hooked to allow user callbacks.
		// We don't process it, because IE and Safari don't fire keypress for cursor keys.
//		this.tree.logDebug("dtnode.onKeypress(" + event.type + "): dtnode:" + this + ", charCode:" + event.charCode + ", keyCode: " + event.keyCode + ", which: " + event.which);
	},
	
	onFocus: function(event) {
		// Handles blur and focus events.
//		this.tree.logDebug("dtnode.onFocus(%o): %o", event, this);
		var opts = this.tree.options;
		if ( event.type=="blur" || event.type=="focusout" ) {
			if ( opts.onBlur ) // Pass element as 'this' (jQuery convention)
				opts.onBlur.call(this.span, this);
			if( this.tree.tnFocused )
				$(this.tree.tnFocused.span).removeClass(opts.classNames.focused);
			this.tree.tnFocused = null;
	        if( opts.persist ) 
				$.cookie(opts.cookieId+"-focus", "", opts.cookie);
		} else if ( event.type=="focus" || event.type=="focusin") {
			// Fix: sometimes the blur event is not generated
			if( this.tree.tnFocused && this.tree.tnFocused !== this ) {
				this.tree.logDebug("dtnode.onFocus: out of sync: curFocus: %o", this.tree.tnFocused);
				$(this.tree.tnFocused.span).removeClass(opts.classNames.focused);
			}
			this.tree.tnFocused = this;
			if ( opts.onFocus ) // Pass element as 'this' (jQuery convention)
				opts.onFocus.call(this.span, this);
			$(this.tree.tnFocused.span).addClass(opts.classNames.focused);
	        if( opts.persist )
				$.cookie(opts.cookieId+"-focus", this.data.key, opts.cookie);
		}
		// : return anything?
//		return false;
	},

	visit: function(fn, data, includeSelf) {
		// Call fn(dtnode, data) for all child nodes. Stop iteration, if fn() returns false.
		var n = 0;
		if( includeSelf == true ) {
			if( fn(this, data) == false )
				return 1; 
			n++; 
		}
		if ( this.childList )
			for (var i=0; i<this.childList.length; i++)
				n += this.childList[i].visit(fn, data, true);
		return n;
	},

	remove: function() {
        // Remove this node
//		this.tree.logDebug ("%o.remove()", this);
        if ( this === this.tree.root )
            return false;
        return this.parent.removeChild(this);
	},

	removeChild: function(tn) {
		// Remove tn from list of direct children.
		var ac = this.childList;
		if( ac.length == 1 ) {
			if( tn !== ac[0] )
				throw "removeChild: invalid child";
			return this.removeChildren();
		}
        if( tn === this.tree.activeNode )
        	tn.deactivate();
        if( this.tree.options.persist ) {
	        if( tn.bSelected )
	            this.tree.persistence.clearSelect(tn.data.key);
	        if ( tn.bExpanded )
	            this.tree.persistence.clearExpand(tn.data.key);
        }
		tn.removeChildren(true);
		this.div.removeChild(tn.div);
		for(var i=0; i<ac.length; i++) {
			if( ac[i] === tn ) {
				this.childList.splice(i, 1);
				delete tn;
				break;
			}
		}
	},

	removeChildren: function(isRecursiveCall, retainPersistence) {
        // Remove all child nodes (more efficiently than recursive remove())
//		this.tree.logDebug ("%o.removeChildren(%o)", this, isRecursiveCall);
		var tree = this.tree;
        var ac = this.childList;
        if( ac ) {
        	for(var i=0; i<ac.length; i++) {
				var tn=ac[i];
//        		this.tree.logDebug ("del %o", tn);
                if ( tn === tree.activeNode && !retainPersistence )
                	tn.deactivate();
                if( this.tree.options.persist && !retainPersistence ) {
	                if( tn.bSelected )
	                    this.tree.persistence.clearSelect(tn.data.key);
	                if ( tn.bExpanded )
	                    this.tree.persistence.clearExpand(tn.data.key);
                }
                tn.removeChildren(true, retainPersistence);
				this.div.removeChild(tn.div);
                delete tn;
        	}
        	this.childList = null;
        }
		if( ! isRecursiveCall ) {
//			this._expand(false);
//			this.isRead = false;
			this.isLoading = false;
			this.render(false, false);
		}
	},

	reload: function(force) {
		// Discard lazy content (and reload, if node was expanded). 
		if( this.parent == null )
			return this.tree.reload();
		
		if( ! this.data.isLazy )
			throw "node.reload() requires lazy nodes.";
		if( this.bExpanded ) {
			this.expand(false);
			this.removeChildren();
			this.expand(true);
		} else {
			this.removeChildren();
			if( force )
				this._loadContent();
		}
	},

	_addChildNode: function(dtnode, beforeNode) {
		/** 
		 * Internal function to add one single DynatreeNode as a child.
		 * 
		 */
		var tree = this.tree;
		var opts = tree.options;
		var pers = tree.persistence;
		
//		tree.logDebug("%o._addChildNode(%o)", this, dtnode);
		
		// --- Update and fix dtnode attributes if necessary 
		dtnode.parent = this;
//		if( beforeNode && (beforeNode.parent !== this || beforeNode === dtnode ) )
//			throw "<beforeNode> must be another child of <this>";

		// --- Add dtnode as a child
		if ( this.childList==null ) {
			this.childList = [];
		} else if( ! beforeNode ) {
			// Fix 'lastsib'
			$(this.childList[this.childList.length-1].span).removeClass(opts.classNames.lastsib);
		}
		if( beforeNode ) {
			var iBefore = $.inArray(beforeNode, this.childList);
			if( iBefore < 0 )
				throw "<beforeNode> must be a child of <this>";
			this.childList.splice(iBefore, 0, dtnode);
//			alert(this.childList);
		} else {
			// Append node
			this.childList.push(dtnode);
		}

		// --- Handle persistence 
		// Initial status is read from cookies, if persistence is active and 
		// cookies are already present.
		// Otherwise the status is read from the data attributes and then persisted.
		var isInitializing = tree.isInitializing();
		if( opts.persist && pers.cookiesFound && isInitializing ) {
			// Init status from cookies
//			tree.logDebug("init from cookie, pa=%o, dk=%o", pers.activeKey, dtnode.data.key);
			if( pers.activeKey == dtnode.data.key )
				tree.activeNode = dtnode;
			if( pers.focusedKey == dtnode.data.key )
				tree.focusNode = dtnode;
			dtnode.bExpanded = ($.inArray(dtnode.data.key, pers.expandedKeyList) >= 0);
			dtnode.bSelected = ($.inArray(dtnode.data.key, pers.selectedKeyList) >= 0);
//			tree.logDebug("    key=%o, bSelected=%o", dtnode.data.key, dtnode.bSelected);
		} else {
			// Init status from data (Note: we write the cookies after the init phase)
//			tree.logDebug("init from data");
			if( dtnode.data.activate ) {
				tree.activeNode = dtnode;
				if( opts.persist )
					pers.activeKey = dtnode.data.key;
			}
			if( dtnode.data.focus ) {
				tree.focusNode = dtnode;
				if( opts.persist )
					pers.focusedKey = dtnode.data.key;
			}
			dtnode.bExpanded = ( dtnode.data.expand == true ); // Collapsed by default
			if( dtnode.bExpanded && opts.persist )
				pers.addExpand(dtnode.data.key);
			dtnode.bSelected = ( dtnode.data.select == true ); // Deselected by default
/*			
			Doesn't work, cause pers.selectedKeyList may be null
			if( dtnode.bSelected && opts.selectMode==1 
				&& pers.selectedKeyList && pers.selectedKeyList.length>0 ) {
				tree.logWarning("Ignored multi-selection in single-mode for %o", dtnode);
				dtnode.bSelected = false; // Fixing bad input data (multi selection for mode:1)
			}
*/
			if( dtnode.bSelected && opts.persist )
				pers.addSelect(dtnode.data.key);
		}

		// Always expand, if it's below minExpandLevel
//		tree.logDebug ("%o._addChildNode(%o), l=%o", this, dtnode, dtnode.getLevel());
		if ( opts.minExpandLevel >= dtnode.getLevel() ) {
//			tree.logDebug ("Force expand for %o", dtnode);
			this.bExpanded = true;
		}

		// In multi-hier mode, update the parents selection state
		// issue #82: only if not initializing, because the children may not exist yet
//		if( !dtnode.data.isStatusNode && opts.selectMode==3 && !isInitializing )
//			dtnode._fixSelectionState();

		// In multi-hier mode, update the parents selection state
		if( dtnode.bSelected && opts.selectMode==3 ) {
			var p = this;
			while( p ) {
				if( !p.hasSubSel )
					p._setSubSel(true);
				p = p.parent;
			}
		}
		// render this node and the new child
		if ( tree.bEnableUpdate )
			this.render(true, true);

		return dtnode;
	},

	addChild: function(obj, beforeNode) {
		/**
		 * Add a node object as child.
		 * 
		 * This should be the only place, where a DynaTreeNode is constructed!
		 * (Except for the root node creation in the tree constructor)
		 * 
		 * @param obj A JS object (may be recursive) or an array of those.
		 * @param {DynaTreeNode} beforeNode (optional) sibling node.
		 *     
		 * Data format: array of node objects, with optional 'children' attributes.
		 * [
		 *	{ title: "t1", isFolder: true, ... }
		 *	{ title: "t2", isFolder: true, ...,
		 *		children: [
		 *			{title: "t2.1", ..},
		 *			{..}
		 *			]
		 *	}
		 * ]
		 * A simple object is also accepted instead of an array.
		 * 
		 */
//		this.tree.logDebug("%o.addChild(%o, %o)", this, obj, beforeNode);
		if( !obj || obj.length==0 ) // Passed null or undefined or empty array
			return;
		if( obj instanceof DynaTreeNode )
			return this._addChildNode(obj, beforeNode);
		if( !obj.length ) // Passed a single data object
			obj = [ obj ];

		var prevFlag = this.tree.enableUpdate(false);

		var tnFirst = null;
		for (var i=0; i<obj.length; i++) {
			var data = obj[i];
			var dtnode = this._addChildNode(new DynaTreeNode(this, this.tree, data), beforeNode);
			if( !tnFirst ) tnFirst = dtnode;
			// Add child nodes recursively
			if( data.children )
				dtnode.addChild(data.children, null);
		}
		this.tree.enableUpdate(prevFlag);
		return tnFirst;
	},

	append: function(obj) {
		this.tree.logWarning("node.append() is deprecated (use node.addChild() instead).");
		return this.addChild(obj, null);
	},

	appendAjax: function(ajaxOptions) {
		this.removeChildren(false, true);
		this.setLazyNodeStatus(DTNodeStatus_Loading);
		// Ajax option inheritance: $.ajaxSetup < $.ui.dynatree.defaults.ajaxDefaults < tree.options.ajaxDefaults < ajaxOptions
		var self = this;
		var orgSuccess = ajaxOptions.success;
		var orgError = ajaxOptions.error;
		var options = $.extend({}, this.tree.options.ajaxDefaults, ajaxOptions, {
/*
       		complete: function(req, textStatus){
	 		    alert("ajax complete");
   			},
   			timeout: 5000, // 5 sec
*/   			
       		success: function(data, textStatus){
     		    // <this> is the request options
//				self.tree.logDebug("appendAjax().success");
				var prevPhase = self.tree.phase;
				self.tree.phase = "init";
//				self.append(data);
				self.addChild(data, null);
				self.tree.phase = "postInit";
				self.setLazyNodeStatus(DTNodeStatus_Ok);
				if( orgSuccess )
					orgSuccess.call(options, self);
				self.tree.phase = prevPhase;
       			},
       		error: function(XMLHttpRequest, textStatus, errorThrown){
       		    // <this> is the request options  
//				self.tree.logDebug("appendAjax().error");
				self.setLazyNodeStatus(DTNodeStatus_Error);
				if( orgError )
					orgError.call(options, self, XMLHttpRequest, textStatus, errorThrown);
       			}
		});
       	$.ajax(options);
	},
	// --- end of class
	lastentry: undefined
}

/*************************************************************************
 * class DynaTreeStatus
 */

var DynaTreeStatus = Class.create();


DynaTreeStatus._getTreePersistData = function(cookieId, cookieOpts) {
	// Static member: Return persistence information from cookies
	var ts = new DynaTreeStatus(cookieId, cookieOpts);
	ts.read();
	return ts.toDict();
}
// Make available in global scope
getDynaTreePersistData = DynaTreeStatus._getTreePersistData;


DynaTreeStatus.prototype = {
	// Constructor
	initialize: function(cookieId, cookieOpts) {
		this._log("DynaTreeStatus: initialize");
		if( cookieId === undefined )
			cookieId = $.ui.dynatree.defaults.cookieId;
		cookieOpts = $.extend({}, $.ui.dynatree.defaults.cookie, cookieOpts);
		
		this.cookieId = cookieId; 
		this.cookieOpts = cookieOpts;
		this.cookiesFound = undefined;
		this.activeKey = null;
		this.focusedKey = null;
		this.expandedKeyList = null;
		this.selectedKeyList = null;
	},
	// member functions
	_log: function(msg) {
		//	this.logDebug("_changeNodeList(%o): nodeList:%o, idx:%o", mode, nodeList, idx);
		Array.prototype.unshift.apply(arguments, ["debug"]);
		_log.apply(this, arguments);
	},
	read: function() {
		this._log("DynaTreeStatus: read");
		// Read or init cookies. 
		this.cookiesFound = false;
			
		var cookie = $.cookie(this.cookieId + "-active");
		this.activeKey = ( cookie == null ) ? "" : cookie;
		if( cookie != null ) this.cookiesFound = true;

		cookie = $.cookie(this.cookieId + "-focus");
		this.focusedKey = ( cookie == null ) ? "" : cookie;
		if( cookie != null ) this.cookiesFound = true;

		cookie = $.cookie(this.cookieId + "-expand");
		this.expandedKeyList = ( cookie == null ) ? [] : cookie.split(","); 
		if( cookie != null ) this.cookiesFound = true;

		cookie = $.cookie(this.cookieId + "-select");
		this.selectedKeyList = ( cookie == null ) ? [] : cookie.split(","); 
		if( cookie != null ) this.cookiesFound = true;
	},
	write: function() {
		this._log("DynaTreeStatus: write");
		$.cookie(this.cookieId + "-active", ( this.activeKey == null ) ? "" : this.activeKey, this.cookieOpts);
		$.cookie(this.cookieId + "-focus", ( this.focusedKey == null ) ? "" : this.focusedKey, this.cookieOpts);
		$.cookie(this.cookieId + "-expand", ( this.expandedKeyList == null ) ? "" : this.expandedKeyList.join(","), this.cookieOpts);
		$.cookie(this.cookieId + "-select", ( this.selectedKeyList == null ) ? "" : this.selectedKeyList.join(","), this.cookieOpts);
	},
	addExpand: function(key) {
		this._log("addExpand(%o)", key);
		if( $.inArray(key, this.expandedKeyList) < 0 ) {
			this.expandedKeyList.push(key);
			$.cookie(this.cookieId + "-expand", this.expandedKeyList.join(","), this.cookieOpts);
		}
	},
	clearExpand: function(key) {
		this._log("clearExpand(%o)", key);
		var idx = $.inArray(key, this.expandedKeyList); 
		if( idx >= 0 ) {
			this.expandedKeyList.splice(idx, 1);
			$.cookie(this.cookieId + "-expand", this.expandedKeyList.join(","), this.cookieOpts);
		}
	},
	addSelect: function(key) {
		this._log("addSelect(%o)", key);
		if( $.inArray(key, this.selectedKeyList) < 0 ) {
			this.selectedKeyList.push(key);
			$.cookie(this.cookieId + "-select", this.selectedKeyList.join(","), this.cookieOpts);
		}
	},
	clearSelect: function(key) {
		this._log("clearSelect(%o)", key);
		var idx = $.inArray(key, this.selectedKeyList); 
		if( idx >= 0 ) {
			this.selectedKeyList.splice(idx, 1);
			$.cookie(this.cookieId + "-select", this.selectedKeyList.join(","), this.cookieOpts);
		}
	},
	isReloading: function() {
		return this.cookiesFound == true;
	},
	toDict: function() {
		return {
			cookiesFound: this.cookiesFound,
			activeKey: this.activeKey,
			focusedKey: this.activeKey,
			expandedKeyList: this.expandedKeyList,
			selectedKeyList: this.selectedKeyList
		};
	},
	// --- end of class
	lastentry: undefined
};


/*************************************************************************
 * class DynaTree
 */

var DynaTree = Class.create();

// --- Static members ----------------------------------------------------------

DynaTree.version = "$Version: 0.5.2$"; 
/*
DynaTree._initTree = function() {
};

DynaTree._bind = function() {
};
*/
//--- Class members ------------------------------------------------------------

DynaTree.prototype = {
	// Constructor
//	initialize: function(divContainer, options) {
	initialize: function($widget) {
		// instance members
		this.phase = "init";
		this.$widget = $widget;
		this.options = $widget.options;
		this.$tree = $widget.element;
		// find container element
		this.divTree = this.$tree.get(0);
	},

	// member functions

	_load: function() {
		var $widget = this.$widget;
		var opts = this.options;
		this.bEnableUpdate = true;
		this._nodeCount = 1;
		this.activeNode = null;
		this.focusNode = null;

		// If a 'options.classNames' dictionary was passed, still use defaults 
    	// for undefined classes:
    	if( opts.classNames !== $.ui.dynatree.defaults.classNames ) {
    		opts.classNames = $.extend({}, $.ui.dynatree.defaults.classNames, opts.classNames);
    	}
    	// Guess skin path, if not specified
    	if(!opts.imagePath) {
    		$("script").each( function () {
    			// Eclipse syntax parser breaks on this expression, so put it at the bottom:
    			if( this.src.search(_rexDtLibName) >= 0 ) {
                    if( this.src.indexOf("/")>=0 ) // issue #47
    				    opts.imagePath = this.src.slice(0, this.src.lastIndexOf("/")) + "/skin/";
                    else
    				    opts.imagePath = "skin/";
//    				logMsg("Guessing imagePath from '%s': '%s'", this.src, opts.imagePath);
    				return false; // first match
    			}
    		});
    	}
    	
		this.persistence = new DynaTreeStatus(opts.cookieId, opts.cookie);
		if( opts.persist ) {
			if( !$.cookie )
				_log("warn", "Please include jquery.cookie.js to use persistence.");
			this.persistence.read();
		}
		this.logDebug("DynaTree.persistence: %o", this.persistence.toDict());

		// Cached tag strings
		this.cache = {
			tagEmpty: "<span class='" + opts.classNames.empty + "'></span>",
			tagVline: "<span class='" + opts.classNames.vline + "'></span>",
			tagExpander: "<span class='" + opts.classNames.expander + "'></span>",
			tagConnector: "<span class='" + opts.classNames.connector + "'></span>",
			tagNodeIcon: "<span class='" + opts.classNames.nodeIcon + "'></span>",
			tagCheckbox: "<span class='" + opts.classNames.checkbox + "'></span>",
			lastentry: undefined
		};

    	// Clear container, in case it contained some 'waiting' or 'error' text 
    	// for clients that don't support JS.
		// We don't do this however, if we try to load from an embedded UL element.
    	if( opts.children || (opts.initAjax && opts.initAjax.url) || opts.initId )
    		$(this.divTree).empty();
    	else if( this.divRoot )
    		$(this.divRoot).remove();

		// create the root element
		this.tnRoot = new DynaTreeNode(null, this, {title: opts.title, key: "root"});
		this.tnRoot.data.isFolder = true;
		this.tnRoot.render(false, false);
		this.divRoot = this.tnRoot.div;
		this.divRoot.className = opts.classNames.container;
		// add root to container
		// : this should be delayed until all children have been created for performance reasons
		this.divTree.appendChild(this.divRoot);

    	var root = this.tnRoot;
    	var isReloading = ( opts.persist && this.persistence.isReloading() );
    	var isLazy = false;
    	var prevFlag = this.enableUpdate(false);  

    	this.logDebug("Dynatree._load(): read tree structure...");

    	// Init tree structure
    	if( opts.children ) {
    		// Read structure from node array
    		root.addChild(opts.children);

    	} else if( opts.initAjax && opts.initAjax.url ) {
    		// Init tree from AJAX request
    		isLazy = true;
    		root.data.isLazy = true;
    		this._reloadAjax();

    	} else if( opts.initId ) {
    		// Init tree from another UL element
    		this._createFromTag(root, $("#"+opts.initId));

    	} else {
    		// Init tree from the first UL element inside the container <div>
    		var $ul = this.$tree.find(">ul").hide();
    		this._createFromTag(root, $ul);
    		$ul.remove();
    	}
    	
    	this._checkConsistency();
    	// Render html markup
    	this.logDebug("Dynatree._load(): render nodes...");
    	this.enableUpdate(prevFlag);
    	
    	// bind event handlers
    	this.logDebug("Dynatree._load(): bind events...");
    	this.$widget.bind();

        // --- Post-load processing
    	this.logDebug("Dynatree._load(): postInit...");
    	this.phase = "postInit";
    	
    	// In persist mode, make sure that cookies are written, even if they are empty
        if( opts.persist ) { 
			this.persistence.write();
        }
        
    	// Set focus, if possible (this will also fire an event and write a cookie)
    	if( this.focusNode && this.focusNode.isVisible() ) {
    		this.logDebug("Focus on init: %o", this.focusNode);
    		this.focusNode.focus();
    	}

    	if( !isLazy && opts.onPostInit ) {
    		opts.onPostInit.call(this, isReloading, false);
    	}

    	this.phase = "idle";
	},
	
	_reloadAjax: function() {
		// Reload 
		var opts = this.options;
		if( ! opts.initAjax || ! opts.initAjax.url )
			throw "tree.reload() requires 'initAjax' mode.";
		var pers = this.persistence;
		var ajaxOpts = $.extend({}, opts.initAjax);
		// Append cookie info to the request
//		this.logDebug("reloadAjax: key=%o, an.key:%o", pers.activeKey, this.activeNode?this.activeNode.data.key:"?");
		if( ajaxOpts.addActiveKey )
			ajaxOpts.data.activeKey = pers.activeKey; 
		if( ajaxOpts.addFocusedKey )
			ajaxOpts.data.focusedKey = pers.focusedKey; 
		if( ajaxOpts.addExpandedKeyList )
			ajaxOpts.data.expandedKeyList = pers.expandedKeyList.join(","); 
		if( ajaxOpts.addSelectedKeyList )
			ajaxOpts.data.selectedKeyList = pers.selectedKeyList.join(","); 

		// Set up onPostInit callback to be called when Ajax returns
		if( opts.onPostInit ) {
			if( ajaxOpts.success )
				this.tree.logWarning("initAjax: success callback is ignored when onPostInit was specified.");
			if( ajaxOpts.error )
				this.tree.logWarning("initAjax: error callback is ignored when onPostInit was specified.");
			var isReloading = pers.isReloading();
			ajaxOpts["success"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, false); }; 
			ajaxOpts["error"] = function(dtnode) { opts.onPostInit.call(dtnode.tree, isReloading, true); }; 
		}
    	this.logDebug("Dynatree._init(): send Ajax request...");
    	this.tnRoot.appendAjax(ajaxOpts);
	},

	toString: function() {
		return "DynaTree '" + this.options.title + "'";
	},

	toDict: function() {
		return this.tnRoot.toDict(true);
	},
	
	getPersistData: function() {
		return this.persistence.toDict();
	},
	
	logDebug: function(msg) {
		if( this.options.debugLevel >= 2 ) {
			Array.prototype.unshift.apply(arguments, ["debug"]);
			_log.apply(this, arguments);
		}
	},

	logInfo: function(msg) {
		if( this.options.debugLevel >= 1 ) {
			Array.prototype.unshift.apply(arguments, ["info"]);
			_log.apply(this, arguments);
		}
	},

	logWarning: function(msg) {
		Array.prototype.unshift.apply(arguments, ["warn"]);
		_log.apply(this, arguments);
	},

	isInitializing: function() {
		return ( this.phase=="init" || this.phase=="postInit" );
	},
	isReloading: function() {
		return ( this.phase=="init" || this.phase=="postInit" ) && this.options.persist && this.persistence.cookiesFound;
	},
	isUserEvent: function() {
		return ( this.phase=="userEvent" );
	},

	redraw: function() {
		this.logDebug("dynatree.redraw()...");
		this.tnRoot.render(true, true);
		this.logDebug("dynatree.redraw() done.");
	},

	reloadAjax: function() {
		this.logWarning("tree.reloadAjax() is deprecated since v0.5.2 (use reload() instead).");
	},
	
	reload: function() {
		this._load();
	},
	
	getRoot: function() {
		return this.tnRoot;
	},

	getNodeByKey: function(key) {
		// $("#...") has problems, if the key contains '.', so we use getElementById()
//		return $("#" + this.options.idPrefix + key).attr("dtnode");
		var el = document.getElementById(this.options.idPrefix + key);
		return ( el && el.dtnode ) ? el.dtnode : null;
	},

	getActiveNode: function() {
		return this.activeNode;
	},
	
	reactivate: function(setFocus) {
		// Re-fire onQueryActivate and onActivate events.
		var node = this.activeNode;
//		this.logDebug("reactivate %o", node);
		if( node ) {
			this.activeNode = null; // Force re-activating
			node.activate();
			if( setFocus )
				node.focus();
		}
	},

	getSelectedNodes: function(stopOnParents) {
		var nodeList = [];
		this.tnRoot.visit(function(dtnode){
			if( dtnode.bSelected ) {
				nodeList.push(dtnode);
				if( stopOnParents == true )
					return false; // stop processing this branch
			}
		});
		return nodeList;
	},

	activateKey: function(key) {
		var dtnode = (key === null) ? null : this.getNodeByKey(key);
		if( !dtnode ) {
			if( this.activeNode )
				this.activeNode.deactivate();
			this.activeNode = null;
			return null;
		}
		dtnode.focus();
		dtnode.activate();
		return dtnode;
	},

	selectKey: function(key, select) {
		var dtnode = this.getNodeByKey(key);
		if( !dtnode )
			return null;
		dtnode.select(select);
		return dtnode;
	},

	enableUpdate: function(bEnable) {
		if ( this.bEnableUpdate==bEnable )
			return bEnable;
		this.bEnableUpdate = bEnable;
		if ( bEnable )
			this.redraw();
		return !bEnable; // return previous value
	},

	visit: function(fn, data, includeRoot) {
		return this.tnRoot.visit(fn, data, includeRoot);
	},

	_createFromTag: function(parentTreeNode, $ulParent) {
		// Convert a <UL>...</UL> list into children of the parent tree node.
		var self = this;
/*
: better?
		this.$lis = $("li:has(a[href])", this.element);
		this.$tabs = this.$lis.map(function() { return $("a", this)[0]; });
 */
		$ulParent.find(">li").each(function() {
			var $li = $(this);
			var $liSpan = $li.find(">span:first");
			var title;
			if( $liSpan.length ) {
				// If a <li><span> tag is specified, use it literally.
				title = $liSpan.html();
			} else {
				// If only a <li> tag is specified, use the trimmed string up to the next child <ul> tag.
				title = $li.html();
				var iPos = title.search(/<ul/i);
				if( iPos>=0 )
					title = $.trim(title.substring(0, iPos));
				else
					title = $.trim(title);
//				self.logDebug("%o", title);
			}
			// Parse node options from ID, title and class attributes
			var data = {
				title: title,
				isFolder: $li.hasClass("folder"),
				isLazy: $li.hasClass("lazy"),
				expand: $li.hasClass("expanded"),
				select: $li.hasClass("selected"),
				activate: $li.hasClass("active"),
				focus: $li.hasClass("focused")
			};
			if( $li.attr("title") )
				data.tooltip = $li.attr("title");
			if( $li.attr("id") )
				data.key = $li.attr("id");
			// If a data attribute is present, evaluate as a JavaScript object
			if( $li.attr("data") ) {
				var dataAttr = $.trim($li.attr("data"));
				if( dataAttr ) {
					if( dataAttr.charAt(0) != "{" )
						dataAttr = "{" + dataAttr + "}"
					try {
						$.extend(data, eval("(" + dataAttr + ")"));
					} catch(e) {
						throw ("Error parsing node data: " + e + "\ndata:\n'" + dataAttr + "'");
					}
				}
			}
			childNode = parentTreeNode.addChild(data);
			// Recursive reading of child nodes, if LI tag contains an UL tag
			var $ul = $li.find(">ul:first");
			if( $ul.length ) {
				self._createFromTag(childNode, $ul); // must use 'self', because 'this' is the each() context
			}
		});
	},

	_checkConsistency: function() {
//		this.logDebug("tree._checkConsistency() NOT IMPLEMENTED - %o", this);
	},
	
	// --- end of class
	lastentry: undefined
};

/*************************************************************************
 * widget $(..).dynatree
 */

$.widget("ui.dynatree", {
	init: function() {
        // ui.core 1.6 renamed init() to _init(): this stub assures backward compatibility
        _log("warn", "ui.dynatree.init() was called; you should upgrade to ui.core.js v1.6 or higher.");
        return this._init();
    },

	_init: function() {
    	logMsg("Dynatree._init(): version='%s', debugLevel=%o.", DynaTree.version, this.options.debugLevel);

    	var opts = this.options;
    	// The widget framework supplies this.element and this.options.
    	this.options.event += ".dynatree"; // namespace event

    	var divTree = this.element.get(0);
/*    	// Clear container, in case it contained some 'waiting' or 'error' text 
    	// for clients that don't support JS
    	if( opts.children || (opts.initAjax && opts.initAjax.url) || opts.initId )
    		$(divTree).empty();
*/
    	// Create the DynaTree object
    	this.tree = new DynaTree(this);
    	this.tree._load();
    	this.tree.logDebug("Dynatree._init(): done.");
	},

	bind: function() {
		var $this = this.element;
		var o = this.options;

		// Prevent duplicate binding
		this.unbind();
		
		// Tool function to get dtnode from the event target:
		function __getNodeFromElement(el) {
			var iMax = 5;
			while( el && iMax-- ) {
				if( el.dtnode ) return el.dtnode;
				el = el.parentNode;
			};
			return null;
		}

		var eventNames = "click.dynatree dblclick.dynatree";
		if( o.keyboard ) // Note: leading ' '!
			eventNames += " keypress.dynatree keydown.dynatree";
		$this.bind(eventNames, function(event){
			var dtnode = __getNodeFromElement(event.target);
			if( !dtnode )
				return true;  // Allow bubbling of other events
			var prevPhase = dtnode.tree.phase;
			dtnode.tree.phase = "userEvent";
			try {
				dtnode.tree.logDebug("bind(%o): dtnode: %o", event, dtnode);

				switch(event.type) {
				case "click":
					return ( o.onClick && o.onClick(dtnode, event)===false ) ? false : dtnode.onClick(event);
				case "dblclick":
					return ( o.onDblClick && o.onDblClick(dtnode, event)===false ) ? false : dtnode.onDblClick(event);
				case "keydown":
					return ( o.onKeydown && o.onKeydown(dtnode, event)===false ) ? false : dtnode.onKeydown(event);
				case "keypress":
					return ( o.onKeypress && o.onKeypress(dtnode, event)===false ) ? false : dtnode.onKeypress(event);
				};
			} catch(e) {
				var _ = null; // issue 117
//				dtnode.tree.logError("bind(%o): dtnode: %o", event, dtnode);
			} finally {
				dtnode.tree.phase = prevPhase;
			}
		});
		
		// focus/blur don't bubble, i.e. are not delegated to parent <div> tags,
		// so we use the addEventListener capturing phase.
		// See http://www.howtocreate.co.uk/tutorials/javascript/domevents
		function __focusHandler(event) {
			// Handles blur and focus.
			// Fix event for IE:
			event = arguments[0] = $.event.fix( event || window.event );
			var dtnode = __getNodeFromElement(event.target);
			return dtnode ? dtnode.onFocus(event) : false;
		}
		var div = this.tree.divTree;
		if( div.addEventListener ) {
			div.addEventListener("focus", __focusHandler, true);
			div.addEventListener("blur", __focusHandler, true);
		} else {
			div.onfocusin = div.onfocusout = __focusHandler;
		}
		// EVENTS
		// disable click if event is configured to something else
//		if (!(/^click/).test(o.event))
//			this.$tabs.bind("click.tabs", function() { return false; });
		
	},
	
	unbind: function() {
		this.element.unbind(".dynatree");
	},
	
/* : we could handle option changes during runtime here (maybe to re-render, ...)
	setData: function(key, value) {
		this.tree.logDebug("dynatree.setData('" + key + "', '" + value + "')");
	},
*/	
	enable: function() {
		this.bind();
		// Call default disable(): remove -disabled from css: 
		$.widget.prototype.enable.apply(this, arguments);
	},
	
	disable: function() {
		this.unbind();
		// Call default disable(): add -disabled to css: 
		$.widget.prototype.disable.apply(this, arguments);
	},
	
	// --- getter methods (i.e. NOT returning a reference to $)
	getTree: function() {
		return this.tree;
	},

	getRoot: function() {
		return this.tree.getRoot();
	},

	getActiveNode: function() {
		return this.tree.getActiveNode();
	},

	getSelectedNodes: function() {
		return this.tree.getSelectedNodes();
	},

	// ------------------------------------------------------------------------
	lastentry: undefined
});


// The following methods return a value (thus breaking the jQuery call chain):

$.ui.dynatree.getter = "getTree getRoot getActiveNode getSelectedNodes";


// Plugin default options:

$.ui.dynatree.defaults = {
	title: "Dynatree root", // Name of the root node.
	rootVisible: false, // Set to true, to make the root node visible.
 	minExpandLevel: 1, // 1: root node is not collapsible
	imagePath: null, // Path to a folder containing icons. Defaults to 'skin/' subdirectory.
	children: null, // Init tree structure from this object array.
	initId: null, // Init tree structure from a <ul> element with this ID.
	initAjax: null, // Ajax options used to initialize the tree strucuture.
	autoFocus: true, // Set focus to first child, when expanding or lazy-loading.
	keyboard: true, // Support keyboard navigation.
    persist: false, // Persist expand-status to a cookie
	autoCollapse: false, // Automatically collapse all siblings, when a node is expanded.
	clickFolderMode: 3, // 1:activate, 2:expand, 3:activate and expand
	activeVisible: true, // Make sure, active nodes are visible (expanded).
	checkbox: false, // Show checkboxes.
	selectMode: 2, // 1:single, 2:multi, 3:multi-hier
	fx: null, // Animations, e.g. null or { height: "toggle", duration: 200 }

	// Low level event handlers: onEvent(dtnode, event): return false, to stop default processing
	onClick: null, // null: generate focus, expand, activate, select events.
	onDblClick: null, // (No default actions.)
	onKeydown: null, // null: generate keyboard navigation (focus, expand, activate).
	onKeypress: null, // (No default actions.)
	onFocus: null, // null: set focus to node.
	onBlur: null, // null: remove focus from node.

	// Pre-event handlers onQueryEvent(flag, dtnode): return false, to stop processing
	onQueryActivate: null, // Callback(flag, dtnode) before a node is (de)activated.
	onQuerySelect: null, // Callback(flag, dtnode) before a node is (de)selected.
	onQueryExpand: null, // Callback(flag, dtnode) before a node is expanded/collpsed.
	
	// High level event handlers
	onPostInit: null, // Callback(isReloading, isError) when tree was (re)loaded.
	onActivate: null, // Callback(dtnode) when a node is activated.
	onDeactivate: null, // Callback(dtnode) when a node is deactivated.
	onSelect: null, // Callback(flag, dtnode) when a node is (de)selected.
	onExpand: null, // Callback(dtnode) when a node is expanded/collapsed.
	onLazyRead: null, // Callback(dtnode) when a lazy node is expanded for the first time.
	
	ajaxDefaults: { // Used by initAjax option
		cache: false, // false: Append random '_' argument to the request url to prevent caching.
		dataType: "json" // Expect json format and pass json object to callbacks.
	},
	strings: {
		loading: "Loading&#8230;",
		loadError: "Load error!"
	},
	idPrefix: "ui-dynatree-id-", // Used to generate node id's like <span id="ui-dynatree-id-<key>">.
//    cookieId: "ui-dynatree-cookie", // Choose a more unique name, to allow multiple trees.
    cookieId: "dynatree", // Choose a more unique name, to allow multiple trees.
	cookie: {
		expires: null //7, // Days or Date; null: session cookie
//		path: "/", // Defaults to current page
//		domain: "jquery.com",
//		secure: true
	},
    // Class names used, when rendering the HTML markup.
	// Note: if only single entries are passed for options.classNames, all other 
	// values are still set to default. 
	classNames: {
		container: "ui-dynatree-container",
		folder: "ui-dynatree-folder",
		document: "ui-dynatree-document",
		
		empty: "ui-dynatree-empty",
		vline: "ui-dynatree-vline",
		expander: "ui-dynatree-expander",
		connector: "ui-dynatree-connector",
		checkbox: "ui-dynatree-checkbox",
		nodeIcon: "ui-dynatree-icon",
		title: "ui-dynatree-title",
		
		nodeError: "ui-dynatree-statusnode-error",
		nodeWait: "ui-dynatree-statusnode-wait",
		hidden: "ui-dynatree-hidden",
		combinedExpanderPrefix: "ui-dynatree-exp-",
		combinedIconPrefix: "ui-dynatree-ico-",
//		disabled: "ui-dynatree-disabled",
		hasChildren: "ui-dynatree-has-children",
		active: "ui-dynatree-active",
		selected: "ui-dynatree-selected",
		expanded: "ui-dynatree-expanded",
		lazy: "ui-dynatree-lazy",
		focused: "ui-dynatree-focused",
		partsel: "ui-dynatree-partsel",
		lastsib: "ui-dynatree-lastsib"
	},
	debugLevel: 1,

	// ------------------------------------------------------------------------
	lastentry: undefined
};

/**
 * Reserved data attributes for a tree node.
 */
$.ui.dynatree.nodedatadefaults = {
	title: null, // (required) Displayed name of the node (html is allowed here)
	key: null, // May be used with activate(), select(), find(), ...
	isFolder: false, // Use a folder icon. Also the node is expandable but not selectable.
	isLazy: false, // Call onLazyRead(), when the node is expanded for the first time to allow for delayed creation of children.
	tooltip: null, // Show this popup text.
	icon: null, // Use a custom image (filename relative to tree.options.imagePath). 'null' for default icon, 'false' for no icon.
	addClass: null, // Class name added to the node's span tag.  
	activate: false, // Initial active status.
	focus: false, // Initial focused status.
	expand: false, // Initial expanded status.
	select: false, // Initial selected status.
	hideCheckbox: false, // Suppress checkbox display for this node.
	unselectable: false, // Prevent selection.
//  disabled: false,	
	// The following attributes are only valid if passed to some functions:
	children: null, // Array of child nodes.
	// NOTE: we can also add custom attributes here.
	// This may then also be used in the onActivate(), onSelect() or onLazyTree() callbacks.
	// ------------------------------------------------------------------------
	lastentry: undefined
};

// ---------------------------------------------------------------------------
})(jQuery);

// Eclipse syntax parser breaks on this expression, so we put it at the bottom.
var _rexDtLibName = /.*dynatree[^/]*\.js$/i;


// *
// * jQuery UI Core & Resizable 1.7.2 - New Wave Javascript (Packed)
// *
// * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
// * Dual licensed under the MIT (MIT-LICENSE.txt)
// * and GPL (GPL-LICENSE.txt) licenses.
// *
// * http://docs.jquery.com/UI
// *

if (typeof(jQuery) == "function") {
  jQuery.ui||(function(c){var i=c.fn.remove,d=c.browser.mozilla&&(parseFloat(c.browser.version)<1.9);c.ui={version:"1.7.2",plugin:{add:function(k,l,n){var m=c.ui[k].prototype;for(var j in n){m.plugins[j]=m.plugins[j]||[];m.plugins[j].push([l,n[j]])}},call:function(j,l,k){var n=j.plugins[l];if(!n||!j.element[0].parentNode){return}for(var m=0;m<n.length;m++){if(j.options[n[m][0]]){n[m][1].apply(j.element,k)}}}},contains:function(k,j){return document.compareDocumentPosition?k.compareDocumentPosition(j)&16:k!==j&&k.contains(j)},hasScroll:function(m,k){if(c(m).css("overflow")=="hidden"){return false}var j=(k&&k=="left")?"scrollLeft":"scrollTop",l=false;if(m[j]>0){return true}m[j]=1;l=(m[j]>0);m[j]=0;return l},isOverAxis:function(k,j,l){return(k>j)&&(k<(j+l))},isOver:function(o,k,n,m,j,l){return c.ui.isOverAxis(o,n,j)&&c.ui.isOverAxis(k,m,l)},keyCode:{BACKSPACE:8,CAPS_LOCK:20,COMMA:188,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,INSERT:45,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SHIFT:16,SPACE:32,TAB:9,UP:38}};if(d){var f=c.attr,e=c.fn.removeAttr,h="http://www.w3.org/2005/07/aaa",a=/^aria-/,b=/^wairole:/;c.attr=function(k,j,l){var m=l!==undefined;return(j=="role"?(m?f.call(this,k,j,"wairole:"+l):(f.apply(this,arguments)||"").replace(b,"")):(a.test(j)?(m?k.setAttributeNS(h,j.replace(a,"aaa:"),l):f.call(this,k,j.replace(a,"aaa:"))):f.apply(this,arguments)))};c.fn.removeAttr=function(j){return(a.test(j)?this.each(function(){this.removeAttributeNS(h,j.replace(a,""))}):e.call(this,j))}}c.fn.extend({remove:function(){c("*",this).add(this).each(function(){c(this).triggerHandler("remove")});return i.apply(this,arguments)},enableSelection:function(){return this.attr("unselectable","off").css("MozUserSelect","").unbind("selectstart.ui")},disableSelection:function(){return this.attr("unselectable","on").css("MozUserSelect","none").bind("selectstart.ui",function(){return false})},scrollParent:function(){var j;if((c.browser.msie&&(/(static|relative)/).test(this.css("position")))||(/absolute/).test(this.css("position"))){j=this.parents().filter(function(){return(/(relative|absolute|fixed)/).test(c.curCSS(this,"position",1))&&(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}else{j=this.parents().filter(function(){return(/(auto|scroll)/).test(c.curCSS(this,"overflow",1)+c.curCSS(this,"overflow-y",1)+c.curCSS(this,"overflow-x",1))}).eq(0)}return(/fixed/).test(this.css("position"))||!j.length?c(document):j}});c.extend(c.expr[":"],{data:function(l,k,j){return !!c.data(l,j[3])},focusable:function(k){var l=k.nodeName.toLowerCase(),j=c.attr(k,"tabindex");return(/input|select|textarea|button|object/.test(l)?!k.disabled:"a"==l||"area"==l?k.href||!isNaN(j):!isNaN(j))&&!c(k)["area"==l?"parents":"closest"](":hidden").length},tabbable:function(k){var j=c.attr(k,"tabindex");return(isNaN(j)||j>=0)&&c(k).is(":focusable")}});function g(m,n,o,l){function k(q){var p=c[m][n][q]||[];return(typeof p=="string"?p.split(/,?\s+/):p)}var j=k("getter");if(l.length==1&&typeof l[0]=="string"){j=j.concat(k("getterSetter"))}return(c.inArray(o,j)!=-1)}c.widget=function(k,j){var l=k.split(".")[0];k=k.split(".")[1];c.fn[k]=function(p){var n=(typeof p=="string"),o=Array.prototype.slice.call(arguments,1);if(n&&p.substring(0,1)=="_"){return this}if(n&&g(l,k,p,o)){var m=c.data(this[0],k);return(m?m[p].apply(m,o):undefined)}return this.each(function(){var q=c.data(this,k);(!q&&!n&&c.data(this,k,new c[l][k](this,p))._init());(q&&n&&c.isFunction(q[p])&&q[p].apply(q,o))})};c[l]=c[l]||{};c[l][k]=function(o,n){var m=this;this.namespace=l;this.widgetName=k;this.widgetEventPrefix=c[l][k].eventPrefix||k;this.widgetBaseClass=l+"-"+k;this.options=c.extend({},c.widget.defaults,c[l][k].defaults,c.metadata&&c.metadata.get(o)[k],n);this.element=c(o).bind("setData."+k,function(q,p,r){if(q.target==o){return m._setData(p,r)}}).bind("getData."+k,function(q,p){if(q.target==o){return m._getData(p)}}).bind("remove",function(){return m.destroy()})};c[l][k].prototype=c.extend({},c.widget.prototype,j);c[l][k].getterSetter="option"};c.widget.prototype={_init:function(){},destroy:function(){this.element.removeData(this.widgetName).removeClass(this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").removeAttr("aria-disabled")},option:function(l,m){var k=l,j=this;if(typeof l=="string"){if(m===undefined){return this._getData(l)}k={};k[l]=m}c.each(k,function(n,o){j._setData(n,o)})},_getData:function(j){return this.options[j]},_setData:function(j,k){this.options[j]=k;if(j=="disabled"){this.element[k?"addClass":"removeClass"](this.widgetBaseClass+"-disabled "+this.namespace+"-state-disabled").attr("aria-disabled",k)}},enable:function(){this._setData("disabled",false)},disable:function(){this._setData("disabled",true)},_trigger:function(l,m,n){var p=this.options[l],j=(l==this.widgetEventPrefix?l:this.widgetEventPrefix+l);m=c.Event(m);m.type=j;if(m.originalEvent){for(var k=c.event.props.length,o;k;){o=c.event.props[--k];m[o]=m.originalEvent[o]}}this.element.trigger(m,n);return !(c.isFunction(p)&&p.call(this.element[0],m,n)===false||m.isDefaultPrevented())}};c.widget.defaults={disabled:false};c.ui.mouse={_mouseInit:function(){var j=this;this.element.bind("mousedown."+this.widgetName,function(k){return j._mouseDown(k)}).bind("click."+this.widgetName,function(k){if(j._preventClickEvent){j._preventClickEvent=false;k.stopImmediatePropagation();return false}});if(c.browser.msie){this._mouseUnselectable=this.element.attr("unselectable");this.element.attr("unselectable","on")}this.started=false},_mouseDestroy:function(){this.element.unbind("."+this.widgetName);(c.browser.msie&&this.element.attr("unselectable",this._mouseUnselectable))},_mouseDown:function(l){l.originalEvent=l.originalEvent||{};if(l.originalEvent.mouseHandled){return}(this._mouseStarted&&this._mouseUp(l));this._mouseDownEvent=l;var k=this,m=(l.which==1),j=(typeof this.options.cancel=="string"?c(l.target).parents().add(l.target).filter(this.options.cancel).length:false);if(!m||j||!this._mouseCapture(l)){return true}this.mouseDelayMet=!this.options.delay;if(!this.mouseDelayMet){this._mouseDelayTimer=setTimeout(function(){k.mouseDelayMet=true},this.options.delay)}if(this._mouseDistanceMet(l)&&this._mouseDelayMet(l)){this._mouseStarted=(this._mouseStart(l)!==false);if(!this._mouseStarted){l.preventDefault();return true}}this._mouseMoveDelegate=function(n){return k._mouseMove(n)};this._mouseUpDelegate=function(n){return k._mouseUp(n)};c(document).bind("mousemove."+this.widgetName,this._mouseMoveDelegate).bind("mouseup."+this.widgetName,this._mouseUpDelegate);(c.browser.safari||l.preventDefault());l.originalEvent.mouseHandled=true;return true},_mouseMove:function(j){if(c.browser.msie&&!j.button){return this._mouseUp(j)}if(this._mouseStarted){this._mouseDrag(j);return j.preventDefault()}if(this._mouseDistanceMet(j)&&this._mouseDelayMet(j)){this._mouseStarted=(this._mouseStart(this._mouseDownEvent,j)!==false);(this._mouseStarted?this._mouseDrag(j):this._mouseUp(j))}return !this._mouseStarted},_mouseUp:function(j){c(document).unbind("mousemove."+this.widgetName,this._mouseMoveDelegate).unbind("mouseup."+this.widgetName,this._mouseUpDelegate);if(this._mouseStarted){this._mouseStarted=false;this._preventClickEvent=(j.target==this._mouseDownEvent.target);this._mouseStop(j)}return false},_mouseDistanceMet:function(j){return(Math.max(Math.abs(this._mouseDownEvent.pageX-j.pageX),Math.abs(this._mouseDownEvent.pageY-j.pageY))>=this.options.distance)},_mouseDelayMet:function(j){return this.mouseDelayMet},_mouseStart:function(j){},_mouseDrag:function(j){},_mouseStop:function(j){},_mouseCapture:function(j){return true}};c.ui.mouse.defaults={cancel:null,distance:1,delay:0}})(jQuery);;
  if (!jQuery.ui.resizable) {
    (function(c){c.widget("ui.resizable",c.extend({},c.ui.mouse,{_init:function(){var e=this,j=this.options;this.element.addClass("ui-resizable");c.extend(this,{_aspectRatio:!!(j.aspectRatio),aspectRatio:j.aspectRatio,originalElement:this.element,_proportionallyResizeElements:[],_helper:j.helper||j.ghost||j.animate?j.helper||"ui-resizable-helper":null});if(this.element[0].nodeName.match(/canvas|textarea|input|select|button|img/i)){if(/relative/.test(this.element.css("position"))&&c.browser.opera){this.element.css({position:"relative",top:"auto",left:"auto"})}this.element.wrap(c('<div class="ui-wrapper" style="overflow: hidden;"></div>').css({position:this.element.css("position"),width:this.element.outerWidth(),height:this.element.outerHeight(),top:this.element.css("top"),left:this.element.css("left")}));this.element=this.element.parent().data("resizable",this.element.data("resizable"));this.elementIsWrapper=true;this.element.css({marginLeft:this.originalElement.css("marginLeft"),marginTop:this.originalElement.css("marginTop"),marginRight:this.originalElement.css("marginRight"),marginBottom:this.originalElement.css("marginBottom")});this.originalElement.css({marginLeft:0,marginTop:0,marginRight:0,marginBottom:0});this.originalResizeStyle=this.originalElement.css("resize");this.originalElement.css("resize","none");this._proportionallyResizeElements.push(this.originalElement.css({position:"static",zoom:1,display:"block"}));this.originalElement.css({margin:this.originalElement.css("margin")});this._proportionallyResize()}this.handles=j.handles||(!c(".ui-resizable-handle",this.element).length?"e,s,se":{n:".ui-resizable-n",e:".ui-resizable-e",s:".ui-resizable-s",w:".ui-resizable-w",se:".ui-resizable-se",sw:".ui-resizable-sw",ne:".ui-resizable-ne",nw:".ui-resizable-nw"});if(this.handles.constructor==String){if(this.handles=="all"){this.handles="n,e,s,w,se,sw,ne,nw"}var k=this.handles.split(",");this.handles={};for(var f=0;f<k.length;f++){var h=c.trim(k[f]),d="ui-resizable-"+h;var g=c('<div class="ui-resizable-handle '+d+'"></div>');if(/sw|se|ne|nw/.test(h)){g.css({zIndex:++j.zIndex})}if("se"==h){g.addClass("ui-icon ui-icon-gripsmall-diagonal-se")}this.handles[h]=".ui-resizable-"+h;this.element.append(g)}}this._renderAxis=function(p){p=p||this.element;for(var m in this.handles){if(this.handles[m].constructor==String){this.handles[m]=c(this.handles[m],this.element).show()}if(this.elementIsWrapper&&this.originalElement[0].nodeName.match(/textarea|input|select|button/i)){var n=c(this.handles[m],this.element),o=0;o=/sw|ne|nw|se|n|s/.test(m)?n.outerHeight():n.outerWidth();var l=["padding",/ne|nw|n/.test(m)?"Top":/se|sw|s/.test(m)?"Bottom":/^e$/.test(m)?"Right":"Left"].join("");p.css(l,o);this._proportionallyResize()}if(!c(this.handles[m]).length){continue}}};this._renderAxis(this.element);this._handles=c(".ui-resizable-handle",this.element).disableSelection();this._handles.mouseover(function(){if(!e.resizing){if(this.className){var i=this.className.match(/ui-resizable-(se|sw|ne|nw|n|e|s|w)/i)}e.axis=i&&i[1]?i[1]:"se"}});if(j.autoHide){this._handles.hide();c(this.element).addClass("ui-resizable-autohide").hover(function(){c(this).removeClass("ui-resizable-autohide");e._handles.show()},function(){if(!e.resizing){c(this).addClass("ui-resizable-autohide");e._handles.hide()}})}this._mouseInit()},destroy:function(){this._mouseDestroy();var d=function(f){c(f).removeClass("ui-resizable ui-resizable-disabled ui-resizable-resizing").removeData("resizable").unbind(".resizable").find(".ui-resizable-handle").remove()};if(this.elementIsWrapper){d(this.element);var e=this.element;e.parent().append(this.originalElement.css({position:e.css("position"),width:e.outerWidth(),height:e.outerHeight(),top:e.css("top"),left:e.css("left")})).end().remove()}this.originalElement.css("resize",this.originalResizeStyle);d(this.originalElement)},_mouseCapture:function(e){var f=false;for(var d in this.handles){if(c(this.handles[d])[0]==e.target){f=true}}return this.options.disabled||!!f},_mouseStart:function(f){var i=this.options,e=this.element.position(),d=this.element;this.resizing=true;this.documentScroll={top:c(document).scrollTop(),left:c(document).scrollLeft()};if(d.is(".ui-draggable")||(/absolute/).test(d.css("position"))){d.css({position:"absolute",top:e.top,left:e.left})}if(c.browser.opera&&(/relative/).test(d.css("position"))){d.css({position:"relative",top:"auto",left:"auto"})}this._renderProxy();var j=b(this.helper.css("left")),g=b(this.helper.css("top"));if(i.containment){j+=c(i.containment).scrollLeft()||0;g+=c(i.containment).scrollTop()||0}this.offset=this.helper.offset();this.position={left:j,top:g};this.size=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalSize=this._helper?{width:d.outerWidth(),height:d.outerHeight()}:{width:d.width(),height:d.height()};this.originalPosition={left:j,top:g};this.sizeDiff={width:d.outerWidth()-d.width(),height:d.outerHeight()-d.height()};this.originalMousePosition={left:f.pageX,top:f.pageY};this.aspectRatio=(typeof i.aspectRatio=="number")?i.aspectRatio:((this.originalSize.width/this.originalSize.height)||1);var h=c(".ui-resizable-"+this.axis).css("cursor");c("body").css("cursor",h=="auto"?this.axis+"-resize":h);d.addClass("ui-resizable-resizing");this._propagate("start",f);return true},_mouseDrag:function(d){var g=this.helper,f=this.options,l={},p=this,i=this.originalMousePosition,m=this.axis;var q=(d.pageX-i.left)||0,n=(d.pageY-i.top)||0;var h=this._change[m];if(!h){return false}var k=h.apply(this,[d,q,n]),j=c.browser.msie&&c.browser.version<7,e=this.sizeDiff;if(this._aspectRatio||d.shiftKey){k=this._updateRatio(k,d)}k=this._respectSize(k,d);this._propagate("resize",d);g.css({top:this.position.top+"px",left:this.position.left+"px",width:this.size.width+"px",height:this.size.height+"px"});if(!this._helper&&this._proportionallyResizeElements.length){this._proportionallyResize()}this._updateCache(k);this._trigger("resize",d,this.ui());return false},_mouseStop:function(g){this.resizing=false;var h=this.options,l=this;if(this._helper){var f=this._proportionallyResizeElements,d=f.length&&(/textarea/i).test(f[0].nodeName),e=d&&c.ui.hasScroll(f[0],"left")?0:l.sizeDiff.height,j=d?0:l.sizeDiff.width;var m={width:(l.size.width-j),height:(l.size.height-e)},i=(parseInt(l.element.css("left"),10)+(l.position.left-l.originalPosition.left))||null,k=(parseInt(l.element.css("top"),10)+(l.position.top-l.originalPosition.top))||null;if(!h.animate){this.element.css(c.extend(m,{top:k,left:i}))}l.helper.height(l.size.height);l.helper.width(l.size.width);if(this._helper&&!h.animate){this._proportionallyResize()}}c("body").css("cursor","auto");this.element.removeClass("ui-resizable-resizing");this._propagate("stop",g);if(this._helper){this.helper.remove()}return false},_updateCache:function(d){var e=this.options;this.offset=this.helper.offset();if(a(d.left)){this.position.left=d.left}if(a(d.top)){this.position.top=d.top}if(a(d.height)){this.size.height=d.height}if(a(d.width)){this.size.width=d.width}},_updateRatio:function(g,f){var h=this.options,i=this.position,e=this.size,d=this.axis;if(g.height){g.width=(e.height*this.aspectRatio)}else{if(g.width){g.height=(e.width/this.aspectRatio)}}if(d=="sw"){g.left=i.left+(e.width-g.width);g.top=null}if(d=="nw"){g.top=i.top+(e.height-g.height);g.left=i.left+(e.width-g.width)}return g},_respectSize:function(k,f){var i=this.helper,h=this.options,q=this._aspectRatio||f.shiftKey,p=this.axis,s=a(k.width)&&h.maxWidth&&(h.maxWidth<k.width),l=a(k.height)&&h.maxHeight&&(h.maxHeight<k.height),g=a(k.width)&&h.minWidth&&(h.minWidth>k.width),r=a(k.height)&&h.minHeight&&(h.minHeight>k.height);if(g){k.width=h.minWidth}if(r){k.height=h.minHeight}if(s){k.width=h.maxWidth}if(l){k.height=h.maxHeight}var e=this.originalPosition.left+this.originalSize.width,n=this.position.top+this.size.height;var j=/sw|nw|w/.test(p),d=/nw|ne|n/.test(p);if(g&&j){k.left=e-h.minWidth}if(s&&j){k.left=e-h.maxWidth}if(r&&d){k.top=n-h.minHeight}if(l&&d){k.top=n-h.maxHeight}var m=!k.width&&!k.height;if(m&&!k.left&&k.top){k.top=null}else{if(m&&!k.top&&k.left){k.left=null}}return k},_proportionallyResize:function(){var j=this.options;if(!this._proportionallyResizeElements.length){return}var f=this.helper||this.element;for(var e=0;e<this._proportionallyResizeElements.length;e++){var g=this._proportionallyResizeElements[e];if(!this.borderDif){var d=[g.css("borderTopWidth"),g.css("borderRightWidth"),g.css("borderBottomWidth"),g.css("borderLeftWidth")],h=[g.css("paddingTop"),g.css("paddingRight"),g.css("paddingBottom"),g.css("paddingLeft")];this.borderDif=c.map(d,function(k,m){var l=parseInt(k,10)||0,n=parseInt(h[m],10)||0;return l+n})}if(c.browser.msie&&!(!(c(f).is(":hidden")||c(f).parents(":hidden").length))){continue}g.css({height:(f.height()-this.borderDif[0]-this.borderDif[2])||0,width:(f.width()-this.borderDif[1]-this.borderDif[3])||0})}},_renderProxy:function(){var e=this.element,h=this.options;this.elementOffset=e.offset();if(this._helper){this.helper=this.helper||c('<div style="overflow:hidden;"></div>');var d=c.browser.msie&&c.browser.version<7,f=(d?1:0),g=(d?2:-1);this.helper.addClass(this._helper).css({width:this.element.outerWidth()+g,height:this.element.outerHeight()+g,position:"absolute",left:this.elementOffset.left-f+"px",top:this.elementOffset.top-f+"px",zIndex:++h.zIndex});this.helper.appendTo("body").disableSelection()}else{this.helper=this.element}},_change:{e:function(f,e,d){return{width:this.originalSize.width+e}},w:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{left:h.left+e,width:f.width-e}},n:function(g,e,d){var i=this.options,f=this.originalSize,h=this.originalPosition;return{top:h.top+d,height:f.height-d}},s:function(f,e,d){return{height:this.originalSize.height+d}},se:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},sw:function(f,e,d){return c.extend(this._change.s.apply(this,arguments),this._change.w.apply(this,[f,e,d]))},ne:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.e.apply(this,[f,e,d]))},nw:function(f,e,d){return c.extend(this._change.n.apply(this,arguments),this._change.w.apply(this,[f,e,d]))}},_propagate:function(e,d){c.ui.plugin.call(this,e,[d,this.ui()]);(e!="resize"&&this._trigger(e,d,this.ui()))},plugins:{},ui:function(){return{originalElement:this.originalElement,element:this.element,helper:this.helper,position:this.position,size:this.size,originalSize:this.originalSize,originalPosition:this.originalPosition}}}));c.extend(c.ui.resizable,{version:"1.7.2",eventPrefix:"resize",defaults:{alsoResize:false,animate:false,animateDuration:"slow",animateEasing:"swing",aspectRatio:false,autoHide:false,cancel:":input,option",containment:false,delay:0,distance:1,ghost:false,grid:false,handles:"e,s,se",helper:false,maxHeight:null,maxWidth:null,minHeight:10,minWidth:10,zIndex:1000}});c.ui.plugin.add("resizable","alsoResize",{start:function(e,f){var d=c(this).data("resizable"),g=d.options;_store=function(h){c(h).each(function(){c(this).data("resizable-alsoresize",{width:parseInt(c(this).width(),10),height:parseInt(c(this).height(),10),left:parseInt(c(this).css("left"),10),top:parseInt(c(this).css("top"),10)})})};if(typeof(g.alsoResize)=="object"&&!g.alsoResize.parentNode){if(g.alsoResize.length){g.alsoResize=g.alsoResize[0];_store(g.alsoResize)}else{c.each(g.alsoResize,function(h,i){_store(h)})}}else{_store(g.alsoResize)}},resize:function(f,h){var e=c(this).data("resizable"),i=e.options,g=e.originalSize,k=e.originalPosition;var j={height:(e.size.height-g.height)||0,width:(e.size.width-g.width)||0,top:(e.position.top-k.top)||0,left:(e.position.left-k.left)||0},d=function(l,m){c(l).each(function(){var p=c(this),q=c(this).data("resizable-alsoresize"),o={},n=m&&m.length?m:["width","height","top","left"];c.each(n||["width","height","top","left"],function(r,t){var s=(q[t]||0)+(j[t]||0);if(s&&s>=0){o[t]=s||null}});if(/relative/.test(p.css("position"))&&c.browser.opera){e._revertToRelativePosition=true;p.css({position:"absolute",top:"auto",left:"auto"})}p.css(o)})};if(typeof(i.alsoResize)=="object"&&!i.alsoResize.nodeType){c.each(i.alsoResize,function(l,m){d(l,m)})}else{d(i.alsoResize)}},stop:function(e,f){var d=c(this).data("resizable");if(d._revertToRelativePosition&&c.browser.opera){d._revertToRelativePosition=false;el.css({position:"relative"})}c(this).removeData("resizable-alsoresize-start")}});c.ui.plugin.add("resizable","animate",{stop:function(h,m){var n=c(this).data("resizable"),i=n.options;var g=n._proportionallyResizeElements,d=g.length&&(/textarea/i).test(g[0].nodeName),e=d&&c.ui.hasScroll(g[0],"left")?0:n.sizeDiff.height,k=d?0:n.sizeDiff.width;var f={width:(n.size.width-k),height:(n.size.height-e)},j=(parseInt(n.element.css("left"),10)+(n.position.left-n.originalPosition.left))||null,l=(parseInt(n.element.css("top"),10)+(n.position.top-n.originalPosition.top))||null;n.element.animate(c.extend(f,l&&j?{top:l,left:j}:{}),{duration:i.animateDuration,easing:i.animateEasing,step:function(){var o={width:parseInt(n.element.css("width"),10),height:parseInt(n.element.css("height"),10),top:parseInt(n.element.css("top"),10),left:parseInt(n.element.css("left"),10)};if(g&&g.length){c(g[0]).css({width:o.width,height:o.height})}n._updateCache(o);n._propagate("resize",h)}})}});c.ui.plugin.add("resizable","containment",{start:function(e,q){var s=c(this).data("resizable"),i=s.options,k=s.element;var f=i.containment,j=(f instanceof c)?f.get(0):(/parent/.test(f))?k.parent().get(0):f;if(!j){return}s.containerElement=c(j);if(/document/.test(f)||f==document){s.containerOffset={left:0,top:0};s.containerPosition={left:0,top:0};s.parentData={element:c(document),left:0,top:0,width:c(document).width(),height:c(document).height()||document.body.parentNode.scrollHeight}}else{var m=c(j),h=[];c(["Top","Right","Left","Bottom"]).each(function(p,o){h[p]=b(m.css("padding"+o))});s.containerOffset=m.offset();s.containerPosition=m.position();s.containerSize={height:(m.innerHeight()-h[3]),width:(m.innerWidth()-h[1])};var n=s.containerOffset,d=s.containerSize.height,l=s.containerSize.width,g=(c.ui.hasScroll(j,"left")?j.scrollWidth:l),r=(c.ui.hasScroll(j)?j.scrollHeight:d);s.parentData={element:j,left:n.left,top:n.top,width:g,height:r}}},resize:function(f,p){var s=c(this).data("resizable"),h=s.options,e=s.containerSize,n=s.containerOffset,l=s.size,m=s.position,q=s._aspectRatio||f.shiftKey,d={top:0,left:0},g=s.containerElement;if(g[0]!=document&&(/static/).test(g.css("position"))){d=n}if(m.left<(s._helper?n.left:0)){s.size.width=s.size.width+(s._helper?(s.position.left-n.left):(s.position.left-d.left));if(q){s.size.height=s.size.width/h.aspectRatio}s.position.left=h.helper?n.left:0}if(m.top<(s._helper?n.top:0)){s.size.height=s.size.height+(s._helper?(s.position.top-n.top):s.position.top);if(q){s.size.width=s.size.height*h.aspectRatio}s.position.top=s._helper?n.top:0}s.offset.left=s.parentData.left+s.position.left;s.offset.top=s.parentData.top+s.position.top;var k=Math.abs((s._helper?s.offset.left-d.left:(s.offset.left-d.left))+s.sizeDiff.width),r=Math.abs((s._helper?s.offset.top-d.top:(s.offset.top-n.top))+s.sizeDiff.height);var j=s.containerElement.get(0)==s.element.parent().get(0),i=/relative|absolute/.test(s.containerElement.css("position"));if(j&&i){k-=s.parentData.left}if(k+s.size.width>=s.parentData.width){s.size.width=s.parentData.width-k;if(q){s.size.height=s.size.width/s.aspectRatio}}if(r+s.size.height>=s.parentData.height){s.size.height=s.parentData.height-r;if(q){s.size.width=s.size.height*s.aspectRatio}}},stop:function(e,m){var p=c(this).data("resizable"),f=p.options,k=p.position,l=p.containerOffset,d=p.containerPosition,g=p.containerElement;var i=c(p.helper),q=i.offset(),n=i.outerWidth()-p.sizeDiff.width,j=i.outerHeight()-p.sizeDiff.height;if(p._helper&&!f.animate&&(/relative/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}if(p._helper&&!f.animate&&(/static/).test(g.css("position"))){c(this).css({left:q.left-d.left-l.left,width:n,height:j})}}});c.ui.plugin.add("resizable","ghost",{start:function(f,g){var d=c(this).data("resizable"),h=d.options,e=d.size;d.ghost=d.originalElement.clone();d.ghost.css({opacity:0.25,display:"block",position:"relative",height:e.height,width:e.width,margin:0,left:0,top:0}).addClass("ui-resizable-ghost").addClass(typeof h.ghost=="string"?h.ghost:"");d.ghost.appendTo(d.helper)},resize:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost){d.ghost.css({position:"relative",height:d.size.height,width:d.size.width})}},stop:function(e,f){var d=c(this).data("resizable"),g=d.options;if(d.ghost&&d.helper){d.helper.get(0).removeChild(d.ghost.get(0))}}});c.ui.plugin.add("resizable","grid",{resize:function(d,l){var n=c(this).data("resizable"),g=n.options,j=n.size,h=n.originalSize,i=n.originalPosition,m=n.axis,k=g._aspectRatio||d.shiftKey;g.grid=typeof g.grid=="number"?[g.grid,g.grid]:g.grid;var f=Math.round((j.width-h.width)/(g.grid[0]||1))*(g.grid[0]||1),e=Math.round((j.height-h.height)/(g.grid[1]||1))*(g.grid[1]||1);if(/^(se|s|e)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e}else{if(/^(ne)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e}else{if(/^(sw)$/.test(m)){n.size.width=h.width+f;n.size.height=h.height+e;n.position.left=i.left-f}else{n.size.width=h.width+f;n.size.height=h.height+e;n.position.top=i.top-e;n.position.left=i.left-f}}}}});var b=function(d){return parseInt(d,10)||0};var a=function(d){return !isNaN(parseInt(d,10))}})(jQuery);;
  }
}

// *
// * jQuery Effects Core & Clip 1.7.2 - New Wave Javascript (Packed)
// *
// * Copyright (c) 2009 AUTHORS.txt (http://jqueryui.com/about)
// * Dual licensed under the MIT (MIT-LICENSE.txt)
// * and GPL (GPL-LICENSE.txt) licenses.
// *
// * http://docs.jquery.com/UI
// *

if (typeof(jQuery) == "function") {
  jQuery.effects||(function(d){d.effects={version:"1.7.2",save:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.data("ec.storage."+h[f],g[0].style[h[f]])}}},restore:function(g,h){for(var f=0;f<h.length;f++){if(h[f]!==null){g.css(h[f],g.data("ec.storage."+h[f]))}}},setMode:function(f,g){if(g=="toggle"){g=f.is(":hidden")?"show":"hide"}return g},getBaseline:function(g,h){var i,f;switch(g[0]){case"top":i=0;break;case"middle":i=0.5;break;case"bottom":i=1;break;default:i=g[0]/h.height}switch(g[1]){case"left":f=0;break;case"center":f=0.5;break;case"right":f=1;break;default:f=g[1]/h.width}return{x:f,y:i}},createWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent()}var g={width:f.outerWidth(true),height:f.outerHeight(true),"float":f.css("float")};f.wrap('<div class="ui-effects-wrapper" style="font-size:100%;background:transparent;border:none;margin:0;padding:0"></div>');var j=f.parent();if(f.css("position")=="static"){j.css({position:"relative"});f.css({position:"relative"})}else{var i=f.css("top");if(isNaN(parseInt(i,10))){i="auto"}var h=f.css("left");if(isNaN(parseInt(h,10))){h="auto"}j.css({position:f.css("position"),top:i,left:h,zIndex:f.css("z-index")}).show();f.css({position:"relative",top:0,left:0})}j.css(g);return j},removeWrapper:function(f){if(f.parent().is(".ui-effects-wrapper")){return f.parent().replaceWith(f)}return f},setTransition:function(g,i,f,h){h=h||{};d.each(i,function(k,j){unit=g.cssUnit(j);if(unit[0]>0){h[j]=unit[0]*f+unit[1]}});return h},animateClass:function(h,i,k,j){var f=(typeof k=="function"?k:(j?j:null));var g=(typeof k=="string"?k:null);return this.each(function(){var q={};var o=d(this);var p=o.attr("style")||"";if(typeof p=="object"){p=p.cssText}if(h.toggle){o.hasClass(h.toggle)?h.remove=h.toggle:h.add=h.toggle}var l=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.addClass(h.add)}if(h.remove){o.removeClass(h.remove)}var m=d.extend({},(document.defaultView?document.defaultView.getComputedStyle(this,null):this.currentStyle));if(h.add){o.removeClass(h.add)}if(h.remove){o.addClass(h.remove)}for(var r in m){if(typeof m[r]!="function"&&m[r]&&r.indexOf("Moz")==-1&&r.indexOf("length")==-1&&m[r]!=l[r]&&(r.match(/color/i)||(!r.match(/color/i)&&!isNaN(parseInt(m[r],10))))&&(l.position!="static"||(l.position=="static"&&!r.match(/left|top|bottom|right/)))){q[r]=m[r]}}o.animate(q,i,g,function(){if(typeof d(this).attr("style")=="object"){d(this).attr("style")["cssText"]="";d(this).attr("style")["cssText"]=p}else{d(this).attr("style",p)}if(h.add){d(this).addClass(h.add)}if(h.remove){d(this).removeClass(h.remove)}if(f){f.apply(this,arguments)}})})}};function c(g,f){var i=g[1]&&g[1].constructor==Object?g[1]:{};if(f){i.mode=f}var h=g[1]&&g[1].constructor!=Object?g[1]:(i.duration?i.duration:g[2]);h=d.fx.off?0:typeof h==="number"?h:d.fx.speeds[h]||d.fx.speeds._default;var j=i.callback||(d.isFunction(g[1])&&g[1])||(d.isFunction(g[2])&&g[2])||(d.isFunction(g[3])&&g[3]);return[g[0],i,h,j]}d.fn.extend({_show:d.fn.show,_hide:d.fn.hide,__toggle:d.fn.toggle,_addClass:d.fn.addClass,_removeClass:d.fn.removeClass,_toggleClass:d.fn.toggleClass,effect:function(g,f,h,i){return d.effects[g]?d.effects[g].call(this,{method:g,options:f||{},duration:h,callback:i}):null},show:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._show.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"show"))}},hide:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))){return this._hide.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"hide"))}},toggle:function(){if(!arguments[0]||(arguments[0].constructor==Number||(/(slow|normal|fast)/).test(arguments[0]))||(d.isFunction(arguments[0])||typeof arguments[0]=="boolean")){return this.__toggle.apply(this,arguments)}else{return this.effect.apply(this,c(arguments,"toggle"))}},addClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{add:g},f,i,h]):this._addClass(g)},removeClass:function(g,f,i,h){return f?d.effects.animateClass.apply(this,[{remove:g},f,i,h]):this._removeClass(g)},toggleClass:function(g,f,i,h){return((typeof f!=="boolean")&&f)?d.effects.animateClass.apply(this,[{toggle:g},f,i,h]):this._toggleClass(g,f)},morph:function(f,h,g,j,i){return d.effects.animateClass.apply(this,[{add:h,remove:f},g,j,i])},switchClass:function(){return this.morph.apply(this,arguments)},cssUnit:function(f){var g=this.css(f),h=[];d.each(["em","px","%","pt"],function(j,k){if(g.indexOf(k)>0){h=[parseFloat(g),k]}});return h}});d.each(["backgroundColor","borderBottomColor","borderLeftColor","borderRightColor","borderTopColor","color","outlineColor"],function(g,f){d.fx.step[f]=function(h){if(h.state==0){h.start=e(h.elem,f);h.end=b(h.end)}h.elem.style[f]="rgb("+[Math.max(Math.min(parseInt((h.pos*(h.end[0]-h.start[0]))+h.start[0],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[1]-h.start[1]))+h.start[1],10),255),0),Math.max(Math.min(parseInt((h.pos*(h.end[2]-h.start[2]))+h.start[2],10),255),0)].join(",")+")"}});function b(g){var f;if(g&&g.constructor==Array&&g.length==3){return g}if(f=/rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(g)){return[parseInt(f[1],10),parseInt(f[2],10),parseInt(f[3],10)]}if(f=/rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(g)){return[parseFloat(f[1])*2.55,parseFloat(f[2])*2.55,parseFloat(f[3])*2.55]}if(f=/#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(g)){return[parseInt(f[1],16),parseInt(f[2],16),parseInt(f[3],16)]}if(f=/#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(g)){return[parseInt(f[1]+f[1],16),parseInt(f[2]+f[2],16),parseInt(f[3]+f[3],16)]}if(f=/rgba\(0, 0, 0, 0\)/.exec(g)){return a.transparent}return a[d.trim(g).toLowerCase()]}function e(h,f){var g;do{g=d.curCSS(h,f);if(g!=""&&g!="transparent"||d.nodeName(h,"body")){break}f="backgroundColor"}while(h=h.parentNode);return b(g)}var a={aqua:[0,255,255],azure:[240,255,255],beige:[245,245,220],black:[0,0,0],blue:[0,0,255],brown:[165,42,42],cyan:[0,255,255],darkblue:[0,0,139],darkcyan:[0,139,139],darkgrey:[169,169,169],darkgreen:[0,100,0],darkkhaki:[189,183,107],darkmagenta:[139,0,139],darkolivegreen:[85,107,47],darkorange:[255,140,0],darkorchid:[153,50,204],darkred:[139,0,0],darksalmon:[233,150,122],darkviolet:[148,0,211],fuchsia:[255,0,255],gold:[255,215,0],green:[0,128,0],indigo:[75,0,130],khaki:[240,230,140],lightblue:[173,216,230],lightcyan:[224,255,255],lightgreen:[144,238,144],lightgrey:[211,211,211],lightpink:[255,182,193],lightyellow:[255,255,224],lime:[0,255,0],magenta:[255,0,255],maroon:[128,0,0],navy:[0,0,128],olive:[128,128,0],orange:[255,165,0],pink:[255,192,203],purple:[128,0,128],violet:[128,0,128],red:[255,0,0],silver:[192,192,192],white:[255,255,255],yellow:[255,255,0],transparent:[255,255,255]};d.easing.jswing=d.easing.swing;d.extend(d.easing,{def:"easeOutQuad",swing:function(g,h,f,j,i){return d.easing[d.easing.def](g,h,f,j,i)},easeInQuad:function(g,h,f,j,i){return j*(h/=i)*h+f},easeOutQuad:function(g,h,f,j,i){return -j*(h/=i)*(h-2)+f},easeInOutQuad:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h+f}return -j/2*((--h)*(h-2)-1)+f},easeInCubic:function(g,h,f,j,i){return j*(h/=i)*h*h+f},easeOutCubic:function(g,h,f,j,i){return j*((h=h/i-1)*h*h+1)+f},easeInOutCubic:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h+f}return j/2*((h-=2)*h*h+2)+f},easeInQuart:function(g,h,f,j,i){return j*(h/=i)*h*h*h+f},easeOutQuart:function(g,h,f,j,i){return -j*((h=h/i-1)*h*h*h-1)+f},easeInOutQuart:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h+f}return -j/2*((h-=2)*h*h*h-2)+f},easeInQuint:function(g,h,f,j,i){return j*(h/=i)*h*h*h*h+f},easeOutQuint:function(g,h,f,j,i){return j*((h=h/i-1)*h*h*h*h+1)+f},easeInOutQuint:function(g,h,f,j,i){if((h/=i/2)<1){return j/2*h*h*h*h*h+f}return j/2*((h-=2)*h*h*h*h+2)+f},easeInSine:function(g,h,f,j,i){return -j*Math.cos(h/i*(Math.PI/2))+j+f},easeOutSine:function(g,h,f,j,i){return j*Math.sin(h/i*(Math.PI/2))+f},easeInOutSine:function(g,h,f,j,i){return -j/2*(Math.cos(Math.PI*h/i)-1)+f},easeInExpo:function(g,h,f,j,i){return(h==0)?f:j*Math.pow(2,10*(h/i-1))+f},easeOutExpo:function(g,h,f,j,i){return(h==i)?f+j:j*(-Math.pow(2,-10*h/i)+1)+f},easeInOutExpo:function(g,h,f,j,i){if(h==0){return f}if(h==i){return f+j}if((h/=i/2)<1){return j/2*Math.pow(2,10*(h-1))+f}return j/2*(-Math.pow(2,-10*--h)+2)+f},easeInCirc:function(g,h,f,j,i){return -j*(Math.sqrt(1-(h/=i)*h)-1)+f},easeOutCirc:function(g,h,f,j,i){return j*Math.sqrt(1-(h=h/i-1)*h)+f},easeInOutCirc:function(g,h,f,j,i){if((h/=i/2)<1){return -j/2*(Math.sqrt(1-h*h)-1)+f}return j/2*(Math.sqrt(1-(h-=2)*h)+1)+f},easeInElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return -(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f},easeOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l)==1){return f+m}if(!k){k=l*0.3}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}return h*Math.pow(2,-10*i)*Math.sin((i*l-j)*(2*Math.PI)/k)+m+f},easeInOutElastic:function(g,i,f,m,l){var j=1.70158;var k=0;var h=m;if(i==0){return f}if((i/=l/2)==2){return f+m}if(!k){k=l*(0.3*1.5)}if(h<Math.abs(m)){h=m;var j=k/4}else{var j=k/(2*Math.PI)*Math.asin(m/h)}if(i<1){return -0.5*(h*Math.pow(2,10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k))+f}return h*Math.pow(2,-10*(i-=1))*Math.sin((i*l-j)*(2*Math.PI)/k)*0.5+m+f},easeInBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*(h/=j)*h*((i+1)*h-i)+f},easeOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}return k*((h=h/j-1)*h*((i+1)*h+i)+1)+f},easeInOutBack:function(g,h,f,k,j,i){if(i==undefined){i=1.70158}if((h/=j/2)<1){return k/2*(h*h*(((i*=(1.525))+1)*h-i))+f}return k/2*((h-=2)*h*(((i*=(1.525))+1)*h+i)+2)+f},easeInBounce:function(g,h,f,j,i){return j-d.easing.easeOutBounce(g,i-h,0,j,i)+f},easeOutBounce:function(g,h,f,j,i){if((h/=i)<(1/2.75)){return j*(7.5625*h*h)+f}else{if(h<(2/2.75)){return j*(7.5625*(h-=(1.5/2.75))*h+0.75)+f}else{if(h<(2.5/2.75)){return j*(7.5625*(h-=(2.25/2.75))*h+0.9375)+f}else{return j*(7.5625*(h-=(2.625/2.75))*h+0.984375)+f}}}},easeInOutBounce:function(g,h,f,j,i){if(h<i/2){return d.easing.easeInBounce(g,h*2,0,j,i)*0.5+f}return d.easing.easeOutBounce(g,h*2-i,0,j,i)*0.5+j*0.5+f}})})(jQuery);;
  if (!jQuery.effects.clip) {
    (function(a){a.effects.clip=function(b){return this.queue(function(){var f=a(this),j=["position","top","left","height","width"];var i=a.effects.setMode(f,b.options.mode||"hide");var k=b.options.direction||"vertical";a.effects.save(f,j);f.show();var c=a.effects.createWrapper(f).css({overflow:"hidden"});var e=f[0].tagName=="IMG"?c:f;var g={size:(k=="vertical")?"height":"width",position:(k=="vertical")?"top":"left"};var d=(k=="vertical")?e.height():e.width();if(i=="show"){e.css(g.size,0);e.css(g.position,d/2)}var h={};h[g.size]=i=="show"?d:0;h[g.position]=i=="show"?0:d/2;e.animate(h,{queue:false,duration:b.duration,easing:b.options.easing,complete:function(){if(i=="hide"){f.hide()}a.effects.restore(f,j);a.effects.removeWrapper(f);if(b.callback){b.callback.apply(f[0],arguments)}f.dequeue()}})})}})(jQuery);;
  }
}


if(typeof(TopUp)=="undefined"){var scriptElement=(function deriveScriptElement(){var c="tu_dummy_script";document.write('<script id="'+c+'"><\/script>');var b=document.getElementById(c);var a=b.previousSibling;b.parentNode.removeChild(b);return a}());var scriptHost=(function deriveScriptHost(){var a=scriptElement.getAttribute("src");return a.match(/^\w+\:\/\//)?a.match(/^\w+\:\/\/[^\/]*\//)[0]:""}());TopUp=(function(){var m=false,i=null,d=[],y=false,v=null,r=null,D=null,R=null;var l={layout:"dashboard",effect:"transform",resizable:1},Q={};var j=function(){jQuery.extend({keys:function(W){var V=[];for(var U in W){if(W.hasOwnProperty(U)){V.push(U)}}return V},ie:jQuery.browser.msie,ie6:jQuery.browser.msie&&parseInt(jQuery.browser.version,10)==6,ie7:jQuery.browser.msie&&parseInt(jQuery.browser.version,10)>=7,ff2:jQuery.browser.mozilla&&parseFloat(jQuery.browser.version)<1.9});jQuery.fn.extend({id:function(){if(!this.is("[id]")){var V="";var U=0;do{V="element_"+U++}while(jQuery("#"+V).length);jQuery(this).attr("id",V)}return jQuery(this).attr("id")},bubbleDetect:function(U,X){var V=null;var W=this;jQuery.each(U.split(X||","),function(Z,aa){var Y=jQuery.trim(aa);if(jQuery(Y).index(W)!=-1){V={element:jQuery(W),selector:Y}}});return V||(W.parent()[0]?jQuery(W.parent()[0]).bubbleDetect(U,X):null)},center:function(){var U={top:parseInt((jQuery(window).height()-this.outerHeight())/2,10)+jQuery(window).scrollTop(),left:parseInt((jQuery(window).width()-this.outerWidth())/2,10)+jQuery(window).scrollLeft(),position:"absolute"};this.css(U);return this},lockDimensions:function(){this.css({width:this.outerWidth(),height:this.outerHeight()});return this},unlockDimensions:function(){this.css({width:"auto",height:"auto"});return this},centerWrap:function(V){var X={width:this.outerWidth(),height:this.outerHeight()},Z={width:0,height:0},W=0;W=V.outerWidth()-X.width;if(Z.width<W){Z.width=W}W=V.outerHeight()-X.height;if(Z.height<W){Z.height=W}var Y=this.offset();var U={top:Y.top-(Z.height===0?0:parseInt(Z.height/2,10)),left:Y.left-(Z.width===0?0:parseInt(Z.width/2,10)),width:this.width()+Z.width,height:this.height()+Z.height};if(v.x){U.left=v.x-parseInt((U.width-V.outerWidth())/2,10)}if(v.y){U.top=v.y-parseInt((U.height-V.outerHeight())/2,10)}jQuery("#tu_center_wrapper").css(U);jQuery("#tu_centered_content").append(this);this.css({top:"auto",left:"auto",width:"auto",height:"auto",display:"inline-block",position:"relative"});if(jQuery.ff2){this.css({display:"table"})}if(jQuery.ie){this.css({display:"inline"})}jQuery("#tu_center_wrapper").show();return this},removeCenterWrap:function(){var U=jQuery("#tu_center_wrapper").offset();var V={width:jQuery("#tu_center_wrapper").outerWidth()-this.outerWidth(),height:jQuery("#tu_center_wrapper").outerHeight()-this.outerHeight()};this.css({top:U.top+parseInt(V.height/2,10),left:U.left+parseInt(V.width/2,10),position:"absolute"}).appendTo("body");jQuery("#tu_center_wrapper").hide();return this},draggable:function(V){var U=this;this.mousedown(function(W){if(V&&V.only&&!jQuery(W.target).is(V.only)){return}W.preventDefault();var Y=U.offset();var X={top:W.pageY-Y.top,left:W.pageX-Y.left};jQuery("body").addClass("te_dragging");jQuery("*").bind("mousemove.draggable",function(Z){U.css({top:Z.pageY-X.top,left:Z.pageX-X.left})})});jQuery("#top_up").mouseup(function(W){jQuery("body").removeClass("te_dragging");jQuery("*").unbind("mousemove.draggable")})}})};var x=function(){var V=TopUp.host+TopUp.images_path;var X='<style type="text/css" media="screen">.te_overflow{overflow:hidden !important}.te_dragging{cursor:move !important}#tu_overlay,.te_top_up{top:0;left:0}#tu_overlay{width:100%;height:100%;position:fixed;z-index:999}#temp_up{top:-9999px;z-index:-1}.te_transparent{opacity:0}.te_shaded{opacity:.65;background:black}.te_scrollable{overflow:auto}.te_top_up{position:absolute;z-index:1000}.te_top_up a{border:0}.te_top_up a:hover{border:0}.te_top_up .ui-resizable-se{position:absolute !important;background-color:transparent !important;border:0 !important}.te_wrapper{position:relative}.te_title{width:100%;color:white;font-family:"Lucida Grande", "Arial";font-size:11px;position:absolute;text-align:center;z-index:1001}.te_frame,#tu_center_wrapper{border-collapse:collapse}.te_frame tr,.te_frame td{margin:0;padding:0}.te_frame .te_left,.te_frame .te_middle,.te_frame .te_right{padding:0}.te_controls{position:absolute;z-index:1001}.te_close_link,.te_previous_link,.te_next_link{cursor:pointer}.te_close_link{position:absolute;z-index:1002}.te_previous_link,.te_next_link{display:block;float:left}#tu_center_wrapper{position:absolute;z-index:1000}#tu_loader{width:100%;height:100%;position:absolute;background:url('+V+"loader.gif) no-repeat 50% 50%;z-index:1003} #top_up .te_dashboard .ui-resizable-se{width:10px !important;height:10px !important;bottom:12px !important;right:10px !important;background-image:url("+V+"dashboard/sprite.png) !important;background-position:0 0 !important}.te_dashboard .te_title{top:-9px;font-weight:bold}.te_dashboard .te_corner,.te_dashboard .te_rib{background-image:url("+V+"dashboard/sprite.png)}.te_dashboard .te_top,.te_dashboard .te_bottom{height:20px}.te_dashboard .te_left_filler{width:20px}.te_dashboard .te_right_filler{width:19px}.te_dashboard .te_middle .te_middle{background:url("+V+"dashboard/middle.png)}.te_dashboard .te_top .te_left{background-position:-17px -29px}.te_dashboard .te_top .te_middle{background-position:0 -71px}.te_dashboard .te_top .te_right{background-position:-33px -29px}.te_dashboard .te_middle .te_left{background-position:-17px -232px}.te_dashboard .te_middle .te_right{background-position:-33px -232px}.te_dashboard .te_bottom .te_left{background-position:-17px -47px}.te_dashboard .te_bottom .te_middle{background-position:-17px -89px}.te_dashboard .te_bottom .te_right{background-position:-33px -47px}.te_dashboard .te_content{margin:-11px -12px -11px -13px}.te_dashboard .te_controls{left:50%;width:63px;height:29px;margin-left:-33px;padding-left:5px;bottom:35px;background-image:url("+V+"dashboard/sprite.png);background-position:0 -178px}.te_dashboard .te_previous_link,.te_dashboard .te_next_link{width:31px;height:29px;background-image:url("+V+"dashboard/sprite.png)}.te_dashboard .te_previous_link{background-position:66px -113px}.te_dashboard .te_next_link{background-position:30px -113px}.te_dashboard .te_previous_link:hover{background-position:66px -142px}.te_dashboard .te_next_link:hover{background-position:30px -142px}.te_dashboard .te_close_link{width:28px;height:26px;top:-1px;right:-6px;background-image:url("+V+"dashboard/sprite.png);background-position:-20px 0} #top_up .te_quicklook .ui-resizable-se{width:10px !important;height:10px !important;bottom:12px !important;right:9px !important;background-image:url("+V+"quicklook/sprite.png) !important;background-position:-75px -181px !important}.te_quicklook .te_title{top:6px}.te_quicklook .te_corner,.te_quicklook .te_rib{background-image:url("+V+"quicklook/sprite.png)}.te_quicklook .te_top{height:24px}.te_quicklook .te_bottom{height:56px}.te_quicklook .te_left_filler,.te_quicklook .te_right_filler{width:12px}.te_quicklook .te_middle .te_middle{background:url("+V+"quicklook/middle.png)}.te_quicklook .te_top .te_left{background-position:0 0}.te_quicklook .te_top .te_middle{background-position:0 -30px}.te_quicklook .te_top .te_right{background-position:12px 0}.te_quicklook .te_middle .te_left{background-position:0 -181px}.te_quicklook .te_middle .te_right{background-position:12px -181px}.te_quicklook .te_bottom .te_left{background-position:0 -122px}.te_quicklook .te_bottom .te_middle{background-position:0 -61px}.te_quicklook .te_bottom .te_right{background-position:12px -122px}.te_quicklook .te_content{margin:0 -7px}.te_quicklook .te_controls{left:50%;width:66px;margin-left:-33px;bottom:18px}.te_quicklook .te_previous_link,.te_quicklook .te_next_link{width:31px;height:29px;margin:0 1px;background-image:url("+V+"quicklook/sprite.png)}.te_quicklook .te_previous_link{background-position:89px -195px}.te_quicklook .te_next_link{background-position:52px -195px}.te_quicklook .te_previous_link:hover{background-position:89px -226px}.te_quicklook .te_next_link:hover{background-position:52px -226px}.te_quicklook .te_close_link{width:13px;height:13px;top:7px;left:9px;background-image:url("+V+"quicklook/sprite.png);background-position:-24px -181px}</style>";var Z='<style type="text/css" media="screen">.te_dashboard .te_content{margin-bottom:-14px}</style>';var U='<style type="text/css" media="screen">.te_dashboard .te_content{margin-bottom:-13px}.te_dashboard .te_controls{width:65px;padding-left:3px}.te_dashboard .te_top .te_left,.te_dashboard .te_top .te_middle,.te_dashboard .te_top .te_right{background-image:none}.te_dashboard .te_middle .te_left,.te_dashboard .te_middle .te_right{background-image:none}.te_dashboard .te_bottom .te_left,.te_dashboard .te_bottom .te_middle,.te_dashboard .te_bottom .te_right{background-image:none}.te_dashboard .te_controls,.te_dashboard .te_previous_link,.te_dashboard .te_next_link,.te_dashboard .te_close_link{background-image:none}.te_dashboard .te_top .te_left{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/top_left.png" , sizingMethod="crop" )}.te_dashboard .te_top .te_middle{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/top_middle.png" , sizingMethod="scale")}.te_dashboard .te_top .te_right{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/top_right.png" , sizingMethod="crop" )}.te_dashboard .te_middle .te_left{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/middle_left.png" , sizingMethod="scale")}.te_dashboard .te_middle .te_middle{filter:alpha(opacity = 75);background:black}.te_dashboard .te_middle .te_right{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/middle_right.png" , sizingMethod="scale")}.te_dashboard .te_bottom .te_left{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/bottom_left.png" , sizingMethod="crop" )}.te_dashboard .te_bottom .te_middle{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/bottom_middle.png", sizingMethod="scale")}.te_dashboard .te_bottom .te_right{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/bottom_right.png" , sizingMethod="crop" )}.te_dashboard .te_controls{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/controls.png" , sizingMethod="crop" )}.te_dashboard .te_previous_link{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/previous.png" , sizingMethod="crop" )}.te_dashboard .te_next_link{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/next.png" , sizingMethod="crop" )}.te_dashboard .te_close_link{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'dashboard/close_link.png" , sizingMethod="crop" )} .te_quicklook .te_bottom{height:55px}.te_quicklook .te_controls{width:67px}.te_quicklook .te_top .te_left,.te_quicklook .te_top .te_middle,.te_quicklook .te_top .te_right{background-image:none}.te_quicklook .te_middle .te_left,.te_quicklook .te_middle .te_right{background-image:none}.te_quicklook .te_bottom .te_left,.te_quicklook .te_bottom .te_middle,.te_quicklook .te_bottom .te_right{background-image:none}.te_quicklook .te_previous_link,.te_quicklook .te_next_link,.te_quicklook .te_close_link{background-image:none}.te_quicklook .te_top .te_left{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/top_left.png" , sizingMethod="crop" )}.te_quicklook .te_top .te_middle{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/top_middle.png" , sizingMethod="scale")}.te_quicklook .te_top .te_right{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/top_right.png" , sizingMethod="crop" )}.te_quicklook .te_middle .te_left{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/middle_left.png" , sizingMethod="scale")}.te_quicklook .te_middle .te_middle{filter:alpha(opacity = 70);background:black}.te_quicklook .te_middle .te_right{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/middle_right.png" , sizingMethod="scale")}.te_quicklook .te_bottom .te_left{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/bottom_left.png" , sizingMethod="crop" )}.te_quicklook .te_bottom .te_middle{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/bottom_middle.png", sizingMethod="scale")}.te_quicklook .te_bottom .te_right{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/bottom_right.png" , sizingMethod="crop" )}.te_quicklook .te_previous_link{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/previous.png" , sizingMethod="crop" )}.te_quicklook .te_next_link{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/next.png" , sizingMethod="crop" )}.te_quicklook .te_close_link{filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src="'+V+'quicklook/close_link.png" , sizingMethod="crop" )}</style>';var Y='<style type="text/css" media="screen">#tu_overlay{top:expression((ignoreMe = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px");left:expression((ignoreMe2 = document.documentElement.scrollLeft ? document.documentElement.scrollLeft : document.body.scrollLeft) + "px");position:absolute}.te_transparent{filter:alpha(opacity = 0)}.te_shaded{filter:alpha(opacity = 65)}.te_content{position:relative;zoom:1}</style>';var W='<div id="tu_overlay" onclick="TopUp.overlayClose()" style="display: none"></div><div id="top_up" class="te_top_up" style="display: none"><div class="te_wrapper"><div class="te_title"></div><table class="te_frame"><tr class="te_top"><td class="te_left te_corner"><div class="te_left_filler"></div></td><td class="te_middle te_rib"></td><td class="te_right te_corner"><div class="te_right_filler"></div></td></tr><tr class="te_middle"><td class="te_left te_rib"></td><td class="te_middle"><div class="te_content"><!-- Content --></div></td><td class="te_right te_rib"></td></tr><tr class="te_bottom"><td class="te_left te_corner"></td><td class="te_middle te_rib"></td><td class="te_right te_corner"></td></tr></table><div class="te_controls" style="display: none"><a class="te_previous_link" onclick="TopUp.previous()"></a><a class="te_next_link" onclick="TopUp.next()"></a></div><a class="te_close_link" onclick="TopUp.close()" style="display: none"></a></div></div><div id="temp_up" class="te_top_up te_transparent"><div class="te_wrapper"><div class="te_title"></div><table class="te_frame"><tr class="te_top"><td class="te_left te_corner"><div class="te_left_filler"></div></td><td class="te_middle te_rib"></td><td class="te_right te_corner"><div class="te_right_filler"></div></td></tr><tr class="te_middle"><td class="te_left te_rib"></td><td class="te_middle"><div class="te_content"><!-- Content --></div></td><td class="te_right te_rib"></td></tr><tr class="te_bottom"><td class="te_left te_corner"></td><td class="te_middle te_rib"></td><td class="te_right te_corner"></td></tr></table><div class="te_controls" style="display: none"><a class="te_previous_link" onclick="TopUp.previous()"></a><a class="te_next_link" onclick="TopUp.next()"></a></div><a class="te_close_link" onclick="TopUp.close()" style="display: none"></a></div></div><table id="tu_center_wrapper" style="display: none"><tr valign="middle"><td id="tu_centered_content" align="center"><!-- Top ups --></td></tr></table><div id="tu_loader" style="display: none"></div>';if(!jQuery("head").length){jQuery(document.body).before("<head></head>")}jQuery(X).prependTo("head");if(jQuery.ie7){jQuery(Z).insertAfter("head > style:first")}if(jQuery.ie6){jQuery(U).insertAfter("head > style:first")}if(jQuery.ie){jQuery(Y).insertAfter("head > style:first")}jQuery(W).appendTo("body")};var g=function(){var U=["[class*=x]"];jQuery.each(["db","ql","image","html","dom","iframe","ajax","script"],function(V,W){U.push("[class*=_"+W+"]")});i=jQuery.merge([".top_up","[toptions]","[class^=tu_]:"+U.join(",")],jQuery.keys(Q)).join();jQuery(i).bind("click",C);jQuery(document).bind("keypress",p)};var c=function(U){return jQuery.ie7?1:U};var C=function(U){TopUp.displayTopUp(jQuery(U.target));return false};var p=function(U){if(jQuery("#top_up").is(":hidden")||jQuery(U.target).is(":input")){return}switch(U.keyCode){case 27:TopUp.close();break;case 37:TopUp.previous();break;case 39:TopUp.next();break}};var s=function(V,W){var U=jQuery.extend({},{topUp:"#"+V.element.id(),preset:V.selector});jQuery.each(V.element.attr("class").split(/\s/),function(X,Y){if(Y.match(/^tu_/)){jQuery.each(Y.replace(/^tu_/,"").split("_"),function(Z,aa){switch(aa){case"db":case"ql":U.layout={db:"dashboard",ql:"quicklook"}[aa];break;case"image":case"html":case"dom":case"iframe":case"ajax":case"script":U.type=aa;break;default:if(aa.match(/\dx\d/)){U.width=aa.split("x")[0];U.height=aa.split("x")[1]}}})}});if(V.element.is("[toptions]")){jQuery.each(V.element.attr("toptions").split(","),function(Y,Z){var X=Z.split("=");U[jQuery.trim(X[0])]=jQuery.trim(X[1])})}if(U.noGroup&&parseInt(U.noGroup,10)==1){U.group=null}if(W){U=jQuery.extend(U,W)}return U};var F=function(V,X,W){var U=jQuery.extend({},l);if(X){if(Q[X.preset]){U=jQuery.extend(U,Q[X.preset])}U=jQuery.extend(U,X)}if(W){U.reference=U.reference?jQuery(U.reference):V;if(!U.type){U.type=e(V)}if(k(U)){U.resizable=0}v=jQuery.extend({},U)}return U};var e=function(U){if(U.toLowerCase().match(/\.(gif|jpg|jpeg|png)$/)){return"image"}if(U.toLowerCase().match(/\.(swf)$/)){return"flash"}if(U.toLowerCase().match(/\.(flv)$/)){return"flashvideo"}if(U.toLowerCase().match(/\.(aif|aiff|aac|au|bmp|gsm|mov|mid|midi|mpg|mpeg|m4a|m4v|mp4|psd|qt|qtif|qif|qti|snd|tif|tiff|wav|3g2|3gp|wbmp)$/)){return"quicktime"}if(U.toLowerCase().match(/\.(ra|ram|rm|rpm|rv|smi|smil)$/)){return"realplayer"}if(U.toLowerCase().match(/\.(asf|avi|wma|wmv)$/)){return"windowsmedia"}return"ajax"};var k=function(U){return jQuery.inArray((U||v).type,["flash","flashvideo","quicktime","realplayer","windowsmedia"])!=-1};var a=function(){if(v.group){if(!(r&&r.name==v.group)){r={name:v.group,items:jQuery([])};jQuery.each(jQuery(i),function(V,W){if(!jQuery(W).is("[tu_group]")){jQuery(W).attr("tu_group",F(null,s(jQuery(W).bubbleDetect(i))).group)}if(jQuery(W).attr("tu_group")==r.name){r.items=r.items.add(W)}})}var U=jQuery.map(r.items,function(W,V){return"#"+jQuery(W).id()});D=v.topUp?jQuery.inArray(v.topUp,U):-1}else{r=null}};var N=function(U){if(r===null){return}D=D+U;if(D<0){D=r.items.length-1}if(D>r.items.length-1){D=0}TopUp.displayTopUp(r.items[D])};var S=function(){jQuery("#top_up .te_frame").resizable("destroy");jQuery("#top_up .te_title").fadeOut(c(200));if(!(r&&r.items.length>1)){jQuery("#top_up .te_controls").fadeOut(c(200))}jQuery(".te_wrapper").attr("class","te_wrapper te_"+v.layout);jQuery(".te_frame,.te_content").unlockDimensions();if(parseInt(v.shaded,10)==1){jQuery("#tu_overlay").addClass("te_shaded")}else{jQuery("#tu_overlay").removeClass("te_shaded")}if((parseInt(v.modal,10)==1)||(parseInt(v.shaded,10)==1)||(parseInt(v.overlayClose,10)==1)){jQuery("#tu_overlay").show()}else{jQuery("#tu_overlay").hide()}var U="";if(v.topUp&&(v.topUp!="")&&((parseInt(v.readAltText,10)==1)||(v.title&&v.title.match("{alt}")))){var V=jQuery(v.topUp);if(V.length){var W=V.find("img");if(W.length){U=W.attr("alt")||""}if(U!=""&&!(v.title&&v.title.match("{alt}"))){v.title="{alt}"}}}v.title=(v.title||"").replace("{alt}",U).replace("{current}",r===null?"":(D+1)).replace("{total}",r===null?"":r.items.length)};var A=function(){f();switch(v.type){case"image":v.content=new Image();jQuery(v.content).load(function(){v.content=jQuery(this);M()}).attr("src",v.reference);break;case"flash":case"flashvideo":case"quicktime":case"realplayer":case"windowsmedia":b(v.type,v.reference,v.width,v.height);break;case"iframe":v.content=jQuery('<iframe src="'+v.reference+'" frameborder="0" border="0"></iframe>');break;case"html":case"dom":v.content=jQuery(v.reference);break;case"ajax":case"script":v.content=null;jQuery.ajax({url:v.reference,type:(parseInt(v.post,10)==1)?"POST":"GET",cache:false,async:false,data:v.parameters,dataType:(v.type=="ajax")?"html":"script",success:M})}if(jQuery.inArray(v.type,["html","dom","iframe"])!=-1){M()}};var b=function(ac,U,V,af){if(!jQuery.ie){switch(v.type){case"flash":K();break;case"flashvideo":I();break;case"quicktime":q();break;case"realplayer":z();break;case"windowsmedia":u();break}return}var ag={width:V,height:af},W={src:U},ab=null,ad=null,Z=null,aa=null;switch(ac){case"flash":case"flashvideo":ab="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000";Z="http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0";ad="application/x-shockwave-flash";aa="http://get.adobe.com/flashplayer/";break;case"quicktime":ab="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B";Z="http://www.apple.com/qtactivex/qtplugin.cab";ad="video/quicktime";aa="http://www.apple.com/quicktime/download/";W.scale="aspect";W.bgcolor="black";W.showlogo="false";W.autoplay="true";break;case"realplayer":ab="clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA";ad="audio/x-pn-realaudio-plugin";aa="http://www.real.com/freeplayer/?rppr=rnwk";W.controls="imagewindow";W.console="one";W.autostart="true";W.nojava="true";break;case"windowsmedia":ab="clsid:6BF52A52-394A-11D3-B153-00C04F79FAA6";Z="http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab#Version=5,1,52,701";ad="application/x-oleobject";aa="http://www.microsoft.com/Windows/MediaPlayer/";W.filename=U;W.animationatstart="true";W.transparentatstart="true";W.autostart="true";W.showcontrols="true";W.showstatusbar="true";W.windowlessvideo="true";break}if(ac=="flashvideo"){W.flashvars="file="+U+"&autostart=true";U=TopUp.host+TopUp.players_path+"flvplayer.swf";W.src=U;W.movie=U}ag.codebase=Z;if(window.ActiveXObject){ag.classid=ab;ag.data=U}var X="";for(var ae in W){X+=" "+J("param",{name:ae,value:W[ae]})}W.width=V;W.height=af;W.mimetype=ad;W.pluginspage=aa;var Y=document.createElement("div");Y.innerHTML=J("object",ag)+X+J("embed",W)+"</embed></object>";v.content=jQuery(Y);M()};var J=function(X,U){var W="<"+X;for(var V in U){W+=" "+V+"='"+U[V]+"'"}return W+">"};var K=function(){var U=jQuery("<object></object>").attr({width:v.width,height:v.height,classid:"clsid:D27CDB6E-AE6D-11CF-96B8-444553540000",codebase:"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0",style:"display: none"});U.append(jQuery("<param></param>").attr({name:"src",value:v.reference}));U.append(jQuery("<embed></embed>").attr({src:v.reference,width:v.width,height:v.height,type:"application/x-shockwave-flash",pluginspage:"http://get.adobe.com/flashplayer/"}));v.content=jQuery("<div></div>").attr({width:v.width,height:v.height});v.content.append(U);M()};var I=function(){var U=jQuery("<object></object>").attr({width:v.width,height:v.height,classid:"clsid:D27CDB6E-AE6D-11CF-96B8-444553540000",codebase:"http://fpdownload.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0",style:"display: none"});U.append(jQuery("<param></param>").attr({name:"movie",value:TopUp.host+TopUp.players_path+"flvplayer.swf"}));U.append(jQuery("<param></param>").attr({name:"flashvars",value:"file="+v.reference+"&autostart=true"}));U.append(jQuery("<embed></embed>").attr({src:TopUp.host+TopUp.players_path+"flvplayer.swf",width:v.width,height:v.height,flashvars:"file="+v.reference+"&autostart=true",type:"application/x-shockwave-flash",pluginspage:"http://get.adobe.com/flashplayer/"}));v.content=jQuery("<div></div>").attr({width:v.width,height:v.height});v.content.append(U);M()};var q=function(){var U=jQuery("<object></object>").attr({width:v.width,height:v.height,classid:"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B",codebase:"http://www.apple.com/qtactivex/qtplugin.cab",style:"display: none"});U.append(jQuery("<param></param>").attr({name:"src",value:v.reference}));U.append(jQuery("<param></param>").attr({name:"scale",value:"aspect"}));U.append(jQuery("<param></param>").attr({name:"bgcolor",value:"black"}));U.append(jQuery("<param></param>").attr({name:"showlogo",value:"false"}));U.append(jQuery("<param></param>").attr({name:"autoplay",value:"true"}));U.append(jQuery("<embed></embed>").attr({src:v.reference,width:v.width,height:v.height,scale:"aspect",bgcolor:"black",showlogo:"false",autoplay:"true",type:"video/quicktime",pluginspage:"http://www.apple.com/quicktime/download/"}));v.content=jQuery("<div></div>").attr({width:v.width,height:v.height,style:"background: black"});v.content.append(U);M()};var z=function(){var U=jQuery("<object></object>").attr({width:v.width,height:v.height,classid:"clsid:CFCDAA03-8BE4-11CF-B84B-0020AFBBCCFA",style:"display: none"});U.append(jQuery("<param></param>").attr({name:"src",value:v.reference}));U.append(jQuery("<param></param>").attr({name:"controls",value:"imagewindow"}));U.append(jQuery("<param></param>").attr({name:"console",value:"one"}));U.append(jQuery("<param></param>").attr({name:"autostart",value:"true"}));U.append(jQuery("<embed></embed>").attr({src:v.reference,width:v.width,height:v.height,controls:"imagewindow",console:"one",autostart:"true",nojava:"true",type:"audio/x-pn-realaudio-plugin",pluginspage:"http://www.real.com/freeplayer/?rppr=rnwk"}));v.content=jQuery("<div></div>").attr({width:v.width,height:v.height});v.content.append(U);M()};var u=function(){q()};var M=function(U){o();if(U){v.content=jQuery(U)}switch(v.type){case"image":case"iframe":v.resize=v.content;jQuery(".te_content").removeClass("te_scrollable");break;default:v.resize=jQuery("#temp_up .te_content");jQuery(".te_content").addClass("te_scrollable")}if(jQuery("#top_up").is(":hidden")){G()}else{w()}};var f=function(){var U=jQuery("#top_up");if(jQuery("#top_up").is(":hidden")){U=jQuery(v.topUp);if(!U.length){U=jQuery(document)}else{if(U.children().length>0){U=jQuery(U.children()[0])}}}try{var V={top:U.offset().top,left:U.offset().left,width:U.outerWidth(),height:U.outerHeight()}}catch(W){var V={top:jQuery(window).scrollTop(),left:jQuery(window).scrollLeft(),width:parseInt(jQuery(window).width()/2),height:parseInt(jQuery(window).height()/2)}}jQuery("#tu_loader").css(V).show()};var o=function(){jQuery("#tu_loader").hide()};var G=function(){h();H();T("top_up");jQuery("#top_up").center();if(v.x){jQuery("#top_up").css({left:parseInt(v.x,10)})}if(v.y){jQuery("#top_up").css({top:parseInt(v.y,10)})}switch(v.effect){case"appear":case"fade":jQuery("#top_up").fadeIn(c(300),n);break;case"switch":case"clip":jQuery("#top_up").show("clip",{direction:"vertical"},500,n);break;default:var V=jQuery(v.topUp);if(V.children().length>0){V=jQuery(V.children()[0])}var U=jQuery("#top_up").find(".te_content");var W=v.topUp?jQuery.extend({width:V.outerWidth(),height:V.outerHeight()},V.offset()):{top:parseInt(jQuery(window).height()/2)-parseInt(U.height()/2)+jQuery(window).scrollTop(),left:parseInt(jQuery(window).width()/2)-parseInt(U.width()/2)+jQuery(window).scrollLeft(),width:10,height:10};B("from",W,n)}};var w=function(V){var U=jQuery("#top_up .te_content").lockDimensions().wrapInner("<div></div>").children();U.fadeOut(c(250),function(){T("temp_up");U.remove();if(V){V.apply([],[jQuery("#top_up .te_content").id()])}else{O();h()}H();jQuery("#top_up").centerWrap(jQuery("#temp_up"));var W={width:jQuery("#temp_up .te_content").outerWidth(),height:jQuery("#temp_up .te_content").outerHeight()};jQuery("#top_up .te_content").animate(W,400,function(){T("top_up");jQuery("#top_up").removeCenterWrap();n()})})};var h=function(){v.content.appendTo("#temp_up .te_content")};var T=function(V){var U=V=="top_up"?"temp_up":"top_up";jQuery("#"+U+" .te_content").children().appendTo("#"+V+" .te_content");if(V=="top_up"){jQuery("#top_up .te_content").css({width:jQuery("#temp_up .te_content").css("width"),height:jQuery("#temp_up .te_content").css("height")})}};var O=function(){jQuery(".te_content").children().remove()};var B=function(ab,V,ae){var ad=jQuery("#top_up");var Z=ad.find(".te_content");if(ab=="from"){ad.addClass("te_transparent").show()}var aa=ad.offset();var W=Z.offset();var X={width:ad.width()-Z.width(),height:ad.height()-Z.height()};V.top-=W.top-aa.top;V.left-=W.left-aa.left;var ac={top:ad.css("top"),left:ad.css("left"),width:ad.outerWidth(),height:ad.outerHeight()};var U={to:ab=="from"?ac:V,duration:500};if(ab=="from"){U.to.width-=X.width;U.to.height-=X.height}var Y=function(){var af=ab=="to"?function(){ad.fadeOut(c(250),ae).removeClass("te_overflow")}:function(){ae.apply();ad.removeClass("te_overflow")};ad.animate({top:U.to.top,left:U.to.left},U.duration);v.content.animate({width:U.to.width,height:U.to.height},U.duration,af)};if(ab=="from"){ad.css({top:V.top,left:V.left});v.content.css({width:V.width,height:V.height});jQuery(".te_top_up,.te_content").unlockDimensions();ad.hide().addClass("te_overflow").removeClass("te_transparent").fadeIn(c(300),Y)}else{Y.apply()}};var n=function(){var V=c(500);if(parseInt(v.resizable,10)==1){var U={stop:function(){jQuery("#top_up .te_frame").css({width:"auto",height:"auto"})},handles:"se",minWidth:200,minHeight:75,alsoResize:"#"+v.resize.id(),aspectRatio:v.type=="image"};jQuery("#top_up .te_frame").resizable(U)}if(jQuery.ie6){jQuery("#top_up .te_title").css("width",jQuery("#top_up").width())}jQuery("#top_up .te_title").html(v.title||"").fadeIn(V);if(r&&r.items.length>1&&jQuery("#top_up .te_controls").is(":hidden")){if(jQuery.ie6){jQuery("#top_up .te_controls").show()}else{jQuery("#top_up .te_controls").fadeIn(V)}}if(jQuery("#top_up .te_close_link").is(":hidden")){if(jQuery.ie6){jQuery("#top_up .te_close_link").show()}else{jQuery("#top_up .te_close_link").fadeIn(V)}}P();jQuery(".te_top_up,.te_content").unlockDimensions();if(k()){v.content.find("object").show()}if(v.ondisplay){v.ondisplay.apply(this,[jQuery("#top_up .te_content"),R])}y=false};var H=function(V){var U=V?null:t;if(!V){v.resize.unlockDimensions();if(jQuery.inArray(v.type,["image","iframe"])!=-1){jQuery("#temp_up .te_content").unlockDimensions()}V={};if(v.width){V.width=parseInt(v.width,10)}if(v.height){V.height=parseInt(v.height,10)}if(jQuery.ie6){jQuery("#top_up .te_title").css("width",jQuery("#temp_up").outerWidth())}}v.resize.css(V);if(U){U.apply()}};var t=function(){if(jQuery("#temp_up").outerHeight()<=jQuery(window).height()-4){return}var U=jQuery("#temp_up").outerHeight()-jQuery("#temp_up .te_content").height(),V={height:jQuery(window).height()-4-U};if(v.type=="image"){V.width=parseInt(v.content.width()*(V.height/v.content.height()),10)}H(V)};var P=function(){var W=jQuery("#top_up").offset();var V={width:jQuery("#top_up").outerWidth(),height:jQuery("#top_up").outerHeight()};var U={};if(W.top-jQuery(window).scrollTop()<2){U.top=jQuery(window).scrollTop()+2}else{if(W.top+V.height-jQuery(window).scrollTop()>jQuery(window).height()-2){U.top=jQuery(window).scrollTop()+jQuery(window).height()-V.height-2}}if(W.left-jQuery(window).scrollLeft()<2){U.left=jQuery(window).scrollLeft()+2}else{if(W.left+V.width-jQuery(window).scrollLeft()>jQuery(window).width()-2){U.left=jQuery(window).scrollLeft()+jQuery(window).width()-V.width-24}}if(jQuery.keys(U).length>0){jQuery("#top_up").animate(U,300)}};var L=function(W){var V=c(250);var U=function(){E(W)};jQuery("#top_up .te_title").fadeOut(V);jQuery("#top_up .te_controls").fadeOut(V);if(k()){v.content.find("object").hide()}if(jQuery.ie){jQuery("#top_up .te_close_link").hide();U.apply()}else{jQuery("#top_up .te_close_link").fadeOut(V,U)}};var E=function(Y){var X=function(){if(Y){Y.apply(this,[jQuery("#top_up .te_content"),R])}if(v.onclose){v.onclose.apply(this,[jQuery("#top_up .te_content"),R])}O();T("temp_up")};switch(v.effect){case"appear":case"fade":jQuery("#top_up").fadeOut(c(300),X);break;case"switch":case"clip":jQuery("#top_up").hide("clip",{direction:"vertical"},400,X);break;default:var V=jQuery(v.topUp);if(V.children().length>0){V=jQuery(V.children()[0])}var U=jQuery("#top_up").find(".te_content");var W=v.topUp?jQuery.extend({width:V.outerWidth(),height:V.outerHeight()},V.offset()):{top:parseInt(jQuery(window).height()/2)+jQuery(window).scrollTop(),left:parseInt(jQuery(window).width()/2)+jQuery(window).scrollLeft(),width:10,height:10};B("to",W,X)}jQuery("#tu_overlay").hide()};return{host:scriptHost,images_path:"images/top_up/",players_path:"players/",data:R,init:function(){if(m){return false}try{jQuery(document).ready(function(){j();x();g();jQuery("#top_up").draggable({only:".te_title,.te_top *,.te_bottom *"});jQuery.each(d,function(V,W){W.apply()})});jQuery(window).unload(function(){jQuery("*").unbind();jQuery("#top_up .te_frame").resizable("destroy")});m=true}catch(U){}},defaultPreset:function(U){l=jQuery.extend(l,U)},addPresets:function(U){Q=jQuery.extend(Q,U)},ready:function(U){d.push(U)},rebind:function(){g()},displayTopUp:function(V,X){var W=jQuery(V).bubbleDetect(i);var U=s(W,jQuery.extend(X||{},{trigger:"#"+jQuery(V).id()}));TopUp.display(W.element.attr("href"),U)},display:function(U,V){if(y){return false}try{y=true;R={};F(U,V,true);a();S();A()}catch(W){y=false;alert("Sorry, but the following error occured:\n\n"+W)}},update:function(U){if(jQuery("#top_up").is(":hidden")){return}v.type="html";v.resize=jQuery("#temp_up .te_content");jQuery(".te_content").addClass("te_scrollable");w(U||function(){})},previous:function(){N(-1)},next:function(){N(1)},overlayClose:function(){if(parseInt(v.overlayClose,10)==1){TopUp.close()}},close:function(U){if(jQuery("#top_up").is(":visible")){L(U)}}}}());(function(){var b=[];if(typeof(jQuery)=="undefined"){b.push("all")}else{if(!jQuery.ui||!jQuery.ui.resizable){b.push("uic-resizable")}if(!jQuery.effects||!jQuery.effects.clip){b.push("fxc-clip")}}if(b.length==0){TopUp.init()}else{var a=scriptElement.getAttribute("src").replace(/(development\/)?top_up(\-min)?\.js.*$/,"jquery/"+b.join(".")+".js");document.write('<script src="'+a+'" type="text/javascript" onload="TopUp.init()" onreadystatechange="TopUp.init()"><\/script>')}}())};
jQuery.fn.DetailedProductInfo = function (settings) {
	var current_modifiers = {price: 0, weight: 0};
	var product_quantity_limit = undefined;
	var options_quantity_limit = undefined;
	var is_options_combination_available = true;
	
	var can_add_to_cart = true;
	var can_add_to_wishlist = true;
	
	var $product_info = $(this);
	var $quantity_selector = $product_info.find('select[name=quantity_in_cart]');
	var $options_error = $product_info.find('.options_error');
	
	$product_info.submit(function (event) {
		var action = $product_info.find('input[name=asc_action]').val();
		if ((action == 'AddToCart' && ! can_add_to_cart) || (action == 'AddToWishlist' && ! can_add_to_wishlist)) {
			event.preventDefault();
		}
		return true;
	});
	
	// Product options changing handler
	$product_info.find('.product_options').bind('options_change', function (event, parameters) {
		current_modifiers = parameters.modifiers;
		options_quantity_limit = parameters.quantity;
		is_options_combination_available = parameters.combination;
		
		if (current_modifiers) {
            var total_price = settings.sale_price + current_modifiers.price;
			$product_info.find('.product_sale_price .value')
				.html(formatPrice(total_price, settings.currency_settings));
			if (current_modifiers.price && total_price >= settings.list_price) { 
				$product_info.find('.product_list_price, .discount_star').hide();
			}
			else {
				$product_info.find('.product_list_price, .discount_star').show();
			}
		}
		
		checkErrorState();
	});
	
	// Quantity dropdown changing handler
	$quantity_selector.change(function () {
		checkErrorState();
	});
	
	function checkErrorState()
	{
		$options_error.hide();
		can_add_to_cart = true;
		can_add_to_wishlist = true;
		
		if (! is_options_combination_available) {
			can_add_to_cart = false;
			can_add_to_wishlist = false;
			$options_error.html(settings.labels.inv_unavailable).show();
		}
		else if (options_quantity_limit == null) {
			// not in inventory
			if (settings.aanic != 'Y') {
				can_add_to_cart = false;
				can_add_to_wishlist = false;
				$options_error.html(settings.labels.comb_unavailable).show();
			}
		}
		else if (options_quantity_limit != undefined && options_quantity_limit < parseInt($quantity_selector.val())) {
			// out of stock
			if (settings.aanis != 'Y') {
    			can_add_to_cart = false;
    			can_add_to_wishlist = true;
    			if (options_quantity_limit > 0) {
    				$options_error.html(settings.labels.comb_limit_stock.replace('%quantity%', options_quantity_limit));
    			}
    			else {
    				$options_error.html(settings.labels.comb_out_of_stock);
    			}
    			$options_error.show();
			}
		}
		
		setButtonDisabled($product_info.find('.button_add_to_cart'), ! can_add_to_cart)
		setButtonDisabled($product_info.find('.add_to_wishlist'), ! can_add_to_wishlist)
	}
	
	function setButtonDisabled($button, disabled)
	{
		$button.attr('disabled', disabled);
		if (disabled) {
			$button.addClass('disabled');
		}
		else {
			$button.removeClass('disabled');
		}
	}
	
};

jQuery.fn.ProductOptionsChoice = function (modifiers, inventory, combinations_formula)
{
	var options_box = $(this);
	
	// На некоторые элементы формы нужно навесить обработчики события 'change',
	// чтобы сгенерировать событие 'change_option' ("одна из опций изменена").
	options_box.find('.form_row')
	
	.filter('.multiselect,.dropdown').each(function () {
		$(this).find('select').change(function () {
			options_box.trigger('one_option_change');
		});
	}).end()
	
	.filter('.radio').each(function () {
		$(this).find('input[type=radio]').change(function () {
			options_box.trigger('one_option_change');
		});
	}).end()
	
	.filter('.checkbox_set,.checkbox_input,.checkbox_text').each(function () {
		$(this).find('input[type=checkbox]').change(function () {
			options_box.trigger('one_option_change');
		});
	}).end()
	
	.filter('.file').each(function () {
		$(this).find('input[type=file]').change(function () {
			options_box.trigger('one_option_change');
		});
	});
	
	// Обработчик события "одна из опций изменена".
	options_box.bind('one_option_change', function() {
		var values = {};
		
		// fetch values of all options 
		options_box.find('.form_row')
		
		.filter('.checkbox_set').each(function () {
			// set of checkboxes
			var cb_name = $(this).find('input[type=checkbox]').attr('name');
			var option_id = cb_name.match(/^po\[(\d+)\]/)[1];
			var option_value = cb_name.match(/^po\[\d+\]\[(\d+)\]/)[1];
			var value = [];
			$(this).find('input[type=checkbox]:checked').each(function () {
				value.push(option_value);
			});
			values[ option_id ] = value;
		}).end()
		
		.filter('.radio').each(function () {
			// set of radio buttons
			var option_id = $(this).find('input[type=radio]').attr('name').match(/^po\[(\d+)\]/)[1];
			var value = [];
			$(this).find('input[type=radio]:checked').each(function () {
				value.push($(this).val());
			});
			values[ option_id ] = value;
		}).end()
		
		.filter('.multiselect,.dropdown').each(function () {
			// single select dropdown or multiple select list
			var $sel = $(this).find('select');
			var option_id = $sel.attr('name').match(/^po\[(\d+)\]/)[1];
			var value = $sel.val();
			if (value == null) {
				value = [];
			}
			else
			if (typeof value == 'string') {
				value = [ value ];
			}
			values[ option_id ] = value;
		}).end()
		
		.filter('.checkbox_input,.checkbox_text').each(function () {
			// optional text (with checkbox)
			var $cb = $(this).find('input[type=checkbox]');
			var option_id = $cb.attr('name').match(/^po\[(\d+)\]/)[1];
			values[ option_id ] = [ $cb.attr('checked') ? 'on' : 'off' ];
		}).end()
		
		.filter('.file').each(function () {
			// file
			var $file = $(this).find('input[type=file]');
			var option_id = $file.attr('name').match(/^po\[(\d+)\]/)[1];
			values[ option_id ] = [ $file.val() ? 'on' : 'off' ];
		}).end()

        .find('input[type=text], textarea').each(function () {
            var option_id = $(this).attr('name').match(/^po\[(\d+)\]/)[1];
            values[ option_id ] = [ $(this).val() ? 'on' : 'off' ];
        });
		
		// Вычисление суммы модификаторов согласно комбинации значений опций
		var values_ids = [];
		for(var option_id in values) {
			values_ids = values_ids.concat(values[option_id]);
		}
		var values_ids_re = new RegExp('\\{' + values_ids.join('\\}|\\{') + '\\}', 'g');
		
		var result = {
				modifiers: calcModifiers(modifiers, values),
				quantity: calcQuantity(inventory, values_ids_re),
				combination: checkCombinations(combinations_formula, values_ids_re)
		};
		options_box.trigger('options_change', [result]);
	})
	.trigger('one_option_change');
};

function calcModifiers(modifiers, options_values)
{
	var price = 0;
	var weight = 0;
	
	for (var option_id in modifiers) {
		var option_modifier = modifiers[option_id];
		if (option_id in options_values) {
			for (var value_num in options_values[option_id]) {
				var value_id = options_values[option_id][value_num];
				if (typeof option_modifier[value_id] == 'object') {
					price += option_modifier[value_id].price;
					weight += option_modifier[value_id].weight;
				}
			}
		}
	}
	return {price: price, weight: weight};
}

function calcQuantity(inventory, values_ids_re)
{
	var stock_limit = null;
    var any_selected = /[0-9]+/.test(values_ids_re);
	for (var i = 0; i < inventory.length; i++) {
		var formula = inventory[i].formula;
        if(any_selected && !(/[0-9]+/.test(formula))) continue;
		formula = formula.replace(values_ids_re, 'true');
		formula = formula.replace(/\{\d+\}/g, 'false');
		if (eval(formula)) {
			stock_limit = parseInt(inventory[i].quantity);
			break;
		}
	}
	return stock_limit;
}

function checkCombinations(formula, values_ids_re)
{
	formula = formula.replace(values_ids_re, 'true');
	formula = formula.replace(/\{\d+\}/g, 'false');
	return eval(formula);
}

ASCLIB = {
    getCurrentScroll: function(){
        return {
            left: document.body.scrollLeft
                                || document.documentElement.scrollLeft
                                || window.pageXOffset
                                || $(window).scrollLeft()
                                || 0,
            top: document.body.scrollTop
                                || document.documentElement.scrollTop
                                || window.pageYOffset
                                || $(window).scrollTop()
                                || 0
           }
    },
    
    getObjectSize: function(jObject){
        var size = {width: 0, height: 0}
        var children = jObject.children();
        var getSize = function(elem, size){
            var size = size || {width: 0, height: 0};
            size.width = size.width + ($.browser.opera ? $(elem).innerWidth() : $(elem).width())
                                    + (parseInt($(elem).css('margin-left')) || 0)
                                    + (parseInt($(elem).css('margin-right')) || 0)
                                    + (parseInt($(elem).css('padding-left')) || 0)
                                    + (parseInt($(elem).css('padding-right')) || 0);
            size.height = size.height + ($.browser.opera ? $(elem).innerHeight() : $(elem).height())
                                    + (parseInt($(elem).css('margin-top')) || 0)
                                    + (parseInt($(elem).css('margin-bottom')) || 0)
                                    + (parseInt($(elem).css('padding-top')) || 0)
                                    + (parseInt($(elem).css('padding-bottom')) || 0);
            return size;
        }

        if(children.length) $.each(jObject.children(), function(i,child){ size=getSize(child, size); });
        else size = getSize(jObject[0]);

        return size;
    },

    centerizeX: function(selector, addTopScroll, adjustToBottom){
        var scr = this.getCurrentScroll();
        $(selector).css('left', scr.left 
                                    + Math.round($(window).width()/2) 
                                    - Math.round(this.getObjectSize($(selector)).width/2) + 'px');
        var top = scr.top;
        if(adjustToBottom) 
            top = top + $(window).height() - this.getObjectSize($(selector)).height - 15;
        if(addTopScroll) 
            $(selector).css('top', top+'px');
    },

    centerizeY: function(selector, addLeftScroll, adjustToRight){
        var scr = this.getCurrentScroll();
        $(selector).css('top', scr.top 
                                    + Math.round($(window).height()/2) 
                                    - Math.round(this.getObjectSize($(selector)).height/2)+'px');
        var left = scr.left;
        if(adjustToRight) 
            left = left + $(window).width() - this.getObjectSize($(selector)).width;
        if(addLeftScroll) 
            $(selector).css('left', left+'px');
    },

    centerizeRelative: function(selector, relative){
        var offset = relative.offset();
        $(selector).css({
            left: offset.left+Math.round(relative.width()/2)-Math.round($(selector).width()/2)+'px',
            top: offset.top +Math.round(relative.height()/2)-Math.round($(selector).height()/2)+'px'
        });
    },

    centerize: function(selector){
        this.centerizeX(selector);
        this.centerizeY(selector);
    },

    jCollection2array: function(jObj){
        var arr = new Array();
        if(jObj && jObj.length)
            for(var i=0;i<jObj.length;i++)
                arr[i] = jObj[i];
        return arr;
    }
}

function AjaxManager(settings) {

    this.method = 'POST';
    this.getURL = '';
    this.actionScript = window.location.href;     // target server script for AJAX requests

    // additional POST params
    this.postData = {
        asc_ajax_req: 1                 // required param, don't remove!!
    };

    // CSS selector which initiates AJAX requests
    this.iSelector = '';
    // CSS selector which is parent of iSelector
    this.instance = '';
    // update all instances on page
    this.updateAllInstances = true;

    // Array of DOM handling events for DOM-element (AJAX request initiator)
    this.domEvents = {
        click: null,                    // don't propogate event
        change: 'propogate'             // propogate event
    }; 

    this.enableMessages = true;         // enables after request message blobs
    this.enableAjaxLoaderImage = true;  // enables AJAX-loader animated image
    this.enableCoverlet = false;        // enables AJAX-coverlet

    this.beforeCB = null;               // before AJAX request 
    this.afterCB = null;                // after AJAX request

    this.ajaxTimeout = 10;              // timeout for AJAX request (seconds)

    // custom or overriding settings
    var self = this;
    if(typeof(settings) == 'object')
        $.each(settings, function(k, v){ 
            self[k] = v; 
        });

    window.AjaxManagerInstances = window.AjaxManagerInstances || {};
    var iid = this.instance + this.iSelector;
    window.AjaxManagerInstances[iid] = window.AjaxManagerInstances[this.iid] || [];
    window.AjaxManagerInstances[iid].push(this);
    this.init();
}

AjaxManager.prototype.init = function(){
    var self = this;

    if(!Array.indexOf){ // fix for stupid IE
        Array.prototype.indexOf = function(obj){ 
            for(var i=0; i<this.length; i++)
                if(this[i]===obj) return i; 
            return -1; 
        } 
    }

    if(this.enableAjaxLoaderImage) this.getLoader();
    if(this.enableMessages) this.getMessageBox();
    if(this.enableCoverlet) this.getCoverlet();

    this.toggleCtrls(true); // add event handlers

    if(!this.enableCoverlet)
        $(window).scroll(function(){
            if($('.ajax_loader').css('display')!='none') 
                ASCLIB.centerizeX('.ajax_loader', true);
            if($('.ajax_message_box').css('display')!='none') 
                ASCLIB.centerizeX('.ajax_message_box', true, true);
        });

    return this;
}

AjaxManager.prototype.getLoader = function(){
    $(".ajax_loader").appendTo("body");
    return this;
}

AjaxManager.prototype.getMessageBox = function(){
    $(".ajax_message_box").appendTo("body");
    return this;
}

AjaxManager.prototype.getCoverlet = function(){
    $(".ajax_coverlet").appendTo("body");
    return this;
}

AjaxManager.prototype.enableLoader = function(elem2cover){
    $('.ajax_loader').fadeIn(1,function(){
        if(elem2cover) ASCLIB.centerizeRelative('.ajax_loader', elem2cover);
        else ASCLIB.centerizeX('.ajax_loader', true);
    });
    return this;
}

AjaxManager.prototype.disableLoader = function(){
    var self = this;
    $('.ajax_loader').fadeOut(1, function(){
        if(self.enableCoverlet) $(".ajax_coverlet").fadeOut(200);
    });
    return this;
}

AjaxManager.prototype.toggleCoverlet = function(elem2cover){
    var self = this;
    $(".ajax_coverlet")
        .css({
            left: elem2cover.offset().left+'px',
            top: elem2cover.offset().top+'px',
            width: elem2cover.width()+'px',
            height: elem2cover.height()+'px'
        })
        .fadeTo(100,0.5,function(){ self.enableLoader(elem2cover);});
}

AjaxManager.prototype.showMessageBox = function(message, status){
    if(status == 'success') $('.ajax_message_box').removeClass('ajax_message_error');
    else $('.ajax_message_box').addClass('ajax_message_error');
    $('.ajax_message_box_text').html(message);
    
    $('.ajax_message_box').fadeIn(1, function(){
        ASCLIB.centerizeX('.ajax_message_box', true, true);
        $('.ajax_message_box_cross').click(function(){ $(this).parent().hide(); });
    });
    if(status == 'success') setTimeout(function(){$('.ajax_message_box').fadeOut(700);}, 4000);
    return this;
}

AjaxManager.prototype.getInstance = function(jElem) {
    var result = {instance:null, pos:null};

    if(jElem && jElem.parents && typeof(jElem.parents)=='function'){
        var all_instances = ASCLIB.jCollection2array($(this.instance));
        var cur_instance = ASCLIB.jCollection2array(jElem.parents(this.instance))[0];
        result.instance = $(cur_instance);
        result.pos = all_instances.indexOf(cur_instance);
    }

    return result;
}

AjaxManager.prototype.toggleCtrls = function(enable){
    var self = this;
    var domElements = $(this.instance).find(this.iSelector);
    if(domElements && domElements.length>0) {
        for(var i=0; i<domElements.length; i++) {
            var domElement = domElements[i];
            if(!domElement) continue;
            for(var domEvent in this.domEvents){
                var hdlr = function(e){
                    if(!self.domEvents.domEvent) {
                        e.stopPropagation ? e.stopPropagation() : e.cancelBubble = true;
                    }
                    e.preventDefault ? e.preventDefault() : e.returnValue = false;
                    self.initiator = $(this);
                    // dropdown handling
                    var onchangeurl = $(this).attr('onchangeurl');
                    if(onchangeurl) eval('self.getURL = ' + onchangeurl); 
                    // links handling
                    if(self.method.toLowerCase()=='get' && this.href) self.getURL = this.href;
                    // forms handling
                    self.post(this.form || $(this).parents('form')[0]);
                    return false;
                };
                $(domElement).unbind(domEvent).bind(domEvent, function(){return false}, false);
                if(enable) $(domElement).unbind(domEvent).bind(domEvent, hdlr);
            }
        }
    }
}

// action that should be done before POST request (ex. enable loader image)
AjaxManager.prototype.beforeRequest = function(){
    var self = this;

    this.tid = window.setTimeout(function(){
        self.postCB({status:'error', message:'<p>Server connection timeout. Please, try again later.</p>', data:{}}, true);
    }, this.ajaxTimeout*1000);

    if(this.beforeCB && typeof(this.beforeCB)=='function') this.beforeCB(this);
    this.toggleCtrls();  // disable ctrls
    if(this.enableAjaxLoaderImage && !this.enableCoverlet) this.enableLoader();
    return this;
}

// action that should be done after POST request (ex. disable loader image, show popup-message)
AjaxManager.prototype.afterRequest = function(){
    if(this.enableAjaxLoaderImage) this.disableLoader();

    // re-initialize all AjaxManager instances
    for(var iid in window.AjaxManagerInstances) 
        if(window.AjaxManagerInstances[iid].length)
            for(var i=0; i<window.AjaxManagerInstances[iid].length; i++)
                if(typeof(window.AjaxManagerInstances[iid][i].toggleCtrls)=='function')
                    window.AjaxManagerInstances[iid][i].toggleCtrls(true);

    if(this.afterCB && typeof(this.afterCB)=='function') this.afterCB(this);
    return this;
}

AjaxManager.prototype.addPostData = function(obj){
    if(typeof(obj)=='object')
        for(var i in obj)
            if(typeof(i)=='string')
                this.postData[i] = obj[i];
    return this;
}

AjaxManager.prototype.customPostRequest = function(serverScript, postData, callback, format){
    if(!(serverScript && typeof(serverScript) == 'string')) return this;
    $.post(serverScript, postData, callback, format||'json');
    return this;
}

AjaxManager.prototype.postCB = function(response, died){
    $('.ajax_message_box, .ajax_loader, .ajax_coverlet').hide();
    window.clearTimeout(this.tid);
    if((this.enableMessages && response.message) || died)
        this.showMessageBox(response.message, response.status);
    if(!died) this.renderData(response.data);
    this.afterRequest();
}

AjaxManager.prototype.post = function(form){
    var self = this;
    var data = {};
    
    this.beforeRequest();
    if(this.enableCoverlet) {
        var instance = this.getInstance(this.initiator).instance;
        instance ? this.toggleCoverlet(instance) : this.enableLoader();
    }

    if(form && this.method.toLowerCase()=='post') {
        var serializedData = this.serializePostData(form);
        for(var i=0; i<serializedData.length; i++)
        {
            this.postData[serializedData[i].name] = serializedData[i].value;
        }

    }
    for(var i in this.postData) data[i] = this.postData[i];
    
    if(this.method.toLowerCase()=='get' && this.getURL)
        $.get(this.getURL, data, function(resp){ self.postCB(resp);}, 'json');
    else if(form && typeof(form.submit == 'function') && this.postData['asc_ajax_upload']) 
        form.submit();//this.iFramePost(form, data);
    else 
        $.post(this.actionScript, data, function(resp){ self.postCB(resp);}, 'json');

    return this;
}

AjaxManager.prototype.iFramePost = function(form, extPostData){
    var self = this;
    var id = new Date().getTime()
    $('.asc_ifr, .asc_iform').remove();

    var ifr = $('<iframe>', {name: 'ifr_'+id, className: 'asc_ifr'})
        .css({position: 'absolute', left: '-1000px', top: '-1000px'});

    ifr.load(function(){
        var content = this.contentWindow || this.contentDocument;
        eval($(content.document).find('body > script').text());
        if(resp) self.postCB(resp);
    });

    ifr.appendTo('body');

    var iform = $('<form>', {
            className: 'asc_iform', 
            method:'POST', 
            action: this.actionScript, 
            target: 'ifr_'+id,
            enctype: 'multipart/form-data'
    }).css({position: 'absolute', left: '-1000px', top: '-1000px'});

    var real = $(form).find('input[type=file]');
    var cloned = real.clone(true);
    real.hide();
    cloned.insertAfter(real)
    real.appendTo(iform);

    if(typeof(extPostData) == 'object')
    $.each(extPostData, function(k, v){
        if(iform.find('*[name='+k+']').length==0)
            $('<input type="hidden" name="'+k+'" value="'+v+'" />').appendTo(iform);
    });

    iform.appendTo('body');
    iform.submit();
}

AjaxManager.prototype.serializePostData = function(form){
     var data = $(form).serializeArray();
     if(form.action){
        var m = form.action.match(/asc_action=([0-9a-zA-Z_]+)/);
        if(m && m[1]) data.push({name:'asc_action', value: m[1]});
     }

     var files = $(form).find('input[type=file]');     
     if(files.length) this.postData['asc_ajax_upload'] = 1;

     return data;
}

AjaxManager.prototype.renderData = function(data){
    for(var block in data) {
        var blocks = $('.'+block);
        if(!this.updateAllInstances) {
            var instanceData = this.getInstance(this.initiator);
            if(instanceData.instance) blocks = instanceData.instance;
        }
        blocks.fadeTo(200, 0.5).replaceWith(data[block]).fadeTo(200, 1);
    }

    return this;
}

AjaxManager.prototype.debug = function(data){
    $('<div>').text(data.toString()).appendTo('body');
}


